1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: dumperbase.cxx,v $
10 * $Revision: 1.4.20.13 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 #include "oox/dump/dumperbase.hxx"
34 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
35 #include <com/sun/star/ucb/XSimpleFileAccess.hpp>
36 #include <com/sun/star/io/XActiveDataSink.hpp>
37 #include <com/sun/star/io/XActiveDataSource.hpp>
38 #include <com/sun/star/io/XTextInputStream.hpp>
39 #include <com/sun/star/io/XTextOutputStream.hpp>
40 #include <rtl/math.hxx>
41 #include <osl/file.hxx>
42 #include <comphelper/docpasswordhelper.hxx>
43 #include "oox/helper/binaryoutputstream.hxx"
44 #include "oox/core/filterbase.hxx"
45 #include "oox/xls/biffhelper.hxx"
47 #if OOX_INCLUDE_DUMPER
50 using ::rtl::OStringBuffer
;
51 using ::rtl::OStringToOUString
;
52 using ::rtl::OUString
;
53 using ::rtl::OUStringBuffer
;
54 using ::rtl::OUStringToOString
;
55 using ::com::sun::star::uno::Exception
;
56 using ::com::sun::star::uno::Reference
;
57 using ::com::sun::star::uno::UNO_QUERY_THROW
;
58 using ::com::sun::star::util::DateTime
;
59 using ::com::sun::star::lang::XMultiServiceFactory
;
60 using ::com::sun::star::ucb::XSimpleFileAccess
;
61 using ::com::sun::star::io::XActiveDataSink
;
62 using ::com::sun::star::io::XActiveDataSource
;
63 using ::com::sun::star::io::XInputStream
;
64 using ::com::sun::star::io::XOutputStream
;
65 using ::com::sun::star::io::XTextInputStream
;
66 using ::com::sun::star::io::XTextOutputStream
;
67 using ::comphelper::MediaDescriptor
;
68 using ::oox::core::FilterBase
;
73 const sal_Unicode OOX_DUMP_BOM
= 0xFEFF;
74 const sal_Int32 OOX_DUMP_MAXSTRLEN
= 80;
75 const sal_Int32 OOX_DUMP_INDENT
= 2;
76 const sal_Unicode OOX_DUMP_BINDOT
= '.';
77 const sal_Unicode OOX_DUMP_CFG_LISTSEP
= ',';
78 const sal_Unicode OOX_DUMP_CFG_QUOTE
= '\'';
79 const sal_Unicode OOX_DUMP_LF
= '\n';
80 const sal_Unicode OOX_DUMP_ITEMSEP
= '=';
81 const sal_Int32 OOX_DUMP_BYTESPERLINE
= 16;
82 const sal_Int64 OOX_DUMP_MAXARRAY
= 16;
84 // ============================================================================
85 // ============================================================================
87 // file names -----------------------------------------------------------------
89 OUString
InputOutputHelper::convertFileNameToUrl( const OUString
& rFileName
)
92 if( ::osl::FileBase::getFileURLFromSystemPath( rFileName
, aFileUrl
) == ::osl::FileBase::E_None
)
97 sal_Int32
InputOutputHelper::getFileNamePos( const OUString
& rFileUrl
)
99 sal_Int32 nSepPos
= rFileUrl
.lastIndexOf( '/' );
100 return (nSepPos
< 0) ? 0 : (nSepPos
+ 1);
103 OUString
InputOutputHelper::getFileNameExtension( const OUString
& rFileUrl
)
105 sal_Int32 nNamePos
= getFileNamePos( rFileUrl
);
106 sal_Int32 nExtPos
= rFileUrl
.lastIndexOf( '.' );
107 if( nExtPos
>= nNamePos
)
108 return rFileUrl
.copy( nExtPos
+ 1 );
112 // input streams --------------------------------------------------------------
114 Reference
< XInputStream
> InputOutputHelper::getXInputStream( BinaryInputStream
& rStrm
)
116 if( BinaryXInputStream
* pXStrm
= dynamic_cast< BinaryXInputStream
* >( &rStrm
) )
117 return pXStrm
->getXInputStream();
121 Reference
< XInputStream
> InputOutputHelper::openInputStream(
122 const Reference
< XMultiServiceFactory
>& rxFactory
, const OUString
& rFileName
)
124 Reference
< XInputStream
> xInStrm
;
125 if( rxFactory
.is() ) try
127 Reference
< XSimpleFileAccess
> xFileAccess( rxFactory
->createInstance( CREATE_OUSTRING( "com.sun.star.ucb.SimpleFileAccess" ) ), UNO_QUERY_THROW
);
128 xInStrm
= xFileAccess
->openFileRead( rFileName
);
136 Reference
< XTextInputStream
> InputOutputHelper::openTextInputStream(
137 const Reference
< XMultiServiceFactory
>& rxFactory
, const Reference
< XInputStream
>& rxInStrm
, const OUString
& rEncoding
)
139 Reference
< XTextInputStream
> xTextInStrm
;
140 if( rxFactory
.is() && rxInStrm
.is() ) try
142 Reference
< XActiveDataSink
> xDataSink( rxFactory
->createInstance( CREATE_OUSTRING( "com.sun.star.io.TextInputStream" ) ), UNO_QUERY_THROW
);
143 xDataSink
->setInputStream( rxInStrm
);
144 xTextInStrm
.set( xDataSink
, UNO_QUERY_THROW
);
145 xTextInStrm
->setEncoding( rEncoding
);
153 Reference
< XTextInputStream
> InputOutputHelper::openTextInputStream(
154 const Reference
< XMultiServiceFactory
>& rxFactory
, const OUString
& rFileName
, const OUString
& rEncoding
)
156 return openTextInputStream( rxFactory
, openInputStream( rxFactory
, rFileName
), rEncoding
);
159 // output streams -------------------------------------------------------------
161 Reference
< XOutputStream
> InputOutputHelper::openOutputStream(
162 const Reference
< XMultiServiceFactory
>& rxFactory
, const OUString
& rFileName
)
164 Reference
< XOutputStream
> xOutStrm
;
165 if( rxFactory
.is() ) try
167 Reference
< XSimpleFileAccess
> xFileAccess( rxFactory
->createInstance( CREATE_OUSTRING( "com.sun.star.ucb.SimpleFileAccess" ) ), UNO_QUERY_THROW
);
168 xOutStrm
= xFileAccess
->openFileWrite( rFileName
);
176 Reference
< XTextOutputStream
> InputOutputHelper::openTextOutputStream(
177 const Reference
< XMultiServiceFactory
>& rxFactory
, const Reference
< XOutputStream
>& rxOutStrm
, const OUString
& rEncoding
)
179 Reference
< XTextOutputStream
> xTextOutStrm
;
180 if( rxFactory
.is() && rxOutStrm
.is() ) try
182 Reference
< XActiveDataSource
> xDataSource( rxFactory
->createInstance( CREATE_OUSTRING( "com.sun.star.io.TextOutputStream" ) ), UNO_QUERY_THROW
);
183 xDataSource
->setOutputStream( rxOutStrm
);
184 xTextOutStrm
.set( xDataSource
, UNO_QUERY_THROW
);
185 xTextOutStrm
->setEncoding( rEncoding
);
193 Reference
< XTextOutputStream
> InputOutputHelper::openTextOutputStream(
194 const Reference
< XMultiServiceFactory
>& rxFactory
, const OUString
& rFileName
, const OUString
& rEncoding
)
196 return openTextOutputStream( rxFactory
, openOutputStream( rxFactory
, rFileName
), rEncoding
);
199 // ============================================================================
200 // ============================================================================
202 ItemFormat::ItemFormat() :
203 meDataType( DATATYPE_VOID
),
204 meFmtType( FORMATTYPE_NONE
)
208 void ItemFormat::set( DataType eDataType
, FormatType eFmtType
, const OUString
& rItemName
)
210 meDataType
= eDataType
;
211 meFmtType
= eFmtType
;
212 maItemName
= rItemName
;
213 maListName
= OUString();
216 void ItemFormat::set( DataType eDataType
, FormatType eFmtType
, const OUString
& rItemName
, const OUString
& rListName
)
218 set( eDataType
, eFmtType
, rItemName
);
219 maListName
= rListName
;
222 OUStringVector::const_iterator
ItemFormat::parse( const OUStringVector
& rFormatVec
)
224 set( DATATYPE_VOID
, FORMATTYPE_NONE
, OUString() );
226 OUStringVector::const_iterator aIt
= rFormatVec
.begin(), aEnd
= rFormatVec
.end();
227 OUString aDataType
, aFmtType
;
228 if( aIt
!= aEnd
) aDataType
= *aIt
++;
229 if( aIt
!= aEnd
) aFmtType
= *aIt
++;
230 if( aIt
!= aEnd
) maItemName
= *aIt
++;
231 if( aIt
!= aEnd
) maListName
= *aIt
++;
233 meDataType
= StringHelper::convertToDataType( aDataType
);
234 meFmtType
= StringHelper::convertToFormatType( aFmtType
);
236 if( meFmtType
== FORMATTYPE_NONE
)
238 if( aFmtType
.equalsAscii( "unused" ) )
239 set( meDataType
, FORMATTYPE_HEX
, CREATE_OUSTRING( OOX_DUMP_UNUSED
) );
240 else if( aFmtType
.equalsAscii( "unknown" ) )
241 set( meDataType
, FORMATTYPE_HEX
, CREATE_OUSTRING( OOX_DUMP_UNKNOWN
) );
247 OUStringVector
ItemFormat::parse( const OUString
& rFormatStr
)
249 OUStringVector aFormatVec
;
250 StringHelper::convertStringToStringList( aFormatVec
, rFormatStr
, false );
251 OUStringVector::const_iterator aIt
= parse( aFormatVec
);
252 return OUStringVector( aIt
, const_cast< const OUStringVector
& >( aFormatVec
).end() );
255 // ============================================================================
256 // ============================================================================
258 // append string to string ----------------------------------------------------
260 void StringHelper::appendChar( OUStringBuffer
& rStr
, sal_Unicode cChar
, sal_Int32 nCount
)
262 for( sal_Int32 nIndex
= 0; nIndex
< nCount
; ++nIndex
)
263 rStr
.append( cChar
);
266 void StringHelper::appendString( OUStringBuffer
& rStr
, const OUString
& rData
, sal_Int32 nWidth
, sal_Unicode cFill
)
268 appendChar( rStr
, cFill
, nWidth
- rData
.getLength() );
269 rStr
.append( rData
);
272 // append decimal -------------------------------------------------------------
274 void StringHelper::appendDec( OUStringBuffer
& rStr
, sal_uInt8 nData
, sal_Int32 nWidth
, sal_Unicode cFill
)
276 appendString( rStr
, OUString::valueOf( static_cast< sal_Int32
>( nData
) ), nWidth
, cFill
);
279 void StringHelper::appendDec( OUStringBuffer
& rStr
, sal_Int8 nData
, sal_Int32 nWidth
, sal_Unicode cFill
)
281 appendString( rStr
, OUString::valueOf( static_cast< sal_Int32
>( nData
) ), nWidth
, cFill
);
284 void StringHelper::appendDec( OUStringBuffer
& rStr
, sal_uInt16 nData
, sal_Int32 nWidth
, sal_Unicode cFill
)
286 appendString( rStr
, OUString::valueOf( static_cast< sal_Int32
>( nData
) ), nWidth
, cFill
);
289 void StringHelper::appendDec( OUStringBuffer
& rStr
, sal_Int16 nData
, sal_Int32 nWidth
, sal_Unicode cFill
)
291 appendString( rStr
, OUString::valueOf( static_cast< sal_Int32
>( nData
) ), nWidth
, cFill
);
294 void StringHelper::appendDec( OUStringBuffer
& rStr
, sal_uInt32 nData
, sal_Int32 nWidth
, sal_Unicode cFill
)
296 appendString( rStr
, OUString::valueOf( static_cast< sal_Int64
>( nData
) ), nWidth
, cFill
);
299 void StringHelper::appendDec( OUStringBuffer
& rStr
, sal_Int32 nData
, sal_Int32 nWidth
, sal_Unicode cFill
)
301 appendString( rStr
, OUString::valueOf( nData
), nWidth
, cFill
);
304 void StringHelper::appendDec( OUStringBuffer
& rStr
, sal_uInt64 nData
, sal_Int32 nWidth
, sal_Unicode cFill
)
306 /* Values greater than biggest signed 64bit integer will change to
307 negative when converting to sal_Int64. Therefore, the trailing digit
308 will be written separately. */
309 OUStringBuffer aBuffer
;
311 aBuffer
.append( OUString::valueOf( static_cast< sal_Int64
>( nData
/ 10 ) ) );
312 aBuffer
.append( static_cast< sal_Unicode
>( '0' + (nData
% 10) ) );
313 appendString( rStr
, aBuffer
.makeStringAndClear(), nWidth
, cFill
);
316 void StringHelper::appendDec( OUStringBuffer
& rStr
, sal_Int64 nData
, sal_Int32 nWidth
, sal_Unicode cFill
)
318 appendString( rStr
, OUString::valueOf( nData
), nWidth
, cFill
);
321 void StringHelper::appendDec( OUStringBuffer
& rStr
, double fData
, sal_Int32 nWidth
, sal_Unicode cFill
)
323 appendString( rStr
, ::rtl::math::doubleToUString( fData
, rtl_math_StringFormat_G
, 15, '.', true ), nWidth
, cFill
);
326 // append hexadecimal ---------------------------------------------------------
328 void StringHelper::appendHex( OUStringBuffer
& rStr
, sal_uInt8 nData
, bool bPrefix
)
330 static const sal_Unicode spcHexDigits
[] = { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' };
332 rStr
.appendAscii( "0x" );
333 rStr
.append( spcHexDigits
[ (nData
>> 4) & 0x0F ] ).append( spcHexDigits
[ nData
& 0x0F ] );
336 void StringHelper::appendHex( OUStringBuffer
& rStr
, sal_Int8 nData
, bool bPrefix
)
338 appendHex( rStr
, static_cast< sal_uInt8
>( nData
), bPrefix
);
341 void StringHelper::appendHex( OUStringBuffer
& rStr
, sal_uInt16 nData
, bool bPrefix
)
343 appendHex( rStr
, static_cast< sal_uInt8
>( nData
>> 8 ), bPrefix
);
344 appendHex( rStr
, static_cast< sal_uInt8
>( nData
), false );
347 void StringHelper::appendHex( OUStringBuffer
& rStr
, sal_Int16 nData
, bool bPrefix
)
349 appendHex( rStr
, static_cast< sal_uInt16
>( nData
), bPrefix
);
352 void StringHelper::appendHex( OUStringBuffer
& rStr
, sal_uInt32 nData
, bool bPrefix
)
354 appendHex( rStr
, static_cast< sal_uInt16
>( nData
>> 16 ), bPrefix
);
355 appendHex( rStr
, static_cast< sal_uInt16
>( nData
), false );
358 void StringHelper::appendHex( OUStringBuffer
& rStr
, sal_Int32 nData
, bool bPrefix
)
360 appendHex( rStr
, static_cast< sal_uInt32
>( nData
), bPrefix
);
363 void StringHelper::appendHex( OUStringBuffer
& rStr
, sal_uInt64 nData
, bool bPrefix
)
365 appendHex( rStr
, static_cast< sal_uInt32
>( nData
>> 32 ), bPrefix
);
366 appendHex( rStr
, static_cast< sal_uInt32
>( nData
), false );
369 void StringHelper::appendHex( OUStringBuffer
& rStr
, sal_Int64 nData
, bool bPrefix
)
371 appendHex( rStr
, static_cast< sal_uInt64
>( nData
), bPrefix
);
374 void StringHelper::appendHex( OUStringBuffer
& rStr
, double fData
, bool bPrefix
)
376 appendHex( rStr
, *reinterpret_cast< const sal_uInt64
* >( &fData
), bPrefix
);
379 // append shortened hexadecimal -----------------------------------------------
381 void StringHelper::appendShortHex( OUStringBuffer
& rStr
, sal_uInt8 nData
, bool bPrefix
)
383 appendHex( rStr
, nData
, bPrefix
);
386 void StringHelper::appendShortHex( OUStringBuffer
& rStr
, sal_Int8 nData
, bool bPrefix
)
388 appendHex( rStr
, nData
, bPrefix
);
391 void StringHelper::appendShortHex( OUStringBuffer
& rStr
, sal_uInt16 nData
, bool bPrefix
)
393 if( nData
> SAL_MAX_UINT8
)
394 appendHex( rStr
, nData
, bPrefix
);
396 appendHex( rStr
, static_cast< sal_uInt8
>( nData
), bPrefix
);
399 void StringHelper::appendShortHex( OUStringBuffer
& rStr
, sal_Int16 nData
, bool bPrefix
)
401 appendShortHex( rStr
, static_cast< sal_uInt16
>( nData
), bPrefix
);
404 void StringHelper::appendShortHex( OUStringBuffer
& rStr
, sal_uInt32 nData
, bool bPrefix
)
406 if( nData
> SAL_MAX_UINT16
)
407 appendHex( rStr
, nData
, bPrefix
);
409 appendShortHex( rStr
, static_cast< sal_uInt16
>( nData
), bPrefix
);
412 void StringHelper::appendShortHex( OUStringBuffer
& rStr
, sal_Int32 nData
, bool bPrefix
)
414 appendShortHex( rStr
, static_cast< sal_uInt32
>( nData
), bPrefix
);
417 void StringHelper::appendShortHex( OUStringBuffer
& rStr
, sal_uInt64 nData
, bool bPrefix
)
419 if( nData
> SAL_MAX_UINT32
)
420 appendHex( rStr
, nData
, bPrefix
);
422 appendShortHex( rStr
, static_cast< sal_uInt32
>( nData
), bPrefix
);
425 void StringHelper::appendShortHex( OUStringBuffer
& rStr
, sal_Int64 nData
, bool bPrefix
)
427 appendShortHex( rStr
, static_cast< sal_uInt64
>( nData
), bPrefix
);
430 void StringHelper::appendShortHex( OUStringBuffer
& rStr
, double fData
, bool bPrefix
)
432 appendHex( rStr
, fData
, bPrefix
);
435 // append binary --------------------------------------------------------------
437 void StringHelper::appendBin( OUStringBuffer
& rStr
, sal_uInt8 nData
, bool bDots
)
439 for( sal_uInt8 nMask
= 0x80; nMask
!= 0; (nMask
>>= 1) &= 0x7F )
441 rStr
.append( static_cast< sal_Unicode
>( (nData
& nMask
) ? '1' : '0' ) );
442 if( bDots
&& (nMask
== 0x10) )
443 rStr
.append( OOX_DUMP_BINDOT
);
447 void StringHelper::appendBin( OUStringBuffer
& rStr
, sal_Int8 nData
, bool bDots
)
449 appendBin( rStr
, static_cast< sal_uInt8
>( nData
), bDots
);
452 void StringHelper::appendBin( OUStringBuffer
& rStr
, sal_uInt16 nData
, bool bDots
)
454 appendBin( rStr
, static_cast< sal_uInt8
>( nData
>> 8 ), bDots
);
456 rStr
.append( OOX_DUMP_BINDOT
);
457 appendBin( rStr
, static_cast< sal_uInt8
>( nData
), bDots
);
460 void StringHelper::appendBin( OUStringBuffer
& rStr
, sal_Int16 nData
, bool bDots
)
462 appendBin( rStr
, static_cast< sal_uInt16
>( nData
), bDots
);
465 void StringHelper::appendBin( OUStringBuffer
& rStr
, sal_uInt32 nData
, bool bDots
)
467 appendBin( rStr
, static_cast< sal_uInt16
>( nData
>> 16 ), bDots
);
469 rStr
.append( OOX_DUMP_BINDOT
);
470 appendBin( rStr
, static_cast< sal_uInt16
>( nData
), bDots
);
473 void StringHelper::appendBin( OUStringBuffer
& rStr
, sal_Int32 nData
, bool bDots
)
475 appendBin( rStr
, static_cast< sal_uInt32
>( nData
), bDots
);
478 void StringHelper::appendBin( OUStringBuffer
& rStr
, sal_uInt64 nData
, bool bDots
)
480 appendBin( rStr
, static_cast< sal_uInt32
>( nData
>> 32 ), bDots
);
482 rStr
.append( OOX_DUMP_BINDOT
);
483 appendBin( rStr
, static_cast< sal_uInt32
>( nData
), bDots
);
486 void StringHelper::appendBin( OUStringBuffer
& rStr
, sal_Int64 nData
, bool bDots
)
488 appendBin( rStr
, static_cast< sal_uInt64
>( nData
), bDots
);
491 void StringHelper::appendBin( OUStringBuffer
& rStr
, double fData
, bool bDots
)
493 appendBin( rStr
, *reinterpret_cast< const sal_uInt64
* >( &fData
), bDots
);
496 // append formatted value -----------------------------------------------------
498 void StringHelper::appendBool( OUStringBuffer
& rStr
, bool bData
)
500 rStr
.appendAscii( bData
? "true" : "false" );
503 // append columns, rows, addresses --------------------------------------------
505 void StringHelper::appendAddrCol( OUStringBuffer
& rStr
, sal_Int32 nCol
, bool bRel
)
507 if( !bRel
) rStr
.append( OOX_DUMP_ADDRABS
);
508 sal_Int32 nPos
= rStr
.getLength();
509 for( sal_Int32 nTemp
= nCol
; nTemp
>= 0; (nTemp
/= 26) -= 1 )
510 rStr
.insert( nPos
, static_cast< sal_Unicode
>( 'A' + (nTemp
% 26) ) );
513 void StringHelper::appendAddrRow( OUStringBuffer
& rStr
, sal_Int32 nRow
, bool bRel
)
515 if( !bRel
) rStr
.append( OOX_DUMP_ADDRABS
);
516 appendDec( rStr
, nRow
+ 1 );
519 void StringHelper::appendAddrName( OUStringBuffer
& rStr
, sal_Unicode cPrefix
, sal_Int32 nColRow
, bool bRel
)
521 rStr
.append( cPrefix
);
522 if( bRel
&& (nColRow
!= 0) )
524 rStr
.append( OOX_DUMP_R1C1OPEN
);
525 appendDec( rStr
, nColRow
);
526 rStr
.append( OOX_DUMP_R1C1CLOSE
);
529 appendDec( rStr
, nColRow
+ 1 );
532 void StringHelper::appendAddress( OUStringBuffer
& rStr
, const Address
& rPos
)
534 appendAddrCol( rStr
, rPos
.mnCol
, true );
535 appendAddrRow( rStr
, rPos
.mnRow
, true );
538 void StringHelper::appendRange( OUStringBuffer
& rStr
, const Range
& rRange
)
540 appendAddress( rStr
, rRange
.maFirst
);
541 rStr
.append( OOX_DUMP_RANGESEP
);
542 appendAddress( rStr
, rRange
.maLast
);
545 void StringHelper::appendRangeList( OUStringBuffer
& rStr
, const RangeList
& rRanges
)
547 OUStringBuffer aData
;
548 for( RangeList::const_iterator aIt
= rRanges
.begin(), aEnd
= rRanges
.end(); aIt
!= aEnd
; ++aIt
)
550 OUStringBuffer aRange
;
551 appendRange( aRange
, *aIt
);
552 appendToken( aData
, aRange
.makeStringAndClear(), OOX_DUMP_LISTSEP
);
554 rStr
.append( aData
.makeStringAndClear() );
557 void StringHelper::appendAddress( OUStringBuffer
& rStr
, const TokenAddress
& rPos
, bool bR1C1
)
559 if( bR1C1
&& (rPos
.mbRelCol
|| rPos
.mbRelRow
) )
561 appendAddrName( rStr
, OOX_DUMP_R1C1ROW
, rPos
.mnRow
, rPos
.mbRelRow
);
562 appendAddrName( rStr
, OOX_DUMP_R1C1COL
, rPos
.mnCol
, rPos
.mbRelCol
);
566 appendAddrCol( rStr
, rPos
.mnCol
, rPos
.mbRelCol
);
567 appendAddrRow( rStr
, rPos
.mnRow
, rPos
.mbRelRow
);
571 void StringHelper::appendRange( OUStringBuffer
& rStr
, const TokenRange
& rRange
, bool bR1C1
)
573 appendAddress( rStr
, rRange
.maFirst
, bR1C1
);
574 rStr
.append( OOX_DUMP_RANGESEP
);
575 appendAddress( rStr
, rRange
.maLast
, bR1C1
);
578 // encoded text output --------------------------------------------------------
580 void StringHelper::appendCChar( OUStringBuffer
& rStr
, sal_Unicode cChar
, bool bPrefix
)
585 rStr
.appendAscii( "\\u" );
586 appendHex( rStr
, static_cast< sal_uInt16
>( cChar
), false );
591 rStr
.appendAscii( "\\x" );
592 appendHex( rStr
, static_cast< sal_uInt8
>( cChar
), false );
596 void StringHelper::appendEncChar( OUStringBuffer
& rStr
, sal_Unicode cChar
, sal_Int32 nCount
, bool bPrefix
)
601 OUStringBuffer aCode
;
602 appendCChar( aCode
, cChar
, bPrefix
);
603 for( sal_Int32 nIdx
= 0; nIdx
< nCount
; ++nIdx
)
604 rStr
.append( aCode
);
608 appendChar( rStr
, cChar
, nCount
);
612 void StringHelper::appendEncString( OUStringBuffer
& rStr
, const OUString
& rData
, bool bPrefix
)
616 sal_Int32 nEnd
= rData
.getLength();
619 // find next character that needs encoding
620 while( (nIdx
< nEnd
) && (rData
[ nIdx
] >= 0x20) ) ++nIdx
;
624 if( (nBeg
== 0) && (nIdx
== nEnd
) )
625 rStr
.append( rData
);
627 rStr
.append( rData
.copy( nBeg
, nIdx
- nBeg
) );
629 // append characters to be encoded
630 while( (nIdx
< nEnd
) && (rData
[ nIdx
] < 0x20) )
632 appendCChar( rStr
, rData
[ nIdx
], bPrefix
);
640 // token list -----------------------------------------------------------------
642 void StringHelper::appendToken( OUStringBuffer
& rStr
, const OUString
& rToken
, sal_Unicode cSep
)
644 if( (rStr
.getLength() > 0) && (rToken
.getLength() > 0) )
646 rStr
.append( rToken
);
649 void StringHelper::appendToken( OUStringBuffer
& rStr
, sal_Int64 nToken
, sal_Unicode cSep
)
651 OUStringBuffer aToken
;
652 appendDec( aToken
, nToken
);
653 appendToken( rStr
, aToken
.makeStringAndClear(), cSep
);
656 void StringHelper::prependToken( OUStringBuffer
& rStr
, const OUString
& rToken
, sal_Unicode cSep
)
658 if( (rStr
.getLength() > 0) && (rToken
.getLength() > 0) )
659 rStr
.insert( 0, cSep
);
660 rStr
.insert( 0, rToken
);
663 void StringHelper::prependToken( OUStringBuffer
& rStr
, sal_Int64 nToken
, sal_Unicode cSep
)
665 OUStringBuffer aToken
;
666 appendDec( aToken
, nToken
);
667 prependToken( rStr
, aToken
.makeStringAndClear(), cSep
);
670 void StringHelper::appendIndex( OUStringBuffer
& rStr
, const OUString
& rIdx
)
672 rStr
.append( sal_Unicode( '[' ) ).append( rIdx
).append( sal_Unicode( ']' ) );
675 void StringHelper::appendIndex( OUStringBuffer
& rStr
, sal_Int64 nIdx
)
677 OUStringBuffer aToken
;
678 appendDec( aToken
, nIdx
);
679 appendIndex( rStr
, aToken
.makeStringAndClear() );
682 void StringHelper::appendIndexedText( OUStringBuffer
& rStr
, const OUString
& rData
, const OUString
& rIdx
)
684 rStr
.append( rData
);
685 appendIndex( rStr
, rIdx
);
688 void StringHelper::appendIndexedText( OUStringBuffer
& rStr
, const OUString
& rData
, sal_Int64 nIdx
)
690 rStr
.append( rData
);
691 appendIndex( rStr
, nIdx
);
694 OUString
StringHelper::getToken( const OUString
& rData
, sal_Int32
& rnPos
, sal_Unicode cSep
)
696 return trimSpaces( rData
.getToken( 0, cSep
, rnPos
) );
699 void StringHelper::enclose( OUStringBuffer
& rStr
, sal_Unicode cOpen
, sal_Unicode cClose
)
701 rStr
.insert( 0, cOpen
).append( cClose
? cClose
: cOpen
);
704 // string conversion ----------------------------------------------------------
708 sal_Int32
lclIndexOf( const OUString
& rStr
, sal_Unicode cChar
, sal_Int32 nStartPos
)
710 sal_Int32 nIndex
= rStr
.indexOf( cChar
, nStartPos
);
711 return (nIndex
< 0) ? rStr
.getLength() : nIndex
;
714 OUString
lclTrimQuotedStringList( const OUString
& rStr
)
716 OUStringBuffer aBuffer
;
718 sal_Int32 nLen
= rStr
.getLength();
721 if( rStr
[ nPos
] == OOX_DUMP_CFG_QUOTE
)
723 // quoted string, skip leading quote character
725 // process quoted text and ambedded literal quote characters
726 OUStringBuffer aToken
;
729 // seek to next quote character and add text portion to token buffer
730 sal_Int32 nEnd
= lclIndexOf( rStr
, OOX_DUMP_CFG_QUOTE
, nPos
);
731 aToken
.append( rStr
.copy( nPos
, nEnd
- nPos
) );
732 // process literal quotes
733 while( (nEnd
+ 1 < nLen
) && (rStr
[ nEnd
] == OOX_DUMP_CFG_QUOTE
) && (rStr
[ nEnd
+ 1 ] == OOX_DUMP_CFG_QUOTE
) )
735 aToken
.append( OOX_DUMP_CFG_QUOTE
);
738 // nEnd is start of possible next text portion
741 while( (nPos
< nLen
) && (rStr
[ nPos
] != OOX_DUMP_CFG_QUOTE
) );
742 // add token, seek to list separator, ignore text following closing quote
743 aBuffer
.append( aToken
.makeStringAndClear() );
744 nPos
= lclIndexOf( rStr
, OOX_DUMP_CFG_LISTSEP
, nPos
);
746 aBuffer
.append( OOX_DUMP_LF
);
747 // set current position behind list separator
752 // find list separator, add token text to buffer
753 sal_Int32 nEnd
= lclIndexOf( rStr
, OOX_DUMP_CFG_LISTSEP
, nPos
);
754 aBuffer
.append( rStr
.copy( nPos
, nEnd
- nPos
) );
756 aBuffer
.append( OOX_DUMP_LF
);
757 // set current position behind list separator
762 return aBuffer
.makeStringAndClear();
767 OUString
StringHelper::trimSpaces( const OUString
& rStr
)
770 while( (nBeg
< rStr
.getLength()) && ((rStr
[ nBeg
] == ' ') || (rStr
[ nBeg
] == '\t')) )
772 sal_Int32 nEnd
= rStr
.getLength();
773 while( (nEnd
> nBeg
) && ((rStr
[ nEnd
- 1 ] == ' ') || (rStr
[ nEnd
- 1 ] == '\t')) )
775 return rStr
.copy( nBeg
, nEnd
- nBeg
);
778 OString
StringHelper::convertToUtf8( const OUString
& rStr
)
780 return OUStringToOString( rStr
, RTL_TEXTENCODING_UTF8
);
783 DataType
StringHelper::convertToDataType( const OUString
& rStr
)
785 DataType eType
= DATATYPE_VOID
;
786 if( rStr
.equalsAscii( "int8" ) )
787 eType
= DATATYPE_INT8
;
788 else if( rStr
.equalsAscii( "uint8" ) )
789 eType
= DATATYPE_UINT8
;
790 else if( rStr
.equalsAscii( "int16" ) )
791 eType
= DATATYPE_INT16
;
792 else if( rStr
.equalsAscii( "uint16" ) )
793 eType
= DATATYPE_UINT16
;
794 else if( rStr
.equalsAscii( "int32" ) )
795 eType
= DATATYPE_INT32
;
796 else if( rStr
.equalsAscii( "uint32" ) )
797 eType
= DATATYPE_UINT32
;
798 else if( rStr
.equalsAscii( "int64" ) )
799 eType
= DATATYPE_INT64
;
800 else if( rStr
.equalsAscii( "uint64" ) )
801 eType
= DATATYPE_UINT64
;
802 else if( rStr
.equalsAscii( "float" ) )
803 eType
= DATATYPE_FLOAT
;
804 else if( rStr
.equalsAscii( "double" ) )
805 eType
= DATATYPE_DOUBLE
;
809 FormatType
StringHelper::convertToFormatType( const OUString
& rStr
)
811 FormatType eType
= FORMATTYPE_NONE
;
812 if( rStr
.equalsAscii( "dec" ) )
813 eType
= FORMATTYPE_DEC
;
814 else if( rStr
.equalsAscii( "hex" ) )
815 eType
= FORMATTYPE_HEX
;
816 else if( rStr
.equalsAscii( "shorthex" ) )
817 eType
= FORMATTYPE_SHORTHEX
;
818 else if( rStr
.equalsAscii( "bin" ) )
819 eType
= FORMATTYPE_BIN
;
820 else if( rStr
.equalsAscii( "fix" ) )
821 eType
= FORMATTYPE_FIX
;
822 else if( rStr
.equalsAscii( "bool" ) )
823 eType
= FORMATTYPE_BOOL
;
827 bool StringHelper::convertFromDec( sal_Int64
& ornData
, const OUString
& rData
)
830 sal_Int32 nLen
= rData
.getLength();
832 if( (nLen
> 0) && (rData
[ 0 ] == '-') )
838 for( ; nPos
< nLen
; ++nPos
)
840 sal_Unicode cChar
= rData
[ nPos
];
841 if( (cChar
< '0') || (cChar
> '9') )
843 (ornData
*= 10) += (cChar
- '0');
850 bool StringHelper::convertFromHex( sal_Int64
& ornData
, const OUString
& rData
)
853 for( sal_Int32 nPos
= 0, nLen
= rData
.getLength(); nPos
< nLen
; ++nPos
)
855 sal_Unicode cChar
= rData
[ nPos
];
856 if( ('0' <= cChar
) && (cChar
<= '9') )
858 else if( ('A' <= cChar
) && (cChar
<= 'F') )
860 else if( ('a' <= cChar
) && (cChar
<= 'f') )
864 (ornData
<<= 4) += cChar
;
869 bool StringHelper::convertStringToInt( sal_Int64
& ornData
, const OUString
& rData
)
871 if( (rData
.getLength() > 2) && (rData
[ 0 ] == '0') && ((rData
[ 1 ] == 'X') || (rData
[ 1 ] == 'x')) )
872 return convertFromHex( ornData
, rData
.copy( 2 ) );
873 return convertFromDec( ornData
, rData
);
876 bool StringHelper::convertStringToDouble( double& orfData
, const OUString
& rData
)
878 rtl_math_ConversionStatus eStatus
= rtl_math_ConversionStatus_Ok
;
880 orfData
= rtl::math::stringToDouble( rData
, '.', '\0', &eStatus
, &nSize
);
881 return (eStatus
== rtl_math_ConversionStatus_Ok
) && (nSize
== rData
.getLength());
884 bool StringHelper::convertStringToBool( const OUString
& rData
)
886 if( rData
.equalsAscii( "true" ) )
888 if( rData
.equalsAscii( "false" ) )
891 return convertStringToInt( nData
, rData
) && (nData
!= 0);
894 void StringHelper::convertStringToStringList( OUStringVector
& orVec
, const OUString
& rData
, bool bIgnoreEmpty
)
897 OUString aUnquotedData
= lclTrimQuotedStringList( rData
);
899 sal_Int32 nLen
= aUnquotedData
.getLength();
900 while( (0 <= nPos
) && (nPos
< nLen
) )
902 OUString aToken
= getToken( aUnquotedData
, nPos
, OOX_DUMP_LF
);
903 if( !bIgnoreEmpty
|| (aToken
.getLength() > 0) )
904 orVec
.push_back( aToken
);
908 void StringHelper::convertStringToIntList( Int64Vector
& orVec
, const OUString
& rData
, bool bIgnoreEmpty
)
911 OUString aUnquotedData
= lclTrimQuotedStringList( rData
);
913 sal_Int32 nLen
= aUnquotedData
.getLength();
915 while( (0 <= nPos
) && (nPos
< nLen
) )
917 bool bOk
= convertStringToInt( nData
, getToken( aUnquotedData
, nPos
, OOX_DUMP_LF
) );
918 if( !bIgnoreEmpty
|| bOk
)
919 orVec
.push_back( bOk
? nData
: 0 );
923 // ============================================================================
924 // ============================================================================
926 FormulaStack::FormulaStack() :
931 void FormulaStack::pushOperand( const String
& rOp
, const OUString
& rTokClass
)
933 maFmlaStack
.push( rOp
);
934 maClassStack
.push( rTokClass
);
937 void FormulaStack::pushOperand( const String
& rOp
)
939 pushOperand( rOp
, OUString( OOX_DUMP_BASECLASS
) );
942 void FormulaStack::pushUnaryOp( const String
& rLOp
, const String
& rROp
)
944 pushUnaryOp( maFmlaStack
, rLOp
, rROp
);
945 pushUnaryOp( maClassStack
, rLOp
, rROp
);
948 void FormulaStack::pushBinaryOp( const String
& rOp
)
950 pushBinaryOp( maFmlaStack
, rOp
);
951 pushBinaryOp( maClassStack
, rOp
);
954 void FormulaStack::pushFuncOp( const String
& rFunc
, const OUString
& rTokClass
, sal_uInt8 nParamCount
)
956 pushFuncOp( maFmlaStack
, rFunc
, nParamCount
);
957 pushFuncOp( maClassStack
, rTokClass
, nParamCount
);
960 void FormulaStack::replaceOnTop( const OUString
& rOld
, const OUString
& rNew
)
962 if( !maFmlaStack
.empty() )
964 sal_Int32 nPos
= maFmlaStack
.top().indexOf( rOld
);
966 maFmlaStack
.top() = maFmlaStack
.top().copy( 0, nPos
) + rNew
+ maFmlaStack
.top().copy( nPos
+ rOld
.getLength() );
970 const OUString
& FormulaStack::getString( const StringStack
& rStack
) const
972 static const OUString saStackError
= OOX_DUMP_ERRSTRING( "stack" );
973 return (mbError
|| rStack
.empty()) ? saStackError
: rStack
.top();
976 void FormulaStack::pushUnaryOp( StringStack
& rStack
, const OUString
& rLOp
, const OUString
& rROp
)
978 if( check( !rStack
.empty() ) )
979 rStack
.top() = rLOp
+ rStack
.top() + rROp
;
982 void FormulaStack::pushBinaryOp( StringStack
& rStack
, const OUString
& rOp
)
985 if( check( !rStack
.empty() ) )
987 aSecond
= rStack
.top();
990 if( check( !rStack
.empty() ) )
991 rStack
.top() = rStack
.top() + rOp
+ aSecond
;
994 void FormulaStack::pushFuncOp( StringStack
& rStack
, const OUString
& rOp
, sal_uInt8 nParamCount
)
996 OUStringBuffer aFunc
;
997 for( sal_uInt8 nParam
= 0; (nParam
< nParamCount
) && check( !rStack
.empty() ); ++nParam
)
999 StringHelper::prependToken( aFunc
, rStack
.top(), OOX_DUMP_FUNCSEP
);
1002 StringHelper::enclose( aFunc
, '(', ')' );
1003 aFunc
.insert( 0, rOp
);
1004 rStack
.push( aFunc
.makeStringAndClear() );
1007 // ============================================================================
1008 // ============================================================================
1014 // ============================================================================
1015 // ============================================================================
1017 ConfigItemBase::~ConfigItemBase()
1021 void ConfigItemBase::readConfigBlock( const ConfigInputStreamRef
& rxStrm
)
1023 readConfigBlockContents( rxStrm
);
1026 void ConfigItemBase::implProcessConfigItemStr(
1027 const ConfigInputStreamRef
& /*rxStrm*/, const OUString
& /*rKey*/, const OUString
& /*rData*/ )
1031 void ConfigItemBase::implProcessConfigItemInt(
1032 const ConfigInputStreamRef
& /*rxStrm*/, sal_Int64
/*nKey*/, const OUString
& /*rData*/ )
1036 void ConfigItemBase::readConfigBlockContents( const ConfigInputStreamRef
& rxStrm
)
1039 while( bLoop
&& !rxStrm
->isEOF() )
1041 OUString aKey
, aData
;
1042 switch( readConfigLine( rxStrm
, aKey
, aData
) )
1045 processConfigItem( rxStrm
, aKey
, aData
);
1054 ConfigItemBase::LineType
ConfigItemBase::readConfigLine(
1055 const ConfigInputStreamRef
& rxStrm
, OUString
& orKey
, OUString
& orData
) const
1058 while( !rxStrm
->isEOF() && (aLine
.getLength() == 0) )
1060 try { aLine
= rxStrm
->readLine(); } catch( Exception
& ) { aLine
= OUString(); }
1061 if( (aLine
.getLength() > 0) && (aLine
[ 0 ] == OOX_DUMP_BOM
) )
1062 aLine
= aLine
.copy( 1 );
1063 aLine
= StringHelper::trimSpaces( aLine
);
1064 if( aLine
.getLength() > 0 )
1066 // ignore comments (starting with hash or semicolon)
1067 sal_Unicode cChar
= aLine
[ 0 ];
1068 if( (cChar
== '#') || (cChar
== ';') )
1073 LineType eResult
= LINETYPE_END
;
1074 if( aLine
.getLength() > 0 )
1076 sal_Int32 nEqPos
= aLine
.indexOf( '=' );
1083 orKey
= StringHelper::trimSpaces( aLine
.copy( 0, nEqPos
) );
1084 orData
= StringHelper::trimSpaces( aLine
.copy( nEqPos
+ 1 ) );
1087 if( (orKey
.getLength() > 0) && ((orData
.getLength() > 0) || !orKey
.equalsAscii( "end" )) )
1088 eResult
= LINETYPE_DATA
;
1094 ConfigItemBase::LineType
ConfigItemBase::readConfigLine( const ConfigInputStreamRef
& rxStrm
) const
1096 OUString aKey
, aData
;
1097 return readConfigLine( rxStrm
, aKey
, aData
);
1100 void ConfigItemBase::processConfigItem(
1101 const ConfigInputStreamRef
& rxStrm
, const OUString
& rKey
, const OUString
& rData
)
1104 if( StringHelper::convertStringToInt( nKey
, rKey
) )
1105 implProcessConfigItemInt( rxStrm
, nKey
, rData
);
1107 implProcessConfigItemStr( rxStrm
, rKey
, rData
);
1110 // ============================================================================
1112 NameListBase::~NameListBase()
1116 void NameListBase::setName( sal_Int64 nKey
, const String
& rName
)
1118 implSetName( nKey
, rName
);
1121 void NameListBase::includeList( const NameListRef
& rxList
)
1125 for( const_iterator aIt
= rxList
->begin(), aEnd
= rxList
->end(); aIt
!= aEnd
; ++aIt
)
1126 maMap
[ aIt
->first
] = aIt
->second
;
1127 implIncludeList( *rxList
);
1131 bool NameListBase::implIsValid() const
1136 void NameListBase::implProcessConfigItemStr(
1137 const ConfigInputStreamRef
& rxStrm
, const OUString
& rKey
, const OUString
& rData
)
1139 if( rKey
.equalsAscii( "include" ) )
1141 else if( rKey
.equalsAscii( "exclude" ) )
1144 ConfigItemBase::implProcessConfigItemStr( rxStrm
, rKey
, rData
);
1147 void NameListBase::implProcessConfigItemInt(
1148 const ConfigInputStreamRef
& /*rxStrm*/, sal_Int64 nKey
, const OUString
& rData
)
1150 implSetName( nKey
, rData
);
1153 void NameListBase::insertRawName( sal_Int64 nKey
, const OUString
& rName
)
1155 maMap
[ nKey
] = rName
;
1158 const OUString
* NameListBase::findRawName( sal_Int64 nKey
) const
1160 const_iterator aIt
= maMap
.find( nKey
);
1161 return (aIt
== end()) ? 0 : &aIt
->second
;
1164 void NameListBase::include( const OUString
& rListKeys
)
1166 OUStringVector aVec
;
1167 StringHelper::convertStringToStringList( aVec
, rListKeys
, true );
1168 for( OUStringVector::const_iterator aIt
= aVec
.begin(), aEnd
= aVec
.end(); aIt
!= aEnd
; ++aIt
)
1169 includeList( mrCfgData
.getNameList( *aIt
) );
1172 void NameListBase::exclude( const OUString
& rKeys
)
1175 StringHelper::convertStringToIntList( aVec
, rKeys
, true );
1176 for( Int64Vector::const_iterator aIt
= aVec
.begin(), aEnd
= aVec
.end(); aIt
!= aEnd
; ++aIt
)
1177 maMap
.erase( *aIt
);
1180 // ============================================================================
1182 ConstList::ConstList( const SharedConfigData
& rCfgData
) :
1183 NameListBase( rCfgData
),
1184 maDefName( OOX_DUMP_ERR_NONAME
),
1185 mbQuoteNames( false )
1189 void ConstList::implProcessConfigItemStr(
1190 const ConfigInputStreamRef
& rxStrm
, const OUString
& rKey
, const OUString
& rData
)
1192 if( rKey
.equalsAscii( "default" ) )
1193 setDefaultName( rData
);
1194 else if( rKey
.equalsAscii( "quote-names" ) )
1195 setQuoteNames( StringHelper::convertStringToBool( rData
) );
1197 NameListBase::implProcessConfigItemStr( rxStrm
, rKey
, rData
);
1200 void ConstList::implSetName( sal_Int64 nKey
, const OUString
& rName
)
1202 insertRawName( nKey
, rName
);
1205 OUString
ConstList::implGetName( const Config
& /*rCfg*/, sal_Int64 nKey
) const
1207 const OUString
* pName
= findRawName( nKey
);
1208 OUString aName
= pName
? *pName
: maDefName
;
1211 OUStringBuffer
aBuffer( aName
);
1212 StringHelper::enclose( aBuffer
, OOX_DUMP_STRQUOTE
);
1213 aName
= aBuffer
.makeStringAndClear();
1218 OUString
ConstList::implGetNameDbl( const Config
& /*rCfg*/, double /*fValue*/ ) const
1223 void ConstList::implIncludeList( const NameListBase
& rList
)
1225 if( const ConstList
* pConstList
= dynamic_cast< const ConstList
* >( &rList
) )
1227 maDefName
= pConstList
->maDefName
;
1228 mbQuoteNames
= pConstList
->mbQuoteNames
;
1232 // ============================================================================
1234 MultiList::MultiList( const SharedConfigData
& rCfgData
) :
1235 ConstList( rCfgData
),
1236 mbIgnoreEmpty( true )
1240 void MultiList::setNamesFromVec( sal_Int64 nStartKey
, const OUStringVector
& rNames
)
1242 sal_Int64 nKey
= nStartKey
;
1243 for( OUStringVector::const_iterator aIt
= rNames
.begin(), aEnd
= rNames
.end(); aIt
!= aEnd
; ++aIt
, ++nKey
)
1244 if( !mbIgnoreEmpty
|| (aIt
->getLength() > 0) )
1245 insertRawName( nKey
, *aIt
);
1248 void MultiList::implProcessConfigItemStr(
1249 const ConfigInputStreamRef
& rxStrm
, const OUString
& rKey
, const OUString
& rData
)
1251 if( rKey
.equalsAscii( "ignore-empty" ) )
1252 mbIgnoreEmpty
= StringHelper::convertStringToBool( rData
);
1254 ConstList::implProcessConfigItemStr( rxStrm
, rKey
, rData
);
1257 void MultiList::implSetName( sal_Int64 nKey
, const OUString
& rName
)
1259 OUStringVector aNames
;
1260 StringHelper::convertStringToStringList( aNames
, rName
, false );
1261 setNamesFromVec( nKey
, aNames
);
1264 // ============================================================================
1266 FlagsList::FlagsList( const SharedConfigData
& rCfgData
) :
1267 NameListBase( rCfgData
),
1272 void FlagsList::implProcessConfigItemStr(
1273 const ConfigInputStreamRef
& rxStrm
, const OUString
& rKey
, const OUString
& rData
)
1275 if( rKey
.equalsAscii( "ignore" ) )
1278 if( StringHelper::convertStringToInt( nIgnore
, rData
) )
1279 setIgnoreFlags( nIgnore
);
1283 NameListBase::implProcessConfigItemStr( rxStrm
, rKey
, rData
);
1287 void FlagsList::implSetName( sal_Int64 nKey
, const OUString
& rName
)
1289 insertRawName( nKey
, rName
);
1292 OUString
FlagsList::implGetName( const Config
& /*rCfg*/, sal_Int64 nKey
) const
1294 sal_Int64 nFlags
= nKey
;
1295 setFlag( nFlags
, mnIgnore
, false );
1296 sal_Int64 nFound
= 0;
1297 OUStringBuffer aName
;
1299 for( const_iterator aIt
= begin(), aEnd
= end(); aIt
!= aEnd
; ++aIt
)
1301 sal_Int64 nMask
= aIt
->first
;
1302 const OUString
& rFlagName
= aIt
->second
;
1303 bool bNegated
= (rFlagName
.getLength() > 0) && (rFlagName
[ 0 ] == '!');
1304 sal_Int32 nBothSep
= bNegated
? rFlagName
.indexOf( '!', 1 ) : -1;
1305 bool bFlag
= getFlag( nFlags
, nMask
);
1309 StringHelper::appendToken( aName
, rFlagName
);
1310 else if( nBothSep
> 0 )
1311 StringHelper::appendToken( aName
, rFlagName
.copy( nBothSep
+ 1 ) );
1316 StringHelper::appendToken( aName
, rFlagName
.copy( 1, nBothSep
- 1 ) );
1318 StringHelper::appendToken( aName
, rFlagName
.copy( 1 ) );
1320 setFlag( nFound
, nMask
);
1322 // add unknown flags
1323 setFlag( nFlags
, nFound
, false );
1326 OUStringBuffer
aUnknown( CREATE_OUSTRING( OOX_DUMP_UNKNOWN
) );
1327 aUnknown
.append( OOX_DUMP_ITEMSEP
);
1328 StringHelper::appendShortHex( aUnknown
, nFlags
, true );
1329 StringHelper::enclose( aUnknown
, '(', ')' );
1330 StringHelper::appendToken( aName
, aUnknown
.makeStringAndClear() );
1332 return aName
.makeStringAndClear();
1335 OUString
FlagsList::implGetNameDbl( const Config
& /*rCfg*/, double /*fValue*/ ) const
1340 void FlagsList::implIncludeList( const NameListBase
& rList
)
1342 if( const FlagsList
* pFlagsList
= dynamic_cast< const FlagsList
* >( &rList
) )
1343 mnIgnore
= pFlagsList
->mnIgnore
;
1346 // ============================================================================
1348 CombiList::CombiList( const SharedConfigData
& rCfgData
) :
1349 FlagsList( rCfgData
)
1353 void CombiList::implSetName( sal_Int64 nKey
, const OUString
& rName
)
1355 if( (nKey
& (nKey
- 1)) != 0 ) // more than a single bit set?
1357 ExtItemFormat
& rItemFmt
= maFmtMap
[ nKey
];
1358 OUStringVector aRemain
= rItemFmt
.parse( rName
);
1359 rItemFmt
.mbShiftValue
= aRemain
.empty() || !aRemain
.front().equalsAscii( "noshift" );
1363 FlagsList::implSetName( nKey
, rName
);
1367 OUString
CombiList::implGetName( const Config
& rCfg
, sal_Int64 nKey
) const
1369 sal_Int64 nFlags
= nKey
;
1370 sal_Int64 nFound
= 0;
1371 OUStringBuffer aName
;
1372 // add known flag fields
1373 for( ExtItemFormatMap::const_iterator aIt
= maFmtMap
.begin(), aEnd
= maFmtMap
.end(); aIt
!= aEnd
; ++aIt
)
1375 sal_Int64 nMask
= aIt
->first
;
1378 const ExtItemFormat
& rItemFmt
= aIt
->second
;
1380 sal_uInt64 nUFlags
= static_cast< sal_uInt64
>( nFlags
);
1381 sal_uInt64 nUMask
= static_cast< sal_uInt64
>( nMask
);
1382 if( rItemFmt
.mbShiftValue
)
1383 while( (nUMask
& 1) == 0 ) { nUFlags
>>= 1; nUMask
>>= 1; }
1385 sal_uInt64 nUValue
= nUFlags
& nUMask
;
1386 sal_Int64 nSValue
= static_cast< sal_Int64
>( nUValue
);
1387 if( getFlag
< sal_uInt64
>( nUValue
, (nUMask
+ 1) >> 1 ) )
1388 setFlag( nSValue
, static_cast< sal_Int64
>( ~nUMask
) );
1390 OUStringBuffer
aItem( rItemFmt
.maItemName
);
1391 OUStringBuffer aValue
;
1392 switch( rItemFmt
.meDataType
)
1394 case DATATYPE_INT8
: StringHelper::appendValue( aValue
, static_cast< sal_Int8
>( nSValue
), rItemFmt
.meFmtType
); break;
1395 case DATATYPE_UINT8
: StringHelper::appendValue( aValue
, static_cast< sal_uInt8
>( nUValue
), rItemFmt
.meFmtType
); break;
1396 case DATATYPE_INT16
: StringHelper::appendValue( aValue
, static_cast< sal_Int16
>( nSValue
), rItemFmt
.meFmtType
); break;
1397 case DATATYPE_UINT16
: StringHelper::appendValue( aValue
, static_cast< sal_uInt16
>( nUValue
), rItemFmt
.meFmtType
); break;
1398 case DATATYPE_INT32
: StringHelper::appendValue( aValue
, static_cast< sal_Int32
>( nSValue
), rItemFmt
.meFmtType
); break;
1399 case DATATYPE_UINT32
: StringHelper::appendValue( aValue
, static_cast< sal_uInt32
>( nUValue
), rItemFmt
.meFmtType
); break;
1400 case DATATYPE_INT64
: StringHelper::appendValue( aValue
, nSValue
, rItemFmt
.meFmtType
); break;
1401 case DATATYPE_UINT64
: StringHelper::appendValue( aValue
, nUValue
, rItemFmt
.meFmtType
); break;
1402 case DATATYPE_FLOAT
: StringHelper::appendValue( aValue
, static_cast< float >( nSValue
), rItemFmt
.meFmtType
); break;
1403 case DATATYPE_DOUBLE
: StringHelper::appendValue( aValue
, static_cast< double >( nSValue
), rItemFmt
.meFmtType
); break;
1406 StringHelper::appendToken( aItem
, aValue
.makeStringAndClear(), OOX_DUMP_ITEMSEP
);
1407 if( rItemFmt
.maListName
.getLength() > 0 )
1409 OUString aValueName
= rCfg
.getName( rItemFmt
.maListName
, static_cast< sal_Int64
>( nUValue
) );
1410 StringHelper::appendToken( aItem
, aValueName
, OOX_DUMP_ITEMSEP
);
1412 StringHelper::enclose( aItem
, '(', ')' );
1413 StringHelper::appendToken( aName
, aItem
.makeStringAndClear() );
1414 setFlag( nFound
, nMask
);
1417 setFlag( nFlags
, nFound
, false );
1418 StringHelper::appendToken( aName
, FlagsList::implGetName( rCfg
, nFlags
) );
1419 return aName
.makeStringAndClear();
1422 void CombiList::implIncludeList( const NameListBase
& rList
)
1424 if( const CombiList
* pCombiList
= dynamic_cast< const CombiList
* >( &rList
) )
1425 maFmtMap
= pCombiList
->maFmtMap
;
1426 FlagsList::implIncludeList( rList
);
1429 // ============================================================================
1431 UnitConverter::UnitConverter( const SharedConfigData
& rCfgData
) :
1432 NameListBase( rCfgData
),
1437 void UnitConverter::implSetName( sal_Int64
/*nKey*/, const OUString
& /*rName*/ )
1442 OUString
UnitConverter::implGetName( const Config
& rCfg
, sal_Int64 nKey
) const
1444 return implGetNameDbl( rCfg
, static_cast< double >( nKey
) );
1447 OUString
UnitConverter::implGetNameDbl( const Config
& /*rCfg*/, double fValue
) const
1449 OUStringBuffer aValue
;
1450 StringHelper::appendDec( aValue
, mfFactor
* fValue
);
1451 aValue
.append( maUnitName
);
1452 return aValue
.makeStringAndClear();
1455 void UnitConverter::implIncludeList( const NameListBase
& /*rList*/ )
1459 // ============================================================================
1461 NameListRef
NameListWrapper::getNameList( const Config
& rCfg
) const
1463 return mxList
.get() ? mxList
: (mxList
= rCfg
.getNameList( maName
));
1466 // ============================================================================
1467 // ============================================================================
1469 SharedConfigData::SharedConfigData( const OUString
& rFileName
,
1470 const Reference
< XMultiServiceFactory
>& rxFactory
, const StorageRef
& rxRootStrg
,
1471 const OUString
& rSysFileName
, MediaDescriptor
& rMediaDesc
) :
1472 mxFactory( rxFactory
),
1473 mxRootStrg( rxRootStrg
),
1474 maSysFileName( rSysFileName
),
1475 mrMediaDesc( rMediaDesc
),
1477 mbPwCancelled( false )
1479 OUString aFileUrl
= InputOutputHelper::convertFileNameToUrl( rFileName
);
1480 if( aFileUrl
.getLength() > 0 )
1482 sal_Int32 nNamePos
= InputOutputHelper::getFileNamePos( aFileUrl
);
1483 maConfigPath
= aFileUrl
.copy( 0, nNamePos
);
1484 mbLoaded
= readConfigFile( aFileUrl
);
1488 SharedConfigData::~SharedConfigData()
1492 void SharedConfigData::setOption( const OUString
& rKey
, const OUString
& rData
)
1494 maConfigData
[ rKey
] = rData
;
1497 const OUString
* SharedConfigData::getOption( const OUString
& rKey
) const
1499 ConfigDataMap::const_iterator aIt
= maConfigData
.find( rKey
);
1500 return (aIt
== maConfigData
.end()) ? 0 : &aIt
->second
;
1503 void SharedConfigData::setNameList( const OUString
& rListName
, const NameListRef
& rxList
)
1505 if( rListName
.getLength() > 0 )
1506 maNameLists
[ rListName
] = rxList
;
1509 void SharedConfigData::eraseNameList( const OUString
& rListName
)
1511 maNameLists
.erase( rListName
);
1514 NameListRef
SharedConfigData::getNameList( const OUString
& rListName
) const
1517 NameListMap::const_iterator aIt
= maNameLists
.find( rListName
);
1518 if( aIt
!= maNameLists
.end() )
1519 xList
= aIt
->second
;
1523 OUString
SharedConfigData::requestPassword( ::comphelper::IDocPasswordVerifier
& rVerifier
)
1526 if( !mbPwCancelled
)
1528 ::std::vector
< OUString
> aDefaultPasswords
;
1529 aDefaultPasswords
.push_back( CREATE_OUSTRING( "VelvetSweatshop" ) );
1530 aPassword
= ::comphelper::DocPasswordHelper::requestAndVerifyDocPassword(
1531 rVerifier
, mrMediaDesc
, ::comphelper::DocPasswordRequestType_MS
, &aDefaultPasswords
);
1532 mbPwCancelled
= aPassword
.getLength() == 0;
1537 bool SharedConfigData::implIsValid() const
1539 return mbLoaded
&& mxFactory
.is() && mxRootStrg
.get() && (maSysFileName
.getLength() > 0);
1542 void SharedConfigData::implProcessConfigItemStr(
1543 const ConfigInputStreamRef
& rxStrm
, const OUString
& rKey
, const OUString
& rData
)
1545 if( rKey
.equalsAscii( "include-config-file" ) )
1546 readConfigFile( maConfigPath
+ rData
);
1547 else if( rKey
.equalsAscii( "constlist" ) )
1548 readNameList
< ConstList
>( rxStrm
, rData
);
1549 else if( rKey
.equalsAscii( "multilist" ) )
1550 readNameList
< MultiList
>( rxStrm
, rData
);
1551 else if( rKey
.equalsAscii( "flagslist" ) )
1552 readNameList
< FlagsList
>( rxStrm
, rData
);
1553 else if( rKey
.equalsAscii( "combilist" ) )
1554 readNameList
< CombiList
>( rxStrm
, rData
);
1555 else if( rKey
.equalsAscii( "shortlist" ) )
1556 createShortList( rData
);
1557 else if( rKey
.equalsAscii( "unitconverter" ) )
1558 createUnitConverter( rData
);
1560 setOption( rKey
, rData
);
1563 bool SharedConfigData::readConfigFile( const OUString
& rFileUrl
)
1565 bool bLoaded
= maConfigFiles
.count( rFileUrl
) > 0;
1568 Reference
< XTextInputStream
> xTextInStrm
=
1569 InputOutputHelper::openTextInputStream( mxFactory
, rFileUrl
, CREATE_OUSTRING( "UTF-8" ) );
1570 if( xTextInStrm
.is() )
1572 maConfigFiles
.insert( rFileUrl
);
1573 readConfigBlockContents( xTextInStrm
);
1580 void SharedConfigData::createShortList( const OUString
& rData
)
1582 OUStringVector aDataVec
;
1583 StringHelper::convertStringToStringList( aDataVec
, rData
, false );
1584 if( aDataVec
.size() >= 3 )
1586 sal_Int64 nStartKey
;
1587 if( StringHelper::convertStringToInt( nStartKey
, aDataVec
[ 1 ] ) )
1589 ::boost::shared_ptr
< MultiList
> xList
= createNameList
< MultiList
>( aDataVec
[ 0 ] );
1592 aDataVec
.erase( aDataVec
.begin(), aDataVec
.begin() + 2 );
1593 xList
->setNamesFromVec( nStartKey
, aDataVec
);
1599 void SharedConfigData::createUnitConverter( const OUString
& rData
)
1601 OUStringVector aDataVec
;
1602 StringHelper::convertStringToStringList( aDataVec
, rData
, false );
1603 if( aDataVec
.size() >= 2 )
1605 OUString aFactor
= aDataVec
[ 1 ];
1606 bool bRecip
= (aFactor
.getLength() > 0) && (aFactor
[ 0 ] == '/');
1608 aFactor
= aFactor
.copy( 1 );
1610 if( StringHelper::convertStringToDouble( fFactor
, aFactor
) && (fFactor
!= 0.0) )
1612 ::boost::shared_ptr
< UnitConverter
> xList
= createNameList
< UnitConverter
>( aDataVec
[ 0 ] );
1615 xList
->setFactor( bRecip
? (1.0 / fFactor
) : fFactor
);
1616 if( aDataVec
.size() >= 3 )
1617 xList
->setUnitName( aDataVec
[ 2 ] );
1623 // ============================================================================
1625 Config::Config( const Config
& rParent
) :
1626 Base() // c'tor needs to be called explicitly to avoid compiler warning
1628 construct( rParent
);
1631 Config::Config( const sal_Char
* pcEnvVar
, const FilterBase
& rFilter
)
1633 construct( pcEnvVar
, rFilter
);
1636 Config::Config( const sal_Char
* pcEnvVar
, const Reference
< XMultiServiceFactory
>& rxFactory
, const StorageRef
& rxRootStrg
, const OUString
& rSysFileName
, MediaDescriptor
& rMediaDesc
)
1638 construct( pcEnvVar
, rxFactory
, rxRootStrg
, rSysFileName
, rMediaDesc
);
1645 void Config::construct( const Config
& rParent
)
1650 void Config::construct( const sal_Char
* pcEnvVar
, const FilterBase
& rFilter
)
1652 if( rFilter
.getFileUrl().getLength() > 0 )
1653 construct( pcEnvVar
, rFilter
.getGlobalFactory(), rFilter
.getStorage(), rFilter
.getFileUrl(), rFilter
.getMediaDescriptor() );
1656 void Config::construct( const sal_Char
* pcEnvVar
, const Reference
< XMultiServiceFactory
>& rxFactory
, const StorageRef
& rxRootStrg
, const OUString
& rSysFileName
, MediaDescriptor
& rMediaDesc
)
1658 if( pcEnvVar
&& rxRootStrg
.get() && (rSysFileName
.getLength() > 0) )
1659 if( const sal_Char
* pcFileName
= ::getenv( pcEnvVar
) )
1660 mxCfgData
.reset( new SharedConfigData( OUString::createFromAscii( pcFileName
), rxFactory
, rxRootStrg
, rSysFileName
, rMediaDesc
) );
1663 void Config::setStringOption( const String
& rKey
, const String
& rData
)
1665 mxCfgData
->setOption( rKey
, rData
);
1668 const OUString
& Config::getStringOption( const String
& rKey
, const OUString
& rDefault
) const
1670 const OUString
* pData
= implGetOption( rKey
);
1671 return pData
? *pData
: rDefault
;
1674 bool Config::getBoolOption( const String
& rKey
, bool bDefault
) const
1676 const OUString
* pData
= implGetOption( rKey
);
1677 return pData
? StringHelper::convertStringToBool( *pData
) : bDefault
;
1680 bool Config::isDumperEnabled() const
1682 return getBoolOption( "enable-dumper", false );
1685 bool Config::isImportEnabled() const
1687 return getBoolOption( "enable-import", true );
1690 void Config::setNameList( const String
& rListName
, const NameListRef
& rxList
)
1692 mxCfgData
->setNameList( rListName
, rxList
);
1695 void Config::eraseNameList( const String
& rListName
)
1697 mxCfgData
->eraseNameList( rListName
);
1700 NameListRef
Config::getNameList( const String
& rListName
) const
1702 return implGetNameList( rListName
);
1705 OUString
Config::requestPassword( ::comphelper::IDocPasswordVerifier
& rVerifier
)
1707 return mxCfgData
->requestPassword( rVerifier
);
1710 bool Config::isPasswordCancelled() const
1712 return mxCfgData
->isPasswordCancelled();
1715 bool Config::implIsValid() const
1717 return isValid( mxCfgData
);
1720 const OUString
* Config::implGetOption( const OUString
& rKey
) const
1722 return mxCfgData
->getOption( rKey
);
1725 NameListRef
Config::implGetNameList( const OUString
& rListName
) const
1727 return mxCfgData
->getNameList( rListName
);
1730 // ============================================================================
1731 // ============================================================================
1733 Output::Output( const Reference
< XTextOutputStream
>& rxStrm
)
1735 construct( rxStrm
);
1738 Output::Output( const Reference
< XMultiServiceFactory
>& rxFactory
, const OUString
& rFileName
)
1740 construct( InputOutputHelper::openTextOutputStream( rxFactory
, rFileName
, CREATE_OUSTRING( "UTF-8" ) ) );
1743 // ----------------------------------------------------------------------------
1745 void Output::newLine()
1747 if( maLine
.getLength() > 0 )
1749 mxStrm
->writeString( maIndent
);
1750 maLine
.append( sal_Unicode( '\n' ) );
1751 mxStrm
->writeString( maLine
.makeStringAndClear() );
1757 void Output::emptyLine( size_t nCount
)
1759 for( size_t nIdx
= 0; nIdx
< nCount
; ++nIdx
)
1760 mxStrm
->writeString( OUString( sal_Unicode( '\n' ) ) );
1763 void Output::incIndent()
1765 OUStringBuffer
aBuffer( maIndent
);
1766 StringHelper::appendChar( aBuffer
, ' ', OOX_DUMP_INDENT
);
1767 maIndent
= aBuffer
.makeStringAndClear();
1770 void Output::decIndent()
1772 if( maIndent
.getLength() >= OOX_DUMP_INDENT
)
1773 maIndent
= maIndent
.copy( OOX_DUMP_INDENT
);
1776 void Output::resetIndent()
1778 maIndent
= OUString();
1781 void Output::startTable( sal_Int32 nW1
)
1783 startTable( 1, &nW1
);
1786 void Output::startTable( sal_Int32 nW1
, sal_Int32 nW2
)
1788 sal_Int32 pnColWidths
[ 2 ];
1789 pnColWidths
[ 0 ] = nW1
;
1790 pnColWidths
[ 1 ] = nW2
;
1791 startTable( 2, pnColWidths
);
1794 void Output::startTable( sal_Int32 nW1
, sal_Int32 nW2
, sal_Int32 nW3
)
1796 sal_Int32 pnColWidths
[ 3 ];
1797 pnColWidths
[ 0 ] = nW1
;
1798 pnColWidths
[ 1 ] = nW2
;
1799 pnColWidths
[ 2 ] = nW3
;
1800 startTable( 3, pnColWidths
);
1803 void Output::startTable( sal_Int32 nW1
, sal_Int32 nW2
, sal_Int32 nW3
, sal_Int32 nW4
)
1805 sal_Int32 pnColWidths
[ 4 ];
1806 pnColWidths
[ 0 ] = nW1
;
1807 pnColWidths
[ 1 ] = nW2
;
1808 pnColWidths
[ 2 ] = nW3
;
1809 pnColWidths
[ 3 ] = nW4
;
1810 startTable( 4, pnColWidths
);
1813 void Output::startTable( size_t nColCount
, const sal_Int32
* pnColWidths
)
1816 maColPos
.push_back( 0 );
1817 sal_Int32 nColPos
= 0;
1818 for( size_t nCol
= 0; nCol
< nColCount
; ++nCol
)
1820 nColPos
= nColPos
+ pnColWidths
[ nCol
];
1821 maColPos
.push_back( nColPos
);
1830 void Output::tab( size_t nCol
)
1833 if( mnCol
< maColPos
.size() )
1835 sal_Int32 nColPos
= maColPos
[ mnCol
];
1836 if( maLine
.getLength() >= nColPos
)
1837 maLine
.setLength( ::std::max
< sal_Int32
>( nColPos
- 1, 0 ) );
1838 StringHelper::appendChar( maLine
, ' ', nColPos
- maLine
.getLength() );
1842 StringHelper::appendChar( maLine
, ' ', 2 );
1846 void Output::endTable()
1851 void Output::resetItemIndex( sal_Int64 nIdx
)
1856 void Output::startItem( const String
& rItemName
)
1858 if( mnItemLevel
== 0 )
1860 if( (mnMultiLevel
> 0) && (maLine
.getLength() > 0) )
1862 if( rItemName
.has() )
1864 writeItemName( rItemName
);
1865 writeChar( OOX_DUMP_ITEMSEP
);
1869 mnLastItem
= maLine
.getLength();
1872 void Output::contItem()
1874 if( mnItemLevel
> 0 )
1876 if( (maLine
.getLength() == 0) || (maLine
[ maLine
.getLength() - 1 ] != OOX_DUMP_ITEMSEP
) )
1877 writeChar( OOX_DUMP_ITEMSEP
);
1878 mnLastItem
= maLine
.getLength();
1882 void Output::endItem()
1884 if( mnItemLevel
> 0 )
1886 maLastItem
= OUString( maLine
.getStr() + mnLastItem
);
1887 if( (maLastItem
.getLength() == 0) && (mnLastItem
> 0) && (maLine
[ mnLastItem
- 1 ] == OOX_DUMP_ITEMSEP
) )
1888 maLine
.setLength( mnLastItem
- 1 );
1891 if( mnItemLevel
== 0 )
1893 if( mnMultiLevel
== 0 )
1900 void Output::startMultiItems()
1905 void Output::endMultiItems()
1907 if( mnMultiLevel
> 0 )
1909 if( mnMultiLevel
== 0 )
1913 // ----------------------------------------------------------------------------
1915 void Output::writeChar( sal_Unicode cChar
, sal_Int32 nCount
)
1917 StringHelper::appendEncChar( maLine
, cChar
, nCount
);
1920 void Output::writeAscii( const sal_Char
* pcStr
)
1923 maLine
.appendAscii( pcStr
);
1926 void Output::writeString( const OUString
& rStr
)
1928 StringHelper::appendEncString( maLine
, rStr
);
1931 void Output::writeArray( const sal_uInt8
* pnData
, sal_Size nSize
, sal_Unicode cSep
)
1933 const sal_uInt8
* pnEnd
= pnData
? (pnData
+ nSize
) : 0;
1934 for( const sal_uInt8
* pnByte
= pnData
; pnByte
< pnEnd
; ++pnByte
)
1936 if( pnByte
> pnData
)
1938 writeHex( *pnByte
, false );
1942 void Output::writeBool( bool bData
)
1944 StringHelper::appendBool( maLine
, bData
);
1947 void Output::writeColorABGR( sal_Int32 nColor
)
1950 writeDec( static_cast< sal_uInt8
>( nColor
>> 24 ) );
1952 writeDec( static_cast< sal_uInt8
>( nColor
) );
1954 writeDec( static_cast< sal_uInt8
>( nColor
>> 8 ) );
1956 writeDec( static_cast< sal_uInt8
>( nColor
>> 16 ) );
1959 void Output::writeDateTime( const DateTime
& rDateTime
)
1961 writeDec( rDateTime
.Year
, 4, '0' );
1963 writeDec( rDateTime
.Month
, 2, '0' );
1965 writeDec( rDateTime
.Day
, 2, '0' );
1967 writeDec( rDateTime
.Hours
, 2, '0' );
1969 writeDec( rDateTime
.Minutes
, 2, '0' );
1971 writeDec( rDateTime
.Seconds
, 2, '0' );
1974 void Output::writeColIndex( sal_Int32 nCol
)
1976 StringHelper::appendAddrCol( maLine
, nCol
, true );
1979 void Output::writeRowIndex( sal_Int32 nRow
)
1981 StringHelper::appendAddrRow( maLine
, nRow
, true );
1984 void Output::writeColRowRange( sal_Int32 nColRow1
, sal_Int32 nColRow2
)
1986 writeDec( nColRow1
);
1987 writeChar( OOX_DUMP_RANGESEP
);
1988 writeDec( nColRow2
);
1991 void Output::writeColRange( sal_Int32 nCol1
, sal_Int32 nCol2
)
1993 writeColIndex( nCol1
);
1994 writeChar( OOX_DUMP_RANGESEP
);
1995 writeColIndex( nCol2
);
1998 void Output::writeRowRange( sal_Int32 nRow1
, sal_Int32 nRow2
)
2000 writeRowIndex( nRow1
);
2001 writeChar( OOX_DUMP_RANGESEP
);
2002 writeRowIndex( nRow2
);
2005 void Output::writeAddress( const Address
& rPos
)
2007 StringHelper::appendAddress( maLine
, rPos
);
2010 void Output::writeRange( const Range
& rRange
)
2012 StringHelper::appendRange( maLine
, rRange
);
2015 void Output::writeRangeList( const RangeList
& rRanges
)
2017 StringHelper::appendRangeList( maLine
, rRanges
);
2020 // ----------------------------------------------------------------------------
2022 void Output::construct( const Reference
< XTextOutputStream
>& rxStrm
)
2025 mnCol
= mnItemLevel
= mnMultiLevel
= 0;
2030 writeChar( OOX_DUMP_BOM
);
2035 bool Output::implIsValid() const
2040 void Output::writeItemName( const String
& rItemName
)
2042 if( rItemName
.has() && (rItemName
[ 0 ] == '#') )
2044 writeString( rItemName
.copy( 1 ) );
2045 StringHelper::appendIndex( maLine
, mnItemIdx
++ );
2048 writeString( rItemName
);
2051 // ============================================================================
2053 StorageIterator::StorageIterator( const StorageRef
& rxStrg
) :
2057 mxStrg
->getElementNames( maNames
);
2058 maIt
= maNames
.begin();
2061 StorageIterator::~StorageIterator()
2065 size_t StorageIterator::getElementCount() const
2067 return maNames
.size();
2070 StorageIterator
& StorageIterator::operator++()
2072 if( maIt
!= maNames
.end() )
2077 OUString
StorageIterator::getName() const
2080 if( maIt
!= maNames
.end() )
2085 bool StorageIterator::isStream() const
2087 return isValid() && mxStrg
->openInputStream( *maIt
).is();
2090 bool StorageIterator::isStorage() const
2094 StorageRef xStrg
= mxStrg
->openSubStorage( *maIt
, false );
2095 return xStrg
.get() && xStrg
->isStorage();
2098 bool StorageIterator::implIsValid() const
2100 return mxStrg
.get() && mxStrg
->isStorage() && (maIt
!= maNames
.end());
2103 // ============================================================================
2104 // ============================================================================
2106 ObjectBase::~ObjectBase()
2110 void ObjectBase::construct( const ConfigRef
& rxConfig
)
2112 mxConfig
= rxConfig
;
2115 void ObjectBase::construct( const ObjectBase
& rParent
)
2120 void ObjectBase::dump()
2126 bool ObjectBase::implIsValid() const
2128 return isValid( mxConfig
);
2131 void ObjectBase::implDump()
2135 void ObjectBase::reconstructConfig( const ConfigRef
& rxConfig
)
2137 if( isValid( rxConfig
) )
2138 mxConfig
= rxConfig
;
2141 // ============================================================================
2142 // ============================================================================
2144 void StorageObjectBase::construct( const ObjectBase
& rParent
, const StorageRef
& rxStrg
, const OUString
& rSysPath
)
2146 ObjectBase::construct( rParent
);
2148 maSysPath
= rSysPath
;
2151 void StorageObjectBase::construct( const ObjectBase
& rParent
)
2153 ObjectBase::construct( rParent
);
2154 if( ObjectBase::implIsValid() )
2156 mxStrg
= cfg().getRootStorage();
2157 maSysPath
= cfg().getSysFileName();
2161 bool StorageObjectBase::implIsValid() const
2163 return mxStrg
.get() && mxStrg
->isStorage() && (maSysPath
.getLength() > 0) && ObjectBase::implIsValid();
2166 void StorageObjectBase::implDump()
2170 Reference
< XSimpleFileAccess
> xFileAccess( getFactory()->createInstance( CREATE_OUSTRING( "com.sun.star.ucb.SimpleFileAccess" ) ), UNO_QUERY_THROW
);
2171 xFileAccess
->kill( maSysPath
+ OOX_DUMP_DUMPEXT
);
2176 extractStorage( mxStrg
, OUString(), maSysPath
);
2179 void StorageObjectBase::implDumpStream( const BinaryInputStreamRef
&, const OUString
&, const OUString
&, const OUString
& )
2183 void StorageObjectBase::implDumpStorage( const StorageRef
& rxStrg
, const OUString
& rStrgPath
, const OUString
& rSysPath
)
2185 extractStorage( rxStrg
, rStrgPath
, rSysPath
);
2188 void StorageObjectBase::addPreferredStream( const String
& rStrmName
)
2190 if( rStrmName
.has() )
2191 maPreferred
.push_back( PreferredItem( rStrmName
, false ) );
2194 void StorageObjectBase::addPreferredStorage( const String
& rStrgPath
)
2196 if( rStrgPath
.has() )
2197 maPreferred
.push_back( PreferredItem( rStrgPath
, true ) );
2200 OUString
StorageObjectBase::getSysFileName( const OUString
& rStrmName
, const OUString
& rSysOutPath
)
2202 // encode all characters < 0x20
2203 OUStringBuffer aBuffer
;
2204 StringHelper::appendEncString( aBuffer
, rStrmName
, false );
2206 // replace all characters reserved in file system
2207 OUString aFileName
= aBuffer
.makeStringAndClear();
2208 static const sal_Unicode spcReserved
[] = { '/', '\\', ':', '*', '?', '<', '>', '|' };
2209 for( const sal_Unicode
* pcChar
= spcReserved
; pcChar
< STATIC_ARRAY_END( spcReserved
); ++pcChar
)
2210 aFileName
= aFileName
.replace( *pcChar
, '_' );
2213 return rSysOutPath
+ OUString( sal_Unicode( '/' ) ) + aFileName
;
2216 void StorageObjectBase::extractStream( StorageBase
& rStrg
, const OUString
& rStrgPath
, const OUString
& rStrmName
, const OUString
& rSysFileName
)
2218 BinaryXInputStream
aInStrm( rStrg
.openInputStream( rStrmName
), true );
2219 if( !aInStrm
.isEof() )
2221 BinaryXOutputStream
aOutStrm( InputOutputHelper::openOutputStream( getFactory(), rSysFileName
), true );
2222 if( !aOutStrm
.isEof() )
2223 aOutStrm
.copyStream( aInStrm
);
2225 BinaryXInputStreamRef
xDumpStrm( new BinaryXInputStream( InputOutputHelper::openInputStream( getFactory(), rSysFileName
), true ) );
2226 if( !xDumpStrm
->isEof() )
2227 implDumpStream( xDumpStrm
, rStrgPath
, rStrmName
, rSysFileName
);
2230 void StorageObjectBase::extractStorage( const StorageRef
& rxStrg
, const OUString
& rStrgPath
, const OUString
& rSysPath
)
2232 OUString aSysOutPath
= rSysPath
+ OOX_DUMP_DUMPEXT
;
2234 // create directory in file system
2235 ::osl::FileBase::RC eRes
= ::osl::Directory::create( aSysOutPath
);
2236 if( (eRes
!= ::osl::FileBase::E_None
) && (eRes
!= ::osl::FileBase::E_EXIST
) )
2239 // process preferred storages and streams in root storage first
2240 if( rStrgPath
.getLength() == 0 )
2241 for( PreferredItemVector::iterator aIt
= maPreferred
.begin(), aEnd
= maPreferred
.end(); aIt
!= aEnd
; ++aIt
)
2242 extractItem( rxStrg
, rStrgPath
, aIt
->maName
, aSysOutPath
, aIt
->mbStorage
, !aIt
->mbStorage
);
2244 // process children of the storage
2245 for( StorageIterator
aIt( rxStrg
); aIt
.isValid(); ++aIt
)
2247 // skip processed preferred items
2248 OUString aItemName
= aIt
.getName();
2249 bool bFound
= false;
2250 if( rStrgPath
.getLength() == 0 )
2251 for( PreferredItemVector::iterator aIIt
= maPreferred
.begin(), aIEnd
= maPreferred
.end(); !bFound
&& (aIIt
!= aIEnd
); ++aIIt
)
2252 bFound
= aIIt
->maName
== aItemName
;
2254 extractItem( rxStrg
, rStrgPath
, aItemName
, aSysOutPath
, aIt
.isStorage(), aIt
.isStream() );
2258 void StorageObjectBase::extractItem( const StorageRef
& rxStrg
, const OUString
& rStrgPath
, const OUString
& rItemName
, const OUString
& rSysOutPath
, bool bIsStrg
, bool bIsStrm
)
2260 OUString aSysFileName
= getSysFileName( rItemName
, rSysOutPath
);
2263 OUStringBuffer
aStrgPath( rStrgPath
);
2264 StringHelper::appendToken( aStrgPath
, rItemName
, '/' );
2265 implDumpStorage( rxStrg
->openSubStorage( rItemName
, false ), aStrgPath
.makeStringAndClear(), aSysFileName
);
2269 extractStream( *rxStrg
, rStrgPath
, rItemName
, aSysFileName
);
2273 // ============================================================================
2274 // ============================================================================
2276 OutputObjectBase::~OutputObjectBase()
2280 void OutputObjectBase::construct( const ObjectBase
& rParent
, const OUString
& rSysFileName
)
2282 ObjectBase::construct( rParent
);
2283 if( ObjectBase::implIsValid() )
2284 mxOut
.reset( new Output( getFactory(), rSysFileName
+ OOX_DUMP_DUMPEXT
) );
2287 void OutputObjectBase::construct( const ObjectBase
& rParent
, const OutputRef
& rxOut
)
2289 ObjectBase::construct( rParent
);
2293 void OutputObjectBase::construct( const OutputObjectBase
& rParent
)
2298 bool OutputObjectBase::implIsValid() const
2300 return isValid( mxOut
) && ObjectBase::implIsValid();
2303 void OutputObjectBase::writeEmptyItem( const String
& rName
)
2305 ItemGuard
aItem( *mxOut
, rName
);
2308 void OutputObjectBase::writeInfoItem( const String
& rName
, const String
& rData
)
2310 ItemGuard
aItem( *mxOut
, rName
);
2311 mxOut
->writeString( rData
);
2314 void OutputObjectBase::writeCharItem( const String
& rName
, sal_Unicode cData
)
2316 ItemGuard
aItem( *mxOut
, rName
);
2317 mxOut
->writeChar( OOX_DUMP_STRQUOTE
);
2318 mxOut
->writeChar( cData
);
2319 mxOut
->writeChar( OOX_DUMP_STRQUOTE
);
2322 void OutputObjectBase::writeStringItem( const String
& rName
, const OUString
& rData
)
2324 ItemGuard
aItem( *mxOut
, rName
);
2325 mxOut
->writeAscii( "(len=" );
2326 mxOut
->writeDec( rData
.getLength() );
2327 mxOut
->writeAscii( ")," );
2328 OUStringBuffer
aValue( rData
.copy( 0, ::std::min( rData
.getLength(), OOX_DUMP_MAXSTRLEN
) ) );
2329 StringHelper::enclose( aValue
, OOX_DUMP_STRQUOTE
);
2330 mxOut
->writeString( aValue
.makeStringAndClear() );
2331 if( rData
.getLength() > OOX_DUMP_MAXSTRLEN
)
2332 mxOut
->writeAscii( ",cut" );
2335 void OutputObjectBase::writeArrayItem( const String
& rName
, const sal_uInt8
* pnData
, sal_Size nSize
, sal_Unicode cSep
)
2337 ItemGuard
aItem( *mxOut
, rName
);
2338 mxOut
->writeArray( pnData
, nSize
, cSep
);
2341 void OutputObjectBase::writeBoolItem( const String
& rName
, bool bData
)
2343 ItemGuard
aItem( *mxOut
, rName
);
2344 mxOut
->writeBool( bData
);
2347 double OutputObjectBase::writeRkItem( const String
& rName
, sal_Int32 nRk
)
2349 MultiItemsGuard
aMultiGuard( out() );
2350 writeHexItem( rName
, static_cast< sal_uInt32
>( nRk
), "RK-FLAGS" );
2351 double fValue
= ::oox::xls::BiffHelper::calcDoubleFromRk( nRk
);
2352 writeDecItem( "decoded", fValue
);
2356 void OutputObjectBase::writeColorABGRItem( const String
& rName
, sal_Int32 nColor
)
2358 ItemGuard
aItem( *mxOut
, rName
);
2359 writeHexItem( rName
, nColor
);
2360 mxOut
->writeColorABGR( nColor
);
2363 void OutputObjectBase::writeDateTimeItem( const String
& rName
, const DateTime
& rDateTime
)
2365 ItemGuard
aItem( *mxOut
, rName
);
2366 mxOut
->writeDateTime( rDateTime
);
2369 void OutputObjectBase::writeGuidItem( const String
& rName
, const OUString
& rGuid
)
2371 ItemGuard
aItem( *mxOut
, rName
);
2372 mxOut
->writeString( rGuid
);
2374 mxOut
->writeString( cfg().getStringOption( rGuid
, OUString() ) );
2377 void OutputObjectBase::writeColIndexItem( const String
& rName
, sal_Int32 nCol
)
2379 Output
& rOut
= out();
2380 ItemGuard
aItem( rOut
, rName
);
2381 rOut
.writeDec( nCol
);
2383 rOut
.writeColIndex( nCol
);
2386 void OutputObjectBase::writeRowIndexItem( const String
& rName
, sal_Int32 nRow
)
2388 Output
& rOut
= out();
2389 ItemGuard
aItem( rOut
, rName
);
2390 rOut
.writeDec( nRow
);
2392 rOut
.writeRowIndex( nRow
);
2395 void OutputObjectBase::writeColRangeItem( const String
& rName
, sal_Int32 nCol1
, sal_Int32 nCol2
)
2397 Output
& rOut
= out();
2398 ItemGuard
aItem( rOut
, rName
);
2399 rOut
.writeColRowRange( nCol1
, nCol2
);
2401 rOut
.writeColRange( nCol1
, nCol2
);
2404 void OutputObjectBase::writeRowRangeItem( const String
& rName
, sal_Int32 nRow1
, sal_Int32 nRow2
)
2406 Output
& rOut
= out();
2407 ItemGuard
aItem( rOut
, rName
);
2408 rOut
.writeColRowRange( nRow1
, nRow2
);
2410 rOut
.writeRowRange( nRow1
, nRow2
);
2413 void OutputObjectBase::writeAddressItem( const String
& rName
, const Address
& rPos
)
2415 ItemGuard
aItem( out(), rName
);
2416 StringHelper::appendAddress( out().getLine(), rPos
);
2419 void OutputObjectBase::writeRangeItem( const String
& rName
, const Range
& rRange
)
2421 ItemGuard
aItem( out(), rName
);
2422 StringHelper::appendRange( out().getLine(), rRange
);
2425 void OutputObjectBase::writeRangeListItem( const String
& rName
, const RangeList
& rRanges
)
2427 MultiItemsGuard
aMultiGuard( out() );
2428 writeEmptyItem( rName
);
2429 writeDecItem( "count", static_cast< sal_uInt16
>( rRanges
.size() ) );
2430 ItemGuard
aItem( out(), "ranges" );
2431 StringHelper::appendRangeList( out().getLine(), rRanges
);
2434 void OutputObjectBase::writeTokenAddressItem( const String
& rName
, const TokenAddress
& rPos
, bool bNameMode
)
2436 ItemGuard
aItem( out(), rName
);
2437 StringHelper::appendAddress( out().getLine(), rPos
, bNameMode
);
2440 void OutputObjectBase::writeTokenAddress3dItem( const String
& rName
, const OUString
& rRef
, const TokenAddress
& rPos
, bool bNameMode
)
2442 ItemGuard
aItem( out(), rName
);
2443 out().writeString( rRef
);
2444 StringHelper::appendAddress( out().getLine(), rPos
, bNameMode
);
2447 void OutputObjectBase::writeTokenRangeItem( const String
& rName
, const TokenRange
& rRange
, bool bNameMode
)
2449 ItemGuard
aItem( out(), rName
);
2450 StringHelper::appendRange( out().getLine(), rRange
, bNameMode
);
2453 void OutputObjectBase::writeTokenRange3dItem( const String
& rName
, const OUString
& rRef
, const TokenRange
& rRange
, bool bNameMode
)
2455 ItemGuard
aItem( out(), rName
);
2456 out().writeString( rRef
);
2457 StringHelper::appendRange( out().getLine(), rRange
, bNameMode
);
2460 // ============================================================================
2461 // ============================================================================
2463 InputObjectBase::~InputObjectBase()
2467 void InputObjectBase::construct( const ObjectBase
& rParent
, const BinaryInputStreamRef
& rxStrm
, const OUString
& rSysFileName
)
2469 OutputObjectBase::construct( rParent
, rSysFileName
);
2473 void InputObjectBase::construct( const ObjectBase
& rParent
, const BinaryInputStreamRef
& rxStrm
, const OutputRef
& rxOut
)
2475 OutputObjectBase::construct( rParent
, rxOut
);
2479 void InputObjectBase::construct( const OutputObjectBase
& rParent
, const BinaryInputStreamRef
& rxStrm
)
2481 OutputObjectBase::construct( rParent
);
2485 void InputObjectBase::construct( const InputObjectBase
& rParent
)
2490 bool InputObjectBase::implIsValid() const
2492 return mxStrm
.get() && OutputObjectBase::implIsValid();
2495 void InputObjectBase::skipBlock( sal_Int64 nBytes
, bool bShowSize
)
2497 sal_Int64 nEndPos
= ::std::min
< sal_Int64
>( mxStrm
->tell() + nBytes
, mxStrm
->getLength() );
2498 if( mxStrm
->tell() < nEndPos
)
2501 writeDecItem( "skipped-data-size", static_cast< sal_uInt64
>( nEndPos
- mxStrm
->tell() ) );
2502 mxStrm
->seek( nEndPos
);
2506 void InputObjectBase::dumpRawBinary( sal_Int64 nBytes
, bool bShowOffset
, bool bStream
)
2508 Output
& rOut
= out();
2509 TableGuard
aTabGuard( rOut
,
2510 bShowOffset
? 12 : 0,
2511 3 * OOX_DUMP_BYTESPERLINE
/ 2 + 1,
2512 3 * OOX_DUMP_BYTESPERLINE
/ 2 + 1,
2513 OOX_DUMP_BYTESPERLINE
/ 2 + 1 );
2515 sal_Int64 nMaxShowSize
= cfg().getIntOption
< sal_Int64
>(
2516 bStream
? "max-binary-stream-size" : "max-binary-data-size", SAL_MAX_INT64
);
2518 bool bSeekable
= mxStrm
->getLength() >= 0;
2519 sal_Int64 nEndPos
= bSeekable
? ::std::min
< sal_Int64
>( mxStrm
->tell() + nBytes
, mxStrm
->getLength() ) : 0;
2520 sal_Int64 nDumpEnd
= bSeekable
? ::std::min
< sal_Int64
>( mxStrm
->tell() + nMaxShowSize
, nEndPos
) : nMaxShowSize
;
2521 sal_Int64 nPos
= bSeekable
? mxStrm
->tell() : 0;
2524 while( bLoop
&& (nPos
< nDumpEnd
) )
2526 rOut
.writeHex( static_cast< sal_uInt32
>( nPos
) );
2529 sal_uInt8 pnLineData
[ OOX_DUMP_BYTESPERLINE
];
2530 sal_Int32 nLineSize
= bSeekable
? ::std::min( static_cast< sal_Int32
>( nDumpEnd
- mxStrm
->tell() ), OOX_DUMP_BYTESPERLINE
) : OOX_DUMP_BYTESPERLINE
;
2531 sal_Int32 nReadSize
= mxStrm
->readMemory( pnLineData
, nLineSize
);
2532 bLoop
= nReadSize
== nLineSize
;
2537 const sal_uInt8
* pnByte
= 0;
2538 const sal_uInt8
* pnEnd
= 0;
2539 for( pnByte
= pnLineData
, pnEnd
= pnLineData
+ nReadSize
; pnByte
!= pnEnd
; ++pnByte
)
2541 if( (pnByte
- pnLineData
) == (OOX_DUMP_BYTESPERLINE
/ 2) ) rOut
.tab();
2542 rOut
.writeHex( *pnByte
, false );
2543 rOut
.writeChar( ' ' );
2547 for( pnByte
= pnLineData
, pnEnd
= pnLineData
+ nReadSize
; pnByte
!= pnEnd
; ++pnByte
)
2549 if( (pnByte
- pnLineData
) == (OOX_DUMP_BYTESPERLINE
/ 2) ) rOut
.tab();
2550 rOut
.writeChar( static_cast< sal_Unicode
>( (*pnByte
< 0x20) ? '.' : *pnByte
) );
2556 // skip undumped data
2558 skipBlock( nEndPos
- mxStrm
->tell() );
2561 void InputObjectBase::dumpBinary( const String
& rName
, sal_Int64 nBytes
, bool bShowOffset
)
2564 MultiItemsGuard
aMultiGuard( out() );
2565 writeEmptyItem( rName
);
2566 writeDecItem( "size", nBytes
);
2568 IndentGuard
aIndGuard( out() );
2569 dumpRawBinary( nBytes
, bShowOffset
);
2572 void InputObjectBase::dumpRemaining( sal_Int64 nBytes
)
2576 if( cfg().getBoolOption( "show-trailing-unknown", true ) )
2577 dumpBinary( "remaining-data", nBytes
, false );
2579 skipBlock( nBytes
);
2583 void InputObjectBase::dumpRemainingTo( sal_Int64 nPos
)
2585 if( mxStrm
->isEof() )
2586 writeInfoItem( "stream-state", OOX_DUMP_ERR_STREAM
);
2588 dumpRemaining( nPos
- mxStrm
->tell() );
2589 mxStrm
->seek( nPos
);
2592 void InputObjectBase::dumpRemainingStream()
2594 dumpRemainingTo( mxStrm
->getLength() );
2597 void InputObjectBase::dumpArray( const String
& rName
, sal_Int32 nBytes
, sal_Unicode cSep
)
2599 sal_Int32 nDumpSize
= getLimitedValue
< sal_Int32
, sal_Int64
>( mxStrm
->getLength() - mxStrm
->tell(), 0, nBytes
);
2600 if( nDumpSize
> OOX_DUMP_MAXARRAY
)
2602 dumpBinary( rName
, nBytes
, false );
2604 else if( nDumpSize
> 1 )
2606 sal_uInt8 pnData
[ OOX_DUMP_MAXARRAY
];
2607 mxStrm
->readMemory( pnData
, nDumpSize
);
2608 writeArrayItem( rName
, pnData
, nDumpSize
, cSep
);
2610 else if( nDumpSize
== 1 )
2611 dumpHex
< sal_uInt8
>( rName
);
2614 sal_Unicode
InputObjectBase::dumpChar( const String
& rName
, rtl_TextEncoding eTextEnc
)
2618 OUString aChar
= OStringToOUString( OString( static_cast< sal_Char
>( nChar
) ), eTextEnc
);
2619 sal_Unicode cChar
= (aChar
.getLength() > 0) ? aChar
[ 0 ] : 0;
2620 writeCharItem( rName( "char" ), cChar
);
2624 sal_Unicode
InputObjectBase::dumpUnicode( const String
& rName
)
2628 sal_Unicode cChar
= static_cast< sal_Unicode
>( nChar
);
2629 writeCharItem( rName( "char" ), cChar
);
2633 OUString
InputObjectBase::dumpCharArray( const String
& rName
, sal_Int32 nLen
, rtl_TextEncoding eTextEnc
)
2635 sal_Int32 nDumpSize
= getLimitedValue
< sal_Int32
, sal_Int64
>( mxStrm
->getLength() - mxStrm
->tell(), 0, nLen
);
2639 ::std::vector
< sal_Char
> aBuffer( static_cast< sal_Size
>( nLen
) + 1 );
2640 sal_Int32 nCharsRead
= mxStrm
->readMemory( &aBuffer
.front(), nLen
);
2641 aBuffer
[ nCharsRead
] = 0;
2642 aString
= OStringToOUString( OString( &aBuffer
.front() ), eTextEnc
);
2644 writeStringItem( rName( "text" ), aString
);
2648 OUString
InputObjectBase::dumpUnicodeArray( const String
& rName
, sal_Int32 nLen
)
2650 OUStringBuffer aBuffer
;
2651 for( sal_Int32 nIndex
= 0; !mxStrm
->isEof() && (nIndex
< nLen
); ++nIndex
)
2652 aBuffer
.append( static_cast< sal_Unicode
>( mxStrm
->readuInt16() ) );
2653 OUString aString
= aBuffer
.makeStringAndClear();
2654 writeStringItem( rName( "text" ), aString
);
2658 OUString
InputObjectBase::dumpNullCharArray( const String
& rName
, rtl_TextEncoding eTextEnc
)
2660 OStringBuffer aBuffer
;
2662 for( *mxStrm
>> nChar
; !mxStrm
->isEof() && (nChar
> 0); *mxStrm
>> nChar
)
2663 aBuffer
.append( static_cast< sal_Char
>( nChar
) );
2664 OUString aString
= OStringToOUString( aBuffer
.makeStringAndClear(), eTextEnc
);
2665 writeStringItem( rName( "text" ), aString
);
2669 OUString
InputObjectBase::dumpNullUnicodeArray( const String
& rName
)
2671 OUStringBuffer aBuffer
;
2673 for( *mxStrm
>> nChar
; !mxStrm
->isEof() && (nChar
> 0); *mxStrm
>> nChar
)
2674 aBuffer
.append( static_cast< sal_Unicode
>( nChar
) );
2675 OUString aString
= aBuffer
.makeStringAndClear();
2676 writeStringItem( rName( "text" ), aString
);
2680 double InputObjectBase::dumpRk( const String
& rName
)
2684 return writeRkItem( rName( "rk-value" ), nRk
);
2687 sal_Int32
InputObjectBase::dumpColorABGR( const String
& rName
)
2691 writeColorABGRItem( rName( "color" ), nColor
);
2695 DateTime
InputObjectBase::dumpFileTime( const String
& rName
)
2699 ItemGuard
aItem( out(), rName( "file-time" ) );
2700 sal_Int64 nFileTime
= dumpDec
< sal_Int64
>( EMPTY_STRING
);
2701 // file time is in 10^-7 seconds (100 nanoseconds), convert to 1/100 seconds
2702 nFileTime
/= 100000;
2704 sal_Int64 nDays
= nFileTime
/ sal_Int64( 360000 * 24 );
2705 // number of entire years
2706 sal_Int64 nYears
= (nDays
- (nDays
/ (4 * 365)) + (nDays
/ (100 * 365)) - (nDays
/ (400 * 365))) / 365;
2707 // remaining days in the year
2708 sal_Int64 nDaysInYear
= nDays
- (nYears
* 365 + nYears
/ 4 - nYears
/ 100 + nYears
/ 400);
2709 // the year (file dates start from 1601-01-01)
2710 aDateTime
.Year
= static_cast< sal_uInt16
>( 1601 + nYears
);
2712 bool bLeap
= ((aDateTime
.Year
% 4 == 0) && (aDateTime
.Year
% 100 != 0)) || (aDateTime
.Year
% 400 == 0);
2713 // static arrays with number of days in month
2714 static const sal_Int64 spnDaysInMonth
[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
2715 static const sal_Int64 spnDaysInMonthL
[] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
2716 const sal_Int64
* pnDaysInMonth
= bLeap
? spnDaysInMonthL
: spnDaysInMonth
;
2718 aDateTime
.Month
= 1;
2719 while( nDaysInYear
>= *pnDaysInMonth
)
2721 nDaysInYear
-= *pnDaysInMonth
++;
2725 aDateTime
.Day
= static_cast< sal_uInt16
>( nDaysInYear
+ 1 );
2726 // number of 1/100 seconds in the day
2727 sal_Int64 nTimeInDay
= nFileTime
% sal_Int64( 360000 * 24 );
2729 aDateTime
.HundredthSeconds
= static_cast< sal_uInt16
>( nTimeInDay
% 100 );
2732 aDateTime
.Seconds
= static_cast< sal_uInt16
>( nTimeInDay
% 60 );
2735 aDateTime
.Minutes
= static_cast< sal_uInt16
>( nTimeInDay
% 60 );
2738 aDateTime
.Hours
= static_cast< sal_uInt16
>( nTimeInDay
);
2740 writeDateTimeItem( EMPTY_STRING
, aDateTime
);
2744 OUString
InputObjectBase::dumpGuid( const String
& rName
)
2746 OUStringBuffer aBuffer
;
2752 StringHelper::appendHex( aBuffer
, nData32
, false );
2753 aBuffer
.append( sal_Unicode( '-' ) );
2755 StringHelper::appendHex( aBuffer
, nData16
, false );
2756 aBuffer
.append( sal_Unicode( '-' ) );
2758 StringHelper::appendHex( aBuffer
, nData16
, false );
2759 aBuffer
.append( sal_Unicode( '-' ) );
2761 StringHelper::appendHex( aBuffer
, nData8
, false );
2763 StringHelper::appendHex( aBuffer
, nData8
, false );
2764 aBuffer
.append( sal_Unicode( '-' ) );
2765 for( int nIndex
= 0; nIndex
< 6; ++nIndex
)
2768 StringHelper::appendHex( aBuffer
, nData8
, false );
2770 StringHelper::enclose( aBuffer
, '{', '}' );
2771 OUString aGuid
= aBuffer
.makeStringAndClear();
2772 writeGuidItem( rName( "guid" ), aGuid
);
2776 void InputObjectBase::dumpItem( const ItemFormat
& rItemFmt
)
2778 switch( rItemFmt
.meDataType
)
2780 case DATATYPE_VOID
: break;
2781 case DATATYPE_INT8
: dumpValue
< sal_Int8
>( rItemFmt
); break;
2782 case DATATYPE_UINT8
: dumpValue
< sal_uInt8
>( rItemFmt
); break;
2783 case DATATYPE_INT16
: dumpValue
< sal_Int16
>( rItemFmt
); break;
2784 case DATATYPE_UINT16
: dumpValue
< sal_uInt16
>( rItemFmt
); break;
2785 case DATATYPE_INT32
: dumpValue
< sal_Int32
>( rItemFmt
); break;
2786 case DATATYPE_UINT32
: dumpValue
< sal_uInt32
>( rItemFmt
); break;
2787 case DATATYPE_INT64
: dumpValue
< sal_Int64
>( rItemFmt
); break;
2788 case DATATYPE_UINT64
: dumpValue
< sal_uInt64
>( rItemFmt
); break;
2789 case DATATYPE_FLOAT
: dumpValue
< float >( rItemFmt
); break;
2790 case DATATYPE_DOUBLE
: dumpValue
< double >( rItemFmt
); break;
2795 // ============================================================================
2796 // ============================================================================
2798 BinaryStreamObject::BinaryStreamObject( const ObjectBase
& rParent
, const BinaryInputStreamRef
& rxStrm
, const OUString
& rSysFileName
)
2800 InputObjectBase::construct( rParent
, rxStrm
, rSysFileName
);
2803 BinaryStreamObject::BinaryStreamObject( const OutputObjectBase
& rParent
, const BinaryInputStreamRef
& rxStrm
)
2805 InputObjectBase::construct( rParent
, rxStrm
);
2808 void BinaryStreamObject::dumpBinaryStream( bool bShowOffset
)
2811 dumpRawBinary( in().getLength(), bShowOffset
, true );
2815 void BinaryStreamObject::implDump()
2820 // ============================================================================
2824 bool lclIsEof( BinaryInputStream
& rStrm
)
2826 return rStrm
.isEof() || (rStrm
.isSeekable() && (rStrm
.tell() >= rStrm
.getLength()));
2829 template< typename BufferType
, typename CharType
>
2830 CharType
lclAppendChar( BufferType
& orBuffer
, CharType cChar
)
2832 if( (cChar
== 0x0A) || (cChar
== 0x0D) )
2834 orBuffer
.append( cChar
);
2838 template< typename BufferType
, typename CharType
, typename StreamDataType
>
2839 bool lclReadLine( BufferType
& orBuffer
, sal_Unicode
& orcNextLineChar
, BinaryInputStream
& rStrm
)
2841 CharType cLineEndChar
= (orcNextLineChar
== 0) ? 0 : lclAppendChar( orBuffer
, static_cast< CharType
>( orcNextLineChar
) );
2842 orcNextLineChar
= 0;
2844 // read chars until EOF or line end character (LF or CR)
2845 bool bIsEof
= lclIsEof( rStrm
);
2846 while( !bIsEof
&& (cLineEndChar
== 0) )
2848 CharType cChar
= static_cast< CharType
>( rStrm
.readValue
< StreamDataType
>() );
2849 bIsEof
= rStrm
.isEof();
2850 cLineEndChar
= bIsEof
? 0 : lclAppendChar( orBuffer
, cChar
);
2853 // try to skip LF following CR, or CR following LF
2854 if( !lclIsEof( rStrm
) && (cLineEndChar
!= 0) )
2856 CharType cChar
= static_cast< CharType
>( rStrm
.readValue
< StreamDataType
>() );
2857 bool bLineEnd
= ((cChar
== 0x0A) || (cChar
== 0x0D)) && (cChar
!= cLineEndChar
);
2858 if( !rStrm
.isEof() && !bLineEnd
)
2859 orcNextLineChar
= static_cast< sal_Unicode
>( cChar
);
2862 return (cLineEndChar
!= 0) || (orBuffer
.getLength() > 0);
2867 // ----------------------------------------------------------------------------
2869 TextStreamObject::TextStreamObject( const ObjectBase
& rParent
,
2870 const BinaryInputStreamRef
& rxStrm
, rtl_TextEncoding eTextEnc
, const OUString
& rSysFileName
) :
2871 meTextEnc( eTextEnc
)
2873 InputObjectBase::construct( rParent
, rxStrm
, rSysFileName
);
2876 TextStreamObject::TextStreamObject( const OutputObjectBase
& rParent
,
2877 const BinaryInputStreamRef
& rxStrm
, rtl_TextEncoding eTextEnc
) :
2878 meTextEnc( eTextEnc
)
2880 InputObjectBase::construct( rParent
, rxStrm
);
2883 void TextStreamObject::implDump()
2886 sal_Unicode cNextLineChar
= 0;
2887 sal_uInt32 nLine
= 0;
2888 while( readLine( aLine
, cNextLineChar
) )
2889 implDumpLine( aLine
, ++nLine
);
2893 void TextStreamObject::implDumpLine( const OUString
& rLine
, sal_uInt32 nLine
)
2895 Output
& rOut
= out();
2896 TableGuard
aTabGuard( rOut
, 8 );
2897 rOut
.writeDec( nLine
, 6 );
2899 rOut
.writeString( rLine
);
2903 bool TextStreamObject::readCharLine( OUString
& orLine
, sal_Unicode
& orcNextLineChar
)
2905 OStringBuffer aBuffer
;
2906 bool bHasData
= lclReadLine
< OStringBuffer
, sal_Char
, sal_uInt8
>( aBuffer
, orcNextLineChar
, in() );
2908 orLine
= OStringToOUString( aBuffer
.makeStringAndClear(), meTextEnc
);
2912 bool TextStreamObject::readUcs2Line( OUString
& orLine
, sal_Unicode
& orcNextLineChar
)
2914 OUStringBuffer aBuffer
;
2915 bool bHasData
= lclReadLine
< OUStringBuffer
, sal_Unicode
, sal_uInt16
>( aBuffer
, orcNextLineChar
, in() );
2917 orLine
= aBuffer
.makeStringAndClear();
2921 bool TextStreamObject::readLine( OUString
& orLine
, sal_Unicode
& orcNextLineChar
)
2923 return (meTextEnc
== RTL_TEXTENCODING_UCS2
) ?
2924 readUcs2Line( orLine
, orcNextLineChar
) :
2925 readCharLine( orLine
, orcNextLineChar
);
2928 // ============================================================================
2930 XmlStreamObject::XmlStreamObject( const ObjectBase
& rParent
, const BinaryInputStreamRef
& rxStrm
, const OUString
& rSysFileName
) :
2931 TextStreamObject( rParent
, rxStrm
, RTL_TEXTENCODING_UTF8
, rSysFileName
)
2935 void XmlStreamObject::implDump()
2937 maIncompleteLine
= OUString();
2938 TextStreamObject::implDump();
2939 if( maIncompleteLine
.getLength() > 0 )
2941 out().resetIndent();
2942 out().writeString( maIncompleteLine
);
2944 writeInfoItem( "stream-state", OOX_DUMP_ERR_STREAM
);
2948 void XmlStreamObject::implDumpLine( const OUString
& rLine
, sal_uInt32
)
2950 // build input line from cached incomplete element and new text data
2951 OUStringBuffer aLine
;
2952 if( maIncompleteLine
.getLength() > 0 )
2953 aLine
.append( maIncompleteLine
).append( sal_Unicode( ' ' ) );
2954 aLine
.append( rLine
);
2955 maIncompleteLine
= OUString();
2957 Output
& rOut
= out();
2958 if( aLine
.getLength() == 0 )
2964 const sal_Unicode
* pcPos
= aLine
.getStr();
2965 const sal_Unicode
* pcEnd
= pcPos
+ aLine
.getLength();
2966 while( pcPos
< pcEnd
)
2968 OUStringBuffer aOutLine
;
2969 bool bIsStartElement
= false;
2970 bool bIsComplElement
= false;
2971 bool bIsEndElement
= false;
2973 /* check for start element at beginning of the line - pcEnd and thus (pcPos+1)
2974 are dereferenceable, because OUStringBuffer::getStr is null-terminated. */
2975 if( (*pcPos
== '<') && (pcPos
[ 1 ] != '/') )
2977 const sal_Unicode
* pcElementEnd
= ::std::find( pcPos
, pcEnd
, '>' );
2978 if( pcElementEnd
== pcEnd
)
2980 // incomplete start element
2981 maIncompleteLine
= OUString( pcPos
, static_cast< sal_Int32
>( pcEnd
- pcPos
) );
2986 bIsComplElement
= (pcPos
[ 1 ] == '?') || (pcPos
[ 1 ] == '!') || (pcElementEnd
[ -1 ] == '/');
2987 bIsStartElement
= !bIsComplElement
;
2989 aOutLine
.append( pcPos
, static_cast< sal_Int32
>( pcElementEnd
- pcPos
) );
2990 pcPos
= pcElementEnd
;
2994 // check for following element text
2995 if( !bIsComplElement
&& (pcPos
< pcEnd
) )
2997 const sal_Unicode
* pcElementStart
= ::std::find( pcPos
, pcEnd
, '<' );
2998 // append text between elements
2999 if( pcPos
< pcElementStart
)
3001 OUString
aText( pcPos
, static_cast< sal_Int32
>( pcElementStart
- pcPos
) );
3002 if( aText
.trim().getLength() > 0 )
3003 aOutLine
.append( aText
);
3004 pcPos
= pcElementStart
;
3008 // check for stand-alone or following end element
3009 if( !bIsComplElement
&& (pcPos
< pcEnd
) && (pcPos
[ 1 ] == '/') )
3011 const sal_Unicode
* pcElementEnd
= ::std::find( pcPos
, pcEnd
, '>' );
3012 if( pcElementEnd
== pcEnd
)
3014 // incomplete end element
3015 aOutLine
.append( pcPos
, static_cast< sal_Int32
>( pcEnd
- pcPos
) );
3016 maIncompleteLine
= aOutLine
.makeStringAndClear();
3021 bIsEndElement
= true;
3023 aOutLine
.append( pcPos
, static_cast< sal_Int32
>( pcElementEnd
- pcPos
) );
3024 pcPos
= pcElementEnd
;
3028 // flush output line
3029 if( maIncompleteLine
.getLength() == 0 )
3031 if( !bIsStartElement
&& bIsEndElement
) rOut
.decIndent();
3032 rOut
.writeString( aOutLine
.makeStringAndClear() );
3034 if( bIsStartElement
&& !bIsEndElement
) rOut
.incIndent();
3039 // ============================================================================
3040 // ============================================================================
3042 void RecordObjectBase::construct( const ObjectBase
& rParent
,
3043 const BinaryInputStreamRef
& rxBaseStrm
, const OUString
& rSysFileName
,
3044 const BinaryInputStreamRef
& rxRecStrm
, const String
& rRecNames
, const String
& rSimpleRecs
)
3046 InputObjectBase::construct( rParent
, rxRecStrm
, rSysFileName
);
3047 constructRecObjBase( rxBaseStrm
, rRecNames
, rSimpleRecs
);
3050 void RecordObjectBase::construct( const OutputObjectBase
& rParent
, const BinaryInputStreamRef
& rxBaseStrm
,
3051 const BinaryInputStreamRef
& rxRecStrm
, const String
& rRecNames
, const String
& rSimpleRecs
)
3053 InputObjectBase::construct( rParent
, rxRecStrm
);
3054 constructRecObjBase( rxBaseStrm
, rRecNames
, rSimpleRecs
);
3057 bool RecordObjectBase::implIsValid() const
3059 return mxBaseStrm
.get() && InputObjectBase::implIsValid();
3062 void RecordObjectBase::implDump()
3064 NameListRef xRecNames
= getRecNames();
3066 typedef ::std::map
< sal_Int64
, ItemFormat
> ItemFormatMap
;
3067 ItemFormatMap aSimpleRecs
;
3068 if( NameListBase
* pSimpleRecs
= maSimpleRecs
.getNameList( cfg() ).get() )
3069 for( NameListBase::const_iterator aIt
= pSimpleRecs
->begin(), aEnd
= pSimpleRecs
->end(); aIt
!= aEnd
; ++aIt
)
3070 aSimpleRecs
[ aIt
->first
].parse( aIt
->second
);
3072 while( implStartRecord( *mxBaseStrm
, mnRecPos
, mnRecId
, mnRecSize
) )
3077 implWriteExtHeader();
3078 IndentGuard
aIndGuard( out() );
3079 sal_Int64 nRecPos
= in().tell();
3082 if( !mbBinaryOnly
&& cfg().hasName( xRecNames
, mnRecId
) )
3084 ItemFormatMap::const_iterator aIt
= aSimpleRecs
.find( mnRecId
);
3085 if( aIt
!= aSimpleRecs
.end() )
3086 dumpItem( aIt
->second
);
3088 implDumpRecordBody();
3091 // remaining undumped data
3092 if( !in().isEof() && (in().tell() == nRecPos
) )
3093 dumpRawBinary( mnRecSize
, false );
3095 dumpRemainingTo( nRecPos
+ mnRecSize
);
3099 void RecordObjectBase::implWriteExtHeader()
3103 void RecordObjectBase::implDumpRecordBody()
3107 void RecordObjectBase::constructRecObjBase( const BinaryInputStreamRef
& rxBaseStrm
, const String
& rRecNames
, const String
& rSimpleRecs
)
3109 mxBaseStrm
= rxBaseStrm
;
3110 maRecNames
= rRecNames
;
3111 maSimpleRecs
= rSimpleRecs
;
3112 mnRecPos
= mnRecId
= mnRecSize
= 0;
3113 mbBinaryOnly
= false;
3114 if( InputObjectBase::implIsValid() )
3115 mbShowRecPos
= cfg().getBoolOption( "show-record-position", true );
3118 void RecordObjectBase::writeHeader()
3120 MultiItemsGuard
aMultiGuard( out() );
3121 writeEmptyItem( "REC" );
3122 if( mbShowRecPos
&& mxBaseStrm
->isSeekable() )
3123 writeShortHexItem( "pos", mnRecPos
, "CONV-DEC" );
3124 writeShortHexItem( "size", mnRecSize
, "CONV-DEC" );
3125 ItemGuard
aItem( out(), "id" );
3126 out().writeShortHex( mnRecId
);
3127 addNameToItem( mnRecId
, "CONV-DEC" );
3128 addNameToItem( mnRecId
, maRecNames
);
3131 // ============================================================================
3133 void SequenceRecordObjectBase::construct(
3134 const ObjectBase
& rParent
, const BinaryInputStreamRef
& rxBaseStrm
, const ::rtl::OUString
& rSysFileName
,
3135 const BinaryInputStreamRef
& rxRecStrm
, const String
& rRecNames
, const String
& rSimpleRecs
)
3137 RecordObjectBase::construct( rParent
, rxBaseStrm
, rSysFileName
, rxRecStrm
, rRecNames
, rSimpleRecs
);
3140 void SequenceRecordObjectBase::construct( const OutputObjectBase
& rParent
,
3141 const BinaryInputStreamRef
& rxBaseStrm
, const BinaryInputStreamRef
& rxRecStrm
,
3142 const String
& rRecNames
, const String
& rSimpleRecs
)
3144 RecordObjectBase::construct( rParent
, rxBaseStrm
, rxRecStrm
, rRecNames
, rSimpleRecs
);
3147 void SequenceRecordObjectBase::construct( const ObjectBase
& rParent
,
3148 const BinaryInputStreamRef
& rxBaseStrm
, const ::rtl::OUString
& rSysFileName
,
3149 const String
& rRecNames
, const String
& rSimpleRecs
)
3151 BinaryInputStreamRef
xRecStrm( new SequenceInputStream( *mxRecData
) );
3152 RecordObjectBase::construct( rParent
, rxBaseStrm
, rSysFileName
, xRecStrm
, rRecNames
, rSimpleRecs
);
3155 void SequenceRecordObjectBase::construct( const OutputObjectBase
& rParent
,
3156 const BinaryInputStreamRef
& rxBaseStrm
, const String
& rRecNames
, const String
& rSimpleRecs
)
3158 BinaryInputStreamRef
xRecStrm( new SequenceInputStream( *mxRecData
) );
3159 RecordObjectBase::construct( rParent
, rxBaseStrm
, xRecStrm
, rRecNames
, rSimpleRecs
);
3162 bool SequenceRecordObjectBase::implStartRecord( BinaryInputStream
& rBaseStrm
, sal_Int64
& ornRecPos
, sal_Int64
& ornRecId
, sal_Int64
& ornRecSize
)
3165 if( rBaseStrm
.isSeekable() )
3167 ornRecPos
= rBaseStrm
.tell();
3168 // do not try to overread seekable streams, may cause assertions
3169 bValid
= ornRecPos
< rBaseStrm
.getLength();
3172 // read the record header
3174 bValid
= implReadRecordHeader( rBaseStrm
, ornRecId
, ornRecSize
) && !rBaseStrm
.isEof() && (0 <= ornRecSize
) && (ornRecSize
<= 0x00100000);
3176 // read record contents into data sequence
3179 sal_Int32 nRecSize
= static_cast< sal_Int32
>( ornRecSize
);
3180 mxRecData
->realloc( nRecSize
);
3181 bValid
= (nRecSize
== 0) || (rBaseStrm
.readData( *mxRecData
, nRecSize
) == nRecSize
);
3187 // ============================================================================
3188 // ============================================================================
3190 DumperBase::~DumperBase()
3194 bool DumperBase::isImportEnabled() const
3196 return !isValid() || cfg().isImportEnabled();
3199 bool DumperBase::isImportCancelled() const
3201 return isValid() && cfg().isPasswordCancelled();
3204 void DumperBase::construct( const ConfigRef
& rxConfig
)
3206 if( isValid( rxConfig
) && rxConfig
->isDumperEnabled() )
3207 ObjectBase::construct( rxConfig
);
3210 // ============================================================================
3211 // ============================================================================