1 #ifndef TAG_INFO_HPP
2 #define TAG_INFO_HPP
3 
4 #include "moab/Range.hpp"
5 #include <string>
6 
7 namespace moab {
8 
9 class SequenceManager;
10 class Range;
11 class Error;
12 
13 // ! stores information about a tag
14 class TagInfo
15 {
16 public:
17 
18   //! constructor
TagInfo()19   TagInfo() : mDefaultValue(NULL),
20               mMeshValue(NULL),
21               mDefaultValueSize(0),
22               mMeshValueSize(0),
23               mDataSize(0),
24               dataType(MB_TYPE_OPAQUE)
25               {}
26 
27   //! constructor that takes all parameters
28   TagInfo( const char * name,
29            int size,
30            DataType type,
31            const void * default_value,
32            int default_value_size);
33 
34   virtual ~TagInfo();
35 
36   /**\brief Remove/clear tag data for all entities
37    *
38    * Remove tag values from entities.
39    *
40    *\param tag_delete_pending  If true, then release any global
41    *          data associated with the tag in preparation for deleting
42    *          the tag itself.
43    *
44    *\Note Invalidates tag if \c tag_delete_pending is true.  The only
45    *        valid method that can be invoked that is is the destructor.
46    *
47    *\param seqman    Pointer to mesh entity database
48    */
49   virtual ErrorCode release_all_data( SequenceManager* seqman,
50                                       Error* error_handler,
51                                       bool tag_delete_pending ) = 0;
52 
53   //! set the name of the tag
set_name(const std::string & name)54   void set_name( const std::string& name) { mTagName = name; }
55 
56   //! get the name of the tag
get_name() const57   const std::string& get_name() const { return mTagName; }
58 
59     //! get length of default value
get_default_value_size() const60   int get_default_value_size() const { return mDefaultValueSize; }
61 
62     //! get the default data
get_default_value() const63   const void *get_default_value() const { return mDefaultValue; }
64 
65     //! compare the passed value to the default value.
66     //! returns false if no default value.
67   bool equals_default_value( const void* data, int size = -1 ) const;
68 
get_data_type() const69   inline DataType get_data_type() const     { return dataType; }
70 
71   //! get the size of the data in bytes
get_size() const72   int get_size() const { return mDataSize; }
73 
74   //! Check if variable-length tag
variable_length() const75   bool variable_length() const { return get_size() == MB_VARIABLE_LENGTH; }
76 
77   static int size_from_data_type( DataType t );
78 
79     // Check that all lengths are valid multiples of the type size.
80     // Returns true if all lengths are valid, false otherwise.
81   bool check_valid_sizes( const int* sizes, int num_sizes ) const;
82 
83     /**\return MB_VARIABLE_LENGTH_DATA If variable_length() && lengths is NULL
84      *         MB_INVALID_SIZE         If variable_length() && lengths is not
85      *                                 NULL && any size is not a multiple of
86      *                                 type size.
87      *         MB_INVALID_SIZE         If !variable_length() && lengths is not
88      *                                 NULL && any size is not the tag size.
89      *         MB_SUCCESS              Otherwise.
90      */
91   ErrorCode validate_lengths( Error* error_handler,
92                               const int* lengths,
93                               size_t num_lengths ) const;
94 
95   virtual
96   TagType get_storage_type() const = 0;
97 
98   /**\brief Get tag value for passed entities
99    *
100    * Get tag values for specified entities.
101    *
102    *\Note Will fail for variable-length data.
103    *\param seqman Pointer to mesh entity database
104    *\param entities Entity handles for which to retrieve tag data
105    *\param num_entities Length of \c entities array
106    *\param data Pointer to memory in which to store consecutive tag values,
107    *            one for each passed entity.
108    */
109   virtual
110   ErrorCode get_data( const SequenceManager* seqman,
111                       Error* error_handler,
112                       const EntityHandle* entities,
113                       size_t num_entities,
114                       void* data ) const = 0;
115 
116   /**\brief Get tag value for passed entities
117    *
118    * Get tag values for specified entities.
119    *
120    *\Note Will fail for variable-length data.
121    *\param seqman Pointer to mesh entity database
122    *\param entities Entity handles for which to retrieve tag data
123    *\param data Pointer to memory in which to store consecutive tag values,
124    *            one for each passed entity.
125    */
126   virtual
127   ErrorCode get_data( const SequenceManager* seqman,
128                       Error* error_handler,
129                       const Range& entities,
130                       void* data ) const = 0;
131 
132   /**\brief Get tag value for passed entities
133    *
134    * Get tag values for specified entities.
135    *
136    *\param seqman    Pointer to mesh entity database
137    *\param entities  Entity handles for which to retrieve tag data
138    *\param num_entities Length of \c entities array
139    *\param data_ptrs Array of pointers to tag values, one pointer
140    *                 for each passed entity.
141    *\param data_lengths One value for each entity specifying the
142    *                length of the tag value for the corresponding
143    *                entity.
144    */
145   virtual
146   ErrorCode get_data( const SequenceManager* seqman,
147                       Error* error_handler,
148                       const EntityHandle* entities,
149                       size_t num_entities,
150                       const void** data_ptrs,
151                       int* data_lengths ) const = 0;
152 
153 
154   /**\brief Get tag value for passed entities
155    *
156    * Get tag values for specified entities.
157    *
158    *\param seqman    Pointer to mesh entity database
159    *\param entities  Entity handles for which to retrieve tag data
160    *\param data_ptrs Array of pointers to tag values, one pointer
161    *                 for each passed entity.
162    *\param data_lengths One value for each entity specifying the
163    *                length of the tag value for the corresponding
164    *                entity.
165    */
166   virtual
167   ErrorCode get_data( const SequenceManager* seqman,
168                       Error* error_handler,
169                       const Range& entities,
170                       const void** data_ptrs,
171                       int* data_lengths ) const = 0;
172 
173   /**\brief Set tag value for passed entities
174    *
175    * Store tag data or update stored tag values
176    *\Note Will fail for variable-length data.
177    *\param seqman Pointer to mesh entity database
178    *\param entities Entity handles for which to store tag data
179    *\param num_entities Length of \c entities array
180    *\param data Pointer to memory holding consecutive tag values,
181    *            one for each passed entity.
182    */
183   virtual
184   ErrorCode set_data( SequenceManager* seqman,
185                       Error* error_handler,
186                       const EntityHandle* entities,
187                       size_t num_entities,
188                       const void* data ) = 0;
189 
190   /**\brief Set tag value for passed entities
191    *
192    * Store tag data or update stored tag values
193    *\Note Will fail for variable-length data.
194    *\param seqman Pointer to mesh entity database
195    *\param entities Entity handles for which to store tag data
196    *\param data Pointer to memory holding consecutive tag values,
197    *            one for each passed entity.
198    */
199   virtual
200   ErrorCode set_data( SequenceManager* seqman,
201                       Error* error_handler,
202                       const Range& entities,
203                       const void* data ) = 0;
204 
205   /**\brief Set tag value for passed entities
206    *
207    * Store tag data or update stored tag values
208    *
209    *\param seqman    Pointer to mesh entity database
210    *\param entities  Entity handles for which to store tag data
211    *\param num_entities Length of \c entities array
212    *\param data_ptrs Array of pointers to tag values, one pointer
213    *                 for each passed entity.
214    *\param data_lengths One value for each entity specifying the
215    *                length of the tag value for the corresponding
216    *                entity.  Array is required for variable-length
217    *                tags and is ignored for fixed-length tags.
218    */
219   virtual
220   ErrorCode set_data( SequenceManager* seqman,
221                       Error* error_handler,
222                       const EntityHandle* entities,
223                       size_t num_entities,
224                       void const* const* data_ptrs,
225                       const int* data_lengths ) = 0;
226 
227 
228   /**\brief Set tag value for passed entities
229    *
230    * Store tag data or update stored tag values
231    *
232    *\param seqman    Pointer to mesh entity database
233    *\param entities  Entity handles for which to store tag data
234    *\param data_ptrs Array of pointers to tag values, one pointer
235    *                 for each passed entity.
236    *\param data_lengths One value for each entity specifying the
237    *                length of the tag value for the corresponding
238    *                entity.  Array is required for variable-length
239    *                tags and is ignored for fixed-length tags.
240    */
241   virtual
242   ErrorCode set_data( SequenceManager* seqman,
243                       Error* error_handler,
244                       const Range& entities,
245                       void const* const* data_ptrs,
246                       const int* data_lengths ) = 0;
247 
248   /**\brief Set tag value for passed entities
249    *
250    * Store tag data or update stored tag values.
251    *
252    *\param seqman    Pointer to mesh entity database
253    *\param entities  Entity handles for which to store tag data
254    *\param num_entities Length of \c entities array
255    *\param value_ptr Pointer to a single tag value which is to be
256    *                 stored for each of the passed entities.
257    *\param value_len Length of tag value in bytes.  Ignored for
258    *                 fixed-length tags.  Required for variable-
259    *                 length tags.
260    */
261   virtual
262   ErrorCode clear_data( SequenceManager* seqman,
263                         Error* error_handler,
264                         const EntityHandle* entities,
265                         size_t num_entities,
266                         const void* value_ptr,
267                         int value_len = 0 ) = 0;
268 
269   /**\brief Set tag value for passed entities
270    *
271    * Store tag data or update stored tag values.
272    *
273    *\param seqman    Pointer to mesh entity database
274    *\param entities  Entity handles for which to store tag data
275    *\param value_ptr Pointer to a single tag value which is to be
276    *                 stored for each of the passed entities.
277    *\param value_len Length of tag value in bytes.  Ignored for
278    *                 fixed-length tags.  Required for variable-
279    *                 length tags.
280    */
281   virtual
282   ErrorCode clear_data( SequenceManager* seqman,
283                         Error* error_handler,
284                         const Range& entities,
285                         const void* value_ptr,
286                         int value_len = 0 ) = 0;
287 
288   /**\brief Remove/clear tag data for entities
289    *
290    * Remove tag values from entities.
291    *
292    *\param seqman    Pointer to mesh entity database
293    *\param entities  Entity handles for which to store tag data
294    *\param num_entities Length of \c entities array
295    */
296   virtual ErrorCode remove_data( SequenceManager* seqman,
297                                  Error* error_handler,
298                                  const EntityHandle* entities,
299                                  size_t num_entities ) = 0;
300 
301   /**\brief Remove/clear tag data for entities
302    *
303    * Remove tag values from entities.
304    *
305    *\param seqman    Pointer to mesh entity database
306    *\param entities  Entity handles for which to store tag data
307    */
308   virtual ErrorCode remove_data( SequenceManager* seqman,
309                                  Error* error_handler,
310                                  const Range& entities ) = 0;
311 
312   /**\brief Access tag data via direct pointer into contiguous blocks
313    *
314    * Iteratively obtain direct access to contiguous blocks of tag
315    * storage.  This function cannot be used with bit tags because
316    * of the compressed bit storage.  This function cannot be used
317    * with variable length tags because it does not provide a mechanism
318    * to determine the length of the value for each entity.  This
319    * function may be used with sparse tags, but if it is used, it
320    * will return data for a single entity at a time.
321    *
322    *\param iter        As input, the first entity for which to return
323    *                   data.  As output, one past the last entity for
324    *                   which data was returned.
325    *\param end         One past the last entity for which data is desired
326    *\param data_ptr    Output: pointer to tag storage.
327    *\param allocate    If true, space for this tag will be allocated, if not it wont
328    *
329    *\Note If this function is called for entities for which no tag value
330    *      has been set, but for which a default value exists, it will
331    *      force the allocation of explicit storage for each such entity
332    *      even though MOAB would normally not explicitly store tag values
333    *      for such entities.
334    */
335   virtual
336   ErrorCode tag_iterate( SequenceManager* seqman,
337                          Error* error_handler,
338                          Range::iterator& iter,
339                          const Range::iterator& end,
340                          void*& data_ptr,
341                          bool allocate = true) = 0;
342 
343   /**\brief Get all tagged entities
344    *
345    * Get the list of entities for which the a tag value has been set,
346    * or a close approximation if the tag storage scheme cannot
347    * accurately determine exactly which entities have explicit values.
348    *
349    *\param seqman   Pointer to entity storage database
350    *\param output_entities Results *appended* to this range
351    *\param type     Optional entity type.  If specified, search is
352    *                limited to entities of specified type.
353    *\param intersect Optional intersect list.  If specified,
354    *                search is restricted to entities in this list.
355    */
356   virtual
357   ErrorCode get_tagged_entities( const SequenceManager* seqman,
358                                  Range& output_entities,
359                                  EntityType type = MBMAXTYPE,
360                                  const Range* intersect = 0 ) const = 0;
361 
362   /**\brief Count all tagged entities
363    *
364    * Count the entities for which the a tag value has been set,
365    * or a close approximation if the tag storage scheme cannot
366    * accurately determine exactly which entities have explicit values.
367    *
368    *\param seqman   Pointer to entity storage database
369    *\param output_count This is *incremented* for each detected entity.
370    *\param type     Optional entity type.  If specified, search is
371    *                limited to entities of specified type.
372    *\param intersect Optional intersect list.  If specified,
373    *                search is restricted to entities in this list.
374    */
375   virtual
376   ErrorCode num_tagged_entities( const SequenceManager* seqman,
377                                  size_t& output_count,
378                                  EntityType type = MBMAXTYPE,
379                                  const Range* intersect = 0 ) const = 0;
380 
381   /**\brief Get all tagged entities with tag value
382    *
383    * Get the list of entities which have the specified tag value.
384    *
385    *\param seqman   Pointer to entity storage database
386    *\param output_entities Results *appended* to this range
387    *\param value    Pointer to tag value
388    *\param value_bytes Size of tag value in bytes.
389    *\param type     Optional entity type.  If specified, search is
390    *                limited to entities of specified type.
391    *\param intersect_entities Optional intersect list.  If specified,
392    *                search is restricted to entities in this list.
393    */
394   virtual
395   ErrorCode find_entities_with_value( const SequenceManager* seqman,
396                                       Error* error_handler,
397                                       Range& output_entities,
398                                       const void* value,
399                                       int value_bytes = 0,
400                                       EntityType type = MBMAXTYPE,
401                                       const Range* intersect_entities = 0 ) const = 0;
402 
403   /**\brief Check if entity is tagged */
404   virtual
405   bool is_tagged( const SequenceManager* seqman, EntityHandle entity ) const = 0;
406 
407   /**\brief Get memory use for tag data.
408    *
409    */
410   virtual
411   ErrorCode get_memory_use( const SequenceManager* seqman,
412                             unsigned long& total,
413                             unsigned long& per_entity ) const = 0;
414 
415 protected:
416 
get_memory_use() const417   unsigned long get_memory_use() const
418   {
419     return get_default_value_size() + get_name().size();
420   }
421 
422 private:
423 
424   TagInfo( const TagInfo& copy );
425 
426   TagInfo& operator=( const TagInfo& copy );
427 
428   //! stores the default data, if any
429   void* mDefaultValue;
430 
431   //! store the mesh value, if any
432   void* mMeshValue;
433 
434   //! Size of mDefaultValue and mMeshValue, in bytes
435   //! NOTE: These sizes differ from mDataSize in two cases:
436   //!    a) Variable-length tags
437   //!    b) Bit tags (where mDataSize is bits, not bytes.)
438   int mDefaultValueSize, mMeshValueSize;
439 
440   //! stores the size of the data for this tag
441   int mDataSize;
442 
443   //! type of tag data
444   DataType dataType;
445 
446   //! stores the tag name
447   std::string mTagName;
448 };
449 
450 } // namespace moab
451 
452 #endif // TAG_INFO_HPP
453