1 #include "TagInfo.hpp"
2 #include "moab/Error.hpp"
3 #include "moab/ErrorHandler.hpp"
4 #include <string.h> /* memcpy */
5 #include <stdlib.h> /* realloc & free */
6 #include <assert.h>
7
8 namespace moab {
9
TagInfo(const char * name,int size,DataType type,const void * default_value,int default_value_size)10 TagInfo::TagInfo(const char* name,
11 int size,
12 DataType type,
13 const void* default_value,
14 int default_value_size)
15 : mDefaultValue(NULL),
16 mMeshValue(NULL),
17 mDefaultValueSize(default_value_size),
18 mMeshValueSize(0),
19 mDataSize(size),
20 dataType(type)
21 {
22 if (default_value) {
23 mDefaultValue = malloc(mDefaultValueSize);
24 memcpy(mDefaultValue, default_value, mDefaultValueSize);
25 }
26 if (name)
27 mTagName = name;
28 }
29
~TagInfo()30 TagInfo::~TagInfo()
31 {
32 free(mDefaultValue);
33 mDefaultValue = 0;
34 mDefaultValueSize = 0;
35 }
36
size_from_data_type(DataType t)37 int TagInfo::size_from_data_type(DataType t)
38 {
39 static const int sizes[] = {1,
40 sizeof(int),
41 sizeof(double),
42 1,
43 sizeof(EntityHandle),
44 0 };
45 return sizes[t];
46 }
47
equals_default_value(const void * data,int size) const48 bool TagInfo::equals_default_value(const void* data, int size) const
49 {
50 if (!get_default_value())
51 return false;
52
53 if (variable_length() && size != get_default_value_size())
54 return false;
55
56 if (!variable_length() && size >=0 && size != get_size())
57 return false;
58
59 if (get_data_type() == MB_TYPE_BIT) {
60 assert(get_size() <= 8 && get_default_value_size() == 1);
61 unsigned char byte1 = *reinterpret_cast<const unsigned char*>(data);
62 unsigned char byte2 = *reinterpret_cast<const unsigned char*>(get_default_value());
63 unsigned char mask = (unsigned char)((1u << get_size()) - 1);
64 return (byte1 & mask) == (byte2 & mask);
65 }
66 else {
67 return !memcmp(data, get_default_value(), get_default_value_size());
68 }
69 }
70
71 // Check that all lengths are valid multiples of the type size.
72 // Returns true if all lengths are valid, false otherwise.
check_valid_sizes(const int * sizes,int num_sizes) const73 bool TagInfo::check_valid_sizes(const int* sizes, int num_sizes) const
74 {
75 const unsigned size = size_from_data_type(get_data_type());
76 if (1 == size)
77 return true;
78
79 unsigned sum = 0;
80 for (int i = 0; i < num_sizes; ++i)
81 sum |= ((unsigned)sizes[i]) % size;
82
83 return (0 == sum);
84 }
85
validate_lengths(Error *,const int * lengths,size_t num_lengths) const86 ErrorCode TagInfo::validate_lengths(Error* /* error_handler */,
87 const int* lengths,
88 size_t num_lengths) const
89 {
90 int bits = 0;
91 if (variable_length()) {
92 if (!lengths) {
93 MB_SET_ERR(MB_VARIABLE_DATA_LENGTH, "No size specified for variable-length tag");
94 }
95 const unsigned type_size = size_from_data_type(get_data_type());
96 if (type_size == 1)
97 return MB_SUCCESS;
98 for (size_t i = 0; i < num_lengths; ++i)
99 bits |= lengths[i] % type_size;
100 }
101 else if (lengths) {
102 for (size_t i = 0; i < num_lengths; ++i)
103 bits |= lengths[i] - get_size();
104 }
105 if (0 == bits)
106 return MB_SUCCESS;
107
108 MB_SET_ERR(MB_INVALID_SIZE, "Tag data with invalid size");
109 }
110
111 } // namespace moab
112