1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * The Contents of this file are made available subject to the terms of
5 * either of the following licenses
7 * - GNU Lesser General Public License Version 2.1
8 * - Sun Industry Standards Source License Version 1.1
10 * Sun Microsystems Inc., October, 2000
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
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.
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.
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,
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.
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.
46 * The Initial Developer of the Original Code is: IBM Corporation
48 * Copyright: 2008 by IBM Corporation
50 * All Rights Reserved.
52 * Contributor(s): _______________________________________
55 ************************************************************************/
57 #include <lwpobjstrm.hxx>
58 #include <lwptools.hxx>
60 #include <sal/types.h>
61 #include <tools/solar.h>
65 * @descr ctor() from LwpSvStream
67 LwpObjectStream::LwpObjectStream(LwpSvStream
* pStrm
, bool isCompressed
, sal_uInt16 size
)
68 : m_pContentBuf(nullptr)
72 , m_bCompressed(isCompressed
)
74 if (m_nBufSize
>= IO_BUFFERSIZE
)
75 throw std::range_error("bad Object size");
76 // read object data from stream
82 * @descr read object data from stream to buffer
84 void LwpObjectStream::Read2Buffer()
92 std::unique_ptr
<sal_uInt8
[]> xCompressBuf(new sal_uInt8
[m_nBufSize
]);
94 sal_uInt8
* pCompressBuffer
= xCompressBuf
.get();
95 memset(pCompressBuffer
, 0, m_nBufSize
);
96 m_nBufSize
= m_pStrm
->Read(pCompressBuffer
, m_nBufSize
);
98 sal_uInt8 pTempDst
[IO_BUFFERSIZE
];
99 m_nBufSize
= DecompressBuffer(pTempDst
, pCompressBuffer
, m_nBufSize
);
100 assert(m_nBufSize
< IO_BUFFERSIZE
);
102 m_pContentBuf
= AllocBuffer(m_nBufSize
);
103 memcpy(m_pContentBuf
, pTempDst
, m_nBufSize
);
107 m_pContentBuf
= AllocBuffer(m_nBufSize
);
108 m_nBufSize
= m_pStrm
->Read(m_pContentBuf
, m_nBufSize
);
112 * @descr alloc size of buffer
114 sal_uInt8
* LwpObjectStream::AllocBuffer(sal_uInt16 size
)
118 return m_SmallBuffer
;
120 m_BigBuffer
.resize(size
);
121 return m_BigBuffer
.data();
124 * @descr signal complete to release object buffer
126 void LwpObjectStream::ReadComplete() { ReleaseBuffer(); }
128 LwpObjectStream::~LwpObjectStream() { ReleaseBuffer(); }
130 * @descr release object buffer
132 void LwpObjectStream::ReleaseBuffer()
135 m_pContentBuf
= nullptr;
138 sal_uInt16
LwpObjectStream::remainingSize() const { return m_nBufSize
- m_nReadPos
; }
141 * @descr read len bytes from object stream to buffer
143 sal_uInt16
LwpObjectStream::QuickRead(void* buf
, sal_uInt16 len
)
146 if (len
> m_nBufSize
- m_nReadPos
)
148 len
= m_nBufSize
- m_nReadPos
;
150 if (m_pContentBuf
&& len
)
152 memcpy(buf
, m_pContentBuf
+ m_nReadPos
, len
);
158 * @descr SeekRel pos in object stream/buffer
160 void LwpObjectStream::SeekRel(sal_uInt16 pos
)
162 if (pos
> m_nBufSize
- m_nReadPos
)
163 pos
= m_nBufSize
- m_nReadPos
;
167 * @descr Seek to pos in object buffer/buffer
169 void LwpObjectStream::Seek(sal_uInt16 pos
)
171 if (pos
< m_nBufSize
)
178 * @descr Quick read sal_Bool
180 bool LwpObjectStream::QuickReadBool()
182 SVBT16 aValue
= { 0 };
183 QuickRead(aValue
, sizeof(aValue
));
184 return static_cast<bool>(SVBT16ToUInt16(aValue
));
187 * @descr Quick read sal_uInt32
189 sal_uInt32
LwpObjectStream::QuickReaduInt32(bool* pFailure
)
191 SVBT32 aValue
= { 0 };
192 sal_uInt16 nRead
= QuickRead(aValue
, sizeof(aValue
));
194 *pFailure
= (nRead
!= sizeof(aValue
));
195 return SVBT32ToUInt32(aValue
);
198 * @descr Quick read sal_uInt32
200 sal_uInt16
LwpObjectStream::QuickReaduInt16(bool* pFailure
)
202 SVBT16 aValue
= { 0 };
203 sal_uInt16 nRead
= QuickRead(aValue
, sizeof(aValue
));
205 *pFailure
= (nRead
!= sizeof(aValue
));
206 return SVBT16ToUInt16(aValue
);
209 * @descr Quick read sal_Int32
211 sal_Int32
LwpObjectStream::QuickReadInt32()
213 SVBT32 aValue
= { 0 };
214 QuickRead(aValue
, sizeof(aValue
));
215 return static_cast<sal_Int32
>(SVBT32ToUInt32(aValue
));
218 * @descr Quick read sal_Int16
220 sal_Int16
LwpObjectStream::QuickReadInt16()
222 SVBT16 aValue
= { 0 };
223 QuickRead(aValue
, sizeof(aValue
));
225 return static_cast<sal_Int16
>(SVBT16ToUInt16(aValue
));
228 * @descr Quick read sal_uInt8
230 sal_uInt8
LwpObjectStream::QuickReaduInt8(bool* pFailure
)
232 sal_uInt8 aValue
= 0;
233 sal_uInt16 nRead
= QuickRead(&aValue
, sizeof(aValue
));
235 *pFailure
= (nRead
!= sizeof(aValue
));
239 * @descr Quick read double
241 double LwpObjectStream::QuickReadDouble()
247 memset(s
.c
, 0, sizeof(s
.c
));
248 QuickRead(s
.c
, sizeof(s
.c
));
249 #if defined(OSL_BIGENDIAN)
250 for (size_t i
= 0; i
< 4; ++i
)
251 std::swap(s
.c
[i
], s
.c
[7 - i
]);
256 * @descr skip extra bytes
258 void LwpObjectStream::SkipExtra()
260 sal_uInt16 extra
= QuickReaduInt16();
262 extra
= QuickReaduInt16();
265 * @descr check if extra bytes
267 sal_uInt16
LwpObjectStream::CheckExtra() { return QuickReaduInt16(); }
269 * @descr decompress data buffer from pSrc to pDst
270 * Refer to the CAmiPro40File::DecompressObject(~) in LWP
272 sal_uInt16
LwpObjectStream::DecompressBuffer(sal_uInt8
* pDst
, sal_uInt8
* pSrc
, sal_uInt16 Size
)
275 sal_uInt32 DstSize
= 0;
279 switch (*pSrc
& 0xC0)
284 // where zzzzzz is the count - 1 of compressed 0 bytes
286 Cnt
= (*pSrc
++ & 0x3F) + 1;
287 if (DstSize
+ Cnt
>= IO_BUFFERSIZE
)
288 throw BadDecompress();
289 memset(pDst
, 0, Cnt
);
296 // 1 - 8 zeros followed by 1 - 8 non-zero
297 // Code 01zzznnn binary
298 // where zzz is the count - 1 of compressed zero bytes
299 // and nnn is the count - 1 of following non-zero bytes
301 Cnt
= ((*pSrc
& 0x38) >> 3) + 1;
302 if (DstSize
+ Cnt
>= IO_BUFFERSIZE
)
303 throw BadDecompress();
304 memset(pDst
, 0, Cnt
);
307 Cnt
= (*pSrc
++ & 0x07) + 1;
309 throw BadDecompress();
311 if (DstSize
+ Cnt
>= IO_BUFFERSIZE
)
312 throw BadDecompress();
313 memcpy(pDst
, pSrc
, Cnt
);
320 // 1 0 followed by 1 - 64 bytes of non-zero
321 // Code 0x80 (or 0x40 if 8 or less non-zero)
322 // Code 10nnnnnn binary
323 // where nnnnnn is the count - 1 of following non-zero bytes
330 // 1 - 64 bytes of non-zero
331 // Code = 11nnnnnn binary
332 // nnnnnn is the count less 1 of following non-zero bytes
334 Cnt
= (*pSrc
++ & 0x3F) + 1;
336 throw BadDecompress();
338 if (DstSize
+ Cnt
>= IO_BUFFERSIZE
)
339 throw BadDecompress();
340 memcpy(pDst
, pSrc
, Cnt
);
346 assert(DstSize
< IO_BUFFERSIZE
);
347 if (DstSize
>= IO_BUFFERSIZE
)
348 throw BadDecompress();
350 return static_cast<sal_uInt16
>(DstSize
);
353 * @descr quick read string with 1252
355 OUString
LwpObjectStream::QuickReadStringPtr()
359 diskSize
= QuickReaduInt16();
360 QuickReaduInt16(); //len
363 if (diskSize
< sizeof diskSize
)
364 throw std::range_error("Too small size");
365 LwpTools::QuickReadUnicode(this, str
, diskSize
- sizeof(diskSize
), RTL_TEXTENCODING_MS_1252
);
369 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */