[MOAB-dev] r1576 - MOAB/trunk

kraftche at mcs.anl.gov kraftche at mcs.anl.gov
Fri Feb 1 17:37:36 CST 2008


Author: kraftche
Date: 2008-02-01 17:37:36 -0600 (Fri, 01 Feb 2008)
New Revision: 1576

Modified:
   MOAB/trunk/MBCore.cpp
   MOAB/trunk/MBInterface.hpp
   MOAB/trunk/SequenceData.cpp
   MOAB/trunk/SequenceManager.cpp
   MOAB/trunk/SequenceManager.hpp
   MOAB/trunk/SparseTagCollection.cpp
   MOAB/trunk/SparseTagCollection.hpp
   MOAB/trunk/SparseTagSuperCollection.cpp
   MOAB/trunk/SparseTagSuperCollection.hpp
   MOAB/trunk/TagInfo.hpp
   MOAB/trunk/TagServer.cpp
   MOAB/trunk/TagServer.hpp
Log:
o Add support for variable-length tags (no I/O yet)

o Add API to get/set tag values as lists of pointers to per-entity values.

o Fix handling of default value for tags on mesh.


New APIs:

tag_create_variable_length(..) 
  - need extra argument for length of default value
  - old tag_create w/ size == MB_VARIABLE_LENGTH can also be used if no 
    default value.

tag_get_default_value( MBTag, const void*&, int& size ) const
  - get reference to internal storage for tag default value
  - passes back size of tag value also
  - old tag_get_default_value cannot be used for variable-length tags
  - new tag_get_default_value can be used for fixed- or variable-length tags

tag_get_data( MBTag, const MBEntityHandle*, int, const void** data, int* sizes = 0 )
tag_get_data( MBTag, const MBRange&,             const void** data, int* sizes = 0 )
  - get pointers to internal storage for each tag value
  - get size (in bytes) for each tag value
  - 'sizes' is optional for fixed-length tags, but will be set appropriately 
    if passed.
  - 'sizes' is mandatory for variable-length tags

tag_set_data( MBTag, const MBEntityHandle*, int, void const* const* data, int* sizes = 0 )
tag_set_data( MBTag, const MBRange&,             void const* const* data, int* sizes = 0 )
  - set tag data given separate pointers to each tag value
  - 'sizes' is optional for fixed-length tags, but will be set appropriately 
     if passed.
  - 'sizes' is mandatory for variable-length tags
  - if 'sizes' is specified for fixed-length tags, it must contain the correct
    values (same value for every entity.)


Modified: MOAB/trunk/MBCore.cpp
===================================================================
--- MOAB/trunk/MBCore.cpp	2008-02-01 22:53:46 UTC (rev 1575)
+++ MOAB/trunk/MBCore.cpp	2008-02-01 23:37:36 UTC (rev 1576)
@@ -1388,6 +1388,69 @@
   return tagServer->set_data(tag_handle, entity_handles, tag_data);
 }
 
+
+//! return the tag data for a given EntityHandle and MBTag
+MBErrorCode  MBCore::tag_get_data( const MBTag tag_handle, 
+                                   const MBEntityHandle* entity_handles, 
+                                   const int num_entities,
+                                   const void** tag_data,
+                                   int* tag_sizes ) const
+{
+  if (NULL == entity_handles && 0 == num_entities) {
+    int size;
+    return tagServer->get_mesh_data(tag_handle, tag_data, tag_sizes ? *tag_sizes : size );
+  }
+
+  else return tagServer->get_data(tag_handle, entity_handles, num_entities, tag_data, tag_sizes);
+}
+
+//! return the tag data for a given EntityHandle and MBTag
+MBErrorCode  MBCore::tag_get_data( const MBTag tag_handle, 
+                                   const MBRange& entity_handles,
+                                   const void** tag_data,
+                                   int* tag_sizes ) const
+{
+  return tagServer->get_data(tag_handle, entity_handles, tag_data, tag_sizes );
+}
+
+//! set the data  for given EntityHandles and MBTag
+MBErrorCode  MBCore::tag_set_data( const MBTag tag_handle, 
+                                   const MBEntityHandle* entity_handles, 
+                                   const int num_entities,
+                                   void const* const* tag_data,
+                                   const int* tag_sizes )
+{
+  if (NULL == entity_handles && 0 == num_entities)
+    return tagServer->set_mesh_data(tag_handle, tag_data, tag_sizes ? *tag_sizes : 0);
+
+  //verify handles
+  const EntitySequence* seq;
+  const MBEntityHandle* iter;
+  const MBEntityHandle* end = entity_handles + num_entities;
+  for(iter = entity_handles; iter != end; ++iter)
+  {
+    if (TYPE_FROM_HANDLE(*iter) == MBENTITYSET) continue;
+    
+    else if(sequenceManager->find(*iter, seq) != MB_SUCCESS)
+      return MB_ENTITY_NOT_FOUND;
+  }
+
+  return tagServer->set_data(tag_handle, entity_handles, num_entities, tag_data, tag_sizes);
+}
+
+//! set the data  for given EntityHandles and MBTag
+MBErrorCode  MBCore::tag_set_data( const MBTag tag_handle, 
+                                   const MBRange& entity_handles, 
+                                   void const* const* tag_data,
+                                   const int* tag_sizes )
+{
+  //verify handles
+  MBErrorCode result = sequence_manager()->check_valid_entities( entity_handles );
+  if (MB_SUCCESS != result)
+    return result;
+  return tagServer->set_data(tag_handle, entity_handles, tag_data, tag_sizes);
+}
+
 //! adds a sparse tag for this specific EntityHandle/tag_name combination
 MBErrorCode MBCore::tag_create(const char *tag_name,
                                  const int tag_size, 
@@ -1407,6 +1470,12 @@
                                 const void* def_val,
                                 bool use_existing )
 {
+    // This API cannot be used for creating variable-length tags with a 
+    // default value, because there is no argument for the length of
+    // the default value.
+  if (def_val && MB_VARIABLE_LENGTH == size)
+    return MB_VARIABLE_DATA_LENGTH;
+  
   MBErrorCode rval = tagServer->add_tag( name, size, storage, data, handle, def_val );
 
     // If it is okay to use an existing tag of the same name, check that it 
@@ -1437,6 +1506,16 @@
   return rval;
 }
 
+MBErrorCode MBCore::tag_create_variable_length( const char* name,
+                                                MBTagType storage,
+                                                MBDataType data,
+                                                MBTag& handle,
+                                                const void* def_val,
+                                                int def_val_size )
+{
+  return tagServer->add_tag( name, MB_VARIABLE_LENGTH, storage, data, handle, def_val, def_val_size );
+}
+
 //! removes the tag from the entity
 MBErrorCode  MBCore::tag_delete_data(const MBTag tag_handle, 
                                        const MBEntityHandle *entity_handles,
@@ -1511,7 +1590,7 @@
     return MB_TAG_NOT_FOUND;
   
   tag_size = tag_info->get_size();
-  return MB_SUCCESS;
+  return MB_VARIABLE_LENGTH == tag_size ? MB_VARIABLE_DATA_LENGTH : MB_SUCCESS;
 }
 
 MBErrorCode MBCore::tag_get_data_type( const MBTag handle, 
@@ -1532,6 +1611,11 @@
   return tagServer->get_default_data( tag_handle, def_value, size );
 }
 
+MBErrorCode MBCore::tag_get_default_value( MBTag tag, const void*& ptr, int& size ) const
+{
+  return tagServer->get_default_data_ref( tag, ptr, size );
+}
+
   //! get type of tag (sparse, dense, etc.; 0 = dense, 1 = sparse, 2 = bit, 3 = static)
 MBErrorCode MBCore::tag_get_type(const MBTag tag_handle, MBTagType &tag_type) const
 {

Modified: MOAB/trunk/MBInterface.hpp
===================================================================
--- MOAB/trunk/MBInterface.hpp	2008-02-01 22:53:46 UTC (rev 1575)
+++ MOAB/trunk/MBInterface.hpp	2008-02-01 23:37:36 UTC (rev 1576)
@@ -1053,6 +1053,29 @@
                                   const      void* def_val,
                                               bool use_existing = false ) = 0;
 
+    /**\brief Define a new tag that can store variable-length data.
+     *
+     * Define a new tag for storing application-defined data on MB entities.  
+     *
+     * \param name          The name of the tag.
+     * \param storage       The tag storage type (MB_TAG_BIT not supported).
+     * \param data_type     The tag data type.
+     * \param handle_out    The tag handle (output)
+     * \param default_value Optional default value for tag.
+     * \param default_val_len Length of default value.  Required if
+     *                      default value is specified.
+     * \return - MB_ALREADY_ALLOCATED if a tag with name already exists.
+     *         - MB_FAILURE if inconsistant arguments
+     *         - MB_SUCCESS otherwise.
+     */
+  virtual MBErrorCode tag_create_variable_length( const char* name,
+                                                  MBTagType   storage,
+                                                  MBDataType  data_type,
+                                                  MBTag&      handle_out,
+                                                  const void* default_value = 0,
+                                                  int         default_val_len = 0 
+                                                 ) = 0;
+
     //! Get the name of a tag corresponding to a handle
     /** \param tag_handle Tag you want the name of.  
         \param tag_name Name string for <em>tag_handle</em>. 
@@ -1104,6 +1127,7 @@
                 - MB_TAG_NOT_FOUND    If <code>tag_handle</code> is invalid.
     */ 
   virtual MBErrorCode tag_get_default_value(const MBTag tag, void *def_val) const = 0;
