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 938 : LwpObjectStream::LwpObjectStream(LwpSvStream *pStrm, sal_Bool isCompressed, sal_uInt16 size)
69 : :m_pContentBuf(NULL), m_nBufSize(size), m_nReadPos(0),
70 938 : m_pStrm(pStrm), m_bCompressed(isCompressed)
71 : {
72 : assert(size<IO_BUFFERSIZE);
73 938 : ReadStream();
74 937 : }
75 : /**
76 : * @descr read object data from stream
77 : */
78 938 : void LwpObjectStream::ReadStream()
79 : {
80 938 : if(m_nBufSize == 0)
81 : {
82 0 : m_pContentBuf = NULL;
83 : }
84 : else
85 : {
86 938 : Read2Buffer();
87 : }
88 937 : }
89 : /**
90 : * @descr read object data from stream to buffer
91 : */
92 938 : void LwpObjectStream::Read2Buffer()
93 : {
94 938 : if( m_pContentBuf )
95 : {
96 0 : ReleaseBuffer();
97 : }
98 :
99 938 : m_nReadPos = 0;
100 :
101 938 : if( m_bCompressed )
102 : {
103 931 : boost::scoped_array<sal_uInt8> xCompressBuf(new sal_uInt8[m_nBufSize]);
104 :
105 931 : sal_uInt8* pCompressBuffer = xCompressBuf.get();
106 931 : memset(pCompressBuffer, 0, m_nBufSize);
107 931 : m_pStrm->Read(pCompressBuffer, m_nBufSize);
108 :
109 : sal_uInt8 pTempDst[IO_BUFFERSIZE];
110 931 : m_nBufSize = DecompressBuffer(pTempDst, pCompressBuffer, m_nBufSize);
111 : assert( m_nBufSize < IO_BUFFERSIZE);
112 :
113 930 : m_pContentBuf = AllocBuffer(m_nBufSize);
114 931 : 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 937 : }
124 : /**
125 : * @descr alloc size of buffer
126 : */
127 937 : sal_uInt8* LwpObjectStream::AllocBuffer(sal_uInt16 size)
128 : {
129 937 : if(size<=100)
130 : {
131 614 : 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 917 : void LwpObjectStream::ReadComplete()
142 : {
143 917 : ReleaseBuffer();
144 917 : }
145 :
146 935 : LwpObjectStream::~LwpObjectStream()
147 : {
148 935 : ReleaseBuffer();
149 935 : }
150 : /**
151 : * @descr release object buffer
152 : */
153 1852 : void LwpObjectStream::ReleaseBuffer()
154 : {
155 :
156 1852 : if(m_nBufSize>100)
157 : {
158 628 : if(m_pContentBuf)
159 : {
160 321 : delete [] m_pContentBuf;
161 321 : m_pContentBuf = NULL;
162 : }
163 : }
164 1852 : }
165 : /**
166 : * @descr read len bytes from object stream to buffer
167 : */
168 62924 : sal_uInt16 LwpObjectStream::QuickRead(void* buf, sal_uInt16 len)
169 : {
170 62924 : memset(buf, 0, len);
171 62924 : if( len > m_nBufSize - m_nReadPos )
172 : {
173 : assert(false);
174 0 : len = m_nBufSize - m_nReadPos;
175 : }
176 62924 : if( m_pContentBuf && len)
177 : {
178 62924 : memcpy(buf, m_pContentBuf+m_nReadPos, len);
179 62924 : m_nReadPos += len;
180 : }
181 62924 : return len;
182 : }
183 : /**
184 : * @descr SeekRel pos in object stream/buffer
185 : */
186 403 : void LwpObjectStream::SeekRel(sal_uInt16 pos)
187 : {
188 403 : if( pos > m_nBufSize - m_nReadPos)
189 0 : pos = m_nBufSize - m_nReadPos;
190 403 : m_nReadPos +=pos;
191 403 : }
192 : /**
193 : * @descr Seek to pos in object buffer/buffer
194 : */
195 908 : sal_Bool LwpObjectStream::Seek( sal_uInt16 pos)
196 : {
197 908 : if (pos < m_nBufSize)
198 : {
199 908 : m_nReadPos = pos;
200 908 : return sal_True;
201 : }
202 0 : return sal_False;
203 : }
204 :
205 : /**
206 : * @descr Quick read sal_Bool
207 : */
208 759 : sal_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<sal_Bool>(SVBT16ToShort(aValue));
215 : }
216 : /**
217 : * @descr Quick read sal_uInt32
218 : */
219 7396 : sal_uInt32 LwpObjectStream::QuickReaduInt32(bool *pFailure)
220 : {
221 7396 : SVBT32 aValue = {0};
222 7396 : sal_uInt16 nRead = QuickRead(aValue, sizeof(aValue));
223 7396 : if (pFailure)
224 669 : *pFailure = (nRead != sizeof(aValue));
225 7396 : return SVBT32ToUInt32(aValue);
226 : }
227 : /**
228 : * @descr Quick read sal_uInt32
229 : */
230 22021 : sal_uInt16 LwpObjectStream::QuickReaduInt16(bool *pFailure)
231 : {
232 22021 : SVBT16 aValue = {0};
233 22021 : sal_uInt16 nRead = QuickRead(aValue, sizeof(aValue));
234 22021 : if (pFailure)
235 469 : *pFailure = (nRead != sizeof(aValue));
236 22021 : 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 29864 : sal_uInt8 LwpObjectStream::QuickReaduInt8(bool *pFailure)
265 : {
266 29864 : SVBT8 aValue = {0};
267 29864 : sal_uInt16 nRead = QuickRead(aValue, sizeof(aValue));
268 29864 : if (pFailure)
269 2209 : *pFailure = (nRead != sizeof(aValue));
270 29864 : return SVBT8ToByte(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 3773 : void LwpObjectStream::SkipExtra()
296 : {
297 3773 : sal_uInt16 extra = QuickReaduInt16();
298 7559 : while (extra != 0)
299 13 : extra = QuickReaduInt16();
300 3773 : }
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 931 : sal_uInt16 LwpObjectStream::DecompressBuffer(sal_uInt8* pDst, sal_uInt8* pSrc, sal_uInt16 Size)
313 : {
314 : sal_uInt16 Cnt;
315 931 : sal_uInt32 DstSize = 0;
316 :
317 22504 : while (Size)
318 : {
319 20643 : 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 2131 : Cnt = (*pSrc++ & 0x3F) + 1;
327 2131 : if (DstSize+Cnt >= IO_BUFFERSIZE)
328 0 : throw BadDecompress();
329 2131 : memset(pDst, 0, Cnt);
330 2131 : pDst += Cnt;
331 2131 : DstSize += Cnt;
332 2131 : Size--;
333 2131 : 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 15750 : Cnt = ((*pSrc & 0x38) >> 3) + 1;
342 15750 : if (DstSize+Cnt >= IO_BUFFERSIZE)
343 0 : throw BadDecompress();
344 15750 : memset(pDst, 0, Cnt);
345 15750 : pDst += Cnt;
346 15750 : DstSize += Cnt;
347 15750 : Cnt = (*pSrc++ & 0x07) + 1;
348 15750 : if (Size < Cnt + 1)
349 1 : throw BadDecompress();
350 15749 : Size -= Cnt + 1;
351 15749 : if (DstSize+Cnt >= IO_BUFFERSIZE)
352 0 : throw BadDecompress();
353 15749 : memcpy(pDst, pSrc, Cnt);
354 15749 : pDst += Cnt;
355 15749 : DstSize += Cnt;
356 15749 : pSrc += Cnt;
357 15749 : 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 556 : *pDst++ = 0;
366 556 : DstSize++;
367 : // fall thru 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 2762 : Cnt = (*pSrc++ & 0x3F) + 1;
375 2762 : if (Size < Cnt + 1)
376 0 : throw BadDecompress();
377 2762 : Size -= Cnt + 1;
378 2762 : if (DstSize+Cnt >= IO_BUFFERSIZE)
379 0 : throw BadDecompress();
380 2762 : memcpy(pDst, pSrc, Cnt);
381 2762 : pDst += Cnt;
382 2762 : DstSize += Cnt;
383 2762 : pSrc += Cnt;
384 2762 : break;
385 : }
386 : assert(DstSize < IO_BUFFERSIZE);
387 20642 : if (DstSize >= IO_BUFFERSIZE)
388 0 : throw BadDecompress();
389 :
390 : }
391 930 : return(static_cast<sal_uInt16>(DstSize));
392 : }
393 : /**
394 : * @descr quick read string with 1252
395 : */
396 24 : OUString LwpObjectStream::QuickReadStringPtr(void)
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: */
|