/* * 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 #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