LibreOffice Module oox (master)  1
dumperbase.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <oox/dump/dumperbase.hxx>
21 
22 #include <algorithm>
23 #include <string_view>
24 
25 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
26 #include <com/sun/star/io/TextOutputStream.hpp>
27 #include <com/sun/star/ucb/SimpleFileAccess.hpp>
28 #include <osl/file.hxx>
29 #include <rtl/math.hxx>
30 #include <rtl/tencinfo.h>
31 #include <oox/core/filterbase.hxx>
34 #include <tools/time.hxx>
35 
36 #ifdef DBG_UTIL
37 
38 namespace oox::dump {
39 
40 using namespace ::com::sun::star;
41 using namespace ::com::sun::star::beans;
42 using namespace ::com::sun::star::io;
43 using namespace ::com::sun::star::lang;
44 using namespace ::com::sun::star::ucb;
45 using namespace ::com::sun::star::uno;
46 
47 using ::oox::core::FilterBase;
48 
49 namespace {
50 
51 const sal_Unicode OOX_DUMP_BOM = 0xFEFF;
52 const sal_Int32 OOX_DUMP_MAXSTRLEN = 80;
53 const sal_Int32 OOX_DUMP_INDENT = 2;
54 const sal_Unicode OOX_DUMP_BINDOT = '.';
55 const sal_Unicode OOX_DUMP_CFG_LISTSEP = ',';
56 const sal_Unicode OOX_DUMP_CFG_QUOTE = '\'';
57 const sal_Unicode OOX_DUMP_LF = '\n';
58 const sal_Unicode OOX_DUMP_ITEMSEP = '=';
59 const sal_Int32 OOX_DUMP_BYTESPERLINE = 16;
60 const sal_Int64 OOX_DUMP_MAXARRAY = 16;
61 
62 } // namespace
63 
64 // file names -----------------------------------------------------------------
65 
66 OUString InputOutputHelper::convertFileNameToUrl( const OUString& rFileName )
67 {
68  OUString aFileUrl;
69  if( ::osl::FileBase::getFileURLFromSystemPath( rFileName, aFileUrl ) == ::osl::FileBase::E_None )
70  return aFileUrl;
71  return OUString();
72 }
73 
74 sal_Int32 InputOutputHelper::getFileNamePos( const OUString& rFileUrl )
75 {
76  sal_Int32 nSepPos = rFileUrl.lastIndexOf( '/' );
77  return (nSepPos < 0) ? 0 : (nSepPos + 1);
78 }
79 
80 OUString InputOutputHelper::getFileNameExtension( const OUString& rFileUrl )
81 {
82  sal_Int32 nNamePos = getFileNamePos( rFileUrl );
83  sal_Int32 nExtPos = rFileUrl.lastIndexOf( '.' );
84  if( nExtPos >= nNamePos )
85  return rFileUrl.copy( nExtPos + 1 );
86  return OUString();
87 }
88 
89 // input streams --------------------------------------------------------------
90 
92  const Reference< XComponentContext >& rxContext, const OUString& rFileName )
93 {
95  if( rxContext.is() ) try
96  {
97  Reference<XSimpleFileAccess3> xFileAccess(SimpleFileAccess::create(rxContext));
98  xInStrm = xFileAccess->openFileRead( rFileName );
99  }
100  catch( Exception& )
101  {
102  }
103  return xInStrm;
104 }
105 
106 // output streams -------------------------------------------------------------
107 
108 Reference< XOutputStream > InputOutputHelper::openOutputStream(
109  const Reference< XComponentContext >& rxContext, const OUString& rFileName )
110 {
111  Reference< XOutputStream > xOutStrm;
112  if( rxContext.is() ) try
113  {
114  Reference<XSimpleFileAccess3> xFileAccess(SimpleFileAccess::create(rxContext));
115  xOutStrm = xFileAccess->openFileWrite( rFileName );
116  }
117  catch( Exception& )
118  {
119  }
120  return xOutStrm;
121 }
122 
123 Reference< XTextOutputStream2 > InputOutputHelper::openTextOutputStream(
124  const Reference< XComponentContext >& rxContext, const Reference< XOutputStream >& rxOutStrm, rtl_TextEncoding eTextEnc )
125 {
126  Reference< XTextOutputStream2 > xTextOutStrm;
127  const char* pcCharset = rtl_getMimeCharsetFromTextEncoding( eTextEnc );
128  if( rxContext.is() && rxOutStrm.is() && pcCharset ) try
129  {
130  xTextOutStrm = TextOutputStream::create(rxContext);
131  xTextOutStrm->setOutputStream( rxOutStrm );
132  xTextOutStrm->setEncoding( OUString::createFromAscii( pcCharset ) );
133  }
134  catch( Exception& )
135  {
136  }
137  return xTextOutStrm;
138 }
139 
140 Reference< XTextOutputStream2 > InputOutputHelper::openTextOutputStream(
141  const Reference< XComponentContext >& rxContext, const OUString& rFileName, rtl_TextEncoding eTextEnc )
142 {
143  return openTextOutputStream( rxContext, openOutputStream( rxContext, rFileName ), eTextEnc );
144 }
145 
147  meDataType( DATATYPE_VOID ),
148  meFmtType( FORMATTYPE_NONE )
149 {
150 }
151 
152 void ItemFormat::set( DataType eDataType, FormatType eFmtType, const OUString& rItemName )
153 {
154  meDataType = eDataType;
155  meFmtType = eFmtType;
156  maItemName = rItemName;
157  maListName.clear();
158 }
159 
160 OUStringVector::const_iterator ItemFormat::parse( const OUStringVector& rFormatVec )
161 {
162  set( DATATYPE_VOID, FORMATTYPE_NONE, OUString() );
163 
164  OUStringVector::const_iterator aIt = rFormatVec.begin(), aEnd = rFormatVec.end();
165  OUString aDataType, aFmtType;
166  if( aIt != aEnd ) aDataType = *aIt++;
167  if( aIt != aEnd ) aFmtType = *aIt++;
168  if( aIt != aEnd ) maItemName = *aIt++;
169  if( aIt != aEnd ) maListName = *aIt++;
170 
173 
174  if( meFmtType == FORMATTYPE_NONE )
175  {
176  if ( aFmtType == "unused" )
178  else if ( aFmtType == "unknown" )
180  }
181 
182  return aIt;
183 }
184 
185 OUStringVector ItemFormat::parse( const OUString& rFormatStr )
186 {
187  OUStringVector aFormatVec;
188  StringHelper::convertStringToStringList( aFormatVec, rFormatStr, false );
189  OUStringVector::const_iterator aIt = parse( aFormatVec );
190  return OUStringVector( aIt, const_cast< const OUStringVector& >( aFormatVec ).end() );
191 }
192 
193 // append string to string ----------------------------------------------------
194 
195 void StringHelper::appendChar( OUStringBuffer& rStr, sal_Unicode cChar, sal_Int32 nCount )
196 {
197  for( sal_Int32 nIndex = 0; nIndex < nCount; ++nIndex )
198  rStr.append( cChar );
199 }
200 
201 void StringHelper::appendString( OUStringBuffer& rStr, const OUString& rData, sal_Int32 nWidth, sal_Unicode cFill )
202 {
203  appendChar( rStr, cFill, nWidth - rData.getLength() );
204  rStr.append( rData );
205 }
206 
207 // append decimal -------------------------------------------------------------
208 
209 void StringHelper::appendDec( OUStringBuffer& rStr, sal_uInt8 nData, sal_Int32 nWidth, sal_Unicode cFill )
210 {
211  appendString( rStr, OUString::number( nData ), nWidth, cFill );
212 }
213 
214 void StringHelper::appendDec( OUStringBuffer& rStr, sal_Int8 nData, sal_Int32 nWidth, sal_Unicode cFill )
215 {
216  appendString( rStr, OUString::number( nData ), nWidth, cFill );
217 }
218 
219 void StringHelper::appendDec( OUStringBuffer& rStr, sal_uInt16 nData, sal_Int32 nWidth, sal_Unicode cFill )
220 {
221  appendString( rStr, OUString::number( nData ), nWidth, cFill );
222 }
223 
224 void StringHelper::appendDec( OUStringBuffer& rStr, sal_Int16 nData, sal_Int32 nWidth, sal_Unicode cFill )
225 {
226  appendString( rStr, OUString::number( nData ), nWidth, cFill );
227 }
228 
229 void StringHelper::appendDec( OUStringBuffer& rStr, sal_uInt32 nData, sal_Int32 nWidth, sal_Unicode cFill )
230 {
231  appendString( rStr, OUString::number( nData ), nWidth, cFill );
232 }
233 
234 void StringHelper::appendDec( OUStringBuffer& rStr, sal_Int32 nData, sal_Int32 nWidth, sal_Unicode cFill )
235 {
236  appendString( rStr, OUString::number( nData ), nWidth, cFill );
237 }
238 
239 void StringHelper::appendDec( OUStringBuffer& rStr, sal_uInt64 nData, sal_Int32 nWidth, sal_Unicode cFill )
240 {
241  /* Values greater than biggest signed 64bit integer will change to
242  negative when converting to sal_Int64. Therefore, the trailing digit
243  will be written separately. */
244  OUStringBuffer aBuffer;
245  if( nData > 9 )
246  aBuffer.append( static_cast<sal_Int64>(nData / 10 ) );
247  aBuffer.append( static_cast< sal_Unicode >( '0' + (nData % 10) ) );
248  appendString( rStr, aBuffer.makeStringAndClear(), nWidth, cFill );
249 }
250 
251 void StringHelper::appendDec( OUStringBuffer& rStr, sal_Int64 nData, sal_Int32 nWidth, sal_Unicode cFill )
252 {
253  appendString( rStr, OUString::number( nData ), nWidth, cFill );
254 }
255 
256 void StringHelper::appendDec( OUStringBuffer& rStr, double fData, sal_Int32 nWidth, sal_Unicode cFill )
257 {
258  appendString( rStr, ::rtl::math::doubleToUString( fData, rtl_math_StringFormat_G, 15, '.', true ), nWidth, cFill );
259 }
260 
261 // append hexadecimal ---------------------------------------------------------
262 
263 void StringHelper::appendHex( OUStringBuffer& rStr, sal_uInt8 nData, bool bPrefix )
264 {
265  static const sal_Unicode spcHexDigits[] = { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' };
266  if( bPrefix )
267  rStr.append( "0x" );
268  rStr.append( spcHexDigits[ (nData >> 4) & 0x0F ] ).append( spcHexDigits[ nData & 0x0F ] );
269 }
270 
271 void StringHelper::appendHex( OUStringBuffer& rStr, sal_Int8 nData, bool bPrefix )
272 {
273  appendHex( rStr, static_cast< sal_uInt8 >( nData ), bPrefix );
274 }
275 
276 void StringHelper::appendHex( OUStringBuffer& rStr, sal_uInt16 nData, bool bPrefix )
277 {
278  appendHex( rStr, static_cast< sal_uInt8 >( nData >> 8 ), bPrefix );
279  appendHex( rStr, static_cast< sal_uInt8 >( nData ), false );
280 }
281 
282 void StringHelper::appendHex( OUStringBuffer& rStr, sal_Int16 nData, bool bPrefix )
283 {
284  appendHex( rStr, static_cast< sal_uInt16 >( nData ), bPrefix );
285 }
286 
287 void StringHelper::appendHex( OUStringBuffer& rStr, sal_uInt32 nData, bool bPrefix )
288 {
289  appendHex( rStr, static_cast< sal_uInt16 >( nData >> 16 ), bPrefix );
290  appendHex( rStr, static_cast< sal_uInt16 >( nData ), false );
291 }
292 
293 void StringHelper::appendHex( OUStringBuffer& rStr, sal_Int32 nData, bool bPrefix )
294 {
295  appendHex( rStr, static_cast< sal_uInt32 >( nData ), bPrefix );
296 }
297 
298 void StringHelper::appendHex( OUStringBuffer& rStr, sal_uInt64 nData, bool bPrefix )
299 {
300  appendHex( rStr, static_cast< sal_uInt32 >( nData >> 32 ), bPrefix );
301  appendHex( rStr, static_cast< sal_uInt32 >( nData ), false );
302 }
303 
304 void StringHelper::appendHex( OUStringBuffer& rStr, sal_Int64 nData, bool bPrefix )
305 {
306  appendHex( rStr, static_cast< sal_uInt64 >( nData ), bPrefix );
307 }
308 
309 static sal_uInt64
310 lcl_ConvertDouble(double const f)
311 {
312  sal_uInt64 i = sal_uInt64();
313  for (size_t j = 0; j < sizeof(double); ++j)
314  { // hopefully both endian independent and strict aliasing safe
315  reinterpret_cast<char *>(&i)[j] = reinterpret_cast<char const *>(&f)[j];
316  }
317  return i;
318 }
319 
320 void StringHelper::appendHex( OUStringBuffer& rStr, double fData, bool bPrefix )
321 {
322  appendHex( rStr, lcl_ConvertDouble(fData), bPrefix );
323 }
324 
325 // append shortened hexadecimal -----------------------------------------------
326 
327 void StringHelper::appendShortHex( OUStringBuffer& rStr, sal_uInt8 nData, bool bPrefix )
328 {
329  appendHex( rStr, nData, bPrefix );
330 }
331 
332 void StringHelper::appendShortHex( OUStringBuffer& rStr, sal_Int8 nData, bool bPrefix )
333 {
334  appendHex( rStr, nData, bPrefix );
335 }
336 
337 void StringHelper::appendShortHex( OUStringBuffer& rStr, sal_uInt16 nData, bool bPrefix )
338 {
339  if( nData > SAL_MAX_UINT8 )
340  appendHex( rStr, nData, bPrefix );
341  else
342  appendHex( rStr, static_cast< sal_uInt8 >( nData ), bPrefix );
343 }
344 
345 void StringHelper::appendShortHex( OUStringBuffer& rStr, sal_Int16 nData, bool bPrefix )
346 {
347  appendShortHex( rStr, static_cast< sal_uInt16 >( nData ), bPrefix );
348 }
349 
350 void StringHelper::appendShortHex( OUStringBuffer& rStr, sal_uInt32 nData, bool bPrefix )
351 {
352  if( nData > SAL_MAX_UINT16 )
353  appendHex( rStr, nData, bPrefix );
354  else
355  appendShortHex( rStr, static_cast< sal_uInt16 >( nData ), bPrefix );
356 }
357 
358 void StringHelper::appendShortHex( OUStringBuffer& rStr, sal_Int32 nData, bool bPrefix )
359 {
360  appendShortHex( rStr, static_cast< sal_uInt32 >( nData ), bPrefix );
361 }
362 
363 void StringHelper::appendShortHex( OUStringBuffer& rStr, sal_uInt64 nData, bool bPrefix )
364 {
365  if( nData > SAL_MAX_UINT32 )
366  appendHex( rStr, nData, bPrefix );
367  else
368  appendShortHex( rStr, static_cast< sal_uInt32 >( nData ), bPrefix );
369 }
370 
371 void StringHelper::appendShortHex( OUStringBuffer& rStr, sal_Int64 nData, bool bPrefix )
372 {
373  appendShortHex( rStr, static_cast< sal_uInt64 >( nData ), bPrefix );
374 }
375 
376 void StringHelper::appendShortHex( OUStringBuffer& rStr, double fData, bool bPrefix )
377 {
378  appendHex( rStr, fData, bPrefix );
379 }
380 
381 // append binary --------------------------------------------------------------
382 
383 void StringHelper::appendBin( OUStringBuffer& rStr, sal_uInt8 nData, bool bDots )
384 {
385  for( sal_uInt8 nMask = 0x80; nMask != 0; (nMask >>= 1) &= 0x7F )
386  {
387  rStr.append( static_cast< sal_Unicode >( (nData & nMask) ? '1' : '0' ) );
388  if( bDots && (nMask == 0x10) )
389  rStr.append( OOX_DUMP_BINDOT );
390  }
391 }
392 
393 void StringHelper::appendBin( OUStringBuffer& rStr, sal_Int8 nData, bool bDots )
394 {
395  appendBin( rStr, static_cast< sal_uInt8 >( nData ), bDots );
396 }
397 
398 void StringHelper::appendBin( OUStringBuffer& rStr, sal_uInt16 nData, bool bDots )
399 {
400  appendBin( rStr, static_cast< sal_uInt8 >( nData >> 8 ), bDots );
401  if( bDots )
402  rStr.append( OOX_DUMP_BINDOT );
403  appendBin( rStr, static_cast< sal_uInt8 >( nData ), bDots );
404 }
405 
406 void StringHelper::appendBin( OUStringBuffer& rStr, sal_Int16 nData, bool bDots )
407 {
408  appendBin( rStr, static_cast< sal_uInt16 >( nData ), bDots );
409 }
410 
411 void StringHelper::appendBin( OUStringBuffer& rStr, sal_uInt32 nData, bool bDots )
412 {
413  appendBin( rStr, static_cast< sal_uInt16 >( nData >> 16 ), bDots );
414  if( bDots )
415  rStr.append( OOX_DUMP_BINDOT );
416  appendBin( rStr, static_cast< sal_uInt16 >( nData ), bDots );
417 }
418 
419 void StringHelper::appendBin( OUStringBuffer& rStr, sal_Int32 nData, bool bDots )
420 {
421  appendBin( rStr, static_cast< sal_uInt32 >( nData ), bDots );
422 }
423 
424 void StringHelper::appendBin( OUStringBuffer& rStr, sal_uInt64 nData, bool bDots )
425 {
426  appendBin( rStr, static_cast< sal_uInt32 >( nData >> 32 ), bDots );
427  if( bDots )
428  rStr.append( OOX_DUMP_BINDOT );
429  appendBin( rStr, static_cast< sal_uInt32 >( nData ), bDots );
430 }
431 
432 void StringHelper::appendBin( OUStringBuffer& rStr, sal_Int64 nData, bool bDots )
433 {
434  appendBin( rStr, static_cast< sal_uInt64 >( nData ), bDots );
435 }
436 
437 void StringHelper::appendBin( OUStringBuffer& rStr, double fData, bool bDots )
438 {
439  appendBin( rStr, lcl_ConvertDouble(fData), bDots );
440 }
441 
442 // append formatted value -----------------------------------------------------
443 
444 void StringHelper::appendBool( OUStringBuffer& rStr, bool bData )
445 {
446  rStr.appendAscii( bData ? "true" : "false" );
447 }
448 
449 // encoded text output --------------------------------------------------------
450 
451 void StringHelper::appendCChar( OUStringBuffer& rStr, sal_Unicode cChar, bool bPrefix )
452 {
453  if( cChar > 0x00FF )
454  {
455  if( bPrefix )
456  rStr.append( "\\u" );
457  appendHex( rStr, static_cast< sal_uInt16 >( cChar ), false );
458  }
459  else
460  {
461  if( bPrefix )
462  rStr.append( "\\x" );
463  appendHex( rStr, static_cast< sal_uInt8 >( cChar ), false );
464  }
465 }
466 
467 void StringHelper::appendEncChar( OUStringBuffer& rStr, sal_Unicode cChar, sal_Int32 nCount, bool bPrefix )
468 {
469  if( cChar < 0x0020 )
470  {
471  // C-style hex code
472  OUStringBuffer aCode;
473  appendCChar( aCode, cChar, bPrefix );
474  OUString aCodeStr = aCode.makeStringAndClear();
475  for( sal_Int32 nIdx = 0; nIdx < nCount; ++nIdx )
476  rStr.append( aCodeStr );
477  }
478  else
479  {
480  appendChar( rStr, cChar, nCount );
481  }
482 }
483 
484 void StringHelper::appendEncString( OUStringBuffer& rStr, const OUString& rData, bool bPrefix )
485 {
486  sal_Int32 nBeg = 0;
487  sal_Int32 nIdx = 0;
488  sal_Int32 nEnd = rData.getLength();
489  while( nIdx < nEnd )
490  {
491  // find next character that needs encoding
492  while( (nIdx < nEnd) && (rData[ nIdx ] >= 0x20) ) ++nIdx;
493  // append portion
494  if( nBeg < nIdx )
495  {
496  if( (nBeg == 0) && (nIdx == nEnd) )
497  rStr.append( rData );
498  else
499  rStr.append( rData.subView(nBeg, nIdx - nBeg) );
500  }
501  // append characters to be encoded
502  while( (nIdx < nEnd) && (rData[ nIdx ] < 0x20) )
503  {
504  appendCChar( rStr, rData[ nIdx ], bPrefix );
505  ++nIdx;
506  }
507  // adjust limits
508  nBeg = nIdx;
509  }
510 }
511 
512 // token list -----------------------------------------------------------------
513 
514 void StringHelper::appendToken( OUStringBuffer& rStr, std::u16string_view rToken, sal_Unicode cSep )
515 {
516  if( (rStr.getLength() > 0) && (!rToken.empty()) )
517  rStr.append( cSep );
518  rStr.append( rToken );
519 }
520 
521 void StringHelper::appendIndex( OUStringBuffer& rStr, sal_Int64 nIdx )
522 {
523  OUStringBuffer aToken;
524  appendDec( aToken, nIdx );
525  rStr.append( '[' ).append( aToken.makeStringAndClear() ).append( ']' );
526 }
527 
528 OUString StringHelper::getToken( const OUString& rData, sal_Int32& rnPos, sal_Unicode cSep )
529 {
530  return trimSpaces( rData.getToken( 0, cSep, rnPos ) );
531 }
532 
533 void StringHelper::enclose( OUStringBuffer& rStr, sal_Unicode cOpen, sal_Unicode cClose )
534 {
535  rStr.insert( 0, cOpen ).append( cClose ? cClose : cOpen );
536 }
537 
538 // string conversion ----------------------------------------------------------
539 
540 namespace {
541 
542 sal_Int32 lclIndexOf( const OUString& rStr, sal_Unicode cChar, sal_Int32 nStartPos )
543 {
544  sal_Int32 nIndex = rStr.indexOf( cChar, nStartPos );
545  return (nIndex < 0) ? rStr.getLength() : nIndex;
546 }
547 
548 OUString lclTrimQuotedStringList( const OUString& rStr )
549 {
550  OUStringBuffer aBuffer;
551  sal_Int32 nPos = 0;
552  sal_Int32 nLen = rStr.getLength();
553  while( nPos < nLen )
554  {
555  if( rStr[ nPos ] == OOX_DUMP_CFG_QUOTE )
556  {
557  // quoted string, skip leading quote character
558  ++nPos;
559  // process quoted text and embedded literal quote characters
560  OUStringBuffer aToken;
561  do
562  {
563  // seek to next quote character and add text portion to token buffer
564  sal_Int32 nEnd = lclIndexOf( rStr, OOX_DUMP_CFG_QUOTE, nPos );
565  aToken.append( rStr.subView(nPos, nEnd - nPos) );
566  // process literal quotes
567  while( (nEnd + 1 < nLen) && (rStr[ nEnd ] == OOX_DUMP_CFG_QUOTE) && (rStr[ nEnd + 1 ] == OOX_DUMP_CFG_QUOTE) )
568  {
569  aToken.append( OOX_DUMP_CFG_QUOTE );
570  nEnd += 2;
571  }
572  // nEnd is start of possible next text portion
573  nPos = nEnd;
574  }
575  while( (nPos < nLen) && (rStr[ nPos ] != OOX_DUMP_CFG_QUOTE) );
576  // add token, seek to list separator, ignore text following closing quote
577  aBuffer.append( aToken.makeStringAndClear() );
578  nPos = lclIndexOf( rStr, OOX_DUMP_CFG_LISTSEP, nPos );
579  if( nPos < nLen )
580  aBuffer.append( OOX_DUMP_LF );
581  // set current position behind list separator
582  ++nPos;
583  }
584  else
585  {
586  // find list separator, add token text to buffer
587  sal_Int32 nEnd = lclIndexOf( rStr, OOX_DUMP_CFG_LISTSEP, nPos );
588  aBuffer.append( rStr.subView(nPos, nEnd - nPos) );
589  if( nEnd < nLen )
590  aBuffer.append( OOX_DUMP_LF );
591  // set current position behind list separator
592  nPos = nEnd + 1;
593  }
594  }
595 
596  return aBuffer.makeStringAndClear();
597 }
598 
599 } // namespace
600 
601 OUString StringHelper::trimSpaces( const OUString& rStr )
602 {
603  sal_Int32 nBeg = 0;
604  while( (nBeg < rStr.getLength()) && ((rStr[ nBeg ] == ' ') || (rStr[ nBeg ] == '\t')) )
605  ++nBeg;
606  sal_Int32 nEnd = rStr.getLength();
607  while( (nEnd > nBeg) && ((rStr[ nEnd - 1 ] == ' ') || (rStr[ nEnd - 1 ] == '\t')) )
608  --nEnd;
609  return rStr.copy( nBeg, nEnd - nBeg );
610 }
611 
612 OUString StringHelper::trimTrailingNul( const OUString& rStr )
613 {
614  sal_Int32 nLastPos = rStr.getLength() - 1;
615  if( (nLastPos >= 0) && (rStr[ nLastPos ] == 0) )
616  return rStr.copy( 0, nLastPos );
617  return rStr;
618 }
619 
620 OString StringHelper::convertToUtf8( std::u16string_view rStr )
621 {
622  return OUStringToOString( rStr, RTL_TEXTENCODING_UTF8 );
623 }
624 
625 DataType StringHelper::convertToDataType( std::u16string_view rStr )
626 {
628  if ( rStr == u"int8" )
629  eType = DATATYPE_INT8;
630  else if ( rStr == u"uint8" )
631  eType = DATATYPE_UINT8;
632  else if ( rStr == u"int16" )
633  eType = DATATYPE_INT16;
634  else if ( rStr == u"uint16" )
635  eType = DATATYPE_UINT16;
636  else if ( rStr == u"int32" )
637  eType = DATATYPE_INT32;
638  else if ( rStr == u"uint32" )
639  eType = DATATYPE_UINT32;
640  else if ( rStr == u"int64" )
641  eType = DATATYPE_INT64;
642  else if ( rStr == u"uint64" )
643  eType = DATATYPE_UINT64;
644  else if ( rStr == u"float" )
645  eType = DATATYPE_FLOAT;
646  else if ( rStr == u"double" )
647  eType = DATATYPE_DOUBLE;
648  return eType;
649 }
650 
652 {
654  if ( rStr == u"dec" )
655  eType = FORMATTYPE_DEC;
656  else if ( rStr == u"hex" )
657  eType = FORMATTYPE_HEX;
658  else if ( rStr == u"shorthex" )
659  eType = FORMATTYPE_SHORTHEX;
660  else if ( rStr == u"bin" )
661  eType = FORMATTYPE_BIN;
662  else if ( rStr == u"fix" )
663  eType = FORMATTYPE_FIX;
664  else if ( rStr == u"bool" )
665  eType = FORMATTYPE_BOOL;
666  return eType;
667 }
668 
669 bool StringHelper::convertFromDec( sal_Int64& ornData, const OUString& rData )
670 {
671  sal_Int32 nPos = 0;
672  sal_Int32 nLen = rData.getLength();
673  bool bNeg = false;
674  if( (nLen > 0) && (rData[ 0 ] == '-') )
675  {
676  bNeg = true;
677  ++nPos;
678  }
679  ornData = 0;
680  for( ; nPos < nLen; ++nPos )
681  {
682  sal_Unicode cChar = rData[ nPos ];
683  if( (cChar < '0') || (cChar > '9') )
684  return false;
685  ornData = (ornData * 10) + (cChar - '0');
686  }
687  if( bNeg )
688  ornData *= -1;
689  return true;
690 }
691 
692 bool StringHelper::convertFromHex( sal_Int64& ornData, const OUString& rData )
693 {
694  ornData = 0;
695  for( sal_Int32 nPos = 0, nLen = rData.getLength(); nPos < nLen; ++nPos )
696  {
697  sal_Unicode cChar = rData[ nPos ];
698  if( ('0' <= cChar) && (cChar <= '9') )
699  cChar -= '0';
700  else if( ('A' <= cChar) && (cChar <= 'F') )
701  cChar -= ('A' - 10);
702  else if( ('a' <= cChar) && (cChar <= 'f') )
703  cChar -= ('a' - 10);
704  else
705  return false;
706  ornData = (ornData << 4) + cChar;
707  }
708  return true;
709 }
710 
711 bool StringHelper::convertStringToInt( sal_Int64& ornData, const OUString& rData )
712 {
713  if( (rData.getLength() > 2) && (rData[ 0 ] == '0') && ((rData[ 1 ] == 'X') || (rData[ 1 ] == 'x')) )
714  return convertFromHex( ornData, rData.copy( 2 ) );
715  return convertFromDec( ornData, rData );
716 }
717 
718 bool StringHelper::convertStringToDouble( double& orfData, const OUString& rData )
719 {
720  rtl_math_ConversionStatus eStatus = rtl_math_ConversionStatus_Ok;
721  sal_Int32 nSize = 0;
722  orfData = rtl::math::stringToDouble( rData, '.', '\0', &eStatus, &nSize );
723  return (eStatus == rtl_math_ConversionStatus_Ok) && (nSize == rData.getLength());
724 }
725 
726 bool StringHelper::convertStringToBool( const OUString& rData )
727 {
728  if ( rData == "true" )
729  return true;
730  if ( rData == "false" )
731  return false;
732  sal_Int64 nData;
733  return convertStringToInt( nData, rData ) && (nData != 0);
734 }
735 
737 {
738  OUStringPair aPair;
739  if( !rString.isEmpty() )
740  {
741  sal_Int32 nEqPos = rString.indexOf( cSep );
742  if( nEqPos < 0 )
743  {
744  aPair.first = rString;
745  }
746  else
747  {
748  aPair.first = StringHelper::trimSpaces( rString.copy( 0, nEqPos ) );
749  aPair.second = StringHelper::trimSpaces( rString.copy( nEqPos + 1 ) );
750  }
751  }
752  return aPair;
753 }
754 
755 void StringHelper::convertStringToStringList( OUStringVector& orVec, const OUString& rData, bool bIgnoreEmpty )
756 {
757  orVec.clear();
758  OUString aUnquotedData = lclTrimQuotedStringList( rData );
759  sal_Int32 nPos = 0;
760  sal_Int32 nLen = aUnquotedData.getLength();
761  while( (0 <= nPos) && (nPos < nLen) )
762  {
763  OUString aToken = getToken( aUnquotedData, nPos, OOX_DUMP_LF );
764  if( !bIgnoreEmpty || !aToken.isEmpty() )
765  orVec.push_back( aToken );
766  }
767 }
768 
769 void StringHelper::convertStringToIntList( Int64Vector& orVec, const OUString& rData, bool bIgnoreEmpty )
770 {
771  orVec.clear();
772  OUString aUnquotedData = lclTrimQuotedStringList( rData );
773  sal_Int32 nPos = 0;
774  sal_Int32 nLen = aUnquotedData.getLength();
775  sal_Int64 nData;
776  while( (0 <= nPos) && (nPos < nLen) )
777  {
778  bool bOk = convertStringToInt( nData, getToken( aUnquotedData, nPos, OOX_DUMP_LF ) );
779  if( !bIgnoreEmpty || bOk )
780  orVec.push_back( bOk ? nData : 0 );
781  }
782 }
783 
785 {
786 }
787 
789 {
790 }
791 
793 {
794  readConfigBlockContents( rStrm );
795 }
796 
798  TextInputStream& /*rStrm*/, const OUString& /*rKey*/, const OUString& /*rData*/ )
799 {
800 }
801 
803  TextInputStream& /*rStrm*/, sal_Int64 /*nKey*/, const OUString& /*rData*/ )
804 {
805 }
806 
808 {
809  bool bLoop = true;
810  while( bLoop && !rStrm.isEof() )
811  {
812  OUString aKey, aData;
813  switch( readConfigLine( rStrm, aKey, aData ) )
814  {
815  case LINETYPE_DATA:
816  processConfigItem( rStrm, aKey, aData );
817  break;
818  case LINETYPE_END:
819  bLoop = false;
820  break;
821  }
822  }
823 }
824 
826  TextInputStream& rStrm, OUString& orKey, OUString& orData )
827 {
828  OUString aLine;
829  while( !rStrm.isEof() && aLine.isEmpty() )
830  {
831  aLine = rStrm.readLine();
832  if( !aLine.isEmpty() && (aLine[ 0 ] == OOX_DUMP_BOM) )
833  aLine = aLine.copy( 1 );
834  aLine = StringHelper::trimSpaces( aLine );
835  if( !aLine.isEmpty() )
836  {
837  // ignore comments (starting with hash or semicolon)
838  sal_Unicode cChar = aLine[ 0 ];
839  if( (cChar == '#') || (cChar == ';') )
840  aLine.clear();
841  }
842  }
843 
845  orKey = aPair.first;
846  orData = aPair.second;
847  return ( !orKey.isEmpty() && (!orData.isEmpty() || orKey != "end" )) ?
849 }
850 
852  TextInputStream& rStrm, const OUString& rKey, const OUString& rData )
853 {
854  sal_Int64 nKey;
855  if( StringHelper::convertStringToInt( nKey, rKey ) )
856  implProcessConfigItemInt( rStrm, nKey, rData );
857  else
858  implProcessConfigItemStr( rStrm, rKey, rData );
859 }
860 
862 {
863 }
864 
865 void NameListBase::setName( sal_Int64 nKey, const String& rName )
866 {
867  implSetName( nKey, rName );
868 }
869 
871 {
872  if( rxList )
873  {
874  for (auto const& elem : *rxList)
875  maMap[ elem.first ] = elem.second;
876  implIncludeList( *rxList );
877  }
878 }
879 
881 {
882  return true;
883 }
884 
886  TextInputStream& rStrm, const OUString& rKey, const OUString& rData )
887 {
888  if ( rKey == "include" )
889  include( rData );
890  else if ( rKey == "exclude" )
891  exclude( rData );
892  else
893  ConfigItemBase::implProcessConfigItemStr( rStrm, rKey, rData );
894 }
895 
897  TextInputStream& /*rStrm*/, sal_Int64 nKey, const OUString& rData )
898 {
899  implSetName( nKey, rData );
900 }
901 
902 void NameListBase::insertRawName( sal_Int64 nKey, const OUString& rName )
903 {
904  maMap[ nKey ] = rName;
905 }
906 
907 const OUString* NameListBase::findRawName( sal_Int64 nKey ) const
908 {
909  const_iterator aIt = maMap.find( nKey );
910  return (aIt == end()) ? nullptr : &aIt->second;
911 }
912 
913 void NameListBase::include( const OUString& rListKeys )
914 {
915  OUStringVector aVec;
916  StringHelper::convertStringToStringList( aVec, rListKeys, true );
917  for (auto const& elem : aVec)
919 }
920 
921 void NameListBase::exclude( const OUString& rKeys )
922 {
923  Int64Vector aVec;
924  StringHelper::convertStringToIntList( aVec, rKeys, true );
925  for (auto const& elem : aVec)
926  maMap.erase(elem);
927 }
928 
929 void ItemFormatMap::insertFormats( const NameListRef& rxNameList )
930 {
931  if( Base::isValid( rxNameList ) )
932  {
933  for (auto const& elemName : *rxNameList)
934  maMap[ elemName.first ].parse( elemName.second );
935  }
936 }
937 
939  NameListBase( rCfgData ),
940  maDefName( OOX_DUMP_ERR_NONAME ),
941  mbQuoteNames( false )
942 {
943 }
944 
946  TextInputStream& rStrm, const OUString& rKey, const OUString& rData )
947 {
948  if ( rKey == "default" )
949  maDefName = rData; // Sets a default name for unknown keys.
950  else if ( rKey == "quote-names" )
952  else
953  NameListBase::implProcessConfigItemStr( rStrm, rKey, rData );
954 }
955 
956 void ConstList::implSetName( sal_Int64 nKey, const OUString& rName )
957 {
958  insertRawName( nKey, rName );
959 }
960 
961 OUString ConstList::implGetName( const Config& /*rCfg*/, sal_Int64 nKey ) const
962 {
963  const OUString* pName = findRawName( nKey );
964  OUString aName = pName ? *pName : maDefName;
965  if( mbQuoteNames )
966  {
967  OUStringBuffer aBuffer( aName );
969  aName = aBuffer.makeStringAndClear();
970  }
971  return aName;
972 }
973 
974 OUString ConstList::implGetNameDbl( const Config& /*rCfg*/, double /*fValue*/ ) const
975 {
976  return OUString();
977 }
978 
980 {
981  if( const ConstList* pConstList = dynamic_cast< const ConstList* >( &rList ) )
982  {
983  maDefName = pConstList->maDefName;
984  mbQuoteNames = pConstList->mbQuoteNames;
985  }
986 }
987 
989  ConstList( rCfgData ),
990  mbIgnoreEmpty( true )
991 {
992 }
993 
994 void MultiList::setNamesFromVec( sal_Int64 nStartKey, const OUStringVector& rNames )
995 {
996  sal_Int64 nKey = nStartKey;
997  for (auto const& name : rNames)
998  {
999  if( !mbIgnoreEmpty || !name.isEmpty() )
1000  insertRawName( nKey, name);
1001  ++nKey;
1002  }
1003 }
1004 
1006  TextInputStream& rStrm, const OUString& rKey, const OUString& rData )
1007 {
1008  if ( rKey == "ignore-empty" )
1010  else
1011  ConstList::implProcessConfigItemStr( rStrm, rKey, rData );
1012 }
1013 
1014 void MultiList::implSetName( sal_Int64 nKey, const OUString& rName )
1015 {
1016  OUStringVector aNames;
1017  StringHelper::convertStringToStringList( aNames, rName, false );
1018  setNamesFromVec( nKey, aNames );
1019 }
1020 
1022  NameListBase( rCfgData ),
1023  mnIgnore( 0 )
1024 {
1025 }
1026 
1028  TextInputStream& rStrm, const OUString& rKey, const OUString& rData )
1029 {
1030  if ( rKey == "ignore" )
1031  {
1032  sal_Int64 nIgnore;
1033  if( StringHelper::convertStringToInt( nIgnore, rData ) )
1034  setIgnoreFlags( nIgnore );
1035  }
1036  else
1037  {
1038  NameListBase::implProcessConfigItemStr( rStrm, rKey, rData );
1039  }
1040 }
1041 
1042 void FlagsList::implSetName( sal_Int64 nKey, const OUString& rName )
1043 {
1044  if( (nKey != 0) && ((nKey & (nKey - 1)) == 0) ) // only a single bit set?
1045  insertRawName( nKey, rName );
1046 }
1047 
1048 OUString FlagsList::implGetName( const Config& /*rCfg*/, sal_Int64 nKey ) const
1049 {
1050  sal_Int64 nFound = mnIgnore;
1051  OUStringBuffer aName;
1052  // add known flags
1053  for( const_iterator aIt = begin(), aEnd = end(); aIt != aEnd; ++aIt )
1054  {
1055  sal_Int64 nMask = aIt->first;
1056  setFlag( nFound, nMask );
1057  if( !getFlag( mnIgnore, nMask ) )
1058  {
1059  const OUString& rFlagName = aIt->second;
1060  bool bOnOff = rFlagName.startsWith(":");
1061  bool bFlag = getFlag( nKey, nMask );
1062  if( bOnOff )
1063  {
1064  StringHelper::appendToken( aName, rFlagName.subView( 1 ) );
1065  aName.appendAscii( bFlag ? ":on" : ":off" );
1066  }
1067  else
1068  {
1069  bool bNegated = rFlagName.startsWith("!");
1070  sal_Int32 nBothSep = bNegated ? rFlagName.indexOf( '!', 1 ) : -1;
1071  if( bFlag )
1072  {
1073  if( !bNegated )
1074  StringHelper::appendToken( aName, rFlagName );
1075  else if( nBothSep > 0 )
1076  StringHelper::appendToken( aName, rFlagName.subView( nBothSep + 1 ) );
1077  }
1078  else if( bNegated )
1079  {
1080  if( nBothSep > 0 )
1081  StringHelper::appendToken( aName, rFlagName.subView( 1, nBothSep - 1 ) );
1082  else
1083  StringHelper::appendToken( aName, rFlagName.subView( 1 ) );
1084  }
1085  }
1086  }
1087  }
1088  // add unknown flags
1089  setFlag( nKey, nFound, false );
1090  if( nKey != 0 )
1091  {
1092  OUStringBuffer aUnknown( OOX_DUMP_UNKNOWN );
1093  aUnknown.append( OOX_DUMP_ITEMSEP );
1094  StringHelper::appendShortHex( aUnknown, nKey );
1095  StringHelper::enclose( aUnknown, '(', ')' );
1096  StringHelper::appendToken( aName, aUnknown.makeStringAndClear() );
1097  }
1098  return aName.makeStringAndClear();
1099 }
1100 
1101 OUString FlagsList::implGetNameDbl( const Config& /*rCfg*/, double /*fValue*/ ) const
1102 {
1103  return OUString();
1104 }
1105 
1107 {
1108  if( const FlagsList* pFlagsList = dynamic_cast< const FlagsList* >( &rList ) )
1109  mnIgnore = pFlagsList->mnIgnore;
1110 }
1111 
1113 {
1114  return (mnKey < rRight.mnKey) || ((mnKey == rRight.mnKey) && (maFilter < rRight.maFilter));
1115 }
1116 
1118  FlagsList( rCfgData )
1119 {
1120 }
1121 
1122 void CombiList::implSetName( sal_Int64 nKey, const OUString& rName )
1123 {
1124  if( (nKey & (nKey - 1)) != 0 ) // more than a single bit set?
1125  {
1126  ::std::set< ExtItemFormatKey > aItemKeys;
1127  ExtItemFormat aItemFmt;
1128  OUStringVector aRemain = aItemFmt.parse( rName );
1129  for (auto const& elemRemain : aRemain)
1130  {
1131  OUStringPair aPair = StringHelper::convertStringToPair(elemRemain);
1132  if ( aPair.first == "noshift" )
1133  {
1134  aItemFmt.mbShiftValue = StringHelper::convertStringToBool( aPair.second );
1135  }
1136  else if ( aPair.first == "filter" )
1137  {
1138  OUStringPair aFilter = StringHelper::convertStringToPair( aPair.second, '~' );
1139  ExtItemFormatKey aKey( nKey );
1140  if( !aFilter.first.isEmpty() && StringHelper::convertStringToInt( aKey.maFilter.first, aFilter.first ) &&
1141  !aFilter.second.isEmpty() && StringHelper::convertStringToInt( aKey.maFilter.second, aFilter.second ) )
1142  {
1143  if( aKey.maFilter.first == 0 )
1144  aKey.maFilter.second = 0;
1145  aItemKeys.insert( aKey );
1146  }
1147  }
1148  }
1149  if( aItemKeys.empty() )
1150  aItemKeys.insert( ExtItemFormatKey( nKey ) );
1151  for (auto const& itemKey : aItemKeys)
1152  maFmtMap[itemKey] = aItemFmt;
1153  }
1154  else
1155  {
1156  FlagsList::implSetName( nKey, rName );
1157  }
1158 }
1159 
1160 OUString CombiList::implGetName( const Config& rCfg, sal_Int64 nKey ) const
1161 {
1162  sal_Int64 nFound = 0;
1163  OUStringBuffer aName;
1164  // add known flag fields
1165  for (auto const& fmt : maFmtMap)
1166  {
1167  const ExtItemFormatKey& rMapKey = fmt.first;
1168  sal_Int64 nMask = rMapKey.mnKey;
1169  if( (nMask != 0) && ((nKey & rMapKey.maFilter.first) == rMapKey.maFilter.second) )
1170  {
1171  const ExtItemFormat& rItemFmt = fmt.second;
1172 
1173  sal_uInt64 nUFlags = static_cast< sal_uInt64 >( nKey );
1174  sal_uInt64 nUMask = static_cast< sal_uInt64 >( nMask );
1175  if( rItemFmt.mbShiftValue )
1176  while( (nUMask & 1) == 0 ) { nUFlags >>= 1; nUMask >>= 1; }
1177 
1178  sal_uInt64 nUValue = nUFlags & nUMask;
1179  sal_Int64 nSValue = static_cast< sal_Int64 >( nUValue );
1180  if( getFlag< sal_uInt64 >( nUValue, (nUMask + 1) >> 1 ) )
1181  setFlag( nSValue, static_cast< sal_Int64 >( ~nUMask ) );
1182 
1183  OUStringBuffer aItem( rItemFmt.maItemName );
1184  OUStringBuffer aValue;
1185  switch( rItemFmt.meDataType )
1186  {
1187  case DATATYPE_INT8: StringHelper::appendValue( aValue, static_cast< sal_Int8 >( nSValue ), rItemFmt.meFmtType ); break;
1188  case DATATYPE_UINT8: StringHelper::appendValue( aValue, static_cast< sal_uInt8 >( nUValue ), rItemFmt.meFmtType ); break;
1189  case DATATYPE_INT16: StringHelper::appendValue( aValue, static_cast< sal_Int16 >( nSValue ), rItemFmt.meFmtType ); break;
1190  case DATATYPE_UINT16: StringHelper::appendValue( aValue, static_cast< sal_uInt16 >( nUValue ), rItemFmt.meFmtType ); break;
1191  case DATATYPE_INT32: StringHelper::appendValue( aValue, static_cast< sal_Int32 >( nSValue ), rItemFmt.meFmtType ); break;
1192  case DATATYPE_UINT32: StringHelper::appendValue( aValue, static_cast< sal_uInt32 >( nUValue ), rItemFmt.meFmtType ); break;
1193  case DATATYPE_INT64: StringHelper::appendValue( aValue, nSValue, rItemFmt.meFmtType ); break;
1194  case DATATYPE_UINT64: StringHelper::appendValue( aValue, nUValue, rItemFmt.meFmtType ); break;
1195  case DATATYPE_FLOAT: StringHelper::appendValue( aValue, static_cast< float >( nSValue ), rItemFmt.meFmtType ); break;
1196  case DATATYPE_DOUBLE: StringHelper::appendValue( aValue, static_cast< double >( nSValue ), rItemFmt.meFmtType ); break;
1197  default:;
1198  }
1199  StringHelper::appendToken( aItem, aValue.makeStringAndClear(), OOX_DUMP_ITEMSEP );
1200  if( !rItemFmt.maListName.isEmpty() )
1201  {
1202  OUString aValueName = rCfg.getName( rItemFmt.maListName, static_cast< sal_Int64 >( nUValue ) );
1203  StringHelper::appendToken( aItem, aValueName, OOX_DUMP_ITEMSEP );
1204  }
1205  StringHelper::enclose( aItem, '(', ')' );
1206  StringHelper::appendToken( aName, aItem.makeStringAndClear() );
1207  setFlag( nFound, nMask );
1208  }
1209  }
1210  setFlag( nKey, nFound, false );
1211  StringHelper::appendToken( aName, FlagsList::implGetName( rCfg, nKey ) );
1212  return aName.makeStringAndClear();
1213 }
1214 
1216 {
1217  if( const CombiList* pCombiList = dynamic_cast< const CombiList* >( &rList ) )
1218  maFmtMap = pCombiList->maFmtMap;
1219  FlagsList::implIncludeList( rList );
1220 }
1221 
1223  NameListBase( rCfgData ),
1224  mfFactor( 1.0 )
1225 {
1226 }
1227 
1228 void UnitConverter::implSetName( sal_Int64 /*nKey*/, const OUString& /*rName*/ )
1229 {
1230  // nothing to do
1231 }
1232 
1233 OUString UnitConverter::implGetName( const Config& rCfg, sal_Int64 nKey ) const
1234 {
1235  return implGetNameDbl( rCfg, static_cast< double >( nKey ) );
1236 }
1237 
1238 OUString UnitConverter::implGetNameDbl( const Config& /*rCfg*/, double fValue ) const
1239 {
1240  OUStringBuffer aValue;
1241  StringHelper::appendDec( aValue, mfFactor * fValue );
1242  aValue.append( maUnitName );
1243  return aValue.makeStringAndClear();
1244 }
1245 
1247 {
1248 }
1249 
1251 {
1252  if (!mxList)
1253  mxList = rCfg.getNameList( maName );
1254  return mxList;
1255 }
1256 
1257 SharedConfigData::SharedConfigData( const OUString& rFileName,
1258  const Reference< XComponentContext >& rxContext, const StorageRef& rxRootStrg,
1259  const OUString& rSysFileName ) :
1260  mxContext( rxContext ),
1261  mxRootStrg( rxRootStrg ),
1262  maSysFileName( rSysFileName ),
1263  mbLoaded( false )
1264 {
1265  OUString aFileUrl = InputOutputHelper::convertFileNameToUrl( rFileName );
1266  if( !aFileUrl.isEmpty() )
1267  {
1268  sal_Int32 nNamePos = InputOutputHelper::getFileNamePos( aFileUrl );
1269  maConfigPath = aFileUrl.copy( 0, nNamePos );
1270  mbLoaded = readConfigFile( aFileUrl );
1271  }
1272 }
1273 
1275 {
1276 }
1277 
1278 const OUString* SharedConfigData::getOption( const OUString& rKey ) const
1279 {
1280  ConfigDataMap::const_iterator aIt = maConfigData.find( rKey );
1281  return (aIt == maConfigData.end()) ? nullptr : &aIt->second;
1282 }
1283 
1284 void SharedConfigData::setNameList( const OUString& rListName, const NameListRef& rxList )
1285 {
1286  if( !rListName.isEmpty() )
1287  maNameLists[ rListName ] = rxList;
1288 }
1289 
1290 void SharedConfigData::eraseNameList( const OUString& rListName )
1291 {
1292  maNameLists.erase( rListName );
1293 }
1294 
1295 NameListRef SharedConfigData::getNameList( const OUString& rListName ) const
1296 {
1297  NameListRef xList;
1298  NameListMap::const_iterator aIt = maNameLists.find( rListName );
1299  if( aIt != maNameLists.end() )
1300  xList = aIt->second;
1301  return xList;
1302 }
1303 
1305 {
1306  return mbLoaded && mxContext.is() && mxRootStrg && !maSysFileName.isEmpty();
1307 }
1308 
1310  TextInputStream& rStrm, const OUString& rKey, const OUString& rData )
1311 {
1312  if ( rKey == "include-config-file" )
1313  readConfigFile( maConfigPath + rData );
1314  else if ( rKey == "constlist" )
1315  readNameList< ConstList >( rStrm, rData );
1316  else if ( rKey == "multilist" )
1317  readNameList< MultiList >( rStrm, rData );
1318  else if ( rKey == "flagslist" )
1319  readNameList< FlagsList >( rStrm, rData );
1320  else if ( rKey == "combilist" )
1321  readNameList< CombiList >( rStrm, rData );
1322  else if ( rKey == "shortlist" )
1323  createShortList( rData );
1324  else if ( rKey == "unitconverter" )
1325  createUnitConverter( rData );
1326  else
1327  maConfigData[ rKey ] = rData;
1328 }
1329 
1330 bool SharedConfigData::readConfigFile( const OUString& rFileUrl )
1331 {
1332  bool bLoaded = maConfigFiles.count( rFileUrl ) > 0;
1333  if( !bLoaded )
1334  {
1336  TextInputStream aTxtStrm( mxContext, xInStrm, RTL_TEXTENCODING_UTF8 );
1337  if( !aTxtStrm.isEof() )
1338  {
1339  maConfigFiles.insert( rFileUrl );
1340  readConfigBlockContents( aTxtStrm );
1341  bLoaded = true;
1342  }
1343  }
1344  return bLoaded;
1345 }
1346 
1347 void SharedConfigData::createShortList( const OUString& rData )
1348 {
1349  OUStringVector aDataVec;
1350  StringHelper::convertStringToStringList( aDataVec, rData, false );
1351  if( aDataVec.size() < 3 )
1352  return;
1353 
1354  sal_Int64 nStartKey;
1355  if( StringHelper::convertStringToInt( nStartKey, aDataVec[ 1 ] ) )
1356  {
1357  std::shared_ptr< MultiList > xList = createNameList< MultiList >( aDataVec[ 0 ] );
1358  if( xList )
1359  {
1360  aDataVec.erase( aDataVec.begin(), aDataVec.begin() + 2 );
1361  xList->setNamesFromVec( nStartKey, aDataVec );
1362  }
1363  }
1364 }
1365 
1366 void SharedConfigData::createUnitConverter( const OUString& rData )
1367 {
1368  OUStringVector aDataVec;
1369  StringHelper::convertStringToStringList( aDataVec, rData, false );
1370  if( aDataVec.size() < 2 )
1371  return;
1372 
1373  OUString aFactor = aDataVec[ 1 ];
1374  bool bRecip = aFactor.startsWith("/");
1375  if( bRecip )
1376  aFactor = aFactor.copy( 1 );
1377  double fFactor;
1378  if( StringHelper::convertStringToDouble( fFactor, aFactor ) && (fFactor != 0.0) )
1379  {
1380  std::shared_ptr< UnitConverter > xList = createNameList< UnitConverter >( aDataVec[ 0 ] );
1381  if( xList )
1382  {
1383  xList->setFactor( bRecip ? (1.0 / fFactor) : fFactor );
1384  if( aDataVec.size() >= 3 )
1385  xList->setUnitName( aDataVec[ 2 ] );
1386  }
1387  }
1388 }
1389 
1390 Config::Config( const char* pcEnvVar, const FilterBase& rFilter )
1391 {
1392  construct( pcEnvVar, rFilter );
1393 }
1394 
1395 Config::Config( const char* pcEnvVar, const Reference< XComponentContext >& rxContext, const StorageRef& rxRootStrg, const OUString& rSysFileName )
1396 {
1397  construct( pcEnvVar, rxContext, rxRootStrg, rSysFileName );
1398 }
1399 
1401 {
1402 }
1403 
1404 void Config::construct( const char* pcEnvVar, const FilterBase& rFilter )
1405 {
1406  if( !rFilter.getFileUrl().isEmpty() )
1407  construct( pcEnvVar, rFilter.getComponentContext(), rFilter.getStorage(), rFilter.getFileUrl() );
1408 }
1409 
1410 void Config::construct( const char* pcEnvVar, const Reference< XComponentContext >& rxContext, const StorageRef& rxRootStrg, const OUString& rSysFileName )
1411 {
1412  if( pcEnvVar && rxRootStrg && !rSysFileName.isEmpty() )
1413  if( const char* pcFileName = ::getenv( pcEnvVar ) )
1414  mxCfgData = std::make_shared<SharedConfigData>( OUString::createFromAscii( pcFileName ), rxContext, rxRootStrg, rSysFileName );
1415 }
1416 
1417 const OUString& Config::getStringOption( const String& rKey, const OUString& rDefault ) const
1418 {
1419  const OUString* pData = implGetOption( rKey );
1420  return pData ? *pData : rDefault;
1421 }
1422 
1423 bool Config::getBoolOption( const String& rKey, bool bDefault ) const
1424 {
1425  const OUString* pData = implGetOption( rKey );
1426  return pData ? StringHelper::convertStringToBool( *pData ) : bDefault;
1427 }
1428 
1430 {
1431  return getBoolOption( "enable-dumper", false );
1432 }
1433 
1435 {
1436  return getBoolOption( "enable-import", true );
1437 }
1438 
1439 void Config::eraseNameList( const String& rListName )
1440 {
1441  mxCfgData->eraseNameList( rListName );
1442 }
1443 
1444 NameListRef Config::getNameList( const String& rListName ) const
1445 {
1446  return mxCfgData->getNameList( rListName );
1447 }
1448 
1450 {
1451  return isValid( mxCfgData );
1452 }
1453 
1454 const OUString* Config::implGetOption( const OUString& rKey ) const
1455 {
1456  return mxCfgData->getOption( rKey );
1457 }
1458 
1459 Output::Output( const Reference< XComponentContext >& rxContext, const OUString& rFileName ) :
1460  mxStrm( InputOutputHelper::openTextOutputStream( rxContext, rFileName, RTL_TEXTENCODING_UTF8 ) ),
1461  mnCol( 0 ),
1462  mnItemLevel( 0 ),
1463  mnMultiLevel( 0 ),
1464  mnItemIdx( 0 ),
1465  mnLastItem( 0 )
1466 {
1467  if( mxStrm.is() )
1468  mxStrm->writeString( OUString( OOX_DUMP_BOM ) );
1469 }
1470 
1472 {
1473  if( maLine.getLength() > 0 )
1474  {
1475  mxStrm->writeString( maIndent );
1476  maLine.append( '\n' );
1477  mxStrm->writeString( maLine.makeStringAndClear() );
1478  mnCol = 0;
1479  mnLastItem = 0;
1480  }
1481 }
1482 
1484 {
1485  for( size_t nIdx = 0; nIdx < nCount; ++nIdx )
1486  mxStrm->writeString( OUString('\n') );
1487 }
1488 
1490 {
1491  OUStringBuffer aBuffer( maIndent );
1492  StringHelper::appendChar( aBuffer, ' ', OOX_DUMP_INDENT );
1493  maIndent = aBuffer.makeStringAndClear();
1494 }
1495 
1497 {
1498  if( maIndent.getLength() >= OOX_DUMP_INDENT )
1499  maIndent = maIndent.copy( OOX_DUMP_INDENT );
1500 }
1501 
1502 void Output::startTable( sal_Int32 nW1 )
1503 {
1504  startTable( 1, &nW1 );
1505 }
1506 
1507 void Output::startTable( sal_Int32 nW1, sal_Int32 nW2 )
1508 {
1509  sal_Int32 pnColWidths[ 2 ];
1510  pnColWidths[ 0 ] = nW1;
1511  pnColWidths[ 1 ] = nW2;
1512  startTable( 2, pnColWidths );
1513 }
1514 
1515 void Output::startTable( sal_Int32 nW1, sal_Int32 nW2, sal_Int32 nW3, sal_Int32 nW4 )
1516 {
1517  sal_Int32 pnColWidths[ 4 ];
1518  pnColWidths[ 0 ] = nW1;
1519  pnColWidths[ 1 ] = nW2;
1520  pnColWidths[ 2 ] = nW3;
1521  pnColWidths[ 3 ] = nW4;
1522  startTable( 4, pnColWidths );
1523 }
1524 
1525 void Output::startTable( size_t nColCount, const sal_Int32* pnColWidths )
1526 {
1527  maColPos.clear();
1528  maColPos.push_back( 0 );
1529  sal_Int32 nColPos = 0;
1530  for( size_t nCol = 0; nCol < nColCount; ++nCol )
1531  {
1532  nColPos = nColPos + pnColWidths[ nCol ];
1533  maColPos.push_back( nColPos );
1534  }
1535 }
1536 
1538 {
1539  tab( mnCol + 1 );
1540 }
1541 
1542 void Output::tab( size_t nCol )
1543 {
1544  mnCol = nCol;
1545  if( mnCol < maColPos.size() )
1546  {
1547  sal_Int32 nColPos = maColPos[ mnCol ];
1548  if( maLine.getLength() >= nColPos )
1549  maLine.setLength( ::std::max< sal_Int32 >( nColPos - 1, 0 ) );
1550  StringHelper::appendChar( maLine, ' ', nColPos - maLine.getLength() );
1551  }
1552  else
1553  {
1554  StringHelper::appendChar( maLine, ' ', 2 );
1555  }
1556 }
1557 
1559 {
1560  maColPos.clear();
1561 }
1562 
1563 void Output::resetItemIndex( sal_Int64 nIdx )
1564 {
1565  mnItemIdx = nIdx;
1566 }
1567 
1568 void Output::startItem( const String& rItemName )
1569 {
1570  if( mnItemLevel == 0 )
1571  {
1572  if( (mnMultiLevel > 0) && (maLine.getLength() > 0) )
1573  tab();
1574  if( rItemName.has() )
1575  {
1576  writeItemName( rItemName );
1577  writeChar( OOX_DUMP_ITEMSEP );
1578  }
1579  }
1580  ++mnItemLevel;
1581  mnLastItem = maLine.getLength();
1582 }
1583 
1585 {
1586  if( mnItemLevel > 0 )
1587  {
1588  if( (maLine.getLength() == 0) || (maLine[ maLine.getLength() - 1 ] != OOX_DUMP_ITEMSEP) )
1589  writeChar( OOX_DUMP_ITEMSEP );
1590  mnLastItem = maLine.getLength();
1591  }
1592 }
1593 
1595 {
1596  if( mnItemLevel > 0 )
1597  {
1598  maLastItem = maLine.copy( mnLastItem ).makeStringAndClear();
1599  if( maLastItem.isEmpty() && mnLastItem > 0 && maLine[ mnLastItem - 1 ] == OOX_DUMP_ITEMSEP )
1600  maLine.setLength( mnLastItem - 1 );
1601  --mnItemLevel;
1602  }
1603  if( mnItemLevel == 0 )
1604  {
1605  if( mnMultiLevel == 0 )
1606  newLine();
1607  }
1608  else
1609  contItem();
1610 }
1611 
1613 {
1614  ++mnMultiLevel;
1615 }
1616 
1618 {
1619  if( mnMultiLevel > 0 )
1620  --mnMultiLevel;
1621  if( mnMultiLevel == 0 )
1622  newLine();
1623 }
1624 
1625 void Output::writeChar( sal_Unicode cChar, sal_Int32 nCount )
1626 {
1627  StringHelper::appendEncChar( maLine, cChar, nCount );
1628 }
1629 
1630 void Output::writeAscii( const char* pcStr )
1631 {
1632  if( pcStr )
1633  maLine.appendAscii( pcStr );
1634 }
1635 
1636 void Output::writeString( const OUString& rStr )
1637 {
1639 }
1640 
1641 void Output::writeArray( const sal_uInt8* pnData, std::size_t nSize, sal_Unicode cSep )
1642 {
1643  const sal_uInt8* pnEnd = pnData ? (pnData + nSize) : nullptr;
1644  for( const sal_uInt8* pnByte = pnData; pnByte < pnEnd; ++pnByte )
1645  {
1646  if( pnByte > pnData )
1647  writeChar( cSep );
1648  writeHex( *pnByte, false );
1649  }
1650 }
1651 
1652 void Output::writeBool( bool bData )
1653 {
1654  StringHelper::appendBool( maLine, bData );
1655 }
1656 
1657 void Output::writeDateTime( const util::DateTime& rDateTime )
1658 {
1659  writeDec( rDateTime.Year, 4, '0' );
1660  writeChar( '-' );
1661  writeDec( rDateTime.Month, 2, '0' );
1662  writeChar( '-' );
1663  writeDec( rDateTime.Day, 2, '0' );
1664  writeChar( 'T' );
1665  writeDec( rDateTime.Hours, 2, '0' );
1666  writeChar( ':' );
1667  writeDec( rDateTime.Minutes, 2, '0' );
1668  writeChar( ':' );
1669  writeDec( rDateTime.Seconds, 2, '0' );
1670 }
1671 
1673 {
1674  return mxStrm.is();
1675 }
1676 
1677 void Output::writeItemName( const String& rItemName )
1678 {
1679  if( rItemName.has() && (rItemName[ 0 ] == '#') )
1680  {
1681  writeString( rItemName.copy( 1 ) );
1683  }
1684  else
1685  writeString( rItemName );
1686 }
1687 
1689  mxStrg( rxStrg )
1690 {
1691  if( mxStrg )
1692  mxStrg->getElementNames( maNames );
1693  maIt = maNames.begin();
1694 }
1695 
1697 {
1698 }
1699 
1701 {
1702  if( maIt != maNames.end() )
1703  ++maIt;
1704  return *this;
1705 }
1706 
1708 {
1709  OUString aName;
1710  if( maIt != maNames.end() )
1711  aName = *maIt;
1712  return aName;
1713 }
1714 
1716 {
1717  return isValid() && mxStrg->openInputStream( *maIt ).is();
1718 }
1719 
1721 {
1722  if( !isValid() )
1723  return false;
1724  StorageRef xStrg = mxStrg->openSubStorage( *maIt, false );
1725  return xStrg && xStrg->isStorage();
1726 }
1727 
1729 {
1730  return mxStrg && mxStrg->isStorage() && (maIt != maNames.end());
1731 }
1732 
1734 {
1735 }
1736 
1737 void ObjectBase::construct( const ConfigRef& rxConfig )
1738 {
1739  mxConfig = rxConfig;
1740 }
1741 
1742 void ObjectBase::construct( const ObjectBase& rParent )
1743 {
1744  *this = rParent;
1745 }
1746 
1748 {
1749  if( isValid() )
1750  implDump();
1751 }
1752 
1754 {
1755  return isValid( mxConfig );
1756 }
1757 
1759 {
1760 }
1761 
1762 void StorageObjectBase::construct( const ObjectBase& rParent, const StorageRef& rxStrg, const OUString& rSysPath )
1763 {
1764  ObjectBase::construct( rParent );
1765  mxStrg = rxStrg;
1766  maSysPath = rSysPath;
1767 }
1768 
1770 {
1771  ObjectBase::construct( rParent );
1772  if( ObjectBase::implIsValid() )
1773  {
1774  mxStrg = cfg().getRootStorage();
1776  }
1777 }
1778 
1780 {
1781  return mxStrg && !maSysPath.isEmpty() && ObjectBase::implIsValid();
1782 }
1783 
1785 {
1786  bool bIsStrg = mxStrg->isStorage();
1787  bool bIsRoot = mxStrg->isRootStorage();
1788  Reference< XInputStream > xBaseStrm;
1789  if( !bIsStrg )
1790  xBaseStrm = mxStrg->openInputStream( OUString() );
1791 
1792  OUString aSysOutPath = maSysPath;
1793  if( bIsRoot ) try
1794  {
1795  aSysOutPath += OOX_DUMP_DUMPEXT;
1796  Reference<XSimpleFileAccess3> xFileAccess(SimpleFileAccess::create(getContext()));
1797  xFileAccess->kill( aSysOutPath );
1798  }
1799  catch( Exception& )
1800  {
1801  }
1802 
1803  if( bIsStrg )
1804  {
1805  extractStorage( mxStrg, OUString(), aSysOutPath );
1806  }
1807  else if( xBaseStrm.is() )
1808  {
1809  BinaryInputStreamRef xInStrm( std::make_shared<BinaryXInputStream>( xBaseStrm, false ) );
1810  xInStrm->seekToStart();
1811  implDumpBaseStream( xInStrm, aSysOutPath );
1812  }
1813 }
1814 
1815 void StorageObjectBase::implDumpStream( const Reference< XInputStream >&, const OUString&, const OUString&, const OUString& )
1816 {
1817 }
1818 
1819 void StorageObjectBase::implDumpStorage( const StorageRef& rxStrg, const OUString& rStrgPath, const OUString& rSysPath )
1820 {
1821  extractStorage( rxStrg, rStrgPath, rSysPath );
1822 }
1823 
1825 {
1826 }
1827 
1829 {
1830  if( rStrmName.has() )
1831  maPreferred.emplace_back( rStrmName, false );
1832 }
1833 
1835 {
1836  if( rStrgPath.has() )
1837  maPreferred.emplace_back( rStrgPath, true );
1838 }
1839 
1841  const OUString& rStrmName, std::u16string_view rSysOutPath )
1842 {
1843  // encode all characters < 0x20
1844  OUStringBuffer aBuffer;
1845  StringHelper::appendEncString( aBuffer, rStrmName, false );
1846 
1847  // replace all characters reserved in file system
1848  OUString aFileName = aBuffer.makeStringAndClear();
1849  static const sal_Unicode spcReserved[] = { '/', '\\', ':', '*', '?', '<', '>', '|' };
1850  for(const sal_Unicode cChar : spcReserved)
1851  aFileName = aFileName.replace(cChar, '_');
1852 
1853  // build full path
1854  return OUString::Concat(rSysOutPath) + "/" + aFileName;
1855 }
1856 
1857 void StorageObjectBase::extractStream( StorageBase& rStrg, const OUString& rStrgPath, const OUString& rStrmName, const OUString& rSysFileName )
1858 {
1859  BinaryXInputStream aInStrm( rStrg.openInputStream( rStrmName ), true );
1860  if( !aInStrm.isEof() )
1861  {
1862  BinaryXOutputStream aOutStrm( InputOutputHelper::openOutputStream( getContext(), rSysFileName ), true );
1863  if( !aOutStrm.isEof() )
1864  aInStrm.copyToStream( aOutStrm );
1865  }
1867  if( xDumpStrm.is() )
1868  implDumpStream( xDumpStrm, rStrgPath, rStrmName, rSysFileName );
1869 }
1870 
1871 void StorageObjectBase::extractStorage( const StorageRef& rxStrg, const OUString& rStrgPath, const OUString& rSysPath )
1872 {
1873  // create directory in file system
1874  ::osl::FileBase::RC eRes = ::osl::Directory::create( rSysPath );
1875  if( (eRes != ::osl::FileBase::E_None) && (eRes != ::osl::FileBase::E_EXIST) )
1876  return;
1877 
1878  // process preferred storages and streams in root storage first
1879  if( rStrgPath.isEmpty() )
1880  {
1881  for (auto const& elemPreferred : maPreferred)
1882  extractItem( rxStrg, rStrgPath, elemPreferred.maName, rSysPath, elemPreferred.mbStorage, !elemPreferred.mbStorage );
1883  }
1884 
1885  // process children of the storage
1886  for( StorageIterator aIt( rxStrg ); aIt.isValid(); ++aIt )
1887  {
1888  // skip processed preferred items
1889  OUString aItemName = aIt.getName();
1890  bool bFound = false;
1891  if( rStrgPath.isEmpty() )
1892  {
1893  for (auto const& elemPreferred : maPreferred)
1894  {
1895  bFound = elemPreferred.maName == aItemName;
1896  if (bFound)
1897  break;
1898  }
1899  }
1900  if( !bFound )
1901  extractItem( rxStrg, rStrgPath, aItemName, rSysPath, aIt.isStorage(), aIt.isStream() );
1902  }
1903 }
1904 
1905 void StorageObjectBase::extractItem( const StorageRef& rxStrg, const OUString& rStrgPath, const OUString& rItemName, std::u16string_view rSysPath, bool bIsStrg, bool bIsStrm )
1906 {
1907  OUString aSysFileName = getSysFileName( rItemName, rSysPath );
1908  if( bIsStrg )
1909  {
1910  OUStringBuffer aStrgPath( rStrgPath );
1911  StringHelper::appendToken( aStrgPath, rItemName, '/' );
1912  implDumpStorage( rxStrg->openSubStorage( rItemName, false ), aStrgPath.makeStringAndClear(), aSysFileName );
1913  }
1914  else if( bIsStrm )
1915  {
1916  extractStream( *rxStrg, rStrgPath, rItemName, aSysFileName );
1917  }
1918 }
1919 
1921 {
1922 }
1923 
1924 void OutputObjectBase::construct( const ObjectBase& rParent, const OUString& rSysFileName )
1925 {
1926  ObjectBase::construct( rParent );
1927  if( ObjectBase::implIsValid() )
1928  {
1929  maSysFileName = rSysFileName;
1930  mxOut = std::make_shared<Output>( getContext(), rSysFileName + OOX_DUMP_DUMPEXT );
1931  }
1932 }
1933 
1935 {
1936  *this = rParent;
1937 }
1938 
1940 {
1941  return isValid( mxOut ) && ObjectBase::implIsValid();
1942 }
1943 
1945 {
1946  ItemGuard aItem( mxOut, rName );
1947 }
1948 
1949 void OutputObjectBase::writeInfoItem( const String& rName, const String& rData )
1950 {
1951  ItemGuard aItem( mxOut, rName );
1952  mxOut->writeString( rData );
1953 }
1954 
1956 {
1957  ItemGuard aItem( mxOut, rName );
1958  mxOut->writeChar( OOX_DUMP_STRQUOTE );
1959  mxOut->writeChar( cData );
1960  mxOut->writeChar( OOX_DUMP_STRQUOTE );
1961 }
1962 
1963 void OutputObjectBase::writeStringItem( const String& rName, const OUString& rData )
1964 {
1965  ItemGuard aItem( mxOut, rName );
1966  mxOut->writeAscii( "(len=" );
1967  mxOut->writeDec( rData.getLength() );
1968  mxOut->writeAscii( ")," );
1969  OUStringBuffer aValue( rData.subView( 0, ::std::min( rData.getLength(), OOX_DUMP_MAXSTRLEN ) ) );
1971  mxOut->writeString( aValue.makeStringAndClear() );
1972  if( rData.getLength() > OOX_DUMP_MAXSTRLEN )
1973  mxOut->writeAscii( ",cut" );
1974 }
1975 
1976 void OutputObjectBase::writeArrayItem( const String& rName, const sal_uInt8* pnData, std::size_t nSize, sal_Unicode cSep )
1977 {
1978  ItemGuard aItem( mxOut, rName );
1979  mxOut->writeArray( pnData, nSize, cSep );
1980 }
1981 
1982 void OutputObjectBase::writeDateTimeItem( const String& rName, const util::DateTime& rDateTime )
1983 {
1984  ItemGuard aItem( mxOut, rName );
1985  mxOut->writeDateTime( rDateTime );
1986 }
1987 
1988 void OutputObjectBase::writeGuidItem( const String& rName, const OUString& rGuid )
1989 {
1990  ItemGuard aItem( mxOut, rName );
1991  mxOut->writeString( rGuid );
1992  aItem.cont();
1993  mxOut->writeString( cfg().getStringOption( rGuid, OUString() ) );
1994 }
1995 
1997 {
1998 }
1999 
2000 void InputObjectBase::construct( const ObjectBase& rParent, const BinaryInputStreamRef& rxStrm, const OUString& rSysFileName )
2001 {
2002  OutputObjectBase::construct( rParent, rSysFileName );
2003  mxStrm = rxStrm;
2004 }
2005 
2007 {
2008  OutputObjectBase::construct( rParent );
2009  mxStrm = rxStrm;
2010 }
2011 
2013 {
2014  *this = rParent;
2015 }
2016 
2018 {
2020 }
2021 
2022 void InputObjectBase::skipBlock( sal_Int64 nBytes, bool bShowSize )
2023 {
2024  sal_Int64 nEndPos = ::std::min< sal_Int64 >( mxStrm->tell() + nBytes, mxStrm->size() );
2025  if( mxStrm->tell() < nEndPos )
2026  {
2027  if( bShowSize )
2028  writeDecItem( "skipped-data-size", static_cast< sal_uInt64 >( nEndPos - mxStrm->tell() ) );
2029  mxStrm->seek( nEndPos );
2030  }
2031 }
2032 
2033 void InputObjectBase::dumpRawBinary( sal_Int64 nBytes, bool bShowOffset, bool bStream )
2034 {
2035  TableGuard aTabGuard( mxOut,
2036  bShowOffset ? 12 : 0,
2037  3 * OOX_DUMP_BYTESPERLINE / 2 + 1,
2038  3 * OOX_DUMP_BYTESPERLINE / 2 + 1,
2039  OOX_DUMP_BYTESPERLINE / 2 + 1 );
2040 
2041  sal_Int64 nMaxShowSize = cfg().getIntOption< sal_Int64 >(
2042  bStream ? "max-binary-stream-size" : "max-binary-data-size", SAL_MAX_INT64 );
2043 
2044  bool bSeekable = mxStrm->size() >= 0;
2045  sal_Int64 nEndPos = bSeekable ? ::std::min< sal_Int64 >( mxStrm->tell() + nBytes, mxStrm->size() ) : 0;
2046  sal_Int64 nDumpEnd = bSeekable ? ::std::min< sal_Int64 >( mxStrm->tell() + nMaxShowSize, nEndPos ) : nMaxShowSize;
2047  sal_Int64 nPos = bSeekable ? mxStrm->tell() : 0;
2048  bool bLoop = true;
2049 
2050  while( bLoop && (nPos < nDumpEnd) )
2051  {
2052  mxOut->writeHex( static_cast< sal_uInt32 >( nPos ) );
2053  mxOut->tab();
2054 
2055  sal_uInt8 pnLineData[ OOX_DUMP_BYTESPERLINE ];
2056  sal_Int32 nLineSize = bSeekable ? ::std::min( static_cast< sal_Int32 >( nDumpEnd - mxStrm->tell() ), OOX_DUMP_BYTESPERLINE ) : OOX_DUMP_BYTESPERLINE;
2057  sal_Int32 nReadSize = mxStrm->readMemory( pnLineData, nLineSize );
2058  bLoop = nReadSize == nLineSize;
2059  nPos += nReadSize;
2060 
2061  if( nReadSize > 0 )
2062  {
2063  const sal_uInt8* pnByte = nullptr;
2064  const sal_uInt8* pnEnd = nullptr;
2065  for( pnByte = pnLineData, pnEnd = pnLineData + nReadSize; pnByte != pnEnd; ++pnByte )
2066  {
2067  if( (pnByte - pnLineData) == (OOX_DUMP_BYTESPERLINE / 2) ) mxOut->tab();
2068  mxOut->writeHex( *pnByte, false );
2069  mxOut->writeChar( ' ' );
2070  }
2071 
2072  aTabGuard.tab( 3 );
2073  for( pnByte = pnLineData, pnEnd = pnLineData + nReadSize; pnByte != pnEnd; ++pnByte )
2074  {
2075  if( (pnByte - pnLineData) == (OOX_DUMP_BYTESPERLINE / 2) ) mxOut->tab();
2076  mxOut->writeChar( static_cast< sal_Unicode >( (*pnByte < 0x20) ? '.' : *pnByte ) );
2077  }
2078  mxOut->newLine();
2079  }
2080  }
2081 
2082  // skip undumped data
2083  if( bSeekable )
2084  skipBlock( nEndPos - mxStrm->tell() );
2085 }
2086 
2087 void InputObjectBase::dumpBinary( const String& rName, sal_Int64 nBytes, bool bShowOffset )
2088 {
2089  {
2090  MultiItemsGuard aMultiGuard( mxOut );
2091  writeEmptyItem( rName );
2092  writeDecItem( "size", nBytes );
2093  }
2094  IndentGuard aIndGuard( mxOut );
2095  dumpRawBinary( nBytes, bShowOffset );
2096 }
2097 
2098 void InputObjectBase::dumpRemaining( sal_Int64 nBytes )
2099 {
2100  if( nBytes > 0 )
2101  {
2102  if( cfg().getBoolOption( "show-trailing-unknown", true ) )
2103  dumpBinary( "remaining-data", nBytes, false );
2104  else
2105  skipBlock( nBytes );
2106  }
2107 }
2108 
2109 void InputObjectBase::dumpRemainingTo( sal_Int64 nPos )
2110 {
2111  if( mxStrm->isEof() || (mxStrm->tell() > nPos) )
2112  writeInfoItem( "stream-state", OOX_DUMP_ERR_STREAM );
2113  else
2114  dumpRemaining( nPos - mxStrm->tell() );
2115  mxStrm->seek( nPos );
2116 }
2117 
2119 {
2120  dumpRemainingTo( mxStrm->size() );
2121 }
2122 
2123 void InputObjectBase::dumpArray( const String& rName, sal_Int32 nBytes, sal_Unicode cSep )
2124 {
2125  sal_Int32 nDumpSize = getLimitedValue< sal_Int32, sal_Int64 >( mxStrm->size() - mxStrm->tell(), 0, nBytes );
2126  if( nDumpSize > OOX_DUMP_MAXARRAY )
2127  {
2128  dumpBinary( rName, nBytes, false );
2129  }
2130  else if( nDumpSize > 1 )
2131  {
2132  sal_uInt8 pnData[ OOX_DUMP_MAXARRAY ];
2133  mxStrm->readMemory( pnData, nDumpSize );
2134  writeArrayItem( rName, pnData, nDumpSize, cSep );
2135  }
2136  else if( nDumpSize == 1 )
2137  dumpHex< sal_uInt8 >( rName );
2138 }
2139 
2141 {
2142  sal_uInt16 nChar = mxStrm->readuInt16();
2143  sal_Unicode cChar = static_cast< sal_Unicode >( nChar );
2144  writeCharItem( rName( "char" ), cChar );
2145  return cChar;
2146 }
2147 
2148 OUString InputObjectBase::dumpCharArray( const String& rName, sal_Int32 nLen, rtl_TextEncoding eTextEnc, bool bHideTrailingNul )
2149 {
2150  sal_Int32 nDumpSize = getLimitedValue< sal_Int32, sal_Int64 >( mxStrm->size() - mxStrm->tell(), 0, nLen );
2151  OUString aString;
2152  if( nDumpSize > 0 )
2153  {
2154  ::std::vector< char > aBuffer( static_cast< std::size_t >( nLen ) + 1 );
2155  sal_Int32 nCharsRead = mxStrm->readMemory(aBuffer.data(), nLen);
2156  aBuffer[ nCharsRead ] = 0;
2157  aString = OStringToOUString(std::string_view(aBuffer.data()), eTextEnc);
2158  }
2159  if( bHideTrailingNul )
2160  aString = StringHelper::trimTrailingNul( aString );
2161  writeStringItem( rName( "text" ), aString );
2162  return aString;
2163 }
2164 
2165 OUString InputObjectBase::dumpUnicodeArray( const String& rName, sal_Int32 nLen, bool bHideTrailingNul )
2166 {
2167  OUStringBuffer aBuffer;
2168  for( sal_Int32 nIndex = 0; !mxStrm->isEof() && (nIndex < nLen); ++nIndex )
2169  {
2170  aBuffer.append( static_cast< sal_Unicode >( mxStrm->readuInt16() ) );
2171  }
2172  OUString aString = aBuffer.makeStringAndClear();
2173  if( bHideTrailingNul )
2174  aString = StringHelper::trimTrailingNul( aString );
2175  writeStringItem( rName( "text" ), aString );
2176  return aString;
2177 }
2178 
2179 util::DateTime InputObjectBase::dumpFileTime( const String& rName )
2180 {
2181  util::DateTime aDateTime;
2182 
2183  ItemGuard aItem( mxOut, rName( "file-time" ) );
2184  sal_Int64 nFileTime = dumpDec< sal_Int64 >( EMPTY_STRING );
2185  // file time is in 10^-7 seconds (100 nanoseconds), convert to nanoseconds
2186  nFileTime *= 100;
2187  // entire days
2188  sal_Int64 nDays = nFileTime / sal_Int64( ::tools::Time::nanoSecPerDay );
2189  // number of entire years
2190  sal_Int64 nYears = (nDays - (nDays / (4 * 365)) + (nDays / (100 * 365)) - (nDays / (400 * 365))) / 365;
2191  // remaining days in the year
2192  sal_Int64 nDaysInYear = nDays - (nYears * 365 + nYears / 4 - nYears / 100 + nYears / 400);
2193  // the year (file dates start from 1601-01-01)
2194  aDateTime.Year = static_cast< sal_uInt16 >( 1601 + nYears );
2195  // leap year?
2196  bool bLeap = ((aDateTime.Year % 4 == 0) && (aDateTime.Year % 100 != 0)) || (aDateTime.Year % 400 == 0);
2197  // static arrays with number of days in month
2198  static const sal_Int64 spnDaysInMonth[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
2199  static const sal_Int64 spnDaysInMonthL[] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
2200  const sal_Int64* pnDaysInMonth = bLeap ? spnDaysInMonthL : spnDaysInMonth;
2201  // the month
2202  aDateTime.Month = 1;
2203  while( nDaysInYear >= *pnDaysInMonth )
2204  {
2205  nDaysInYear -= *pnDaysInMonth++;
2206  ++aDateTime.Month;
2207  }
2208  // the day
2209  aDateTime.Day = static_cast< sal_uInt16 >( nDaysInYear + 1 );
2210  // number of nanoseconds in the day
2211  sal_Int64 nTimeInDay = nFileTime % sal_Int64( ::tools::Time::nanoSecPerDay );
2212  // nanoseconds
2213  aDateTime.NanoSeconds = static_cast< sal_uInt32 >( nTimeInDay % ::tools::Time::nanoSecPerSec );
2214  nTimeInDay /= ::tools::Time::nanoSecPerSec;
2215  // seconds
2216  aDateTime.Seconds = static_cast< sal_uInt16 >( nTimeInDay % ::tools::Time::secondPerMinute );
2217  nTimeInDay /= ::tools::Time::secondPerMinute;
2218  // minutes
2219  aDateTime.Minutes = static_cast< sal_uInt16 >( nTimeInDay % ::tools::Time::minutePerHour );
2220  nTimeInDay /= ::tools::Time::minutePerHour;
2221  // hours
2222  aDateTime.Hours = static_cast< sal_uInt16 >( nTimeInDay );
2223 
2224  writeDateTimeItem( EMPTY_STRING, aDateTime );
2225  return aDateTime;
2226 }
2227 
2228 OUString InputObjectBase::dumpGuid( const String& rName )
2229 {
2230  OUStringBuffer aBuffer;
2231  sal_uInt32 nData32;
2232  sal_uInt16 nData16;
2233  sal_uInt8 nData8;
2234 
2235  nData32 = mxStrm->readuInt32();
2236  StringHelper::appendHex( aBuffer, nData32, false );
2237  aBuffer.append( '-' );
2238  nData16 = mxStrm->readuInt16();
2239  StringHelper::appendHex( aBuffer, nData16, false );
2240  aBuffer.append( '-' );
2241  nData16 = mxStrm->readuInt16();
2242  StringHelper::appendHex( aBuffer, nData16, false );
2243  aBuffer.append( '-' );
2244  nData8 = mxStrm->readuChar();
2245  StringHelper::appendHex( aBuffer, nData8, false );
2246  nData8 = mxStrm->readuChar( );
2247  StringHelper::appendHex( aBuffer, nData8, false );
2248  aBuffer.append( '-' );
2249  for( int nIndex = 0; nIndex < 6; ++nIndex )
2250  {
2251  nData8 = mxStrm->readuChar( );
2252  StringHelper::appendHex( aBuffer, nData8, false );
2253  }
2254  StringHelper::enclose( aBuffer, '{', '}' );
2255  OUString aGuid = aBuffer.makeStringAndClear();
2256  writeGuidItem( rName( "guid" ), aGuid );
2257  return aGuid;
2258 }
2259 
2260 void InputObjectBase::dumpItem( const ItemFormat& rItemFmt )
2261 {
2262  switch( rItemFmt.meDataType )
2263  {
2264  case DATATYPE_VOID: break;
2265  case DATATYPE_INT8: dumpValue< sal_Int8 >( rItemFmt ); break;
2266  case DATATYPE_UINT8: dumpValue< sal_uInt8 >( rItemFmt ); break;
2267  case DATATYPE_INT16: dumpValue< sal_Int16 >( rItemFmt ); break;
2268  case DATATYPE_UINT16: dumpValue< sal_uInt16 >( rItemFmt ); break;
2269  case DATATYPE_INT32: dumpValue< sal_Int32 >( rItemFmt ); break;
2270  case DATATYPE_UINT32: dumpValue< sal_uInt32 >( rItemFmt ); break;
2271  case DATATYPE_INT64: dumpValue< sal_Int64 >( rItemFmt ); break;
2272  case DATATYPE_UINT64: dumpValue< sal_uInt64 >( rItemFmt ); break;
2273  case DATATYPE_FLOAT: dumpValue< float >( rItemFmt ); break;
2274  case DATATYPE_DOUBLE: dumpValue< double >( rItemFmt ); break;
2275  default:;
2276  }
2277 }
2278 
2279 BinaryStreamObject::BinaryStreamObject( const ObjectBase& rParent, const BinaryInputStreamRef& rxStrm, const OUString& rSysFileName )
2280 {
2281  InputObjectBase::construct( rParent, rxStrm, rSysFileName );
2282 }
2283 
2285 {
2286  mxStrm->seekToStart();
2287  dumpRawBinary( mxStrm->size(), bShowOffset, true );
2288  mxOut->emptyLine();
2289 }
2290 
2292 {
2293  dumpBinaryStream();
2294 }
2295 
2297  const BinaryInputStreamRef& rxStrm, rtl_TextEncoding eTextEnc, const OUString& rSysFileName )
2298 {
2299  InputObjectBase::construct( rParent, rxStrm, rSysFileName );
2300  constructTextStrmObj( eTextEnc );
2301 }
2302 
2304  const BinaryInputStreamRef& rxStrm, rtl_TextEncoding eTextEnc )
2305 {
2306  InputObjectBase::construct( rParent, rxStrm );
2307  constructTextStrmObj( eTextEnc );
2308 }
2309 
2311 {
2313 }
2314 
2316 {
2318 }
2319 
2320 void TextStreamObjectBase::constructTextStrmObj( rtl_TextEncoding eTextEnc )
2321 {
2322  if( mxStrm )
2323  mxTextStrm = std::make_shared<TextInputStream>( getContext(), *mxStrm, eTextEnc );
2324 }
2325 
2327  const BinaryInputStreamRef& rxStrm, rtl_TextEncoding eTextEnc, const OUString& rSysFileName )
2328 {
2329  TextStreamObjectBase::construct( rParent, rxStrm, eTextEnc, rSysFileName );
2330 }
2331 
2333  const BinaryInputStreamRef& rxStrm, rtl_TextEncoding eTextEnc )
2334 {
2335  TextStreamObjectBase::construct( rParent, rxStrm, eTextEnc );
2336 }
2337 
2339 {
2340  sal_uInt32 nLine = 0;
2341  while( !rTextStrm.isEof() )
2342  {
2343  OUString aLine = rTextStrm.readLine();
2344  if( !rTextStrm.isEof() || !aLine.isEmpty() )
2345  implDumpLine( aLine, ++nLine );
2346  }
2347 }
2348 
2349 void TextLineStreamObject::implDumpLine( const OUString& rLine, sal_uInt32 nLine )
2350 {
2351  TableGuard aTabGuard( mxOut, 8 );
2352  mxOut->writeDec( nLine, 6 );
2353  mxOut->tab();
2354  mxOut->writeString( rLine );
2355  mxOut->newLine();
2356 }
2357 
2359  const BinaryInputStreamRef& rxStrm, const OUString& rSysFileName )
2360 {
2361  TextStreamObjectBase::construct( rParent, rxStrm, RTL_TEXTENCODING_UTF8, rSysFileName );
2362 }
2363 
2365 {
2366  /* Buffers a start element and the following element text. Needed to dump
2367  matching start/end elements and the element text on the same line. */
2368  OUStringBuffer aOldStartElem;
2369  // special handling for VML
2370  bool bIsVml = InputOutputHelper::getFileNameExtension( maSysFileName ).equalsIgnoreAsciiCase("vml");
2371 
2372  while( !rTextStrm.isEof() )
2373  {
2374  // get the next element and the following element text from text stream
2375  OUString aElem = rTextStrm.readToChar( '>', true ).trim();
2376  OUString aText = rTextStrm.readToChar( '<', false );
2377 
2378  // remove multiple whitespace from element
2379  sal_Int32 nPos = 0;
2380  while( nPos < aElem.getLength() )
2381  {
2382  while( (nPos < aElem.getLength()) && (aElem[ nPos ] >= 32) ) ++nPos;
2383  if( nPos < aElem.getLength() )
2384  aElem = aElem.subView( 0, nPos ) + OUStringChar(' ') + aElem.copy( nPos ).trim();
2385  ++nPos;
2386  }
2387 
2388  sal_Int32 nElemLen = aElem.getLength();
2389  if( (nElemLen >= 2) && (aElem[ 0 ] == '<') && (aElem[ nElemLen - 1 ] == '>') )
2390  {
2391  // determine type of the element
2392  bool bSimpleElem = (aElem[ 1 ] == '!') || (aElem[ 1 ] == '?') || (aElem[ nElemLen - 2 ] == '/') ||
2393  (bIsVml && (nElemLen == 4) && (aElem[ 1 ] == 'b') && (aElem[ 2 ] == 'r'));
2394  bool bStartElem = !bSimpleElem && (aElem[ 1 ] != '/');
2395  bool bEndElem = !bSimpleElem && !bStartElem;
2396 
2397  /* Start element or simple element: flush old start element and
2398  its text from previous iteration, and start a new indentation
2399  level for the new element. Trim whitespace and line breaks from
2400  the text of the old start element. */
2401  if( (bSimpleElem || bStartElem) && (aOldStartElem.getLength() > 0) )
2402  {
2403  mxOut->writeString( aOldStartElem.makeStringAndClear().trim() );
2404  mxOut->newLine();
2405  mxOut->incIndent();
2406  }
2407 
2408  /* Start element: remember it and its text, to be able to print the
2409  matching end element on the same line in the next iteration. */
2410  if( bStartElem )
2411  {
2412  aOldStartElem.append( aElem + aText );
2413  }
2414  else
2415  {
2416  /* End element: if a start element has been remembered in the
2417  previous iteration, write it out here untrimmed, to show
2418  all whitespace in the element text, and without trailing
2419  line break. Code below will add the end element right after
2420  it. Otherwise, return to previous indentation level. */
2421  if( bEndElem )
2422  {
2423  if( aOldStartElem.getLength() == 0 )
2424  mxOut->decIndent();
2425  else
2426  mxOut->writeString( aOldStartElem.makeStringAndClear() );
2427  }
2428 
2429  /* Write the element. Write following element text in a new
2430  line, but only, if it does not contain of white space
2431  entirely. */
2432  mxOut->writeString( aElem );
2433  mxOut->newLine();
2434  if( !aText.trim().isEmpty() )
2435  {
2436  mxOut->writeString( aText );
2437  mxOut->newLine();
2438  }
2439  }
2440  }
2441  }
2442 }
2443 
2445  const BinaryInputStreamRef& rxBaseStrm, const OUString& rSysFileName,
2446  const BinaryInputStreamRef& rxRecStrm, const String& rRecNames, const String& rSimpleRecs )
2447 {
2448  InputObjectBase::construct( rParent, rxRecStrm, rSysFileName );
2449  constructRecObjBase( rxBaseStrm, rRecNames, rSimpleRecs );
2450 }
2451 
2453 {
2455 }
2456 
2458 {
2459  NameListRef xRecNames = maRecNames.getNameList( cfg() );
2460  ItemFormatMap aSimpleRecs( maSimpleRecs.getNameList( cfg() ) );
2461 
2463  {
2464  // record header
2465  mxOut->emptyLine();
2466  writeHeader();
2468  IndentGuard aIndGuard( mxOut );
2469  sal_Int64 nRecPos = mxStrm->tell();
2470 
2471  // record body
2472  if( !mbBinaryOnly && cfg().hasName( xRecNames, mnRecId ) )
2473  {
2474  ::std::map< sal_Int64, ItemFormat >::const_iterator aIt = aSimpleRecs.find( mnRecId );
2475  if( aIt != aSimpleRecs.end() )
2476  dumpItem( aIt->second );
2477  else
2479  }
2480 
2481  // remaining undumped data
2482  if( !mxStrm->isEof() && (mxStrm->tell() == nRecPos) )
2483  dumpRawBinary( mnRecSize, false );
2484  else
2485  dumpRemainingTo( nRecPos + mnRecSize );
2486  }
2487 }
2488 
2490 {
2491 }
2492 
2494 {
2495 }
2496 
2497 void RecordObjectBase::constructRecObjBase( const BinaryInputStreamRef& rxBaseStrm, const String& rRecNames, const String& rSimpleRecs )
2498 {
2499  mxBaseStrm = rxBaseStrm;
2500  maRecNames = rRecNames;
2501  maSimpleRecs = rSimpleRecs;
2502  mnRecPos = mnRecId = mnRecSize = 0;
2503  mbBinaryOnly = false;
2505  mbShowRecPos = cfg().getBoolOption( "show-record-position", true );
2506 }
2507 
2509 {
2510  MultiItemsGuard aMultiGuard( mxOut );
2511  writeEmptyItem( "REC" );
2512  if( mbShowRecPos && mxBaseStrm->isSeekable() )
2513  writeShortHexItem( "pos", mnRecPos, "CONV-DEC" );
2514  writeShortHexItem( "size", mnRecSize, "CONV-DEC" );
2515  ItemGuard aItem( mxOut, "id" );
2516  mxOut->writeShortHex( mnRecId );
2517  addNameToItem( mnRecId, "CONV-DEC" );
2519 }
2520 
2522  const BinaryInputStreamRef& rxBaseStrm, const OUString& rSysFileName,
2523  const String& rRecNames, const String& rSimpleRecs )
2524 {
2525  BinaryInputStreamRef xRecStrm( std::make_shared<SequenceInputStream>( *mxRecData ) );
2526  RecordObjectBase::construct( rParent, rxBaseStrm, rSysFileName, xRecStrm, rRecNames, rSimpleRecs );
2527 }
2528 
2529 bool SequenceRecordObjectBase::implStartRecord( BinaryInputStream& rBaseStrm, sal_Int64& ornRecPos, sal_Int64& ornRecId, sal_Int64& ornRecSize )
2530 {
2531  bool bValid = true;
2532  if( rBaseStrm.isSeekable() )
2533  {
2534  ornRecPos = rBaseStrm.tell();
2535  // do not try to overread seekable streams, may cause assertions
2536  bValid = ornRecPos < rBaseStrm.size();
2537  }
2538 
2539  // read the record header
2540  if( bValid )
2541  bValid = implReadRecordHeader( rBaseStrm, ornRecId, ornRecSize ) && !rBaseStrm.isEof() && (0 <= ornRecSize) && (ornRecSize <= 0x00100000);
2542 
2543  // read record contents into data sequence
2544  if( bValid )
2545  {
2546  sal_Int32 nRecSize = static_cast< sal_Int32 >( ornRecSize );
2547  mxRecData->realloc( nRecSize );
2548  bValid = (nRecSize == 0) || (rBaseStrm.readData( *mxRecData, nRecSize ) == nRecSize);
2549  mxStrm->seekToStart();
2550  }
2551  return bValid;
2552 }
2553 
2555 {
2556 }
2557 
2559 {
2560  return !isValid() || cfg().isImportEnabled();
2561 }
2562 
2563 void DumperBase::construct( const ConfigRef& rxConfig )
2564 {
2565  if( isValid( rxConfig ) && rxConfig->isDumperEnabled() )
2566  ObjectBase::construct( rxConfig );
2567 }
2568 
2569 } // namespace oox
2570 
2571 #endif
2572 
2573 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
OUString maItemName
Name of the item.
Definition: dumperbase.hxx:207
virtual void implDumpText(TextInputStream &rTextStrm) override
Unsigned 32-bit integer.
Definition: dumperbase.hxx:162
virtual OUString implGetName(const Config &rCfg, sal_Int64 nKey) const override
Returns the name for the passed key.
virtual void implDumpBaseStream(const BinaryInputStreamRef &rxStrm, const OUString &rSysFileName)
static const sal_Int64 minutePerHour
bool getBoolOption(const String &rKey, bool bDefault) const
const_iterator end() const
Returns a map iterator pointing one past the last contained name.
Definition: dumperbase.hxx:542
XmlStreamObject(const ObjectBase &rParent, const BinaryInputStreamRef &rxStrm, const OUString &rSysFileName)
static LineType readConfigLine(TextInputStream &rStrm, OUString &orKey, OUString &orData)
Definition: dumperbase.cxx:825
void writeStringItem(const String &rName, const OUString &rData)
const OUString & getStringOption(const String &rKey, const OUString &rDefault) const
bool isImportEnabled() const
sal_Int32 nIndex
void writeItemName(const String &rItemName)
virtual void implProcessConfigItemInt(TextInputStream &rStrm, sal_Int64 nKey, const OUString &rData) override
Definition: dumperbase.cxx:896
static const sal_Int64 nanoSecPerSec
static const sal_Int64 secondPerMinute
const css::uno::Reference< css::uno::XComponentContext > & getContext() const
Wraps a UNO input stream and provides convenient access functions.
static void convertStringToStringList(OUStringVector &orVec, const OUString &rData, bool bIgnoreEmpty)
Definition: dumperbase.cxx:755
::std::map< sal_Int64, ItemFormat > maMap
Definition: dumperbase.hxx:742
Hexadecimal, as short as possible (no leading zeros).
Definition: dumperbase.hxx:176
static OUString getToken(const OUString &rData, sal_Int32 &rnPos, sal_Unicode cSep=OOX_DUMP_LISTSEP)
Definition: dumperbase.cxx:528
void construct(const ConfigRef &rxConfig)
static OUStringPair convertStringToPair(const OUString &rString, sal_Unicode cSep= '=')
Definition: dumperbase.cxx:736
void writeHex(Type nData, bool bPrefix=true)
Definition: dumperbase.hxx:967
void setNamesFromVec(sal_Int64 nStartKey, const OUStringVector &rNames)
Definition: dumperbase.cxx:994
bool readConfigFile(const OUString &rFileUrl)
std::unique_ptr< ContentProperties > pData
PreferredItemVector maPreferred
UnitConverter(const SharedConfigData &rCfgData)
virtual void implSetName(sal_Int64 nKey, const OUString &rName) override
Sets the name for the passed key.
static void appendBin(OUStringBuffer &rStr, sal_uInt8 nData, bool bDots=true)
Definition: dumperbase.cxx:383
signed char sal_Int8
virtual bool implIsValid() const override
virtual ~ObjectBase() override
Unsigned 64-bit integer.
Definition: dumperbase.hxx:164
Static helper functions for system file and stream access.
Definition: dumperbase.hxx:99
uno::Reference< uno::XComponentContext > mxContext
OUString readToChar(sal_Unicode cChar, bool bIncludeChar)
Reads a text portion from the stream until the specified character is found.
static void appendDec(OUStringBuffer &rStr, sal_uInt8 nData, sal_Int32 nWidth=0, sal_Unicode cFill= ' ')
Definition: dumperbase.cxx:209
bool operator<(const ExtItemFormatKey &rRight) const
FormatType
Specifiers for the output format of values.
Definition: dumperbase.hxx:171
virtual void implIncludeList(const NameListBase &rList)=0
Derived classes insert all names and other settings from the passed list.
bool isDumperEnabled() const
bool isImportEnabled() const
void emptyLine(size_t nCount=1)
virtual ~NameListBase() override
Definition: dumperbase.cxx:861
void createUnitConverter(const OUString &rData)
sal_Int32 mnLastItem
static sal_uInt64 lcl_ConvertDouble(double const f)
Definition: dumperbase.cxx:310
#define OOX_DUMP_ERR_NONAME
Definition: dumperbase.hxx:70
void setNameList(const OUString &rListName, const NameListRef &rxList)
static bool convertStringToBool(const OUString &rData)
Definition: dumperbase.cxx:726
sal_Int32 mnCol
static OUString getFileNameExtension(const OUString &rFileUrl)
Definition: dumperbase.cxx:80
::std::vector< OUString > OUStringVector
Definition: dumperbase.hxx:94
void implDumpLine(const OUString &rLine, sal_uInt32 nLine)
void dumpArray(const String &rName, sal_Int32 nBytes, sal_Unicode cSep=OOX_DUMP_LISTSEP)
Boolean ('true' or 'false').
Definition: dumperbase.hxx:179
void addPreferredStream(const String &rStrmName)
const NameListRef & getNameList(const Config &rCfg) const
Type getIntOption(const String &rKey, Type nDefault) const
Definition: dumperbase.hxx:897
static sal_Int32 getFileNamePos(const OUString &rFileUrl)
Definition: dumperbase.cxx:74
::std::pair< OUString, OUString > OUStringPair
Definition: dumperbase.hxx:92
OUString readLine()
Reads a text line from the stream.
virtual void implDump() override
virtual void implProcessConfigItemStr(TextInputStream &rStrm, const OUString &rKey, const OUString &rData) override
virtual bool implIsValid() const override
std::shared_ptr< StorageBase > StorageRef
Definition: storagebase.hxx:42
virtual void implDumpText(TextInputStream &rTextStrm) override
static void appendChar(OUStringBuffer &rStr, sal_Unicode cChar, sal_Int32 nCount)
Definition: dumperbase.cxx:195
OUString getName() const
void readConfigBlockContents(TextInputStream &rStrm)
Definition: dumperbase.cxx:807
virtual OUString implGetName(const Config &rCfg, sal_Int64 nKey) const override
Returns the converted value with appended unit name.
#define OOX_DUMP_ERR_STREAM
Definition: dumperbase.hxx:71
NameListWrapper maSimpleRecs
static void appendIndex(OUStringBuffer &rStr, sal_Int64 nIdx)
Definition: dumperbase.cxx:521
void writeArray(const sal_uInt8 *pnData, std::size_t nSize, sal_Unicode cSep=OOX_DUMP_LISTSEP)
Signed 8-bit integer.
Definition: dumperbase.hxx:157
virtual sal_Int64 size() const =0
Implementations return the size of the stream, if possible.
NameListRef getNameList(const String &rListName) const
Wraps a UNO output stream and provides convenient access functions.
virtual ~OutputObjectBase() override
virtual void implProcessConfigItemStr(TextInputStream &rStrm, const OUString &rKey, const OUString &rData)
Definition: dumperbase.cxx:797
#define SAL_MAX_UINT32
static bool convertFromHex(sal_Int64 &ornData, const OUString &rData)
Definition: dumperbase.cxx:692
void dumpRemainingTo(sal_Int64 nPos)
void construct(const ObjectBase &rParent, const BinaryInputStreamRef &rxBaseStrm, const OUString &rSysFileName, const BinaryInputStreamRef &rxRecStrm, const String &rRecNames, const String &rSimpleRecs)
static OUString convertFileNameToUrl(const OUString &rFileName)
Definition: dumperbase.cxx:66
virtual void implDumpRecordBody()
void createShortList(const OUString &rData)
sal_uInt16 sal_Unicode
::std::vector< sal_Int64 > Int64Vector
Definition: dumperbase.hxx:95
bool has() const
Definition: dumperbase.hxx:383
Floating-point, double precision.
Definition: dumperbase.hxx:166
OUString dumpCharArray(const String &rName, sal_Int32 nLen, rtl_TextEncoding eTextEnc, bool bHideTrailingNul=false)
void eraseNameList(const OUString &rListName)
virtual bool implIsValid() const override
OUStringVector::const_iterator maIt
void dumpRawBinary(sal_Int64 nBytes, bool bShowOffset, bool bStream=false)
std::shared_ptr< SharedConfigData > mxCfgData
Definition: dumperbase.hxx:890
std::shared_ptr< TextInputStream > mxTextStrm
StorageIterator(const StorageRef &rxStrg)
OUStringBuffer maLine
Definition: dumperbase.hxx:995
DataType
Specifiers for atomic data types.
Definition: dumperbase.hxx:154
#define SAL_MAX_UINT16
Signed 16-bit integer.
Definition: dumperbase.hxx:159
static OUString trimSpaces(const OUString &rStr)
Definition: dumperbase.cxx:601
int nCount
Output(const css::uno::Reference< css::uno::XComponentContext > &rxContext, const OUString &rFileName)
void writeDateTimeItem(const String &rName, const css::util::DateTime &rDateTime)
void constructTextStrmObj(rtl_TextEncoding eTextEnc)
void construct(const ObjectBase &rParent, const BinaryInputStreamRef &rxStrm, rtl_TextEncoding eTextEnc, const OUString &rSysFileName)
virtual void implSetName(sal_Int64 nKey, const OUString &rName) override
Sets the name for the passed key.
const OUString & getSysFileName() const
Definition: dumperbase.hxx:853
void writeBool(bool bData)
void writeDec(Type nData, sal_Int32 nWidth=0, sal_Unicode cFill= ' ')
Definition: dumperbase.hxx:964
virtual OUString implGetNameDbl(const Config &rCfg, double fValue) const override
Returns the converted value with appended unit name.
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
void include(const OUString &rListKeys)
Includes name lists, given in a comma separated list of names of the lists.
Definition: dumperbase.cxx:913
static void appendValue(OUStringBuffer &rStr, Type nData, FormatType eFmtType)
Definition: dumperbase.hxx:360
virtual void implSetName(sal_Int64 nKey, const OUString &rName) override
Sets the name for the passed key.
virtual bool implIsValid() const override
virtual void implDumpText(TextInputStream &rTextStrm)=0
FormatType meFmtType
Output format for the value.
Definition: dumperbase.hxx:206
virtual OUString implGetName(const Config &rCfg, sal_Int64 nKey) const override
Returns the name for the passed key.
bool getFlag(Type nBitField, Type nMask)
Returns true, if at least one of the bits set in nMask is set in nBitField.
Definition: helper.hxx:135
virtual void implProcessConfigItemStr(TextInputStream &rStrm, const OUString &rKey, const OUString &rData) override
const String EMPTY_STRING
Definition: dumperbase.hxx:387
virtual OUString implGetName(const Config &rCfg, sal_Int64 nKey) const override
Returns the name for the passed key, or the default name, if key is not contained.
Definition: dumperbase.cxx:961
void writeAscii(const char *pcStr)
virtual void implIncludeList(const NameListBase &rList) override
Inserts all flags from the passed list.
Signed 64-bit integer.
Definition: dumperbase.hxx:163
DocumentType eType
void construct(const ObjectBase &rParent, const StorageRef &rxStrg, const OUString &rSysPath)
OUString dumpUnicodeArray(const String &rName, sal_Int32 nLen, bool bHideTrailingNul=false)
Interface for binary input stream classes.
const SharedConfigData & mrCfgData
Definition: dumperbase.hxx:581
void setFlag(Type &ornBitField, Type nMask, bool bSet=true)
Sets or clears (according to bSet) all set bits of nMask in ornBitField.
Definition: helper.hxx:165
std::shared_ptr< StreamDataSequence > mxRecData
DataType meDataType
Data type of the item.
Definition: dumperbase.hxx:205
::std::pair< sal_Int64, sal_Int64 > maFilter
Definition: dumperbase.hxx:681
void writeGuidItem(const String &rName, const OUString &rGuid)
Base class for storage access implementations.
Definition: storagebase.hxx:51
css::uno::Reference< css::uno::XComponentContext > mxContext
Definition: dumperbase.hxx:800
void writeDecItem(const String &rName, Type nData, const NameListWrapper &rListWrp=NO_LIST)
virtual ~DumperBase() override
sal_uInt16 char * pName
void addNameToItem(Type nData, const NameListWrapper &rListWrp)
OUString dumpGuid(const String &rName=EMPTY_STRING)
void dumpBinary(const String &rName, sal_Int64 nBytes, bool bShowOffset=true)
void dumpItem(const ItemFormat &rItemFmt)
sal_Unicode dumpUnicode(const String &rName)
css::util::DateTime dumpFileTime(const String &rName=EMPTY_STRING)
Describes the output format of a data item.
Definition: dumperbase.hxx:203
static void appendShortHex(OUStringBuffer &rStr, sal_uInt8 nData, bool bPrefix=true)
Definition: dumperbase.cxx:327
Unsigned 16-bit integer.
Definition: dumperbase.hxx:160
void construct(const ObjectBase &rParent, const BinaryInputStreamRef &rxBaseStrm, const OUString &rSysFileName, const String &rRecNames, const String &rSimpleRecs)
void processConfigItem(TextInputStream &rStrm, const OUString &rKey, const OUString &rData)
Definition: dumperbase.cxx:851
void construct(const ObjectBase &rParent, const BinaryInputStreamRef &rxStrm, const OUString &rSysFileName)
virtual void implProcessConfigItemStr(TextInputStream &rStrm, const OUString &rKey, const OUString &rData) override
Definition: dumperbase.cxx:945
void insertRawName(sal_Int64 nKey, const OUString &rName)
Inserts the passed name into the internal map.
Definition: dumperbase.cxx:902
#define OOX_DUMP_UNUSED
Definition: dumperbase.hxx:64
virtual void implIncludeList(const NameListBase &rList) override
Inserts all flags from the passed list.
static css::uno::Reference< css::io::XInputStream > openInputStream(const css::uno::Reference< css::uno::XComponentContext > &rxContext, const OUString &rFileName)
Definition: dumperbase.cxx:91
void constructRecObjBase(const BinaryInputStreamRef &rxBaseStrm, const String &rRecNames, const String &rSimpleRecs)
virtual bool implIsValid() const override
void skipBlock(sal_Int64 nBytes, bool bShowSize=true)
virtual bool implIsValid() const override
SharedConfigData(const OUString &rFileName, const css::uno::Reference< css::uno::XComponentContext > &rxContext, const StorageRef &rxRootStrg, const OUString &rSysFileName)
void writeCharItem(const String &rName, sal_Unicode cData)
static FormatType convertToFormatType(std::u16string_view rStr)
Definition: dumperbase.cxx:651
void set(DataType eDataType, FormatType eFmtType, const OUString &rItemName)
Definition: dumperbase.cxx:152
ExtItemFormatMap maFmtMap
Definition: dumperbase.hxx:692
::std::vector< sal_Int32 > maColPos
Definition: dumperbase.hxx:998
float u
virtual bool implReadRecordHeader(BinaryInputStream &rBaseStrm, sal_Int64 &ornRecId, sal_Int64 &ornRecSize)=0
virtual void implSetName(sal_Int64 nKey, const OUString &rName) override
Sets the name for the passed key.
bool isValid() const
Definition: dumperbase.hxx:449
virtual bool implIsValid() const override
Definition: dumperbase.cxx:880
virtual bool implIsValid() const override
static OString convertToUtf8(std::u16string_view rStr)
Definition: dumperbase.cxx:620
const OUString * implGetOption(const OUString &rKey) const
void setQuoteNames(bool bQuoteNames)
Enables or disables automatic quotation of returned names.
Definition: dumperbase.hxx:591
#define OOX_DUMP_UNKNOWN
Definition: dumperbase.hxx:65
void construct(const ObjectBase &rParent, const OUString &rSysFileName)
Config & cfg() const
virtual sal_Int64 tell() const =0
Implementations return the current stream position, if possible.
FlagsList(const SharedConfigData &rCfgData)
void includeList(const NameListRef &rxList)
Include all names of the passed list.
Definition: dumperbase.cxx:870
virtual void implDumpStorage(const StorageRef &rxStrg, const OUString &rStrgPath, const OUString &rSysPath)
static void appendString(OUStringBuffer &rStr, const OUString &rData, sal_Int32 nWidth, sal_Unicode cFill= ' ')
Definition: dumperbase.cxx:201
static void appendCChar(OUStringBuffer &rStr, sal_Unicode cChar, bool bPrefix=true)
Definition: dumperbase.cxx:451
static OUString getSysFileName(const OUString &rStrmName, std::u16string_view rSysOutPath)
void extractStorage(const StorageRef &rxStrg, const OUString &rStrgPath, const OUString &rSysPath)
css::uno::Reference< css::io::XInputStream > openInputStream(const OUString &rStreamName)
Opens and returns the specified input stream from the storage.
void writeArrayItem(const String &rName, const sal_uInt8 *pnData, std::size_t nSize, sal_Unicode cSep=OOX_DUMP_LISTSEP)
void insertFormats(const NameListRef &rxNameList)
Definition: dumperbase.cxx:929
virtual bool implIsValid() const override
void setIgnoreFlags(sal_Int64 nIgnore)
Sets flags to be ignored on output.
Definition: dumperbase.hxx:642
void addPreferredStorage(const String &rStrgPath)
static void appendHex(OUStringBuffer &rStr, sal_uInt8 nData, bool bPrefix=true)
Definition: dumperbase.cxx:263
virtual ~SharedConfigData() override
virtual ~InputObjectBase() override
virtual void implDump() override
enumrange< T >::Iterator end(enumrange< T >)
void dumpBinaryStream(bool bShowOffset=true)
void writeChar(sal_Unicode cChar, sal_Int32 nCount=1)
void construct(const char *pcEnvVar, const ::oox::core::FilterBase &rFilter)
const sal_Unicode OOX_DUMP_STRQUOTE
Definition: dumperbase.hxx:75
OUStringVector::const_iterator parse(const OUStringVector &rFormatVec)
Initializes the struct from a vector of strings containing the item format.
Definition: dumperbase.cxx:160
virtual ~Base()
Definition: dumperbase.cxx:784
virtual ~Config() override
bool isEof() const
Returns true, if no more text is available in the stream.
static void convertStringToIntList(Int64Vector &orVec, const OUString &rData, bool bIgnoreEmpty)
Definition: dumperbase.cxx:769
static bool convertFromDec(sal_Int64 &ornData, const OUString &rData)
Definition: dumperbase.cxx:669
virtual OUString implGetNameDbl(const Config &rCfg, double fValue) const override
Returns the name for the passed double value.
virtual bool implStartRecord(BinaryInputStream &rBaseStrm, sal_Int64 &ornRecPos, sal_Int64 &ornRecId, sal_Int64 &ornRecSize)=0
std::shared_ptr< NameListBase > NameListRef
Definition: dumperbase.hxx:499
#define OOX_DUMP_DUMPEXT
Definition: dumperbase.hxx:73
virtual void implDump()
virtual bool implIsValid() const override
std::unique_ptr< char[]> aBuffer
void writeString(const OUString &rStr)
void startTable(sal_Int32 nW1)
virtual void implSetName(sal_Int64 nKey, const OUString &rName)=0
Derived classes set the name for the passed key.
Base class of all classes providing names for specific values (name lists).
Definition: dumperbase.hxx:510
StorageIterator & operator++()
virtual void implSetName(sal_Int64 nKey, const OUString &rName) override
Sets the name for the passed key.
Definition: dumperbase.cxx:956
virtual ~StorageIterator() override
void writeDateTime(const css::util::DateTime &rDateTime)
unsigned char sal_uInt8
#define SAL_MAX_UINT8
OUString aName
void extractStream(StorageBase &rStrg, const OUString &rStrgPath, const OUString &rStrmName, const OUString &rSysFileName)
Signed 32-bit integer.
Definition: dumperbase.hxx:161
MultiList(const SharedConfigData &rCfgData)
Definition: dumperbase.cxx:988
void construct(const ConfigRef &rxConfig)
void resetItemIndex(sal_Int64 nIdx=0)
virtual void implProcessConfigItemStr(TextInputStream &rStrm, const OUString &rKey, const OUString &rData) override
Definition: dumperbase.cxx:885
bool isSeekable() const
Returns true, if the implementation supports the seek() operation.
void startItem(const String &rItemName)
NameListRef getNameList(const OUString &rListName) const
const char * name
static void appendEncString(OUStringBuffer &rStr, const OUString &rData, bool bPrefix=true)
Definition: dumperbase.cxx:484
OUString getName(const NameListWrapper &rListWrp, Type nKey) const
Returns the name for the passed key from the passed name list.
Definition: dumperbase.hxx:912
CombiList(const SharedConfigData &rCfgData)
static DataType convertToDataType(std::u16string_view rStr)
Definition: dumperbase.cxx:625
virtual void implDumpStream(const css::uno::Reference< css::io::XInputStream > &rxStrm, const OUString &rStrgPath, const OUString &rStrmName, const OUString &rSysFileName)
void readConfigBlock(TextInputStream &rStrm)
Definition: dumperbase.cxx:792
virtual bool implStartRecord(BinaryInputStream &rBaseStrm, sal_Int64 &ornRecPos, sal_Int64 &ornRecId, sal_Int64 &ornRecSize) override
const OUString * findRawName(sal_Int64 nKey) const
Returns the name for the passed key, or 0, if nothing found.
Definition: dumperbase.cxx:907
const OUString * getOption(const OUString &rKey) const
static const sal_Int64 nanoSecPerDay
virtual void implIncludeList(const NameListBase &rList) override
Inserts all names from the passed list.
Definition: dumperbase.cxx:979
void writeInfoItem(const String &rName, const String &rData)
virtual bool implIsValid() const override
static void appendEncChar(OUStringBuffer &rStr, sal_Unicode cChar, sal_Int32 nCount, bool bPrefix=true)
Definition: dumperbase.cxx:467
virtual sal_Int32 readData(StreamDataSequence &orData, sal_Int32 nBytes, size_t nAtomSize=1)=0
Derived classes implement reading nBytes bytes to the passed sequence.
std::shared_ptr< Config > ConfigRef
Definition: dumperbase.hxx:893
static void appendToken(OUStringBuffer &rStr, std::u16string_view rToken, sal_Unicode cSep=OOX_DUMP_LISTSEP)
Definition: dumperbase.cxx:514
void writeEmptyItem(const String &rName)
BinaryInputStreamRef mxBaseStrm
static css::uno::Reference< css::io::XTextOutputStream2 > openTextOutputStream(const css::uno::Reference< css::uno::XComponentContext > &rxContext, const css::uno::Reference< css::io::XOutputStream > &rxOutStrm, rtl_TextEncoding eTextEnc)
virtual void implIncludeList(const NameListBase &rList) override
Empty implementation.
bool isEof() const
Returns true, if the stream position is invalid (EOF).
OUString maListName
Name of a name list to be used for this item.
Definition: dumperbase.hxx:208
virtual void implProcessConfigItemStr(TextInputStream &rStrm, const OUString &rKey, const OUString &rData) override
TextLineStreamObject(const ObjectBase &rParent, const BinaryInputStreamRef &rxStrm, rtl_TextEncoding eTextEnc, const OUString &rSysFileName)
const StorageRef & getRootStorage() const
Definition: dumperbase.hxx:852
Floating-point, single precision.
Definition: dumperbase.hxx:165
virtual void implProcessConfigItemInt(TextInputStream &rStrm, sal_Int64 nKey, const OUString &rData)
Definition: dumperbase.cxx:802
static bool convertStringToDouble(double &orfData, const OUString &rData)
Definition: dumperbase.cxx:718
OUStringMap::const_iterator const_iterator
Definition: dumperbase.hxx:514
BinaryStreamObject(const ObjectBase &rParent, const BinaryInputStreamRef &rxStrm, const OUString &rSysFileName)
void setName(sal_Int64 nKey, const String &rName)
Sets a name for the specified key.
Definition: dumperbase.cxx:865
void tab(size_t nCol)
void dumpRemaining(sal_Int64 nBytes)
void eraseNameList(const String &rListName)
static void appendBool(OUStringBuffer &rStr, bool bData)
Definition: dumperbase.cxx:444
GUIDCNamePair aData
Definition: olehelper.cxx:98
void extractItem(const StorageRef &rxStrg, const OUString &rStrgPath, const OUString &rItemName, std::u16string_view rSysPath, bool bIsStrg, bool bIsStrm)
virtual OUString implGetNameDbl(const Config &rCfg, double fValue) const override
Returns the name for the passed double value.
Definition: dumperbase.cxx:974
virtual void implDump() override
No numeric format (e.g. show name only).
Definition: dumperbase.hxx:173
#define SAL_MAX_INT64
virtual void implWriteExtHeader()
static OUString trimTrailingNul(const OUString &rStr)
Definition: dumperbase.cxx:612
static bool convertStringToInt(sal_Int64 &ornData, const OUString &rData)
Definition: dumperbase.cxx:711
BinaryInputStreamRef mxStrm
void writeShortHexItem(const String &rName, Type nData, const NameListWrapper &rListWrp=NO_LIST)
sal_uInt16 nPos
void exclude(const OUString &rKeys)
Excludes names from the list, given in a comma separated list of their keys.
Definition: dumperbase.cxx:921
static css::uno::Reference< css::io::XOutputStream > openOutputStream(const css::uno::Reference< css::uno::XComponentContext > &rxContext, const OUString &rFileName)
Definition: dumperbase.cxx:108
static void enclose(OUStringBuffer &rStr, sal_Unicode cOpen, sal_Unicode cClose= '\0')
Encloses the passed string with the passed characters.
Definition: dumperbase.cxx:533
const_iterator begin() const
Returns a map iterator pointing to the first contained name.
Definition: dumperbase.hxx:540
Unsigned 8-bit integer.
Definition: dumperbase.hxx:158
ConstList(const SharedConfigData &rCfgData)
Definition: dumperbase.cxx:938
virtual void implDump() override
css::uno::Reference< css::io::XTextOutputStream2 > mxStrm
Definition: dumperbase.hxx:993