+  virtual MBErrorCode tag_get_default_value( MBTag tag, const void*& def_val, int& size) const = 0;
 
     //! Get handles for all tags defined in the mesh instance
     /** Get handles for all tags defined on the mesh instance.
@@ -1167,6 +1191,77 @@
                                     const MBRange& entity_handles,
                                     const void *tag_data ) = 0;
 
+
+    /**\brief Get pointers to tag data
+     *
+     * For a tag, get the values for a list of passed entity handles.
+     *\param tag_handle     The tag
+     *\param entity_handles An array of entity handles for which to retreive tag values.
+     *\param num_entities   The length of the 'entity_handles' array.
+     *\param tag_data       An array of 'const void*'.  Array must be at least
+     *                      'num_entitities' long.  Array is populated (output)
+     *                      with pointers to the internal storage for the
+     *                      tag value corresponding to each entity handle.
+     *\param tag_sizes      The length of each tag value.  Optional for 
+     *                      fixed-length tags.  Required for variable-length tags.
+     */
+  virtual MBErrorCode  tag_get_data(const MBTag tag_handle, 
+                                    const MBEntityHandle* entity_handles, 
+                                    const int num_entities, 
+                                    const void** tag_data,
+                                    int* tag_sizes = 0 ) const = 0;
+
+    /**\brief Get pointers to tag data
+     *
+     * For a tag, get the values for a list of passed entity handles.
+     *\param tag_handle     The tag
+     *\param entity_handles The entity handles for which to retreive tag values.
+     *\param tag_data       An array of 'const void*'.  Array is populated (output)
+     *                      with pointers to the internal storage for the
+     *                      tag value corresponding to each entity handle.
+     *\param tag_sizes      The length of each tag value.  Optional for 
+     *                      fixed-length tags.  Required for variable-length tags.
+     */
+  virtual MBErrorCode  tag_get_data(const MBTag tag_handle, 
+                                    const MBRange& entity_handles, 
+                                    const void** tag_data,
+                                    int* tag_sizes = 0 ) const = 0;
+
+    /**\brief Set tag data given an array of pointers to tag values.
+     *
+     * For a tag, set the values for a list of passed entity handles.
+     *\param tag_handle     The tag
+     *\param entity_handles An array of entity handles for which to set tag values.
+     *\param num_entities   The length of the 'entity_handles' array.
+     *\param tag_data       An array of 'const void*'.  Array must be at least
+     *                      'num_entitities' long.  Array is expected to
+     *                      contain pointers to tag values for the corresponding
+     *                      MBEntityHandle in 'entity_handles'.
+     *\param tag_sizes      The length of each tag value.  Optional for 
+     *                      fixed-length tags.  Required for variable-length tags.
+     */
+  virtual MBErrorCode  tag_set_data(const MBTag tag_handle, 
+                                    const MBEntityHandle* entity_handles, 
+                                    const int num_entities,
+                                    void const* const* tag_data,
+                                    const int* tag_sizes = 0 ) = 0;
+  
+    /**\brief Set tag data given an array of pointers to tag values.
+     *
+     * For a tag, set the values for a list of passed entity handles.
+     *\param tag_handle     The tag
+     *\param entity_handles The entity handles for which to set tag values.
+     *\param tag_data       An array of 'const void*'.  Array is expected to
+     *                      contain pointers to tag values for the corresponding
+     *                      MBEntityHandle in 'entity_handles'.
+     *\param tag_sizes      The length of each tag value.  Optional for 
+     *                      fixed-length tags.  Required for variable-length tags.
+     */
+  virtual MBErrorCode  tag_set_data(const MBTag tag_handle, 
+                                    const MBRange& entity_handles,
+                                    void const* const* tag_data,
+                                    const int* tag_sizes = 0 ) = 0;
+
     //! Delete the data of a vector of entity handles and sparse tag
     /** Delete the data of a tag on a vector of entity handles.  Only sparse tag data are deleted with this
         function; dense tags are deleted by deleting the tag itself using tag_delete.

Modified: MOAB/trunk/SequenceData.cpp
===================================================================
--- MOAB/trunk/SequenceData.cpp	2008-02-01 22:53:46 UTC (rev 1575)
+++ MOAB/trunk/SequenceData.cpp	2008-02-01 23:37:36 UTC (rev 1576)
@@ -153,7 +153,7 @@
 
 void SequenceData::release_tag_data( const int* tag_sizes, int num_tag_sizes )
 {
-  assert( num_tag_sizes >= numTagData );
+  assert( num_tag_sizes >= (int)numTagData );
   for (unsigned i = 1; i <= numTagData; ++i)
     release_tag_data( i, tag_sizes[i-1] );
 }

Modified: MOAB/trunk/SequenceManager.cpp
===================================================================
--- MOAB/trunk/SequenceManager.cpp	2008-02-01 22:53:46 UTC (rev 1575)
+++ MOAB/trunk/SequenceManager.cpp	2008-02-01 23:37:36 UTC (rev 1576)
@@ -18,6 +18,71 @@
 const MBEntityID DEFAULT_POLY_SEQUENCE_SIZE = 4 * DEFAULT_ELEMENT_SEQUENCE_SIZE;
 const MBEntityID DEFAULT_MESHSET_SEQUENCE_SIZE = DEFAULT_VERTEX_SEQUENCE_SIZE;
 
+static inline
+const unsigned char* tag_array( const EntitySequence* seq, 
+                                MBEntityHandle h,
+                                int tag_id, 
+                                int tag_size )
+{
+  const void* mem = seq->data()->get_tag_data(tag_id);
+  return mem ? reinterpret_cast<const unsigned char*>(mem)
+    + tag_size * (h - seq->data()->start_handle()) : 0;
+}
+
+static inline
+unsigned char* tag_array( EntitySequence* seq, 
+                          MBEntityHandle h, 
+                          int tag_id, 
+                          int tag_size )
+{
+  void* mem = seq->data()->get_tag_data(tag_id);
+  return mem ? reinterpret_cast<unsigned char*>(mem)
+    + tag_size * (h - seq->data()->start_handle()) : 0;
+}
+
+static inline
+unsigned char* make_tag( EntitySequence* seq, 
+                         MBEntityHandle h, 
+                         int tag_id, 
+                         int tag_size,
+                         const void* default_value )
+{
+  void* mem = seq->data()->get_tag_data(tag_id);
+  if (!mem)
+    mem = seq->data()->create_tag_data( tag_id, tag_size, default_value );
+  return reinterpret_cast<unsigned char*>(mem)
+    + tag_size * (h - seq->data()->start_handle());
+}
+
+static inline
+const VarLenTag* vtag_array( const EntitySequence* seq, 
+                             MBEntityHandle h, 
+                             int tag_id )
+{
+  const void* mem = seq->data()->get_tag_data(tag_id);
+  return mem ? reinterpret_cast<const VarLenTag*>(mem) + h - seq->data()->start_handle() : 0;
+}
+
+static inline
+VarLenTag* vtag_array( EntitySequence* seq, 
+                       MBEntityHandle h, 
+                       int tag_id )
+{
+  void* mem = seq->data()->get_tag_data(tag_id);
+  return mem ? reinterpret_cast<VarLenTag*>(mem) + h - seq->data()->start_handle() : 0;
+}
+
+static inline
+VarLenTag* make_vtag( EntitySequence* seq, 
+                      MBEntityHandle h, 
+                      int tag_id )
+{
+  void* mem = seq->data()->get_tag_data(tag_id);
+  if (!mem)
+    mem = seq->data()->create_tag_data( tag_id, sizeof(VarLenTag), 0 );
+  return reinterpret_cast<VarLenTag*>(mem) + h - seq->data()->start_handle();
+}
+
 MBEntityID SequenceManager::default_poly_sequence_size( int conn_len )
   {  return std::max( DEFAULT_POLY_SEQUENCE_SIZE / conn_len, (MBEntityID)1 ); }
 
@@ -693,7 +758,7 @@
 
 MBErrorCode SequenceManager::reserve_tag_id( int size, MBTagId tag_id )
 {
-  if (size < 1) //&& size != MB_VARIABLE_LENGTH)
+  if (size < 1 && size != MB_VARIABLE_LENGTH)
     return MB_INVALID_SIZE;
   if (tag_id >= tagSizes.size())
     tagSizes.resize( tag_id+1, 0 );
@@ -730,74 +795,102 @@
   if (MB_SUCCESS != rval)
     return rval;
   
-  void* tag_array = seq->data()->get_tag_data( tag_id );
-  if (!tag_array)
-    return MB_TAG_NOT_FOUND;
-  
-  char* tag_data = reinterpret_cast<char*>(tag_array) + 
-                   tagSizes[tag_id] * (handle - seq->data()->start_handle());
   if (tagSizes[tag_id] == MB_VARIABLE_LENGTH) {
+    VarLenTag* tag_data = vtag_array( seq, handle, tag_id );
+    if (!tag_data)
+      return MB_TAG_NOT_FOUND;
     VarLenTag* vdata = reinterpret_cast<VarLenTag*>(tag_data);
     if (default_tag_value)
       vdata->set( default_tag_value, default_value_size );
     else
       vdata->clear();
   }
-  else if (default_tag_value)  
-    memcpy( tag_data, default_tag_value, tagSizes[tag_id] );
-  else
-    memset( tag_data, 0, tagSizes[tag_id] );
-  
+  else {
+    void* tag_data = tag_array( seq, handle, tag_id, tagSizes[tag_id] );
+    if (!tag_data)
+      return MB_TAG_NOT_FOUND;
+    if (default_tag_value)  
+      memcpy( tag_data, default_tag_value, tagSizes[tag_id] );
+    else
+      memset( tag_data, 0, tagSizes[tag_id] );
+  }
   return MB_SUCCESS;
 }
 
 MBErrorCode SequenceManager::set_tag_data( MBTagId tag_id,
-                                           MBEntityHandle handle,
-                                           const void* value,
+                                           const MBEntityHandle* handles,
+                                           int num_handles,
+                                           const void* values,
                                            const void* default_value )
 {
-  if (tag_id >= tagSizes.size() || tagSizes[tag_id] < 1)
-    return MB_TAG_NOT_FOUND;
-
-  EntitySequence* seq = 0;
-  MBErrorCode rval = find( handle, seq );
-  if (MB_SUCCESS != rval)
-    return rval;
+  if (tag_id >= tagSizes.size() || tagSizes[tag_id] < 1) {
+    if (tag_id < tagSizes.size() && tagSizes[tag_id] == MB_VARIABLE_LENGTH)
+      return MB_VARIABLE_DATA_LENGTH;
+    else
+      return MB_TAG_NOT_FOUND;
+  }
   
-  void* tag_array = seq->data()->get_tag_data( tag_id );
-  if (!tag_array)
-    tag_array = seq->data()->create_tag_data( tag_id, tagSizes[tag_id], default_value );
+  MBErrorCode result = MB_SUCCESS;
+  const unsigned char* ptr = reinterpret_cast<const unsigned char*>(values);
+  const MBEntityHandle* const end = handles + num_handles;
+  for (const MBEntityHandle* i = handles; i != end; ++i, ptr += tagSizes[tag_id] ) {
+    EntitySequence* seq = 0;
+    MBErrorCode rval = find( *i, seq );
+    if (MB_SUCCESS != rval) {
+      result = rval;
+      continue;
+    }
   
-  char* tag_data = reinterpret_cast<char*>(tag_array) + 
-                   tagSizes[tag_id] * (handle - seq->data()->start_handle());
-  memcpy( tag_data, value, tagSizes[tag_id] );
-  return MB_SUCCESS;
+    unsigned char* tag_data = make_tag( seq, *i, tag_id, tagSizes[tag_id], default_value );
+    memcpy( tag_data, ptr, tagSizes[tag_id] );
+  }
+
+  return result;
 }
 
 MBErrorCode SequenceManager::set_tag_data( MBTagId tag_id,
-                                           MBEntityHandle handle,
-                                           const void* value,
-                                           const void* default_value,
-                                           int length )
+                                           const MBEntityHandle* handles,
+                                           int num_handles,
+                                           void const* const* values,
+                                           const int* lengths,
+                                           const void* default_value )
 {
-  if (tag_id >= tagSizes.size() || !tagSizes[tag_id])
-    return MB_TAG_NOT_FOUND;
-  if (tagSizes[tag_id] != MB_VARIABLE_LENGTH && length != tagSizes[tag_id])
-    return MB_INVALID_SIZE;
-
-  EntitySequence* seq = 0;
-  MBErrorCode rval = find( handle, seq );
-  if (MB_SUCCESS != rval)
-    return rval;
+  MBErrorCode result = MB_SUCCESS;
+  const MBEntityHandle* const end = handles + num_handles;
   
-  void* tag_array = seq->data()->get_tag_data( tag_id );
-  if (!tag_array)
-    tag_array = seq->data()->create_tag_data( tag_id, sizeof(VarLenTag), default_value );
+  if (tagSizes[tag_id] == MB_VARIABLE_LENGTH) {
+    if (!lengths)
+      return MB_VARIABLE_DATA_LENGTH;
+    
+    for (const MBEntityHandle* i = handles; i != end; ++i, ++values, ++lengths ) {
+        // find sequence for entity
+      EntitySequence* seq = 0;
+      MBErrorCode rval = find( *i, seq );
+      if (MB_SUCCESS != rval) {
+        result = rval;
+        continue;
+      }
+        // set value
+      VarLenTag* data = make_vtag( seq, *i, tag_id );
+      data->set( *values, *lengths );
+    }
+  }
+  else {
+    for (const MBEntityHandle* i = handles; i != end; ++i, ++values ) {
+        // find sequence for entity
+      EntitySequence* seq = 0;
+      MBErrorCode rval = find( *i, seq );
+      if (MB_SUCCESS != rval) {
+        result = rval;
+        continue;
+      }
+        // set value
+      unsigned char* data = make_tag( seq, *i, tag_id, tagSizes[tag_id], default_value );
+      memcpy( data, *values, tagSizes[tag_id] );
+    }
+  }
   
-  VarLenTag* tag_data = reinterpret_cast<VarLenTag*>(tag_array) + 
-                        (handle - seq->data()->start_handle());
-  memcpy( tag_data->resize(length), value, length );
-  return MB_SUCCESS;
+  return result;
 }
 
 MBErrorCode SequenceManager::set_tag_data( MBTagId tag_id,
@@ -808,9 +901,13 @@
   MBErrorCode rval, result = MB_SUCCESS;
     // NOTE: Comparison of size to 1 should also catch 
     //       case where tag is variable-length.  
-  if (tag_id >= tagSizes.size() || tagSizes[tag_id] < 1)
-    return MB_TAG_NOT_FOUND;
-    
+  if (tag_id >= tagSizes.size() || tagSizes[tag_id] < 1) {
+    if (tag_id < tagSizes.size() && tagSizes[tag_id] == MB_VARIABLE_LENGTH)
+      return MB_VARIABLE_DATA_LENGTH;
+    else
+      return MB_TAG_NOT_FOUND;
+  }
+  
   const char* data = reinterpret_cast<const char*>(values);
 
   MBRange::const_pair_iterator p = handles.begin();
@@ -849,59 +946,197 @@
 }
       
 
+MBErrorCode SequenceManager::set_tag_data( MBTagId tag_id,
+                                           const MBRange& handles,
+                                           void const* const* values,
+                                           const int* lengths,
+                                           const void* default_value )
+{
+  MBErrorCode rval, result = MB_SUCCESS;
+  if (tag_id >= tagSizes.size() || !tagSizes[tag_id])
+    return MB_TAG_NOT_FOUND;
+
+  int alloc_size = tagSizes[tag_id];
+  if (alloc_size == MB_VARIABLE_LENGTH) {
+    alloc_size = sizeof(VarLenTag);
+  
+    if (!lengths)
+      return MB_VARIABLE_DATA_LENGTH;
+    
+    // Ignore default value for var-len tags.  Just zero the array
+    // data, which results in VarLenTag structs with zero-length
+    // per-entity values.  The query code will return the default
+    // value for such cases.  
+    default_value = NULL;
+  }
+
+
+  MBRange::const_pair_iterator p = handles.begin();
+  for (MBRange::const_pair_iterator p = handles.const_pair_begin(); 
+       p != handles.const_pair_end(); ++p) {
+       
+    MBEntityHandle start = p->first;
+    while (start <= p->second) {
+      
+      EntitySequence* seq = 0;
+      rval = find( start, seq );
+      if (MB_SUCCESS != rval) {
+        result = rval;
+        ++start;
+        ++values;
+        if (lengths)
+          ++lengths;
+        continue;
+      }
+      
+      const MBEntityHandle finish = std::min( p->second, seq->end_handle() ) + 1;
+      const MBEntityID count = finish - start;
+      
+      void* tag_array = seq->data()->get_tag_data( tag_id );
+      if (!tag_array)
+        tag_array = seq->data()->create_tag_data( tag_id, alloc_size, default_value );
+
+      if (tagSizes[tag_id] == MB_VARIABLE_LENGTH) {
+        VarLenTag* tag_data = reinterpret_cast<VarLenTag*>(tag_array) +
+                              start - seq->data()->start_handle();
+        VarLenTag* end_data = tag_data + count;
+        while (tag_data != end_data) {
+          tag_data->set( *values, *lengths );
+          ++tag_data;
+          ++values;
+          ++lengths;
+        }
+      }
+      else {
+        char* tag_data = reinterpret_cast<char*>(tag_array) + 
+                         alloc_size * (start - seq->data()->start_handle());
+        char* end_data = tag_data + alloc_size * count;
+        while (tag_data != end_data) {
+          memcpy( tag_data, *values, alloc_size );
+          tag_data += alloc_size;
+          ++values;
+        }
+      }
+    
+      start = finish;
+    }
+  }
+  
+  return result;
+}
+      
+
 MBErrorCode SequenceManager::get_tag_data( MBTagId tag_id,
-                                           MBEntityHandle handle,
-                                           void* value ) const
+                                           const MBEntityHandle* handles,
+                                           int num_handles,
+                                           void* values,
+                                           const void* default_value ) const
 {
     // NOTE: Comparison of size to 1 should also catch 
     //       case where tag is variable-length.  
-  if (tag_id >= tagSizes.size() || tagSizes[tag_id] < 1)
-    return MB_TAG_NOT_FOUND;
+  if (tag_id >= tagSizes.size() || tagSizes[tag_id] < 1) {
+    if (tag_id < tagSizes.size() && tagSizes[tag_id] == MB_VARIABLE_LENGTH)
+      return MB_VARIABLE_DATA_LENGTH;
+    else
+      return MB_TAG_NOT_FOUND;
+  }
 
-  const EntitySequence* seq = 0;
-  MBErrorCode rval = find( handle, seq );
-  if (MB_SUCCESS != rval)
-    return rval;
+  const int len = tagSizes[tag_id];
+  unsigned char* ptr = reinterpret_cast<unsigned char*>(values);
+  const MBEntityHandle *const end = handles + num_handles;
+  for (const MBEntityHandle* i = handles; i != end; ++i, ptr += len) {
+    
+    const EntitySequence* seq = 0;
+    MBErrorCode rval = find( *i, seq );
+    // keep MOAB 3.0 behavior : return default value for invalid handles
+    if (MB_SUCCESS != rval)
+      return rval;
   
-  const void* tag_array = seq->data()->get_tag_data( tag_id );
-  if (!tag_array)
-    return MB_TAG_NOT_FOUND;
-  
-  const char* tag_data = reinterpret_cast<const char*>(tag_array) + 
-                   tagSizes[tag_id] * (handle - seq->data()->start_handle());
-  memcpy( value, tag_data, tagSizes[tag_id] );
+    const unsigned char* tag_data = tag_array( seq, *i, tag_id, len );
+    if (!tag_data) {
+      if (default_value) 
+        memcpy( ptr, default_value, tagSizes[tag_id] );
+      else
+        return MB_TAG_NOT_FOUND;
+    } 
+    else {
+      memcpy( ptr, tag_data, len );
+    }
+  }
   return MB_SUCCESS;
 }
 
 MBErrorCode SequenceManager::get_tag_data( MBTagId tag_id,
-                                           MBEntityHandle handle,
-                                           const void*& value,
-                                           int& length ) const
+                                           const MBEntityHandle* handles,
+                                           int num_handles,
+                                           const void** values,
+                                           int* lengths,
+                                           const void* default_value,
+                                           int default_value_length ) const
 {
   if (tag_id >= tagSizes.size() || !tagSizes[tag_id])
     return MB_TAG_NOT_FOUND;
   
-  const EntitySequence* seq = 0;
-  MBErrorCode rval = find( handle, seq );
-  if (MB_SUCCESS != rval)
-    return rval;
+  MBErrorCode result = MB_SUCCESS;
+  const MBEntityHandle *const end = handles + num_handles;
+  const int len = tagSizes[tag_id];
   
-  const void* tag_array = seq->data()->get_tag_data( tag_id );
-  if (!tag_array)
-    return MB_TAG_NOT_FOUND;
-    
-  length = tagSizes[tag_id];
-  if (length == MB_VARIABLE_LENGTH) {
-    const VarLenTag* tag_data = reinterpret_cast<const VarLenTag*>(tag_array) + 
-                               (handle - seq->data()->start_handle());
-    length = tag_data->size();
-    value = tag_data->data();
+  if (len == MB_VARIABLE_LENGTH) {
+    for (const MBEntityHandle* i = handles; i != end; ++i) {
+      
+      const EntitySequence* seq = 0;
+      MBErrorCode rval = find( *i, seq );
+      if (MB_SUCCESS != rval) {
+        result = rval;
+        *values = 0;
+        *lengths = 0;
+      }
+      else {
+        const VarLenTag* tag_data = vtag_array( seq, *i, tag_id );
+        if (tag_data && tag_data->size()) {
+          *values = tag_data->data();
+          *lengths = tag_data->size();
+        }
+        else if (default_value) {
+          *values = default_value;
+          *lengths = default_value_length;
+        }
+        else {
+          result = MB_TAG_NOT_FOUND;
+          *values = 0;
+          *lengths = 0;
+        }
+      }
+      
+      ++values;
+      ++lengths;
+    }
   }
   else {
-    value = reinterpret_cast<const char*>(tag_array) + 
-                   length * (handle - seq->data()->start_handle());
+    if (lengths) 
+      MBSysUtil::setmem( lengths, &len, sizeof(int), num_handles );
+  
+    for (const MBEntityHandle* i = handles; i != end; ++i) {
+      const EntitySequence* seq = 0;
+      MBErrorCode rval = find( *i, seq );
+      if (MB_SUCCESS != rval) {
+        result = rval;
+        *values = 0;
+      }
+      else {
+        *values = tag_array( seq, *i, tag_id, len ); 
+        if (!*values) {
+          if (default_value)
+            *values = default_value;
+          else
+            result = MB_TAG_NOT_FOUND;
+        }
+      }
+      ++values;
+    }
   }
-  return MB_SUCCESS;
+  
+  return result;
 }
 
 MBErrorCode SequenceManager::get_tag_data( MBTagId tag_id,
@@ -909,13 +1144,18 @@
                                            void* values,
                                            const void* default_value ) const
 {
-  MBErrorCode rval, result = MB_SUCCESS;;
-  if (tag_id >= tagSizes.size() || !tagSizes[tag_id])
-    return MB_TAG_NOT_FOUND;
+  MBErrorCode rval;
+    // NOTE: Comparison of size to 1 should also catch 
+    //       case where tag is variable-length.  
+  if (tag_id >= tagSizes.size() || tagSizes[tag_id] < 1) {
+    if (tag_id < tagSizes.size() && tagSizes[tag_id] == MB_VARIABLE_LENGTH)
+      return MB_VARIABLE_DATA_LENGTH;
+    else
+      return MB_TAG_NOT_FOUND;
+  }
     
   char* data = reinterpret_cast<char*>(values);
 
-  MBRange::const_pair_iterator p = handles.begin();
   for (MBRange::const_pair_iterator p = handles.const_pair_begin(); 
        p != handles.const_pair_end(); ++p) {
        
@@ -924,18 +1164,7 @@
       
       const EntitySequence* seq = 0;
       rval = find( start, seq );
-        // keep MOAB 3.0 behavior : return default value for invalid handles
-      if (MB_ENTITY_NOT_FOUND == rval) {
-        if (default_value)
-          memcpy( data, default_value, tagSizes[tag_id] );
-        else
-          memset( data, 0, tagSizes[tag_id] );
-        result = MB_ENTITY_NOT_FOUND;
-        data += tagSizes[tag_id];
-        ++start;
-        continue;
-      }
-      else if (MB_SUCCESS != rval) 
+      if (MB_SUCCESS != rval)
         return rval;
      
       const MBEntityHandle finish = std::min( p->second, seq->end_handle() );
@@ -962,6 +1191,107 @@
   return MB_SUCCESS;
 }
 
+MBErrorCode SequenceManager::get_tag_data( MBTagId tag_id,
+                                           const MBRange& handles,
+                                           const void** values,
+                                           int* lengths,
+                                           const void* default_value,
+                                           int default_value_length ) const
+{
+  MBErrorCode rval, result = MB_SUCCESS;
+  if (!default_value)
+    default_value_length = 0;
+
+  if (tag_id >= tagSizes.size() || !tagSizes[tag_id]) 
+    return MB_TAG_NOT_FOUND;
+  
+  if (tagSizes[tag_id] == MB_VARIABLE_LENGTH) {
+    if (!lengths || (default_value && !default_value_length))
+      return MB_VARIABLE_DATA_LENGTH;
+  }
+  else if (lengths) {
+    int len = tagSizes[tag_id];
+    MBSysUtil::setmem( lengths, &len, sizeof(int), handles.size() );
+  }
+  
+  for (MBRange::const_pair_iterator p = handles.const_pair_begin(); 
+       p != handles.const_pair_end(); ++p) {
+
+    MBEntityHandle start = p->first;
+    while (start <= p->second) {
+
+      const EntitySequence* seq = 0;
+      rval = find( start, seq );
+      if (MB_SUCCESS != rval) {
+        *values = 0; 
+        ++values;
+        if (lengths) {
+          *lengths = 0;
+          ++lengths;
+        }
+        result = rval;
+        ++start;
+        continue;
+      }
+
+      const MBEntityHandle finish = std::min( p->second, seq->end_handle() ) + 1;
+      const MBEntityID count = finish - start;
+      if (tagSizes[tag_id] == MB_VARIABLE_LENGTH) {
+        const VarLenTag* tag_data = vtag_array( seq, start, tag_id );
+        if (!tag_data) {
+          MBSysUtil::setmem( values, &default_value, sizeof(void*), count );
+          MBSysUtil::setmem( lengths, &default_value_length, sizeof(int), count );
+          values += count;
+          lengths += count;
+          if (!default_value)
+            result = MB_TAG_NOT_FOUND;
+          continue;
+        }
+
+        const VarLenTag* end_data = tag_data + count;
+        while (tag_data != end_data) {
+          if (tag_data->size()) {
+            *values = tag_data->data();
+            *lengths = tag_data->size();
+          }
+          else if (default_value) {
+            *values = default_value;
+            *lengths = default_value_length;
+          }
+          else {
+            *values = 0;
+            *lengths = 0;
+            result = MB_TAG_NOT_FOUND;
+          }
+          ++values;
+          ++lengths;
+          ++tag_data;
+        }
+      }
+      else {
+        const unsigned char* tag_data = tag_array( seq, start, tag_id, tagSizes[tag_id] );
+        if (!tag_data) {
+          MBSysUtil::setmem( values, &default_value, sizeof(void*), count );
+          values += count;
+          if (!default_value)
+            result = MB_TAG_NOT_FOUND;
+        }
+        else {
+          const unsigned char* end_data = tag_data + count * tagSizes[tag_id];
+          while (tag_data != end_data) {
+            *values = tag_data; 
+            ++values;
+            tag_data += tagSizes[tag_id];
+          }
+        }
+      }
+      start = finish;
+    }
+  }
+  
+  return result;
+}
+
 MBErrorCode SequenceManager::get_entity_tags(  MBEntityHandle entity,
                                  std::vector<MBTag>& tags_out ) const
 {
@@ -970,9 +1300,21 @@
   if (MB_SUCCESS != rval)
     return rval;
   
-  for (MBTagId i = 0; i < tagSizes.size(); ++i)
-    if (seq->data()->get_tag_data(i))
-      tags_out.push_back( TAG_HANDLE_FROM_ID( i, MB_TAG_DENSE ) );
+  for (MBTagId i = 0; i < tagSizes.size(); ++i) {
+    if (tagSizes[i] == MB_VARIABLE_LENGTH) {
+      const void* data_array = seq->data()->get_tag_data(i);
+      if (data_array) {
+        const VarLenTag* tag_ptr = reinterpret_cast<const VarLenTag*>(data_array);
+        tag_ptr += (entity - seq->data()->start_handle());
+        if (tag_ptr->size())
+          tags_out.push_back( TAG_HANDLE_FROM_ID( i, MB_TAG_DENSE ) );
+      }
+    }
+    else {
+      if (seq->data()->get_tag_data(i))
+        tags_out.push_back( TAG_HANDLE_FROM_ID( i, MB_TAG_DENSE ) );
+    }
+  }
   
   return MB_SUCCESS;
 }
@@ -986,9 +1328,25 @@
 
   MBRange::iterator insert = entities_out.begin();
   const TypeSequenceManager& map = entity_map( type );
-  for (TypeSequenceManager::const_iterator i = map.begin(); i != map.end(); ++i) 
-    if ((*i)->data()->get_tag_data(tag_id))
-      insert = entities_out.insert( insert, (*i)->start_handle(), (*i)->end_handle() );
+  if (tagSizes[tag_id] == MB_VARIABLE_LENGTH) {
+    const VarLenTag *data, *iter, *end;
+    for (TypeSequenceManager::const_iterator i = map.begin(); i != map.end(); ++i) {
+      data = reinterpret_cast<const VarLenTag*>((*i)->data()->get_tag_data(tag_id));
+      if (!data)
+        continue;
+      end = data + (*i)->end_handle() - (*i)->data()->start_handle();
+      iter = data + (*i)->start_handle() - (*i)->data()->start_handle();
+      MBEntityHandle handle = (*i)->start_handle();
+      for (; iter != end; ++iter, ++handle)
+        if (iter->size()) 
+          insert = entities_out.insert( insert, handle, handle );
+    }
+  }
+  else {
+    for (TypeSequenceManager::const_iterator i = map.begin(); i != map.end(); ++i) 
+      if ((*i)->data()->get_tag_data(tag_id))
+        insert = entities_out.insert( insert, (*i)->start_handle(), (*i)->end_handle() );
+  }
   
   return MB_SUCCESS;
 }
@@ -1002,10 +1360,26 @@
 
   count = 0;
   const TypeSequenceManager& map = entity_map( type );
-  for (TypeSequenceManager::const_iterator i = map.begin(); i != map.end(); ++i) 
-    if ((*i)->data()->get_tag_data(tag_id))
-      count += (*i)->size();
   
+  if (tagSizes[tag_id] == MB_VARIABLE_LENGTH) {
+    const VarLenTag *data, *iter, *end;
+    for (TypeSequenceManager::const_iterator i = map.begin(); i != map.end(); ++i) {
+      data = reinterpret_cast<const VarLenTag*>((*i)->data()->get_tag_data(tag_id));
+      if (!data)
+        continue;
+      end = data + (*i)->end_handle() - (*i)->data()->start_handle();
+      iter = data + (*i)->start_handle() - (*i)->data()->start_handle();
+      for (; iter != end; ++iter)
+        if (iter->size()) 
+          ++count;
+    }
+  }
+  else {
+    for (TypeSequenceManager::const_iterator i = map.begin(); i != map.end(); ++i) 
+      if ((*i)->data()->get_tag_data(tag_id))
+        count += (*i)->size();
+  }
+  
   return MB_SUCCESS;
 }
 

Modified: MOAB/trunk/SequenceManager.hpp
===================================================================
--- MOAB/trunk/SequenceManager.hpp	2008-02-01 22:53:46 UTC (rev 1575)
+++ MOAB/trunk/SequenceManager.hpp	2008-02-01 23:37:36 UTC (rev 1576)
@@ -213,61 +213,132 @@
                                  const void* default_tag_value,
                                  int default_value_size = 0 );
                                  
-      /** Set fixed-length tag value for a single entity.
+      /** Set fixed-length tag values.
        *\NOTE Default value must be given because it is often
-       *      necessary to allocate storage for other entities
+       *      necessary to allocate storage for additional entities
+       *
+       *\NOTE Will fail for variable-length tag data.
        */
     MBErrorCode set_tag_data( MBTagId tag_id,
-                              MBEntityHandle handle,
-                              const void* value,
+                              const MBEntityHandle* handles,
+                              int num_handles,
+                              const void* values,
                               const void* default_value );
                               
