Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*************************************************************************
3 : *
4 : * The Contents of this file are made available subject to the terms of
5 : * either of the following licenses
6 : *
7 : * - GNU Lesser General Public License Version 2.1
8 : * - Sun Industry Standards Source License Version 1.1
9 : *
10 : * Sun Microsystems Inc., October, 2000
11 : *
12 : * GNU Lesser General Public License Version 2.1
13 : * =============================================
14 : * Copyright 2000 by Sun Microsystems, Inc.
15 : * 901 San Antonio Road, Palo Alto, CA 94303, USA
16 : *
17 : * This library is free software; you can redistribute it and/or
18 : * modify it under the terms of the GNU Lesser General Public
19 : * License version 2.1, as published by the Free Software Foundation.
20 : *
21 : * This library is distributed in the hope that it will be useful,
22 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24 : * Lesser General Public License for more details.
25 : *
26 : * You should have received a copy of the GNU Lesser General Public
27 : * License along with this library; if not, write to the Free Software
28 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
29 : * MA 02111-1307 USA
30 : *
31 : *
32 : * Sun Industry Standards Source License Version 1.1
33 : * =================================================
34 : * The contents of this file are subject to the Sun Industry Standards
35 : * Source License Version 1.1 (the "License"); You may not use this file
36 : * except in compliance with the License. You may obtain a copy of the
37 : * License at http://www.openoffice.org/license.html.
38 : *
39 : * Software provided under this License is provided on an "AS IS" basis,
40 : * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
41 : * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
42 : * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
43 : * See the License for the specific provisions governing your rights and
44 : * obligations concerning the Software.
45 : *
46 : * The Initial Developer of the Original Code is: IBM Corporation
47 : *
48 : * Copyright: 2008 by IBM Corporation
49 : *
50 : * All Rights Reserved.
51 : *
52 : * Contributor(s): _______________________________________
53 : *
54 : *
55 : ************************************************************************/
56 : /*************************************************************************
57 : * Change History
58 : Jan 2005 Created
59 : ************************************************************************/
60 :
61 : #include "lwpobjstrm.hxx"
62 : #include "lwptools.hxx"
63 : #include <boost/scoped_array.hpp>
64 :
65 : /**
66 : * @descr ctor() from LwpSvStream
67 : */
68 932 : LwpObjectStream::LwpObjectStream(LwpSvStream *pStrm, bool isCompressed, sal_uInt16 size)
69 : :m_pContentBuf(NULL), m_nBufSize(size), m_nReadPos(0),
70 932 : m_pStrm(pStrm), m_bCompressed(isCompressed)
71 : {
72 : assert(size<IO_BUFFERSIZE);
73 932 : ReadStream();
74 931 : }
75 : /**
76 : * @descr read object data from stream
77 : */
78 932 : void LwpObjectStream::ReadStream()
79 : {
80 932 : if(m_nBufSize == 0)
81 : {
82 0 : m_pContentBuf = NULL;
83 : }
84 : else
85 : {
86 932 : Read2Buffer();
87 : }
88 931 : }
89 : /**
90 : * @descr read object data from stream to buffer
91 : */
92 932 : void LwpObjectStream::Read2Buffer()
93 : {
94 932 : if( m_pContentBuf )
95 : {
96 0 : ReleaseBuffer();
97 : }
98 :
99 932 : m_nReadPos = 0;
100 :
101 932 : if( m_bCompressed )
102 : {
103 925 : boost::scoped_array<sal_uInt8> xCompressBuf(new sal_uInt8[m_nBufSize]);
104 :
105 925 : sal_uInt8* pCompressBuffer = xCompressBuf.get();
106 925 : memset(pCompressBuffer, 0, m_nBufSize);
107 925 : m_pStrm->Read(pCompressBuffer, m_nBufSize);
108 :
109 : sal_uInt8 pTempDst[IO_BUFFERSIZE];
110 925 : m_nBufSize = DecompressBuffer(pTempDst, pCompressBuffer, m_nBufSize);
111 : assert( m_nBufSize < IO_BUFFERSIZE);
112 :
113 924 : m_pContentBuf = AllocBuffer(m_nBufSize);
114 925 : memcpy(m_pContentBuf, pTempDst, m_nBufSize);
115 : //delete [] pTempDst;
116 :
117 : }
118 : else
119 : {
120 7 : m_pContentBuf = AllocBuffer(m_nBufSize);
121 7 : m_pStrm->Read(m_pContentBuf, m_nBufSize);
122 : }
123 931 : }
124 : /**
125 : * @descr alloc size of buffer
126 : */
127 931 : sal_uInt8* LwpObjectStream::AllocBuffer(sal_uInt16 size)
128 : {
129 931 : if(size<=100)
130 : {
131 608 : return m_SmallBuffer;
132 : }
133 : else
134 : {
135 323 : return new sal_uInt8[size];
136 : }
137 : }
138 : /**
139 : * @descr signal complete to release object buffer
140 : */
141 911 : void LwpObjectStream::ReadComplete()
142 : {
143 911 : ReleaseBuffer();
144 911 : }
145 :
146 931 : LwpObjectStream::~LwpObjectStream()
147 : {
148 931 : ReleaseBuffer();
149 931 : }
150 : /**
151 : * @descr release object buffer
152 : */
153 1842 : void LwpObjectStream::ReleaseBuffer()
154 : {
155 :
156 1842 : if(m_nBufSize>100)
157 : {
158 630 : if(m_pContentBuf)
159 : {
160 323 : delete [] m_pContentBuf;
161 323 : m_pContentBuf = NULL;
162 : }
163 : }
164 1842 : }
165 : /**
166 : * @descr read len bytes from object stream to buffer
167 : */
168 62734 : sal_uInt16 LwpObjectStream::QuickRead(void* buf, sal_uInt16 len)
169 : {
170 62734 : memset(buf, 0, len);
171 62734 : if( len > m_nBufSize - m_nReadPos )
172 : {
173 : assert(false);
174 0 : len = m_nBufSize - m_nReadPos;
175 : }
176 62734 : if( m_pContentBuf && len)
177 : {
178 62734 : memcpy(buf, m_pContentBuf+m_nReadPos, len);
179 62734 : m_nReadPos += len;
180 : }
181 62734 : return len;
182 : }
183 : /**
184 : * @descr SeekRel pos in object stream/buffer
185 : */
186 400 : void LwpObjectStream::SeekRel(sal_uInt16 pos)
187 : {
188 400 : if( pos > m_nBufSize - m_nReadPos)
189 0 : pos = m_nBufSize - m_nReadPos;
190 400 : m_nReadPos +=pos;
191 400 : }
192 : /**
193 : * @descr Seek to pos in object buffer/buffer
194 : */
195 903 : bool LwpObjectStream::Seek( sal_uInt16 pos)
196 : {
197 903 : if (pos < m_nBufSize)
198 : {
199 903 : m_nReadPos = pos;
200 903 : return true;
201 : }
202 0 : return false;
203 : }
204 :
205 : /**
206 : * @descr Quick read sal_Bool
207 : */
208 759 : bool LwpObjectStream::QuickReadBool(bool *pFailure)
209 : {
210 759 : SVBT16 aValue = {0};
211 759 : sal_uInt16 nRead = QuickRead(aValue, sizeof(aValue));
212 759 : if (pFailure)
213 0 : *pFailure = (nRead != sizeof(aValue));
214 759 : return static_cast<bool>(SVBT16ToShort(aValue));
215 : }
216 : /**
217 : * @descr Quick read sal_uInt32
218 : */
219 7378 : sal_uInt32 LwpObjectStream::QuickReaduInt32(bool *pFailure)
220 : {
221 7378 : SVBT32 aValue = {0};
222 7378 : sal_uInt16 nRead = QuickRead(aValue, sizeof(aValue));
223 7378 : if (pFailure)
224 666 : *pFailure = (nRead != sizeof(aValue));
225 7378 : return SVBT32ToUInt32(aValue);
226 : }
227 : /**
228 : * @descr Quick read sal_uInt32
229 : */
230 21944 : sal_uInt16 LwpObjectStream::QuickReaduInt16(bool *pFailure)
231 : {
232 21944 : SVBT16 aValue = {0};
233 21944 : sal_uInt16 nRead = QuickRead(aValue, sizeof(aValue));
234 21944 : if (pFailure)
235 469 : *pFailure = (nRead != sizeof(aValue));
236 21944 : return SVBT16ToShort(aValue);
237 : }
238 : /**
239 : * @descr Quick read sal_Int32
240 : */
241 1941 : sal_Int32 LwpObjectStream::QuickReadInt32(bool *pFailure)
242 : {
243 1941 : SVBT32 aValue = {0};
244 1941 : sal_uInt16 nRead = QuickRead(aValue, sizeof(aValue));
245 1941 : if (pFailure)
246 0 : *pFailure = (nRead != sizeof(aValue));
247 1941 : return static_cast<sal_Int32>(SVBT32ToUInt32(aValue));
248 : }
249 : /**
250 : * @descr Quick read sal_Int16
251 : */
252 58 : sal_Int16 LwpObjectStream::QuickReadInt16(bool *pFailure)
253 : {
254 58 : SVBT16 aValue = {0};
255 58 : sal_uInt16 nRead = QuickRead(aValue, sizeof(aValue));
256 58 : if (pFailure)
257 0 : *pFailure = (nRead != sizeof(aValue));
258 :
259 58 : return static_cast<sal_Int16>(SVBT16ToShort(aValue));
260 : }
261 : /**
262 : * @descr Quick read sal_uInt8
263 : */
264 29774 : sal_uInt8 LwpObjectStream::QuickReaduInt8(bool *pFailure)
265 : {
266 29774 : sal_uInt8 aValue = 0;
267 29774 : sal_uInt16 nRead = QuickRead(&aValue, sizeof(aValue));
268 29774 : if (pFailure)
269 2209 : *pFailure = (nRead != sizeof(aValue));
270 29774 : return aValue;
271 : }
272 : /**
273 : * @descr Quick read double
274 : */
275 0 : double LwpObjectStream::QuickReadDouble(bool *pFailure)
276 : {
277 : union
278 : {
279 : double d;
280 : sal_uInt8 c[8];
281 : } s;
282 0 : memset(s.c, 0, sizeof(s.c));
283 0 : sal_uInt16 nRead = QuickRead(s.c, sizeof(s.c));
284 0 : if (pFailure)
285 0 : *pFailure = (nRead != sizeof(s.c));
286 : #if defined(OSL_BIGENDIAN)
287 : for (size_t i = 0; i < 4; ++i)
288 : std::swap(s.c[i], s.c[7-i]);
289 : #endif
290 0 : return s.d;
291 : }
292 : /**
293 : * @descr skip extra bytes
294 : */
295 3764 : void LwpObjectStream::SkipExtra()
296 : {
297 3764 : sal_uInt16 extra = QuickReaduInt16();
298 7541 : while (extra != 0)
299 13 : extra = QuickReaduInt16();
300 3764 : }
301 : /**
302 : * @descr check if extra bytes
303 : */
304 514 : sal_uInt16 LwpObjectStream::CheckExtra()
305 : {
306 514 : return QuickReaduInt16();
307 : }
308 : /**
309 : * @descr decompress data buffer from pSrc to pDst
310 : * Refer to the CAmiPro40File::DecompressObject(~) in LWP
311 : */
312 925 : sal_uInt16 LwpObjectStream::DecompressBuffer(sal_uInt8* pDst, sal_uInt8* pSrc, sal_uInt16 Size)
313 : {
314 : sal_uInt16 Cnt;
315 925 : sal_uInt32 DstSize = 0;
316 :
317 22441 : while (Size)
318 : {
319 20592 : switch (*pSrc & 0xC0)
320 : {
321 : case 0x00:
322 : // 1 - 64 bytes of 0
323 : // Code 00zzzzzz
324 : // where zzzzzz is the count - 1 of compressed 0 bytes
325 :
326 2121 : Cnt = (*pSrc++ & 0x3F) + 1;
327 2121 : if (DstSize+Cnt >= IO_BUFFERSIZE)
328 0 : throw BadDecompress();
329 2121 : memset(pDst, 0, Cnt);
330 2121 : pDst += Cnt;
331 2121 : DstSize += Cnt;
332 2121 : Size--;
333 2121 : break;
334 :
335 : case 0x40:
336 : // 1 - 8 zeros followed by 1 - 8 non-zero
337 : // Code 01zzznnn binary
338 : // where zzz is the count - 1 of compressed zero bytes
339 : // and nnn is the count - 1 of following non-zero bytes
340 :
341 15726 : Cnt = ((*pSrc & 0x38) >> 3) + 1;
342 15726 : if (DstSize+Cnt >= IO_BUFFERSIZE)
343 0 : throw BadDecompress();
344 15726 : memset(pDst, 0, Cnt);
345 15726 : pDst += Cnt;
346 15726 : DstSize += Cnt;
347 15726 : Cnt = (*pSrc++ & 0x07) + 1;
348 15726 : if (Size < Cnt + 1)
349 1 : throw BadDecompress();
350 15725 : Size -= Cnt + 1;
351 15725 : if (DstSize+Cnt >= IO_BUFFERSIZE)
352 0 : throw BadDecompress();
353 15725 : memcpy(pDst, pSrc, Cnt);
354 15725 : pDst += Cnt;
355 15725 : DstSize += Cnt;
356 15725 : pSrc += Cnt;
357 15725 : break;
358 :
359 : case 0x80:
360 : // 1 0 followed by 1 - 64 bytes of non-zero
361 : // Code 0x80 (or 0x40 if 8 or less non-zero)
362 : // Code 10nnnnnn binary
363 : // where nnnnnn is the count - 1 of following non-zero bytes
364 :
365 553 : *pDst++ = 0;
366 553 : DstSize++;
367 : // fall through into next case!
368 :
369 : case 0xC0:
370 : // 1 - 64 bytes of non-zero
371 : // Code = 11nnnnnn binary
372 : // nnnnnn is the count less 1 of following non-zero bytes
373 :
374 2745 : Cnt = (*pSrc++ & 0x3F) + 1;
375 2745 : if (Size < Cnt + 1)
376 0 : throw BadDecompress();
377 2745 : Size -= Cnt + 1;
378 2745 : if (DstSize+Cnt >= IO_BUFFERSIZE)
379 0 : throw BadDecompress();
380 2745 : memcpy(pDst, pSrc, Cnt);
381 2745 : pDst += Cnt;
382 2745 : DstSize += Cnt;
383 2745 : pSrc += Cnt;
384 2745 : break;
385 : }
386 : assert(DstSize < IO_BUFFERSIZE);
387 20591 : if (DstSize >= IO_BUFFERSIZE)
388 0 : throw BadDecompress();
389 :
390 : }
391 924 : return static_cast<sal_uInt16>(DstSize);
392 : }
393 : /**
394 : * @descr quick read string with 1252
395 : */
396 24 : OUString LwpObjectStream::QuickReadStringPtr()
397 : {
398 : sal_uInt16 diskSize;
399 :
400 24 : diskSize = QuickReaduInt16();
401 24 : QuickReaduInt16(); //len
402 :
403 24 : OUString str;
404 24 : rtl_TextEncoding rEncode = RTL_TEXTENCODING_MS_1252;
405 24 : LwpTools::QuickReadUnicode(this, str, diskSize-sizeof(diskSize), rEncode);
406 24 : return str;
407 : }
408 :
409 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|