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