-      /** Set variable-length tag value for a single entity.
-       *\NOTE Default value must be given because it is often
-       *      necessary to allocate storage for other entities
+      /** Set tag values for array of entity handles
+       *\param tag_id      The tag.
+       *\param handles     Array of entity handles.
+       *\param num_handles Length of 'handles' array.
+       *\param values      Array of pointers to tag values, one pointer for each handle
+       *\param lengths     Length of each tag value.  Ignored for fixed-length tags.
+       *\param default_value Used to initialize any additional tag storage.  Ignored
+       *                   for variable-length tags.
        */
     MBErrorCode set_tag_data( MBTagId tag_id,
-                              MBEntityHandle handle,
-                              const void* value,
-                              const void* default_value,
-                              int length );
+                              const MBEntityHandle* handles,
+                              int num_handles,
+                              void const* const* values,
+                              const int* lengths,
+                              const void* default_value );
                               
-      /** Set fixed-length tag value an MBRange of entities
+      /** Set fixed-length tag value for an MBRange of entities
+       *\NOTE Default value must be given because it is often
+       *      necessary to allocate storage for other entities
+       *\NOTE Will fail for variable-length tag data
        */
     MBErrorCode set_tag_data( MBTagId tag_id,
                               const MBRange& handles,
                               const void* values,
                               const void* default_value );
+                              
+      /** Set tag data for an MBRange of entities.
+       *
+       *\param tag_id  The tag
+       *\param handles The entities
+       *\param values  An array of pointers, one per entity, pointing to the
+       *               tag value for the corresponding entity.
+       *\param lengths An array of integers, one per entity, indicating the
+       *               length of the tag value for each entity.  Ingored
+       *               for fixed-length tags.
+       *\param default_value The default value for the tag.  Ignored for
+       *               variable-length tags.
+       */
+     MBErrorCode set_tag_data( MBTagId tag_id,
+                               const MBRange& handles,
+                               void const* const* values,
+                               const int* lengths,
+                               const void* default_value );
 
-      /** Get fixed-length tag value for a single entity 
+      /** Get fixed-length tag values for array of entities
+       *\NOTE Will fail with MB_VARIABLE_DATA_LENGTH if called
+       *      for variable-length tag.
        */
     MBErrorCode get_tag_data( MBTagId tag_id,
-                              MBEntityHandle handle,
-                              void* value ) const;
+                              const MBEntityHandle* handles,
+                              int num_handles,
+                              void* values, 
+                              const void* default_value ) const;
                               
-      /** Get variable-length tag size and pointer to internal data storage.
-       *\param value Reference at which to store pointer to tag data.
+      /** Get pointers to tag data for array of entities
+       *\param tag_id      The Tag.
+       *\param handles     Array of entity handles.
+       *\param num_handles Length of 'handles' array.
+       *\param tag_ptrs    Pointers to tag values, one pointer for each input handle.
+       *\param lengths     Length of each tag value.  Ignored for fixed-length tags.
+       *\param default_value Pointer to default value for tag, or NULL if none.
+       *\param default_value_length  Length of default tag value.  Ingored for
+       *                   fixed-length tags.
        */
     MBErrorCode get_tag_data( MBTagId tag_id,
-                              MBEntityHandle handle,
-                              const void*& value_ptr,
-                              int& length ) const;
+                              const MBEntityHandle* handles,
+                              int num_handles,
+                              const void** tag_ptrs,
+                              int* lengths,
+                              const void* default_value,
+                              int default_value_length ) const;
                               
       /** Get fixed-length tag value for an MBRange of entities
+       *\NOTE Will fail with MB_VARIABLE_DATA_LENGTH if called
+       *      for variable-length tag.
        */
     MBErrorCode get_tag_data( MBTagId tag_id,
                               const MBRange& handles,
                               void* values,
                               const void* default_value ) const;
