[MOAB-dev] r3570 - MOAB/trunk/tools/iMesh
kraftche at cae.wisc.edu
kraftche at cae.wisc.edu
Fri Mar 5 19:22:59 CST 2010
Author: kraftche
Date: 2010-03-05 19:22:59 -0600 (Fri, 05 Mar 2010)
New Revision: 3570
Modified:
MOAB/trunk/tools/iMesh/iMeshP_MOAB.cpp
MOAB/trunk/tools/iMesh/iMesh_MOAB.cpp
MOAB/trunk/tools/iMesh/iMesh_MOAB.hpp
Log:
Free allocated arrays in any iGeom call that returns something other than
iBase_SUCCESS (a few in iMesh_MOAB, many in iMeshP_MOAB).
Details:
Replace CHECK_SIZE macro with new macro: ALLOC_CHECK_ARRAY. The argument
list for the new macro is a lot simpler: the type is inferred from
the array type and all array arguments (pointer, allocated, size) are
inferred from the array name. Thus:
*adjacency_table_size = 16;
CHECK_SIZE(*adjacency_table, *adjacency_table_allocated,
*adjacency_table_size, int, iBase_MEMORY_ALLOCATION_FAILED);
becomes:
ALLOC_CHECK_ARRAY(adjacency_table, 16);
However, the big difference is that if (and only if) ALLOC_CHECK_ARRAY
allocated the array, then it will free it when the macro call goes out of
scope (typically when returning from the function) unless KEEP_ARRAY(name)
is called. Thus one can safely write code like:
ALLOC_CHECK_ARRAY(uv, 2*count);
for (...) {
...
if (error)
RETURN(iBase_FAILURE);
...
if (iBase_SUCCESS != *err)
return;
}
KEEP_ARRAY(uv);
RETURN(iBase_SUCCESS);
And even the hairy cases like the memory allocation for the second of
two arrays failing is handled correctly.
Also, provide the macro ALLOC_CHECK_ARRAY_NOFAIL for convenience. It
is equivalent to consecutive calls to ALLOC_CHECK_ARRAY and KEEP_ARRAY.
Modified: MOAB/trunk/tools/iMesh/iMeshP_MOAB.cpp
===================================================================
--- MOAB/trunk/tools/iMesh/iMeshP_MOAB.cpp 2010-03-06 01:10:21 UTC (rev 3569)
+++ MOAB/trunk/tools/iMesh/iMeshP_MOAB.cpp 2010-03-06 01:22:59 UTC (rev 3570)
@@ -140,40 +140,9 @@
/********************* ITAPS arrays **************************/
-// Access this method using ALLOCATE_ARRAY macro, rather than callind directly.
-template <typename ArrType> inline bool
-allocate_itaps_array( ArrType*& array, int& allocated, int& size, int requested )
-{
- size = requested;
- if (allocated) {
- return (allocated >= requested);
- }
- else {
- array = (ArrType*)malloc( requested * sizeof(ArrType) );
- allocated = requested;
- return (array != 0);
- }
-}
-
-// For use by ALLOCATE_ARRAY macro
-inline int allocate_itaps_array_failed()
-{
- strcpy( iMesh_LAST_ERROR.description,
- "Insufficient allocated array size or insufficient "
- "memory to allocate array." );
- iMesh_LAST_ERROR.error_type = iBase_MEMORY_ALLOCATION_FAILED;
- return iBase_MEMORY_ALLOCATION_FAILED;
-}
-
-// If ITAPS array is NULL, allocate it to the requested size, otherwise
-// verify that it can hold at least SIZE values.
-#define ALLOCATE_ARRAY( NAME, SIZE ) \
- if (!allocate_itaps_array( *NAME, *NAME##_allocated, *NAME##_size, (SIZE) )) \
- RETURN(allocate_itaps_array_failed())
-
// Handle returning MBRange in ITAPS array (do ALLOCATE_ARRAY and copy).
#define MBRANGE_TO_ITAPS_ARRAY( RANGE, NAME ) do { \
- ALLOCATE_ARRAY( NAME, (RANGE).size() ); \
+ ALLOC_CHECK_ARRAY_NOFAIL( NAME, (RANGE).size() ); \
std::copy( (RANGE).begin(), (RANGE).end(), itaps_cast<MBEntityHandle*>(*(NAME)) ); \
} while (false)
@@ -342,13 +311,14 @@
{
MBErrorCode rval;
MBParallelComm* pcomm = PCOMM;
- ALLOCATE_ARRAY( part_ids, part_handles_size );
+ ALLOC_CHECK_ARRAY( part_ids, part_handles_size );
for (int i = 0; i < part_handles_size; ++i) {
int id;
rval = pcomm->get_part_id( itaps_cast<MBEntityHandle>(part_handles[i]), id );
(*part_ids)[i] = id;
CHKERR(rval,"error getting part id");
}
+ KEEP_ARRAY(part_ids);
RETURN(iBase_SUCCESS);
}
@@ -364,13 +334,14 @@
{
MBErrorCode rval;
MBParallelComm* pcomm = PCOMM;
- ALLOCATE_ARRAY( part_handles, part_ids_size );
+ ALLOC_CHECK_ARRAY( part_handles, part_ids_size );
for (int i = 0; i < part_ids_size; ++i) {
MBEntityHandle handle;
rval = pcomm->get_part_handle( part_ids[i], handle );
CHKERR(rval,"error getting part handle");
(*part_handles)[i] = itaps_cast<iMeshP_PartHandle>(handle);
}
+ KEEP_ARRAY(part_handles);
RETURN(iBase_SUCCESS);
}
@@ -430,7 +401,7 @@
for (i = pcomms.begin(); i != pcomms.end(); ++i)
if ((*i)->get_partitioning())
++count;
- ALLOCATE_ARRAY( partition_handle, count );
+ ALLOC_CHECK_ARRAY_NOFAIL( partition_handle, count );
*partition_handle_size = 0;
for (i = pcomms.begin(); i != pcomms.end(); ++i)
@@ -507,12 +478,13 @@
if (!pcomm)
ERROR (iBase_FAILURE,"No PComm");
- ALLOCATE_ARRAY( rank, part_ids_size );
+ ALLOC_CHECK_ARRAY( rank, part_ids_size );
MBErrorCode rval = MB_SUCCESS;
for (int i = 0; i < part_ids_size; ++i) {
rval = pcomm->get_part_owner( part_ids[i], (*rank)[i] );
CHKERR(rval,"PComm::get_part_owner failed");
}
+ KEEP_ARRAY(rank);
RETURN(iBase_SUCCESS);
}
@@ -635,7 +607,7 @@
if (!pcomm)
ERROR (iBase_FAILURE,"No PComm");
- ALLOCATE_ARRAY( num_part_nbors, part_handles_size );
+ ALLOC_CHECK_ARRAY( num_part_nbors, part_handles_size );
int n, neighbors[MAX_SHARING_PROCS];
MBErrorCode rval;
@@ -646,6 +618,7 @@
(*num_part_nbors)[i] = n;
}
+ KEEP_ARRAY(num_part_nbors);
RETURN(iBase_SUCCESS);
}
@@ -685,7 +658,7 @@
if (!pcomm)
ERROR (iBase_FAILURE,"No PComm");
- ALLOCATE_ARRAY( num_part_nbors, part_handles_size );
+ ALLOC_CHECK_ARRAY( num_part_nbors, part_handles_size );
std::vector<int> all_neighbors;
int n, pnbor[MAX_SHARING_PROCS];
@@ -698,9 +671,10 @@
std::copy( pnbor, pnbor+n, std::back_inserter(all_neighbors) );
}
- ALLOCATE_ARRAY( nbor_part_ids, all_neighbors.size() );
+ ALLOC_CHECK_ARRAY_NOFAIL( nbor_part_ids, all_neighbors.size() );
memcpy( *nbor_part_ids, &all_neighbors[0], sizeof(int)*all_neighbors.size() );
+ KEEP_ARRAY(num_part_nbors);
RETURN(iBase_SUCCESS);
}
@@ -1059,8 +1033,8 @@
}
// get adjacencies
- ALLOCATE_ARRAY( adj_entity_handles, num_adj );
- ALLOCATE_ARRAY( offset, r.size() );
+ ALLOC_CHECK_ARRAY( adj_entity_handles, num_adj );
+ ALLOC_CHECK_ARRAY( offset, r.size() );
int arr_pos = 0;
int* offset_iter = *offset;
for (MBRange::iterator i = r.begin(); i != r.end(); ++i) {
@@ -1085,6 +1059,11 @@
in_entity_set_allocated,
in_entity_set_size,
err );
+
+ if (iBase_SUCCESS == *err) {
+ KEEP_ARRAY(adj_entity_handles);
+ KEEP_ARRAY(offset);
+ }
}
void iMeshP_initEntIter( iMesh_Instance instance,
@@ -1153,7 +1132,7 @@
ERROR (iBase_FAILURE,"No PComm");
int id;
- ALLOCATE_ARRAY( part_ids, entity_handles_size );
+ ALLOC_CHECK_ARRAY( part_ids, entity_handles_size );
MBErrorCode rval = MB_SUCCESS;
for (int i = 0; i < entity_handles_size; ++i) {
MBEntityHandle h = itaps_cast<MBEntityHandle>(entity_handles[i]);
@@ -1161,6 +1140,7 @@
(*part_ids)[i] = id;
CHKERR(rval,"Failet get part owner");
}
+ KEEP_ARRAY(part_ids);
RETURN(iBase_SUCCESS);
}
@@ -1197,7 +1177,7 @@
rval = pcomm->get_part_id( itaps_cast<MBEntityHandle>(part_handle), id );
CHKERR(rval,"error getting part id");
- ALLOCATE_ARRAY( is_owner, entity_handles_size );
+ ALLOC_CHECK_ARRAY( is_owner, entity_handles_size );
*is_owner_size = entity_handles_size;
int owner;
@@ -1207,6 +1187,7 @@
(*is_owner)[i] = (owner == id);
}
+ KEEP_ARRAY(is_owner);
RETURN(iBase_SUCCESS);
}
@@ -1245,7 +1226,7 @@
&pstatus[0]);
CHKERR(result,"error getting pstatus_tag");
- ALLOCATE_ARRAY( par_status, entity_handles_size );
+ ALLOC_CHECK_ARRAY( par_status, entity_handles_size );
for (int i = 0; i < entity_handles_size; i++) {
if (!pstatus[i])
(*par_status)[i] = iMeshP_INTERNAL;
@@ -1255,6 +1236,7 @@
(*par_status)[i] = iMeshP_BOUNDARY;
}
+ KEEP_ARRAY(par_status);
RETURN(iBase_SUCCESS);
}
@@ -1293,7 +1275,7 @@
itaps_cast<MBEntityHandle>(entity_handle),
ids, num_ids );
CHKERR(rval,"MBParallelComm::get_sharing_parts failed");
- ALLOCATE_ARRAY( part_ids, num_ids );
+ ALLOC_CHECK_ARRAY_NOFAIL( part_ids, num_ids );
std::copy( ids, ids+num_ids, *part_ids );
RETURN (iBase_SUCCESS);
}
@@ -1321,8 +1303,8 @@
itaps_cast<MBEntityHandle>(entity_handle),
ids, num_ids, handles );
CHKERR(rval,"MBParallelComm::get_sharing_parts failed");
- ALLOCATE_ARRAY( part_ids, num_ids );
- ALLOCATE_ARRAY( copies_entity_handles, num_ids );
+ ALLOC_CHECK_ARRAY_NOFAIL( part_ids, num_ids );
+ ALLOC_CHECK_ARRAY_NOFAIL( copies_entity_handles, num_ids );
for (int i = 0; i < num_ids; ++i) {
(*part_ids)[i] = ids[i];
(*copies_entity_handles)[i] = itaps_cast<iBase_EntityHandle>(handles[i]);
@@ -1730,7 +1712,7 @@
MBRange part_sets;
- ALLOCATE_ARRAY( part_handles, pc->partition_sets().size() );
+ ALLOC_CHECK_ARRAY_NOFAIL( part_handles, pc->partition_sets().size() );
MBRange::iterator rit;
int i;
for (i = 0, rit = pc->partition_sets().begin();
Modified: MOAB/trunk/tools/iMesh/iMesh_MOAB.cpp
===================================================================
--- MOAB/trunk/tools/iMesh/iMesh_MOAB.cpp 2010-03-06 01:10:21 UTC (rev 3569)
+++ MOAB/trunk/tools/iMesh/iMesh_MOAB.cpp 2010-03-06 01:22:59 UTC (rev 3570)
@@ -52,34 +52,6 @@
MBErrorCode create_int_ents(MBInterface *instance,
MBRange &from_ents,
const MBEntityHandle* in_set = 0);
-
-#define CHECK_SIZE(array, allocated, size, type, retval) \
- if (0 != allocated && NULL != array && allocated < (size)) {\
- iMesh_processError(iBase_MEMORY_ALLOCATION_FAILED, \
- "Allocated array not large enough to hold returned contents.");\
- RETURN(iBase_MEMORY_ALLOCATION_FAILED);\
- }\
- if ((size) && ((allocated) == 0 || NULL == (array))) {\
- array = (type*)malloc((size)*sizeof(type));\
- allocated=(size);\
- if (NULL == array) {iMesh_processError(iBase_MEMORY_ALLOCATION_FAILED, \
- "Couldn't allocate array.");RETURN(iBase_MEMORY_ALLOCATION_FAILED); }\
- }
-// TAG_CHECK_SIZE is like CHECK_SIZE except it checks for and makes the allocated memory
-// size a multiple of sizeof(void*), and the pointer is assumed to be type char*
-#define TAG_CHECK_SIZE(array, allocated, size) \
- if (0 != allocated && NULL != array && allocated < (size)) {\
- iMesh_processError(iBase_MEMORY_ALLOCATION_FAILED, \
- "Allocated array not large enough to hold returned contents.");\
- RETURN(iBase_MEMORY_ALLOCATION_FAILED);\
- }\
- if ((size) && (NULL == (array) || (allocated) == 0)) {\
- allocated=(size); \
- if (allocated%sizeof(void*) != 0) allocated=((size)/sizeof(void*)+1)*sizeof(void*);\
- array = (char*)malloc(allocated); \
- if (NULL == array) {iMesh_processError(iBase_MEMORY_ALLOCATION_FAILED, \
- "Couldn't allocate array.");RETURN(iBase_MEMORY_ALLOCATION_FAILED); }\
- }
#define HANDLE_ARRAY_PTR(array) reinterpret_cast<MBEntityHandle*>(array)
#define CONST_HANDLE_ARRAY_PTR(array) reinterpret_cast<const MBEntityHandle*>(array)
#define TAG_HANDLE(handle) reinterpret_cast<MBTag>(handle)
@@ -388,9 +360,7 @@
/*inout*/ int* adjacency_table_allocated,
/*out*/ int* adjacency_table_size, int *err)
{
- *adjacency_table_size = 16;
- CHECK_SIZE(*adjacency_table, *adjacency_table_allocated,
- *adjacency_table_size, int, iBase_MEMORY_ALLOCATION_FAILED);
+ ALLOC_CHECK_ARRAY_NOFAIL(adjacency_table, 16);
memcpy(*adjacency_table, MBimesh->AdjTable, 16*sizeof(int));
RETURN(iBase_SUCCESS);
}
@@ -465,7 +435,7 @@
{
// make sure we can hold them all
- CHECK_SIZE(*coords, *coords_allocated, 3*vertex_handles_size, double, iBase_MEMORY_ALLOCATION_FAILED);
+ ALLOC_CHECK_ARRAY(coords, 3*vertex_handles_size);
// now get all the coordinates
// coords will come back interleaved by default
@@ -493,9 +463,8 @@
*z = *c_iter; ++z; ++c_iter;
}
}
-
- *coords_size = 3*vertex_handles_size;
+ KEEP_ARRAY(coords);
RETURN(iBase_SUCCESS);
}
@@ -552,8 +521,7 @@
// check the size of the destination array
int expected_size = (this_it->requestedSize < (int)this_it->iteratorRange.size() ?
this_it->requestedSize : this_it->iteratorRange.size());
- CHECK_SIZE(*entity_handles, *entity_handles_allocated, expected_size,
- iBase_EntityHandle, false);
+ ALLOC_CHECK_ARRAY_NOFAIL(entity_handles, expected_size);
int i = 0;
while (i < this_it->requestedSize && this_it->currentPos != this_it->iteratorRange.end())
@@ -599,8 +567,7 @@
/*out*/ int* topology_size, int *err)
{
// go through each entity and look up its type
- CHECK_SIZE(*topology, *topology_allocated, entity_handles_size,
- int, iBase_MEMORY_ALLOCATION_FAILED);
+ ALLOC_CHECK_ARRAY_NOFAIL(topology, entity_handles_size);
for (int i = 0; i < entity_handles_size; i++)
(*topology)[i] =
@@ -619,8 +586,7 @@
/*out*/ int* etype_size, int *err)
{
// go through each entity and look up its type
- CHECK_SIZE(*etype, *etype_allocated, entity_handles_size,
- int, iBase_MEMORY_ALLOCATION_FAILED);
+ ALLOC_CHECK_ARRAY_NOFAIL(etype, entity_handles_size);
for (int i = 0; i < entity_handles_size; i++)
(*etype)[i] =
@@ -644,8 +610,7 @@
{
MBErrorCode result = MB_SUCCESS;
- CHECK_SIZE(*offset, *offset_allocated, entity_handles_size+1,
- int, iBase_MEMORY_ALLOCATION_FAILED);
+ ALLOC_CHECK_ARRAY(offset, entity_handles_size+1);
const MBEntityHandle* entity_iter = (const MBEntityHandle*)entity_handles;
const MBEntityHandle* const entity_end = entity_iter + entity_handles_size;
@@ -677,7 +642,11 @@
if (iBase_VERTEX == entity_type_requested &&
TYPE_FROM_HANDLE(*entity_iter) != MBPOLYHEDRON) {
result = MBI->get_connectivity(*entity_iter, connect, num_connect, false, &conn_storage);
- CHKERR(result, "iMesh_getEntArrAdj: trouble getting adjacency list.");
+ if (MB_SUCCESS != result) {
+ if (allocated_array)
+ free(array);
+ ERROR(result, "iMesh_getEntArrAdj: trouble getting adjacency list.");
+ }
}
else if (iBase_ALL_TYPES == entity_type_requested) {
adj_ents.clear();
@@ -685,7 +654,11 @@
if (MBCN::Dimension(TYPE_FROM_HANDLE(*entity_iter)) == dim)
continue;
result = MBI->get_adjacencies( entity_iter, 1, dim, false, adj_ents, MBInterface::UNION );
- CHKERR(result, "iMesh_getEntArrAdj: trouble getting adjacency list.");
+ if (MB_SUCCESS != result) {
+ if (allocated_array)
+ free(array);
+ ERROR(result, "iMesh_getEntArrAdj: trouble getting adjacency list.");
+ }
}
connect = &adj_ents[0];
num_connect = adj_ents.size();
@@ -694,7 +667,11 @@
adj_ents.clear();
result = MBI->get_adjacencies( entity_iter, 1,
entity_type_requested, false, adj_ents );
- CHKERR(result, "iMesh_getEntArrAdj: trouble getting adjacency list.");
+ if (MB_SUCCESS != result) {
+ if (allocated_array)
+ free(array);
+ ERROR(result, "iMesh_getEntArrAdj: trouble getting adjacency list.");
+ }
connect = &adj_ents[0];
num_connect = adj_ents.size();
}
@@ -726,7 +703,6 @@
prev_off += num_connect;
}
*off_iter = prev_off;
- *offset_size = entity_handles_size+1;
*adjacentEntityHandles_size = prev_off;
if (*adjacentEntityHandles_size > array_alloc) {
@@ -737,6 +713,7 @@
*adjacentEntityHandles_allocated = array_alloc;
}
+ KEEP_ARRAY(offset);
RETURN(iBase_SUCCESS);
}
@@ -755,8 +732,7 @@
{
MBErrorCode result = MB_SUCCESS;
- CHECK_SIZE(*offset, *offset_allocated, entity_handles_size+1,
- int, iBase_MEMORY_ALLOCATION_FAILED);
+ ALLOC_CHECK_ARRAY(offset, entity_handles_size+1 );
const MBEntityHandle* entity_iter = (const MBEntityHandle*)entity_handles;
const MBEntityHandle* const entity_end = entity_iter + entity_handles_size;
@@ -782,14 +758,11 @@
}
*off_iter = prev_off;
- CHECK_SIZE(*adj_entity_handles, *adj_entity_handles_allocated,
- (int)all_adj_ents.size(),
- iBase_EntityHandle, iBase_MEMORY_ALLOCATION_FAILED);
+ ALLOC_CHECK_ARRAY_NOFAIL(adj_entity_handles, all_adj_ents.size() );
memcpy(*adj_entity_handles, &all_adj_ents[0],
sizeof(MBEntityHandle)*all_adj_ents.size() );
- *adj_entity_handles_size = all_adj_ents.size();
- *offset_size = entity_handles_size+1;
+ KEEP_ARRAY(offset);
RETURN(iBase_SUCCESS);
}
@@ -1006,8 +979,7 @@
sets,
std::max( num_hops, 0 ) );
CHKERR(rval, "iMesh_entitysetGetEntitySets: problem getting entities by type.");
- CHECK_SIZE(*contained_entset_handles, *contained_entset_handles_allocated,
- (int)sets.size(), iBase_EntitySetHandle, iBase_MEMORY_ALLOCATION_FAILED);
+ ALLOC_CHECK_ARRAY_NOFAIL(contained_entset_handles, sets.size() );
std::copy( sets.begin(), sets.end(), (MBEntityHandle*)*contained_entset_handles );
*contained_entset_handles_size = sets.size();
@@ -1104,8 +1076,7 @@
{
MBEntityHandle set = ENTITY_HANDLE(containing_set);
- CHECK_SIZE(*is_contained, *is_contained_allocated,
- (int)num_entity_handles, int, iBase_MEMORY_ALLOCATION_FAILED);
+ ALLOC_CHECK_ARRAY_NOFAIL(is_contained, num_entity_handles);
*is_contained_size = num_entity_handles;
if (containing_set) {
@@ -1218,15 +1189,12 @@
(ENTITY_HANDLE(from_entity_set), children, num_hops);
CHKERR(result,"ERROR getChildren failed.");
- CHECK_SIZE(*entity_set_handles, *entity_set_handles_allocated,
- (int)children.size(), iBase_EntitySetHandle, iBase_MEMORY_ALLOCATION_FAILED);
+ ALLOC_CHECK_ARRAY_NOFAIL(entity_set_handles, children.size());
MBEntityHandle *ents = HANDLE_ARRAY_PTR(*entity_set_handles);
// use a memcpy for efficiency
memcpy(ents, &children[0], children.size()*sizeof(MBEntityHandle));
- *entity_set_handles_size = children.size();
-
RETURN(iBase_SUCCESS);
}
@@ -1244,15 +1212,12 @@
CHKERR(result,"ERROR getParents failed.");
- CHECK_SIZE(*entity_set_handles, *entity_set_handles_allocated,
- (int)parents.size(), iBase_EntitySetHandle, iBase_MEMORY_ALLOCATION_FAILED);
+ ALLOC_CHECK_ARRAY_NOFAIL(entity_set_handles, parents.size());
MBEntityHandle *ents = HANDLE_ARRAY_PTR(*entity_set_handles);
// use a memcpy for efficiency
memcpy(ents, &parents[0], parents.size()*sizeof(MBEntityHandle));
- *entity_set_handles_size = parents.size();
-
RETURN(iBase_SUCCESS);
}
@@ -1298,8 +1263,7 @@
}
// if there aren't any elements in the array, allocate it
- CHECK_SIZE(*new_vertex_handles, *new_vertex_handles_allocated,
- num_verts, iBase_EntityHandle, iBase_MEMORY_ALLOCATION_FAILED);
+ ALLOC_CHECK_ARRAY(new_vertex_handles, num_verts);
// make the entities
MBEntityHandle *new_verts = HANDLE_ARRAY_PTR(*new_vertex_handles);
@@ -1309,8 +1273,7 @@
CHKERR(result, "iMesh_createVtxArr: couldn't create vertex.");
}
- *new_vertex_handles_size = new_coords_size/3;
-
+ KEEP_ARRAY(new_vertex_handles);
RETURN(iBase_SUCCESS);
}
@@ -1347,12 +1310,12 @@
}
// if there aren't any elements in the array, allocate it
- CHECK_SIZE(*new_entity_handles, *new_entity_handles_allocated,
- num_ents, iBase_EntityHandle, iBase_MEMORY_ALLOCATION_FAILED);
+
+ // This function is poorly defined. We have to return allocated
+ // arrays even if we fail.
+ ALLOC_CHECK_ARRAY_NOFAIL(new_entity_handles, num_ents);
+ ALLOC_CHECK_ARRAY_NOFAIL(status, num_ents);
- CHECK_SIZE(*status, *status_allocated, num_ents,
- int, iBase_MEMORY_ALLOCATION_FAILED);
-
// make the entities
MBEntityHandle *new_ents = HANDLE_ARRAY_PTR(*new_entity_handles);
@@ -1644,19 +1607,15 @@
MBErrorCode result = MBI->tag_get_size(tag, tag_size);
CHKERR(result, "iMesh_getEntSetData: couldn't get tag size.");
- TAG_CHECK_SIZE(*tag_value, *tag_value_allocated, tag_size);
-
+ ALLOC_CHECK_TAG_ARRAY(tag_value, tag_size);
+
if (eh == 0)
result = MBI->tag_get_data(tag, NULL, 0, *tag_value);
else
result = MBI->tag_get_data(tag, &eh, 1, *tag_value);
- if (MB_SUCCESS != result) {
- ERROR(result, "iMesh_getEntSetData didn't succeed.");
- }
- else
- *tag_value_size = tag_size;
-
+ CHKERR(result, "iMesh_getEntSetData didn't succeed.");
+ KEEP_ARRAY(tag_value);
RETURN(iBase_SUCCESS);
}
@@ -1717,8 +1676,7 @@
CHKERR(result, "iMesh_entitysetGetAllTagHandles failed.");
// now put those tag handles into sidl array
- CHECK_SIZE(*tag_handles, *tag_handles_allocated,
- (int)all_tags.size(), iBase_TagHandle, iBase_MEMORY_ALLOCATION_FAILED);
+ ALLOC_CHECK_ARRAY_NOFAIL(tag_handles, all_tags.size());
memcpy(*tag_handles, &all_tags[0], all_tags.size()*sizeof(MBTag));
*tag_handles_size = (int) all_tags.size();
@@ -1829,8 +1787,7 @@
RETURN(iBase_SUCCESS);
}
- TAG_CHECK_SIZE(*tag_values, *tag_values_allocated,
- tag_size * entity_handles_size);
+ ALLOC_CHECK_TAG_ARRAY(tag_values, tag_size * entity_handles_size);
result = MBI->tag_get_data(tag, ents, entity_handles_size,
*tag_values);
@@ -1851,7 +1808,7 @@
ERROR(result, message.c_str());
}
- *tag_values_size = tag_size * entity_handles_size;
+ KEEP_ARRAY(tag_values);
RETURN(iBase_SUCCESS);
}
@@ -2137,8 +2094,7 @@
CHKERR(result, "iMesh_getAllTags failed.");
// now put those tag handles into sidl array
- CHECK_SIZE(*tag_handles, *tag_handles_allocated,
- (int)all_tags.size(), iBase_TagHandle, iBase_MEMORY_ALLOCATION_FAILED);
+ ALLOC_CHECK_ARRAY_NOFAIL(tag_handles, all_tags.size());
memcpy(*tag_handles, &all_tags[0], all_tags.size()*sizeof(MBTag));
*tag_handles_size = all_tags.size();
@@ -2379,8 +2335,7 @@
int num_ents = out_entities.size();
- CHECK_SIZE(*entity_handles, *entity_handles_allocated,
- num_ents, iBase_EntityHandle, iBase_MEMORY_ALLOCATION_FAILED);
+ ALLOC_CHECK_ARRAY_NOFAIL(entity_handles, num_ents);
int k = 0;
@@ -2576,8 +2531,7 @@
CHKERR(result,"iMesh_GetEntities:ERROR getting entities.");
- CHECK_SIZE(*entity_handles, *entity_handles_allocated,
- (int)out_entities.size(), iBase_EntityHandle, iBase_MEMORY_ALLOCATION_FAILED);
+ ALLOC_CHECK_ARRAY_NOFAIL(entity_handles, out_entities.size());
MBRange::iterator iter = out_entities.begin();
MBRange::iterator end_iter = out_entities.end();
@@ -2622,14 +2576,9 @@
MBInterface::INTERSECT, recursive);
CHKERR(result,"ERROR getting entities.");
- CHECK_SIZE(*set_handles, *set_handles_allocated,
- (int)out_entities.size(), iBase_EntitySetHandle, iBase_MEMORY_ALLOCATION_FAILED);
-
+ ALLOC_CHECK_ARRAY_NOFAIL(set_handles, out_entities.size());
+
std::copy(out_entities.begin(), out_entities.end(), ((MBEntityHandle*) *set_handles));
-
- // now it's safe to set the size; set it to k, not out_entities.size(), to
- // account for sets which might have been removed
- *set_handles_size = out_entities.size();
RETURN(iBase_SUCCESS);
}
Modified: MOAB/trunk/tools/iMesh/iMesh_MOAB.hpp
===================================================================
--- MOAB/trunk/tools/iMesh/iMesh_MOAB.hpp 2010-03-06 01:10:21 UTC (rev 3569)
+++ MOAB/trunk/tools/iMesh/iMesh_MOAB.hpp 2010-03-06 01:22:59 UTC (rev 3570)
@@ -4,6 +4,7 @@
#include "iMesh.h"
#include "MBForward.hpp"
#include <cstring>
+#include <cstdlib>
/* map from MB's entity type to TSTT's entity topology */
extern const iMesh_EntityTopology tstt_topology_table[MBMAXTYPE+1];
@@ -96,4 +97,69 @@
{ return (MB_SUCCESS != code); }
+// Check the array size, and allocate the array if necessary.
+// Free the array upon leaving scope unless KEEP_ARRAY
+// is invoked.
+#define ALLOC_CHECK_ARRAY(array, this_size) \
+ iMeshArrayManager array ## _manager ( reinterpret_cast<void**>(array), *(array ## _allocated), *(array ## _size), this_size, sizeof(**array), err ); \
+ if (iBase_SUCCESS != *err) return
+
+#define ALLOC_CHECK_TAG_ARRAY(array, this_size) \
+ iMeshArrayManager array ## _manager ( reinterpret_cast<void**>(array), *(array ## _allocated), *(array ## _size), this_size, 1, err ); \
+ if (iBase_SUCCESS != *err) return
+
+#define KEEP_ARRAY(array) \
+ array ## _manager .keep_array()
+
+// Check the array size, and allocate the array if necessary.
+// Do NOT free the array upon leaving scope.
+#define ALLOC_CHECK_ARRAY_NOFAIL(array, this_size) \
+ ALLOC_CHECK_ARRAY(array, this_size); KEEP_ARRAY(array)
+
+
+// Implement RAII pattern for allocated arrays
+class iMeshArrayManager
+{
+ void** arrayPtr;
+
+public:
+
+
+ iMeshArrayManager( void** array_ptr,
+ int& array_allocated_space,
+ int& array_size,
+ int count,
+ int val_size,
+ int* err ) : arrayPtr(0)
+ {
+ if (!*array_ptr) {
+ *array_ptr = std::malloc(val_size * count);
+ array_allocated_space = array_size = count;
+ if (!*array_ptr) {
+ IBASE_ERROR(iBase_MEMORY_ALLOCATION_FAILED, "Couldn't allocate array.");
+ }
+ arrayPtr = array_ptr;
+ }
+ else {
+ array_size = count;
+ if (array_allocated_space < count) {
+ IBASE_ERROR(iBase_BAD_ARRAY_DIMENSION,
+ "Allocated array not large enough to hold returned contents.");
+ }
+ }
+ RETURN(iBase_SUCCESS);
+ }
+
+ ~iMeshArrayManager()
+ {
+ if (arrayPtr) {
+ std::free(*arrayPtr);
+ *arrayPtr = 0;
+ }
+ }
+
+ void keep_array()
+ { arrayPtr = 0; }
+};
+
#endif // IMESH_MOAB_HPP
More information about the moab-dev
mailing list