Tabs to spaces

openmw-35
scrawl 10 years ago
parent d541bc8064
commit 51e451e249

@ -11,162 +11,162 @@ namespace {
class ConstrainedDataStream : public Ogre::DataStream { class ConstrainedDataStream : public Ogre::DataStream {
public: public:
static const size_t sBufferSize = 4096; // somewhat arbitrary though 64KB buffers didn't seem to improve performance any static const size_t sBufferSize = 4096; // somewhat arbitrary though 64KB buffers didn't seem to improve performance any
static const size_t sBufferThreshold = 1024; // reads larger than this bypass buffering as cost of memcpy outweighs cost of system call static const size_t sBufferThreshold = 1024; // reads larger than this bypass buffering as cost of memcpy outweighs cost of system call
ConstrainedDataStream(const Ogre::String &fname, size_t start, size_t length) ConstrainedDataStream(const Ogre::String &fname, size_t start, size_t length)
{ {
mFile.open (fname.c_str ()); mFile.open (fname.c_str ());
mSize = length != 0xFFFFFFFF ? length : mFile.size () - start; mSize = length != 0xFFFFFFFF ? length : mFile.size () - start;
mPos = 0; mPos = 0;
mOrigin = start; mOrigin = start;
mExtent = start + mSize; mExtent = start + mSize;
mBufferOrigin = 0; mBufferOrigin = 0;
mBufferExtent = 0; mBufferExtent = 0;
} }
size_t read(void* buf, size_t count) size_t read(void* buf, size_t count)
{ {
assert (mPos <= mSize); assert (mPos <= mSize);
uint8_t * out = reinterpret_cast <uint8_t *> (buf); uint8_t * out = reinterpret_cast <uint8_t *> (buf);
size_t posBeg = mOrigin + mPos; size_t posBeg = mOrigin + mPos;
size_t posEnd = posBeg + count; size_t posEnd = posBeg + count;
if (posEnd > mExtent) if (posEnd > mExtent)
posEnd = mExtent; posEnd = mExtent;
size_t posCur = posBeg; size_t posCur = posBeg;
while (posCur != posEnd) while (posCur != posEnd)
{ {
size_t readLeft = posEnd - posCur; size_t readLeft = posEnd - posCur;
if (posCur < mBufferOrigin || posCur >= mBufferExtent) if (posCur < mBufferOrigin || posCur >= mBufferExtent)
{ {
if (readLeft >= sBufferThreshold || (posCur == mOrigin && posEnd == mExtent)) if (readLeft >= sBufferThreshold || (posCur == mOrigin && posEnd == mExtent))
{ {
assert (mFile.tell () == mBufferExtent); assert (mFile.tell () == mBufferExtent);
if (posCur != mBufferExtent) if (posCur != mBufferExtent)
mFile.seek (posCur); mFile.seek (posCur);
posCur += mFile.read (out, readLeft); posCur += mFile.read (out, readLeft);
mBufferOrigin = mBufferExtent = posCur; mBufferOrigin = mBufferExtent = posCur;
mPos = posCur - mOrigin; mPos = posCur - mOrigin;
return posCur - posBeg; return posCur - posBeg;
} }
else else
{ {
size_t newBufferOrigin; size_t newBufferOrigin;
if ((posCur < mBufferOrigin) && (mBufferOrigin - posCur < sBufferSize)) if ((posCur < mBufferOrigin) && (mBufferOrigin - posCur < sBufferSize))
newBufferOrigin = std::max (mOrigin, mBufferOrigin > sBufferSize ? mBufferOrigin - sBufferSize : 0); newBufferOrigin = std::max (mOrigin, mBufferOrigin > sBufferSize ? mBufferOrigin - sBufferSize : 0);
else else
newBufferOrigin = posCur; newBufferOrigin = posCur;
fill (newBufferOrigin); fill (newBufferOrigin);
} }
} }
size_t xfer = std::min (readLeft, mBufferExtent - posCur); size_t xfer = std::min (readLeft, mBufferExtent - posCur);
memcpy (out, mBuffer + (posCur - mBufferOrigin), xfer); memcpy (out, mBuffer + (posCur - mBufferOrigin), xfer);
posCur += xfer; posCur += xfer;
out += xfer; out += xfer;
} }
count = posEnd - posBeg; count = posEnd - posBeg;
mPos += count; mPos += count;
return count; return count;
} }
void skip(long count) void skip(long count)
{ {
assert (mPos <= mSize); assert (mPos <= mSize);
if((count >= 0 && (size_t)count <= mSize-mPos) || if((count >= 0 && (size_t)count <= mSize-mPos) ||
(count < 0 && (size_t)-count <= mPos)) (count < 0 && (size_t)-count <= mPos))
mPos += count; mPos += count;
} }
void seek(size_t pos) void seek(size_t pos)
{ {
assert (mPos <= mSize); assert (mPos <= mSize);
if (pos < mSize) if (pos < mSize)
mPos = pos; mPos = pos;
} }
virtual size_t tell() const virtual size_t tell() const
{ {
assert (mPos <= mSize); assert (mPos <= mSize);
return mPos; return mPos;
} }
virtual bool eof() const virtual bool eof() const
{ {
assert (mPos <= mSize); assert (mPos <= mSize);
return mPos == mSize; return mPos == mSize;
} }
virtual void close() virtual void close()
{ {
mFile.close(); mFile.close();
} }
private: private:
void fill (size_t newOrigin) void fill (size_t newOrigin)
{ {
assert (mFile.tell () == mBufferExtent); assert (mFile.tell () == mBufferExtent);
size_t newExtent = newOrigin + sBufferSize; size_t newExtent = newOrigin + sBufferSize;
if (newExtent > mExtent) if (newExtent > mExtent)
newExtent = mExtent; newExtent = mExtent;
size_t oldExtent = mBufferExtent; size_t oldExtent = mBufferExtent;
if (newOrigin != oldExtent) if (newOrigin != oldExtent)
mFile.seek (newOrigin); mFile.seek (newOrigin);
mBufferOrigin = mBufferExtent = newOrigin; mBufferOrigin = mBufferExtent = newOrigin;
size_t amountRequested = newExtent - newOrigin; size_t amountRequested = newExtent - newOrigin;
size_t amountRead = mFile.read (mBuffer, amountRequested); size_t amountRead = mFile.read (mBuffer, amountRequested);
if (amountRead != amountRequested) if (amountRead != amountRequested)
throw std::runtime_error ("An unexpected condition occurred while reading from a file."); throw std::runtime_error ("An unexpected condition occurred while reading from a file.");
mBufferExtent = newExtent; mBufferExtent = newExtent;
} }
LowLevelFile mFile; LowLevelFile mFile;
size_t mOrigin; size_t mOrigin;
size_t mExtent; size_t mExtent;
size_t mPos; size_t mPos;
uint8_t mBuffer [sBufferSize]; uint8_t mBuffer [sBufferSize];
size_t mBufferOrigin; size_t mBufferOrigin;
size_t mBufferExtent; size_t mBufferExtent;
}; };
} // end of unnamed namespace } // end of unnamed namespace
Ogre::DataStreamPtr openConstrainedFileDataStream (char const * filename, size_t offset, size_t length) Ogre::DataStreamPtr openConstrainedFileDataStream (char const * filename, size_t offset, size_t length)
{ {
return Ogre::DataStreamPtr(new ConstrainedDataStream(filename, offset, length)); return Ogre::DataStreamPtr(new ConstrainedDataStream(filename, offset, length));
} }

