File indexing completed on 2025-01-19 03:56:11

0001 /*
0002  * The Progressive Graphics File; http://www.libpgf.org
0003  *
0004  * $Date: 2007-01-19 11:51:24 +0100 (Fr, 19 Jan 2007) $
0005  * $Revision: 268 $
0006  *
0007  * This file Copyright (C) 2006 xeraina GmbH, Switzerland
0008  *
0009  * This program is free software; you can redistribute it and/or
0010  * modify it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE
0011  * as published by the Free Software Foundation; either version 2.1
0012  * of the License, or (at your option) any later version.
0013  *
0014  * This program is distributed in the hope that it will be useful,
0015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0017  * GNU General Public License for more details.
0018  *
0019  * You should have received a copy of the GNU General Public License
0020  * along with this program; if not, write to the Free Software
0021  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
0022  */
0023 
0024 //////////////////////////////////////////////////////////////////////
0025 /// @file PGFstream.cpp
0026 /// @brief PGF stream class implementation
0027 /// @author C. Stamm
0028 
0029 #include "PGFstream.h"
0030 
0031 #ifdef WIN32
0032 #include <malloc.h>
0033 #endif
0034 
0035 //////////////////////////////////////////////////////////////////////
0036 // CPGFFileStream
0037 //////////////////////////////////////////////////////////////////////
0038 void CPGFFileStream::Write(int *count, void *buffPtr) {
0039     ASSERT(count);
0040     ASSERT(buffPtr);
0041     ASSERT(IsValid());
0042     OSError err;
0043     if ((err = FileWrite(m_hFile, count, buffPtr)) != NoError) ReturnWithError(err);
0044 
0045 }
0046 
0047 //////////////////////////////////////////////////////////////////////
0048 void CPGFFileStream::Read(int *count, void *buffPtr) {
0049     ASSERT(count);
0050     ASSERT(buffPtr);
0051     ASSERT(IsValid());
0052     OSError err;
0053     if ((err = FileRead(m_hFile, count, buffPtr)) != NoError) ReturnWithError(err);
0054 }
0055 
0056 //////////////////////////////////////////////////////////////////////
0057 void CPGFFileStream::SetPos(short posMode, INT64 posOff) {
0058     ASSERT(IsValid());
0059     OSError err;
0060     if ((err = SetFPos(m_hFile, posMode, posOff)) != NoError) ReturnWithError(err);
0061 }
0062 
0063 //////////////////////////////////////////////////////////////////////
0064 UINT64 CPGFFileStream::GetPos() const {
0065     ASSERT(IsValid());
0066     OSError err;
0067     UINT64 pos = 0;
0068     if ((err = GetFPos(m_hFile, &pos)) != NoError) ReturnWithError2(err, pos);
0069     return pos;
0070 }
0071 
0072 
0073 //////////////////////////////////////////////////////////////////////
0074 // CPGFMemoryStream
0075 //////////////////////////////////////////////////////////////////////
0076 /// Allocate memory block of given size
0077 /// @param size Memory size
0078 CPGFMemoryStream::CPGFMemoryStream(size_t size)
0079 : m_size(size)
0080 , m_allocated(true) {
0081     m_buffer = m_pos = m_eos = new(std::nothrow) UINT8[m_size];
0082     if (!m_buffer) ReturnWithError(InsufficientMemory);
0083 }
0084 
0085 //////////////////////////////////////////////////////////////////////
0086 /// Use already allocated memory of given size
0087 /// @param pBuffer Memory location
0088 /// @param size Memory size
0089 CPGFMemoryStream::CPGFMemoryStream(UINT8 *pBuffer, size_t size)
0090 : m_buffer(pBuffer)
0091 , m_pos(pBuffer)
0092 , m_eos(pBuffer + size)
0093 , m_size(size)
0094 , m_allocated(false) {
0095     ASSERT(IsValid());
0096 }
0097 
0098 //////////////////////////////////////////////////////////////////////
0099 /// Use already allocated memory of given size
0100 /// @param pBuffer Memory location
0101 /// @param size Memory size
0102 void CPGFMemoryStream::Reinitialize(UINT8 *pBuffer, size_t size) {
0103     if (!m_allocated) {
0104         m_buffer = m_pos = pBuffer;
0105         m_size = size;
0106         m_eos = m_buffer + size;
0107     }
0108 }
0109 
0110 //////////////////////////////////////////////////////////////////////
0111 void CPGFMemoryStream::Write(int *count, void *buffPtr) {
0112     ASSERT(count);
0113     ASSERT(buffPtr);
0114     ASSERT(IsValid());
0115     const size_t deltaSize = 0x4000 + *count;
0116 
0117     if (m_pos + *count <= m_buffer + m_size) {
0118         memcpy(m_pos, buffPtr, *count);
0119         m_pos += *count;
0120         if (m_pos > m_eos) m_eos = m_pos;
0121     } else if (m_allocated) {
0122         // memory block is too small -> reallocate a deltaSize larger block
0123         size_t offset = m_pos - m_buffer;
0124         UINT8 *buf_tmp = new(std::nothrow) UINT8[m_size + deltaSize];
0125         if (!buf_tmp) {
0126             delete[] m_buffer;
0127             m_buffer = 0;
0128             ReturnWithError(InsufficientMemory);
0129         } else {
0130             memcpy(buf_tmp, m_buffer, m_size);
0131             delete[] m_buffer;
0132             m_buffer = buf_tmp;
0133         }
0134         m_size += deltaSize;
0135 
0136         // reposition m_pos
0137         m_pos = m_buffer + offset;
0138 
0139         // write block
0140         memcpy(m_pos, buffPtr, *count);
0141         m_pos += *count;
0142         if (m_pos > m_eos) m_eos = m_pos;
0143     } else {
0144         ReturnWithError(InsufficientMemory);
0145     }
0146     ASSERT(m_pos <= m_eos);
0147 }
0148 
0149 //////////////////////////////////////////////////////////////////////
0150 void CPGFMemoryStream::Read(int *count, void *buffPtr) {
0151     ASSERT(IsValid());
0152     ASSERT(count);
0153     ASSERT(buffPtr);
0154     ASSERT(m_buffer + m_size >= m_eos);
0155     ASSERT(m_pos <= m_eos);
0156 
0157     if (m_pos + *count <= m_eos) {
0158         memcpy(buffPtr, m_pos, *count);
0159         m_pos += *count;
0160     } else {
0161         // end of memory block reached -> read only until end
0162         *count = (int)__max(0, m_eos - m_pos);
0163         memcpy(buffPtr, m_pos, *count);
0164         m_pos += *count;
0165     }
0166     ASSERT(m_pos <= m_eos);
0167 }
0168 
0169 //////////////////////////////////////////////////////////////////////
0170 void CPGFMemoryStream::SetPos(short posMode, INT64 posOff) {
0171     ASSERT(IsValid());
0172     switch(posMode) {
0173     case FSFromStart:
0174         m_pos = m_buffer + posOff;
0175         break;
0176     case FSFromCurrent:
0177         m_pos += posOff;
0178         break;
0179     case FSFromEnd:
0180         m_pos = m_eos + posOff;
0181         break;
0182     default:
0183         ASSERT(false);
0184     }
0185     if (m_pos > m_eos)
0186         ReturnWithError(InvalidStreamPos);
0187 }
0188 
0189 
0190 //////////////////////////////////////////////////////////////////////
0191 // CPGFMemFileStream
0192 #ifdef _MFC_VER
0193 //////////////////////////////////////////////////////////////////////
0194 void CPGFMemFileStream::Write(int *count, void *buffPtr) {
0195     ASSERT(count);
0196     ASSERT(buffPtr);
0197     ASSERT(IsValid());
0198     m_memFile->Write(buffPtr, *count);
0199 }
0200 
0201 //////////////////////////////////////////////////////////////////////
0202 void CPGFMemFileStream::Read(int *count, void *buffPtr) {
0203     ASSERT(count);
0204     ASSERT(buffPtr);
0205     ASSERT(IsValid());
0206     m_memFile->Read(buffPtr, *count);
0207 }
0208 
0209 //////////////////////////////////////////////////////////////////////
0210 void CPGFMemFileStream::SetPos(short posMode, INT64 posOff) {
0211     ASSERT(IsValid());
0212     m_memFile->Seek(posOff, posMode);
0213 }
0214 
0215 //////////////////////////////////////////////////////////////////////
0216 UINT64 CPGFMemFileStream::GetPos() const {
0217     return (UINT64)m_memFile->GetPosition();
0218 }
0219 #endif // _MFC_VER
0220 
0221 //////////////////////////////////////////////////////////////////////
0222 // CPGFIStream
0223 #if defined(WIN32) || defined(WINCE)
0224 //////////////////////////////////////////////////////////////////////
0225 void CPGFIStream::Write(int *count, void *buffPtr) {
0226     ASSERT(count);
0227     ASSERT(buffPtr);
0228     ASSERT(IsValid());
0229 
0230     HRESULT hr = m_stream->Write(buffPtr, *count, (ULONG *)count);
0231     if (FAILED(hr)) {
0232         ReturnWithError(hr);
0233     }
0234 }
0235 
0236 //////////////////////////////////////////////////////////////////////
0237 void CPGFIStream::Read(int *count, void *buffPtr) {
0238     ASSERT(count);
0239     ASSERT(buffPtr);
0240     ASSERT(IsValid());
0241 
0242     HRESULT hr = m_stream->Read(buffPtr, *count, (ULONG *)count);
0243     if (FAILED(hr)) {
0244         ReturnWithError(hr);
0245     }
0246 }
0247 
0248 //////////////////////////////////////////////////////////////////////
0249 void CPGFIStream::SetPos(short posMode, INT64 posOff) {
0250     ASSERT(IsValid());
0251 
0252     LARGE_INTEGER li;
0253     li.QuadPart = posOff;
0254 
0255     HRESULT hr = m_stream->Seek(li, posMode, nullptr);
0256     if (FAILED(hr)) {
0257         ReturnWithError(hr);
0258     }
0259 }
0260 
0261 //////////////////////////////////////////////////////////////////////
0262 UINT64 CPGFIStream::GetPos() const {
0263     ASSERT(IsValid());
0264 
0265     LARGE_INTEGER n;
0266     ULARGE_INTEGER pos;
0267     n.QuadPart = 0;
0268 
0269     HRESULT hr = m_stream->Seek(n, FSFromCurrent, &pos);
0270     if (SUCCEEDED(hr)) {
0271         return pos.QuadPart;
0272     } else {
0273         ReturnWithError2(hr, pos.QuadPart);
0274     }
0275 }
0276 #endif // WIN32 || WINCE