PVData C++  8.0.5
createRequest.h
1 /*createRequest.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 #ifndef CREATEREQUEST_H
8 #define CREATEREQUEST_H
9 #include <string>
10 #include <sstream>
11 #include <vector>
12 
13 #include <pv/pvData.h>
14 #include <pv/lock.h>
15 #include <pv/bitSet.h>
16 
17 #include <shareLib.h>
18 
19 namespace epics { namespace pvData {
20 
21 class BitSet;
22 
23 /**
24  * @brief Create pvRequest structure for Channel methods.
25  *
26  * Many methods of the Channel class of pvAccess have an
27  * argument <b>PVStructurePtr const * pvRequest</b>.
28  * This class provides a method that creates a valid pvRequest.
29  *
30  */
31 class epicsShareClass CreateRequest {
32  public:
34  /**
35  * Create s new instance of CreateRequest
36  * @returns A shared pointer to the new instance.
37  */
39  ~CreateRequest() {};
40  /**
41  * Create a request structure for the create calls in Channel.
42  * See the package overview documentation for details.
43  * @param request The field request. See the package overview documentation for details.
44  * @return The request PVStructure if a valid request was given.
45  * If a NULL PVStructure is returned then getMessage will return
46  * the reason.
47  */
49  /**
50  * Get the error message of createRequest returns NULL
51  * return the error message
52  */
54 protected:
55  CreateRequest() {}
57 };
58 
59 /** Parse and build pvRequest structure.
60  *
61  @params request the Request string to be parsed. eg. "field(value)"
62  @returns The resulting strucuture. Never NULL
63  @throws std::exception for various parsing errors
64  */
67 
68 /** Helper for implementations of epics::pvAccess::ChannelProvider in interpreting the
69  * 'field' substructure of a pvRequest.
70  * Copies between an internal (base) Structure, and a client/user visible (requested) Structure.
71  *
72  * @note PVRequestMapper is not re-entrant. It is copyable and swap()able.
73  */
74 class epicsShareClass PVRequestMapper {
75 public:
76  enum mode_t {
77  /** Masking mode.
78  *
79  * Requested Structure is identical to Base.
80  * The 'field' substructure of the provided pvRequest is used to construct a BitSet
81  * where the bits corresponding to the "selected" fields are set. This mask can be
82  * access via. requestedMask(). The copy* and mask* methods operate only
83  * on "selected" fields.
84  */
86  /** Slice mode
87  *
88  * The Requested Structure is a strict sub-set of the Base Structure containing
89  * those fields "selected" by the 'field' substructure of the provided pvRequest.
90  */
92  };
93 
95  //! @see compute()
97  const PVStructure& pvRequest,
98  mode_t mode = Mask);
99 
100  //! return to state of default ctor
101  void reset();
102 
103  //! @returns the Structure of the PVStructure previously passed to compute(). NULL if never computed()'d
104  inline const StructureConstPtr& base() const { return typeBase; }
105  //! @returns the Structure which is the selected sub-set of the base Structure. NULL if never computed()'d
106  inline const StructureConstPtr& requested() const { return typeRequested; }
107 
108  /** A mask of all fields in the base structure which are also in the requested structure,
109  * and any parent/structure "compress" bits. eg. bit 0 is always set.
110  *
111  @code
112  PVRequestMapper mapper(...);
113  ...
114  BitSet changed = ...; // a base changed mask
115  bool wouldcopy = changed.logical_and(mapper.requestedMask());
116  // wouldcopy==false means that copyBaseToRequested(..., changed, ...) would be a no-op
117  @endcode
118  *
119  * eg. allows early detection of empty monitor updates.
120  */
121  inline const BitSet& requestedMask() const { return maskRequested; }
122 
123  //! @returns A new instance of the requested() Structure
125  //! @returns A new instance of the base() Structure
126  PVStructurePtr buildBase() const;
127 
128  /** (re)compute the selected subset of provided base structure.
129  * @param base A full base structure.
130  * Must be "top level" (field offset zero).
131  * @param pvRequest The user/client provided request modifier
132  * @param mode Control how the mapping is constructed. @see mode_t for a description of mapping modes.
133  *
134  * @post Updates warnings()
135  * @throws std::runtime_error For errors involving invalid pvRequest
136  * @throws std::logic_error if the provided base is not a "top level" PVStructure.
137  */
138  void compute(const PVStructure& base,
139  const PVStructure& pvRequest,
140  mode_t mode = Mask);
141 
142  //! After compute(), check if !warnings().empty()
143  inline const std::string& warnings() const { return messages; }
144 
145  /** Copy field values from Base structure into Requested structure
146  *
147  * @param base An instance of the base Structure. Field values are copied from it.
148  * Need not be the same instance passed to compute().
149  * @param baseMask A bit mask selecting those base fields to copy.
150  * @param request An instance of the requested() Structure. Field values are copied to it.
151  * @param requestMask A bit mask indicating which requested fields were copied.
152  * BitSet::clear() is not called.
153  */
154  void copyBaseToRequested(
155  const PVStructure& base,
156  const BitSet& baseMask,
159  ) const;
160 
161  /** Copy field values into Base structure from Requested structure
162  *
163  * @param base An instance of the base Structure. Field values are copied into it.
164  * Need not be the same instance passed to compute().
165  * @param baseMask A bit mask indicating which base fields were copied.
166  * BitSet::clear() is not called.
167  * @param request An instance of the requested() Structure. Field values are copied from it.
168  * @param requestMask A bit mask selecting those requested fields to copy.
169  */
171  PVStructure& base,
172  BitSet& baseMask,
173  const PVStructure& request,
174  const BitSet& requestMask
175  ) const;
176 
177  //! Translate Base bit mask into requested bit mask.
178  //! BitSet::clear() is not called.
179  inline void maskBaseToRequested(
180  const BitSet& baseMask,
182  ) const
183  { _mapMask(baseMask, requestMask, false); }
184 
185  //! Translate requested bit mask into base bit mask.
186  //! BitSet::clear() is not called.
188  BitSet& baseMask,
189  const BitSet& requestMask
190  ) const
191  { _mapMask(requestMask, baseMask, true); }
192 
193  //! Exchange contents of two mappers. O(0) and never throws.
194  void swap(PVRequestMapper& other);
195 
196 private:
197  bool _compute(const PVStructure& base, const PVStructure& pvReq,
198  FieldBuilderPtr& builder, bool keepids, unsigned depth);
199 
200  void _map(const PVStructure& src,
201  const BitSet& maskSrc,
202  PVStructure& dest,
203  BitSet& maskDest,
204  bool dir_r2b) const;
205  void _mapMask(const BitSet& maskSrc,
206  BitSet& maskDest,
207  bool dir_r2b) const;
208 
211  // Map between field offsets of base and requested Structures.
212  // Include all fields, both leaf and sub-structure.
213  struct Mapping {
214  size_t to; // offset in destination Structure
215  BitSet tomask, // if !leaf these are the other bits in the destination mask to changed
216  frommask; // if !leaf these are the other bits in the source mask to be copied
217  bool valid; // only true in (sparse) base -> requested mapping
218  bool leaf; // not a (sub)Structure?
219  Mapping() :valid(false) {}
220  Mapping(size_t to, bool leaf) :to(to), valid(true), leaf(leaf) {}
221  };
222  typedef std::vector<Mapping> mapping_t;
224 
226 
227  mutable BitSet scratch; // avoid temporary allocs. (we aren't re-entrant!)
228 };
229 
230 }}
231 
232 #endif /* CREATEREQUEST_H */
#define POINTER_DEFINITIONS(clazz)
Definition: sharedPtr.h:198
epicsShareFunc bool yajl_parse_helper(std::istream &src, yajl_handle handle)
Create pvRequest structure for Channel methods.
Definition: createRequest.h:31