From 57eb631654fc0db12da790356bd471f9c67902e0 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 24 Jun 2005 19:50:14 +0000 Subject: [PATCH] From Colin McDonald, "On fixing the pointer access I discovered that reading osga archives containing ive files went into a cpu loop. This turned out to be a problem with proxy_streambuf on Solaris. Public methods in the Solaris streambuf standard library implementation rely on the gptr() being set, which proxy_streambuf was not doing. So I have modified proxy_streambuf to set the input sequence pointers, and have also aligned it more with the standard library streambuf implementation where all input is through underflow(), not uflow() which merely calls underflow() and advances the pointer." From Robert Osfield, change from using pointer cast and assignment to using a templated _write and _read method to avoid pointer aliasing to 2/4/8 byte boundaries that some computer system may produce. These changes where inspried by Colin McDonalds change to using memcpy, these changes weren't merged as memcpy is not as clear in naming as _read, _write and memcpy will incurr a function call just for copy a uint. --- src/osgPlugins/osga/OSGA_Archive.cpp | 67 +++++++++++++++------------- src/osgPlugins/osga/OSGA_Archive.h | 12 +++++ 2 files changed, 47 insertions(+), 32 deletions(-) diff --git a/src/osgPlugins/osga/OSGA_Archive.cpp b/src/osgPlugins/osga/OSGA_Archive.cpp index 3bfb00263..97fedd1d3 100644 --- a/src/osgPlugins/osga/OSGA_Archive.cpp +++ b/src/osgPlugins/osga/OSGA_Archive.cpp @@ -83,7 +83,8 @@ OSGA_Archive::IndexBlock* OSGA_Archive::IndexBlock::read(std::istream& in, bool ptr += sizeof(size_type); osg::swapBytes(ptr,sizeof(unsigned int)); - unsigned int filename_size = *(reinterpret_cast(ptr)); + unsigned int filename_size; // = *(reinterpret_cast(ptr)); + _read(ptr, filename_size); ptr += sizeof(unsigned int); ptr += filename_size; @@ -113,7 +114,8 @@ std::string OSGA_Archive::IndexBlock::getFirstFileName() const ptr += sizeof(pos_type); ptr += sizeof(size_type); - unsigned int filename_size = *(reinterpret_cast(ptr)); + unsigned int filename_size; // = *(reinterpret_cast(ptr)); + _read(ptr, filename_size); ptr += sizeof(unsigned int); return std::string(ptr, ptr+filename_size); @@ -134,13 +136,16 @@ bool OSGA_Archive::IndexBlock::getFileReferences(FileNamePositionMap& indexMap) char* end_ptr = _data + _offsetOfNextAvailableSpace; while (ptr(ptr)); + pos_type position; // = *(reinterpret_cast(ptr)); + _read(ptr, position); ptr += sizeof(pos_type); - size_type size = *(reinterpret_cast(ptr)); + size_type size; // = *(reinterpret_cast(ptr)); + _read(ptr, size); ptr += sizeof(size_type); - unsigned int filename_size = *(reinterpret_cast(ptr)); + unsigned int filename_size; // = *(reinterpret_cast(ptr)); + _read(ptr, filename_size); ptr += sizeof(unsigned int); std::string filename(ptr, ptr+filename_size); @@ -184,13 +189,16 @@ bool OSGA_Archive::IndexBlock::addFileReference(pos_type position, size_type siz { char* ptr = _data+_offsetOfNextAvailableSpace; - *(reinterpret_cast(ptr)) = position; + //*(reinterpret_cast(ptr)) = position; + _write(ptr, position); ptr += sizeof(pos_type); - *(reinterpret_cast(ptr)) = size; + //*(reinterpret_cast(ptr)) = size; + _write(ptr, size); ptr += sizeof(size_type); - *(reinterpret_cast(ptr)) = filename.size(); + //*(reinterpret_cast(ptr)) = filename.size(); + _write(ptr, static_cast(filename.size())); ptr += sizeof(unsigned int); for(unsigned int i=0;isbumpc(); - value_peeked = false; - - return val; - } - - virtual int_type - underflow() - { - if (value_peeked) return peek_value; - - value_peeked = true; - peek_value = _streambuf->sbumpc(); - return peek_value; + int_type next_value = _streambuf->sbumpc(); + + if ( !traits_type::eq_int_type(next_value,traits_type::eof()) ) + { + setg(&oneChar, &oneChar, (&oneChar)+1); + oneChar = traits_type::to_char_type(next_value); + } + + return next_value; } }; diff --git a/src/osgPlugins/osga/OSGA_Archive.h b/src/osgPlugins/osga/OSGA_Archive.h index 8a73db6b6..f00e1c6ca 100644 --- a/src/osgPlugins/osga/OSGA_Archive.h +++ b/src/osgPlugins/osga/OSGA_Archive.h @@ -210,6 +210,18 @@ class OSGA_Archive : public osgDB::Archive std::string _masterFileName; IndexBlockList _indexBlockList; FileNamePositionMap _indexMap; + + template + static inline void _write(char* ptr, const T& value) + { + std::copy(reinterpret_cast(&value),reinterpret_cast(&value)+sizeof(value),ptr); + } + + template + static inline void _read(char* ptr, T& value) + { + std::copy(ptr,ptr+sizeof(value),reinterpret_cast(&value)); + } };