libpgf  6.11.42
PGF - Progressive Graphics File
PGFstream.cpp
Go to the documentation of this file.
00001 /*
00002  * The Progressive Graphics File; http://www.libpgf.org
00003  * 
00004  * $Date: 2007-01-19 11:51:24 +0100 (Fr, 19 Jan 2007) $
00005  * $Revision: 268 $
00006  * 
00007  * This file Copyright (C) 2006 xeraina GmbH, Switzerland
00008  * 
00009  * This program is free software; you can redistribute it and/or
00010  * modify it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE
00011  * as published by the Free Software Foundation; either version 2.1
00012  * of the License, or (at your option) any later version.
00013  * 
00014  * This program is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  * GNU General Public License for more details.
00018  * 
00019  * You should have received a copy of the GNU General Public License
00020  * along with this program; if not, write to the Free Software
00021  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00022  */
00023 
00028 
00029 #include "PGFstream.h"
00030 
00031 #ifdef WIN32
00032 #include <malloc.h>
00033 #endif
00034 
00036 // CPGFFileStream
00038 void CPGFFileStream::Write(int *count, void *buffPtr) THROW_ {
00039         ASSERT(count);
00040         ASSERT(buffPtr);
00041         ASSERT(IsValid());
00042         OSError err;
00043         if ((err = FileWrite(m_hFile, count, buffPtr)) != NoError) ReturnWithError(err);
00044         
00045 }
00046 
00048 void CPGFFileStream::Read(int *count, void *buffPtr) THROW_ {
00049         ASSERT(count);
00050         ASSERT(buffPtr);
00051         ASSERT(IsValid());
00052         OSError err;
00053         if ((err = FileRead(m_hFile, count, buffPtr)) != NoError) ReturnWithError(err);
00054 }
00055 
00057 void CPGFFileStream::SetPos(short posMode, INT64 posOff) THROW_ {
00058         ASSERT(IsValid());
00059         OSError err;
00060         if ((err = SetFPos(m_hFile, posMode, posOff)) != NoError) ReturnWithError(err);
00061 }
00062 
00064 UINT64 CPGFFileStream::GetPos() const THROW_ {
00065         ASSERT(IsValid());
00066         OSError err;
00067         UINT64 pos = 0;
00068         if ((err = GetFPos(m_hFile, &pos)) != NoError) ReturnWithError2(err, pos);
00069         return pos;
00070 }
00071 
00072 
00074 // CPGFMemoryStream
00078 CPGFMemoryStream::CPGFMemoryStream(size_t size) THROW_ 
00079 : m_size(size)
00080 , m_allocated(true) {
00081         m_buffer = m_pos = m_eos = new(std::nothrow) UINT8[m_size];
00082         if (!m_buffer) ReturnWithError(InsufficientMemory);
00083 }
00084 
00089 CPGFMemoryStream::CPGFMemoryStream(UINT8 *pBuffer, size_t size) THROW_ 
00090 : m_buffer(pBuffer)
00091 , m_pos(pBuffer)
00092 , m_eos(pBuffer + size)
00093 , m_size(size)
00094 , m_allocated(false) {
00095         ASSERT(IsValid());
00096 }
00097 
00102 void CPGFMemoryStream::Reinitialize(UINT8 *pBuffer, size_t size) THROW_ {
00103         if (!m_allocated) {
00104                 m_buffer = m_pos = pBuffer;
00105                 m_size = size;
00106                 m_eos = m_buffer + size;
00107         }
00108 }
00109 
00111 void CPGFMemoryStream::Write(int *count, void *buffPtr) THROW_ {
00112         ASSERT(count);
00113         ASSERT(buffPtr);
00114         ASSERT(IsValid());
00115         const size_t deltaSize = 0x4000 + *count;
00116         
00117         if (m_pos + *count <= m_buffer + m_size) {
00118                 memcpy(m_pos, buffPtr, *count);
00119                 m_pos += *count; 
00120                 if (m_pos > m_eos) m_eos = m_pos;
00121         } else if (m_allocated) {
00122                 // memory block is too small -> reallocate a deltaSize larger block
00123                 size_t offset = m_pos - m_buffer;
00124                 UINT8 *buf_tmp = (UINT8 *)realloc(m_buffer, m_size + deltaSize);
00125                 if (!buf_tmp) {
00126                         delete[] m_buffer;
00127                         m_buffer = 0;
00128                         ReturnWithError(InsufficientMemory);
00129                 } else {
00130                         m_buffer = buf_tmp;
00131                 }
00132                 m_size += deltaSize;
00133 
00134                 // reposition m_pos
00135                 m_pos = m_buffer + offset;
00136 
00137                 // write block
00138                 memcpy(m_pos, buffPtr, *count);
00139                 m_pos += *count; 
00140                 if (m_pos > m_eos) m_eos = m_pos;
00141         } else {
00142                 ReturnWithError(InsufficientMemory);    
00143         }
00144         ASSERT(m_pos <= m_eos);
00145 }
00146 
00148 void CPGFMemoryStream::Read(int *count, void *buffPtr) {
00149         ASSERT(IsValid());
00150         ASSERT(count);
00151         ASSERT(buffPtr);
00152         ASSERT(m_buffer + m_size >= m_eos);
00153         ASSERT(m_pos <= m_eos);
00154         
00155         if (m_pos + *count <= m_eos) {
00156                 memcpy(buffPtr, m_pos, *count);
00157                 m_pos += *count;
00158         } else {
00159                 // end of memory block reached -> read only until end
00160                 *count = (int)__max(0, m_eos - m_pos);
00161                 memcpy(buffPtr, m_pos, *count);
00162                 m_pos += *count;
00163         }
00164         ASSERT(m_pos <= m_eos);
00165 }
00166 
00168 void CPGFMemoryStream::SetPos(short posMode, INT64 posOff) THROW_ {
00169         ASSERT(IsValid());
00170         switch(posMode) {
00171         case FSFromStart:
00172                 m_pos = m_buffer + posOff;
00173                 break;
00174         case FSFromCurrent:
00175                 m_pos += posOff;
00176                 break;
00177         case FSFromEnd:
00178                 m_pos = m_eos + posOff;
00179                 break;
00180         default:
00181                 ASSERT(false);
00182         }
00183         if (m_pos > m_eos) 
00184                 ReturnWithError(InvalidStreamPos);
00185 }
00186 
00187 
00189 // CPGFMemFileStream
00190 #ifdef _MFC_VER
00191 
00192 void CPGFMemFileStream::Write(int *count, void *buffPtr) THROW_ {
00193         ASSERT(count);
00194         ASSERT(buffPtr);
00195         ASSERT(IsValid());
00196         m_memFile->Write(buffPtr, *count);
00197 }
00198 
00200 void CPGFMemFileStream::Read(int *count, void *buffPtr) THROW_ {
00201         ASSERT(count);
00202         ASSERT(buffPtr);
00203         ASSERT(IsValid());
00204         m_memFile->Read(buffPtr, *count);
00205 }
00206 
00208 void CPGFMemFileStream::SetPos(short posMode, INT64 posOff) THROW_ {
00209         ASSERT(IsValid());
00210         m_memFile->Seek(posOff, posMode); 
00211 }
00212 
00214 UINT64 CPGFMemFileStream::GetPos() const THROW_ {
00215         return (UINT64)m_memFile->GetPosition();
00216 }
00217 #endif // _MFC_VER
00218 
00220 // CPGFIStream
00221 #if defined(WIN32) || defined(WINCE)
00222 
00223 void CPGFIStream::Write(int *count, void *buffPtr) THROW_ {
00224         ASSERT(count);
00225         ASSERT(buffPtr);
00226         ASSERT(IsValid());
00227         
00228         HRESULT hr = m_stream->Write(buffPtr, *count, (ULONG *)count);
00229         if (FAILED(hr)) {
00230                 ReturnWithError(hr);
00231         }
00232 }
00233 
00235 void CPGFIStream::Read(int *count, void *buffPtr) THROW_ {
00236         ASSERT(count);
00237         ASSERT(buffPtr);
00238         ASSERT(IsValid());
00239         
00240         HRESULT hr = m_stream->Read(buffPtr, *count, (ULONG *)count);
00241         if (FAILED(hr)) {
00242                 ReturnWithError(hr);
00243         }
00244 }
00245 
00247 void CPGFIStream::SetPos(short posMode, INT64 posOff) THROW_ {
00248         ASSERT(IsValid());
00249         
00250         LARGE_INTEGER li;
00251         li.QuadPart = posOff;
00252 
00253         HRESULT hr = m_stream->Seek(li, posMode, NULL); 
00254         if (FAILED(hr)) {
00255                 ReturnWithError(hr);
00256         }
00257 }
00258 
00260 UINT64 CPGFIStream::GetPos() const THROW_ {
00261         ASSERT(IsValid());
00262         
00263         LARGE_INTEGER n;
00264         ULARGE_INTEGER pos;
00265         n.QuadPart = 0;
00266 
00267         HRESULT hr = m_stream->Seek(n, FSFromCurrent, &pos); 
00268         if (SUCCEEDED(hr)) {
00269                 return pos.QuadPart;
00270         } else {
00271                 ReturnWithError2(hr, pos.QuadPart);
00272         }
00273 }
00274 #endif // WIN32 || WINCE
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines