~ubuntu-branches/ubuntu/karmic/libwpd/karmic

« back to all changes in this revision

Viewing changes to src/lib/WPXStreamImplementation.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Rene Engelhard
  • Date: 2007-06-15 13:28:41 UTC
  • mfrom: (1.1.9 upstream)
  • Revision ID: james.westby@ubuntu.com-20070615132841-00nybwftc708w96n
Tags: 0.8.10-1
* New upstream release
* bump shlibs for libwpd-stream8c2a 

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* libwpd
 
2
 * Copyright (C) 2006 Ariya Hidayat (ariya@kde.org)
 
3
 *
 
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.
 
8
 *
 
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.
 
13
 *
 
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
 
18
 *
 
19
 * For further information visit http://libwpd.sourceforge.net
 
20
 */
 
21
 
 
22
#include "WPXStreamImplementation.h"
 
23
#include "WPXOLEStream.h"
 
24
#include "libwpd.h"
 
25
 
 
26
#include <fstream>
 
27
#include <sstream>
 
28
#include <string>
 
29
#include <limits>
 
30
 
 
31
using namespace libwpd;
 
32
 
 
33
class WPXFileStreamPrivate
 
34
{
 
35
public:
 
36
        WPXFileStreamPrivate();
 
37
        ~WPXFileStreamPrivate();
 
38
        std::fstream file;
 
39
        std::stringstream buffer;
 
40
        unsigned long streamSize;
 
41
        uint8_t *buf;
 
42
private:
 
43
        WPXFileStreamPrivate(const WPXFileStreamPrivate&);
 
44
        WPXFileStreamPrivate& operator=(const WPXFileStreamPrivate&);
 
45
};
 
46
 
 
47
class WPXStringStreamPrivate
 
48
{
 
49
public:
 
50
        WPXStringStreamPrivate(const std::string str);
 
51
        ~WPXStringStreamPrivate();
 
52
        std::stringstream buffer;
 
53
        unsigned long streamSize;
 
54
        uint8_t *buf;
 
55
private:
 
56
        WPXStringStreamPrivate(const WPXStringStreamPrivate&);
 
57
        WPXStringStreamPrivate& operator=(const WPXStringStreamPrivate&);
 
58
};
 
59
 
 
60
WPXFileStreamPrivate::WPXFileStreamPrivate() :
 
61
        file(),
 
62
        buffer(std::ios::binary | std::ios::in | std::ios::out),
 
63
        streamSize(0),
 
64
        buf(0)
 
65
{       
 
66
}
 
67
 
 
68
WPXFileStreamPrivate::~WPXFileStreamPrivate()
 
69
{
 
70
        if (buf)
 
71
                delete [] buf;
 
72
}
 
73
 
 
74
WPXStringStreamPrivate::WPXStringStreamPrivate(const std::string str) :
 
75
        buffer(str, std::ios::binary | std::ios::in),
 
76
        streamSize(0),
 
77
        buf(0)
 
78
{
 
79
}
 
80
 
 
81
WPXStringStreamPrivate::~WPXStringStreamPrivate()
 
82
{
 
83
        if (buf)
 
84
                delete [] buf;
 
85
}
 
86
 
 
87
WPXFileStream::WPXFileStream(const char* filename) :
 
88
        WPXInputStream(true),
 
89
        d(new WPXFileStreamPrivate)
 
90
{
 
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
 
95
                d->streamSize = 0;
 
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 );
 
100
}
 
101
 
 
102
WPXFileStream::~WPXFileStream()
 
103
{
 
104
        delete d;
 
105
}
 
106
 
 
107
const uint8_t *WPXFileStream::read(size_t numBytes, size_t &numBytesRead)
 
108
{
 
109
        numBytesRead = 0;
 
110
        
 
111
        if (numBytes < 0 || atEOS() || numBytes > (std::numeric_limits<unsigned long>::max)()/2)
 
112
                return 0;
 
113
 
 
114
        unsigned long curpos = d->file.tellg();
 
115
        if (curpos == (unsigned long)-1)  // tellg() returned ERROR
 
116
                return 0;
 
117
 
 
118
        if ( (curpos + numBytes < curpos) /*overflow*/ ||
 
119
                (curpos + numBytes > d->streamSize) ) /*reading more than available*/
 
120
        {
 
121
                numBytes = d->streamSize - curpos;
 
122
        }
 
123
 
 
124
        if (d->buf)
 
125
                delete [] d->buf;
 
126
        d->buf = new uint8_t[numBytes];
 
127
 
 
128
        if(d->file.good())
 
129
        {
 
130
                d->file.read((char *)(d->buf), numBytes); 
 
131
                numBytesRead = (long)d->file.tellg() - curpos;
 
132
        }
 
133
        
 
134
        return d->buf;
 
135
}
 
