1 /*
2 * The Progressive Graphics File; http://www.libpgf.org
3 *
4 * $Date: 2007-01-19 11:51:24 +0100 (Fr, 19 Jan 2007) $
5 * $Revision: 268 $
6 *
7 * This file Copyright (C) 2006 xeraina GmbH, Switzerland
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE
11 * as published by the Free Software Foundation; either version 2.1
12 * of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 */
23
24 //////////////////////////////////////////////////////////////////////
25 /// @file PGFstream.cpp
26 /// @brief PGF stream class implementation
27 /// @author C. Stamm
28
29 #include "PGFstream.h"
30
31 #ifdef WIN32
32 #include <malloc.h>
33 #endif
34
35 //////////////////////////////////////////////////////////////////////
36 // CPGFFileStream
37 //////////////////////////////////////////////////////////////////////
Write(int * count,void * buffPtr)38 void CPGFFileStream::Write(int *count, void *buffPtr) {
39 ASSERT(count);
40 ASSERT(buffPtr);
41 ASSERT(IsValid());
42 OSError err;
43 if ((err = FileWrite(m_hFile, count, buffPtr)) != NoError) ReturnWithError(err);
44
45 }
46
47 //////////////////////////////////////////////////////////////////////
Read(int * count,void * buffPtr)48 void CPGFFileStream::Read(int *count, void *buffPtr) {
49 ASSERT(count);
50 ASSERT(buffPtr);
51 ASSERT(IsValid());
52 OSError err;
53 if ((err = FileRead(m_hFile, count, buffPtr)) != NoError) ReturnWithError(err);
54 }
55
56 //////////////////////////////////////////////////////////////////////
SetPos(short posMode,INT64 posOff)57 void CPGFFileStream::SetPos(short posMode, INT64 posOff) {
58 ASSERT(IsValid());
59 OSError err;
60 if ((err = SetFPos(m_hFile, posMode, posOff)) != NoError) ReturnWithError(err);
61 }
62
63 //////////////////////////////////////////////////////////////////////
GetPos() const64 UINT64 CPGFFileStream::GetPos() const {
65 ASSERT(IsValid());
66 OSError err;
67 UINT64 pos = 0;
68 if ((err = GetFPos(m_hFile, &pos)) != NoError) ReturnWithError2(err, pos);
69 return pos;
70 }
71
72
73 //////////////////////////////////////////////////////////////////////
74 // CPGFMemoryStream
75 //////////////////////////////////////////////////////////////////////
76 /// Allocate memory block of given size
77 /// @param size Memory size
CPGFMemoryStream(size_t size)78 CPGFMemoryStream::CPGFMemoryStream(size_t size)
79 : m_size(size)
80 , m_allocated(true) {
81 m_buffer = m_pos = m_eos = new(std::nothrow) UINT8[m_size];
82 if (!m_buffer) ReturnWithError(InsufficientMemory);
83 }
84
85 //////////////////////////////////////////////////////////////////////
86 /// Use already allocated memory of given size
87 /// @param pBuffer Memory location
88 /// @param size Memory size
CPGFMemoryStream(UINT8 * pBuffer,size_t size)89 CPGFMemoryStream::CPGFMemoryStream(UINT8 *pBuffer, size_t size)
90 : m_buffer(pBuffer)
91 , m_pos(pBuffer)
92 , m_eos(pBuffer + size)
93 , m_size(size)
94 , m_allocated(false) {
95 ASSERT(IsValid());
96 }
97
98 //////////////////////////////////////////////////////////////////////
99 /// Use already allocated memory of given size
100 /// @param pBuffer Memory location
101 /// @param size Memory size
Reinitialize(UINT8 * pBuffer,size_t size)102 void CPGFMemoryStream::Reinitialize(UINT8 *pBuffer, size_t size) {
103 if (!m_allocated) {
104 m_buffer = m_pos = pBuffer;
105 m_size = size;
106 m_eos = m_buffer + size;
107 }
108 }
109
110 //////////////////////////////////////////////////////////////////////
Write(int * count,void * buffPtr)111 void CPGFMemoryStream::Write(int *count, void *buffPtr) {
112 ASSERT(count);
113 ASSERT(buffPtr);
114 ASSERT(IsValid());
115 const size_t deltaSize = 0x4000 + *count;
116
117 if (m_pos + *count <= m_buffer + m_size) {
118 memcpy(m_pos, buffPtr, *count);
119 m_pos += *count;
120 if (m_pos > m_eos) m_eos = m_pos;
121 } else if (m_allocated) {
122 // memory block is too small -> reallocate a deltaSize larger block
123 size_t offset = m_pos - m_buffer;
124 UINT8 *buf_tmp = (UINT8 *)realloc(m_buffer, m_size + deltaSize);
125 if (!buf_tmp) {
126 delete[] m_buffer;
127 m_buffer = 0;
128 ReturnWithError(InsufficientMemory);
129 } else {
130 m_buffer = buf_tmp;
131 }
132 m_size += deltaSize;
133
134 // reposition m_pos
135 m_pos = m_buffer + offset;
136
137 // write block
138 memcpy(m_pos, buffPtr, *count);
139 m_pos += *count;
140 if (m_pos > m_eos) m_eos = m_pos;
141 } else {
142 ReturnWithError(InsufficientMemory);
143 }
144 ASSERT(m_pos <= m_eos);
145 }
146
147 //////////////////////////////////////////////////////////////////////
Read(int * count,void * buffPtr)148 void CPGFMemoryStream::Read(int *count, void *buffPtr) {
149 ASSERT(IsValid());
150 ASSERT(count);
151 ASSERT(buffPtr);
152 ASSERT(m_buffer + m_size >= m_eos);
153 ASSERT(m_pos <= m_eos);
154
155 if (m_pos + *count <= m_eos) {
156 memcpy(buffPtr, m_pos, *count);
157 m_pos += *count;
158 } else {
159 // end of memory block reached -> read only until end
160 *count = (int)__max(0, m_eos - m_pos);
161 memcpy(buffPtr, m_pos, *count);
162 m_pos += *count;
163 }
164 ASSERT(m_pos <= m_eos);
165 }
166
167 //////////////////////////////////////////////////////////////////////
SetPos(short posMode,INT64 posOff)168 void CPGFMemoryStream::SetPos(short posMode, INT64 posOff) {
169 ASSERT(IsValid());
170 switch(posMode) {
171 case FSFromStart:
172 m_pos = m_buffer + posOff;
173 break;
174 case FSFromCurrent:
175 m_pos += posOff;
176 break;
177 case FSFromEnd:
178 m_pos = m_eos + posOff;
179 break;
180 default:
181 ASSERT(false);
182 }
183 if (m_pos > m_eos)
184 ReturnWithError(InvalidStreamPos);
185 }
186
187
188 //////////////////////////////////////////////////////////////////////
189 // CPGFMemFileStream
190 #ifdef _MFC_VER
191 //////////////////////////////////////////////////////////////////////
Write(int * count,void * buffPtr)192 void CPGFMemFileStream::Write(int *count, void *buffPtr) {
193 ASSERT(count);
194 ASSERT(buffPtr);
195 ASSERT(IsValid());
196 m_memFile->Write(buffPtr, *count);
197 }
198
199 //////////////////////////////////////////////////////////////////////
Read(int * count,void * buffPtr)200 void CPGFMemFileStream::Read(int *count, void *buffPtr) {
201 ASSERT(count);
202 ASSERT(buffPtr);
203 ASSERT(IsValid());
204 m_memFile->Read(buffPtr, *count);
205 }
206
207 //////////////////////////////////////////////////////////////////////
SetPos(short posMode,INT64 posOff)208 void CPGFMemFileStream::SetPos(short posMode, INT64 posOff) {
209 ASSERT(IsValid());
210 m_memFile->Seek(posOff, posMode);
211 }
212
213 //////////////////////////////////////////////////////////////////////
GetPos() const214 UINT64 CPGFMemFileStream::GetPos() const {
215 return (UINT64)m_memFile->GetPosition();
216 }
217 #endif // _MFC_VER
218
219 //////////////////////////////////////////////////////////////////////
220 // CPGFIStream
221 #if defined(WIN32) || defined(WINCE)
222 //////////////////////////////////////////////////////////////////////
Write(int * count,void * buffPtr)223 void CPGFIStream::Write(int *count, void *buffPtr) {
224 ASSERT(count);
225 ASSERT(buffPtr);
226 ASSERT(IsValid());
227
228 HRESULT hr = m_stream->Write(buffPtr, *count, (ULONG *)count);
229 if (FAILED(hr)) {
230 ReturnWithError(hr);
231 }
232 }
233
234 //////////////////////////////////////////////////////////////////////
Read(int * count,void * buffPtr)235 void CPGFIStream::Read(int *count, void *buffPtr) {
236 ASSERT(count);
237 ASSERT(buffPtr);
238 ASSERT(IsValid());
239
240 HRESULT hr = m_stream->Read(buffPtr, *count, (ULONG *)count);
241 if (FAILED(hr)) {
242 ReturnWithError(hr);
243 }
244 }
245
246 //////////////////////////////////////////////////////////////////////
SetPos(short posMode,INT64 posOff)247 void CPGFIStream::SetPos(short posMode, INT64 posOff) {
248 ASSERT(IsValid());
249
250 LARGE_INTEGER li;
251 li.QuadPart = posOff;
252
253 HRESULT hr = m_stream->Seek(li, posMode, nullptr);
254 if (FAILED(hr)) {
255 ReturnWithError(hr);
256 }
257 }
258
259 //////////////////////////////////////////////////////////////////////
GetPos() const260 UINT64 CPGFIStream::GetPos() const {
261 ASSERT(IsValid());
262
263 LARGE_INTEGER n;
264 ULARGE_INTEGER pos;
265 n.QuadPart = 0;
266
267 HRESULT hr = m_stream->Seek(n, FSFromCurrent, &pos);
268 if (SUCCEEDED(hr)) {
269 return pos.QuadPart;
270 } else {
271 ReturnWithError2(hr, pos.QuadPart);
272 }
273 }
274 #endif // WIN32 || WINCE
275