PageRenderTime 28ms CodeModel.GetById 16ms app.highlight 10ms RepoModel.GetById 1ms app.codeStats 0ms

/Rainman2/memfile.h

http://modstudio2.googlecode.com/
C++ Header | 126 lines | 80 code | 15 blank | 31 comment | 2 complexity | 8b10d9167c06982564055c4f7eab7205 MD5 | raw file
  1/*
  2Copyright (c) 2008 Peter "Corsix" Cawley
  3
  4Permission is hereby granted, free of charge, to any person
  5obtaining a copy of this software and associated documentation
  6files (the "Software"), to deal in the Software without
  7restriction, including without limitation the rights to use,
  8copy, modify, merge, publish, distribute, sublicense, and/or sell
  9copies of the Software, and to permit persons to whom the
 10Software is furnished to do so, subject to the following
 11conditions:
 12
 13The above copyright notice and this permission notice shall be
 14included in all copies or substantial portions of the Software.
 15
 16THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 17EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 18OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 19NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 20HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 21WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 22FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 23OTHER DEALINGS IN THE SOFTWARE.
 24*/
 25#pragma once
 26#include "file.h"
 27#include "exception.h"
 28
 29//! Common code in both MemoryReadFile and MemoryReadFile
 30/*!
 31  TCharPtr should be either `char*` or `const char*` depending on whether or not
 32  the buffers used by the class are constant or not.
 33  Contains implementations of read, seek and tell functions. write functions must
 34  be provided in a derived class.
 35*/
 36template <class TCharPtr>
 37class RAINMAN2_API MemoryFileBase : public IFile
 38{
 39public:
 40  virtual void read(void* pDestination, size_t iItemSize, size_t iItemCount) throw(...)
 41  {
 42    size_t iBytes = iItemSize * iItemCount;
 43    if(m_pPointer + iBytes > m_pEnd)
 44    {
 45      THROW_SIMPLE_(L"Reading %lu items of size %lu would exceed the memory buffer (only %lu bytes remaining)",
 46        static_cast<unsigned long>(iItemCount), static_cast<unsigned long>(iItemSize), static_cast<unsigned long>(m_pEnd - m_pPointer));
 47    }
 48    memcpy(pDestination, m_pPointer, iBytes);
 49    m_pPointer += iBytes;
 50  }
 51
 52  virtual size_t readNoThrow(void* pDestination, size_t iItemSize, size_t iItemCount) throw()
 53  {
 54    size_t iBytes = iItemSize * iItemCount;
 55    if(m_pPointer + iBytes > m_pEnd)
 56    {
 57      iItemCount = (m_pEnd - m_pPointer) / iItemSize;
 58      iBytes = iItemSize * iItemCount;
 59    }
 60    memcpy(pDestination, m_pPointer, iBytes);
 61    m_pPointer += iBytes;
 62    return iItemCount;
 63  }
 64
 65  virtual void seek(seek_offset_t iOffset, seek_relative_t eRelativeTo) throw(...)
 66  {
 67    seekNoThrow(iOffset, eRelativeTo);
 68  }
 69
 70  virtual bool seekNoThrow(seek_offset_t iOffset, seek_relative_t eRelativeTo) throw()
 71  {
 72    switch(eRelativeTo)
 73    {
 74    case SR_Start:
 75      m_pPointer = m_pBuffer + iOffset;
 76      break;
 77
 78    case SR_Current:
 79      m_pPointer = m_pPointer + iOffset;
 80      break;
 81
 82    case SR_End:
 83      m_pPointer = m_pEnd - iOffset;
 84      break;
 85    };
 86    return true;
 87  }
 88
 89  virtual seek_offset_t tell() throw()
 90  {
 91    return static_cast<seek_offset_t>(m_pPointer - m_pBuffer);
 92  }
 93
 94protected:
 95  TCharPtr m_pBuffer, m_pPointer, m_pEnd;
 96  size_t m_iSize;
 97};
 98
 99class RAINMAN2_API MemoryReadFile : public MemoryFileBase<const char*>
100{
101public:
102  MemoryReadFile(const char *pBuffer, size_t iSize, bool bTakeOwnership = false) throw();
103  virtual ~MemoryReadFile() throw();
104
105  virtual void write(const void* pSource, size_t iItemSize, size_t iItemCount) throw(...);
106  virtual size_t writeNoThrow(const void* pSource, size_t iItemSize, size_t iItemCount) throw();
107
108protected:
109  bool m_bOwnsBuffer;
110};
111
112class RAINMAN2_API MemoryWriteFile : public MemoryFileBase<char*>
113{
114public:
115  MemoryWriteFile(size_t iInitialSize = 1024) throw(...);
116  virtual ~MemoryWriteFile() throw();
117
118  inline char* getBuffer() throw() {return m_pBuffer;}
119  inline size_t getLengthUsed() throw() {return m_pEnd - m_pBuffer;}
120
121  virtual void write(const void* pSource, size_t iItemSize, size_t iItemCount) throw(...);
122  virtual size_t writeNoThrow(const void* pSource, size_t iItemSize, size_t iItemCount) throw();
123
124protected:
125  char *m_pBufferEnd;
126};