136
 
 
137
long WPXFileStream::tell()
 
138
{
 
139
        return d->file.good() ? (long)d->file.tellg() : -1L;
 
140
}
 
141
 
 
142
int WPXFileStream::seek(long offset, WPX_SEEK_TYPE seekType)
 
143
{
 
144
        if (seekType == WPX_SEEK_SET)
 
145
        {
 
146
                if (offset < 0)
 
147
                        offset = 0;
 
148
                if (offset > (long)d->streamSize)
 
149
                        offset = (long)d->streamSize;
 
150
        }
 
151
 
 
152
        if (seekType == WPX_SEEK_CUR)
 
153
        {
 
154
                if (tell() + offset < 0)
 
155
                        offset = -tell();
 
156
                if (tell() + offset > (long)d->streamSize)
 
157
                        offset = d->streamSize - tell();
 
158
        }
 
159
 
 
160
        if(d->file.good())
 
161
        {
 
162
                d->file.seekg(offset, ((seekType == WPX_SEEK_SET) ? std::ios::beg : std::ios::cur));
 
163
                return (int) ((long)d->file.tellg() == -1) ;
 
164
        }
 
165
        else
 
166
                return -1;
 
167
}
 
168
 
 
169
bool WPXFileStream::atEOS()
 
170
{
 
171
        return (d->file.tellg() >= (long)d->streamSize);
 
172
}
 
173
 
 
174
bool WPXFileStream::isOLEStream()
 
175
{
 
176
        if (d->buffer.str().empty())
 
177
                d->buffer << d->file.rdbuf();
 
178
        Storage tmpStorage( d->buffer );
 
179
        if (tmpStorage.isOLEStream())
 
180
        {
 
181
                seek(0, WPX_SEEK_SET);
 
182
                return true;
 
183
        }
 
184
        seek(0, WPX_SEEK_SET);
 
185
        return false;
 
186
}
 
187
 
 
188
WPXInputStream* WPXFileStream::getDocumentOLEStream(const char * name)
 
189
{
 
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())
 
195
        {
 
196
                if (tmpStorage)
 
197
                        delete tmpStorage;
 
198
                return (WPXInputStream*)0;
 
199
        }
 
200
        
 
201
        if (d->buf)
 
202
                delete [] d->buf;
 
203
        d->buf = new uint8_t[tmpStream.size()];
 
204
 
 
205
        unsigned long tmpLength;
 
206
        tmpLength = tmpStream.read((unsigned char *)(d->buf), tmpStream.size());
 
207
 
 
208
        // sanity check
 
209
        if (tmpLength > tmpStream.size() || tmpLength < tmpStream.size())
 
210
        /* something went wrong here and we do not trust the
 
211
           resulting buffer */
 
212
        {
 
213
                if (tmpStorage)
 
214
                        delete tmpStorage;
 
215
                return (WPXInputStream*)0;
 
216
        }
 
217
 
 
218
        delete tmpStorage;
 
219
        return new WPXStringStream((const char *)(d->buf), tmpLength);
 
220
}
 
221
 
 
222
WPXInputStream* WPXFileStream::getDocumentOLEStream()
 
223
{
 
224
        return getDocumentOLEStream("PerfectOffice_MAIN");
 
225
}
 
226
 
 
227
WPXStringStream::WPXStringStream(const char *data, const unsigned int dataSize) :
 
228
        WPXInputStream(true),
 
229
        d(new WPXStringStreamPrivate(std::string(data, dataSize)))
 
230
{
 
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)
 
234
                d->streamSize = 0;
 
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 );
 
239
}
 
240
 
 
241
WPXStringStream::~WPXStringStream()
 
242
{
 
243
        delete d;
 
244
}
 
245
 
 
246
const uint8_t *WPXStringStream::read(size_t numBytes, size_t &numBytesRead)
 
