You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
182 lines
4.0 KiB
182 lines
4.0 KiB
//////////////////////////////////////////////////////////////////// |
|
// MemFile.h |
|
// |
|
// Copyright 2007 cDc@seacave |
|
// Distributed under the Boost Software License, Version 1.0 |
|
// (See http://www.boost.org/LICENSE_1_0.txt) |
|
|
|
#ifndef __SEACAVE_MEMFILE_H__ |
|
#define __SEACAVE_MEMFILE_H__ |
|
|
|
|
|
// I N C L U D E S ///////////////////////////////////////////////// |
|
|
|
#include "Streams.h" |
|
|
|
|
|
// D E F I N E S /////////////////////////////////////////////////// |
|
|
|
|
|
namespace SEACAVE { |
|
|
|
// S T R U C T S /////////////////////////////////////////////////// |
|
|
|
class GENERAL_API MemFile : public IOStream { |
|
public: |
|
MemFile() : m_buffer(NULL), m_sizeBuffer(0), m_size(0), m_pos(0) { |
|
} |
|
MemFile(size_t initialSize) : m_buffer(new BYTE[initialSize]), m_sizeBuffer(initialSize), m_size(0), m_pos(0) { |
|
} |
|
MemFile(BYTE* data, size_t size) : m_buffer(data), m_sizeBuffer(0), m_size(size), m_pos(0) { |
|
} |
|
virtual ~MemFile() { |
|
close(); |
|
} |
|
|
|
static LPCSTR getClassType() { return "MemFile"; } |
|
virtual LPCSTR getClassName() const { return MemFile::getClassType(); } |
|
|
|
bool isOpen() const { return m_buffer != NULL; } |
|
|
|
virtual void close() { |
|
if (!isOpen()) |
|
return; |
|
if (m_sizeBuffer) |
|
delete[] m_buffer; |
|
m_sizeBuffer = 0; |
|
m_buffer = NULL; |
|
m_size = 0; |
|
m_pos = 0; |
|
} |
|
|
|
virtual size_f_t getSizeBuffer() const { |
|
return m_sizeBuffer; |
|
} |
|
|
|
virtual size_f_t getSizeLeft() const { |
|
return m_size - m_pos; |
|
} |
|
|
|
virtual size_f_t getSize() const { |
|
return m_size; |
|
} |
|
|
|
virtual bool setSize(size_f_t newSize) { |
|
ASSERT(newSize >= 0); |
|
if (newSize > m_sizeBuffer) |
|
setMaxSize(newSize); |
|
m_size = newSize; |
|
if (m_pos > m_size) |
|
m_pos = m_size; |
|
return true; |
|
} |
|
|
|
virtual bool growSize(size_f_t deltaSize) { |
|
return setSize(m_size+deltaSize); |
|
} |
|
|
|
virtual bool moveSize(size_f_t delataSize) { |
|
return setSize(m_size + delataSize); |
|
} |
|
|
|
virtual bool setMaxSize(size_f_t newSize) { |
|
ASSERT(newSize > m_sizeBuffer); |
|
// grow by 50% or at least to minNewVectorSize |
|
const size_f_t expoSize(m_sizeBuffer + (m_sizeBuffer>>1)); |
|
if (newSize < expoSize) |
|
newSize = expoSize; |
|
// allocate a larger chunk of memory, copy the data and delete the old chunk |
|
BYTE* const tmp(m_buffer); |
|
m_buffer = new BYTE[(size_t)newSize]; |
|
if (!m_buffer) { |
|
m_buffer = tmp; |
|
return false; |
|
} |
|
if (m_size > newSize) { |
|
m_size = newSize; |
|
if (m_pos > m_size) |
|
m_pos = m_size; |
|
} |
|
memcpy(m_buffer, tmp, (size_t)m_size); |
|
if (m_sizeBuffer) |
|
delete[] tmp; |
|
m_sizeBuffer = newSize; |
|
return true; |
|
} |
|
|
|
virtual bool growMaxSize(size_f_t deltaSize) { |
|
return setMaxSize(m_sizeBuffer+deltaSize); |
|
} |
|
|
|
virtual bool ensureSize(size_f_t extraSize) { |
|
const size_f_t newSize = m_size + extraSize; |
|
if (newSize > m_sizeBuffer) |
|
return setMaxSize(newSize); |
|
return true; |
|
} |
|
|
|
virtual size_f_t getPos() const { |
|
return m_pos; |
|
} |
|
|
|
virtual bool setPos(size_f_t pos) { |
|
if (pos > m_size && !setSize(pos)) |
|
return false; |
|
m_pos = pos; |
|
return true; |
|
} |
|
|
|
virtual bool movePos(size_f_t delataPos) { |
|
return setPos(m_pos + delataPos); |
|
} |
|
|
|
virtual bool isEOF() { |
|
return (m_pos == m_size); |
|
} |
|
|
|
virtual size_t read(void* buf, size_t len) { |
|
if (m_pos >= m_size) |
|
return 0; |
|
if (m_pos+(size_f_t)len > m_size) |
|
len = (size_t)(m_size-m_pos); |
|
memcpy(buf, m_buffer+m_pos, len); |
|
m_pos += len; |
|
return len; |
|
} |
|
|
|
virtual size_t write(const void* buf, size_t len) { |
|
const size_f_t endSize = m_pos+len; |
|
if (endSize > m_size && !setSize(endSize)) |
|
return 0; |
|
memcpy(m_buffer+m_pos, buf, len); |
|
m_pos += len; |
|
return len; |
|
} |
|
|
|
virtual BYTE* getData() { |
|
return m_buffer + m_pos; |
|
} |
|
|
|
virtual BYTE* getBuffer() { |
|
return m_buffer; |
|
} |
|
|
|
virtual size_t flush() { |
|
return 0; |
|
} |
|
|
|
protected: |
|
BYTE* m_buffer; //buffer where we will store the data |
|
size_f_t m_sizeBuffer; //size of the whole buffer, 0 if no buffer or not allocated here |
|
size_f_t m_size; //size of the stored data |
|
size_f_t m_pos; //current position in the stored data |
|
|
|
private: |
|
MemFile(const MemFile&); |
|
MemFile& operator=(const MemFile&); |
|
}; |
|
/*----------------------------------------------------------------*/ |
|
|
|
} // namespace SEACAVE |
|
|
|
#endif // __SEACAVE_MEMFILE_H__
|
|
|