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 INCLUDED_OOX_HELPER_BINARYINPUTSTREAM_HXX
21 : #define INCLUDED_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 5533 : 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 : SAL_WARN_UNUSED_RESULT
82 : Type readValue();
83 :
84 : SAL_WARN_UNUSED_RESULT
85 4 : sal_Int8 readInt8() { return readValue<sal_Int8>(); }
86 : SAL_WARN_UNUSED_RESULT
87 11632 : sal_uInt8 readuInt8() { return readValue<sal_uInt8>(); }
88 : SAL_WARN_UNUSED_RESULT
89 23 : sal_Int16 readInt16() { return readValue<sal_Int16>(); }
90 : SAL_WARN_UNUSED_RESULT
91 29327 : sal_uInt16 readuInt16() { return readValue<sal_uInt16>(); }
92 : SAL_WARN_UNUSED_RESULT
93 3275 : sal_Int32 readInt32() { return readValue<sal_Int32>(); }
94 : SAL_WARN_UNUSED_RESULT
95 333 : sal_uInt32 readuInt32() { return readValue<sal_uInt32>(); }
96 : SAL_WARN_UNUSED_RESULT
97 18 : sal_Int64 readInt64() { return readValue<sal_Int64>(); }
98 : SAL_WARN_UNUSED_RESULT
99 : sal_uInt64 readuInt64() { return readValue<sal_uInt64>(); }
100 : SAL_WARN_UNUSED_RESULT
101 0 : float readFloat() { return readValue<float>(); }
102 : SAL_WARN_UNUSED_RESULT
103 54 : double readDouble() { return readValue<double>(); }
104 : SAL_WARN_UNUSED_RESULT
105 61626 : unsigned char readuChar() { return readValue<unsigned char>(); }
106 :
107 : /** Reads a (preallocated!) C array of values from the stream.
108 :
109 : Converts all values in the array to platform byte order. All data types
110 : supported by the ByteOrderConverter class can be used.
111 :
112 : @param nElemCount
113 : Number of array elements to read (NOT byte count).
114 :
115 : @return
116 : Number of array elements really read (NOT byte count).
117 : */
118 : template< typename Type >
119 : sal_Int32 readArray( Type* opnArray, sal_Int32 nElemCount );
120 :
121 : /** Reads a sequence of values from the stream.
122 :
123 : The sequence will be reallocated internally. Converts all values in the
124 : array to platform byte order. All data types supported by the
125 : ByteOrderConverter class can be used.
126 :
127 : @param nElemCount
128 : Number of elements to put into the sequence (NOT byte count).
129 :
130 : @return
131 : Number of sequence elements really read (NOT byte count).
132 : */
133 : template< typename Type >
134 : sal_Int32 readArray( ::com::sun::star::uno::Sequence< Type >& orSequence, sal_Int32 nElemCount );
135 :
136 : /** Reads a vector of values from the stream.
137 :
138 : The vector will be resized internally. Converts all values in the
139 : vector to platform byte order. All data types supported by the
140 : ByteOrderConverter class can be used.
141 :
142 : @param nElemCount
143 : Number of elements to put into the vector (NOT byte count).
144 :
145 : @return
146 : Number of vector elements really read (NOT byte count).
147 : */
148 : template< typename Type >
149 : sal_Int32 readArray( ::std::vector< Type >& orVector, sal_Int32 nElemCount );
150 :
151 : /** Skips an array of values of a certain type in the stream.
152 :
153 : All data types supported by the ByteOrderConverter class can be used.
154 :
155 : @param nElemCount
156 : Number of array elements to skip (NOT byte count).
157 : */
158 : template< typename Type >
159 : void skipArray( sal_Int32 nElemCount );
160 :
161 : /** Reads a NUL-terminated Unicode character array and returns the string.
162 : */
163 : OUString readNulUnicodeArray();
164 :
165 : /** Reads a byte character array and returns the string.
166 :
167 : @param nChars
168 : Number of characters (bytes) to read from the stream.
169 :
170 : @param bAllowNulChars
171 : True = NUL characters are inserted into the imported string.
172 : False = NUL characters are replaced by question marks (default).
173 : */
174 : OString readCharArray( sal_Int32 nChars, bool bAllowNulChars = false );
175 :
176 : /** Reads a byte character array and returns a Unicode string.
177 :
178 : @param nChars
179 : Number of characters (bytes) to read from the stream.
180 :
181 : @param eTextEnc
182 : The text encoding used to create the Unicode string.
183 :
184 : @param bAllowNulChars
185 : True = NUL characters are inserted into the imported string.
186 : False = NUL characters are replaced by question marks (default).
187 : */
188 : OUString readCharArrayUC( sal_Int32 nChars, rtl_TextEncoding eTextEnc, bool bAllowNulChars = false );
189 :
190 : /** Reads a Unicode character array and returns the string.
191 :
192 : @param nChars
193 : Number of 16-bit characters to read from the stream.
194 :
195 : @param bAllowNulChars
196 : True = NUL characters are inserted into the imported string.
197 : False = NUL characters are replaced by question marks (default).
198 : */
199 : OUString readUnicodeArray( sal_Int32 nChars, bool bAllowNulChars = false );
200 :
201 : /** Reads a Unicode character array (may be compressed) and returns the
202 : string.
203 :
204 : @param nChars
205 : Number of 8-bit or 16-bit characters to read from the stream.
206 :
207 : @param bCompressed
208 : True = Character array is compressed (stored as 8-bit characters).
209 : False = Character array is not compressed (stored as 16-bit characters).
210 :
211 : @param bAllowNulChars
212 : True = NUL characters are inserted into the imported string.
213 : False = NUL characters are replaced by question marks (default).
214 : */
215 : OUString readCompressedUnicodeArray( sal_Int32 nChars, bool bCompressed, bool bAllowNulChars = false );
216 :
217 : /** Copies nBytes bytes from the current position to the passed output stream.
218 : */
219 : void copyToStream( BinaryOutputStream& rOutStrm, sal_Int64 nBytes = SAL_MAX_INT64, sal_Int32 nAtomSize = 1 );
220 :
221 : protected:
222 : /** This dummy default c'tor will never call the c'tor of the virtual base
223 : class BinaryStreamBase as this class cannot be instantiated directly. */
224 5533 : BinaryInputStream() : BinaryStreamBase( false ) {}
225 : };
226 :
227 : typedef std::shared_ptr< BinaryInputStream > BinaryInputStreamRef;
228 :
229 :
230 :
231 : template< typename Type >
232 106595 : Type BinaryInputStream::readValue()
233 : {
234 : Type ornValue;
235 106595 : readMemory( &ornValue, static_cast< sal_Int32 >( sizeof( Type ) ), sizeof( Type ) );
236 106595 : ByteOrderConverter::convertLittleEndian( ornValue );
237 106595 : return ornValue;
238 : }
239 :
240 : template< typename Type >
241 460 : sal_Int32 BinaryInputStream::readArray( Type* opnArray, sal_Int32 nElemCount )
242 : {
243 460 : sal_Int32 nRet = 0;
244 460 : if( !mbEof )
245 : {
246 460 : sal_Int32 nReadSize = getLimitedValue< sal_Int32, sal_Int32 >( nElemCount, 0, SAL_MAX_INT32 / sizeof( Type ) ) * sizeof( Type );
247 460 : nRet = readMemory( opnArray, nReadSize, sizeof( Type ) ) / sizeof( Type );
248 460 : ByteOrderConverter::convertLittleEndianArray( opnArray, static_cast< size_t >( nRet ) );
249 : }
250 460 : return nRet;
251 : }
252 :
253 : template< typename Type >
254 : sal_Int32 BinaryInputStream::readArray( ::com::sun::star::uno::Sequence< Type >& orSequence, sal_Int32 nElemCount )
255 : {
256 : orSequence.reallocate( nElemCount );
257 : return orSequence.hasElements() ? readArray( orSequence.getArray(), nElemCount ) : 0;
258 : }
259 :
260 : template< typename Type >
261 460 : sal_Int32 BinaryInputStream::readArray( ::std::vector< Type >& orVector, sal_Int32 nElemCount )
262 : {
263 460 : orVector.resize( static_cast< size_t >( nElemCount ) );
264 460 : return orVector.empty() ? 0 : readArray( &orVector.front(), nElemCount );
265 : }
266 :
267 : template< typename Type >
268 : void BinaryInputStream::skipArray( sal_Int32 nElemCount )
269 : {
270 : sal_Int32 nSkipSize = getLimitedValue< sal_Int32, sal_Int32 >( nElemCount, 0, SAL_MAX_INT32 / sizeof( Type ) ) * sizeof( Type );
271 : skip( nSkipSize, sizeof( Type ) );
272 : }
273 :
274 :
275 :
276 : /** Wraps a UNO input stream and provides convenient access functions.
277 :
278 : The binary data in the stream is assumed to be in little-endian format.
279 : */
280 : class OOX_DLLPUBLIC BinaryXInputStream : public BinaryXSeekableStream, public BinaryInputStream
281 : {
282 : public:
283 : /** Constructs the wrapper object for the passed input stream.
284 :
285 : @param rxInStream
286 : The com.sun.star.io.XInputStream interface of the UNO input stream
287 : to be wrapped.
288 :
289 : @param bAutoClose
290 : True = automatically close the wrapped input stream on destruction
291 : of this wrapper or when close() is called.
292 : */
293 : explicit BinaryXInputStream(
294 : const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& rxInStrm,
295 : bool bAutoClose );
296 :
297 : virtual ~BinaryXInputStream();
298 :
299 : /** Closes the input stream. Does also close the wrapped UNO input stream
300 : if bAutoClose has been set to true in the constructor. */
301 : virtual void close() SAL_OVERRIDE;
302 :
303 : /** Reads nBytes bytes to the passed sequence.
304 : @return Number of bytes really read. */
305 : virtual sal_Int32 readData( StreamDataSequence& orData, sal_Int32 nBytes, size_t nAtomSize = 1 ) SAL_OVERRIDE;
306 :
307 : /** Reads nBytes bytes to the (existing) buffer opMem.
308 : @return Number of bytes really read. */
309 : virtual sal_Int32 readMemory( void* opMem, sal_Int32 nBytes, size_t nAtomSize = 1 ) SAL_OVERRIDE;
310 :
311 : /** Seeks the stream forward by the passed number of bytes. This works for
312 : non-seekable streams too. */
313 : virtual void skip( sal_Int32 nBytes, size_t nAtomSize = 1 ) SAL_OVERRIDE;
314 :
315 : private:
316 : StreamDataSequence maBuffer; ///< Data buffer used in readMemory() function.
317 : ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >
318 : mxInStrm; ///< Reference to the input stream.
319 : bool mbAutoClose; ///< True = automatically close stream on destruction.
320 : };
321 :
322 :
323 :
324 : /** Wraps a StreamDataSequence and provides convenient access functions.
325 :
326 : The binary data in the stream is assumed to be in little-endian format.
327 : */
328 2823 : class OOX_DLLPUBLIC SequenceInputStream : public SequenceSeekableStream, public BinaryInputStream
329 : {
330 : public:
331 : /** Constructs the wrapper object for the passed data sequence.
332 :
333 : @attention
334 : The passed data sequence MUST live at least as long as this stream
335 : wrapper. The data sequence MUST NOT be changed from outside as long
336 : as this stream wrapper is used to read from it.
337 : */
338 : explicit SequenceInputStream( const StreamDataSequence& rData );
339 :
340 : /** Reads nBytes bytes to the passed sequence.
341 : @return Number of bytes really read. */
342 : virtual sal_Int32 readData( StreamDataSequence& orData, sal_Int32 nBytes, size_t nAtomSize = 1 ) SAL_OVERRIDE;
343 :
344 : /** Reads nBytes bytes to the (existing) buffer opMem.
345 : @return Number of bytes really read. */
346 : virtual sal_Int32 readMemory( void* opMem, sal_Int32 nBytes, size_t nAtomSize = 1 ) SAL_OVERRIDE;
347 :
348 : /** Seeks the stream forward by the passed number of bytes. This works for
349 : non-seekable streams too. */
350 : virtual void skip( sal_Int32 nBytes, size_t nAtomSize = 1 ) SAL_OVERRIDE;
351 :
352 : private:
353 : /** Returns the number of bytes available in the sequence for the passed byte count. */
354 1655 : sal_Int32 getMaxBytes( sal_Int32 nBytes ) const
355 1655 : { return getLimitedValue< sal_Int32, sal_Int32 >( nBytes, 0, mpData->getLength() - mnPos ); }
356 : };
357 :
358 :
359 :
360 : /** Wraps a BinaryInputStream and provides access to a specific part of the
361 : stream data.
362 :
363 : Provides access to the stream data block starting at the current position
364 : of the stream, and with a specific length. If the wrapped stream is
365 : seekable, this wrapper will treat the position of the wrapped stream at
366 : construction time as position "0" (therefore the class name).
367 :
368 : The passed input stream MUST live at least as long as this stream wrapper.
369 : The stream MUST NOT be changed from outside as long as this stream wrapper
370 : is used to read from it.
371 : */
372 0 : class RelativeInputStream : public BinaryInputStream
373 : {
374 : public:
375 : /** Constructs the wrapper object for the passed stream.
376 :
377 : @param nSize
378 : If specified, restricts the amount of data that can be read from
379 : the passed input stream.
380 : */
381 : explicit RelativeInputStream(
382 : BinaryInputStream& rInStrm,
383 : sal_Int64 nSize = SAL_MAX_INT64 );
384 :
385 : /** Returns the size of the data block in the wrapped stream offered by
386 : this wrapper. */
387 : virtual sal_Int64 size() const SAL_OVERRIDE;
388 :
389 : /** Returns the current relative stream position. */
390 : virtual sal_Int64 tell() const SAL_OVERRIDE;
391 :
392 : /** Seeks the stream to the passed relative position, if the wrapped stream
393 : is seekable. */
394 : virtual void seek( sal_Int64 nPos ) SAL_OVERRIDE;
395 :
396 : /** Closes the input stream but not the wrapped stream. */
397 : virtual void close() SAL_OVERRIDE;
398 :
399 : /** Reads nBytes bytes to the passed sequence. Does not read out of the
400 : data block whose size has been specified on construction.
401 : @return Number of bytes really read. */
402 : virtual sal_Int32 readData( StreamDataSequence& orData, sal_Int32 nBytes, size_t nAtomSize = 1 ) SAL_OVERRIDE;
403 :
404 : /** Reads nBytes bytes to the (existing) buffer opMem. Does not read out of
405 : the data block whose size has been specified on construction.
406 : @return Number of bytes really read. */
407 : virtual sal_Int32 readMemory( void* opMem, sal_Int32 nBytes, size_t nAtomSize = 1 ) SAL_OVERRIDE;
408 :
409 : /** Seeks the stream forward by the passed number of bytes. This works for
410 : non-seekable streams too. Does not seek out of the data block. */
411 : virtual void skip( sal_Int32 nBytes, size_t nAtomSize = 1 ) SAL_OVERRIDE;
412 :
413 : private:
414 : /** Returns the number of bytes available in the sequence for the passed byte count. */
415 0 : sal_Int32 getMaxBytes( sal_Int32 nBytes ) const
416 0 : { return getLimitedValue< sal_Int32, sal_Int64 >( nBytes, 0, mnSize - mnRelPos ); }
417 :
418 : private:
419 : BinaryInputStream* mpInStrm;
420 : sal_Int64 mnStartPos;
421 : sal_Int64 mnRelPos;
422 : sal_Int64 mnSize;
423 : };
424 :
425 :
426 :
427 : } // namespace oox
428 :
429 : #endif
430 :
431 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|