247
{
 
248
        numBytesRead = 0;
 
249
        
 
250
        if (numBytes < 0 || atEOS() || numBytes > (std::numeric_limits<unsigned long>::max)()/2)
 
251
                return 0;
 
252
 
 
253
        unsigned long curpos = d->buffer.tellg();
 
254
        if (curpos == (unsigned long)-1) //tellg() returned ERROR
 
255
                return 0;
 
256
 
 
257
        if ( (curpos + numBytes < curpos) /*overflow*/ ||
 
258
                (curpos + numBytes > d->streamSize) ) /*reading more than available*/
 
259
        {
 
260
                numBytes = d->streamSize - curpos;
 
261
        }
 
262
 
 
263
        if (d->buf)
 
264
                delete [] d->buf;
 
265
        d->buf = new uint8_t[numBytes];
 
266
 
 
267
        if(d->buffer.good())
 
268
        {
 
269
                d->buffer.read((char *)(d->buf), numBytes); 
 
270
                numBytesRead = (long)d->buffer.tellg() - curpos;
 
271
        }
 
272
        
 
273
        return d->buf;
 
274
}
 
275
 
 
276
long WPXStringStream::tell()
 
277
{
 
278
        return d->buffer.good() ? (long)d->buffer.tellg() : -1L;
 
279
}
 
280
 
 
281
int WPXStringStream::seek(long offset, WPX_SEEK_TYPE seekType)
 
282
{
 
283
        if (seekType == WPX_SEEK_SET)
 
284
        {
 
285
                if (offset < 0)
 
286
                        offset = 0;
 
287
                if (offset > (long)d->streamSize)
 
288
                        offset = d->streamSize;
 
289
        }
 
290
 
 
291
        if (seekType == WPX_SEEK_CUR)
 
292
        {
 
293
                if (tell() + offset < 0)
 
294
                        offset = -tell();
 
295
                if (tell() + offset > (long)d->streamSize)
 
296
                        offset = d->streamSize - tell();
 
297
        }
 
298
 
 
299
        if(d->buffer.good())
 
300
        {
 
301
                d->buffer.seekg(offset, ((seekType == WPX_SEEK_SET) ? std::ios::beg : std::ios::cur));
 
302
                return (int) ( (long)d->buffer.tellg() == -1);
 
303
        }
 
304
        else
 
305
                return -1;
 
306
}
 
307
 
 
308
bool WPXStringStream::atEOS()
 
309
{
 
310
        return (d->buffer.tellg() >= (long)d->streamSize);
 
311
}
 
312
 
 
313
bool WPXStringStream::isOLEStream()
 
314
{
 
315
        Storage tmpStorage( d->buffer );
 
316
        if (tmpStorage.isOLEStream())
 
317
        {
 
318
                seek(0, WPX_SEEK_SET);
 
319
                return true;
 
320
        }
 
321
        seek(0, WPX_SEEK_SET);
 
322
        return false;
 
323
}
 
324
 
 
325
WPXInputStream* WPXStringStream::getDocumentOLEStream(const char * name)
 
326
{
 
327
        Storage *tmpStorage = new Storage( d->buffer );
 
328
        Stream tmpStream( tmpStorage, name );
 
329
        if (!tmpStorage || (tmpStorage->result() != Storage::Ok)  || !tmpStream.size())
 
330
        {
 
331
                if (tmpStorage)
 
332
                        delete tmpStorage;
 
333
                return (WPXInputStream*)0;
 
334
        }
 
335
        
 
336
        if (d->buf)
 
337
                delete [] d->buf;
 
338
        d->buf = new uint8_t[tmpStream.size()];
 
339
        unsigned long tmpLength;
 
340
        tmpLength = tmpStream.read((unsigned char *)(d->buf), tmpStream.size());
 
341
 
 
342
        // sanity check
 
343
        if (tmpLength > tmpStream.size() || tmpLength < tmpStream.size())
 
344
        /* something went wrong here and we do not trust the
 
345
           resulting buffer */
 
346
        {
 
347
                if (tmpStorage)
 
348
                        delete tmpStorage;
 
349
                return (WPXInputStream*)0;
 
350
        }
 
351
 
 
352
        delete tmpStorage;
 
353
        return new WPXStringStream((const char *)(d->buf), tmpLength);
 
354
}
 
355
 
 
356
WPXInputStream* WPXStringStream::getDocumentOLEStream()
 
357
{
 
358
        return getDocumentOLEStream("PerfectOffice_MAIN");
 
359
}