moab
|
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