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