[MOAB-dev] r1469 - MOAB/trunk
kraftche at mcs.anl.gov
kraftche at mcs.anl.gov
Fri Dec 14 13:26:27 CST 2007
Author: kraftche
Date: 2007-12-14 13:26:27 -0600 (Fri, 14 Dec 2007)
New Revision: 1469
Added:
MOAB/trunk/MBSysUtil.cpp
MOAB/trunk/MBSysUtil.hpp
Modified:
MOAB/trunk/Makefile.am
MOAB/trunk/ReadSTL.cpp
MOAB/trunk/ReadSTL.hpp
MOAB/trunk/SequenceData.cpp
MOAB/trunk/SequenceManager.cpp
MOAB/trunk/WriteSTL.cpp
Log:
o Add new MBSysUtil for low-level utility functions
o Consolidate some duplicate code into common functions in MBSysUtil
o Fix bug in range-based query for dense tag values where default is
not returned when a sequence w/ no allocated data is encountered.
Added: MOAB/trunk/MBSysUtil.cpp
===================================================================
--- MOAB/trunk/MBSysUtil.cpp (rev 0)
+++ MOAB/trunk/MBSysUtil.cpp 2007-12-14 19:26:27 UTC (rev 1469)
@@ -0,0 +1,182 @@
+#include "MBSysUtil.hpp"
+
+#include <fstream>
+#include <algorithm>
+#include <assert.h>
+
+#include "MBEntityHandle.h"
+#ifdef MOAB_HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+#ifdef MOAB_HAVE_STDDEF_H
+#include <stddef.h>
+#endif
+#ifdef MOAB_HAVE_STDINT_H
+#include <stdint.h>
+#endif
+
+#ifdef _MSC_VER /* windows */
+# include <BaseTsd.h>
+typedef ULONG16 uint16_t;
+typedef ULONG32 uint32_t;
+typedef ULONG64 uint64_t;
+#endif
+
+namespace MBSysUtil
+{
+
+
+void setmem( void* mem, const void* value, unsigned value_size, size_t num_elem )
+{
+ if (!num_elem)
+ return;
+
+ char* array = reinterpret_cast<char*>(mem);
+ memcpy( array, value, value_size );
+ size_t count;
+ for (count = 1; count*2 < num_elem; count *= 2)
+ memcpy( array + count * value_size, array, count * value_size );
+ memcpy( array + count * value_size, array, (num_elem - count) * value_size );
+}
+
+
+long filesize( FILE* filp )
+{
+ long curr_pos = ftell( filp );
+ if (fseek( filp, 0, SEEK_END ))
+ return -1;
+
+ long length = ftell( filp );
+ if (fseek( filp, curr_pos, SEEK_SET))
+ {
+ assert(0);
+ return -2;
+ }
+
+ return length;
+}
+
+
+long filesize( std::ifstream& str )
+{
+ std::istream::pos_type curr_pos = str.tellg();
+ if (!str.seekg( 0, std::ios_base::end ))
+ return -1;
+
+ long length = static_cast<long>(str.tellg());
+ if (!str.seekg( curr_pos, std::ios_base::beg ))
+ {
+ assert(0);
+ return -2;
+ }
+
+ return length;
+}
+
+
+void byteswap( void* data, unsigned value_size, size_t num_elem )
+{
+ char* mem = reinterpret_cast<char*>(data);
+ char* const end = mem + value_size * num_elem;
+ for ( ; mem < end; mem += value_size) {
+ unsigned i = 0, j = value_size - 1;
+ while (i < j)
+ std::swap( mem[i++], mem[j--] );
+ }
+}
+
+inline static uint16_t swap_bytes( uint16_t value )
+{
+ return ((value & (uint16_t)0xFF00) >> 8) |
+ ((value & (uint16_t)0x00FF) << 8);
+}
+
+inline static uint32_t swap_bytes( uint32_t value )
+{
+ return ((value & (uint32_t)0xFF000000) >> 24) |
+ ((value & (uint32_t)0x00FF0000) >> 8) |
+ ((value & (uint32_t)0x0000FF00) << 8) |
+ ((value & (uint32_t)0X000000FF) << 24);
+}
+
+inline static uint64_t swap_bytes( uint64_t value )
+{
+ return ((value & (uint64_t)0xFF00000000000000) >> 56) |
+ ((value & (uint64_t)0x00FF000000000000) >> 40) |
+ ((value & (uint64_t)0x0000FF0000000000) >> 24) |
+ ((value & (uint64_t)0x000000FF00000000) >> 8) |
+ ((value & (uint64_t)0x00000000FF000000) << 8) |
+ ((value & (uint64_t)0X0000000000FF0000) << 24) |
+ ((value & (uint64_t)0x000000000000FF00) << 40) |
+ ((value & (uint64_t)0X00000000000000FF) << 56);
+}
+/*
+inline static uint32_t swap_byte_pairs( uint32_t value )
+{
+ return ((value & (uint32_t)0xFF000000) >> 8) |
+ ((value & (uint32_t)0x00FF0000) << 8) |
+ ((value & (uint32_t)0x0000FF00) >> 8) |
+ ((value & (uint32_t)0X000000FF) << 8);
+}
+
+inline static uint64_t swap_byte_quads( uint64_t value )
+{
+ return ((value & (uint64_t)0xFF00000000000000) >> 24) |
+ ((value & (uint64_t)0x00FF000000000000) >> 8) |
+ ((value & (uint64_t)0x0000FF0000000000) << 8) |
+ ((value & (uint64_t)0x000000FF00000000) << 24) |
+ ((value & (uint64_t)0x00000000FF000000) >> 24) |
+ ((value & (uint64_t)0X0000000000FF0000) >> 8) |
+ ((value & (uint64_t)0x000000000000FF00) << 8) |
+ ((value & (uint64_t)0X00000000000000FF) << 24);
+}
+
+inline static uint64_t swap_byte_pairs( uint64_t value )
+{
+ return ((value & (uint64_t)0xFF00000000000000) >> 8) |
+ ((value & (uint64_t)0x00FF000000000000) << 8) |
+ ((value & (uint64_t)0x0000FF0000000000) >> 8) |
+ ((value & (uint64_t)0x000000FF00000000) << 8) |
+ ((value & (uint64_t)0x00000000FF000000) >> 8) |
+ ((value & (uint64_t)0X0000000000FF0000) << 8) |
+ ((value & (uint64_t)0x000000000000FF00) >> 8) |
+ ((value & (uint64_t)0X00000000000000FF) << 8);
+}
+*/
+void byteswap2( void* data, size_t num_elem )
+{
+ uint16_t* mem = reinterpret_cast<uint16_t*>(data);
+ uint16_t* end = mem + num_elem;
+ for (; mem < end; ++mem)
+ *mem = swap_bytes( *mem );
+}
+
+void byteswap4( void* data, size_t num_elem )
+{
+ uint32_t* mem = reinterpret_cast<uint32_t*>(data);
+ uint32_t* end = mem + num_elem;
+ for (; mem < end; ++mem)
+ *mem = swap_bytes( *mem );
+}
+
+void byteswap8( void* data, size_t num_elem )
+{
+ if (sizeof(void*) >= 8) {
+ uint64_t* mem = reinterpret_cast<uint64_t*>(data);
+ uint64_t* end = mem + num_elem;
+ for (; mem < end; ++mem)
+ *mem = swap_bytes( *mem );
+ }
+ else {
+ uint32_t* mem = reinterpret_cast<uint32_t*>(data);
+ uint32_t* end = mem + 2*num_elem;
+ for (; mem < end; mem += 2) {
+ uint32_t tmp = swap_bytes( mem[0] );
+ mem[0] = swap_bytes( mem[1] );
+ mem[1] = tmp;
+ }
+ }
+}
+
+} // namespace MBSysUtil
+
Added: MOAB/trunk/MBSysUtil.hpp
===================================================================
--- MOAB/trunk/MBSysUtil.hpp (rev 0)
+++ MOAB/trunk/MBSysUtil.hpp 2007-12-14 19:26:27 UTC (rev 1469)
@@ -0,0 +1,106 @@
+#ifndef MB_SYS_UTIL_HPP
+#define MB_SYS_UTIL_HPP
+
+#include <string.h> // for size_t
+#include <stdio.h>
+#include <iosfwd>
+
+namespace MBSysUtil
+{
+
+/**\brief Similar to memset, but accepts values larger than 1 char
+ *
+ * Set block of memory to repeating copies of a sequene of bytes.
+ *\param mem Pointer to start of memory block to initialize
+ *\param value Byte sequence to initialize mem with
+ *\param value_size Size of 'value'
+ *\param num_elem Size of 'mem' as a multiple of value_size (the number of
+ * copies of 'value' to write into 'mem'.)
+ */
+void setmem( void* mem, const void* value, unsigned value_size, size_t num_elem );
+
+/**\brief Get size of file (if it is a regular file)
+ *
+ * Get size of regular file.
+ *\return - file size if known
+ * - -1 if file size cannot be determined (e.g. a pipe)
+ * - -2 if an unexpected failure occured (may indicate change
+ * in file position.)
+ */
+long filesize( FILE* filp );
+
+/**\brief Get size of file (if it is a regular file)
+ *
+ * Get size of regular file.
+ *\return - file size if known
+ * - -1 if file size cannot be determined (e.g. a pipe)
+ * - -2 if an unexpected failure occured (may indicate change
+ * in file position.)
+ */
+long filesize( std::ifstream& str );
+
+/**\brief Check if platform is little-endian
+ *
+ * Check if platform is little-endian (least significant
+ * byte at highest memory address.)
+ */
+inline bool little_endian()
+{
+ const unsigned one = 1;
+ return !*((char*)&one);
+}
+
+/**\brief Check if platform is big-endian
+ *
+ * Check if platform is big-endian (least significant
+ * byte at lowest memory address.)
+ */
+inline bool big_endian()
+{
+ const unsigned one = 1;
+ return !(((char*)&one)[sizeof(unsigned)-1]);
+}
+
+/**\brief Swap byte order (e.g. change from big-endian to little-endian)
+ *
+ * Reverse byte order or array of values.
+ *\param data Pointer to beginning of memory block to modify
+ *\param values_size Size of one value
+ *\param num_elem Number of values of size 'value_size' in 'data'
+ */
+void byteswap( void* data, unsigned value_size, size_t num_elem );
+
+/**\brief Alternate byteswap optimized for 2-byte values */
+void byteswap2( void* data, size_t num_elem );
+/**\brief Alternate byteswap optimized for 4-byte values */
+void byteswap4( void* data, size_t num_elem );
+/**\brief Alternate byteswap optimized for 8-byte values */
+void byteswap8( void* data, size_t num_elem );
+
+/**\brief Type-specific byte swap */
+template <typename T>
+inline void byteswap( T* data, size_t num_elem )
+{
+ switch (sizeof(T)) {
+ case 1:
+ break;
+ case 2:
+ byteswap2( data, num_elem );
+ break;
+ case 4:
+ byteswap4( data, num_elem );
+ break;
+ case 8:
+ byteswap8( data, num_elem );
+ break;
+ default:
+ byteswap( data, sizeof(T), num_elem );
+ break;
+ }
+}
+
+
+} // namespace MBSysUtil
+
+
+#endif
Modified: MOAB/trunk/Makefile.am
===================================================================
--- MOAB/trunk/Makefile.am 2007-12-13 22:09:27 UTC (rev 1468)
+++ MOAB/trunk/Makefile.am 2007-12-14 19:26:27 UTC (rev 1469)
@@ -136,6 +136,8 @@
MBReadUtil.hpp \
MBReaderWriterSet.cpp \
MBSkinner.cpp \
+ MBSysUtil.cpp \
+ MBSysUtil.hpp \
MBUtil.cpp \
MBWriteUtil.cpp \
MBWriteUtil.hpp \
Modified: MOAB/trunk/ReadSTL.cpp
===================================================================
--- MOAB/trunk/ReadSTL.cpp 2007-12-13 22:09:27 UTC (rev 1468)
+++ MOAB/trunk/ReadSTL.cpp 2007-12-14 19:26:27 UTC (rev 1469)
@@ -26,6 +26,7 @@
#include "MBReadUtilIface.hpp"
#include "MBRange.hpp"
#include "FileOptions.hpp"
+#include "MBSysUtil.hpp"
#include "MBEntityHandle.h"
#ifdef MOAB_HAVE_INTTYPES_H
@@ -50,31 +51,7 @@
#include <map>
-inline static uint32_t byte_swap( uint32_t value )
-{
- return ((value & 0xFF000000) >> 24) |
- ((value & 0x00FF0000) >> 8) |
- ((value & 0x0000FF00) << 8) |
- ((value & 0X000000FF) << 24);
-}
-
-inline static float byte_swap( float value )
-{
- uint32_t bytes = byte_swap( *(uint32_t*)&value );
- return *(float*)&bytes;
-}
-
-
-inline static bool is_platform_little_endian()
-{
- static const unsigned int one = 1;
- static const bool little = !*((char*)&one);
- return little;
-}
-
-
-
ReadSTL::ReadSTL(MBInterface* impl)
: mdbImpl(impl)
{
@@ -237,23 +214,6 @@
}
-long ReadSTL::get_file_size( FILE* file )
-{
- long curr_pos = ftell( file );
- if (fseek( file, 0, SEEK_END ))
- return -1;
-
- long length = ftell( file );
- if (fseek( file, curr_pos, SEEK_SET))
- {
- assert(0);
- return -2;
- }
-
- return length;
-}
-
-
// Read ASCII file
MBErrorCode ReadSTL::ascii_read_triangles( const char* name,
std::vector<ReadSTL::Triangle>& tris )
@@ -355,7 +315,7 @@
// Allow user setting for byte order, default to little endian
const bool want_big_endian = (byte_order == STL_BIG_ENDIAN);
- const bool am_big_endian = !is_platform_little_endian();
+ const bool am_big_endian = !MBSysUtil::little_endian();
bool swap_bytes = (want_big_endian == am_big_endian);
// Compare the number of triangles to the length of the file.
@@ -371,10 +331,12 @@
// num_tri, resulting in a SEGFAULT.
// Get expected number of triangles
- unsigned long num_tri = swap_bytes ? byte_swap(header.count) : header.count;
+ unsigned long num_tri = header.count;
+ if (swap_bytes)
+ MBSysUtil::byteswap( &num_tri, 1 );
// Get the file length
- long filesize = get_file_size( file );
+ long filesize = MBSysUtil::filesize( file );
if (filesize >= 0) // -1 indicates could not determine file size (e.g. reading from FIFO)
{
// Check file size, but be careful of numeric overflow
@@ -383,7 +345,8 @@
{
// Unless the byte order was specified explicitly in the
// tag, try the opposite byte order.
- unsigned long num_tri_swap = byte_swap( (uint32_t)num_tri );
+ unsigned long num_tri_swap = num_tri;
+ MBSysUtil::byteswap( &num_tri_swap, 1 );
if (byte_order != STL_UNKNOWN_BYTE_ORDER || // If byte order was specified, fail now
ULONG_MAX / 50 - 84 < num_tri_swap || // watch for overflow in next line
84 + 50 * num_tri_swap != (unsigned long)filesize)
@@ -411,12 +374,11 @@
return MB_FILE_WRITE_ERROR;
}
- // Swap bytes if necessary
+ if (swap_bytes)
+ MBSysUtil::byteswap( tri.coords, 9 );
+
for (unsigned j = 0; j < 9; ++j)
- if (swap_bytes)
- i->points[j/3].coords[j%3] = byte_swap( tri.coords[j] );
- else
- i->points[j/3].coords[j%3] = tri.coords[j];
+ i->points[j/3].coords[j%3] = tri.coords[j];
}
fclose( file );
Modified: MOAB/trunk/ReadSTL.hpp
===================================================================
--- MOAB/trunk/ReadSTL.hpp 2007-12-13 22:09:27 UTC (rev 1468)
+++ MOAB/trunk/ReadSTL.hpp 2007-12-14 19:26:27 UTC (rev 1469)
@@ -82,8 +82,6 @@
//! Destructor
virtual ~ReadSTL();
-
- static long get_file_size( FILE* file );
// An object to hold vertex coordinates, and an operator
// for storing them in a STL tree-based container.
Modified: MOAB/trunk/SequenceData.cpp
===================================================================
--- MOAB/trunk/SequenceData.cpp 2007-12-13 22:09:27 UTC (rev 1468)
+++ MOAB/trunk/SequenceData.cpp 2007-12-14 19:26:27 UTC (rev 1469)
@@ -1,5 +1,6 @@
#include "SequenceData.hpp"
#include "TagServer.hpp"
+#include "MBSysUtil.hpp"
#include <assert.h>
SequenceData::~SequenceData()
@@ -12,19 +13,10 @@
void* SequenceData::create_data( int index, int bytes_per_ent, const void* initial_value )
{
char* array = (char*)malloc( bytes_per_ent * size() );
- if (initial_value) {
- memcpy( array, initial_value, bytes_per_ent );
- unsigned count = 1;
- while (2*count < size()) {
- memcpy( array + count * bytes_per_ent, array, count * bytes_per_ent );
- count *= 2;
- }
-
- memcpy( array + count * bytes_per_ent, array, (size() - count) * bytes_per_ent );
- }
- else {
+ if (initial_value)
+ MBSysUtil::setmem( array, initial_value, bytes_per_ent, size() );
+ else
memset( array, 0, bytes_per_ent * size() );
- }
arraySet[index] = array;
return array;
Modified: MOAB/trunk/SequenceManager.cpp
===================================================================
--- MOAB/trunk/SequenceManager.cpp 2007-12-13 22:09:27 UTC (rev 1468)
+++ MOAB/trunk/SequenceManager.cpp 2007-12-14 19:26:27 UTC (rev 1469)
@@ -6,6 +6,7 @@
#include "StructuredElementSeq.hpp"
#include "HomXform.hpp"
#include "PolyElementSeq.hpp"
+#include "MBSysUtil.hpp"
#include <assert.h>
#include <new>
@@ -832,13 +833,18 @@
const MBEntityID count = finish - start + 1;
const void* tag_array = seq->data()->get_tag_data( tag_id );
- if (!tag_array)
+ if (tag_array) {
+ const char* tag_data = reinterpret_cast<const char*>(tag_array) +
+ tagSizes[tag_id] * (start - seq->data()->start_handle());
+ memcpy( data, tag_data, tagSizes[tag_id] * count );
+ }
+ else if (default_value) {
+ MBSysUtil::setmem( data, default_value, tagSizes[tag_id], count );
+ }
+ else {
return MB_TAG_NOT_FOUND;
+ }
- const char* tag_data = reinterpret_cast<const char*>(tag_array) +
- tagSizes[tag_id] * (start - seq->data()->start_handle());
- memcpy( data, tag_data, tagSizes[tag_id] * count );
-
data += tagSizes[tag_id] * count;
start = finish + 1;
}
Modified: MOAB/trunk/WriteSTL.cpp
===================================================================
--- MOAB/trunk/WriteSTL.cpp 2007-12-13 22:09:27 UTC (rev 1468)
+++ MOAB/trunk/WriteSTL.cpp 2007-12-14 19:26:27 UTC (rev 1469)
@@ -26,6 +26,7 @@
#include "MBRange.hpp"
#include "MBWriteUtilIface.hpp"
#include "FileOptions.hpp"
+#include "MBSysUtil.hpp"
#include "MBEntityHandle.h"
#ifdef MOAB_HAVE_INTTYPES_H
@@ -55,30 +56,7 @@
# define _S_IWRITE (S_IWUSR|S_IWGRP|S_IWOTH)
#endif
-inline static uint32_t byte_swap( uint32_t value )
-{
- return ((value & 0xFF000000) >> 24) |
- ((value & 0x00FF0000) >> 8) |
- ((value & 0x0000FF00) << 8) |
- ((value & 0X000000FF) << 24);
-}
-
-inline static float byte_swap( float value )
-{
- uint32_t bytes = byte_swap( *(uint32_t*)&value );
- return *(float*)&bytes;
-}
-
-
-inline static bool is_platform_little_endian()
-{
- static const unsigned int one = 1;
- static const bool little = !*((char*)&one);
- return little;
-}
-
-
MBWriterIface *WriteSTL::factory( MBInterface* iface )
{ return new WriteSTL( iface ); }
@@ -324,13 +302,6 @@
char pad[2];
};
-static inline void byte_swap( float vect[3] )
-{
- vect[0] = byte_swap( vect[0] );
- vect[1] = byte_swap( vect[1] );
- vect[2] = byte_swap( vect[2] );
-}
-
MBErrorCode WriteSTL::binary_write_triangles( FILE* file,
const char header[81],
ByteOrder byte_order,
@@ -342,7 +313,7 @@
// default to little endian if byte_order == UNKNOWN_BYTE_ORDER
const bool want_big_endian = (byte_order == STL_BIG_ENDIAN);
- const bool am_big_endian = !is_platform_little_endian();
+ const bool am_big_endian = !MBSysUtil::little_endian();
const bool swap_bytes = (want_big_endian == am_big_endian);
if (triangles.size() > INT_MAX) // can't write that many triangles
@@ -350,7 +321,7 @@
uint32_t count = (uint32_t)triangles.size();
if (swap_bytes)
- count = byte_swap(count);
+ MBSysUtil::byteswap(&count, 1);
if (fwrite( &count, 4, 1, file ) != 1)
return MB_FILE_WRITE_ERROR;
@@ -378,10 +349,10 @@
if (swap_bytes)
{
- byte_swap( tri.normal );
- byte_swap( tri.vertex1 );
- byte_swap( tri.vertex2 );
- byte_swap( tri.vertex3 );
+ MBSysUtil::byteswap( tri.normal, 3 );
+ MBSysUtil::byteswap( tri.vertex1, 3 );
+ MBSysUtil::byteswap( tri.vertex2, 3 );
+ MBSysUtil::byteswap( tri.vertex3, 3 );
}
if (1 != fwrite( &tri, 50, 1, file ))
More information about the moab-dev
mailing list