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.
274 lines
7.5 KiB
274 lines
7.5 KiB
/* |
|
* 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
|
|
|