Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*
3 : : * This file is part of the LibreOffice project.
4 : : *
5 : : * This Source Code Form is subject to the terms of the Mozilla Public
6 : : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : : *
9 : : * This file incorporates work covered by the following license notice:
10 : : *
11 : : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : : * contributor license agreements. See the NOTICE file distributed
13 : : * with this work for additional information regarding copyright
14 : : * ownership. The ASF licenses this file to you under the Apache
15 : : * License, Version 2.0 (the "License"); you may not use this file
16 : : * except in compliance with the License. You may obtain a copy of
17 : : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : : */
19 : :
20 : : #ifndef OOX_HELPER_BINARYINPUTSTREAM_HXX
21 : : #define OOX_HELPER_BINARYINPUTSTREAM_HXX
22 : :
23 : : #include <vector>
24 : : #include <com/sun/star/io/XInputStream.hpp>
25 : : #include "oox/helper/binarystreambase.hxx"
26 : :
27 : : namespace com { namespace sun { namespace star {
28 : : namespace io { class XInputStream; }
29 : : } } }
30 : :
31 : : namespace oox {
32 : :
33 : : class BinaryOutputStream;
34 : :
35 : : // ============================================================================
36 : :
37 : : /** Interface for binary input stream classes.
38 : :
39 : : The binary data in the stream is assumed to be in little-endian format.
40 : : */
41 [ # # ][ # # ]: 1576 : class OOX_DLLPUBLIC BinaryInputStream : public virtual BinaryStreamBase
[ - + ][ - + ]
42 : : {
43 : : public:
44 : : /** Derived classes implement reading nBytes bytes to the passed sequence.
45 : : The sequence will be reallocated internally.
46 : :
47 : : @param nAtomSize
48 : : The size of the elements in the memory block, if available. Derived
49 : : classes may be interested in this information.
50 : :
51 : : @return
52 : : Number of bytes really read.
53 : : */
54 : : virtual sal_Int32 readData( StreamDataSequence& orData, sal_Int32 nBytes, size_t nAtomSize = 1 ) = 0;
55 : :
56 : : /** Derived classes implement reading nBytes bytes to the (preallocated!)
57 : : memory buffer opMem.
58 : :
59 : : @param nAtomSize
60 : : The size of the elements in the memory block, if available. Derived
61 : : classes may be interested in this information.
62 : :
63 : : @return
64 : : Number of bytes really read.
65 : : */
66 : : virtual sal_Int32 readMemory( void* opMem, sal_Int32 nBytes, size_t nAtomSize = 1 ) = 0;
67 : :
68 : : /** Derived classes implement seeking the stream forward by the passed
69 : : number of bytes. This should work for non-seekable streams too.
70 : :
71 : : @param nAtomSize
72 : : The size of the elements in the memory block, if available. Derived
73 : : classes may be interested in this information.
74 : : */
75 : : virtual void skip( sal_Int32 nBytes, size_t nAtomSize = 1 ) = 0;
76 : :
77 : : /** Reads a value from the stream and converts it to platform byte order.
78 : : All data types supported by the ByteOrderConverter class can be used.
79 : : */
80 : : template< typename Type >
81 : : void readValue( Type& ornValue );
82 : :
83 : : /** Reads a value from the stream and converts it to platform byte order.
84 : : All data types supported by the ByteOrderConverter class can be used.
85 : : */
86 : : template< typename Type >
87 [ + - ][ + - ]: 15430 : inline Type readValue() { Type nValue; readValue( nValue ); return nValue; }
[ + - ][ # # ]
[ # # ]
88 : :
89 : : /** Stream operator for all data types supported by the readValue() function. */
90 : : template< typename Type >
91 : 24370 : inline BinaryInputStream& operator>>( Type& ornValue ) { readValue( ornValue ); return *this; }
92 : :
93 : 0 : inline sal_Int8 readInt8() { return readValue< sal_Int8 >(); }
94 : 3954 : inline sal_uInt8 readuInt8() { return readValue< sal_uInt8 >(); }
95 : 0 : inline sal_Int16 readInt16() { return readValue< sal_Int16 >(); }
96 : 11288 : inline sal_uInt16 readuInt16() { return readValue< sal_uInt16 >(); }
97 : 0 : inline sal_Int32 readInt32() { return readValue< sal_Int32 >(); }
98 : 39 : inline sal_uInt32 readuInt32() { return readValue< sal_uInt32 >(); }
99 : : inline sal_Int64 readInt64() { return readValue< sal_Int64 >(); }
100 : : inline sal_uInt64 readuInt64() { return readValue< sal_uInt64 >(); }
101 : : inline float readFloat() { return readValue< float >(); }
102 : 0 : inline double readDouble() { return readValue< double >(); }
103 : :
104 : : /** Reads a (preallocated!) C array of values from the stream.
105 : :
106 : : Converts all values in the array to platform byte order. All data types
107 : : supported by the ByteOrderConverter class can be used.
108 : :
109 : : @param nElemCount
110 : : Number of array elements to read (NOT byte count).
111 : :
112 : : @return
113 : : Number of array elements really read (NOT byte count).
114 : : */
115 : : template< typename Type >
116 : : sal_Int32 readArray( Type* opnArray, sal_Int32 nElemCount );
117 : :
118 : : /** Reads a sequence of values from the stream.
119 : :
120 : : The sequence will be reallocated internally. Converts all values in the
121 : : array to platform byte order. All data types supported by the
122 : : ByteOrderConverter class can be used.
123 : :
124 : : @param nElemCount
125 : : Number of elements to put into the sequence (NOT byte count).
126 : :
127 : : @return
128 : : Number of sequence elements really read (NOT byte count).
129 : : */
130 : : template< typename Type >
131 : : sal_Int32 readArray( ::com::sun::star::uno::Sequence< Type >& orSequence, sal_Int32 nElemCount );
132 : :
133 : : /** Reads a vector of values from the stream.
134 : :
135 : : The vector will be resized internally. Converts all values in the
136 : : vector to platform byte order. All data types supported by the
137 : : ByteOrderConverter class can be used.
138 : :
139 : : @param nElemCount
140 : : Number of elements to put into the vector (NOT byte count).
141 : :
142 : : @return
143 : : Number of vector elements really read (NOT byte count).
144 : : */
145 : : template< typename Type >
146 : : sal_Int32 readArray( ::std::vector< Type >& orVector, sal_Int32 nElemCount );
147 : :
148 : : /** Skips an array of values of a certain type in the stream.
149 : :
150 : : All data types supported by the ByteOrderConverter class can be used.
151 : :
152 : : @param nElemCount
153 : : Number of array elements to skip (NOT byte count).
154 : : */
155 : : template< typename Type >
156 : : void skipArray( sal_Int32 nElemCount );
157 : :
158 : : /** Reads a NUL-terminated Unicode character array and returns the string.
159 : : */
160 : : ::rtl::OUString readNulUnicodeArray();
161 : :
162 : : /** Reads a byte character array and returns the string.
163 : :
164 : : @param nChars
165 : : Number of characters (bytes) to read from the stream.
166 : :
167 : : @param bAllowNulChars
168 : : True = NUL characters are inserted into the imported string.
169 : : False = NUL characters are replaced by question marks (default).
170 : : */
171 : : ::rtl::OString readCharArray( sal_Int32 nChars, bool bAllowNulChars = false );
172 : :
173 : : /** Reads a byte character array and returns a Unicode string.
174 : :
175 : : @param nChars
176 : : Number of characters (bytes) to read from the stream.
177 : :
178 : : @param eTextEnc
179 : : The text encoding used to create the Unicode string.
180 : :
181 : : @param bAllowNulChars
182 : : True = NUL characters are inserted into the imported string.
183 : : False = NUL characters are replaced by question marks (default).
184 : : */
185 : : ::rtl::OUString readCharArrayUC( sal_Int32 nChars, rtl_TextEncoding eTextEnc, bool bAllowNulChars = false );
186 : :
187 : : /** Reads a Unicode character array and returns the string.
188 : :
189 : : @param nChars
190 : : Number of 16-bit characters to read from the stream.
191 : :
192 : : @param bAllowNulChars
193 : : True = NUL characters are inserted into the imported string.
194 : : False = NUL characters are replaced by question marks (default).
195 : : */
196 : : ::rtl::OUString readUnicodeArray( sal_Int32 nChars, bool bAllowNulChars = false );
197 : :
198 : : /** Reads a Unicode character array (may be compressed) and returns the
199 : : string.
200 : :
201 : : @param nChars
202 : : Number of 8-bit or 16-bit characters to read from the stream.
203 : :
204 : : @param bCompressed
205 : : True = Character array is compressed (stored as 8-bit characters).
206 : : False = Character array is not compressed (stored as 16-bit characters).
207 : :
208 : : @param bAllowNulChars
209 : : True = NUL characters are inserted into the imported string.
210 : : False = NUL characters are replaced by question marks (default).
211 : : */
212 : : ::rtl::OUString readCompressedUnicodeArray( sal_Int32 nChars, bool bCompressed, bool bAllowNulChars = false );
213 : :
214 : : /** Copies nBytes bytes from the current position to the passed output stream.
215 : : */
216 : : void copyToStream( BinaryOutputStream& rOutStrm, sal_Int64 nBytes = SAL_MAX_INT64, sal_Int32 nAtomSize = 1 );
217 : :
218 : : protected:
219 : : /** This dummy default c'tor will never call the c'tor of the virtual base
220 : : class BinaryStreamBase as this class cannot be instanciated directly. */
221 : 2294 : inline explicit BinaryInputStream() : BinaryStreamBase( false ) {}
222 : : };
223 : :
224 : : typedef ::boost::shared_ptr< BinaryInputStream > BinaryInputStreamRef;
225 : :
226 : : // ----------------------------------------------------------------------------
227 : :
228 : : template< typename Type >
229 : 40408 : void BinaryInputStream::readValue( Type& ornValue )
230 : : {
231 : 40408 : readMemory( &ornValue, static_cast< sal_Int32 >( sizeof( Type ) ), sizeof( Type ) );
232 : 40408 : ByteOrderConverter::convertLittleEndian( ornValue );
233 : 40408 : }
234 : :
235 : : template< typename Type >
236 : 238 : sal_Int32 BinaryInputStream::readArray( Type* opnArray, sal_Int32 nElemCount )
237 : : {
238 : 238 : sal_Int32 nRet = 0;
239 [ # # ][ + - ]: 238 : if( !mbEof )
240 : : {
241 : 238 : sal_Int32 nReadSize = getLimitedValue< sal_Int32, sal_Int32 >( nElemCount, 0, SAL_MAX_INT32 / sizeof( Type ) ) * sizeof( Type );
242 : 238 : nRet = readMemory( opnArray, nReadSize, sizeof( Type ) ) / sizeof( Type );
243 : 238 : ByteOrderConverter::convertLittleEndianArray( opnArray, static_cast< size_t >( nRet ) );
244 : : }
245 : 238 : return nRet;
246 : : }
247 : :
248 : : template< typename Type >
249 : : sal_Int32 BinaryInputStream::readArray( ::com::sun::star::uno::Sequence< Type >& orSequence, sal_Int32 nElemCount )
250 : : {
251 : : orSequence.reallocate( nElemCount );
252 : : return orSequence.hasElements() ? readArray( orSequence.getArray(), nElemCount ) : 0;
253 : : }
254 : :
255 : : template< typename Type >
256 : 238 : sal_Int32 BinaryInputStream::readArray( ::std::vector< Type >& orVector, sal_Int32 nElemCount )
257 : : {
258 : 238 : orVector.resize( static_cast< size_t >( nElemCount ) );
259 [ - + ][ # # ]: 238 : return orVector.empty() ? 0 : readArray( &orVector.front(), nElemCount );
260 : : }
261 : :
262 : : template< typename Type >
263 : : void BinaryInputStream::skipArray( sal_Int32 nElemCount )
264 : : {
265 : : sal_Int32 nSkipSize = getLimitedValue< sal_Int32, sal_Int32 >( nElemCount, 0, SAL_MAX_INT32 / sizeof( Type ) ) * sizeof( Type );
266 : : skip( nSkipSize, sizeof( Type ) );
267 : : }
268 : :
269 : : // ============================================================================
270 : :
271 : : /** Wraps a UNO input stream and provides convenient access functions.
272 : :
273 : : The binary data in the stream is assumed to be in little-endian format.
274 : : */
275 : : class OOX_DLLPUBLIC BinaryXInputStream : public BinaryXSeekableStream, public BinaryInputStream
276 : : {
277 : : public:
278 : : /** Constructs the wrapper object for the passed input stream.
279 : :
280 : : @param rxInStream
281 : : The com.sun.star.io.XInputStream interface of the UNO input stream
282 : : to be wrapped.
283 : :
284 : : @param bAutoClose
285 : : True = automatically close the wrapped input stream on destruction
286 : : of this wrapper or when close() is called.
287 : : */
288 : : explicit BinaryXInputStream(
289 : : const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& rxInStrm,
290 : : bool bAutoClose );
291 : :
292 : : virtual ~BinaryXInputStream();
293 : :
294 : : /** Closes the input stream. Does also close the wrapped UNO input stream
295 : : if bAutoClose has been set to true in the constructor. */
296 : : virtual void close();
297 : :
298 : : /** Reads nBytes bytes to the passed sequence.
299 : : @return Number of bytes really read. */
300 : : virtual sal_Int32 readData( StreamDataSequence& orData, sal_Int32 nBytes, size_t nAtomSize = 1 );
301 : :
302 : : /** Reads nBytes bytes to the (existing) buffer opMem.
303 : : @return Number of bytes really read. */
304 : : virtual sal_Int32 readMemory( void* opMem, sal_Int32 nBytes, size_t nAtomSize = 1 );
305 : :
306 : : /** Seeks the stream forward by the passed number of bytes. This works for
307 : : non-seekable streams too. */
308 : : virtual void skip( sal_Int32 nBytes, size_t nAtomSize = 1 );
309 : :
310 : : /** Stream operator for all data types supported by the readValue() function. */
311 : : template< typename Type >
312 : : inline BinaryXInputStream& operator>>( Type& ornValue ) { readValue( ornValue ); return *this; }
313 : :
314 : : private:
315 : : StreamDataSequence maBuffer; /// Data buffer used in readMemory() function.
316 : : ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >
317 : : mxInStrm; /// Reference to the input stream.
318 : : bool mbAutoClose; /// True = automatically close stream on destruction.
319 : : };
320 : :
321 : : // ============================================================================
322 : :
323 : : /** Wraps a StreamDataSequence and provides convenient access functions.
324 : :
325 : : The binary data in the stream is assumed to be in little-endian format.
326 : : */
327 [ + - ][ + - ]: 959 : class OOX_DLLPUBLIC SequenceInputStream : public SequenceSeekableStream, public BinaryInputStream
[ + - ][ - + ]
[ # # ]
328 : : {
329 : : public:
330 : : /** Constructs the wrapper object for the passed data sequence.
331 : :
332 : : @attention
333 : : The passed data sequence MUST live at least as long as this stream
334 : : wrapper. The data sequence MUST NOT be changed from outside as long
335 : : as this stream wrapper is used to read from it.
336 : : */
337 : : explicit SequenceInputStream( const StreamDataSequence& rData );
338 : :
339 : : /** Reads nBytes bytes to the passed sequence.
340 : : @return Number of bytes really read. */
341 : : virtual sal_Int32 readData( StreamDataSequence& orData, sal_Int32 nBytes, size_t nAtomSize = 1 );
342 : :
343 : : /** Reads nBytes bytes to the (existing) buffer opMem.
344 : : @return Number of bytes really read. */
345 : : virtual sal_Int32 readMemory( void* opMem, sal_Int32 nBytes, size_t nAtomSize = 1 );
346 : :
347 : : /** Seeks the stream forward by the passed number of bytes. This works for
348 : : non-seekable streams too. */
349 : : virtual void skip( sal_Int32 nBytes, size_t nAtomSize = 1 );
350 : :
351 : : /** Stream operator for all data types supported by the readValue() function. */
352 : : template< typename Type >
353 : 78 : inline SequenceInputStream& operator>>( Type& ornValue ) { readValue( ornValue ); return *this; }
354 : :
355 : : private:
356 : : /** Returns the number of bytes available in the sequence for the passed byte count. */
357 : 342 : inline sal_Int32 getMaxBytes( sal_Int32 nBytes ) const
358 : 342 : { return getLimitedValue< sal_Int32, sal_Int32 >( nBytes, 0, mpData->getLength() - mnPos ); }
359 : : };
360 : :
361 : : // ============================================================================
362 : :
363 : : /** Wraps a BinaryInputStream and provides access to a specific part of the
364 : : stream data.
365 : :
366 : : Provides access to the stream data block starting at the current position
367 : : of the stream, and with a specific length. If the wrapped stream is
368 : : seekable, this wrapper will treat the position of the wrapped stream at
369 : : construction time as position "0" (therefore the class name).
370 : :
371 : : The passed input stream MUST live at least as long as this stream wrapper.
372 : : The stream MUST NOT be changed from outside as long as this stream wrapper
373 : : is used to read from it.
374 : : */
375 [ # # ][ # # ]: 0 : class RelativeInputStream : public BinaryInputStream
[ # # ][ # # ]
376 : : {
377 : : public:
378 : : /** Constructs the wrapper object for the passed stream.
379 : :
380 : : @param nSize
381 : : If specified, restricts the amount of data that can be read from
382 : : the passed input stream.
383 : : */
384 : : explicit RelativeInputStream(
385 : : BinaryInputStream& rInStrm,
386 : : sal_Int64 nSize = SAL_MAX_INT64 );
387 : :
388 : : /** Returns the size of the data block in the wrapped stream offered by
389 : : this wrapper. */
390 : : virtual sal_Int64 size() const;
391 : :
392 : : /** Returns the current relative stream position. */
393 : : virtual sal_Int64 tell() const;
394 : :
395 : : /** Seeks the stream to the passed relative position, if the wrapped stream
396 : : is seekable. */
397 : : virtual void seek( sal_Int64 nPos );
398 : :
399 : : /** Closes the input stream but not the wrapped stream. */
400 : : virtual void close();
401 : :
402 : : /** Reads nBytes bytes to the passed sequence. Does not read out of the
403 : : data block whose size has been specified on construction.
404 : : @return Number of bytes really read. */
405 : : virtual sal_Int32 readData( StreamDataSequence& orData, sal_Int32 nBytes, size_t nAtomSize = 1 );
406 : :
407 : : /** Reads nBytes bytes to the (existing) buffer opMem. Does not read out of
408 : : the data block whose size has been specified on construction.
409 : : @return Number of bytes really read. */
410 : : virtual sal_Int32 readMemory( void* opMem, sal_Int32 nBytes, size_t nAtomSize = 1 );
411 : :
412 : : /** Seeks the stream forward by the passed number of bytes. This works for
413 : : non-seekable streams too. Does not seek out of the data block. */
414 : : virtual void skip( sal_Int32 nBytes, size_t nAtomSize = 1 );
415 : :
416 : : /** Stream operator for all data types supported by the readValue() function. */
417 : : template< typename Type >
418 : : inline RelativeInputStream& operator>>( Type& ornValue ) { readValue( ornValue ); return *this; }
419 : :
420 : : private:
421 : : /** Returns the number of bytes available in the sequence for the passed byte count. */
422 : 0 : inline sal_Int32 getMaxBytes( sal_Int32 nBytes ) const
423 : 0 : { return getLimitedValue< sal_Int32, sal_Int64 >( nBytes, 0, mnSize - mnRelPos ); }
424 : :
425 : : private:
426 : : BinaryInputStream* mpInStrm;
427 : : sal_Int64 mnStartPos;
428 : : sal_Int64 mnRelPos;
429 : : sal_Int64 mnSize;
430 : : };
431 : :
432 : : // ============================================================================
433 : :
434 : : } // namespace oox
435 : :
436 : : #endif
437 : :
438 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|