2
* Copyright (C) 2006 Ariya Hidayat (ariya@kde.org)
4
* This library is free software; you can redistribute it and/or
5
* modify it under the terms of the GNU Library General Public
6
* License as published by the Free Software Foundation; either
7
* version 2 of the License, or (at your option) any later version.
9
* This library is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
* Library General Public License for more details.
14
* You should have received a copy of the GNU Library General Public
15
* License along with this library; if not, write to the
16
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17
* Boston, MA 02111-1301 USA
19
* For further information visit http://libwpd.sourceforge.net
22
#include "WPXStreamImplementation.h"
23
#include "WPXOLEStream.h"
31
using namespace libwpd;
33
class WPXFileStreamPrivate
36
WPXFileStreamPrivate();
37
~WPXFileStreamPrivate();
39
std::stringstream buffer;
40
unsigned long streamSize;
43
WPXFileStreamPrivate(const WPXFileStreamPrivate&);
44
WPXFileStreamPrivate& operator=(const WPXFileStreamPrivate&);
47
class WPXStringStreamPrivate
50
WPXStringStreamPrivate(const std::string str);
51
~WPXStringStreamPrivate();
52
std::stringstream buffer;
53
unsigned long streamSize;
56
WPXStringStreamPrivate(const WPXStringStreamPrivate&);
57
WPXStringStreamPrivate& operator=(const WPXStringStreamPrivate&);
60
WPXFileStreamPrivate::WPXFileStreamPrivate() :
62
buffer(std::ios::binary | std::ios::in | std::ios::out),
68
WPXFileStreamPrivate::~WPXFileStreamPrivate()
74
WPXStringStreamPrivate::WPXStringStreamPrivate(const std::string str) :
75
buffer(str, std::ios::binary | std::ios::in),
81
WPXStringStreamPrivate::~WPXStringStreamPrivate()
87
WPXFileStream::WPXFileStream(const char* filename) :
89
d(new WPXFileStreamPrivate)
91
d->file.open( filename, std::ios::binary | std::ios::in );
92
d->file.seekg( 0, std::ios::end );
93
d->streamSize = (d->file.good() ? (unsigned long)d->file.tellg() : (unsigned long)-1L);
94
if (d->streamSize == (unsigned long)-1) // tellg() returned ERROR
96
// preventing possible unsigned/signed issues later by truncating the file
97
if (d->streamSize > (std::numeric_limits<unsigned long>::max)() / 2)
98
d->streamSize = (std::numeric_limits<unsigned long>::max)() / 2;
99
d->file.seekg( 0, std::ios::beg );
102
WPXFileStream::~WPXFileStream()
107
const uint8_t *WPXFileStream::read(size_t numBytes, size_t &numBytesRead)
111
if (numBytes < 0 || atEOS() || numBytes > (std::numeric_limits<unsigned long>::max)()/2)
114
unsigned long curpos = d->file.tellg();
115
if (curpos == (unsigned long)-1) // tellg() returned ERROR
118
if ( (curpos + numBytes < curpos) /*overflow*/ ||
119
(curpos + numBytes > d->streamSize) ) /*reading more than available*/
121
numBytes = d->streamSize - curpos;
126
d->buf = new uint8_t[numBytes];
130
d->file.read((char *)(d->buf), numBytes);
131
numBytesRead = (long)d->file.tellg() - curpos;
137
long WPXFileStream::tell()
139
return d->file.good() ? (long)d->file.tellg() : -1L;
142
int WPXFileStream::seek(long offset, WPX_SEEK_TYPE seekType)
144
if (seekType == WPX_SEEK_SET)
148
if (offset > (long)d->streamSize)
149
offset = (long)d->streamSize;
152
if (seekType == WPX_SEEK_CUR)
154
if (tell() + offset < 0)
156
if (tell() + offset > (long)d->streamSize)
157
offset = d->streamSize - tell();
162
d->file.seekg(offset, ((seekType == WPX_SEEK_SET) ? std::ios::beg : std::ios::cur));
163
return (int) ((long)d->file.tellg() == -1) ;
169
bool WPXFileStream::atEOS()
171
return (d->file.tellg() >= (long)d->streamSize);
174
bool WPXFileStream::isOLEStream()
176
if (d->buffer.str().empty())
177
d->buffer << d->file.rdbuf();
178
Storage tmpStorage( d->buffer );
179
if (tmpStorage.isOLEStream())
181
seek(0, WPX_SEEK_SET);
184
seek(0, WPX_SEEK_SET);
188
WPXInputStream* WPXFileStream::getDocumentOLEStream(const char * name)
190
if (d->buffer.str().empty())
191
d->buffer << d->file.rdbuf();
192
Storage *tmpStorage = new Storage( d->buffer );
193
Stream tmpStream( tmpStorage, name );
194
if (!tmpStorage || (tmpStorage->result() != Storage::Ok) || !tmpStream.size())
198
return (WPXInputStream*)0;
203
d->buf = new uint8_t[tmpStream.size()];
205
unsigned long tmpLength;
206
tmpLength = tmpStream.read((unsigned char *)(d->buf), tmpStream.size());
209
if (tmpLength > tmpStream.size() || tmpLength < tmpStream.size())
210
/* something went wrong here and we do not trust the
215
return (WPXInputStream*)0;
219
return new WPXStringStream((const char *)(d->buf), tmpLength);
222
WPXInputStream* WPXFileStream::getDocumentOLEStream()
224
return getDocumentOLEStream("PerfectOffice_MAIN");
227
WPXStringStream::WPXStringStream(const char *data, const unsigned int dataSize) :
228
WPXInputStream(true),
229
d(new WPXStringStreamPrivate(std::string(data, dataSize)))
231
d->buffer.seekg( 0, std::ios::end );
232
d->streamSize = (d->buffer.good() ? (unsigned long)d->buffer.tellg() : (unsigned long)-1L);
233
if (d->streamSize == (unsigned long)-1)
235
// preventing possible unsigned/signed issues later by truncating the file
236
if (d->streamSize > (std::numeric_limits<unsigned long>::max)() / 2)
237
d->streamSize = (std::numeric_limits<unsigned long>::max)() / 2;
238
d->buffer.seekg( 0, std::ios::beg );
241
WPXStringStream::~WPXStringStream()
246
const uint8_t *WPXStringStream::read(size_t numBytes, size_t &numBytesRead)
250
if (numBytes < 0 || atEOS() || numBytes > (std::numeric_limits<unsigned long>::max)()/2)
253
unsigned long curpos = d->buffer.tellg();
254
if (curpos == (unsigned long)-1) //tellg() returned ERROR
257
if ( (curpos + numBytes < curpos) /*overflow*/ ||
258
(curpos + numBytes > d->streamSize) ) /*reading more than available*/
260
numBytes = d->streamSize - curpos;
265
d->buf = new uint8_t[numBytes];
269
d->buffer.read((char *)(d->buf), numBytes);
270
numBytesRead = (long)d->buffer.tellg() - curpos;
276
long WPXStringStream::tell()
278
return d->buffer.good() ? (long)d->buffer.tellg() : -1L;
281
int WPXStringStream::seek(long offset, WPX_SEEK_TYPE seekType)
283
if (seekType == WPX_SEEK_SET)
287
if (offset > (long)d->streamSize)
288
offset = d->streamSize;
291
if (seekType == WPX_SEEK_CUR)
293
if (tell() + offset < 0)
295
if (tell() + offset > (long)d->streamSize)
296
offset = d->streamSize - tell();
301
d->buffer.seekg(offset, ((seekType == WPX_SEEK_SET) ? std::ios::beg : std::ios::cur));
302
return (int) ( (long)d->buffer.tellg() == -1);
308
bool WPXStringStream::atEOS()
310
return (d->buffer.tellg() >= (long)d->streamSize);
313
bool WPXStringStream::isOLEStream()
315
Storage tmpStorage( d->buffer );
316
if (tmpStorage.isOLEStream())
318
seek(0, WPX_SEEK_SET);
321
seek(0, WPX_SEEK_SET);
325
WPXInputStream* WPXStringStream::getDocumentOLEStream(const char * name)
327
Storage *tmpStorage = new Storage( d->buffer );
328
Stream tmpStream( tmpStorage, name );
329
if (!tmpStorage || (tmpStorage->result() != Storage::Ok) || !tmpStream.size())
333
return (WPXInputStream*)0;
338
d->buf = new uint8_t[tmpStream.size()];
339
unsigned long tmpLength;
340
tmpLength = tmpStream.read((unsigned char *)(d->buf), tmpStream.size());
343
if (tmpLength > tmpStream.size() || tmpLength < tmpStream.size())
344
/* something went wrong here and we do not trust the
349
return (WPXInputStream*)0;
353
return new WPXStringStream((const char *)(d->buf), tmpLength);
356
WPXInputStream* WPXStringStream::getDocumentOLEStream()
358
return getDocumentOLEStream("PerfectOffice_MAIN");