PVData C++  8.0.5
pvIntrospect.h
1 /* pvIntrospect.h */
2 /*
3  * Copyright information and license terms for this software can be
4  * found in the file LICENSE that is included with the distribution
5  */
6 /**
7  * @author mrk and Michael Davidsaver
8  */
9 #ifndef PVINTROSPECT_H
10 #define PVINTROSPECT_H
11 
12 #include <string>
13 #include <stdexcept>
14 #include <iostream>
15 #include <map>
16 
17 #include <epicsAssert.h>
18 
19 #include <pv/lock.h>
20 #include <pv/noDefaultMethods.h>
21 #include <pv/pvType.h>
22 #include <pv/byteBuffer.h>
23 #include <pv/serialize.h>
24 #include <pv/pvdVersion.h>
25 
26 #include <shareLib.h>
27 #define PVD_DEPRECATED_52 PVD_DEPRECATED("See https://github.com/epics-base/pvDataCPP/issues/52")
28 
29 /* C++11 keywords
30  @code
31  struct Base {
32  virtual void foo();
33  };
34  struct Class : public Base {
35  virtual void foo() OVERRIDE FINAL;
36  };
37  @endcode
38  */
39 #ifndef FINAL
40 # if __cplusplus>=201103L
41 # define FINAL final
42 # else
43 # define FINAL
44 # endif
45 #endif
46 #ifndef OVERRIDE
47 # if __cplusplus>=201103L
48 # define OVERRIDE override
49 # else
50 # define OVERRIDE
51 # endif
52 #endif
53 
54 namespace epics { namespace pvData {
55 
56 namespace format {
57 
59 {
60  long level;
61 
62  indent_level(long l) : level(l) {}
63 };
64 
65 epicsShareExtern long& indent_value(std::ios_base& ios);
66 
67 epicsShareExtern std::ostream& operator<<(std::ostream& os, indent_level const& indent);
68 
70 {
71  long saved_level;
72  std::ios_base& stream;
73 
74  indent_scope(std::ios_base& ios) :
75  stream(ios)
76  {
77  long& l = indent_value(ios);
78  saved_level = l;
79  l = saved_level + 1;
80  }
81 
82  ~indent_scope()
83  {
84  indent_value(stream) = saved_level;
85  }
86 };
87 
88 struct indent
89 {
90 };
91 
92 epicsShareExtern std::ostream& operator<<(std::ostream& os, indent const&);
93 
94 struct array_at
95 {
96  std::size_t index;
97 
98  array_at(std::size_t ix) : index(ix) {}
99 };
100 
102 {
103  std::size_t index;
104  std::ostream& stream;
105 
106  array_at_internal(std::size_t ix, std::ostream& str) : index(ix), stream(str) {}
107 };
108 
109 epicsShareExtern array_at_internal operator<<(std::ostream& str, array_at const& manip);
110 
111 };
112 
113 class Field;
114 class Scalar;
115 class Array;
116 class ScalarArray;
117 class Structure;
118 class StructureArray;
119 class Union;
120 class UnionArray;
121 
122 class BoundedString;
123 
124 class PVField;
125 class PVScalar;
126 class PVScalarArray;
127 class PVStructure;
128 class PVUnion;
129 template<typename T> class PVValueArray;
130 
131 /**
132  * typedef for a shared pointer to an immutable Field.
133  */
134 typedef std::tr1::shared_ptr<const Field> FieldConstPtr;
135 /**
136  * typedef for an array of shared pointer to an immutable Field.
137  */
139 /**
140  * typedef for a shared pointer to an immutable Scalar.
141  */
143 /**
144  * typedef for a shared pointer to an immutable Array.
145  */
147 /**
148  * typedef for a shared pointer to an immutable ScalarArray.
149  */
151 /**
152  * typedef for a shared pointer to an immutable Structure.
153  */
155 /**
156  * typedef for a shared pointer to an immutable StructureArray.
157  */
159 /**
160  * typedef for a shared pointer to an immutable Union.
161  */
163 /**
164  * typedef for a shared pointer to an immutable UnionArray.
165  */
167 /**
168  * typedef for a shared pointer to an immutable BoundedString.
169  */
171 
172 /**
173  * Definition of support field types.
174  */
175 enum Type {
176  /**
177  * The type is scalar. It has a scalarType
178  */
180  /**
181  * The type is scalarArray. Each element is a scalar of the same scalarType.
182  */
184  /**
185  * The type is structure.
186  */
188  /**
189  * The type is structureArray. Each element is a structure.
190  */
192  /**
193  * The type is an union.
194  */
196  /**
197  * The type is an array of unions.
198  */
200 };
201 
202 /**
203  * @brief Convenience functions for Type.
204  *
205  */
206 namespace TypeFunc {
207  /**
208  * Get a name for the type.
209  * @param type The type.
210  * @return The name for the type.
211  */
212  epicsShareExtern const char* name(Type type);
213 };
214 
215 epicsShareExtern std::ostream& operator<<(std::ostream& o, const Type& type);
216 
217 
218 /**
219  * Definition of support scalar types.
220  */
222  /**
223  * The type is boolean, i.e. value can be @c false or @c true
224  */
226  /**
227  * The type is byte, i.e. a 8 bit signed integer.
228  */
230  /**
231  * The type is short, i.e. a 16 bit signed integer.
232  */
234  /**
235  * The type is int, i.e. a 32 bit signed integer.
236  */
238  /**
239  * The type is long, i.e. a 64 bit signed integer.
240  */
242  /**
243  * The type is unsigned byte, i.e. a 8 bit unsigned integer.
244  */
246  /**
247  * The type is unsigned short, i.e. a 16 bit unsigned integer.
248  */
250  /**
251  * The type is unsigned int, i.e. a 32 bit unsigned integer.
252  */
254  /**
255  * The type is unsigned long, i.e. a 64 bit unsigned integer.
256  */
258  /**
259  * The type is float, i.e. 32 bit IEEE floating point,
260  */
262  /**
263  * The type is float, i.e. 64 bit IEEE floating point,
264  */
266  /**
267  * The type is string, i.e. a UTF8 character string.
268  */
270 };
271 
272 #define MAX_SCALAR_TYPE pvString
273 
274 /**
275  * @brief Convenience functions for ScalarType.
276  *
277  */
278 namespace ScalarTypeFunc {
279  /**
280  * Is the type an integer, i.e. is it one of byte,...ulong
281  * @param scalarType The type.
282  * @return (false,true) if the scalarType is an integer.
283  */
285  /**
286  * Is the type an unsigned integer, i.e. is it one of ubyte,...ulong
287  * @param scalarType The type.
288  * @return (false,true) if the scalarType is an integer.
289  */
291  /**
292  * Is the type numeric, i.e. is it one of byte,...,double
293  * @param scalarType The type.
294  * @return (false,true) if the scalarType is a numeric
295  */
297  /**
298  * Is the type primitive, i.e. not string
299  * @param scalarType The type.
300  * @return (false,true) if the scalarType is primitive.
301  */
303  /**
304  * Get the scalarType for value.
305  * @param value The name of the scalar type.
306  * @return The scalarType.
307  * An exception is thrown if the name is not the name of a scalar type.
308  */
309  epicsShareExtern ScalarType getScalarType(std::string const &value);
310  /**
311  * Get a name for the scalarType.
312  * @param scalarType The type.
313  * @return The name for the scalarType.
314  */
316 
317  //! gives sizeof(T) where T depends on the scalar type id.
318  epicsShareExtern size_t elementSize(ScalarType id);
319 };
320 
321 epicsShareExtern std::ostream& operator<<(std::ostream& o, const ScalarType& scalarType);
322 
323 
324 /**
325  * @brief This class implements introspection object for field.
326  *
327  */
328 class epicsShareClass Field :
329  virtual public Serializable,
331 public:
332  static size_t num_instances;
333 
335  virtual ~Field();
336  /**
337  * Get the field type.
338  * @return The type.
339  */
340  Type getType() const{return m_fieldType;}
341  /**
342  * Get the identification string.
343  * @return The identification string, can be empty.
344  */
345  virtual std::string getID() const = 0;
346 
347  /**
348  * Puts the string representation to the stream.
349  * @param o output stream.
350  * @return The output stream.
351  */
352  virtual std::ostream& dump(std::ostream& o) const = 0;
353 
354  //! Allocate a new instance
355  //! @version Added after 7.0.0
356  std::tr1::shared_ptr<PVField> build() const;
357 
358  enum {isField=1};
359 
360 protected:
361  /**
362  * Constructor
363  * @param type The field type.
364  */
365  Field(Type type);
366  void cacheCleanup();
367 private:
368  const Type m_fieldType;
369  unsigned int m_hash;
370  struct Helper;
371  friend struct Helper;
372 
373  friend class StructureArray;
374  friend class Structure;
375  friend class PVFieldPvt;
376  friend class StandardField;
377  friend class BasePVStructureArray;
378  friend class FieldCreate;
380 };
381 
382 epicsShareExtern std::ostream& operator<<(std::ostream& o, const Field& field);
383 
384 
385 /**
386  * @brief This class implements introspection object for Scalar.
387  *
388  */
389 class epicsShareClass Scalar : public Field{
390 public:
392  virtual ~Scalar();
393  typedef Scalar& reference;
394  typedef const Scalar& const_reference;
395  /**
396  * Get the scalarType
397  * @return the scalarType
398  */
400 
401  virtual std::string getID() const OVERRIDE;
402 
403  virtual std::ostream& dump(std::ostream& o) const OVERRIDE FINAL;
404 
407 
408  //! Allocate a new instance
409  //! @version Added after 7.0.0
410  std::tr1::shared_ptr<PVScalar> build() const;
411 
412 protected:
414 private:
417  friend class FieldCreate;
418  friend class ScalarArray;
419  friend class BoundedScalarArray;
420  friend class FixedScalarArray;
421  friend class BoundedString;
423 };
424 
425 /**
426  * @brief This class implements introspection object for BoundedString.
427  *
428  */
429 class epicsShareClass BoundedString : public Scalar{
430 public:
432  virtual ~BoundedString();
433  typedef BoundedString& reference;
434  typedef const BoundedString& const_reference;
435 
436  virtual std::string getID() const OVERRIDE FINAL;
437 
439 
440  std::size_t getMaximumLength() const;
441 
442 protected:
444 private:
446  friend class FieldCreate;
448 };
449 
450 /**
451  * @brief This class implements introspection object for Array.
452  *
453  */
454 class epicsShareClass Array : public Field{
455 public:
457  virtual ~Array();
458  typedef Array& reference;
459  typedef const Array& const_reference;
460 
461  enum ArraySizeType { variable, fixed, bounded };
462 
463  /**
464  * Get array size type (i.e. variable/fixed/bounded size array).
465  * @return array size type enum.
466  */
467  virtual ArraySizeType getArraySizeType() const = 0;
468 
469  /**
470  * Get maximum capacity of the array.
471  * @return maximum capacity of the array, 0 indicates variable size array.
472  */
473  virtual std::size_t getMaximumCapacity() const = 0;
474 
475 protected:
476  /**
477  * Constructor
478  * @param type The field type.
479  */
480  Array(Type type);
481 
483 };
484 
485 /**
486  * @brief This class implements introspection object for scalar array.
487  *
488  */
489 class epicsShareClass ScalarArray : public Array{
490 public:
492  typedef ScalarArray& reference;
493  typedef const ScalarArray& const_reference;
494 
495  /**
496  * Constructor
497  * @param scalarType The scalarType for the field.
498  */
500  /**
501  * Get the scalarType for the elements.
502  * @return the scalarType
503  */
505 
507 
508  virtual std::size_t getMaximumCapacity() const OVERRIDE {return 0;}
509 
510  virtual std::string getID() const OVERRIDE;
511 
512  virtual std::ostream& dump(std::ostream& o) const OVERRIDE FINAL;
513 
516 
517  //! Allocate a new instance
518  //! @version Added after 7.0.0
519  std::tr1::shared_ptr<PVScalarArray> build() const;
520 
521  virtual ~ScalarArray();
522 private:
523  const std::string getIDScalarArrayLUT() const;
525  friend class FieldCreate;
527 };
528 
529 
530 
531 /**
532  * @brief This class implements introspection object for bounded scalar array.
533  *
534  */
535 class epicsShareClass BoundedScalarArray : public ScalarArray{
536 public:
538  typedef BoundedScalarArray& reference;
539  typedef const BoundedScalarArray& const_reference;
540 
541  /**
542  * Constructor
543  * @param scalarType The scalarType for the field.
544  * @param size maximum (bound) capacity.
545  */
547 
549 
550  virtual std::size_t getMaximumCapacity() const OVERRIDE FINAL {return size;}
551 
552  virtual std::string getID() const OVERRIDE FINAL;
553 
555 
556  virtual ~BoundedScalarArray();
557 private:
558  std::size_t size;
559  friend class FieldCreate;
561 };
562 
563 /**
564  * @brief This class implements introspection object for bounded scalar array.
565  *
566  */
567 class epicsShareClass FixedScalarArray : public ScalarArray{
568 public:
570  typedef FixedScalarArray& reference;
571  typedef const FixedScalarArray& const_reference;
572 
573  /**
574  * Constructor
575  * @param scalarType The scalarType for the field.
576  * @param size maximum (bound) capacity.
577  */
579 
581 
582  virtual std::size_t getMaximumCapacity() const OVERRIDE FINAL {return size;}
583 
584  virtual std::string getID() const OVERRIDE FINAL;
585 
587 
588  virtual ~FixedScalarArray();
589 private:
590  std::size_t size;
591  friend class FieldCreate;
593 };
594 
595 /**
596  * @brief This class implements introspection object for a structureArray
597  *
598  */
599 class epicsShareClass StructureArray : public Array{
600 public:
602  typedef StructureArray& reference;
603  typedef const StructureArray& const_reference;
604 
605  /**
606  * Get the introspection interface for the array elements.
607  * @return The introspection interface.
608  */
609  const StructureConstPtr& getStructure() const {return pstructure;}
610 
612 
613  virtual std::size_t getMaximumCapacity() const OVERRIDE FINAL {return 0;}
614 
615  virtual std::string getID() const OVERRIDE FINAL;
616 
617  virtual std::ostream& dump(std::ostream& o) const OVERRIDE FINAL;
618 
621 
622  //! Allocate a new instance
623  //! @version Added after 7.0.0
625 
626 protected:
627  /**
628  * Constructor.
629  * @param structure The introspection interface for the elements.
630  */
632 public:
633  virtual ~StructureArray();
634 private:
636  friend class FieldCreate;
638 };
639 
640 /**
641  * @brief This class implements introspection object for a unionArray
642  *
643  */
644 class epicsShareClass UnionArray : public Array{
645 public:
647  typedef UnionArray& reference;
648  typedef const UnionArray& const_reference;
649 
650  /**
651  * Get the introspection interface for the array elements.
652  * @return The introspection interface.
653  */
654  UnionConstPtr getUnion() const {return punion;}
655 
657 
658  virtual std::size_t getMaximumCapacity() const OVERRIDE FINAL {return 0;}
659 
660  virtual std::string getID() const OVERRIDE FINAL;
661 
662  virtual std::ostream& dump(std::ostream& o) const OVERRIDE FINAL;
663 
666 
667  //! Allocate a new instance
668  //! @version Added after 7.0.0
670 
671 protected:
672  /**
673  * Constructor.
674  * @param _punion The introspection interface for the elements.
675  */
677 public:
678  virtual ~UnionArray();
679 private:
681  friend class FieldCreate;
683 };
684 
685 /**
686  * @brief This class implements introspection object for a structure.
687  *
688  */
689 class epicsShareClass Structure : public Field {
690 public:
692 
693  /**
694  * Default structure ID.
695  */
696  static const std::string DEFAULT_ID;
697 
698  /**
699  * Get the default structure ID.
700  * @return The default structure ID.
701  */
702  static const std::string & defaultId();
703 
704  virtual ~Structure();
705  typedef Structure& reference;
706  typedef const Structure& const_reference;
707 
708  /**
709  * Get the number of immediate subfields in the structure.
710  * @return The number of fields.
711  */
712  std::size_t getNumberFields() const {return fieldNames.size();}
713 
714  /**
715  * Lookup Field by name
716  * @param fieldName Member field name. May not contain '.'
717  * @return NULL if no member by this name.
718  */
719  FieldConstPtr getField(std::string const &fieldName) const;
720 
721  /** Lookup Field by name and cast to Field sub-class.
722  * @param fieldName Member field name. May not contain '.'
723  * @return NULL If no member by this name, or member exists, but has type other than FT.
724  */
725  template<typename FT>
726  std::tr1::shared_ptr<const FT> getField(std::string const &fieldName) const
727  {
728  STATIC_ASSERT(FT::isField); // only allow cast from Field sub-class
729  return std::tr1::dynamic_pointer_cast<const FT>(getField(fieldName));
730  }
731 
732  /**
733  * Lookup Field by name
734  * @param fieldName Member field name. May not contain '.'
735  * @return Field pointer (never NULL)
736  * @throws std::runtime_error If no member by this name
737  */
739 
740  /** Lookup Field by name and cast to Field sub-class.
741  * @param fieldName Member field name. May not contain '.'
742  * @return Field pointer (never NULL)
743  * @throws std::runtime_error If no member by this name, or member exists, but has type other than FT.
744  */
745  template<typename FT>
746  std::tr1::shared_ptr<const FT> getFieldT(std::string const &fieldName) const
747  {
748  STATIC_ASSERT(FT::isField); // only allow cast from Field sub-class
749  std::tr1::shared_ptr<const FT> result(
751  );
752 
753  if (!result)
754  throw std::runtime_error("Wrong Field type");
755 
756  return result;
757  }
758 
759  /** Lookup Field by index, within this Structure.
760  * @param index Index of member in this structure. @code index>=0 && index<getNumberFields() @endcode
761  * @return Field pointer (never NULL)
762  * @throws std::out_of_range If index >= getNumberFields()
763  */
764  const FieldConstPtr& getField(std::size_t index) const {return fields.at(index);}
765 
766  /** Lookup Field by index, within this Structure.
767  * @param index Index of member in this structure. @code index>=0 && index<getNumberFields() @endcode
768  * @return NULL if member is not a sub-class of FT
769  * @throws std::out_of_range If index >= getNumberFields()
770  */
771  template<typename FT>
773  {
774  STATIC_ASSERT(FT::isField); // only allow cast from Field sub-class
775  return std::tr1::dynamic_pointer_cast<const FT>(getField(index));
776  }
777 
778  /** Lookup Field by index, within this Structure.
779  * @param index Index of member in this structure. @code index>=0 && index<getNumberFields() @endcode
780  * @return Field pointer (never NULL)
781  * @throws std::out_of_range If index >= getNumberFields()
782  */
784 
785  /** Lookup Field by index, within this Structure.
786  * @param index Index of member in this structure. @code index>=0 && index<getNumberFields() @endcode
787  * @return Field pointer (never NULL)
788  * @throws std::out_of_range If index >= getNumberFields()
789  * @throws std::runtime_error If member is not a sub-class of FT
790  */
791  template<typename FT>
793  {
794  STATIC_ASSERT(FT::isField); // only allow cast from Field sub-class
795  std::tr1::shared_ptr<const FT> result(
797  );
798 
799  if (!result)
800  throw std::runtime_error("Wrong Field type");
801 
802  return result;
803  }
804 
805  /**
806  * Get the field index for the specified fieldName.
807  * @return The introspection interface.
808  * This will be -1 if the field is not in the structure.
809  */
810  std::size_t getFieldIndex(std::string const &fieldName) const;
811  /**
812  * Get the fields in the structure.
813  * @return The array of fields.
814  */
815  FieldConstPtrArray const & getFields() const {return fields;}
816  /**
817  * Get the names of the fields in the structure.
818  * @return The array of fieldNames.
819  */
820  StringArray const & getFieldNames() const {return fieldNames;}
821  /**
822  * Get the name of the field with the specified index;
823  * @param fieldIndex The index of the desired field.
824  * @return The fieldName.
825  */
827 
828  virtual std::string getID() const OVERRIDE FINAL;
829 
830  virtual std::ostream& dump(std::ostream& o) const OVERRIDE FINAL;
831 
834 
835  //! Allocate a new instance
836  //! @version Added after 7.0.0
837  std::tr1::shared_ptr<PVStructure> build() const;
838 
839 protected:
841 private:
844  std::string id;
845 
846  FieldConstPtr getFieldImpl(const std::string& fieldName, bool throws) const;
847  void dumpFields(std::ostream& o) const;
848 
849  friend class FieldCreate;
850  friend class Union;
852 };
853 
854 /**
855  * @brief This class implements introspection object for a union.
856  *
857  */
858 class epicsShareClass Union : public Field {
859 public:
861 
862  /**
863  * Default union ID.
864  */
865  static const std::string DEFAULT_ID;
866 
867  /**
868  * Get the default union ID.
869  * @return The default union ID.
870  */
871  static const std::string & defaultId();
872 
873  /**
874  * Default variant union ID.
875  */
876  static const std::string ANY_ID;
877 
878  /**
879  * Get the default variant union ID.
880  * @return The default variant union ID.
881  */
882  static const std::string & anyId();
883 
884  virtual ~Union();
885  typedef Union& reference;
886  typedef const Union& const_reference;
887 
888  /**
889  * Get the number of immediate subfields in the union.
890  * @return The number of fields.
891  */
892  std::size_t getNumberFields() const {return fieldNames.size();}
893 
894  /**
895  * Lookup Field by name
896  * @param fieldName Member field name. May not contain '.'
897  * @return NULL if no member by this name.
898  */
899  FieldConstPtr getField(std::string const &fieldName) const;
900 
901  /** Lookup Field by name and cast to Field sub-class.
902  * @param fieldName Member field name. May not contain '.'
903  * @return NULL If no member by this name, or member exists, but has type other than FT.
904  */
905  template<typename FT>
906  std::tr1::shared_ptr<const FT> getField(std::string const &fieldName) const
907  {
908  STATIC_ASSERT(FT::isField); // only allow cast from Field sub-class
909  return std::tr1::dynamic_pointer_cast<const FT>(getField(fieldName));
910  }
911 
912  /**
913  * Lookup Field by name
914  * @param fieldName Member field name. May not contain '.'
915  * @return Field pointer (never NULL)
916  * @throws std::runtime_error If no member by this name
917  */
919 
920  /** Lookup Field by name and cast to Field sub-class.
921  * @param fieldName Member field name. May not contain '.'
922  * @return Field pointer (never NULL)
923  * @throws std::runtime_error If no member by this name, or member exists, but has type other than FT.
924  */
925  template<typename FT>
926  std::tr1::shared_ptr<const FT> getFieldT(std::string const &fieldName) const
927  {
928  STATIC_ASSERT(FT::isField); // only allow cast from Field sub-class
929  std::tr1::shared_ptr<const FT> result(
931  );
932 
933  if (!result)
934  throw std::runtime_error("Wrong Field type");
935 
936  return result;
937  }
938 
939  /** Lookup Field by index, within this Union.
940  * @param index Index of member in this union. @code index>=0 && index<getNumberFields() @endcode
941  * @return Field pointer (never NULL)
942  * @throws std::out_of_range If index >= getNumberFields()
943  */
945 
946  /** Lookup Field by index, within this Union.
947  * @param index Index of member in this union. @code index>=0 && index<getNumberFields() @endcode
948  * @return NULL if member is not a sub-class of FT
949  * @throws std::out_of_range If index >= getNumberFields()
950  */
951  template<typename FT>
953  {
954  STATIC_ASSERT(FT::isField); // only allow cast from Field sub-class
955  return std::tr1::dynamic_pointer_cast<const FT>(getField(index));
956  }
957 
958  /** Lookup Field by index, within this Union.
959  * @param index Index of member in this union. @code index>=0 && index<getNumberFields() @endcode
960  * @return Field pointer (never NULL)
961  * @throws std::out_of_range If index >= getNumberFields()
962  */
964 
965  /** Lookup Field by index, within this Structure.
966  * @param index Index of member in this structure. @code index>=0 && index<getNumberFields() @endcode
967  * @return Field pointer (never NULL)
968  * @throws std::out_of_range If index >= getNumberFields()
969  * @throws std::runtime_error If member is not a sub-class of FT
970  */
971  template<typename FT>
973  {
974  STATIC_ASSERT(FT::isField); // only allow cast from Field sub-class
975  std::tr1::shared_ptr<const FT> result(
977  );
978 
979  if (!result)
980  throw std::runtime_error("Wrong Field type");
981 
982  return result;
983  }
984 
985  /**
986  * Get the field index for the specified fieldName.
987  * @return The introspection interface.
988  * This will be -1 if the field is not in the union.
989  */
990  std::size_t getFieldIndex(std::string const &fieldName) const;
991  /**
992  * Get the fields in the union.
993  * @return The array of fields.
994  */
995  FieldConstPtrArray const & getFields() const {return fields;}
996  /**
997  * Get the names of the fields in the union.
998  * @return The array of fieldNames.
999  */
1000  StringArray const & getFieldNames() const {return fieldNames;}
1001  /**
1002  * Get the name of the field with the specified index;
1003  * @param fieldIndex The index of the desired field.
1004  * @return The fieldName.
1005  */
1007  /**
1008  * Check if this union is variant union (aka any type).
1009  * @return <code>true</code> if this union is variant union, otherwise <code>false</code>.
1010  */
1011  bool isVariant() const {return (fieldNames.size() == 0);}
1012 
1013  /** Attempt to find an suitable member to stored the specified type.
1014  *
1015  * Returned index is guerenteed to by of specified Type (either scalar or scalarArray).
1016  * Provided ScalarType is taken as a hint.
1017  *
1018  @param t Must be either scalar or scalarArray
1019  @param s The preferred ScalarType
1020  @returns A valid index or -1
1021  */
1022  int32 guess(Type t, ScalarType s) const;
1023 
1024  virtual std::string getID() const OVERRIDE FINAL;
1025 
1026  virtual std::ostream& dump(std::ostream& o) const OVERRIDE FINAL;
1027 
1030 
1031  //! Allocate a new instance
1032  //! @version Added after 7.0.0
1033  std::tr1::shared_ptr<PVUnion> build() const;
1034 
1035 protected:
1036  Union();
1037  Union(StringArray const & fieldNames, FieldConstPtrArray const & fields, std::string const & id = defaultId());
1038 private:
1041  std::string id;
1042 
1043  FieldConstPtr getFieldImpl(const std::string& fieldName, bool throws) const;
1044  void dumpFields(std::ostream& o) const;
1045 
1046  friend class FieldCreate;
1047  friend class Structure;
1049 };
1050 
1051 class FieldCreate;
1052 typedef std::tr1::shared_ptr<FieldCreate> FieldCreatePtr;
1053 
1054 class FieldBuilder;
1055 typedef std::tr1::shared_ptr<FieldBuilder> FieldBuilderPtr;
1056 
1057 /**
1058  * @brief Interface for in-line creating of introspection interfaces.
1059  *
1060  * One instance can be used to create multiple @c Field instances.
1061  * An instance of this object must not be used concurrently (an object has a state).
1062  * @author mse
1063  */
1064 class epicsShareClass FieldBuilder :
1066 {
1067 public:
1068  //! Create a new instance of in-line @c Field builder.
1069  //! @version Added after 7.0.0
1070  static FieldBuilderPtr begin();
1071  //! Create a new instance of in-line @c Field builder pre-initialized with and existing Structure
1073 
1074  /**
1075  * Set ID of an object to be created.
1076  * @param id id to be set.
1077  * @return this instance of a @c FieldBuilder.
1078  */
1079  FieldBuilderPtr setId(std::string const & id);
1080 
1081  /**
1082  * Add a @c Scalar.
1083  * @param name name of the array.
1084  * @param scalarType type of a scalar to add.
1085  * @return this instance of a @c FieldBuilder.
1086  */
1088 
1089  /**
1090  * Add a @c BoundedString.
1091  * @param name name of the array.
1092  * @param maxLength a string maximum length.
1093  * @return this instance of a @c FieldBuilder.
1094  */
1096 
1097  /**
1098  * Add a @c Field (e.g. @c Structure, @c Union).
1099  * @param name name of the array.
1100  * @param field a field to add.
1101  * @return this instance of a @c FieldBuilder.
1102  */
1103  FieldBuilderPtr add(std::string const & name, FieldConstPtr const & field);
1104 
1105  /**
1106  * Add variable size array of @c Scalar elements.
1107  * @param name name of the array.
1108  * @param scalarType type of a scalar element.
1109  * @return this instance of a @c FieldBuilder.
1110  */
1112 
1113  /**
1114  * Add fixed-size array of @c Scalar elements.
1115  * @param name name of the array.
1116  * @param scalarType type of a scalar element.
1117  * @param size Array fixed size.
1118  * @return this instance of a @c FieldBuilder.
1119  */
1121 
1122  /**
1123  * Add bounded-size array of @c Scalar elements.
1124  * @param name name of the array.
1125  * @param scalarType type of a scalar element.
1126  * @param bound Array maximum capacity (size).
1127  * @return this instance of a @c FieldBuilder.
1128  */
1130 
1131  /**
1132  * Add array of @c Field elements.
1133  * @param name name of the array.
1134  * @param element a type of an array element.
1135  * @return this instance of a @c FieldBuilder.
1136  */
1138 
1139  /**
1140  * Create a @c Structure.
1141  * This resets this instance state and allows new @c Field instance to be created.
1142  * @return a new instance of a @c Structure.
1143  */
1145 
1146  /**
1147  * Create an @c Union.
1148  * This resets this instance state and allows new @c Field instance to be created.
1149  * @return a new instance of an @c Union.
1150  */
1152 
1153  /**
1154  * Add new nested @c Structure.
1155  * endNested() method must be called
1156  * to complete creation of the nested @c Structure.
1157  * @param name nested structure name.
1158  * @return a new instance of a @c FieldBuilder is returned.
1159  * @see #endNested()
1160  */
1162 
1163  /**
1164  * Add new nested @c Union.
1165  * endNested() method must be called
1166  * to complete creation of the nested @c Union.
1167  * @param name nested union name.
1168  * @return a new instance of a @c FieldBuilder is returned.
1169  * @see #endNested()
1170  */
1172 
1173  /**
1174  * Add new nested @c Structure[].
1175  * endNested() method must be called
1176  * to complete creation of the nested @c Structure.
1177  * @param name nested structure name.
1178  * @return a new instance of a @c FieldBuilder is returned.
1179  * @see #endNested()
1180  */
1182 
1183  /**
1184  * Add new nested @c Union[].
1185  * endNested() method must be called
1186  * to complete creation of the nested @c Union.
1187  * @param name nested union name.
1188  * @return a new instance of a @c FieldBuilder is returned.
1189  * @see #endNested()
1190  */
1192 
1193  /**
1194  * Complete the creation of a nested object.
1195  * @see #addNestedStructure(std::string const & name)
1196  * @see #addNestedUnion(std::string const & name)
1197  * @return a previous (parent) @c FieldBuilder.
1198  */
1200 
1201 private:
1202  FieldBuilder();
1203  FieldBuilder(const Structure*);
1206  FieldBuilder(const FieldBuilderPtr & _parentBuilder, const std::string& name, const Union*);
1209  std::string const & nestedName,
1211 
1212  const Field *findField(const std::string& name, Type ftype);
1213 
1214  void reset();
1216 
1217  friend class FieldCreate;
1218 
1220 
1221  std::string id;
1222  bool idSet;
1223 
1226 
1228  const Type nestedClassToBuild;
1229  const std::string nestedName;
1230  const bool nestedArray;
1231  const bool createNested; // true - endNested() creates in parent, false - endNested() appends to parent
1232 };
1233 
1234 namespace detail {
1235 struct field_factory;
1236 }
1237 
1238 /**
1239  * @brief This is a singleton class for creating introspection interfaces.
1240  *
1241  */
1242 class epicsShareClass FieldCreate {
1243  friend struct detail::field_factory;
1244 public:
1245  static const FieldCreatePtr &getFieldCreate();
1246  /**
1247  * Create a new instance of in-line @c Field builder.
1248  * @return a new instance of a @c FieldBuilder.
1249  */
1251  /**
1252  * Create a new instance of in-line @c Field builder pre-initialized with and existing Structure
1253  * @return a new instance of a @c FieldBuilder.
1254  */
1256  /**
1257  * Create a @c ScalarField.
1258  * @param scalarType The scalar type.
1259  * @return a @c Scalar interface for the newly created object.
1260  * @throws IllegalArgumentException if an illegal type is specified.
1261  */
1263  /**
1264  * Create a @c BoundedString.
1265  * @param maxLength a string maximum length.
1266  * @return a @c BoundedString interface for the newly created object.
1267  * @throws IllegalArgumentException if maxLength == 0.
1268  */
1270  /**
1271  * Create an @c Array field, variable size array.
1272  * @param elementType The @c ScalarType for array elements
1273  * @return An @c Array Interface for the newly created object.
1274  */
1276  /*
1277  * Create an @c Array field, fixed size array.
1278  * @param elementType The @c ScalarType for array elements
1279  * @param size Fixed array size.
1280  * @return An @c Array Interface for the newly created object.
1281  */
1283  /**
1284  * Create an @c Array field, bounded size array.
1285  * @param elementType The @c ScalarType for array elements
1286  * @param bound Array maximum capacity.
1287  * @return An @c Array Interface for the newly created object.
1288  */
1290  /**
1291  * Create an @c Array field that is has element type @c Structure
1292  * @param structure The @c Structure for each array element.
1293  * @return An @c Array Interface for the newly created object.
1294  */
1296  /**
1297  * Create a @c Structure field.
1298  * @return a @c Structure interface for the newly created object.
1299  */
1301  /**
1302  * Create a @c Structure field.
1303  * @param fieldNames the names of the fields for the structure.
1304  * @param fields The array of @c Field objects for the structure.
1305  * @return a @c Structure interface for the newly created object.
1306  */
1308  StringArray const & fieldNames,
1309  FieldConstPtrArray const & fields) const;
1310  /**
1311  * Create a @c Structure field with identification string.
1312  * @param id The identification string for the structure.
1313  * @param fieldNames the names of the fields for the structure.
1314  * @param fields The array of @c Field objects for the structure.
1315  * @return a @c Structure interface for the newly created object.
1316  */
1318  std::string const & id,
1319  StringArray const & fieldNames,
1320  FieldConstPtrArray const & fields) const;
1321  /**
1322  * Create an @c Array field that is has element type @c Union
1323  * @param punion The @c Union for each array element.
1324  * @return An @c Array Interface for the newly created object.
1325  */
1327  /**
1328  * Create a variant @c UnionArray (aka any type) field.
1329  * @return a @c UnionArray interface for the newly created object.
1330  */
1332  /**
1333  * Create a variant @c Union (aka any type) field.
1334  * @return a @c Union interface for the newly created object.
1335  */
1337  /**
1338  * Create a @c Union field.
1339  * @param fieldNames the names of the fields for the union.
1340  * @param fields The @c Field for each fields for the union.
1341  * @return a @c Union interface for the newly created object.
1342  */
1344  StringArray const & fieldNames,
1345  FieldConstPtrArray const & fields) const;
1346  /**
1347  * Create a @c Union field with identification string.
1348  * @param id The identification string for the union.
1349  * @param fieldNames the names of the fields for the union.
1350  * @param fields The array of @c Field objects for the union.
1351  * @return a @c Union interface for the newly created object.
1352  */
1354  std::string const & id,
1355  StringArray const & fieldNames,
1356  FieldConstPtrArray const & fields) const;
1357  /**
1358  * Append a field to a structure.
1359  * @param structure The structure to which the field is appended.
1360  * @param fieldName The name of the field.
1361  * @param field The field.
1362  * @return a @c Structure interface for the newly created object.
1363  */
1365  StructureConstPtr const & structure,
1366  std::string const & fieldName, FieldConstPtr const & field) const;
1367  /**
1368  * Append fields to a structure.
1369  * @param structure The structure to which the fields appended.
1370  * @param fieldNames The names of the fields.
1371  * @param fields The fields.
1372  * @return a @c Structure interface for the newly created object.
1373  */
1375  StructureConstPtr const & structure,
1376  StringArray const & fieldNames,
1377  FieldConstPtrArray const & fields) const;
1378  /**
1379  * Deserialize @c Field instance from given byte buffer.
1380  * @param buffer Buffer containing serialized @c Field instance.
1381  * @param control Deserialization control instance.
1382  * @return a deserialized @c Field instance.
1383  */
1385 
1386 private:
1387  FieldCreate();
1388 
1389  // const after ctor
1394 
1395  mutable Mutex mutex;
1396  typedef std::multimap<unsigned int, Field*> cache_t;
1397  mutable cache_t cache;
1398 
1399  struct Helper;
1400  friend class Field;
1402 };
1403 
1404 /**
1405  * Get the single class that implements FieldCreate,
1406  * @return The fieldCreate factory.
1407  */
1408 FORCE_INLINE const FieldCreatePtr& getFieldCreate() {
1409  return FieldCreate::getFieldCreate();
1410 }
1411 
1412 /** Define a compile time mapping from
1413  * type to enum value.
1414  @code
1415  ScalarType code = (ScalarType)ScalarTypeID<int8>::value;
1416  assert(code==pvByte);
1417  @endcode
1418  *
1419  * For unspecified types this evaluates to an invalid ScalarType
1420  * value (eg -1).
1421  */
1422 template<typename T>
1423 struct ScalarTypeID {};
1424 
1425 /**
1426  * Static mapping from ScalarType enum to value type.
1427  @code
1428  typename ScalarTypeTraits<pvByte>::type value = 4;
1429  @endcode
1430  */
1431 template<ScalarType ID>
1433 
1434 #define OP(ENUM, TYPE) template
1435  <> struct ScalarTypeTraits<ENUM> {typedef TYPE type;}; template
1436  <> struct ScalarTypeID<TYPE> { enum {value=ENUM}; }; template
1437  <> struct ScalarTypeID<const TYPE> { enum {value=ENUM}; };
1438 
1448 OP(pvFloat, float)
1449 OP(pvDouble, double)
1450 OP(pvString, std::string)
1451 #undef OP
1452 
1453 bool epicsShareExtern compare(const Field&, const Field&);
1454 bool epicsShareExtern compare(const Scalar&, const Scalar&);
1455 bool epicsShareExtern compare(const ScalarArray&, const ScalarArray&);
1456 bool epicsShareExtern compare(const Structure&, const Structure&);
1457 bool epicsShareExtern compare(const StructureArray&, const StructureArray&);
1458 bool epicsShareExtern compare(const Union&, const Union&);
1459 bool epicsShareExtern compare(const UnionArray&, const UnionArray&);
1460 bool epicsShareExtern compare(const BoundedString&, const BoundedString&);
1461 
1462 /** Equality with other Field
1463  *
1464  * The creation process of class FieldCreate ensures that identical field definitions
1465  * will share the same instance. So pointer equality is sufficient to show defintion
1466  * equality. If in doubt, compare() will do an full test.
1467  */
1468 #define MAKE_COMPARE(CLASS) static
1469  FORCE_INLINE bool operator==(const CLASS& a, const CLASS& b) {return (void*)&a==(void*)&b;} static
1470  FORCE_INLINE bool operator!=(const CLASS& a, const CLASS& b) {return !(a==b);}
1471 
1472 MAKE_COMPARE(Field)
1473 MAKE_COMPARE(Scalar)
1474 MAKE_COMPARE(ScalarArray)
1475 MAKE_COMPARE(Structure)
1476 MAKE_COMPARE(StructureArray)
1477 MAKE_COMPARE(Union)
1478 MAKE_COMPARE(UnionArray)
1479 MAKE_COMPARE(BoundedString)
1480 
1481 #undef MAKE_COMPARE
1482 }}
1483 
1484 /**
1485  * stream support for Field
1486  */
1487 namespace std{
1488  epicsShareExtern std::ostream& operator<<(std::ostream& o, const epics::pvData::Field *ptr);
1489 }
1490 
1491 #endif /* PVINTROSPECT_H */
std::tr1::shared_ptr< const StructureArray > StructureArrayConstPtr
Definition: pvIntrospect.h:158
#define PVD_DEPRECATED(msg)
Definition: serialize.h:24
Definition: pvData.h:1662
#define FINAL
Definition: pvIntrospect.h:43
std::tr1::shared_ptr< const Structure > StructureConstPtr
Definition: pvIntrospect.h:154
epicsShareExtern const char * name(Type type)
This class implements introspection object for Array.
Definition: pvIntrospect.h:454
This class implements introspection object for a structureArray.
Definition: pvIntrospect.h:599
This class implements introspection object for field.
Definition: pvIntrospect.h:328
std::tr1::shared_ptr< const UnionArray > UnionArrayConstPtr
Definition: pvIntrospect.h:166
This class implements introspection object for bounded scalar array.
Definition: pvIntrospect.h:567
#define POINTER_DEFINITIONS(clazz)
Definition: sharedPtr.h:198
std::tr1::shared_ptr< const Field > FieldConstPtr
Definition: pvIntrospect.h:129
This class implements introspection object for a union.
Definition: pvIntrospect.h:858
This is a singleton class for creating introspection interfaces.
This class implements introspection object for Scalar.
Definition: pvIntrospect.h:389
std::tr1::shared_ptr< const Union > UnionConstPtr
Definition: pvIntrospect.h:162
This class implements introspection object for a unionArray.
Definition: pvIntrospect.h:644
epicsShareFunc shared_vector< void > allocArray(ScalarType id, size_t len)
Allocate an untyped array based on ScalarType.
This class implements introspection object for scalar array.
Definition: pvIntrospect.h:489
#define FORCE_INLINE
Definition: templateMeta.h:20
#define PVD_DEPRECATED_52
Definition: pvIntrospect.h:27
#define MAKE_COMPARE(CLASS)
This class implements introspection object for BoundedString.
Definition: pvIntrospect.h:429
#define EPICS_NOT_COPYABLE(CLASS)
Disable implicit copyable.
std::vector< FieldConstPtr > FieldConstPtrArray
Definition: pvIntrospect.h:138
epicsShareFunc bool yajl_parse_helper(std::istream &src, yajl_handle handle)
std::tr1::shared_ptr< const ScalarArray > ScalarArrayConstPtr
Definition: pvIntrospect.h:150
const FieldCreatePtr & getFieldCreate()
std::tr1::shared_ptr< const Scalar > ScalarConstPtr
Definition: pvIntrospect.h:142
Interface for in-line creating of introspection interfaces.
This class implements introspection object for bounded scalar array.
Definition: pvIntrospect.h:535
This class implements introspection object for a structure.
Definition: pvIntrospect.h:689
std::tr1::shared_ptr< const Array > ArrayConstPtr
Definition: pvIntrospect.h:146
#define OVERRIDE
Definition: pvIntrospect.h:50
std::tr1::shared_ptr< const BoundedString > BoundedStringConstPtr
Definition: pvIntrospect.h:170
#define OP(ENUM, TYPE)