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 433 : 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 2834 : 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 5786 : inline BinaryInputStream& operator>>( Type& ornValue ) { readValue( ornValue ); return *this; }
92 :
93 0 : inline sal_Int8 readInt8() { return readValue< sal_Int8 >(); }
94 974 : inline sal_uInt8 readuInt8() { return readValue< sal_uInt8 >(); }
95 0 : inline sal_Int16 readInt16() { return readValue< sal_Int16 >(); }
96 1806 : inline sal_uInt16 readuInt16() { return readValue< sal_uInt16 >(); }
97 0 : inline sal_Int32 readInt32() { return readValue< sal_Int32 >(); }
98 15 : 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 433 : inline explicit BinaryInputStream() : BinaryStreamBase( false ) {}
222 : };
223 :
224 : typedef ::boost::shared_ptr< BinaryInputStream > BinaryInputStreamRef;
225 :
226 : // ----------------------------------------------------------------------------
227 :
228 : template< typename Type >
229 8648 : void BinaryInputStream::readValue( Type& ornValue )
230 : {
231 8648 : readMemory( &ornValue, static_cast< sal_Int32 >( sizeof( Type ) ), sizeof( Type ) );
232 8648 : ByteOrderConverter::convertLittleEndian( ornValue );
233 8648 : }
234 :
235 : template< typename Type >
236 38 : sal_Int32 BinaryInputStream::readArray( Type* opnArray, sal_Int32 nElemCount )
237 : {
238 38 : sal_Int32 nRet = 0;
239 38 : if( !mbEof )
240 : {
241 38 : sal_Int32 nReadSize = getLimitedValue< sal_Int32, sal_Int32 >( nElemCount, 0, SAL_MAX_INT32 / sizeof( Type ) ) * sizeof( Type );
242 38 : nRet = readMemory( opnArray, nReadSize, sizeof( Type ) ) / sizeof( Type );
243 38 : ByteOrderConverter::convertLittleEndianArray( opnArray, static_cast< size_t >( nRet ) );
244 : }
245 38 : 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 38 : sal_Int32 BinaryInputStream::readArray( ::std::vector< Type >& orVector, sal_Int32 nElemCount )
257 : {
258 38 : orVector.resize( static_cast< size_t >( nElemCount ) );
259 38 : 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 219 : 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 18 : 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 54 : inline sal_Int32 getMaxBytes( sal_Int32 nBytes ) const
358 54 : { 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: */
|