You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
275 lines
7.5 KiB
C++
275 lines
7.5 KiB
C++
/*
|
|
* The Progressive Graphics File; http://www.libpgf.org
|
|
*
|
|
* $Date: 2007-01-19 11:51:24 +0100 (Fr, 19 Jan 2007) $
|
|
* $Revision: 268 $
|
|
*
|
|
* This file Copyright (C) 2006 xeraina GmbH, Switzerland
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE
|
|
* as published by the Free Software Foundation; either version 2.1
|
|
* of the License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
*/
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
/// @file PGFstream.cpp
|
|
/// @brief PGF stream class implementation
|
|
/// @author C. Stamm
|
|
|
|
#include "PGFstream.h"
|
|
|
|
#ifdef WIN32
|
|
#include <malloc.h>
|
|
#endif
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// CPGFFileStream
|
|
//////////////////////////////////////////////////////////////////////
|
|
void CPGFFileStream::Write(int *count, void *buffPtr) {
|
|
ASSERT(count);
|
|
ASSERT(buffPtr);
|
|
ASSERT(IsValid());
|
|
OSError err;
|
|
if ((err = FileWrite(m_hFile, count, buffPtr)) != NoError) ReturnWithError(err);
|
|
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
void CPGFFileStream::Read(int *count, void *buffPtr) {
|
|
ASSERT(count);
|
|
ASSERT(buffPtr);
|
|
ASSERT(IsValid());
|
|
OSError err;
|
|
if ((err = FileRead(m_hFile, count, buffPtr)) != NoError) ReturnWithError(err);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
void CPGFFileStream::SetPos(short posMode, INT64 posOff) {
|
|
ASSERT(IsValid());
|
|
OSError err;
|
|
if ((err = SetFPos(m_hFile, posMode, posOff)) != NoError) ReturnWithError(err);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
UINT64 CPGFFileStream::GetPos() const {
|
|
ASSERT(IsValid());
|
|
OSError err;
|
|
UINT64 pos = 0;
|
|
if ((err = GetFPos(m_hFile, &pos)) != NoError) ReturnWithError2(err, pos);
|
|
return pos;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// CPGFMemoryStream
|
|
//////////////////////////////////////////////////////////////////////
|
|
/// Allocate memory block of given size
|
|
/// @param size Memory size
|
|
CPGFMemoryStream::CPGFMemoryStream(size_t size)
|
|
: m_size(size)
|
|
, m_allocated(true) {
|
|
m_buffer = m_pos = m_eos = new(std::nothrow) UINT8[m_size];
|
|
if (!m_buffer) ReturnWithError(InsufficientMemory);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
/// Use already allocated memory of given size
|
|
/// @param pBuffer Memory location
|
|
/// @param size Memory size
|
|
CPGFMemoryStream::CPGFMemoryStream(UINT8 *pBuffer, size_t size)
|
|
: m_buffer(pBuffer)
|
|
, m_pos(pBuffer)
|
|
, m_eos(pBuffer + size)
|
|
, m_size(size)
|
|
, m_allocated(false) {
|
|
ASSERT(IsValid());
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
/// Use already allocated memory of given size
|
|
/// @param pBuffer Memory location
|
|
/// @param size Memory size
|
|
void CPGFMemoryStream::Reinitialize(UINT8 *pBuffer, size_t size) {
|
|
if (!m_allocated) {
|
|
m_buffer = m_pos = pBuffer;
|
|
m_size = size;
|
|
m_eos = m_buffer + size;
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
void CPGFMemoryStream::Write(int *count, void *buffPtr) {
|
|
ASSERT(count);
|
|
ASSERT(buffPtr);
|
|
ASSERT(IsValid());
|
|
const size_t deltaSize = 0x4000 + *count;
|
|
|
|
if (m_pos + *count <= m_buffer + m_size) {
|
|
memcpy(m_pos, buffPtr, *count);
|
|
m_pos += *count;
|
|
if (m_pos > m_eos) m_eos = m_pos;
|
|
} else if (m_allocated) {
|
|
// memory block is too small -> reallocate a deltaSize larger block
|
|
size_t offset = m_pos - m_buffer;
|
|
UINT8 *buf_tmp = (UINT8 *)realloc(m_buffer, m_size + deltaSize);
|
|
if (!buf_tmp) {
|
|
delete[] m_buffer;
|
|
m_buffer = 0;
|
|
ReturnWithError(InsufficientMemory);
|
|
} else {
|
|
m_buffer = buf_tmp;
|
|
}
|
|
m_size += deltaSize;
|
|
|
|
// reposition m_pos
|
|
m_pos = m_buffer + offset;
|
|
|
|
// write block
|
|
memcpy(m_pos, buffPtr, *count);
|
|
m_pos += *count;
|
|
if (m_pos > m_eos) m_eos = m_pos;
|
|
} else {
|
|
ReturnWithError(InsufficientMemory);
|
|
}
|
|
ASSERT(m_pos <= m_eos);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
void CPGFMemoryStream::Read(int *count, void *buffPtr) {
|
|
ASSERT(IsValid());
|
|
ASSERT(count);
|
|
ASSERT(buffPtr);
|
|
ASSERT(m_buffer + m_size >= m_eos);
|
|
ASSERT(m_pos <= m_eos);
|
|
|
|
if (m_pos + *count <= m_eos) {
|
|
memcpy(buffPtr, m_pos, *count);
|
|
m_pos += *count;
|
|
} else {
|
|
// end of memory block reached -> read only until end
|
|
*count = (int)__max(0, m_eos - m_pos);
|
|
memcpy(buffPtr, m_pos, *count);
|
|
m_pos += *count;
|
|
}
|
|
ASSERT(m_pos <= m_eos);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
void CPGFMemoryStream::SetPos(short posMode, INT64 posOff) {
|
|
ASSERT(IsValid());
|
|
switch(posMode) {
|
|
case FSFromStart:
|
|
m_pos = m_buffer + posOff;
|
|
break;
|
|
case FSFromCurrent:
|
|
m_pos += posOff;
|
|
break;
|
|
case FSFromEnd:
|
|
m_pos = m_eos + posOff;
|
|
break;
|
|
default:
|
|
ASSERT(false);
|
|
}
|
|
if (m_pos > m_eos)
|
|
ReturnWithError(InvalidStreamPos);
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// CPGFMemFileStream
|
|
#ifdef _MFC_VER
|
|
//////////////////////////////////////////////////////////////////////
|
|
void CPGFMemFileStream::Write(int *count, void *buffPtr) {
|
|
ASSERT(count);
|
|
ASSERT(buffPtr);
|
|
ASSERT(IsValid());
|
|
m_memFile->Write(buffPtr, *count);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
void CPGFMemFileStream::Read(int *count, void *buffPtr) {
|
|
ASSERT(count);
|
|
ASSERT(buffPtr);
|
|
ASSERT(IsValid());
|
|
m_memFile->Read(buffPtr, *count);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
void CPGFMemFileStream::SetPos(short posMode, INT64 posOff) {
|
|
ASSERT(IsValid());
|
|
m_memFile->Seek(posOff, posMode);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
UINT64 CPGFMemFileStream::GetPos() const {
|
|
return (UINT64)m_memFile->GetPosition();
|
|
}
|
|
#endif // _MFC_VER
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// CPGFIStream
|
|
#if defined(WIN32) || defined(WINCE)
|
|
//////////////////////////////////////////////////////////////////////
|
|
void CPGFIStream::Write(int *count, void *buffPtr) {
|
|
ASSERT(count);
|
|
ASSERT(buffPtr);
|
|
ASSERT(IsValid());
|
|
|
|
HRESULT hr = m_stream->Write(buffPtr, *count, (ULONG *)count);
|
|
if (FAILED(hr)) {
|
|
ReturnWithError(hr);
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
void CPGFIStream::Read(int *count, void *buffPtr) {
|
|
ASSERT(count);
|
|
ASSERT(buffPtr);
|
|
ASSERT(IsValid());
|
|
|
|
HRESULT hr = m_stream->Read(buffPtr, *count, (ULONG *)count);
|
|
if (FAILED(hr)) {
|
|
ReturnWithError(hr);
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
void CPGFIStream::SetPos(short posMode, INT64 posOff) {
|
|
ASSERT(IsValid());
|
|
|
|
LARGE_INTEGER li;
|
|
li.QuadPart = posOff;
|
|
|
|
HRESULT hr = m_stream->Seek(li, posMode, nullptr);
|
|
if (FAILED(hr)) {
|
|
ReturnWithError(hr);
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
UINT64 CPGFIStream::GetPos() const {
|
|
ASSERT(IsValid());
|
|
|
|
LARGE_INTEGER n;
|
|
ULARGE_INTEGER pos;
|
|
n.QuadPart = 0;
|
|
|
|
HRESULT hr = m_stream->Seek(n, FSFromCurrent, &pos);
|
|
if (SUCCEEDED(hr)) {
|
|
return pos.QuadPart;
|
|
} else {
|
|
ReturnWithError2(hr, pos.QuadPart);
|
|
}
|
|
}
|
|
#endif // WIN32 || WINCE
|