@ -13,196 +13,196 @@
#if FILE_API == FILE_API_STDIO #if FILE_API == FILE_API_STDIO
/* /*
* *
* Implementation of LowLevelFile methods using c stdio * Implementation of LowLevelFile methods using c stdio
* *
*/ */
LowLevelFile::LowLevelFile () LowLevelFile::LowLevelFile ()
{ {
mHandle = NULL; mHandle = NULL;
} }
LowLevelFile::~LowLevelFile () LowLevelFile::~LowLevelFile ()
{ {
if (mHandle != NULL) if (mHandle != NULL)
fclose (mHandle); fclose (mHandle);
} }
void LowLevelFile::open (char const * filename) void LowLevelFile::open (char const * filename)
{ {
assert (mHandle == NULL); assert (mHandle == NULL);
mHandle = fopen (filename, "rb"); mHandle = fopen (filename, "rb");
if (mHandle == NULL) if (mHandle == NULL)
{ {
std::ostringstream os; std::ostringstream os;
os << "Failed to open '" << filename << "' for reading."; os << "Failed to open '" << filename << "' for reading.";
throw std::runtime_error (os.str ()); throw std::runtime_error (os.str ());
} }
} }
void LowLevelFile::close () void LowLevelFile::close ()
{ {
assert (mHandle != NULL); assert (mHandle != NULL);
fclose (mHandle); fclose (mHandle);
mHandle = NULL; mHandle = NULL;
} }
size_t LowLevelFile::size () size_t LowLevelFile::size ()
{ {
assert (mHandle != NULL); assert (mHandle != NULL);
long oldPosition = ftell (mHandle); long oldPosition = ftell (mHandle);
if (oldPosition == -1) if (oldPosition == -1)
throw std::runtime_error ("A query operation on a file failed."); throw std::runtime_error ("A query operation on a file failed.");
if (fseek (mHandle, 0, SEEK_END) != 0) if (fseek (mHandle, 0, SEEK_END) != 0)
throw std::runtime_error ("A query operation on a file failed."); throw std::runtime_error ("A query operation on a file failed.");
long Size = ftell (mHandle); long Size = ftell (mHandle);
if (Size == -1) if (Size == -1)
throw std::runtime_error ("A query operation on a file failed."); throw std::runtime_error ("A query operation on a file failed.");
if (fseek (mHandle, oldPosition, SEEK_SET) != 0) if (fseek (mHandle, oldPosition, SEEK_SET) != 0)
throw std::runtime_error ("A query operation on a file failed."); throw std::runtime_error ("A query operation on a file failed.");
return size_t (Size); return size_t (Size);
} }
void LowLevelFile::seek (size_t Position) void LowLevelFile::seek (size_t Position)
{ {
assert (mHandle != NULL); assert (mHandle != NULL);
if (fseek (mHandle, Position, SEEK_SET) != 0) if (fseek (mHandle, Position, SEEK_SET) != 0)
throw std::runtime_error ("A seek operation on a file failed."); throw std::runtime_error ("A seek operation on a file failed.");
} }
size_t LowLevelFile::tell () size_t LowLevelFile::tell ()
{ {
assert (mHandle != NULL); assert (mHandle != NULL);
long Position = ftell (mHandle); long Position = ftell (mHandle);
if (Position == -1) if (Position == -1)
throw std::runtime_error ("A query operation on a file failed."); throw std::runtime_error ("A query operation on a file failed.");
return size_t (Position); return size_t (Position);
} }
size_t LowLevelFile::read (void * data, size_t size) size_t LowLevelFile::read (void * data, size_t size)
{ {
assert (mHandle != NULL); assert (mHandle != NULL);
int amount = fread (data, 1, size, mHandle); int amount = fread (data, 1, size, mHandle);
if (amount == 0 && ferror (mHandle)) if (amount == 0 && ferror (mHandle))
throw std::runtime_error ("A read operation on a file failed."); throw std::runtime_error ("A read operation on a file failed.");
return amount; return amount;
} }
#elif FILE_API == FILE_API_POSIX #elif FILE_API == FILE_API_POSIX
/* /*
* *
* Implementation of LowLevelFile methods using posix IO calls * Implementation of LowLevelFile methods using posix IO calls
* *
*/ */
LowLevelFile::LowLevelFile () LowLevelFile::LowLevelFile ()
{ {
mHandle = -1; mHandle = -1;
} }
LowLevelFile::~LowLevelFile () LowLevelFile::~LowLevelFile ()
{ {
if (mHandle != -1) if (mHandle != -1)
::close (mHandle); ::close (mHandle);
} }
void LowLevelFile::open (char const * filename) void LowLevelFile::open (char const * filename)
{ {
assert (mHandle == -1); assert (mHandle == -1);
#ifdef O_BINARY #ifdef O_BINARY
static const int openFlags = O_RDONLY | O_BINARY; static const int openFlags = O_RDONLY | O_BINARY;
#else #else
static const int openFlags = O_RDONLY; static const int openFlags = O_RDONLY;
#endif #endif
mHandle = ::open (filename, openFlags, 0); mHandle = ::open (filename, openFlags, 0);
if (mHandle == -1) if (mHandle == -1)
{ {
std::ostringstream os; std::ostringstream os;
os << "Failed to open '" << filename << "' for reading."; os << "Failed to open '" << filename << "' for reading.";
throw std::runtime_error (os.str ()); throw std::runtime_error (os.str ());
} }
} }
void LowLevelFile::close () void LowLevelFile::close ()
{ {
assert (mHandle != -1); assert (mHandle != -1);
::close (mHandle); ::close (mHandle);
mHandle = -1; mHandle = -1;
} }
size_t LowLevelFile::size () size_t LowLevelFile::size ()
{ {
assert (mHandle != -1); assert (mHandle != -1);
size_t oldPosition = ::lseek (mHandle, 0, SEEK_CUR); size_t oldPosition = ::lseek (mHandle, 0, SEEK_CUR);
if (oldPosition == size_t (-1)) if (oldPosition == size_t (-1))
throw std::runtime_error ("A query operation on a file failed."); throw std::runtime_error ("A query operation on a file failed.");
size_t Size = ::lseek (mHandle, 0, SEEK_END); size_t Size = ::lseek (mHandle, 0, SEEK_END);
if (Size == size_t (-1)) if (Size == size_t (-1))
throw std::runtime_error ("A query operation on a file failed."); throw std::runtime_error ("A query operation on a file failed.");
if (lseek (mHandle, oldPosition, SEEK_SET) == -1) if (lseek (mHandle, oldPosition, SEEK_SET) == -1)
throw std::runtime_error ("A query operation on a file failed."); throw std::runtime_error ("A query operation on a file failed.");
return Size; return Size;
} }
void LowLevelFile::seek (size_t Position) void LowLevelFile::seek (size_t Position)
{ {
assert (mHandle != -1); assert (mHandle != -1);
if (::lseek (mHandle, Position, SEEK_SET) == -1) if (::lseek (mHandle, Position, SEEK_SET) == -1)
throw std::runtime_error ("A seek operation on a file failed."); throw std::runtime_error ("A seek operation on a file failed.");
} }
size_t LowLevelFile::tell () size_t LowLevelFile::tell ()
{ {
assert (mHandle != -1); assert (mHandle != -1);
size_t Position = ::lseek (mHandle, 0, SEEK_CUR); size_t Position = ::lseek (mHandle, 0, SEEK_CUR);
if (Position == size_t (-1)) if (Position == size_t (-1))
throw std::runtime_error ("A query operation on a file failed."); throw std::runtime_error ("A query operation on a file failed.");
return Position; return Position;
} }
size_t LowLevelFile::read (void * data, size_t size) size_t LowLevelFile::read (void * data, size_t size)
{ {
assert (mHandle != -1); assert (mHandle != -1);
int amount = ::read (mHandle, data, size); int amount = ::read (mHandle, data, size);
if (amount == -1) if (amount == -1)
throw std::runtime_error ("A read operation on a file failed."); throw std::runtime_error ("A read operation on a file failed.");
return amount; return amount;
} }
#elif FILE_API == FILE_API_WIN32 #elif FILE_API == FILE_API_WIN32
@ -210,93 +210,93 @@ size_t LowLevelFile::read (void * data, size_t size)
#include <boost/locale.hpp> #include <boost/locale.hpp>
/* /*
* *
* Implementation of LowLevelFile methods using Win32 API calls * Implementation of LowLevelFile methods using Win32 API calls
* *
*/ */
LowLevelFile::LowLevelFile () LowLevelFile::LowLevelFile ()
{ {
mHandle = INVALID_HANDLE_VALUE; mHandle = INVALID_HANDLE_VALUE;
} }
LowLevelFile::~LowLevelFile () LowLevelFile::~LowLevelFile ()
{ {
if (mHandle != INVALID_HANDLE_VALUE) if (mHandle != INVALID_HANDLE_VALUE)
CloseHandle (mHandle); CloseHandle (mHandle);
} }
void LowLevelFile::open (char const * filename) void LowLevelFile::open (char const * filename)
{ {
assert (mHandle == INVALID_HANDLE_VALUE); assert (mHandle == INVALID_HANDLE_VALUE);
std::wstring wname = boost::locale::conv::utf_to_utf<wchar_t>(filename); std::wstring wname = boost::locale::conv::utf_to_utf<wchar_t>(filename);
HANDLE handle = CreateFileW (wname.c_str(), GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0); HANDLE handle = CreateFileW (wname.c_str(), GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
if (handle == INVALID_HANDLE_VALUE) if (handle == INVALID_HANDLE_VALUE)
{ {
std::ostringstream os; std::ostringstream os;
os << "Failed to open '" << filename << "' for reading."; os << "Failed to open '" << filename << "' for reading.";
throw std::runtime_error (os.str ()); throw std::runtime_error (os.str ());
} }
mHandle = handle; mHandle = handle;
} }
void LowLevelFile::close () void LowLevelFile::close ()
{ {
assert (mHandle != INVALID_HANDLE_VALUE); assert (mHandle != INVALID_HANDLE_VALUE);
CloseHandle (mHandle); CloseHandle (mHandle);
mHandle = INVALID_HANDLE_VALUE; mHandle = INVALID_HANDLE_VALUE;
} }
size_t LowLevelFile::size () size_t LowLevelFile::size ()
{ {
assert (mHandle != INVALID_HANDLE_VALUE); assert (mHandle != INVALID_HANDLE_VALUE);
BY_HANDLE_FILE_INFORMATION info; BY_HANDLE_FILE_INFORMATION info;
if (!GetFileInformationByHandle (mHandle, &info)) if (!GetFileInformationByHandle (mHandle, &info))
throw std::runtime_error ("A query operation on a file failed."); throw std::runtime_error ("A query operation on a file failed.");
if (info.nFileSizeHigh != 0) if (info.nFileSizeHigh != 0)
throw std::runtime_error ("Files greater that 4GB are not supported."); throw std::runtime_error ("Files greater that 4GB are not supported.");
return info.nFileSizeLow; return info.nFileSizeLow;
} }
void LowLevelFile::seek (size_t Position) void LowLevelFile::seek (size_t Position)
{ {
assert (mHandle != INVALID_HANDLE_VALUE); assert (mHandle != INVALID_HANDLE_VALUE);
if (SetFilePointer (mHandle, Position, NULL, SEEK_SET) == INVALID_SET_FILE_POINTER) if (SetFilePointer (mHandle, Position, NULL, SEEK_SET) == INVALID_SET_FILE_POINTER)
if (GetLastError () != NO_ERROR) if (GetLastError () != NO_ERROR)
throw std::runtime_error ("A seek operation on a file failed."); throw std::runtime_error ("A seek operation on a file failed.");
} }
size_t LowLevelFile::tell () size_t LowLevelFile::tell ()
{ {
assert (mHandle != INVALID_HANDLE_VALUE); assert (mHandle != INVALID_HANDLE_VALUE);
DWORD value = SetFilePointer (mHandle, 0, NULL, SEEK_CUR); DWORD value = SetFilePointer (mHandle, 0, NULL, SEEK_CUR);
if (value == INVALID_SET_FILE_POINTER && GetLastError () != NO_ERROR) if (value == INVALID_SET_FILE_POINTER && GetLastError () != NO_ERROR)
throw std::runtime_error ("A query operation on a file failed."); throw std::runtime_error ("A query operation on a file failed.");
return value; return value;
} }
size_t LowLevelFile::read (void * data, size_t size) size_t LowLevelFile::read (void * data, size_t size)
{ {
assert (mHandle != INVALID_HANDLE_VALUE); assert (mHandle != INVALID_HANDLE_VALUE);
DWORD read; DWORD read;
if (!ReadFile (mHandle, data, size, &read, NULL)) if (!ReadFile (mHandle, data, size, &read, NULL))
throw std::runtime_error ("A read operation on a file failed."); throw std::runtime_error ("A read operation on a file failed.");
return read; return read;
} }
#endif #endif

@ -5,16 +5,16 @@
#include <cstdlib> #include <cstdlib>
#define FILE_API_STDIO 0 #define FILE_API_STDIO 0
#define FILE_API_POSIX 1 #define FILE_API_POSIX 1
#define FILE_API_WIN32 2 #define FILE_API_WIN32 2
#if OGRE_PLATFORM == OGRE_PLATFORM_LINUX #if OGRE_PLATFORM == OGRE_PLATFORM_LINUX
#define FILE_API FILE_API_POSIX #define FILE_API FILE_API_POSIX
#elif OGRE_PLATFORM == OGRE_PLATFORM_WIN32 #elif OGRE_PLATFORM == OGRE_PLATFORM_WIN32
#define FILE_API FILE_API_WIN32 #define FILE_API FILE_API_WIN32
#else #else
#define FILE_API FILE_API_STDIO #define FILE_API FILE_API_STDIO
#endif #endif
#if FILE_API == FILE_API_STDIO #if FILE_API == FILE_API_STDIO
@ -30,26 +30,26 @@ class LowLevelFile
{ {
public: public:
LowLevelFile (); LowLevelFile ();
~LowLevelFile (); ~LowLevelFile ();
void open (char const * filename); void open (char const * filename);
void close (); void close ();
size_t size (); size_t size ();
void seek (size_t Position); void seek (size_t Position);
size_t tell (); size_t tell ();
size_t read (void * data, size_t size); size_t read (void * data, size_t size);
private: private:
#if FILE_API == FILE_API_STDIO #if FILE_API == FILE_API_STDIO
FILE* mHandle; FILE* mHandle;
#elif FILE_API == FILE_API_POSIX #elif FILE_API == FILE_API_POSIX
int mHandle; int mHandle;
#elif FILE_API == FILE_API_WIN32 #elif FILE_API == FILE_API_WIN32
HANDLE mHandle; HANDLE mHandle;
#endif #endif
}; };

Loading…
Cancel
Save