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