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