[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