fdo#74697 Add Bluez 5 support for impress remote.
[LibreOffice.git] / oox / source / dump / dumperbase.cxx
blob6f1c744fc1bbf894593367064faca21c8364ebcd
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include "oox/dump/dumperbase.hxx"
22 #include <algorithm>
23 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
24 #include <com/sun/star/io/XActiveDataSource.hpp>
25 #include <com/sun/star/io/TextOutputStream.hpp>
26 #include <com/sun/star/ucb/SimpleFileAccess.hpp>
27 #include <comphelper/docpasswordhelper.hxx>
28 #include <osl/file.hxx>
29 #include <rtl/math.hxx>
30 #include <rtl/tencinfo.h>
31 #include "oox/core/filterbase.hxx"
32 #include "oox/helper/binaryoutputstream.hxx"
33 #include "oox/helper/textinputstream.hxx"
34 #include <tools/time.hxx>
36 #if OOX_INCLUDE_DUMPER
38 namespace oox {
39 namespace dump {
41 // ============================================================================
43 using namespace ::com::sun::star;
44 using namespace ::com::sun::star::beans;
45 using namespace ::com::sun::star::io;
46 using namespace ::com::sun::star::lang;
47 using namespace ::com::sun::star::ucb;
48 using namespace ::com::sun::star::uno;
50 using ::comphelper::MediaDescriptor;
51 using ::oox::core::FilterBase;
53 namespace {
55 const sal_Unicode OOX_DUMP_BOM = 0xFEFF;
56 const sal_Int32 OOX_DUMP_MAXSTRLEN = 80;
57 const sal_Int32 OOX_DUMP_INDENT = 2;
58 const sal_Unicode OOX_DUMP_BINDOT = '.';
59 const sal_Unicode OOX_DUMP_CFG_LISTSEP = ',';
60 const sal_Unicode OOX_DUMP_CFG_QUOTE = '\'';
61 const sal_Unicode OOX_DUMP_LF = '\n';
62 const sal_Unicode OOX_DUMP_ITEMSEP = '=';
63 const sal_Int32 OOX_DUMP_BYTESPERLINE = 16;
64 const sal_Int64 OOX_DUMP_MAXARRAY = 16;
66 } // namespace
68 // ============================================================================
69 // ============================================================================
71 // file names -----------------------------------------------------------------
73 OUString InputOutputHelper::convertFileNameToUrl( const OUString& rFileName )
75 OUString aFileUrl;
76 if( ::osl::FileBase::getFileURLFromSystemPath( rFileName, aFileUrl ) == ::osl::FileBase::E_None )
77 return aFileUrl;
78 return OUString();
81 sal_Int32 InputOutputHelper::getFileNamePos( const OUString& rFileUrl )
83 sal_Int32 nSepPos = rFileUrl.lastIndexOf( '/' );
84 return (nSepPos < 0) ? 0 : (nSepPos + 1);
87 OUString InputOutputHelper::getFileNameExtension( const OUString& rFileUrl )
89 sal_Int32 nNamePos = getFileNamePos( rFileUrl );
90 sal_Int32 nExtPos = rFileUrl.lastIndexOf( '.' );
91 if( nExtPos >= nNamePos )
92 return rFileUrl.copy( nExtPos + 1 );
93 return OUString();
96 // input streams --------------------------------------------------------------
98 Reference< XInputStream > InputOutputHelper::openInputStream(
99 const Reference< XComponentContext >& rxContext, const OUString& rFileName )
101 Reference< XInputStream > xInStrm;
102 if( rxContext.is() ) try
104 Reference<XSimpleFileAccess3> xFileAccess(SimpleFileAccess::create(rxContext));
105 xInStrm = xFileAccess->openFileRead( rFileName );
107 catch( Exception& )
110 return xInStrm;
113 // output streams -------------------------------------------------------------
115 Reference< XOutputStream > InputOutputHelper::openOutputStream(
116 const Reference< XComponentContext >& rxContext, const OUString& rFileName )
118 Reference< XOutputStream > xOutStrm;
119 if( rxContext.is() ) try
121 Reference<XSimpleFileAccess3> xFileAccess(SimpleFileAccess::create(rxContext));
122 xOutStrm = xFileAccess->openFileWrite( rFileName );
124 catch( Exception& )
127 return xOutStrm;
130 Reference< XTextOutputStream2 > InputOutputHelper::openTextOutputStream(
131 const Reference< XComponentContext >& rxContext, const Reference< XOutputStream >& rxOutStrm, rtl_TextEncoding eTextEnc )
133 Reference< XTextOutputStream2 > xTextOutStrm;
134 const char* pcCharset = rtl_getMimeCharsetFromTextEncoding( eTextEnc );
135 if( rxContext.is() && rxOutStrm.is() && pcCharset ) try
137 xTextOutStrm = TextOutputStream::create(rxContext);
138 xTextOutStrm->setOutputStream( rxOutStrm );
139 xTextOutStrm->setEncoding( OUString::createFromAscii( pcCharset ) );
141 catch( Exception& )
144 return xTextOutStrm;
147 Reference< XTextOutputStream2 > InputOutputHelper::openTextOutputStream(
148 const Reference< XComponentContext >& rxContext, const OUString& rFileName, rtl_TextEncoding eTextEnc )
150 return openTextOutputStream( rxContext, openOutputStream( rxContext, rFileName ), eTextEnc );
153 // ============================================================================
154 // ============================================================================
156 ItemFormat::ItemFormat() :
157 meDataType( DATATYPE_VOID ),
158 meFmtType( FORMATTYPE_NONE )
162 void ItemFormat::set( DataType eDataType, FormatType eFmtType, const OUString& rItemName )
164 meDataType = eDataType;
165 meFmtType = eFmtType;
166 maItemName = rItemName;
167 maListName = OUString();
170 OUStringVector::const_iterator ItemFormat::parse( const OUStringVector& rFormatVec )
172 set( DATATYPE_VOID, FORMATTYPE_NONE, OUString() );
174 OUStringVector::const_iterator aIt = rFormatVec.begin(), aEnd = rFormatVec.end();
175 OUString aDataType, aFmtType;
176 if( aIt != aEnd ) aDataType = *aIt++;
177 if( aIt != aEnd ) aFmtType = *aIt++;
178 if( aIt != aEnd ) maItemName = *aIt++;
179 if( aIt != aEnd ) maListName = *aIt++;
181 meDataType = StringHelper::convertToDataType( aDataType );
182 meFmtType = StringHelper::convertToFormatType( aFmtType );
184 if( meFmtType == FORMATTYPE_NONE )
186 if ( aFmtType == "unused" )
187 set( meDataType, FORMATTYPE_HEX, OOX_DUMP_UNUSED );
188 else if ( aFmtType == "unknown" )
189 set( meDataType, FORMATTYPE_HEX, OOX_DUMP_UNKNOWN );
192 return aIt;
195 OUStringVector ItemFormat::parse( const OUString& rFormatStr )
197 OUStringVector aFormatVec;
198 StringHelper::convertStringToStringList( aFormatVec, rFormatStr, false );
199 OUStringVector::const_iterator aIt = parse( aFormatVec );
200 return OUStringVector( aIt, const_cast< const OUStringVector& >( aFormatVec ).end() );
203 // ============================================================================
204 // ============================================================================
206 // append string to string ----------------------------------------------------
208 void StringHelper::appendChar( OUStringBuffer& rStr, sal_Unicode cChar, sal_Int32 nCount )
210 for( sal_Int32 nIndex = 0; nIndex < nCount; ++nIndex )
211 rStr.append( cChar );
214 void StringHelper::appendString( OUStringBuffer& rStr, const OUString& rData, sal_Int32 nWidth, sal_Unicode cFill )
216 appendChar( rStr, cFill, nWidth - rData.getLength() );
217 rStr.append( rData );
220 // append decimal -------------------------------------------------------------
222 void StringHelper::appendDec( OUStringBuffer& rStr, sal_uInt8 nData, sal_Int32 nWidth, sal_Unicode cFill )
224 appendString( rStr, OUString::number( nData ), nWidth, cFill );
227 void StringHelper::appendDec( OUStringBuffer& rStr, sal_Int8 nData, sal_Int32 nWidth, sal_Unicode cFill )
229 appendString( rStr, OUString::number( nData ), nWidth, cFill );
232 void StringHelper::appendDec( OUStringBuffer& rStr, sal_uInt16 nData, sal_Int32 nWidth, sal_Unicode cFill )
234 appendString( rStr, OUString::number( nData ), nWidth, cFill );
237 void StringHelper::appendDec( OUStringBuffer& rStr, sal_Int16 nData, sal_Int32 nWidth, sal_Unicode cFill )
239 appendString( rStr, OUString::number( nData ), nWidth, cFill );
242 void StringHelper::appendDec( OUStringBuffer& rStr, sal_uInt32 nData, sal_Int32 nWidth, sal_Unicode cFill )
244 appendString( rStr, OUString::number( nData ), nWidth, cFill );
247 void StringHelper::appendDec( OUStringBuffer& rStr, sal_Int32 nData, sal_Int32 nWidth, sal_Unicode cFill )
249 appendString( rStr, OUString::valueOf( nData ), nWidth, cFill );
252 void StringHelper::appendDec( OUStringBuffer& rStr, sal_uInt64 nData, sal_Int32 nWidth, sal_Unicode cFill )
254 /* Values greater than biggest signed 64bit integer will change to
255 negative when converting to sal_Int64. Therefore, the trailing digit
256 will be written separately. */
257 OUStringBuffer aBuffer;
258 if( nData > 9 )
259 aBuffer.append( OUString::valueOf( static_cast< sal_Int64 >( nData / 10 ) ) );
260 aBuffer.append( static_cast< sal_Unicode >( '0' + (nData % 10) ) );
261 appendString( rStr, aBuffer.makeStringAndClear(), nWidth, cFill );
264 void StringHelper::appendDec( OUStringBuffer& rStr, sal_Int64 nData, sal_Int32 nWidth, sal_Unicode cFill )
266 appendString( rStr, OUString::valueOf( nData ), nWidth, cFill );
269 void StringHelper::appendDec( OUStringBuffer& rStr, double fData, sal_Int32 nWidth, sal_Unicode cFill )
271 appendString( rStr, ::rtl::math::doubleToUString( fData, rtl_math_StringFormat_G, 15, '.', true ), nWidth, cFill );
274 // append hexadecimal ---------------------------------------------------------
276 void StringHelper::appendHex( OUStringBuffer& rStr, sal_uInt8 nData, bool bPrefix )
278 static const sal_Unicode spcHexDigits[] = { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' };
279 if( bPrefix )
280 rStr.appendAscii( "0x" );
281 rStr.append( spcHexDigits[ (nData >> 4) & 0x0F ] ).append( spcHexDigits[ nData & 0x0F ] );
284 void StringHelper::appendHex( OUStringBuffer& rStr, sal_Int8 nData, bool bPrefix )
286 appendHex( rStr, static_cast< sal_uInt8 >( nData ), bPrefix );
289 void StringHelper::appendHex( OUStringBuffer& rStr, sal_uInt16 nData, bool bPrefix )
291 appendHex( rStr, static_cast< sal_uInt8 >( nData >> 8 ), bPrefix );
292 appendHex( rStr, static_cast< sal_uInt8 >( nData ), false );
295 void StringHelper::appendHex( OUStringBuffer& rStr, sal_Int16 nData, bool bPrefix )
297 appendHex( rStr, static_cast< sal_uInt16 >( nData ), bPrefix );
300 void StringHelper::appendHex( OUStringBuffer& rStr, sal_uInt32 nData, bool bPrefix )
302 appendHex( rStr, static_cast< sal_uInt16 >( nData >> 16 ), bPrefix );
303 appendHex( rStr, static_cast< sal_uInt16 >( nData ), false );
306 void StringHelper::appendHex( OUStringBuffer& rStr, sal_Int32 nData, bool bPrefix )
308 appendHex( rStr, static_cast< sal_uInt32 >( nData ), bPrefix );
311 void StringHelper::appendHex( OUStringBuffer& rStr, sal_uInt64 nData, bool bPrefix )
313 appendHex( rStr, static_cast< sal_uInt32 >( nData >> 32 ), bPrefix );
314 appendHex( rStr, static_cast< sal_uInt32 >( nData ), false );
317 void StringHelper::appendHex( OUStringBuffer& rStr, sal_Int64 nData, bool bPrefix )
319 appendHex( rStr, static_cast< sal_uInt64 >( nData ), bPrefix );
322 static sal_uInt64
323 lcl_ConvertDouble(double const f)
325 sal_uInt64 i = sal_uInt64();
326 for (size_t j = 0; j < sizeof(double); ++j)
327 { // hopefully both endian independent and strict aliasing safe
328 reinterpret_cast<char *>(&i)[j] = reinterpret_cast<char const *>(&f)[j];
330 return i;
333 void StringHelper::appendHex( OUStringBuffer& rStr, double fData, bool bPrefix )
335 appendHex( rStr, lcl_ConvertDouble(fData), bPrefix );
338 // append shortened hexadecimal -----------------------------------------------
340 void StringHelper::appendShortHex( OUStringBuffer& rStr, sal_uInt8 nData, bool bPrefix )
342 appendHex( rStr, nData, bPrefix );
345 void StringHelper::appendShortHex( OUStringBuffer& rStr, sal_Int8 nData, bool bPrefix )
347 appendHex( rStr, nData, bPrefix );
350 void StringHelper::appendShortHex( OUStringBuffer& rStr, sal_uInt16 nData, bool bPrefix )
352 if( nData > SAL_MAX_UINT8 )
353 appendHex( rStr, nData, bPrefix );
354 else
355 appendHex( rStr, static_cast< sal_uInt8 >( nData ), bPrefix );
358 void StringHelper::appendShortHex( OUStringBuffer& rStr, sal_Int16 nData, bool bPrefix )
360 appendShortHex( rStr, static_cast< sal_uInt16 >( nData ), bPrefix );
363 void StringHelper::appendShortHex( OUStringBuffer& rStr, sal_uInt32 nData, bool bPrefix )
365 if( nData > SAL_MAX_UINT16 )
366 appendHex( rStr, nData, bPrefix );
367 else
368 appendShortHex( rStr, static_cast< sal_uInt16 >( nData ), bPrefix );
371 void StringHelper::appendShortHex( OUStringBuffer& rStr, sal_Int32 nData, bool bPrefix )
373 appendShortHex( rStr, static_cast< sal_uInt32 >( nData ), bPrefix );
376 void StringHelper::appendShortHex( OUStringBuffer& rStr, sal_uInt64 nData, bool bPrefix )
378 if( nData > SAL_MAX_UINT32 )
379 appendHex( rStr, nData, bPrefix );
380 else
381 appendShortHex( rStr, static_cast< sal_uInt32 >( nData ), bPrefix );
384 void StringHelper::appendShortHex( OUStringBuffer& rStr, sal_Int64 nData, bool bPrefix )
386 appendShortHex( rStr, static_cast< sal_uInt64 >( nData ), bPrefix );
389 void StringHelper::appendShortHex( OUStringBuffer& rStr, double fData, bool bPrefix )
391 appendHex( rStr, fData, bPrefix );
394 // append binary --------------------------------------------------------------
396 void StringHelper::appendBin( OUStringBuffer& rStr, sal_uInt8 nData, bool bDots )
398 for( sal_uInt8 nMask = 0x80; nMask != 0; (nMask >>= 1) &= 0x7F )
400 rStr.append( static_cast< sal_Unicode >( (nData & nMask) ? '1' : '0' ) );
401 if( bDots && (nMask == 0x10) )
402 rStr.append( OOX_DUMP_BINDOT );
406 void StringHelper::appendBin( OUStringBuffer& rStr, sal_Int8 nData, bool bDots )
408 appendBin( rStr, static_cast< sal_uInt8 >( nData ), bDots );
411 void StringHelper::appendBin( OUStringBuffer& rStr, sal_uInt16 nData, bool bDots )
413 appendBin( rStr, static_cast< sal_uInt8 >( nData >> 8 ), bDots );
414 if( bDots )
415 rStr.append( OOX_DUMP_BINDOT );
416 appendBin( rStr, static_cast< sal_uInt8 >( nData ), bDots );
419 void StringHelper::appendBin( OUStringBuffer& rStr, sal_Int16 nData, bool bDots )
421 appendBin( rStr, static_cast< sal_uInt16 >( nData ), bDots );
424 void StringHelper::appendBin( OUStringBuffer& rStr, sal_uInt32 nData, bool bDots )
426 appendBin( rStr, static_cast< sal_uInt16 >( nData >> 16 ), bDots );
427 if( bDots )
428 rStr.append( OOX_DUMP_BINDOT );
429 appendBin( rStr, static_cast< sal_uInt16 >( nData ), bDots );
432 void StringHelper::appendBin( OUStringBuffer& rStr, sal_Int32 nData, bool bDots )
434 appendBin( rStr, static_cast< sal_uInt32 >( nData ), bDots );
437 void StringHelper::appendBin( OUStringBuffer& rStr, sal_uInt64 nData, bool bDots )
439 appendBin( rStr, static_cast< sal_uInt32 >( nData >> 32 ), bDots );
440 if( bDots )
441 rStr.append( OOX_DUMP_BINDOT );
442 appendBin( rStr, static_cast< sal_uInt32 >( nData ), bDots );
445 void StringHelper::appendBin( OUStringBuffer& rStr, sal_Int64 nData, bool bDots )
447 appendBin( rStr, static_cast< sal_uInt64 >( nData ), bDots );
450 void StringHelper::appendBin( OUStringBuffer& rStr, double fData, bool bDots )
452 appendBin( rStr, lcl_ConvertDouble(fData), bDots );
455 // append formatted value -----------------------------------------------------
457 void StringHelper::appendBool( OUStringBuffer& rStr, bool bData )
459 rStr.appendAscii( bData ? "true" : "false" );
462 // encoded text output --------------------------------------------------------
464 void StringHelper::appendCChar( OUStringBuffer& rStr, sal_Unicode cChar, bool bPrefix )
466 if( cChar > 0x00FF )
468 if( bPrefix )
469 rStr.appendAscii( "\\u" );
470 appendHex( rStr, static_cast< sal_uInt16 >( cChar ), false );
472 else
474 if( bPrefix )
475 rStr.appendAscii( "\\x" );
476 appendHex( rStr, static_cast< sal_uInt8 >( cChar ), false );
480 void StringHelper::appendEncChar( OUStringBuffer& rStr, sal_Unicode cChar, sal_Int32 nCount, bool bPrefix )
482 if( cChar < 0x0020 )
484 // C-style hex code
485 OUStringBuffer aCode;
486 appendCChar( aCode, cChar, bPrefix );
487 OUString aCodeStr = aCode.makeStringAndClear();
488 for( sal_Int32 nIdx = 0; nIdx < nCount; ++nIdx )
489 rStr.append( aCodeStr );
491 else
493 appendChar( rStr, cChar, nCount );
497 void StringHelper::appendEncString( OUStringBuffer& rStr, const OUString& rData, bool bPrefix )
499 sal_Int32 nBeg = 0;
500 sal_Int32 nIdx = 0;
501 sal_Int32 nEnd = rData.getLength();
502 while( nIdx < nEnd )
504 // find next character that needs encoding
505 while( (nIdx < nEnd) && (rData[ nIdx ] >= 0x20) ) ++nIdx;
506 // append portion
507 if( nBeg < nIdx )
509 if( (nBeg == 0) && (nIdx == nEnd) )
510 rStr.append( rData );
511 else
512 rStr.append( rData.copy( nBeg, nIdx - nBeg ) );
514 // append characters to be encoded
515 while( (nIdx < nEnd) && (rData[ nIdx ] < 0x20) )
517 appendCChar( rStr, rData[ nIdx ], bPrefix );
518 ++nIdx;
520 // adjust limits
521 nBeg = nIdx;
525 // token list -----------------------------------------------------------------
527 void StringHelper::appendToken( OUStringBuffer& rStr, const OUString& rToken, sal_Unicode cSep )
529 if( (rStr.getLength() > 0) && (!rToken.isEmpty()) )
530 rStr.append( cSep );
531 rStr.append( rToken );
534 void StringHelper::appendIndex( OUStringBuffer& rStr, const OUString& rIdx )
536 rStr.append( sal_Unicode( '[' ) ).append( rIdx ).append( sal_Unicode( ']' ) );
539 void StringHelper::appendIndex( OUStringBuffer& rStr, sal_Int64 nIdx )
541 OUStringBuffer aToken;
542 appendDec( aToken, nIdx );
543 appendIndex( rStr, aToken.makeStringAndClear() );
546 OUString StringHelper::getToken( const OUString& rData, sal_Int32& rnPos, sal_Unicode cSep )
548 return trimSpaces( rData.getToken( 0, cSep, rnPos ) );
551 void StringHelper::enclose( OUStringBuffer& rStr, sal_Unicode cOpen, sal_Unicode cClose )
553 rStr.insert( 0, cOpen ).append( cClose ? cClose : cOpen );
556 // string conversion ----------------------------------------------------------
558 namespace {
560 sal_Int32 lclIndexOf( const OUString& rStr, sal_Unicode cChar, sal_Int32 nStartPos )
562 sal_Int32 nIndex = rStr.indexOf( cChar, nStartPos );
563 return (nIndex < 0) ? rStr.getLength() : nIndex;
566 OUString lclTrimQuotedStringList( const OUString& rStr )
568 OUStringBuffer aBuffer;
569 sal_Int32 nPos = 0;
570 sal_Int32 nLen = rStr.getLength();
571 while( nPos < nLen )
573 if( rStr[ nPos ] == OOX_DUMP_CFG_QUOTE )
575 // quoted string, skip leading quote character
576 ++nPos;
577 // process quoted text and ambedded literal quote characters
578 OUStringBuffer aToken;
581 // seek to next quote character and add text portion to token buffer
582 sal_Int32 nEnd = lclIndexOf( rStr, OOX_DUMP_CFG_QUOTE, nPos );
583 aToken.append( rStr.copy( nPos, nEnd - nPos ) );
584 // process literal quotes
585 while( (nEnd + 1 < nLen) && (rStr[ nEnd ] == OOX_DUMP_CFG_QUOTE) && (rStr[ nEnd + 1 ] == OOX_DUMP_CFG_QUOTE) )
587 aToken.append( OOX_DUMP_CFG_QUOTE );
588 nEnd += 2;
590 // nEnd is start of possible next text portion
591 nPos = nEnd;
593 while( (nPos < nLen) && (rStr[ nPos ] != OOX_DUMP_CFG_QUOTE) );
594 // add token, seek to list separator, ignore text following closing quote
595 aBuffer.append( aToken.makeStringAndClear() );
596 nPos = lclIndexOf( rStr, OOX_DUMP_CFG_LISTSEP, nPos );
597 if( nPos < nLen )
598 aBuffer.append( OOX_DUMP_LF );
599 // set current position behind list separator
600 ++nPos;
602 else
604 // find list separator, add token text to buffer
605 sal_Int32 nEnd = lclIndexOf( rStr, OOX_DUMP_CFG_LISTSEP, nPos );
606 aBuffer.append( rStr.copy( nPos, nEnd - nPos ) );
607 if( nEnd < nLen )
608 aBuffer.append( OOX_DUMP_LF );
609 // set current position behind list separator
610 nPos = nEnd + 1;
614 return aBuffer.makeStringAndClear();
617 } // namespace
619 OUString StringHelper::trimSpaces( const OUString& rStr )
621 sal_Int32 nBeg = 0;
622 while( (nBeg < rStr.getLength()) && ((rStr[ nBeg ] == ' ') || (rStr[ nBeg ] == '\t')) )
623 ++nBeg;
624 sal_Int32 nEnd = rStr.getLength();
625 while( (nEnd > nBeg) && ((rStr[ nEnd - 1 ] == ' ') || (rStr[ nEnd - 1 ] == '\t')) )
626 --nEnd;
627 return rStr.copy( nBeg, nEnd - nBeg );
630 OUString StringHelper::trimTrailingNul( const OUString& rStr )
632 sal_Int32 nLastPos = rStr.getLength() - 1;
633 if( (nLastPos >= 0) && (rStr[ nLastPos ] == 0) )
634 return rStr.copy( 0, nLastPos );
635 return rStr;
638 OString StringHelper::convertToUtf8( const OUString& rStr )
640 return OUStringToOString( rStr, RTL_TEXTENCODING_UTF8 );
643 DataType StringHelper::convertToDataType( const OUString& rStr )
645 DataType eType = DATATYPE_VOID;
646 if ( rStr == "int8" )
647 eType = DATATYPE_INT8;
648 else if ( rStr == "uint8" )
649 eType = DATATYPE_UINT8;
650 else if ( rStr == "int16" )
651 eType = DATATYPE_INT16;
652 else if ( rStr == "uint16" )
653 eType = DATATYPE_UINT16;
654 else if ( rStr == "int32" )
655 eType = DATATYPE_INT32;
656 else if ( rStr == "uint32" )
657 eType = DATATYPE_UINT32;
658 else if ( rStr == "int64" )
659 eType = DATATYPE_INT64;
660 else if ( rStr == "uint64" )
661 eType = DATATYPE_UINT64;
662 else if ( rStr == "float" )
663 eType = DATATYPE_FLOAT;
664 else if ( rStr == "double" )
665 eType = DATATYPE_DOUBLE;
666 return eType;
669 FormatType StringHelper::convertToFormatType( const OUString& rStr )
671 FormatType eType = FORMATTYPE_NONE;
672 if ( rStr == "dec" )
673 eType = FORMATTYPE_DEC;
674 else if ( rStr == "hex" )
675 eType = FORMATTYPE_HEX;
676 else if ( rStr == "shorthex" )
677 eType = FORMATTYPE_SHORTHEX;
678 else if ( rStr == "bin" )
679 eType = FORMATTYPE_BIN;
680 else if ( rStr == "fix" )
681 eType = FORMATTYPE_FIX;
682 else if ( rStr == "bool" )
683 eType = FORMATTYPE_BOOL;
684 return eType;
687 bool StringHelper::convertFromDec( sal_Int64& ornData, const OUString& rData )
689 sal_Int32 nPos = 0;
690 sal_Int32 nLen = rData.getLength();
691 bool bNeg = false;
692 if( (nLen > 0) && (rData[ 0 ] == '-') )
694 bNeg = true;
695 ++nPos;
697 ornData = 0;
698 for( ; nPos < nLen; ++nPos )
700 sal_Unicode cChar = rData[ nPos ];
701 if( (cChar < '0') || (cChar > '9') )
702 return false;
703 (ornData *= 10) += (cChar - '0');
705 if( bNeg )
706 ornData *= -1;
707 return true;
710 bool StringHelper::convertFromHex( sal_Int64& ornData, const OUString& rData )
712 ornData = 0;
713 for( sal_Int32 nPos = 0, nLen = rData.getLength(); nPos < nLen; ++nPos )
715 sal_Unicode cChar = rData[ nPos ];
716 if( ('0' <= cChar) && (cChar <= '9') )
717 cChar -= '0';
718 else if( ('A' <= cChar) && (cChar <= 'F') )
719 cChar -= ('A' - 10);
720 else if( ('a' <= cChar) && (cChar <= 'f') )
721 cChar -= ('a' - 10);
722 else
723 return false;
724 (ornData <<= 4) += cChar;
726 return true;
729 bool StringHelper::convertStringToInt( sal_Int64& ornData, const OUString& rData )
731 if( (rData.getLength() > 2) && (rData[ 0 ] == '0') && ((rData[ 1 ] == 'X') || (rData[ 1 ] == 'x')) )
732 return convertFromHex( ornData, rData.copy( 2 ) );
733 return convertFromDec( ornData, rData );
736 bool StringHelper::convertStringToDouble( double& orfData, const OUString& rData )
738 rtl_math_ConversionStatus eStatus = rtl_math_ConversionStatus_Ok;
739 sal_Int32 nSize = 0;
740 orfData = rtl::math::stringToDouble( rData, '.', '\0', &eStatus, &nSize );
741 return (eStatus == rtl_math_ConversionStatus_Ok) && (nSize == rData.getLength());
744 bool StringHelper::convertStringToBool( const OUString& rData )
746 if ( rData == "true" )
747 return true;
748 if ( rData == "false" )
749 return false;
750 sal_Int64 nData;
751 return convertStringToInt( nData, rData ) && (nData != 0);
754 OUStringPair StringHelper::convertStringToPair( const OUString& rString, sal_Unicode cSep )
756 OUStringPair aPair;
757 if( !rString.isEmpty() )
759 sal_Int32 nEqPos = rString.indexOf( cSep );
760 if( nEqPos < 0 )
762 aPair.first = rString;
764 else
766 aPair.first = StringHelper::trimSpaces( rString.copy( 0, nEqPos ) );
767 aPair.second = StringHelper::trimSpaces( rString.copy( nEqPos + 1 ) );
770 return aPair;
773 void StringHelper::convertStringToStringList( OUStringVector& orVec, const OUString& rData, bool bIgnoreEmpty )
775 orVec.clear();
776 OUString aUnquotedData = lclTrimQuotedStringList( rData );
777 sal_Int32 nPos = 0;
778 sal_Int32 nLen = aUnquotedData.getLength();
779 while( (0 <= nPos) && (nPos < nLen) )
781 OUString aToken = getToken( aUnquotedData, nPos, OOX_DUMP_LF );
782 if( !bIgnoreEmpty || !aToken.isEmpty() )
783 orVec.push_back( aToken );
787 void StringHelper::convertStringToIntList( Int64Vector& orVec, const OUString& rData, bool bIgnoreEmpty )
789 orVec.clear();
790 OUString aUnquotedData = lclTrimQuotedStringList( rData );
791 sal_Int32 nPos = 0;
792 sal_Int32 nLen = aUnquotedData.getLength();
793 sal_Int64 nData;
794 while( (0 <= nPos) && (nPos < nLen) )
796 bool bOk = convertStringToInt( nData, getToken( aUnquotedData, nPos, OOX_DUMP_LF ) );
797 if( !bIgnoreEmpty || bOk )
798 orVec.push_back( bOk ? nData : 0 );
802 // ============================================================================
803 // ============================================================================
805 Base::~Base()
809 // ============================================================================
810 // ============================================================================
812 ConfigItemBase::~ConfigItemBase()
816 void ConfigItemBase::readConfigBlock( TextInputStream& rStrm )
818 readConfigBlockContents( rStrm );
821 void ConfigItemBase::implProcessConfigItemStr(
822 TextInputStream& /*rStrm*/, const OUString& /*rKey*/, const OUString& /*rData*/ )
826 void ConfigItemBase::implProcessConfigItemInt(
827 TextInputStream& /*rStrm*/, sal_Int64 /*nKey*/, const OUString& /*rData*/ )
831 void ConfigItemBase::readConfigBlockContents( TextInputStream& rStrm )
833 bool bLoop = true;
834 while( bLoop && !rStrm.isEof() )
836 OUString aKey, aData;
837 switch( readConfigLine( rStrm, aKey, aData ) )
839 case LINETYPE_DATA:
840 processConfigItem( rStrm, aKey, aData );
841 break;
842 case LINETYPE_END:
843 bLoop = false;
844 break;
849 ConfigItemBase::LineType ConfigItemBase::readConfigLine(
850 TextInputStream& rStrm, OUString& orKey, OUString& orData ) const
852 OUString aLine;
853 while( !rStrm.isEof() && aLine.isEmpty() )
855 aLine = rStrm.readLine();
856 if( !aLine.isEmpty() && (aLine[ 0 ] == OOX_DUMP_BOM) )
857 aLine = aLine.copy( 1 );
858 aLine = StringHelper::trimSpaces( aLine );
859 if( !aLine.isEmpty() )
861 // ignore comments (starting with hash or semicolon)
862 sal_Unicode cChar = aLine[ 0 ];
863 if( (cChar == '#') || (cChar == ';') )
864 aLine = OUString();
868 OUStringPair aPair = StringHelper::convertStringToPair( aLine );
869 orKey = aPair.first;
870 orData = aPair.second;
871 return ( !orKey.isEmpty() && (!orData.isEmpty() || orKey != "end" )) ?
872 LINETYPE_DATA : LINETYPE_END;
875 void ConfigItemBase::processConfigItem(
876 TextInputStream& rStrm, const OUString& rKey, const OUString& rData )
878 sal_Int64 nKey;
879 if( StringHelper::convertStringToInt( nKey, rKey ) )
880 implProcessConfigItemInt( rStrm, nKey, rData );
881 else
882 implProcessConfigItemStr( rStrm, rKey, rData );
885 // ============================================================================
887 NameListBase::~NameListBase()
891 void NameListBase::setName( sal_Int64 nKey, const String& rName )
893 implSetName( nKey, rName );
896 void NameListBase::includeList( const NameListRef& rxList )
898 if( rxList.get() )
900 for( const_iterator aIt = rxList->begin(), aEnd = rxList->end(); aIt != aEnd; ++aIt )
901 maMap[ aIt->first ] = aIt->second;
902 implIncludeList( *rxList );
906 bool NameListBase::implIsValid() const
908 return true;
911 void NameListBase::implProcessConfigItemStr(
912 TextInputStream& rStrm, const OUString& rKey, const OUString& rData )
914 if ( rKey == "include" )
915 include( rData );
916 else if ( rKey == "exclude" )
917 exclude( rData );
918 else
919 ConfigItemBase::implProcessConfigItemStr( rStrm, rKey, rData );
922 void NameListBase::implProcessConfigItemInt(
923 TextInputStream& /*rStrm*/, sal_Int64 nKey, const OUString& rData )
925 implSetName( nKey, rData );
928 void NameListBase::insertRawName( sal_Int64 nKey, const OUString& rName )
930 maMap[ nKey ] = rName;
933 const OUString* NameListBase::findRawName( sal_Int64 nKey ) const
935 const_iterator aIt = maMap.find( nKey );
936 return (aIt == end()) ? 0 : &aIt->second;
939 void NameListBase::include( const OUString& rListKeys )
941 OUStringVector aVec;
942 StringHelper::convertStringToStringList( aVec, rListKeys, true );
943 for( OUStringVector::const_iterator aIt = aVec.begin(), aEnd = aVec.end(); aIt != aEnd; ++aIt )
944 includeList( mrCfgData.getNameList( *aIt ) );
947 void NameListBase::exclude( const OUString& rKeys )
949 Int64Vector aVec;
950 StringHelper::convertStringToIntList( aVec, rKeys, true );
951 for( Int64Vector::const_iterator aIt = aVec.begin(), aEnd = aVec.end(); aIt != aEnd; ++aIt )
952 maMap.erase( *aIt );
955 // ============================================================================
957 void ItemFormatMap::insertFormats( const NameListRef& rxNameList )
959 if( Base::isValid( rxNameList ) )
960 for( NameListBase::const_iterator aIt = rxNameList->begin(), aEnd = rxNameList->end(); aIt != aEnd; ++aIt )
961 (*this)[ aIt->first ].parse( aIt->second );
964 // ============================================================================
966 ConstList::ConstList( const SharedConfigData& rCfgData ) :
967 NameListBase( rCfgData ),
968 maDefName( OOX_DUMP_ERR_NONAME ),
969 mbQuoteNames( false )
973 void ConstList::implProcessConfigItemStr(
974 TextInputStream& rStrm, const OUString& rKey, const OUString& rData )
976 if ( rKey == "default" )
977 setDefaultName( rData );
978 else if ( rKey == "quote-names" )
979 setQuoteNames( StringHelper::convertStringToBool( rData ) );
980 else
981 NameListBase::implProcessConfigItemStr( rStrm, rKey, rData );
984 void ConstList::implSetName( sal_Int64 nKey, const OUString& rName )
986 insertRawName( nKey, rName );
989 OUString ConstList::implGetName( const Config& /*rCfg*/, sal_Int64 nKey ) const
991 const OUString* pName = findRawName( nKey );
992 OUString aName = pName ? *pName : maDefName;
993 if( mbQuoteNames )
995 OUStringBuffer aBuffer( aName );
996 StringHelper::enclose( aBuffer, OOX_DUMP_STRQUOTE );
997 aName = aBuffer.makeStringAndClear();
999 return aName;
1002 OUString ConstList::implGetNameDbl( const Config& /*rCfg*/, double /*fValue*/ ) const
1004 return OUString();
1007 void ConstList::implIncludeList( const NameListBase& rList )
1009 if( const ConstList* pConstList = dynamic_cast< const ConstList* >( &rList ) )
1011 maDefName = pConstList->maDefName;
1012 mbQuoteNames = pConstList->mbQuoteNames;
1016 // ============================================================================
1018 MultiList::MultiList( const SharedConfigData& rCfgData ) :
1019 ConstList( rCfgData ),
1020 mbIgnoreEmpty( true )
1024 void MultiList::setNamesFromVec( sal_Int64 nStartKey, const OUStringVector& rNames )
1026 sal_Int64 nKey = nStartKey;
1027 for( OUStringVector::const_iterator aIt = rNames.begin(), aEnd = rNames.end(); aIt != aEnd; ++aIt, ++nKey )
1028 if( !mbIgnoreEmpty || !aIt->isEmpty() )
1029 insertRawName( nKey, *aIt );
1032 void MultiList::implProcessConfigItemStr(
1033 TextInputStream& rStrm, const OUString& rKey, const OUString& rData )
1035 if ( rKey == "ignore-empty" )
1036 mbIgnoreEmpty = StringHelper::convertStringToBool( rData );
1037 else
1038 ConstList::implProcessConfigItemStr( rStrm, rKey, rData );
1041 void MultiList::implSetName( sal_Int64 nKey, const OUString& rName )
1043 OUStringVector aNames;
1044 StringHelper::convertStringToStringList( aNames, rName, false );
1045 setNamesFromVec( nKey, aNames );
1048 // ============================================================================
1050 FlagsList::FlagsList( const SharedConfigData& rCfgData ) :
1051 NameListBase( rCfgData ),
1052 mnIgnore( 0 )
1056 void FlagsList::implProcessConfigItemStr(
1057 TextInputStream& rStrm, const OUString& rKey, const OUString& rData )
1059 if ( rKey == "ignore" )
1061 sal_Int64 nIgnore;
1062 if( StringHelper::convertStringToInt( nIgnore, rData ) )
1063 setIgnoreFlags( nIgnore );
1065 else
1067 NameListBase::implProcessConfigItemStr( rStrm, rKey, rData );
1071 void FlagsList::implSetName( sal_Int64 nKey, const OUString& rName )
1073 if( (nKey != 0) && ((nKey & (nKey - 1)) == 0) ) // only a single bit set?
1074 insertRawName( nKey, rName );
1077 OUString FlagsList::implGetName( const Config& /*rCfg*/, sal_Int64 nKey ) const
1079 sal_Int64 nFound = mnIgnore;
1080 OUStringBuffer aName;
1081 // add known flags
1082 for( const_iterator aIt = begin(), aEnd = end(); aIt != aEnd; ++aIt )
1084 sal_Int64 nMask = aIt->first;
1085 setFlag( nFound, nMask );
1086 if( !getFlag( mnIgnore, nMask ) )
1088 const OUString& rFlagName = aIt->second;
1089 bool bOnOff = !rFlagName.isEmpty() && rFlagName[ 0 ] == ':';
1090 bool bFlag = getFlag( nKey, nMask );
1091 if( bOnOff )
1093 StringHelper::appendToken( aName, rFlagName.copy( 1 ) );
1094 aName.appendAscii( bFlag ? ":on" : ":off" );
1096 else
1098 bool bNegated = !rFlagName.isEmpty() && rFlagName[ 0 ] == '!';
1099 sal_Int32 nBothSep = bNegated ? rFlagName.indexOf( '!', 1 ) : -1;
1100 if( bFlag )
1102 if( !bNegated )
1103 StringHelper::appendToken( aName, rFlagName );
1104 else if( nBothSep > 0 )
1105 StringHelper::appendToken( aName, rFlagName.copy( nBothSep + 1 ) );
1107 else if( bNegated )
1109 if( nBothSep > 0 )
1110 StringHelper::appendToken( aName, rFlagName.copy( 1, nBothSep - 1 ) );
1111 else
1112 StringHelper::appendToken( aName, rFlagName.copy( 1 ) );
1117 // add unknown flags
1118 setFlag( nKey, nFound, false );
1119 if( nKey != 0 )
1121 OUStringBuffer aUnknown( OOX_DUMP_UNKNOWN );
1122 aUnknown.append( OOX_DUMP_ITEMSEP );
1123 StringHelper::appendShortHex( aUnknown, nKey, true );
1124 StringHelper::enclose( aUnknown, '(', ')' );
1125 StringHelper::appendToken( aName, aUnknown.makeStringAndClear() );
1127 return aName.makeStringAndClear();
1130 OUString FlagsList::implGetNameDbl( const Config& /*rCfg*/, double /*fValue*/ ) const
1132 return OUString();
1135 void FlagsList::implIncludeList( const NameListBase& rList )
1137 if( const FlagsList* pFlagsList = dynamic_cast< const FlagsList* >( &rList ) )
1138 mnIgnore = pFlagsList->mnIgnore;
1141 // ============================================================================
1143 bool CombiList::ExtItemFormatKey::operator<( const ExtItemFormatKey& rRight ) const
1145 return (mnKey < rRight.mnKey) || ((mnKey == rRight.mnKey) && (maFilter < rRight.maFilter));
1148 CombiList::CombiList( const SharedConfigData& rCfgData ) :
1149 FlagsList( rCfgData )
1153 void CombiList::implSetName( sal_Int64 nKey, const OUString& rName )
1155 if( (nKey & (nKey - 1)) != 0 ) // more than a single bit set?
1157 typedef ::std::set< ExtItemFormatKey > ExtItemFormatKeySet;
1158 ::std::set< ExtItemFormatKey > aItemKeys;
1159 ExtItemFormat aItemFmt;
1160 OUStringVector aRemain = aItemFmt.parse( rName );
1161 for( OUStringVector::iterator aIt = aRemain.begin(), aEnd = aRemain.end(); aIt != aEnd; ++aIt )
1163 OUStringPair aPair = StringHelper::convertStringToPair( *aIt );
1164 if ( aPair.first == "noshift" )
1166 aItemFmt.mbShiftValue = StringHelper::convertStringToBool( aPair.second );
1168 else if ( aPair.first == "filter" )
1170 OUStringPair aFilter = StringHelper::convertStringToPair( aPair.second, '~' );
1171 ExtItemFormatKey aKey( nKey );
1172 if( !aFilter.first.isEmpty() && StringHelper::convertStringToInt( aKey.maFilter.first, aFilter.first ) &&
1173 !aFilter.second.isEmpty() && StringHelper::convertStringToInt( aKey.maFilter.second, aFilter.second ) )
1175 if( aKey.maFilter.first == 0 )
1176 aKey.maFilter.second = 0;
1177 aItemKeys.insert( aKey );
1181 if( aItemKeys.empty() )
1182 aItemKeys.insert( ExtItemFormatKey( nKey ) );
1183 for( ExtItemFormatKeySet::iterator aIt = aItemKeys.begin(), aEnd = aItemKeys.end(); aIt != aEnd; ++aIt )
1184 maFmtMap[ *aIt ] = aItemFmt;
1186 else
1188 FlagsList::implSetName( nKey, rName );
1192 OUString CombiList::implGetName( const Config& rCfg, sal_Int64 nKey ) const
1194 sal_Int64 nFound = 0;
1195 OUStringBuffer aName;
1196 // add known flag fields
1197 for( ExtItemFormatMap::const_iterator aIt = maFmtMap.begin(), aEnd = maFmtMap.end(); aIt != aEnd; ++aIt )
1199 const ExtItemFormatKey& rMapKey = aIt->first;
1200 sal_Int64 nMask = rMapKey.mnKey;
1201 if( (nMask != 0) && ((nKey & rMapKey.maFilter.first) == rMapKey.maFilter.second) )
1203 const ExtItemFormat& rItemFmt = aIt->second;
1205 sal_uInt64 nUFlags = static_cast< sal_uInt64 >( nKey );
1206 sal_uInt64 nUMask = static_cast< sal_uInt64 >( nMask );
1207 if( rItemFmt.mbShiftValue )
1208 while( (nUMask & 1) == 0 ) { nUFlags >>= 1; nUMask >>= 1; }
1210 sal_uInt64 nUValue = nUFlags & nUMask;
1211 sal_Int64 nSValue = static_cast< sal_Int64 >( nUValue );
1212 if( getFlag< sal_uInt64 >( nUValue, (nUMask + 1) >> 1 ) )
1213 setFlag( nSValue, static_cast< sal_Int64 >( ~nUMask ) );
1215 OUStringBuffer aItem( rItemFmt.maItemName );
1216 OUStringBuffer aValue;
1217 switch( rItemFmt.meDataType )
1219 case DATATYPE_INT8: StringHelper::appendValue( aValue, static_cast< sal_Int8 >( nSValue ), rItemFmt.meFmtType ); break;
1220 case DATATYPE_UINT8: StringHelper::appendValue( aValue, static_cast< sal_uInt8 >( nUValue ), rItemFmt.meFmtType ); break;
1221 case DATATYPE_INT16: StringHelper::appendValue( aValue, static_cast< sal_Int16 >( nSValue ), rItemFmt.meFmtType ); break;
1222 case DATATYPE_UINT16: StringHelper::appendValue( aValue, static_cast< sal_uInt16 >( nUValue ), rItemFmt.meFmtType ); break;
1223 case DATATYPE_INT32: StringHelper::appendValue( aValue, static_cast< sal_Int32 >( nSValue ), rItemFmt.meFmtType ); break;
1224 case DATATYPE_UINT32: StringHelper::appendValue( aValue, static_cast< sal_uInt32 >( nUValue ), rItemFmt.meFmtType ); break;
1225 case DATATYPE_INT64: StringHelper::appendValue( aValue, nSValue, rItemFmt.meFmtType ); break;
1226 case DATATYPE_UINT64: StringHelper::appendValue( aValue, nUValue, rItemFmt.meFmtType ); break;
1227 case DATATYPE_FLOAT: StringHelper::appendValue( aValue, static_cast< float >( nSValue ), rItemFmt.meFmtType ); break;
1228 case DATATYPE_DOUBLE: StringHelper::appendValue( aValue, static_cast< double >( nSValue ), rItemFmt.meFmtType ); break;
1229 default:;
1231 StringHelper::appendToken( aItem, aValue.makeStringAndClear(), OOX_DUMP_ITEMSEP );
1232 if( !rItemFmt.maListName.isEmpty() )
1234 OUString aValueName = rCfg.getName( rItemFmt.maListName, static_cast< sal_Int64 >( nUValue ) );
1235 StringHelper::appendToken( aItem, aValueName, OOX_DUMP_ITEMSEP );
1237 StringHelper::enclose( aItem, '(', ')' );
1238 StringHelper::appendToken( aName, aItem.makeStringAndClear() );
1239 setFlag( nFound, nMask );
1242 setFlag( nKey, nFound, false );
1243 StringHelper::appendToken( aName, FlagsList::implGetName( rCfg, nKey ) );
1244 return aName.makeStringAndClear();
1247 void CombiList::implIncludeList( const NameListBase& rList )
1249 if( const CombiList* pCombiList = dynamic_cast< const CombiList* >( &rList ) )
1250 maFmtMap = pCombiList->maFmtMap;
1251 FlagsList::implIncludeList( rList );
1254 // ============================================================================
1256 UnitConverter::UnitConverter( const SharedConfigData& rCfgData ) :
1257 NameListBase( rCfgData ),
1258 mfFactor( 1.0 )
1262 void UnitConverter::implSetName( sal_Int64 /*nKey*/, const OUString& /*rName*/ )
1264 // nothing to do
1267 OUString UnitConverter::implGetName( const Config& rCfg, sal_Int64 nKey ) const
1269 return implGetNameDbl( rCfg, static_cast< double >( nKey ) );
1272 OUString UnitConverter::implGetNameDbl( const Config& /*rCfg*/, double fValue ) const
1274 OUStringBuffer aValue;
1275 StringHelper::appendDec( aValue, mfFactor * fValue );
1276 aValue.append( maUnitName );
1277 return aValue.makeStringAndClear();
1280 void UnitConverter::implIncludeList( const NameListBase& /*rList*/ )
1284 // ============================================================================
1286 NameListRef NameListWrapper::getNameList( const Config& rCfg ) const
1288 return mxList.get() ? mxList : (mxList = rCfg.getNameList( maName ));
1291 // ============================================================================
1292 // ============================================================================
1294 SharedConfigData::SharedConfigData( const OUString& rFileName,
1295 const Reference< XComponentContext >& rxContext, const StorageRef& rxRootStrg,
1296 const OUString& rSysFileName ) :
1297 mxContext( rxContext ),
1298 mxRootStrg( rxRootStrg ),
1299 maSysFileName( rSysFileName ),
1300 mbLoaded( false ),
1301 mbPwCancelled( false )
1303 OUString aFileUrl = InputOutputHelper::convertFileNameToUrl( rFileName );
1304 if( !aFileUrl.isEmpty() )
1306 sal_Int32 nNamePos = InputOutputHelper::getFileNamePos( aFileUrl );
1307 maConfigPath = aFileUrl.copy( 0, nNamePos );
1308 mbLoaded = readConfigFile( aFileUrl );
1312 SharedConfigData::~SharedConfigData()
1316 void SharedConfigData::setOption( const OUString& rKey, const OUString& rData )
1318 maConfigData[ rKey ] = rData;
1321 const OUString* SharedConfigData::getOption( const OUString& rKey ) const
1323 ConfigDataMap::const_iterator aIt = maConfigData.find( rKey );
1324 return (aIt == maConfigData.end()) ? 0 : &aIt->second;
1327 void SharedConfigData::setNameList( const OUString& rListName, const NameListRef& rxList )
1329 if( !rListName.isEmpty() )
1330 maNameLists[ rListName ] = rxList;
1333 void SharedConfigData::eraseNameList( const OUString& rListName )
1335 maNameLists.erase( rListName );
1338 NameListRef SharedConfigData::getNameList( const OUString& rListName ) const
1340 NameListRef xList;
1341 NameListMap::const_iterator aIt = maNameLists.find( rListName );
1342 if( aIt != maNameLists.end() )
1343 xList = aIt->second;
1344 return xList;
1347 bool SharedConfigData::implIsValid() const
1349 return mbLoaded && mxContext.is() && mxRootStrg.get() && !maSysFileName.isEmpty();
1352 void SharedConfigData::implProcessConfigItemStr(
1353 TextInputStream& rStrm, const OUString& rKey, const OUString& rData )
1355 if ( rKey == "include-config-file" )
1356 readConfigFile( maConfigPath + rData );
1357 else if ( rKey == "constlist" )
1358 readNameList< ConstList >( rStrm, rData );
1359 else if ( rKey == "multilist" )
1360 readNameList< MultiList >( rStrm, rData );
1361 else if ( rKey == "flagslist" )
1362 readNameList< FlagsList >( rStrm, rData );
1363 else if ( rKey == "combilist" )
1364 readNameList< CombiList >( rStrm, rData );
1365 else if ( rKey == "shortlist" )
1366 createShortList( rData );
1367 else if ( rKey == "unitconverter" )
1368 createUnitConverter( rData );
1369 else
1370 setOption( rKey, rData );
1373 bool SharedConfigData::readConfigFile( const OUString& rFileUrl )
1375 bool bLoaded = maConfigFiles.count( rFileUrl ) > 0;
1376 if( !bLoaded )
1378 Reference< XInputStream > xInStrm = InputOutputHelper::openInputStream( mxContext, rFileUrl );
1379 TextInputStream aTxtStrm( mxContext, xInStrm, RTL_TEXTENCODING_UTF8 );
1380 if( !aTxtStrm.isEof() )
1382 maConfigFiles.insert( rFileUrl );
1383 readConfigBlockContents( aTxtStrm );
1384 bLoaded = true;
1387 return bLoaded;
1390 void SharedConfigData::createShortList( const OUString& rData )
1392 OUStringVector aDataVec;
1393 StringHelper::convertStringToStringList( aDataVec, rData, false );
1394 if( aDataVec.size() >= 3 )
1396 sal_Int64 nStartKey;
1397 if( StringHelper::convertStringToInt( nStartKey, aDataVec[ 1 ] ) )
1399 ::boost::shared_ptr< MultiList > xList = createNameList< MultiList >( aDataVec[ 0 ] );
1400 if( xList.get() )
1402 aDataVec.erase( aDataVec.begin(), aDataVec.begin() + 2 );
1403 xList->setNamesFromVec( nStartKey, aDataVec );
1409 void SharedConfigData::createUnitConverter( const OUString& rData )
1411 OUStringVector aDataVec;
1412 StringHelper::convertStringToStringList( aDataVec, rData, false );
1413 if( aDataVec.size() >= 2 )
1415 OUString aFactor = aDataVec[ 1 ];
1416 bool bRecip = !aFactor.isEmpty() && aFactor[ 0 ] == '/';
1417 if( bRecip )
1418 aFactor = aFactor.copy( 1 );
1419 double fFactor;
1420 if( StringHelper::convertStringToDouble( fFactor, aFactor ) && (fFactor != 0.0) )
1422 ::boost::shared_ptr< UnitConverter > xList = createNameList< UnitConverter >( aDataVec[ 0 ] );
1423 if( xList.get() )
1425 xList->setFactor( bRecip ? (1.0 / fFactor) : fFactor );
1426 if( aDataVec.size() >= 3 )
1427 xList->setUnitName( aDataVec[ 2 ] );
1433 // ============================================================================
1435 Config::Config( const Config& rParent ) :
1436 Base() // c'tor needs to be called explicitly to avoid compiler warning
1438 construct( rParent );
1441 Config::Config( const sal_Char* pcEnvVar, const FilterBase& rFilter )
1443 construct( pcEnvVar, rFilter );
1446 Config::Config( const sal_Char* pcEnvVar, const Reference< XComponentContext >& rxContext, const StorageRef& rxRootStrg, const OUString& rSysFileName )
1448 construct( pcEnvVar, rxContext, rxRootStrg, rSysFileName );
1451 Config::~Config()
1455 void Config::construct( const Config& rParent )
1457 *this = rParent;
1460 void Config::construct( const sal_Char* pcEnvVar, const FilterBase& rFilter )
1462 if( !rFilter.getFileUrl().isEmpty() )
1463 construct( pcEnvVar, rFilter.getComponentContext(), rFilter.getStorage(), rFilter.getFileUrl() );
1466 void Config::construct( const sal_Char* pcEnvVar, const Reference< XComponentContext >& rxContext, const StorageRef& rxRootStrg, const OUString& rSysFileName )
1468 if( pcEnvVar && rxRootStrg.get() && !rSysFileName.isEmpty() )
1469 if( const sal_Char* pcFileName = ::getenv( pcEnvVar ) )
1470 mxCfgData.reset( new SharedConfigData( OUString::createFromAscii( pcFileName ), rxContext, rxRootStrg, rSysFileName ) );
1473 const OUString& Config::getStringOption( const String& rKey, const OUString& rDefault ) const
1475 const OUString* pData = implGetOption( rKey );
1476 return pData ? *pData : rDefault;
1479 bool Config::getBoolOption( const String& rKey, bool bDefault ) const
1481 const OUString* pData = implGetOption( rKey );
1482 return pData ? StringHelper::convertStringToBool( *pData ) : bDefault;
1485 bool Config::isDumperEnabled() const
1487 return getBoolOption( "enable-dumper", false );
1490 bool Config::isImportEnabled() const
1492 return getBoolOption( "enable-import", true );
1495 void Config::eraseNameList( const String& rListName )
1497 mxCfgData->eraseNameList( rListName );
1500 NameListRef Config::getNameList( const String& rListName ) const
1502 return implGetNameList( rListName );
1505 bool Config::isPasswordCancelled() const
1507 return mxCfgData->isPasswordCancelled();
1510 bool Config::implIsValid() const
1512 return isValid( mxCfgData );
1515 const OUString* Config::implGetOption( const OUString& rKey ) const
1517 return mxCfgData->getOption( rKey );
1520 NameListRef Config::implGetNameList( const OUString& rListName ) const
1522 return mxCfgData->getNameList( rListName );
1525 // ============================================================================
1526 // ============================================================================
1528 Output::Output( const Reference< XComponentContext >& rxContext, const OUString& rFileName ) :
1529 mxStrm( InputOutputHelper::openTextOutputStream( rxContext, rFileName, RTL_TEXTENCODING_UTF8 ) ),
1530 mnCol( 0 ),
1531 mnItemLevel( 0 ),
1532 mnMultiLevel( 0 ),
1533 mnItemIdx( 0 ),
1534 mnLastItem( 0 )
1536 if( mxStrm.is() )
1537 mxStrm->writeString( OUString( OOX_DUMP_BOM ) );
1540 // ----------------------------------------------------------------------------
1542 void Output::newLine()
1544 if( maLine.getLength() > 0 )
1546 mxStrm->writeString( maIndent );
1547 maLine.append( sal_Unicode( '\n' ) );
1548 mxStrm->writeString( maLine.makeStringAndClear() );
1549 mnCol = 0;
1550 mnLastItem = 0;
1554 void Output::emptyLine( size_t nCount )
1556 for( size_t nIdx = 0; nIdx < nCount; ++nIdx )
1557 mxStrm->writeString( OUString( sal_Unicode( '\n' ) ) );
1560 void Output::incIndent()
1562 OUStringBuffer aBuffer( maIndent );
1563 StringHelper::appendChar( aBuffer, ' ', OOX_DUMP_INDENT );
1564 maIndent = aBuffer.makeStringAndClear();
1567 void Output::decIndent()
1569 if( maIndent.getLength() >= OOX_DUMP_INDENT )
1570 maIndent = maIndent.copy( OOX_DUMP_INDENT );
1573 void Output::startTable( sal_Int32 nW1 )
1575 startTable( 1, &nW1 );
1578 void Output::startTable( sal_Int32 nW1, sal_Int32 nW2 )
1580 sal_Int32 pnColWidths[ 2 ];
1581 pnColWidths[ 0 ] = nW1;
1582 pnColWidths[ 1 ] = nW2;
1583 startTable( 2, pnColWidths );
1586 void Output::startTable( sal_Int32 nW1, sal_Int32 nW2, sal_Int32 nW3, sal_Int32 nW4 )
1588 sal_Int32 pnColWidths[ 4 ];
1589 pnColWidths[ 0 ] = nW1;
1590 pnColWidths[ 1 ] = nW2;
1591 pnColWidths[ 2 ] = nW3;
1592 pnColWidths[ 3 ] = nW4;
1593 startTable( 4, pnColWidths );
1596 void Output::startTable( size_t nColCount, const sal_Int32* pnColWidths )
1598 maColPos.clear();
1599 maColPos.push_back( 0 );
1600 sal_Int32 nColPos = 0;
1601 for( size_t nCol = 0; nCol < nColCount; ++nCol )
1603 nColPos = nColPos + pnColWidths[ nCol ];
1604 maColPos.push_back( nColPos );
1608 void Output::tab()
1610 tab( mnCol + 1 );
1613 void Output::tab( size_t nCol )
1615 mnCol = nCol;
1616 if( mnCol < maColPos.size() )
1618 sal_Int32 nColPos = maColPos[ mnCol ];
1619 if( maLine.getLength() >= nColPos )
1620 maLine.setLength( ::std::max< sal_Int32 >( nColPos - 1, 0 ) );
1621 StringHelper::appendChar( maLine, ' ', nColPos - maLine.getLength() );
1623 else
1625 StringHelper::appendChar( maLine, ' ', 2 );
1629 void Output::endTable()
1631 maColPos.clear();
1634 void Output::resetItemIndex( sal_Int64 nIdx )
1636 mnItemIdx = nIdx;
1639 void Output::startItem( const String& rItemName )
1641 if( mnItemLevel == 0 )
1643 if( (mnMultiLevel > 0) && (maLine.getLength() > 0) )
1644 tab();
1645 if( rItemName.has() )
1647 writeItemName( rItemName );
1648 writeChar( OOX_DUMP_ITEMSEP );
1651 ++mnItemLevel;
1652 mnLastItem = maLine.getLength();
1655 void Output::contItem()
1657 if( mnItemLevel > 0 )
1659 if( (maLine.getLength() == 0) || (maLine[ maLine.getLength() - 1 ] != OOX_DUMP_ITEMSEP) )
1660 writeChar( OOX_DUMP_ITEMSEP );
1661 mnLastItem = maLine.getLength();
1665 void Output::endItem()
1667 if( mnItemLevel > 0 )
1669 maLastItem = OUString( maLine.getStr() + mnLastItem );
1670 if( maLastItem.isEmpty() && mnLastItem > 0 && maLine[ mnLastItem - 1 ] == OOX_DUMP_ITEMSEP )
1671 maLine.setLength( mnLastItem - 1 );
1672 --mnItemLevel;
1674 if( mnItemLevel == 0 )
1676 if( mnMultiLevel == 0 )
1677 newLine();
1679 else
1680 contItem();
1683 void Output::startMultiItems()
1685 ++mnMultiLevel;
1688 void Output::endMultiItems()
1690 if( mnMultiLevel > 0 )
1691 --mnMultiLevel;
1692 if( mnMultiLevel == 0 )
1693 newLine();
1696 // ----------------------------------------------------------------------------
1698 void Output::writeChar( sal_Unicode cChar, sal_Int32 nCount )
1700 StringHelper::appendEncChar( maLine, cChar, nCount );
1703 void Output::writeAscii( const sal_Char* pcStr )
1705 if( pcStr )
1706 maLine.appendAscii( pcStr );
1709 void Output::writeString( const OUString& rStr )
1711 StringHelper::appendEncString( maLine, rStr );
1714 void Output::writeArray( const sal_uInt8* pnData, sal_Size nSize, sal_Unicode cSep )
1716 const sal_uInt8* pnEnd = pnData ? (pnData + nSize) : 0;
1717 for( const sal_uInt8* pnByte = pnData; pnByte < pnEnd; ++pnByte )
1719 if( pnByte > pnData )
1720 writeChar( cSep );
1721 writeHex( *pnByte, false );
1725 void Output::writeBool( bool bData )
1727 StringHelper::appendBool( maLine, bData );
1730 void Output::writeDateTime( const util::DateTime& rDateTime )
1732 writeDec( rDateTime.Year, 4, '0' );
1733 writeChar( '-' );
1734 writeDec( rDateTime.Month, 2, '0' );
1735 writeChar( '-' );
1736 writeDec( rDateTime.Day, 2, '0' );
1737 writeChar( 'T' );
1738 writeDec( rDateTime.Hours, 2, '0' );
1739 writeChar( ':' );
1740 writeDec( rDateTime.Minutes, 2, '0' );
1741 writeChar( ':' );
1742 writeDec( rDateTime.Seconds, 2, '0' );
1745 // ----------------------------------------------------------------------------
1747 bool Output::implIsValid() const
1749 return mxStrm.is();
1752 void Output::writeItemName( const String& rItemName )
1754 if( rItemName.has() && (rItemName[ 0 ] == '#') )
1756 writeString( rItemName.copy( 1 ) );
1757 StringHelper::appendIndex( maLine, mnItemIdx++ );
1759 else
1760 writeString( rItemName );
1763 // ============================================================================
1765 StorageIterator::StorageIterator( const StorageRef& rxStrg ) :
1766 mxStrg( rxStrg )
1768 if( mxStrg.get() )
1769 mxStrg->getElementNames( maNames );
1770 maIt = maNames.begin();
1773 StorageIterator::~StorageIterator()
1777 StorageIterator& StorageIterator::operator++()
1779 if( maIt != maNames.end() )
1780 ++maIt;
1781 return *this;
1784 OUString StorageIterator::getName() const
1786 OUString aName;
1787 if( maIt != maNames.end() )
1788 aName = *maIt;
1789 return aName;
1792 bool StorageIterator::isStream() const
1794 return isValid() && mxStrg->openInputStream( *maIt ).is();
1797 bool StorageIterator::isStorage() const
1799 if( !isValid() )
1800 return false;
1801 StorageRef xStrg = mxStrg->openSubStorage( *maIt, false );
1802 return xStrg.get() && xStrg->isStorage();
1805 bool StorageIterator::implIsValid() const
1807 return mxStrg.get() && mxStrg->isStorage() && (maIt != maNames.end());
1810 // ============================================================================
1811 // ============================================================================
1813 ObjectBase::~ObjectBase()
1817 void ObjectBase::construct( const ConfigRef& rxConfig )
1819 mxConfig = rxConfig;
1822 void ObjectBase::construct( const ObjectBase& rParent )
1824 *this = rParent;
1827 void ObjectBase::dump()
1829 if( isValid() )
1830 implDump();
1833 bool ObjectBase::implIsValid() const
1835 return isValid( mxConfig );
1838 void ObjectBase::implDump()
1842 // ============================================================================
1843 // ============================================================================
1845 void StorageObjectBase::construct( const ObjectBase& rParent, const StorageRef& rxStrg, const OUString& rSysPath )
1847 ObjectBase::construct( rParent );
1848 mxStrg = rxStrg;
1849 maSysPath = rSysPath;
1852 void StorageObjectBase::construct( const ObjectBase& rParent )
1854 ObjectBase::construct( rParent );
1855 if( ObjectBase::implIsValid() )
1857 mxStrg = cfg().getRootStorage();
1858 maSysPath = cfg().getSysFileName();
1862 bool StorageObjectBase::implIsValid() const
1864 return mxStrg.get() && !maSysPath.isEmpty() && ObjectBase::implIsValid();
1867 void StorageObjectBase::implDump()
1869 bool bIsStrg = mxStrg->isStorage();
1870 bool bIsRoot = mxStrg->isRootStorage();
1871 Reference< XInputStream > xBaseStrm;
1872 if( !bIsStrg )
1873 xBaseStrm = mxStrg->openInputStream( OUString() );
1875 OUString aSysOutPath = maSysPath;
1876 if( bIsRoot ) try
1878 aSysOutPath += OOX_DUMP_DUMPEXT;
1879 Reference<XSimpleFileAccess3> xFileAccess(SimpleFileAccess::create(getContext()));
1880 xFileAccess->kill( aSysOutPath );
1882 catch( Exception& )
1886 if( bIsStrg )
1888 extractStorage( mxStrg, OUString(), aSysOutPath );
1890 else if( xBaseStrm.is() )
1892 BinaryInputStreamRef xInStrm( new BinaryXInputStream( xBaseStrm, false ) );
1893 xInStrm->seekToStart();
1894 implDumpBaseStream( xInStrm, aSysOutPath );
1898 void StorageObjectBase::implDumpStream( const Reference< XInputStream >&, const OUString&, const OUString&, const OUString& )
1902 void StorageObjectBase::implDumpStorage( const StorageRef& rxStrg, const OUString& rStrgPath, const OUString& rSysPath )
1904 extractStorage( rxStrg, rStrgPath, rSysPath );
1907 void StorageObjectBase::implDumpBaseStream( const BinaryInputStreamRef&, const OUString& )
1911 void StorageObjectBase::addPreferredStream( const String& rStrmName )
1913 if( rStrmName.has() )
1914 maPreferred.push_back( PreferredItem( rStrmName, false ) );
1917 void StorageObjectBase::addPreferredStorage( const String& rStrgPath )
1919 if( rStrgPath.has() )
1920 maPreferred.push_back( PreferredItem( rStrgPath, true ) );
1923 OUString StorageObjectBase::getSysFileName( const OUString& rStrmName, const OUString& rSysOutPath )
1925 // encode all characters < 0x20
1926 OUStringBuffer aBuffer;
1927 StringHelper::appendEncString( aBuffer, rStrmName, false );
1929 // replace all characters reserved in file system
1930 OUString aFileName = aBuffer.makeStringAndClear();
1931 static const sal_Unicode spcReserved[] = { '/', '\\', ':', '*', '?', '<', '>', '|' };
1932 for( const sal_Unicode* pcChar = spcReserved; pcChar < STATIC_ARRAY_END( spcReserved ); ++pcChar )
1933 aFileName = aFileName.replace( *pcChar, '_' );
1935 // build full path
1936 return rSysOutPath + OUString( sal_Unicode( '/' ) ) + aFileName;
1939 void StorageObjectBase::extractStream( StorageBase& rStrg, const OUString& rStrgPath, const OUString& rStrmName, const OUString& rSysFileName )
1941 BinaryXInputStream aInStrm( rStrg.openInputStream( rStrmName ), true );
1942 if( !aInStrm.isEof() )
1944 BinaryXOutputStream aOutStrm( InputOutputHelper::openOutputStream( getContext(), rSysFileName ), true );
1945 if( !aOutStrm.isEof() )
1946 aInStrm.copyToStream( aOutStrm );
1948 Reference< XInputStream > xDumpStrm = InputOutputHelper::openInputStream( getContext(), rSysFileName );
1949 if( xDumpStrm.is() )
1950 implDumpStream( xDumpStrm, rStrgPath, rStrmName, rSysFileName );
1953 void StorageObjectBase::extractStorage( const StorageRef& rxStrg, const OUString& rStrgPath, const OUString& rSysPath )
1955 // create directory in file system
1956 ::osl::FileBase::RC eRes = ::osl::Directory::create( rSysPath );
1957 if( (eRes != ::osl::FileBase::E_None) && (eRes != ::osl::FileBase::E_EXIST) )
1958 return;
1960 // process preferred storages and streams in root storage first
1961 if( rStrgPath.isEmpty() )
1962 for( PreferredItemVector::iterator aIt = maPreferred.begin(), aEnd = maPreferred.end(); aIt != aEnd; ++aIt )
1963 extractItem( rxStrg, rStrgPath, aIt->maName, rSysPath, aIt->mbStorage, !aIt->mbStorage );
1965 // process children of the storage
1966 for( StorageIterator aIt( rxStrg ); aIt.isValid(); ++aIt )
1968 // skip processed preferred items
1969 OUString aItemName = aIt.getName();
1970 bool bFound = false;
1971 if( rStrgPath.isEmpty() )
1972 for( PreferredItemVector::iterator aIIt = maPreferred.begin(), aIEnd = maPreferred.end(); !bFound && (aIIt != aIEnd); ++aIIt )
1973 bFound = aIIt->maName == aItemName;
1974 if( !bFound )
1975 extractItem( rxStrg, rStrgPath, aItemName, rSysPath, aIt.isStorage(), aIt.isStream() );
1979 void StorageObjectBase::extractItem( const StorageRef& rxStrg, const OUString& rStrgPath, const OUString& rItemName, const OUString& rSysPath, bool bIsStrg, bool bIsStrm )
1981 OUString aSysFileName = getSysFileName( rItemName, rSysPath );
1982 if( bIsStrg )
1984 OUStringBuffer aStrgPath( rStrgPath );
1985 StringHelper::appendToken( aStrgPath, rItemName, '/' );
1986 implDumpStorage( rxStrg->openSubStorage( rItemName, false ), aStrgPath.makeStringAndClear(), aSysFileName );
1988 else if( bIsStrm )
1990 extractStream( *rxStrg, rStrgPath, rItemName, aSysFileName );
1994 // ============================================================================
1995 // ============================================================================
1997 OutputObjectBase::~OutputObjectBase()
2001 void OutputObjectBase::construct( const ObjectBase& rParent, const OUString& rSysFileName )
2003 ObjectBase::construct( rParent );
2004 if( ObjectBase::implIsValid() )
2006 maSysFileName = rSysFileName;
2007 mxOut.reset( new Output( getContext(), rSysFileName + OOX_DUMP_DUMPEXT ) );
2011 void OutputObjectBase::construct( const OutputObjectBase& rParent )
2013 *this = rParent;
2016 bool OutputObjectBase::implIsValid() const
2018 return isValid( mxOut ) && ObjectBase::implIsValid();
2021 void OutputObjectBase::writeEmptyItem( const String& rName )
2023 ItemGuard aItem( mxOut, rName );
2026 void OutputObjectBase::writeInfoItem( const String& rName, const String& rData )
2028 ItemGuard aItem( mxOut, rName );
2029 mxOut->writeString( rData );
2032 void OutputObjectBase::writeCharItem( const String& rName, sal_Unicode cData )
2034 ItemGuard aItem( mxOut, rName );
2035 mxOut->writeChar( OOX_DUMP_STRQUOTE );
2036 mxOut->writeChar( cData );
2037 mxOut->writeChar( OOX_DUMP_STRQUOTE );
2040 void OutputObjectBase::writeStringItem( const String& rName, const OUString& rData )
2042 ItemGuard aItem( mxOut, rName );
2043 mxOut->writeAscii( "(len=" );
2044 mxOut->writeDec( rData.getLength() );
2045 mxOut->writeAscii( ")," );
2046 OUStringBuffer aValue( rData.copy( 0, ::std::min( rData.getLength(), OOX_DUMP_MAXSTRLEN ) ) );
2047 StringHelper::enclose( aValue, OOX_DUMP_STRQUOTE );
2048 mxOut->writeString( aValue.makeStringAndClear() );
2049 if( rData.getLength() > OOX_DUMP_MAXSTRLEN )
2050 mxOut->writeAscii( ",cut" );
2053 void OutputObjectBase::writeArrayItem( const String& rName, const sal_uInt8* pnData, sal_Size nSize, sal_Unicode cSep )
2055 ItemGuard aItem( mxOut, rName );
2056 mxOut->writeArray( pnData, nSize, cSep );
2059 void OutputObjectBase::writeDateTimeItem( const String& rName, const util::DateTime& rDateTime )
2061 ItemGuard aItem( mxOut, rName );
2062 mxOut->writeDateTime( rDateTime );
2065 void OutputObjectBase::writeGuidItem( const String& rName, const OUString& rGuid )
2067 ItemGuard aItem( mxOut, rName );
2068 mxOut->writeString( rGuid );
2069 aItem.cont();
2070 mxOut->writeString( cfg().getStringOption( rGuid, OUString() ) );
2073 // ============================================================================
2074 // ============================================================================
2076 InputObjectBase::~InputObjectBase()
2080 void InputObjectBase::construct( const ObjectBase& rParent, const BinaryInputStreamRef& rxStrm, const OUString& rSysFileName )
2082 OutputObjectBase::construct( rParent, rSysFileName );
2083 mxStrm = rxStrm;
2086 void InputObjectBase::construct( const OutputObjectBase& rParent, const BinaryInputStreamRef& rxStrm )
2088 OutputObjectBase::construct( rParent );
2089 mxStrm = rxStrm;
2092 void InputObjectBase::construct( const InputObjectBase& rParent )
2094 *this = rParent;
2097 bool InputObjectBase::implIsValid() const
2099 return mxStrm.get() && OutputObjectBase::implIsValid();
2102 void InputObjectBase::skipBlock( sal_Int64 nBytes, bool bShowSize )
2104 sal_Int64 nEndPos = ::std::min< sal_Int64 >( mxStrm->tell() + nBytes, mxStrm->size() );
2105 if( mxStrm->tell() < nEndPos )
2107 if( bShowSize )
2108 writeDecItem( "skipped-data-size", static_cast< sal_uInt64 >( nEndPos - mxStrm->tell() ) );
2109 mxStrm->seek( nEndPos );
2113 void InputObjectBase::dumpRawBinary( sal_Int64 nBytes, bool bShowOffset, bool bStream )
2115 TableGuard aTabGuard( mxOut,
2116 bShowOffset ? 12 : 0,
2117 3 * OOX_DUMP_BYTESPERLINE / 2 + 1,
2118 3 * OOX_DUMP_BYTESPERLINE / 2 + 1,
2119 OOX_DUMP_BYTESPERLINE / 2 + 1 );
2121 sal_Int64 nMaxShowSize = cfg().getIntOption< sal_Int64 >(
2122 bStream ? "max-binary-stream-size" : "max-binary-data-size", SAL_MAX_INT64 );
2124 bool bSeekable = mxStrm->size() >= 0;
2125 sal_Int64 nEndPos = bSeekable ? ::std::min< sal_Int64 >( mxStrm->tell() + nBytes, mxStrm->size() ) : 0;
2126 sal_Int64 nDumpEnd = bSeekable ? ::std::min< sal_Int64 >( mxStrm->tell() + nMaxShowSize, nEndPos ) : nMaxShowSize;
2127 sal_Int64 nPos = bSeekable ? mxStrm->tell() : 0;
2128 bool bLoop = true;
2130 while( bLoop && (nPos < nDumpEnd) )
2132 mxOut->writeHex( static_cast< sal_uInt32 >( nPos ) );
2133 mxOut->tab();
2135 sal_uInt8 pnLineData[ OOX_DUMP_BYTESPERLINE ];
2136 sal_Int32 nLineSize = bSeekable ? ::std::min( static_cast< sal_Int32 >( nDumpEnd - mxStrm->tell() ), OOX_DUMP_BYTESPERLINE ) : OOX_DUMP_BYTESPERLINE;
2137 sal_Int32 nReadSize = mxStrm->readMemory( pnLineData, nLineSize );
2138 bLoop = nReadSize == nLineSize;
2139 nPos += nReadSize;
2141 if( nReadSize > 0 )
2143 const sal_uInt8* pnByte = 0;
2144 const sal_uInt8* pnEnd = 0;
2145 for( pnByte = pnLineData, pnEnd = pnLineData + nReadSize; pnByte != pnEnd; ++pnByte )
2147 if( (pnByte - pnLineData) == (OOX_DUMP_BYTESPERLINE / 2) ) mxOut->tab();
2148 mxOut->writeHex( *pnByte, false );
2149 mxOut->writeChar( ' ' );
2152 aTabGuard.tab( 3 );
2153 for( pnByte = pnLineData, pnEnd = pnLineData + nReadSize; pnByte != pnEnd; ++pnByte )
2155 if( (pnByte - pnLineData) == (OOX_DUMP_BYTESPERLINE / 2) ) mxOut->tab();
2156 mxOut->writeChar( static_cast< sal_Unicode >( (*pnByte < 0x20) ? '.' : *pnByte ) );
2158 mxOut->newLine();
2162 // skip undumped data
2163 if( bSeekable )
2164 skipBlock( nEndPos - mxStrm->tell() );
2167 void InputObjectBase::dumpBinary( const String& rName, sal_Int64 nBytes, bool bShowOffset )
2170 MultiItemsGuard aMultiGuard( mxOut );
2171 writeEmptyItem( rName );
2172 writeDecItem( "size", nBytes );
2174 IndentGuard aIndGuard( mxOut );
2175 dumpRawBinary( nBytes, bShowOffset );
2178 void InputObjectBase::dumpRemaining( sal_Int64 nBytes )
2180 if( nBytes > 0 )
2182 if( cfg().getBoolOption( "show-trailing-unknown", true ) )
2183 dumpBinary( "remaining-data", nBytes, false );
2184 else
2185 skipBlock( nBytes );
2189 void InputObjectBase::dumpRemainingTo( sal_Int64 nPos )
2191 if( mxStrm->isEof() || (mxStrm->tell() > nPos) )
2192 writeInfoItem( "stream-state", OOX_DUMP_ERR_STREAM );
2193 else
2194 dumpRemaining( nPos - mxStrm->tell() );
2195 mxStrm->seek( nPos );
2198 void InputObjectBase::dumpRemainingStream()
2200 dumpRemainingTo( mxStrm->size() );
2203 void InputObjectBase::dumpArray( const String& rName, sal_Int32 nBytes, sal_Unicode cSep )
2205 sal_Int32 nDumpSize = getLimitedValue< sal_Int32, sal_Int64 >( mxStrm->size() - mxStrm->tell(), 0, nBytes );
2206 if( nDumpSize > OOX_DUMP_MAXARRAY )
2208 dumpBinary( rName, nBytes, false );
2210 else if( nDumpSize > 1 )
2212 sal_uInt8 pnData[ OOX_DUMP_MAXARRAY ];
2213 mxStrm->readMemory( pnData, nDumpSize );
2214 writeArrayItem( rName, pnData, nDumpSize, cSep );
2216 else if( nDumpSize == 1 )
2217 dumpHex< sal_uInt8 >( rName );
2220 sal_Unicode InputObjectBase::dumpUnicode( const String& rName )
2222 sal_uInt16 nChar;
2223 *mxStrm >> nChar;
2224 sal_Unicode cChar = static_cast< sal_Unicode >( nChar );
2225 writeCharItem( rName( "char" ), cChar );
2226 return cChar;
2229 OUString InputObjectBase::dumpCharArray( const String& rName, sal_Int32 nLen, rtl_TextEncoding eTextEnc, bool bHideTrailingNul )
2231 sal_Int32 nDumpSize = getLimitedValue< sal_Int32, sal_Int64 >( mxStrm->size() - mxStrm->tell(), 0, nLen );
2232 OUString aString;
2233 if( nDumpSize > 0 )
2235 ::std::vector< sal_Char > aBuffer( static_cast< sal_Size >( nLen ) + 1 );
2236 sal_Int32 nCharsRead = mxStrm->readMemory( &aBuffer.front(), nLen );
2237 aBuffer[ nCharsRead ] = 0;
2238 aString = OStringToOUString( OString( &aBuffer.front() ), eTextEnc );
2240 if( bHideTrailingNul )
2241 aString = StringHelper::trimTrailingNul( aString );
2242 writeStringItem( rName( "text" ), aString );
2243 return aString;
2246 OUString InputObjectBase::dumpUnicodeArray( const String& rName, sal_Int32 nLen, bool bHideTrailingNul )
2248 OUStringBuffer aBuffer;
2249 for( sal_Int32 nIndex = 0; !mxStrm->isEof() && (nIndex < nLen); ++nIndex )
2250 aBuffer.append( static_cast< sal_Unicode >( mxStrm->readuInt16() ) );
2251 OUString aString = aBuffer.makeStringAndClear();
2252 if( bHideTrailingNul )
2253 aString = StringHelper::trimTrailingNul( aString );
2254 writeStringItem( rName( "text" ), aString );
2255 return aString;
2258 util::DateTime InputObjectBase::dumpFileTime( const String& rName )
2260 util::DateTime aDateTime;
2262 ItemGuard aItem( mxOut, rName( "file-time" ) );
2263 sal_Int64 nFileTime = dumpDec< sal_Int64 >( EMPTY_STRING );
2264 // file time is in 10^-7 seconds (100 nanoseconds), convert to nanoseconds
2265 nFileTime *= 100;
2266 // entire days
2267 sal_Int64 nDays = nFileTime / sal_Int64( ::Time::nanoSecPerDay );
2268 // number of entire years
2269 sal_Int64 nYears = (nDays - (nDays / (4 * 365)) + (nDays / (100 * 365)) - (nDays / (400 * 365))) / 365;
2270 // remaining days in the year
2271 sal_Int64 nDaysInYear = nDays - (nYears * 365 + nYears / 4 - nYears / 100 + nYears / 400);
2272 // the year (file dates start from 1601-01-01)
2273 aDateTime.Year = static_cast< sal_uInt16 >( 1601 + nYears );
2274 // leap year?
2275 bool bLeap = ((aDateTime.Year % 4 == 0) && (aDateTime.Year % 100 != 0)) || (aDateTime.Year % 400 == 0);
2276 // static arrays with number of days in month
2277 static const sal_Int64 spnDaysInMonth[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
2278 static const sal_Int64 spnDaysInMonthL[] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
2279 const sal_Int64* pnDaysInMonth = bLeap ? spnDaysInMonthL : spnDaysInMonth;
2280 // the month
2281 aDateTime.Month = 1;
2282 while( nDaysInYear >= *pnDaysInMonth )
2284 nDaysInYear -= *pnDaysInMonth++;
2285 ++aDateTime.Month;
2287 // the day
2288 aDateTime.Day = static_cast< sal_uInt16 >( nDaysInYear + 1 );
2289 // number of nanoseconds in the day
2290 sal_Int64 nTimeInDay = nFileTime % sal_Int64( ::Time::nanoSecPerDay );
2291 // nanoseconds
2292 aDateTime.NanoSeconds = static_cast< sal_uInt32 >( nTimeInDay % ::Time::nanoSecPerSec );
2293 nTimeInDay /= ::Time::nanoSecPerSec;
2294 // seconds
2295 aDateTime.Seconds = static_cast< sal_uInt16 >( nTimeInDay % ::Time::secondPerMinute );
2296 nTimeInDay /= ::Time::secondPerMinute;
2297 // minutes
2298 aDateTime.Minutes = static_cast< sal_uInt16 >( nTimeInDay % ::Time::minutePerHour );
2299 nTimeInDay /= ::Time::minutePerHour;
2300 // hours
2301 aDateTime.Hours = static_cast< sal_uInt16 >( nTimeInDay );
2303 writeDateTimeItem( EMPTY_STRING, aDateTime );
2304 return aDateTime;
2307 OUString InputObjectBase::dumpGuid( const String& rName )
2309 OUStringBuffer aBuffer;
2310 sal_uInt32 nData32;
2311 sal_uInt16 nData16;
2312 sal_uInt8 nData8;
2314 *mxStrm >> nData32;
2315 StringHelper::appendHex( aBuffer, nData32, false );
2316 aBuffer.append( sal_Unicode( '-' ) );
2317 *mxStrm >> nData16;
2318 StringHelper::appendHex( aBuffer, nData16, false );
2319 aBuffer.append( sal_Unicode( '-' ) );
2320 *mxStrm >> nData16;
2321 StringHelper::appendHex( aBuffer, nData16, false );
2322 aBuffer.append( sal_Unicode( '-' ) );
2323 *mxStrm >> nData8;
2324 StringHelper::appendHex( aBuffer, nData8, false );
2325 *mxStrm >> nData8;
2326 StringHelper::appendHex( aBuffer, nData8, false );
2327 aBuffer.append( sal_Unicode( '-' ) );
2328 for( int nIndex = 0; nIndex < 6; ++nIndex )
2330 *mxStrm >> nData8;
2331 StringHelper::appendHex( aBuffer, nData8, false );
2333 StringHelper::enclose( aBuffer, '{', '}' );
2334 OUString aGuid = aBuffer.makeStringAndClear();
2335 writeGuidItem( rName( "guid" ), aGuid );
2336 return aGuid;
2339 void InputObjectBase::dumpItem( const ItemFormat& rItemFmt )
2341 switch( rItemFmt.meDataType )
2343 case DATATYPE_VOID: break;
2344 case DATATYPE_INT8: dumpValue< sal_Int8 >( rItemFmt ); break;
2345 case DATATYPE_UINT8: dumpValue< sal_uInt8 >( rItemFmt ); break;
2346 case DATATYPE_INT16: dumpValue< sal_Int16 >( rItemFmt ); break;
2347 case DATATYPE_UINT16: dumpValue< sal_uInt16 >( rItemFmt ); break;
2348 case DATATYPE_INT32: dumpValue< sal_Int32 >( rItemFmt ); break;
2349 case DATATYPE_UINT32: dumpValue< sal_uInt32 >( rItemFmt ); break;
2350 case DATATYPE_INT64: dumpValue< sal_Int64 >( rItemFmt ); break;
2351 case DATATYPE_UINT64: dumpValue< sal_uInt64 >( rItemFmt ); break;
2352 case DATATYPE_FLOAT: dumpValue< float >( rItemFmt ); break;
2353 case DATATYPE_DOUBLE: dumpValue< double >( rItemFmt ); break;
2354 default:;
2358 // ============================================================================
2359 // ============================================================================
2361 BinaryStreamObject::BinaryStreamObject( const ObjectBase& rParent, const BinaryInputStreamRef& rxStrm, const OUString& rSysFileName )
2363 InputObjectBase::construct( rParent, rxStrm, rSysFileName );
2366 void BinaryStreamObject::dumpBinaryStream( bool bShowOffset )
2368 mxStrm->seekToStart();
2369 dumpRawBinary( mxStrm->size(), bShowOffset, true );
2370 mxOut->emptyLine();
2373 void BinaryStreamObject::implDump()
2375 dumpBinaryStream();
2378 // ============================================================================
2379 // ============================================================================
2381 void TextStreamObjectBase::construct( const ObjectBase& rParent,
2382 const BinaryInputStreamRef& rxStrm, rtl_TextEncoding eTextEnc, const OUString& rSysFileName )
2384 InputObjectBase::construct( rParent, rxStrm, rSysFileName );
2385 constructTextStrmObj( eTextEnc );
2388 void TextStreamObjectBase::construct( const OutputObjectBase& rParent,
2389 const BinaryInputStreamRef& rxStrm, rtl_TextEncoding eTextEnc )
2391 InputObjectBase::construct( rParent, rxStrm );
2392 constructTextStrmObj( eTextEnc );
2395 bool TextStreamObjectBase::implIsValid() const
2397 return InputObjectBase::implIsValid() && mxTextStrm.get();
2400 void TextStreamObjectBase::implDump()
2402 implDumpText( *mxTextStrm );
2405 void TextStreamObjectBase::constructTextStrmObj( rtl_TextEncoding eTextEnc )
2407 if( mxStrm.get() )
2408 mxTextStrm.reset( new TextInputStream( getContext(), *mxStrm, eTextEnc ) );
2411 // ============================================================================
2413 TextLineStreamObject::TextLineStreamObject( const ObjectBase& rParent,
2414 const BinaryInputStreamRef& rxStrm, rtl_TextEncoding eTextEnc, const OUString& rSysFileName )
2416 TextStreamObjectBase::construct( rParent, rxStrm, eTextEnc, rSysFileName );
2419 TextLineStreamObject::TextLineStreamObject( const OutputObjectBase& rParent,
2420 const BinaryInputStreamRef& rxStrm, rtl_TextEncoding eTextEnc )
2422 TextStreamObjectBase::construct( rParent, rxStrm, eTextEnc );
2425 void TextLineStreamObject::implDumpText( TextInputStream& rTextStrm )
2427 sal_uInt32 nLine = 0;
2428 while( !rTextStrm.isEof() )
2430 OUString aLine = rTextStrm.readLine();
2431 if( !rTextStrm.isEof() || !aLine.isEmpty() )
2432 implDumpLine( aLine, ++nLine );
2436 void TextLineStreamObject::implDumpLine( const OUString& rLine, sal_uInt32 nLine )
2438 TableGuard aTabGuard( mxOut, 8 );
2439 mxOut->writeDec( nLine, 6 );
2440 mxOut->tab();
2441 mxOut->writeString( rLine );
2442 mxOut->newLine();
2445 // ============================================================================
2447 XmlStreamObject::XmlStreamObject( const ObjectBase& rParent,
2448 const BinaryInputStreamRef& rxStrm, const OUString& rSysFileName )
2450 TextStreamObjectBase::construct( rParent, rxStrm, RTL_TEXTENCODING_UTF8, rSysFileName );
2453 void XmlStreamObject::implDumpText( TextInputStream& rTextStrm )
2455 /* Buffers a start element and the following element text. Needed to dump
2456 matching start/end elements and the element text on the same line. */
2457 OUStringBuffer aOldStartElem;
2458 // special handling for VML
2459 bool bIsVml = InputOutputHelper::getFileNameExtension( maSysFileName ).equalsIgnoreAsciiCase("vml");
2461 while( !rTextStrm.isEof() )
2463 // get the next element and the following element text from text stream
2464 OUString aElem = rTextStrm.readToChar( '>', true ).trim();
2465 OUString aText = rTextStrm.readToChar( '<', false );
2467 // remove multiple whitespace from element
2468 sal_Int32 nPos = 0;
2469 while( nPos < aElem.getLength() )
2471 while( (nPos < aElem.getLength()) && (aElem[ nPos ] >= 32) ) ++nPos;
2472 if( nPos < aElem.getLength() )
2473 aElem = OUStringBuffer( aElem.copy( 0, nPos ) ).append( sal_Unicode( ' ' ) ).append( aElem.copy( nPos ).trim() ).makeStringAndClear();
2474 ++nPos;
2477 sal_Int32 nElemLen = aElem.getLength();
2478 if( (nElemLen >= 2) && (aElem[ 0 ] == '<') && (aElem[ nElemLen - 1 ] == '>') )
2480 // determine type of the element
2481 bool bSimpleElem = (aElem[ 1 ] == '!') || (aElem[ 1 ] == '?') || (aElem[ nElemLen - 2 ] == '/') ||
2482 (bIsVml && (nElemLen == 4) && (aElem[ 1 ] == 'b') && (aElem[ 2 ] == 'r'));
2483 bool bStartElem = !bSimpleElem && (aElem[ 1 ] != '/');
2484 bool bEndElem = !bSimpleElem && !bStartElem;
2486 /* Start element or simple element: flush old start element and
2487 its text from previous iteration, and start a new indentation
2488 level for the new element. Trim whitespace and line breaks from
2489 the text of the old start element. */
2490 if( (bSimpleElem || bStartElem) && (aOldStartElem.getLength() > 0) )
2492 mxOut->writeString( aOldStartElem.makeStringAndClear().trim() );
2493 mxOut->newLine();
2494 mxOut->incIndent();
2497 /* Start element: remember it and its text, to be able to print the
2498 matching end element on the same line in the next iteration. */
2499 if( bStartElem )
2501 aOldStartElem.append( aElem ).append( aText );
2503 else
2505 /* End element: if a start element has been remembered in the
2506 previous iteration, write it out here untrimmed, to show
2507 all whitespace in the element text, and without trailing
2508 line break. Code below will add the end element right after
2509 it. Otherwise, return to previous indentation level. */
2510 if( bEndElem )
2512 if( aOldStartElem.getLength() == 0 )
2513 mxOut->decIndent();
2514 else
2515 mxOut->writeString( aOldStartElem.makeStringAndClear() );
2518 /* Write the element. Write following element text in a new
2519 line, but only, if it does not contain of white space
2520 entirely. */
2521 mxOut->writeString( aElem );
2522 mxOut->newLine();
2523 if( !aText.trim().isEmpty() )
2525 mxOut->writeString( aText );
2526 mxOut->newLine();
2533 // ============================================================================
2534 // ============================================================================
2536 void RecordObjectBase::construct( const ObjectBase& rParent,
2537 const BinaryInputStreamRef& rxBaseStrm, const OUString& rSysFileName,
2538 const BinaryInputStreamRef& rxRecStrm, const String& rRecNames, const String& rSimpleRecs )
2540 InputObjectBase::construct( rParent, rxRecStrm, rSysFileName );
2541 constructRecObjBase( rxBaseStrm, rRecNames, rSimpleRecs );
2544 bool RecordObjectBase::implIsValid() const
2546 return mxBaseStrm.get() && InputObjectBase::implIsValid();
2549 void RecordObjectBase::implDump()
2551 NameListRef xRecNames = getRecNames();
2552 ItemFormatMap aSimpleRecs( maSimpleRecs.getNameList( cfg() ) );
2554 while( implStartRecord( *mxBaseStrm, mnRecPos, mnRecId, mnRecSize ) )
2556 // record header
2557 mxOut->emptyLine();
2558 writeHeader();
2559 implWriteExtHeader();
2560 IndentGuard aIndGuard( mxOut );
2561 sal_Int64 nRecPos = mxStrm->tell();
2563 // record body
2564 if( !mbBinaryOnly && cfg().hasName( xRecNames, mnRecId ) )
2566 ItemFormatMap::const_iterator aIt = aSimpleRecs.find( mnRecId );
2567 if( aIt != aSimpleRecs.end() )
2568 dumpItem( aIt->second );
2569 else
2570 implDumpRecordBody();
2573 // remaining undumped data
2574 if( !mxStrm->isEof() && (mxStrm->tell() == nRecPos) )
2575 dumpRawBinary( mnRecSize, false );
2576 else
2577 dumpRemainingTo( nRecPos + mnRecSize );
2581 void RecordObjectBase::implWriteExtHeader()
2585 void RecordObjectBase::implDumpRecordBody()
2589 void RecordObjectBase::constructRecObjBase( const BinaryInputStreamRef& rxBaseStrm, const String& rRecNames, const String& rSimpleRecs )
2591 mxBaseStrm = rxBaseStrm;
2592 maRecNames = rRecNames;
2593 maSimpleRecs = rSimpleRecs;
2594 mnRecPos = mnRecId = mnRecSize = 0;
2595 mbBinaryOnly = false;
2596 if( InputObjectBase::implIsValid() )
2597 mbShowRecPos = cfg().getBoolOption( "show-record-position", true );
2600 void RecordObjectBase::writeHeader()
2602 MultiItemsGuard aMultiGuard( mxOut );
2603 writeEmptyItem( "REC" );
2604 if( mbShowRecPos && mxBaseStrm->isSeekable() )
2605 writeShortHexItem( "pos", mnRecPos, "CONV-DEC" );
2606 writeShortHexItem( "size", mnRecSize, "CONV-DEC" );
2607 ItemGuard aItem( mxOut, "id" );
2608 mxOut->writeShortHex( mnRecId );
2609 addNameToItem( mnRecId, "CONV-DEC" );
2610 addNameToItem( mnRecId, maRecNames );
2613 // ============================================================================
2615 void SequenceRecordObjectBase::construct( const ObjectBase& rParent,
2616 const BinaryInputStreamRef& rxBaseStrm, const OUString& rSysFileName,
2617 const String& rRecNames, const String& rSimpleRecs )
2619 BinaryInputStreamRef xRecStrm( new SequenceInputStream( *mxRecData ) );
2620 RecordObjectBase::construct( rParent, rxBaseStrm, rSysFileName, xRecStrm, rRecNames, rSimpleRecs );
2623 bool SequenceRecordObjectBase::implStartRecord( BinaryInputStream& rBaseStrm, sal_Int64& ornRecPos, sal_Int64& ornRecId, sal_Int64& ornRecSize )
2625 bool bValid = true;
2626 if( rBaseStrm.isSeekable() )
2628 ornRecPos = rBaseStrm.tell();
2629 // do not try to overread seekable streams, may cause assertions
2630 bValid = ornRecPos < rBaseStrm.size();
2633 // read the record header
2634 if( bValid )
2635 bValid = implReadRecordHeader( rBaseStrm, ornRecId, ornRecSize ) && !rBaseStrm.isEof() && (0 <= ornRecSize) && (ornRecSize <= 0x00100000);
2637 // read record contents into data sequence
2638 if( bValid )
2640 sal_Int32 nRecSize = static_cast< sal_Int32 >( ornRecSize );
2641 mxRecData->realloc( nRecSize );
2642 bValid = (nRecSize == 0) || (rBaseStrm.readData( *mxRecData, nRecSize ) == nRecSize);
2643 mxStrm->seekToStart();
2645 return bValid;
2648 // ============================================================================
2649 // ============================================================================
2651 DumperBase::~DumperBase()
2655 bool DumperBase::isImportEnabled() const
2657 return !isValid() || cfg().isImportEnabled();
2660 bool DumperBase::isImportCancelled() const
2662 return isValid() && cfg().isPasswordCancelled();
2665 void DumperBase::construct( const ConfigRef& rxConfig )
2667 if( isValid( rxConfig ) && rxConfig->isDumperEnabled() )
2668 ObjectBase::construct( rxConfig );
2671 // ============================================================================
2672 // ============================================================================
2674 } // namespace dump
2675 } // namespace oox
2677 #endif
2679 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */