moab
TagInfo.cpp
Go to the documentation of this file.
00001 #include "TagInfo.hpp"
00002 #include "moab/Error.hpp"
00003 #include <string.h>  /* memcpy */
00004 #include <stdlib.h>  /* realloc & free */
00005 #include <assert.h>
00006 
00007 namespace moab {
00008 
00009 TagInfo::TagInfo( const char* name, 
00010                   int size, 
00011                   DataType type,
00012                   const void* default_value,
00013                   int default_value_size)
00014  : mDefaultValue(0),
00015    mDefaultValueSize(default_value_size),
00016    mDataSize(size),
00017    dataType(type)
00018 {
00019   if (default_value) {
00020     mDefaultValue = malloc( mDefaultValueSize );
00021     memcpy( mDefaultValue, default_value, mDefaultValueSize );
00022   }
00023   if (name)
00024     mTagName = name;
00025 }
00026 
00027 TagInfo::~TagInfo() 
00028 {
00029   free( mDefaultValue );
00030   mDefaultValue = 0;
00031   mDefaultValueSize = 0;
00032 }
00033 
00034 int TagInfo::size_from_data_type( DataType t )
00035 {
00036   static const int sizes[] = { 1, 
00037                                sizeof(int), 
00038                                sizeof(double), 
00039                                1, 
00040                                sizeof(EntityHandle),
00041                                0 };  
00042    return sizes[t];
00043 }
00044 
00045 bool TagInfo::equals_default_value( const void* data, int size ) const
00046 {
00047   if (!get_default_value())
00048     return false;
00049   
00050   if (variable_length() && size != get_default_value_size())
00051     return false;
00052   
00053   if (!variable_length() && size >=0 && size != get_size())
00054     return false;
00055     
00056   if (get_data_type() == MB_TYPE_BIT) {
00057     assert(get_size() <= 8 && get_default_value_size() == 1);
00058     unsigned char byte1 = *reinterpret_cast<const unsigned char*>(data);
00059     unsigned char byte2 = *reinterpret_cast<const unsigned char*>(get_default_value());
00060     unsigned char mask = (unsigned char)((1u << get_size()) - 1);
00061     return (byte1&mask) == (byte2&mask);
00062   }
00063   else {
00064     return !memcmp( data, get_default_value(), get_default_value_size() );
00065   }
00066 }
00067   
00068     // Check that all lengths are valid multiples of the type size.
00069     // Returns true if all lengths are valid, false othersize.
00070 bool TagInfo::check_valid_sizes( const int* sizes, int num_sizes ) const
00071 {
00072   unsigned sum = 0;
00073   const unsigned size = size_from_data_type( get_data_type() );
00074   if (size == 1)
00075     return true;
00076   for (int i = 0; i < num_sizes; ++i)
00077     sum |= ((unsigned)sizes[i]) % size;
00078   return (sum == 0);
00079 }
00080 
00081 ErrorCode TagInfo::validate_lengths( Error* error_handler,
00082                                      const int* lengths, 
00083                                      size_t num_lengths ) const
00084 {
00085   int bits = 0;
00086   if (variable_length()) {
00087     if (!lengths) {
00088       error_handler->set_last_error("No size specified for variable-length tag");
00089       return MB_VARIABLE_DATA_LENGTH;
00090     }
00091     const unsigned type_size = size_from_data_type( get_data_type() );
00092     if (type_size == 1)
00093       return MB_SUCCESS;
00094     for (size_t i = 0; i < num_lengths; ++i)
00095       bits |= lengths[i] % type_size;
00096   }
00097   else if (lengths) {
00098     for (size_t i = 0; i < num_lengths; ++i)
00099       bits |= lengths[i] - get_size();
00100   }
00101   if (!bits)
00102     return MB_SUCCESS;
00103   error_handler->set_last_error("Tag data with invalid size");
00104   return MB_INVALID_SIZE;
00105 }
00106 
00107 } // namespace moab
00108 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines