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