+                              
+      /** Get pointers to tag data for an MBRange of entities.
+       *
+       *\param tag_id   The tag.
+       *\param handles  The entities.
+       *\param values   Array of pointers of type 'const void*'.  Array
+       *                must be the same length as the size of 'entities'.
+       *                The array will be populated with pointers to the
+       *                internal storage of the tag data for each entity.
+       *\param lengths  Array of integers.  Will be populated with the 
+       *                length of the tag value for each entity.  Argument
+       *                is optional for fixed-length tags.
+       *\param default_value The default value for the tag.
+       *\param default_value_length The length of the default tag value.
+       */
+    MBErrorCode get_tag_data( MBTagId tag_id,
+                              const MBRange& handles,
+                              const void** values,
+                              int* lengths,
+                              const void* default_value,
+                              int defaut_value_length ) const;
   
       /** Get all tags for which values (possibly the default value)
-       *  have been allocated for a given entity
+       *  have been allocated for a given entity.
+       *\NOTE For variable-length data, will only return tag if
+       *      data length is greater than zero.
        */
     MBErrorCode get_entity_tags( MBEntityHandle entity,
                                  std::vector<MBTag>& tags_out ) const;
 
       /** Get all entities for which storage for a specific tag has
        *  been allocated.
+       *\NOTE For variable-length data, will only return entities for
+       *      which data length is greater than zero.
        */
     MBErrorCode get_tagged_entities( MBTagId tag_id, 
                                      MBEntityType type,
@@ -275,6 +346,8 @@
 
       /** Count all entities for which storage for a specific tag has
        *  been allocated.
+       *\NOTE For variable-length data, will only count entities for
+       *      which data length is greater than zero.
        */
     MBErrorCode count_tagged_entities( MBTagId tag, 
                                        MBEntityType type, 

Modified: MOAB/trunk/SparseTagCollection.cpp
===================================================================
--- MOAB/trunk/SparseTagCollection.cpp	2008-02-01 22:53:46 UTC (rev 1575)
+++ MOAB/trunk/SparseTagCollection.cpp	2008-02-01 23:37:36 UTC (rev 1576)
@@ -105,6 +105,12 @@
     mData.lower_bound(entity_handle);
   
   if (mDataSize == MB_VARIABLE_LENGTH) {
+    if (size == 0) {
+        // ignore return value: still success if entity not found
+      remove_data( entity_handle );
+      return MB_SUCCESS;
+    }
+  
     if (iterator == mData.end() || iterator->first != entity_handle) {
       void* new_data = mAllocator.allocate(sizeof(VarLenTag));
       new (new_data) VarLenTag;

Modified: MOAB/trunk/SparseTagCollection.hpp
===================================================================
--- MOAB/trunk/SparseTagCollection.hpp	2008-02-01 22:53:46 UTC (rev 1575)
+++ MOAB/trunk/SparseTagCollection.hpp	2008-02-01 23:37:36 UTC (rev 1576)
@@ -74,12 +74,21 @@
   ~SparseTagCollection();
   
   //! set the tag data for an entity id
+  //!\NOTE Will fail with MB_VARIABLE_DATA_LENGTH if called for 
+  //!      variable-length tag.
   MBErrorCode set_data(const MBEntityHandle entity_handle, const void* data);
 
   //! get the tag data for an entity id
+  //!\NOTE Will fail with MB_VARIABLE_DATA_LENGTH if called for 
+  //!      variable-length tag.
   MBErrorCode get_data(const MBEntityHandle entity_handle, void* data);
   
   //! set variable-length tag data for an entity id
+  //!
+  //!\NOTE If called for fixed-length tag, size must be either zero or the tag size.
+  //!
+  //!\NOTE If called with zero size for a variable-length tag, is equivalent
+  //!      to remove_data().
   MBErrorCode set_data(const MBEntityHandle entity_handle, const void* data, int length);
 
   //! get the variable-length data for an entity id

Modified: MOAB/trunk/SparseTagSuperCollection.cpp
===================================================================
--- MOAB/trunk/SparseTagSuperCollection.cpp	2008-02-01 22:53:46 UTC (rev 1575)
+++ MOAB/trunk/SparseTagSuperCollection.cpp	2008-02-01 23:37:36 UTC (rev 1576)
@@ -91,35 +91,266 @@
   return coll ? coll->tag_size() : 0;
 }
 
-MBErrorCode SparseTagSuperCollection::set_data(const MBTagId tag_handle, 
-    const MBEntityHandle entity_handle, const void* data)
+
+MBErrorCode SparseTagSuperCollection::set_data( MBTagId tag_handle,
+                                                const MBEntityHandle* handles,
+                                                int num_handles,
+                                                const void* data )
 {
   SparseTagCollection* coll = get_collection(tag_handle);
-  return coll ? coll->set_data( entity_handle, data ) : MB_TAG_NOT_FOUND;
+  if (!coll)
+    return MB_TAG_NOT_FOUND;
+    
+  const int length = coll->tag_size();
+  if (length == MB_VARIABLE_LENGTH)
+    return MB_VARIABLE_DATA_LENGTH;
+
+  MBErrorCode rval, result = MB_SUCCESS;
+  const unsigned char* ptr = reinterpret_cast<const unsigned char*>(data);
+  const MBEntityHandle *const end = handles + num_handles;
+  for (const MBEntityHandle* i = handles; i != end; ++i, ptr += length) {
+    rval = coll->set_data( *i, ptr );
+    if (MB_SUCCESS != rval)
+      result = rval;
+  }
+    
+  return result;
 }
 
-MBErrorCode SparseTagSuperCollection::get_data(const MBTagId tag_handle, 
-    const MBEntityHandle entity_handle, void* data)
+MBErrorCode SparseTagSuperCollection::set_data( MBTagId tag_handle,
+                                                const MBEntityHandle* handles,
+                                                int num_handles,
+                                                void const* const* data_ptrs,
+                                                const int* lengths )
 {
   SparseTagCollection* coll = get_collection(tag_handle);
-  return coll ? coll->get_data( entity_handle, data ) : MB_TAG_NOT_FOUND;
+  if (!coll)
+    return MB_TAG_NOT_FOUND;
+    
+  const int length = coll->tag_size();
+  int length_step;
+  if (length == MB_VARIABLE_LENGTH) {
+    if (!lengths)
+      return MB_VARIABLE_DATA_LENGTH;
+    length_step = 1;
+  }
+  else {
+    lengths = &length;
+    length_step = 0;
+  }
+
+  MBErrorCode rval, result = MB_SUCCESS;
+  const MBEntityHandle *const end = handles + num_handles;
+  void const* const* ptr = data_ptrs;
+  for (const MBEntityHandle* i = handles; i != end; ++i, ++ptr, lengths += length_step) {
+    rval = coll->set_data( *i, *ptr, *lengths );
+    if (MB_SUCCESS != rval)
+      result = rval;
+  }
+    
+  return result;
 }
 
-MBErrorCode SparseTagSuperCollection::set_data(const MBTagId tag_handle, 
-    const MBEntityHandle entity_handle, const void* data, int size)
+
+MBErrorCode SparseTagSuperCollection::set_data( MBTagId tag_handle,
+                                                const MBRange& handles,
+                                                const void* data )
 {
   SparseTagCollection* coll = get_collection(tag_handle);
-  return coll ? coll->set_data( entity_handle, data, size ) : MB_TAG_NOT_FOUND;
+  if (!coll)
+    return MB_TAG_NOT_FOUND;
+    
+  const int length = coll->tag_size();
+  if (length == MB_VARIABLE_LENGTH)
+    return MB_VARIABLE_DATA_LENGTH;
+
+  MBErrorCode rval, result = MB_SUCCESS;
+  const unsigned char* ptr = reinterpret_cast<const unsigned char*>(data);
+  for (MBRange::const_iterator i = handles.begin(); i != handles.end(); ++i, ptr += length) {
+    rval = coll->set_data( *i, ptr );
+    if (MB_SUCCESS != rval)
+      result = rval;
+  }
+    
+  return result;
 }
 
-MBErrorCode SparseTagSuperCollection::get_data(const MBTagId tag_handle, 
-    const MBEntityHandle entity_handle, const void*& data, int& size)
+MBErrorCode SparseTagSuperCollection::set_data( MBTagId tag_handle,
+                                                const MBRange& handles,
+                                                void const* const* data_ptrs,
+                                                const int* lengths )
 {
   SparseTagCollection* coll = get_collection(tag_handle);
-  return coll ? coll->get_data( entity_handle, data, size ) : MB_TAG_NOT_FOUND;
+  if (!coll)
+    return MB_TAG_NOT_FOUND;
+    
+  const int length = coll->tag_size();
+  int length_step;
+  if (length == MB_VARIABLE_LENGTH) {
+    if (!lengths)
+      return MB_VARIABLE_DATA_LENGTH;
+    length_step = 1;
+  }
+  else {
+    lengths = &length;
+    length_step = 0;
+  }
+
+  MBErrorCode rval, result = MB_SUCCESS;
+  void const* const* ptr = data_ptrs;
+  for (MBRange::const_iterator i = handles.begin(); i != handles.end(); ++i, ++ptr, lengths += length_step) {
+    rval = coll->set_data( *i, *ptr, *lengths );
+    if (MB_SUCCESS != rval)
+      result = rval;
+  }
+    
+  return result;
 }
 
 
+MBErrorCode SparseTagSuperCollection::get_data( MBTagId tag_handle,
+                                                const MBEntityHandle* handles,
+                                                int num_handles,
+                                                void* data,
+                                                const void* default_value ) const
+{
+  SparseTagCollection* coll = get_collection(tag_handle);
+  if (!coll)
+    return MB_TAG_NOT_FOUND;
+    
+  const int length = coll->tag_size();
+  if (length == MB_VARIABLE_LENGTH)
+    return MB_VARIABLE_DATA_LENGTH;
+
+  MBErrorCode rval;
+  unsigned char* ptr = reinterpret_cast<unsigned char*>(data);
+  const MBEntityHandle *const end = handles + num_handles;
+  for (const MBEntityHandle* i = handles; i != end; ++i, ptr += length) {
+    rval = coll->get_data( *i, ptr );
+    if (MB_SUCCESS != rval) {
+      if (MB_TAG_NOT_FOUND == rval && default_value) 
+        memcpy( ptr, default_value, length );
+      else
+        return rval;
+    }
+  }
+    
+  return MB_SUCCESS;
+}
+
+MBErrorCode SparseTagSuperCollection::get_data( MBTagId tag_handle,
+                                                const MBEntityHandle* handles,
+                                                int num_handles,
+                                                const void** data,
+                                                int* lengths,
+                                                const void* default_value,
+                                                int default_val_length ) const
+{
+  SparseTagCollection* coll = get_collection(tag_handle);
+  if (!coll)
+    return MB_TAG_NOT_FOUND;
+  
+  int junk_length;
+  int length_step = 1;
+  const int length = coll->tag_size();
+  if (!lengths) {
+    if (length == MB_VARIABLE_LENGTH)
+      return MB_VARIABLE_DATA_LENGTH;
+    lengths = &junk_length;
+    length_step = 0;
+  }
+  
+  
+  MBErrorCode rval, result = MB_SUCCESS;
+  const MBEntityHandle *const end = handles + num_handles;
+  for (const MBEntityHandle* i = handles; i != end; ++i, ++data, lengths += length_step) {
+    rval = coll->get_data( *i, *data, *lengths );
+    if (MB_SUCCESS != rval) {
+      if (MB_TAG_NOT_FOUND == rval && default_value) {
+        *data = default_value;
+        *lengths = default_val_length;
+      }
+      else {
+        *data = 0;
+        *lengths = 0;
+        result = rval;
+      }
+    }
+  }
+    
+  return result;
+}
+
+
+MBErrorCode SparseTagSuperCollection::get_data( MBTagId tag_handle,
+                                                const MBRange& handles,
+                                                void* data,
+                                                const void* default_value ) const
+{
+  SparseTagCollection* coll = get_collection(tag_handle);
+  if (!coll)
+    return MB_TAG_NOT_FOUND;
+    
+  const int length = coll->tag_size();
+  if (length == MB_VARIABLE_LENGTH)
+    return MB_VARIABLE_DATA_LENGTH;
+
+  MBErrorCode rval;
+  unsigned char* ptr = reinterpret_cast<unsigned char*>(data);
+  for (MBRange::const_iterator i = handles.begin(); i != handles.end(); ++i, ptr += length) {
+    rval = coll->get_data( *i, ptr );
+    if (MB_SUCCESS != rval) {
+      if (MB_TAG_NOT_FOUND == rval && default_value) 
+        memcpy( ptr, default_value, length );
+      else
+        return rval;
+    }
+  }
+    
+  return MB_SUCCESS;
+}
+
+MBErrorCode SparseTagSuperCollection::get_data( MBTagId tag_handle,
+                                                const MBRange& handles,
+                                                const void** data,
+                                                int* lengths,
+                                                const void* default_value,
+                                                int default_val_length ) const
+{
+  SparseTagCollection* coll = get_collection(tag_handle);
+  if (!coll)
+    return MB_TAG_NOT_FOUND;
+  
+  int junk_length;
+  int length_step = 1;
+  const int length = coll->tag_size();
+  if (!lengths) {
+    if (length == MB_VARIABLE_LENGTH)
+      return MB_VARIABLE_DATA_LENGTH;
+    lengths = &junk_length;
+    length_step = 0;
+  }
+  
+  
+  MBErrorCode rval, result = MB_SUCCESS;
+  for (MBRange::const_iterator i = handles.begin(); i != handles.end(); ++i, ++data, lengths += length_step) {
+    rval = coll->get_data( *i, *data, *lengths );
+    if (MB_SUCCESS != rval) {
+      if (MB_TAG_NOT_FOUND == rval && default_value) {
+        *data = default_value;
+        *lengths = default_val_length;
+      }
+      else {
+        *data = 0;
+        *lengths = 0;
+        result = rval;
+      }
+    }
+  }
+    
+  return result;
+}
+
 MBErrorCode SparseTagSuperCollection::remove_data( const MBTagId tag_handle, 
     const MBEntityHandle entity_handle )
 {

Modified: MOAB/trunk/SparseTagSuperCollection.hpp
===================================================================
--- MOAB/trunk/SparseTagSuperCollection.hpp	2008-02-01 22:53:46 UTC (rev 1575)
+++ MOAB/trunk/SparseTagSuperCollection.hpp	2008-02-01 23:37:36 UTC (rev 1576)
@@ -72,17 +72,106 @@
   //! size of data tag
   int tag_size(const MBTagId tag_id) const;
 
-  //! set the data of a tag
-  MBErrorCode set_data(const MBTagId tag_handle, const MBEntityHandle entity_handle, const void* data);
+    /** Set fixed-length tag values.
+     *\NOTE Will fail for variable-length tag data.
+     */
+  MBErrorCode set_data( MBTagId tag_handle,
+                        const MBEntityHandle* handles,
+                        int num_handles,
+                        const void* data );
 
-  //! get the data of a tag
-  MBErrorCode get_data(const MBTagId tag_handle, const MBEntityHandle entity_handle, void* data);
+    /** Set tag values for array of entity handles
+     *\param tag_id      The tag.
+     *\param handles     Array of entity handles.
+     *\param num_handles Length of 'handles' array.
+     *\param values      Array of pointers to tag values, one pointer for each handle
+     *\param lengths     Length of each tag value.  Ignored for fixed-length tags.
+     */
+  MBErrorCode set_data( MBTagId tag_handle,
+                        const MBEntityHandle* handles,
+                        int num_handles,
+                        void const* const* data_pointers,
+                        const int* lengths = 0 );
 
-  //! set the data of a variable-length tag
-  MBErrorCode set_data(const MBTagId tag_handle, const MBEntityHandle entity_handle, const void* data, int length);
+    /** Set fixed-length tag value for an MBRange of entities
+     *\NOTE Will fail for variable-length tag data
+     */
+  MBErrorCode set_data( MBTagId tag_handle,
+                        const MBRange& handles,
+                        const void* data );
 
-  //! get the data of a variable-length tag
-  MBErrorCode get_data(const MBTagId tag_handle, const MBEntityHandle entity_handle, const void*& data, int& length);
+    /** Set tag data for an MBRange of entities.
+     *
+     *\param tag_id  The tag
+     *\param handles The entities
+     *\param values  An array of pointers, one per entity, pointing to the
+     *               tag value for the corresponding entity.
+     *\param lengths An array of integers, one per entity, indicating the
+     *               length of the tag value for each entity.  Ingored
+     *               for fixed-length tags.
+     */
+  MBErrorCode set_data( MBTagId tag_handle,
+                        const MBRange& handles,
+                        void const* const* data_pointers,
+                        const int* lengths = 0 );
+  
+    /** Get fixed-length tag values for array of entities
+     *\NOTE Will fail with MB_VARIABLE_DATA_LENGTH if called
+     *      for variable-length tag.
+     */
+  MBErrorCode get_data( MBTagId tag_handle,
+                        const MBEntityHandle* handles,
+                        int num_handles,
+                        void* data,
+                        const void* default_value ) const;
+  
+    /** Get pointers to tag data for array of entities
+     *\param tag_id      The Tag.
+     *\param handles     Array of entity handles.
+     *\param num_handles Length of 'handles' array.
+     *\param tag_ptrs    Pointers to tag values, one pointer for each input handle.
+     *\param lengths     Length of each tag value.  Ignored for fixed-length tags.
+     *\param default_value Pointer to default value for tag, or NULL if none.
+     *\param default_value_length  Length of default tag value.  Ingored for
+     *                   fixed-length tags.
+     */
+  MBErrorCode get_data( MBTagId tag_handle,
+                        const MBEntityHandle* handles,
+                        int num_handles,
+                        const void** data,
+                        int* lengths,
+                        const void* default_value,
+                        int default_value_length ) const;
+  
+    /** Get fixed-length tag value for an MBRange of entities
+     *\NOTE Will fail with MB_VARIABLE_DATA_LENGTH if called
+     *      for variable-length tag.
+     */
+  MBErrorCode get_data( MBTagId tag_handle,
+                        const MBRange& handles,
+                        void* data,
+                        const void* default_value ) const;
+  
+    /** Get pointers to tag data for an MBRange of entities.
+     *
+     *\param tag_id   The tag.
+     *\param handles  The entities.
+     *\param values   Array of pointers of type 'const void*'.  Array
+     *                must be the same length as the size of 'entities'.
+     *                The array will be populated with pointers to the
+     *                internal storage of the tag data for each entity.
+     *\param lengths  Array of integers.  Will be populated with the 
+     *                length of the tag value for each entity.  Argument
+     *                is optional for fixed-length tags.
+     *\param default_value The default value for the tag.
+     *\param default_value_length The length of the default tag value.
+     */
+  MBErrorCode get_data( MBTagId tag_handle,
+                        const MBRange& handles,
+                        const void** data,
+                        int* lengths,
+                        const void* default_value,
+                        int default_value_length ) const;
 
   //! removes data
   MBErrorCode remove_data(const MBTagId tag_handle, const MBEntityHandle entity_handle);

Modified: MOAB/trunk/TagInfo.hpp
===================================================================
--- MOAB/trunk/TagInfo.hpp	2008-02-01 22:53:46 UTC (rev 1575)
+++ MOAB/trunk/TagInfo.hpp	2008-02-01 23:37:36 UTC (rev 1576)
@@ -76,7 +76,7 @@
   std::string mTagName;
 
   //! stores the size of the data for this tag
-  unsigned short mDataSize;
+  int mDataSize;
   
   //! flag to mark unused entries
   bool isValid;
@@ -103,16 +103,12 @@
    mDefaultValue( default_value_size, default_value ),
    dataType( type )
 {
-    // if tag is not variable-length and default_value_size is not zero,
-    // then size and default_value_size must be the same.
-  assert( size == MB_VARIABLE_LENGTH || default_value_size == 0 || default_value_size == size );
 }
 
 
 inline void TagInfo::set_mesh_value( const void* data, int size )
 {
     // if tag is not variable-length, then size must be tag size
-  assert( get_size() == MB_VARIABLE_LENGTH || get_size() == size );
   mMeshValue.set( data, size );
 }
 

Modified: MOAB/trunk/TagServer.cpp
===================================================================
--- MOAB/trunk/TagServer.cpp	2008-02-01 22:53:46 UTC (rev 1575)
+++ MOAB/trunk/TagServer.cpp	2008-02-01 23:37:36 UTC (rev 1576)
@@ -47,6 +47,14 @@
 
 using namespace std;
   
+static inline bool check_lengths( const int* length_array, int expected_value, int count )
+{
+  if (length_array)
+    for (int i = 0; i < count; ++i)
+      if (length_array[i] != expected_value)
+        return false;
+  return true;
+}
 
 /*
   TagServer functions ----------------------------------
@@ -89,7 +97,8 @@
     default_value_size = 0;
   }
   else if (storage == MB_TAG_BIT) {
-    if (data_size == MB_VARIABLE_LENGTH)
+      // bit tags cannot be zero-length or variable-length
+    if (data_size < 1)
       return MB_INVALID_SIZE;
     default_value_size = (data_size+7)/8; // convert from bits to bytes
   }
@@ -106,9 +115,11 @@
     return MB_ALREADY_ALLOCATED;
 
     // Input size must be a multiple of the size of the data type.
-  int typesize = TagInfo::size_from_data_type( data_type );
-  if (data_size % typesize)
-    return MB_FAILURE;
+  if (data_size != MB_VARIABLE_LENGTH) {
+    int typesize = TagInfo::size_from_data_type( data_type );
+    if (data_size % typesize)
+      return MB_INVALID_SIZE;
+  }
   
     // data type must be BIT of tag storage type is BIT
   if (storage == MB_TAG_BIT && data_type != MB_TYPE_BIT)
@@ -253,7 +264,7 @@
       return MB_INVALID_SIZE;
   }
   else if (PROP_FROM_TAG_HANDLE(tag_handle) == MB_TAG_BIT)
-    size = (size+7)/8; // convert from bits to bytes
+    size = 1; // one byte max for bit tag values
   else
     size = info->get_size();
   
@@ -261,338 +272,257 @@
   return MB_SUCCESS;
 }
 
-MBErrorCode TagServer::set_data(const MBTag tag_handle, 
-                                 const MBEntityHandle entity_handle, 
-                                 const void* data)
-{
 
-  // this assumes that the entity_handle is valid, 
-  // the check for valid handles are done one level up
-  
-  if(TYPE_FROM_HANDLE(entity_handle) >= MBMAXTYPE)
-    return MB_TYPE_OUT_OF_RANGE;
-  
-  MBTagId id = ID_FROM_TAG_HANDLE(tag_handle);
+MBErrorCode TagServer::set_data( const MBTag tag_handle, 
+                                 const MBEntityHandle* entity_handles, 
+                                 const int num_entities,
+                                 const void* data )
+{
+  const MBTagId tag_id = ID_FROM_TAG_HANDLE(tag_handle);
   switch (PROP_FROM_TAG_HANDLE(tag_handle)) {
-    case MB_TAG_BIT:
-      return set_bits(tag_handle, entity_handle, *((unsigned char *)data));
-    case MB_TAG_SPARSE:
-      return mSparseData->set_data(id, entity_handle, data);
     case MB_TAG_DENSE:
-      return sequenceManager->set_tag_data(id, entity_handle, data, 
-                             mTagTable[MB_TAG_DENSE][id-1].default_value());
-    case MB_TAG_MESH:
-      return MB_FAILURE;
+      if (tag_id > mTagTable[MB_TAG_DENSE].size())
+        return MB_TAG_NOT_FOUND;
+      return sequenceManager->set_tag_data( tag_id, entity_handles, num_entities, 
+                           data, mTagTable[MB_TAG_DENSE][tag_id-1].default_value() );
+  
+    case MB_TAG_SPARSE:
+      return mSparseData->set_data( tag_id, entity_handles, num_entities, data );
+    
+    case MB_TAG_BIT:
+      if (num_entities == 1)
+        return set_bits( tag_handle, *entity_handles, *reinterpret_cast<const unsigned char*>(data) );
+      else
+        return MB_FAILURE;
+    
+    default:
+      return MB_TAG_NOT_FOUND;
   }
-  return MB_FAILURE;
 }
 
-
-MBErrorCode TagServer::set_data(const MBTag tag_handle, 
-                       const MBEntityHandle* entity_handles, 
-                       const int num_entities,
-                       const void* data)
+MBErrorCode TagServer::set_data( const MBTag tag_handle, 
+                                 const MBRange& entity_handles, 
+                                 const void* data )
 {
-
-  // this assumes that the entity_handle is valid, 
-  // the check for valid handles are done one level up
-  
-  MBErrorCode result = MB_SUCCESS;
-  
-  
   const MBTagId tag_id = ID_FROM_TAG_HANDLE(tag_handle);
-  const unsigned char* mydata = static_cast<const unsigned char*>(data);
-  const MBEntityHandle* end = entity_handles+num_entities;
+  switch (PROP_FROM_TAG_HANDLE(tag_handle)) {
+    case MB_TAG_DENSE:
+      if (tag_id > mTagTable[MB_TAG_DENSE].size())
+        return MB_TAG_NOT_FOUND;
+      return sequenceManager->set_tag_data( tag_id, entity_handles, 
+                           data, mTagTable[MB_TAG_DENSE][tag_id-1].default_value() );
   
-  if( PROP_FROM_TAG_HANDLE(tag_handle) == MB_TAG_DENSE)
-  {
-    const int data_size = mTagTable[MB_TAG_DENSE][tag_id-1].get_size();
-    for(const MBEntityHandle* iter = entity_handles; iter != end; ++iter)
-    {
-      if(TYPE_FROM_HANDLE(*iter) >= MBMAXTYPE)
-        return MB_TYPE_OUT_OF_RANGE;
-      result = sequenceManager->set_tag_data(tag_id, *iter, mydata, 
-                             mTagTable[MB_TAG_DENSE][tag_id-1].default_value());
-      if(result != MB_SUCCESS)
-        return result;
-      mydata += data_size;
-    }
+    case MB_TAG_SPARSE:
+      return mSparseData->set_data( tag_id, entity_handles, data );
+    
+    case MB_TAG_BIT:
+      if (entity_handles.size() == 1)
+        return set_bits( tag_handle, entity_handles.front(), *reinterpret_cast<const unsigned char*>(data) );
+      else
+        return MB_FAILURE;
+    
+    default:
+      return MB_TAG_NOT_FOUND;
   }
-  else if(PROP_FROM_TAG_HANDLE(tag_handle) == MB_TAG_SPARSE)
-  {
-    const int data_size = mSparseData->tag_size(tag_id);
-    for(const MBEntityHandle* iter = entity_handles; iter != end; ++iter)
-    {
-      if(TYPE_FROM_HANDLE(*iter) >= MBMAXTYPE)
-        return MB_TYPE_OUT_OF_RANGE;
-      result = mSparseData->set_data(tag_id, *iter, mydata);
-      if(result != MB_SUCCESS)
-        return result;
-      mydata += data_size;
-    }
-  }
-  else if(PROP_FROM_TAG_HANDLE(tag_handle) == MB_TAG_BIT)
-  {
-    if (num_entities == 1)
-      return set_data(tag_handle, entity_handles[0], data);
-    else
-      // don't support this right now - not sure how to pass in multiple bit tags
-      return MB_FAILURE;
-  }
-  else {
-      // if we get here, we didn't find the right tag to set
-    return MB_TAG_NOT_FOUND;
-  }
-
-  
-  return MB_SUCCESS;
 }
 
-MBErrorCode TagServer::set_data(const MBTag tag_handle, 
-                       const MBRange& entity_handles, 
-                       const void* data)
+MBErrorCode TagServer::set_data( const MBTag tag_handle, 
+                                 const MBEntityHandle* entity_handles, 
+                                 const int num_entities,
+                                 void const* const* data,
+                                 const int* lengths )
 {
-
-  // this assumes that the entity_handle is valid, 
-  // the check for valid handles are done one level up
-  
-  MBErrorCode result = MB_SUCCESS;
-  
   const MBTagId tag_id = ID_FROM_TAG_HANDLE(tag_handle);
-  const unsigned char* mydata = static_cast<const unsigned char*>(data);
-  const MBRange::const_iterator end = entity_handles.end();
+  switch (PROP_FROM_TAG_HANDLE(tag_handle)) {
+    case MB_TAG_DENSE:
+      if (tag_id > mTagTable[MB_TAG_DENSE].size())
+        return MB_TAG_NOT_FOUND;
+      return sequenceManager->set_tag_data( tag_id, entity_handles, num_entities, 
+                   data, lengths, mTagTable[MB_TAG_DENSE][tag_id-1].default_value() );
   
-  if( PROP_FROM_TAG_HANDLE(tag_handle) == MB_TAG_DENSE)
-  {
-    result = sequenceManager->set_tag_data( tag_id, entity_handles, data, 
-                             mTagTable[MB_TAG_DENSE][tag_id-1].default_value() );
+    case MB_TAG_SPARSE:
+      return mSparseData->set_data( tag_id, entity_handles, num_entities, data, lengths );
+    
+    case MB_TAG_BIT:
+      if (num_entities == 1)
+        return set_bits( tag_handle, *entity_handles, *reinterpret_cast<const unsigned char*>(*data) );
+      else
+        return MB_FAILURE;
+    
+    default:
+      return MB_TAG_NOT_FOUND;
   }
-  else if(PROP_FROM_TAG_HANDLE(tag_handle) == MB_TAG_SPARSE)
-  {
-    const int data_size = mSparseData->tag_size(tag_id);
-    for(MBRange::const_iterator iter = entity_handles.begin(); iter != end; ++iter)
-    {
-      if(TYPE_FROM_HANDLE(*iter) >= MBMAXTYPE)
-        return MB_TYPE_OUT_OF_RANGE;
-      result = mSparseData->set_data(tag_id, *iter, mydata);
-      if(result != MB_SUCCESS)
-        return result;
-      mydata += data_size;
-    }
-  }
-  else if(PROP_FROM_TAG_HANDLE(tag_handle) == MB_TAG_BIT)
-  {
-    if (entity_handles.size() == 1)
-      return set_data(tag_handle, *entity_handles.begin(), data);
-    else
-      // don't support this right now - not sure how to pass in multiple bit tags
-      return MB_FAILURE;
-  }
-  else {
-      // if we get here, we didn't find the right tag to set
-    return MB_TAG_NOT_FOUND;
-  }
+}
 
+MBErrorCode TagServer::set_data( const MBTag tag_handle, 
+                                 const MBRange& entity_handles, 
+                                 void const* const* data,
+                                 const int* lengths )
+{
+  const MBTagId tag_id = ID_FROM_TAG_HANDLE(tag_handle);
+  switch (PROP_FROM_TAG_HANDLE(tag_handle)) {
+    case MB_TAG_DENSE:
+      if (tag_id > mTagTable[MB_TAG_DENSE].size())
+        return MB_TAG_NOT_FOUND;
+      return sequenceManager->set_tag_data( tag_id, entity_handles, 
+                      data, lengths, mTagTable[MB_TAG_DENSE][tag_id-1].default_value() );
   
-  return MB_SUCCESS;
+    case MB_TAG_SPARSE:
+      return mSparseData->set_data( tag_id, entity_handles, data, lengths );
+    
+    case MB_TAG_BIT:
+      if (entity_handles.size() == 1)
+        return set_bits( tag_handle, entity_handles.front(), *reinterpret_cast<const unsigned char*>(*data) );
+      else
+        return MB_FAILURE;
+    
+    default:
+      return MB_TAG_NOT_FOUND;
+  }
 }
 
 
+
 MBErrorCode TagServer::get_mesh_data( const MBTag tag_handle,
                                       void* data,
                                       int& size ) const
 {
   const TagInfo* info = get_tag_info( tag_handle );
-  if (!info || !info->get_mesh_value_size())
+  if (!info)
     return MB_TAG_NOT_FOUND;
   
+  if (info->get_mesh_value()) {
+    size = info->get_mesh_value_size();
+    memcpy( data, info->get_mesh_value(), size );
+  }
+  else if (info->default_value()) {
+    size = info->default_value_size();
+    memcpy( data, info->default_value(), size );
+  }
+  else {
+    return MB_TAG_NOT_FOUND;
+  }
+    
+    // Mesh value and default value sizes are the number of bytes.
+    // For bit tags, the number of bytes is always 1.  We want the
+    // number of bits instead.
   if (PROP_FROM_TAG_HANDLE(tag_handle) == MB_TAG_BIT)
     size = info->get_size();
-  else 
-    size = info->get_mesh_value_size();
-  if (data) 
-    memcpy( data, info->get_mesh_value(), info->get_mesh_value_size() );
+  
   return MB_SUCCESS;
 }
 
-MBErrorCode TagServer::get_data(const MBTag tag_handle,
-                       const MBEntityHandle entity_handle,
-                       void* data)
+MBErrorCode TagServer::get_data( const MBTag tag_handle,
+                                 const MBEntityHandle* entity_handles,
+                                 const int num_entities,
+                                 void* data )
 {
-
-  MBErrorCode result = MB_TAG_NOT_FOUND;
-
-  if(TYPE_FROM_HANDLE(entity_handle) >= MBMAXTYPE)
-    return MB_TYPE_OUT_OF_RANGE;
-
-  switch (PROP_FROM_TAG_HANDLE(tag_handle)) {
+  const MBTagId tag_id = ID_FROM_TAG_HANDLE(tag_handle);
+  const MBTagType type = PROP_FROM_TAG_HANDLE(tag_handle);
+  const TagInfo* info = get_tag_info( tag_handle );
+  if (!info)
+    return MB_TAG_NOT_FOUND;
+  const void* const default_val = info->default_value();
+  switch (type) {
     case MB_TAG_DENSE:
-      result = sequenceManager->get_tag_data(ID_FROM_TAG_HANDLE(tag_handle), entity_handle, data);
-        // preserve MOAB 3.0 behavior for dense tags: 
-        // return default value for invalid handles.
-      if (result == MB_ENTITY_NOT_FOUND) {
-        const TagInfo* info = get_tag_info(tag_handle);
-        if (!info)
-          return MB_TAG_NOT_FOUND;
-        if (info->default_value())
-          memcpy( data, info->default_value(), info->get_size() );
-        else
-          memset( data, 0, info->get_size() );
-      }
-      break;
+      return sequenceManager->get_tag_data( tag_id, entity_handles, num_entities, data, default_val );
     case MB_TAG_SPARSE:
-      result = mSparseData->get_data(ID_FROM_TAG_HANDLE(tag_handle), entity_handle, data);
-      break;
+      return mSparseData->get_data( tag_id, entity_handles, num_entities, data, default_val );
     case MB_TAG_BIT:
-      result = get_bits(tag_handle, entity_handle, *((unsigned char *)data));
-      break;
-    case MB_TAG_MESH:
-      result = MB_FAILURE;
-      break;
+      if (num_entities == 1)
+        return get_bits( tag_handle, *entity_handles, *reinterpret_cast<unsigned char*>(data) );
+      else
+        return MB_FAILURE;
+    
+    default:
+      return MB_TAG_NOT_FOUND;
   }
+}
 
-  // if we couldn't get a value
-  // try to get a default value
-  if(result == MB_TAG_NOT_FOUND)
-  {
-    int size;
-    result = get_default_data(tag_handle, data, size);
-      // if failure is returned, change it back to tag not found, since it's
-      // ok to look for data and not find any
-    if (result == MB_ENTITY_NOT_FOUND) result = MB_TAG_NOT_FOUND;
+MBErrorCode TagServer::get_data( const MBTag tag_handle,
+                                 const MBRange& entity_handles,
+                                 void* data )
+{
+  const MBTagId tag_id = ID_FROM_TAG_HANDLE(tag_handle);
+  const MBTagType type = PROP_FROM_TAG_HANDLE(tag_handle);
+  const TagInfo* info = get_tag_info( tag_handle );
+  if (!info)
+    return MB_TAG_NOT_FOUND;
+  const void* const default_val = info->default_value();
+  switch (type) {
+    case MB_TAG_DENSE:
+      return sequenceManager->get_tag_data( tag_id, entity_handles, data, default_val );
+    case MB_TAG_SPARSE:
+      return mSparseData->get_data( tag_id, entity_handles, data, default_val );
+    case MB_TAG_BIT:
+      if (entity_handles.size() == 1)
+        return get_bits( tag_handle, entity_handles.front(), *reinterpret_cast<unsigned char*>(data) );
+      else
+        return MB_FAILURE;
+    
+    default:
+      return MB_TAG_NOT_FOUND;
   }
-
-  return result;
 }
 
-MBErrorCode TagServer::get_data(const MBTag tag_handle,
-                       const MBEntityHandle* entity_handles,
-                       const int num_entities,
-                       void* data)
+MBErrorCode TagServer::get_data( const MBTag tag_handle,
+                                 const MBEntityHandle* entity_handles,
+                                 const int num_entities,
+                                 const void** data,
+                                 int* lengths )
 {
-
-  MBErrorCode result = MB_SUCCESS, rval;
-
   const MBTagId tag_id = ID_FROM_TAG_HANDLE(tag_handle);
-  unsigned char* mydata = static_cast<unsigned char*>(data);
-  const MBEntityHandle* end = entity_handles+num_entities;
-
-  if(PROP_FROM_TAG_HANDLE(tag_handle) == MB_TAG_DENSE)
-  {
-    const int data_size = mTagTable[MB_TAG_DENSE][tag_id-1].get_size();
-    for(const MBEntityHandle* iter = entity_handles; iter != end; ++iter)
-    {
-      rval = sequenceManager->get_tag_data(tag_id, *iter, mydata);
-        // preserve MOAB 3.0 behavior for dense tags: 
-        // return default value for invalid handles.
-      if(rval == MB_TAG_NOT_FOUND || rval == MB_ENTITY_NOT_FOUND)
-      {
-        const TagInfo* info = get_tag_info(tag_handle);
-        if (!info)
-          return MB_TAG_NOT_FOUND;
-        if (info->default_value()) {
-          memcpy( data, info->default_value(), info->get_size() );
-          if (rval == MB_ENTITY_NOT_FOUND)
-            result = MB_ENTITY_NOT_FOUND;
-        }
-        else {
-          memset( data, 0, info->get_size() );
-          result = rval;
-        }
-      }
-      mydata += data_size;
-    }
-  }
-  else if(PROP_FROM_TAG_HANDLE(tag_handle) == MB_TAG_SPARSE)
-  {
-    const int data_size = mSparseData->tag_size(tag_id);
-    for(const MBEntityHandle* iter = entity_handles; iter != end; ++iter)
-    {
-      result = mSparseData->get_data(tag_id, *iter, mydata);
-      if(result == MB_TAG_NOT_FOUND)
-      {
-        int size;
-        result = get_default_data(tag_handle, mydata, size);
-          // if failure is returned, change it back to tag not found, since it's
-          // ok to look for data and not find any
-        if (result == MB_ENTITY_NOT_FOUND) result = MB_TAG_NOT_FOUND;
-      }
-      if(result != MB_SUCCESS)
-        return result;
-      mydata += data_size;
-    }
-  }
-  else if(PROP_FROM_TAG_HANDLE(tag_handle) == MB_TAG_BIT)
-  {
-    if (num_entities == 1)
-      return get_data(tag_handle, entity_handles[0], data);
-    else
-      // don't support this right now - not sure how to pass in multiple bit tags
-      return MB_FAILURE;
-  }
-  else {
-      // if we get here, we didn't find the right tag to set
+  const MBTagType type = PROP_FROM_TAG_HANDLE(tag_handle);
+  const TagInfo* info = get_tag_info( tag_handle );
+  if (!info)
     return MB_TAG_NOT_FOUND;
+  const void* const default_val = info->default_value();
+  const int def_val_len = info->default_value_size();
+  switch (type) {
+    case MB_TAG_DENSE:
+      return sequenceManager->get_tag_data( tag_id, entity_handles, num_entities, data, lengths, default_val, def_val_len );
+    case MB_TAG_SPARSE:
+      return mSparseData->get_data( tag_id, entity_handles, num_entities, data, lengths, default_val, def_val_len );
+    case MB_TAG_BIT:
+      if (num_entities == 1)
+        return get_bits( tag_handle, *entity_handles, *reinterpret_cast<unsigned char*>(data) );
+      else
+        return MB_FAILURE;
+    
+    default:
+      return MB_TAG_NOT_FOUND;
   }
-
-
-  return MB_SUCCESS;
 }
 
-MBErrorCode TagServer::get_data(const MBTag tag_handle,
-                       const MBRange& entity_handles,
-                       void* data)
+MBErrorCode TagServer::get_data( const MBTag tag_handle,
+                                 const MBRange& entity_handles,
+                                 const void** data,
+                                 int* lengths )
 {
-
-  MBErrorCode result = MB_SUCCESS;
-
   const MBTagId tag_id = ID_FROM_TAG_HANDLE(tag_handle);
-  unsigned char* mydata = static_cast<unsigned char*>(data);
-  const MBRange::const_iterator end = entity_handles.end();
-
-  if(PROP_FROM_TAG_HANDLE(tag_handle) == MB_TAG_DENSE)
-  {
-    result = sequenceManager->get_tag_data( tag_id, entity_handles, mydata, 
-                             mTagTable[MB_TAG_DENSE][tag_id-1].default_value() );
-  }
-  else if(PROP_FROM_TAG_HANDLE(tag_handle) == MB_TAG_SPARSE)
-  {
-    const int data_size = mSparseData->tag_size(tag_id);
-    for(MBRange::const_iterator iter = entity_handles.begin(); iter != end; ++iter)
-    {
-      if(TYPE_FROM_HANDLE(*iter) >= MBMAXTYPE)
-        return MB_TYPE_OUT_OF_RANGE;
-      result = mSparseData->get_data(tag_id, *iter, mydata);
-      if(result == MB_TAG_NOT_FOUND)
-      {
-        int size;
-        result = get_default_data(tag_handle, mydata, size);
-          // if failure is returned, change it back to tag not found, since it's
-          // ok to look for data and not find any
-        if (result == MB_ENTITY_NOT_FOUND) result = MB_TAG_NOT_FOUND;
-      }
-      if(result != MB_SUCCESS)
-        return result;
-      mydata += data_size;
-    }
-  }
-  else if(PROP_FROM_TAG_HANDLE(tag_handle) == MB_TAG_BIT)
-  {
-    if (entity_handles.size() == 1)
-      return get_data(tag_handle, *entity_handles.begin(), data);
-    else
-      // don't support this right now - not sure how to pass in multiple bit tags
-      return MB_FAILURE;
-  }
-  else {
-      // if we get here, we didn't find the right tag to set
+  const MBTagType type = PROP_FROM_TAG_HANDLE(tag_handle);
+  const TagInfo* info = get_tag_info( tag_handle );
+  if (!info)
     return MB_TAG_NOT_FOUND;
+  const void* const default_val = info->default_value();
+  const int def_val_len = info->default_value_size();
+  switch (type) {
+    case MB_TAG_DENSE:
+      return sequenceManager->get_tag_data( tag_id, entity_handles, data, lengths, default_val, def_val_len );
+    case MB_TAG_SPARSE:
+      return mSparseData->get_data( tag_id, entity_handles, data, lengths, default_val, def_val_len );
+    case MB_TAG_BIT:
+      if (entity_handles.size() == 1)
+        return get_bits( tag_handle, entity_handles.front(), *reinterpret_cast<unsigned char*>(data) );
+      else
+        return MB_FAILURE;
+    
+    default:
+      return MB_TAG_NOT_FOUND;
   }
-
-
-  return MB_SUCCESS;
 }
 
+
 MBTag TagServer::get_handle(const char *tag_name) const
 {
   if (tag_name && *tag_name)
@@ -648,7 +578,7 @@
   const TagInfo* tag_info = get_tag_info(tag_handle);
   if(!tag_info)
     return MB_TAG_NOT_FOUND;
-
+  
   size = tag_info->default_value_size();
   if (size) {
     data = tag_info->default_value();

Modified: MOAB/trunk/TagServer.hpp
===================================================================
--- MOAB/trunk/TagServer.hpp	2008-02-01 22:53:46 UTC (rev 1575)
+++ MOAB/trunk/TagServer.hpp	2008-02-01 23:37:36 UTC (rev 1576)
@@ -85,23 +85,141 @@
   //! set global/mesh value of tag
   MBErrorCode set_mesh_data( const MBTag tag_handle, const void* data, int size = 0);
 
-  //! set the value of a tag
-  MBErrorCode set_data(const MBTag tag_handle, const MBEntityHandle entity_handle, const void* data );
+  /**\brief Set value for {MBTag,MBEntityHandle) tuple.
+   * 
+   * Set tag value.
+   *\NOTE Will fail with MB_VARIABLE_DATA_LENGTH for variable-length tags.
+   *\param tag_handle    The tag.
+   *\param entity_handle The entity.
+   *\param data          Pointer to tag value.
+   */
+  MBErrorCode set_data(const MBTag tag_handle, const MBEntityHandle entity_handle, const void* data )
+    { return set_data( tag_handle, &entity_handle, 1, data ); }
   
+  /**\brief Set tag values for an array of entity handles.
+   * 
+   * Set tag values.
+   *\NOTE Will fail with MB_VARIABLE_DATA_LENGTH for variable-length tags.
+   *\param tag_handle     The tag.
+   *\param entity_handles Array of entity handles.
+   *\param num_entities   Length of entity_handles array.
+   *\param data           Pointer to memory containing concatenation of
+   *                      tag values for all entities, in the order the
+   *                      entities are specified in entity_handles.
+   */
   MBErrorCode set_data(const MBTag tag_handle, const MBEntityHandle* entity_handles, const int num_entities, const void* data );
   
+  /**\brief Set tag values for an MBRange of entity handles.
+   * 
+   * Set tag values.
+   *\NOTE Will fail with MB_VARIABLE_DATA_LENGTH for variable-length tags.
+   *\param tag_handle     The tag.
+   *\param entity_handles MBRange of entity handles.
+   *\param data           Pointer to memory containing concatenation of
+   *                      tag values for all entities, in the order the
+   *                      entities are specified in entity_handles.
+   */
   MBErrorCode set_data(const MBTag tag_handle, const MBRange& entity_handles, const void* data );
+  
+  /**\brief Set tag values for an array of entity handles.
+   * 
+   * Set tag values.
+   *\param tag_handle     The tag.
+   *\param entity_handles Array of entity handles.
+   *\param num_entities   Length of entity_handles array.
+   *\param data           Array of pointers to per-entity tag values.
+   *\param lengths        Length of each entity's tag value.  Ignored
+   *                      for fixed-length tags.
+   */
+  MBErrorCode set_data( const MBTag tag_handle, 
+                        const MBEntityHandle* entity_handles, 
+                        const int num_entities, 
+                        void const* const* data,
+                        const int* lengths = 0 );
+  
+  /**\brief Set tag values for an MBRange of entity handles.
+   * 
+   * Set tag values.
+   *\param tag_handle     The tag.
+   *\param entity_handles entity handles.
+   *\param data           Array of pointers to per-entity tag values.
+   *\param lengths        Length of each entity's tag value.  Ignored
+   *                      for fixed-length tags.
+   */
+  MBErrorCode set_data( const MBTag tag_handle, 
+                        const MBRange& entity_handles, 
+                        void const* const* data,
+                        const int* lengths = 0 );
 
   //! get global/mesh value of tag
   MBErrorCode get_mesh_data( const MBTag tag_handle, void* data, int& size ) const;
 
-  //! get the value of a tag
-  MBErrorCode get_data(const MBTag tag_handle, const MBEntityHandle entity_handle, void* data );
+  /**\Brief Get tag value
+   *
+   * Get the value for a {MBTag,MBEntityHandle} tuple.
+   *\NOTE Will fail with MB_VARIABLE_DATA_LENGTH for variable-length tags.
+   *\param tag_handle    The tag
+   *\param entity_handle The entity
+   *\param data          Pointer to memory location to which to copy tag value.
+   */
+  MBErrorCode get_data(const MBTag tag_handle, const MBEntityHandle entity_handle, void* data )
+    { return get_data( tag_handle, &entity_handle, 1, data ); }
   
+  /**\Brief Get tag values
+   *
+   * For a single tag, get the tag value for an array of entities.
+   *\NOTE Will fail with MB_VARIABLE_DATA_LENGTH for variable-length tags.
+   *\param tag_handle     The tag
+   *\param entity_handles Entity handle array
+   *\param num_entiites   Length of entity_handles array
+   *\param data           Pointer to memory location to which to copy tag values.
+   *                      Writes the concatenation of tag values, in the order
+   *                      of the entity handles in the input array.
+   */
   MBErrorCode get_data(const MBTag tag_handle, const MBEntityHandle* entity_handles, const int num_ents, void* data );
   
+  /**\Brief Get tag values
+   *
+   * For a single tag, get the tag value for an MBRange of entities.
+   *\NOTE Will fail with MB_VARIABLE_DATA_LENGTH for variable-length tags.
+   *\param tag_handle     The tag
+   *\param entity_handles Entity handles
+   *\param data           Pointer to memory location to which to copy tag values.
+   *                      Writes the concatenation of tag values, in the order
+   *                      of the entity handles in the input array.
+   */
   MBErrorCode get_data(const MBTag tag_handle, const MBRange& entity_handles, void* data );
   
+  /**\brief Get pointers to tag values for an array of entity handles.
+   * 
+   * Get pointers to tag values.
+   *\param tag_handle     The tag.
+   *\param entity_handles Array of entity handles.
+   *\param num_entities   Length of entity_handles array.
+   *\param data           Output: Array of pointers to per-entity tag values.
+   *\param lengths        Output: Length of each entity's tag value.  
+   *                      Optional for fixed-length tags.
+   */
+  MBErrorCode get_data( const MBTag tag_handle, 
+                        const MBEntityHandle* entity_handles, 
+                        const int num_entities, 
+                        const void** data,
+                        int* lengths = 0 );
+  
+  /**\brief Get pointers to tag values for an MBRange of entity handles.
+   * 
+   * Get pointers to tag values.
+   *\param tag_handle     The tag.
+   *\param entity_handles entity handles.
+   *\param data           Output: Array of pointers to per-entity tag values.
+   *\param lengths        Output: Length of each entity's tag value.  
+   *                      Optional for fixed-length tags.
+   */
+  MBErrorCode get_data( const MBTag tag_handle, 
+                        const MBRange& entity_handles, 
+                        const void** data,
+                        int* lengths = 0 );
+  
   //! set the value of a tag
   MBErrorCode set_bits(const MBTag tag_handle, const MBEntityHandle entity_handle, unsigned char data );
 




More information about the moab-dev mailing list