#include "TagInfo.hpp"
#include "moab/Error.hpp"
#include "moab/ErrorHandler.hpp"
#include <cstring> /* memcpy */
#include <cstdlib> /* realloc & free */
#include <cassert>
namespace moab
{
TagInfo::TagInfo( const char* name, int size, DataType type, const void* default_value, int default_value_size )
: mDefaultValue( NULL ), mMeshValue( NULL ), mDefaultValueSize( default_value_size ), mMeshValueSize( 0 ),
mDataSize( size ), dataType( type )
{
if( default_value )
{
mDefaultValue = malloc( mDefaultValueSize );
memcpy( mDefaultValue, default_value, mDefaultValueSize );
}
if( name ) mTagName = name;
}
TagInfo::~TagInfo()
{
free( mDefaultValue );
mDefaultValue = 0;
mDefaultValueSize = 0;
}
int TagInfo::size_from_data_type( DataType t )
{
static const int sizes[] = { 1, sizeof( int ), sizeof( double ), 1, sizeof( EntityHandle ), 0 };
return sizes[t];
}
bool TagInfo::equals_default_value( const void* data, int size ) const
{
if( !get_default_value() ) return false;
if( variable_length() && size != get_default_value_size() ) return false;
if( !variable_length() && size >= 0 && size != get_size() ) return false;
if( get_data_type() == MB_TYPE_BIT )
{
assert( get_size() <= 8 && get_default_value_size() == 1 );
unsigned char byte1 = *reinterpret_cast< const unsigned char* >( data );
unsigned char byte2 = *reinterpret_cast< const unsigned char* >( get_default_value() );
unsigned char mask = (unsigned char)( ( 1u << get_size() ) - 1 );
return ( byte1 & mask ) == ( byte2 & mask );
}
else
{
return !memcmp( data, get_default_value(), get_default_value_size() );
}
}
// Check that all lengths are valid multiples of the type size.
// Returns true if all lengths are valid, false otherwise.
bool TagInfo::check_valid_sizes( const int* sizes, int num_sizes ) const<--- The function 'check_valid_sizes' is never used.
{
const unsigned size = size_from_data_type( get_data_type() );
if( 1 == size ) return true;
unsigned sum = 0;
for( int i = 0; i < num_sizes; ++i )
sum |= ( (unsigned)sizes[i] ) % size;
return ( 0 == sum );
}
ErrorCode TagInfo::validate_lengths( Error* /* error_handler */, const int* lengths, size_t num_lengths ) const
{
int bits = 0;
if( variable_length() )
{
if( !lengths )
{
MB_SET_ERR( MB_VARIABLE_DATA_LENGTH, "No size specified for variable-length tag" );
}
const unsigned type_size = size_from_data_type( get_data_type() );
if( type_size == 1 ) return MB_SUCCESS;
for( size_t i = 0; i < num_lengths; ++i )
bits |= lengths[i] % type_size;
}
else if( lengths )
{
for( size_t i = 0; i < num_lengths; ++i )
bits |= lengths[i] - get_size();
}
if( 0 == bits ) return MB_SUCCESS;
MB_SET_ERR( MB_INVALID_SIZE, "Tag data with invalid size" );
}
} // namespace moab