diff options
Diffstat (limited to 'include/oox/dump/dumperbase.hxx')
-rw-r--r-- | include/oox/dump/dumperbase.hxx | 1740 |
1 files changed, 1740 insertions, 0 deletions
diff --git a/include/oox/dump/dumperbase.hxx b/include/oox/dump/dumperbase.hxx new file mode 100644 index 0000000000..f80b2f4d93 --- /dev/null +++ b/include/oox/dump/dumperbase.hxx @@ -0,0 +1,1740 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_OOX_DUMP_DUMPERBASE_HXX +#define INCLUDED_OOX_DUMP_DUMPERBASE_HXX + +#include <cmath> +#include <cstddef> +#include <map> +#include <memory> +#include <set> +#include <string_view> +#include <utility> +#include <vector> + +#include <com/sun/star/uno/Reference.hxx> +#include <com/sun/star/uno/Sequence.hxx> +#include <com/sun/star/util/DateTime.hpp> +#include <oox/helper/binaryinputstream.hxx> +#include <oox/helper/binarystreambase.hxx> +#include <oox/helper/storagebase.hxx> +#include <rtl/string.hxx> +#include <rtl/textenc.h> +#include <rtl/ustring.hxx> +#include <rtl/ustrbuf.hxx> +#include <sal/types.h> + +#ifdef DBG_UTIL + +namespace com::sun::star { + namespace io { class XInputStream; } + namespace io { class XOutputStream; } + namespace io { class XTextOutputStream2; } + namespace uno { class XComponentContext; } +} + +namespace oox { + class TextInputStream; +} + +namespace oox::core { + class FilterBase; +} + +namespace oox::dump { + + +inline constexpr OUString OOX_DUMP_UNUSED = u"unused"_ustr; +inline constexpr OUString OOX_DUMP_UNKNOWN = u"?unknown"_ustr; + +#define OOX_DUMP_ERRASCII( ascii ) "?err:" ascii + +#define OOX_DUMP_ERR_NOMAP "no-map" +inline constexpr OUString OOX_DUMP_ERR_NONAME = u"no-name"_ustr; +#define OOX_DUMP_ERR_STREAM "stream-error" + +#define OOX_DUMP_DUMPEXT ".dump" + +const sal_Unicode OOX_DUMP_STRQUOTE = '\''; +const sal_Unicode OOX_DUMP_FMLASTRQUOTE = '"'; +const sal_Unicode OOX_DUMP_ADDRABS = '$'; +const sal_Unicode OOX_DUMP_R1C1ROW = 'R'; +const sal_Unicode OOX_DUMP_R1C1COL = 'C'; +const sal_Unicode OOX_DUMP_R1C1OPEN = '['; +const sal_Unicode OOX_DUMP_R1C1CLOSE = ']'; +const sal_Unicode OOX_DUMP_RANGESEP = ':'; +const sal_Unicode OOX_DUMP_BASECLASS = 'B'; +const sal_Unicode OOX_DUMP_FUNCSEP = ','; +const sal_Unicode OOX_DUMP_LISTSEP = ','; +const sal_Unicode OOX_DUMP_TABSEP = '!'; +const sal_Unicode OOX_DUMP_ARRAYSEP = ';'; +const sal_Unicode OOX_DUMP_EMPTYVALUE = '~'; +const sal_Unicode OOX_DUMP_CMDPROMPT = '?'; +const sal_Unicode OOX_DUMP_PLACEHOLDER = '\x01'; + +typedef ::std::pair< OUString, OUString > OUStringPair; + +typedef ::std::vector< OUString > OUStringVector; +typedef ::std::vector< sal_Int64 > Int64Vector; + + +/** Static helper functions for system file and stream access. */ +class InputOutputHelper +{ +public: + // file names ------------------------------------------------------------- + + static OUString convertFileNameToUrl( const OUString& rFileName ); + static sal_Int32 getFileNamePos( std::u16string_view rFileUrl ); + static std::u16string_view getFileNameExtension( std::u16string_view rFileUrl ); + + // input streams ---------------------------------------------------------- + + static css::uno::Reference< css::io::XInputStream > + openInputStream( + const css::uno::Reference< css::uno::XComponentContext >& rxContext, + const OUString& rFileName ); + + // output streams --------------------------------------------------------- + + static css::uno::Reference< css::io::XOutputStream > + openOutputStream( + const css::uno::Reference< css::uno::XComponentContext >& rxContext, + const OUString& rFileName ); + + 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 ); + + static css::uno::Reference< css::io::XTextOutputStream2 > + openTextOutputStream( + const css::uno::Reference< css::uno::XComponentContext >& rxContext, + const OUString& rFileName, + rtl_TextEncoding eTextEnc ); +}; + + +class BinaryInputStreamRef : public ::oox::BinaryInputStreamRef +{ +public: + BinaryInputStreamRef() {} + + /*implicit*/ BinaryInputStreamRef( std::shared_ptr<BinaryInputStream> const & pInStrm ) : + ::oox::BinaryInputStreamRef( pInStrm ) {} + + /*implicit*/ BinaryInputStreamRef( const css::uno::Reference< css::io::XInputStream >& rxInStrm ) : + ::oox::BinaryInputStreamRef( std::make_shared<BinaryXInputStream>( rxInStrm, true ) ) {} + + template< typename StreamType > + /*implicit*/ BinaryInputStreamRef( const std::shared_ptr< StreamType >& rxInStrm ) : + ::oox::BinaryInputStreamRef( rxInStrm ) {} +}; + + +/** Specifiers for atomic data types. */ +enum DataType +{ + DATATYPE_VOID, ///< No data type. + DATATYPE_INT8, ///< Signed 8-bit integer. + DATATYPE_UINT8, ///< Unsigned 8-bit integer. + DATATYPE_INT16, ///< Signed 16-bit integer. + DATATYPE_UINT16, ///< Unsigned 16-bit integer. + DATATYPE_INT32, ///< Signed 32-bit integer. + DATATYPE_UINT32, ///< Unsigned 32-bit integer. + DATATYPE_INT64, ///< Signed 64-bit integer. + DATATYPE_UINT64, ///< Unsigned 64-bit integer. + DATATYPE_FLOAT, ///< Floating-point, single precision. + DATATYPE_DOUBLE ///< Floating-point, double precision. +}; + + +/** Specifiers for the output format of values. */ +enum FormatType +{ + FORMATTYPE_NONE, ///< No numeric format (e.g. show name only). + FORMATTYPE_DEC, ///< Decimal. + FORMATTYPE_HEX, ///< Hexadecimal. + FORMATTYPE_SHORTHEX, ///< Hexadecimal, as short as possible (no leading zeros). + FORMATTYPE_BIN, ///< Binary. + FORMATTYPE_FIX, ///< Fixed-point. + FORMATTYPE_BOOL ///< Boolean ('true' or 'false'). +}; + + +/** Describes the output format of a data item. + + Data items are written in the following format: + + <NAME>=<VALUE>=<NAME-FROM-LIST> + + NAME is the name of the data item. The name is contained in the member + maItemName. If the name is empty, only the value is written (without a + leading equality sign). + + VALUE is the numeric value of the data item. Its format is dependent on the + output format given in the member meFmtType. If the format type is + FORMATTYPE_NONE, no value is written. + + NAME-FROM-LIST is a symbolic name for the current value of the data item. + Various types of name lists produce different names for values, which can + be used for enumerations or names for single bits in bitfields (see class + NameListBase and derived classes). The name of the list is given in the + member maListName. If it is empty, no name is written for the value. + */ +struct ItemFormat +{ + DataType meDataType; ///< Data type of the item. + FormatType meFmtType; ///< Output format for the value. + OUString maItemName; ///< Name of the item. + OUString maListName; ///< Name of a name list to be used for this item. + + explicit ItemFormat(); + + void set( DataType eDataType, FormatType eFmtType, const OUString& rItemName ); + + /** Initializes the struct from a vector of strings containing the item format. + + The vector must contain at least 2 strings. The struct is filled from + the strings in the vector in the following order: + 1) Data type (one of: [u]int8, [u]int16, [u]int32, [u]int64, float, double). + 2) Format type (one of: dec, hex, shorthex, bin, fix, bool, unused, unknown). + 3) Item name (optional). + 4) Name list name (optional). + + @return Iterator pointing to the first unhandled string. + */ + OUStringVector::const_iterator parse( const OUStringVector& rFormatVec ); + + /** Initializes the struct from a string containing the item format. + + The string must have the following format: + DATATYPE,FORMATTYPE[,ITEMNAME[,LISTNAME]] + + DATATYPE is the data type of the item (see above for possible values). + FORMATTYPE is the format type of the item (see above for possible values). + ITEMNAME is the name of the item (optional). + LISTNAME is the name of a name list (optional). + + @return List containing remaining unhandled format strings. + */ + OUStringVector parse( std::u16string_view rFormatStr ); +}; + + +/** Static helper functions for formatted output to strings. */ +class StringHelper +{ +public: + // append string to string ------------------------------------------------ + + static void appendChar( OUStringBuffer& rStr, sal_Unicode cChar, sal_Int32 nCount ); + static void appendString( OUStringBuffer& rStr, std::u16string_view rData, sal_Int32 nWidth, sal_Unicode cFill = ' ' ); + + // append decimal --------------------------------------------------------- + + static void appendDec( OUStringBuffer& rStr, sal_uInt8 nData, sal_Int32 nWidth = 0, sal_Unicode cFill = ' ' ); + static void appendDec( OUStringBuffer& rStr, sal_Int8 nData, sal_Int32 nWidth = 0, sal_Unicode cFill = ' ' ); + static void appendDec( OUStringBuffer& rStr, sal_uInt16 nData, sal_Int32 nWidth = 0, sal_Unicode cFill = ' ' ); + static void appendDec( OUStringBuffer& rStr, sal_Int16 nData, sal_Int32 nWidth = 0, sal_Unicode cFill = ' ' ); + static void appendDec( OUStringBuffer& rStr, sal_uInt32 nData, sal_Int32 nWidth = 0, sal_Unicode cFill = ' ' ); + static void appendDec( OUStringBuffer& rStr, sal_Int32 nData, sal_Int32 nWidth = 0, sal_Unicode cFill = ' ' ); + static void appendDec( OUStringBuffer& rStr, sal_uInt64 nData, sal_Int32 nWidth = 0, sal_Unicode cFill = ' ' ); + static void appendDec( OUStringBuffer& rStr, sal_Int64 nData, sal_Int32 nWidth = 0, sal_Unicode cFill = ' ' ); + static void appendDec( OUStringBuffer& rStr, double fData, sal_Int32 nWidth = 0, sal_Unicode cFill = ' ' ); + + // append hexadecimal ----------------------------------------------------- + + static void appendHex( OUStringBuffer& rStr, sal_uInt8 nData, bool bPrefix = true ); + static void appendHex( OUStringBuffer& rStr, sal_Int8 nData, bool bPrefix = true ); + static void appendHex( OUStringBuffer& rStr, sal_uInt16 nData, bool bPrefix = true ); + static void appendHex( OUStringBuffer& rStr, sal_Int16 nData, bool bPrefix = true ); + static void appendHex( OUStringBuffer& rStr, sal_uInt32 nData, bool bPrefix = true ); + static void appendHex( OUStringBuffer& rStr, sal_Int32 nData, bool bPrefix = true ); + static void appendHex( OUStringBuffer& rStr, sal_uInt64 nData, bool bPrefix = true ); + static void appendHex( OUStringBuffer& rStr, sal_Int64 nData, bool bPrefix = true ); + static void appendHex( OUStringBuffer& rStr, double fData, bool bPrefix = true ); + + // append shortened hexadecimal ------------------------------------------- + + static void appendShortHex( OUStringBuffer& rStr, sal_uInt8 nData, bool bPrefix = true ); + static void appendShortHex( OUStringBuffer& rStr, sal_Int8 nData, bool bPrefix = true ); + static void appendShortHex( OUStringBuffer& rStr, sal_uInt16 nData, bool bPrefix = true ); + static void appendShortHex( OUStringBuffer& rStr, sal_Int16 nData, bool bPrefix = true ); + static void appendShortHex( OUStringBuffer& rStr, sal_uInt32 nData, bool bPrefix = true ); + static void appendShortHex( OUStringBuffer& rStr, sal_Int32 nData, bool bPrefix = true ); + static void appendShortHex( OUStringBuffer& rStr, sal_uInt64 nData, bool bPrefix = true ); + static void appendShortHex( OUStringBuffer& rStr, sal_Int64 nData, bool bPrefix = true ); + static void appendShortHex( OUStringBuffer& rStr, double fData, bool bPrefix = true ); + + // append binary ---------------------------------------------------------- + + static void appendBin( OUStringBuffer& rStr, sal_uInt8 nData, bool bDots = true ); + static void appendBin( OUStringBuffer& rStr, sal_Int8 nData, bool bDots = true ); + static void appendBin( OUStringBuffer& rStr, sal_uInt16 nData, bool bDots = true ); + static void appendBin( OUStringBuffer& rStr, sal_Int16 nData, bool bDots = true ); + static void appendBin( OUStringBuffer& rStr, sal_uInt32 nData, bool bDots = true ); + static void appendBin( OUStringBuffer& rStr, sal_Int32 nData, bool bDots = true ); + static void appendBin( OUStringBuffer& rStr, sal_uInt64 nData, bool bDots = true ); + static void appendBin( OUStringBuffer& rStr, sal_Int64 nData, bool bDots = true ); + static void appendBin( OUStringBuffer& rStr, double fData, bool bDots = true ); + + // append fixed-point decimal --------------------------------------------- + + template< typename Type > + static void appendFix( OUStringBuffer& rStr, Type nData, sal_Int32 nWidth = 0 ); + + // append formatted value ------------------------------------------------- + + static void appendBool( OUStringBuffer& rStr, bool bData ); + template< typename Type > + static void appendValue( OUStringBuffer& rStr, Type nData, FormatType eFmtType ); + + // encoded text output ---------------------------------------------------- + + static void appendCChar( OUStringBuffer& rStr, sal_Unicode cChar, bool bPrefix = true ); + static void appendEncChar( OUStringBuffer& rStr, sal_Unicode cChar, sal_Int32 nCount, bool bPrefix = true ); + static void appendEncString( OUStringBuffer& rStr, std::u16string_view rData, bool bPrefix = true ); + + // token list ------------------------------------------------------------- + + static void appendToken( OUStringBuffer& rStr, std::u16string_view rToken, sal_Unicode cSep = OOX_DUMP_LISTSEP ); + + static void appendIndex( OUStringBuffer& rStr, sal_Int64 nIdx ); + + static std::u16string_view getToken( std::u16string_view rData, sal_Int32& rnPos, sal_Unicode cSep = OOX_DUMP_LISTSEP ); + + /** Encloses the passed string with the passed characters. Uses cOpen, if cClose is NUL. */ + static void enclose( OUStringBuffer& rStr, sal_Unicode cOpen, sal_Unicode cClose = '\0' ); + + // string conversion ------------------------------------------------------ + + static std::u16string_view trimSpaces( std::u16string_view rStr ); + static OUString trimTrailingNul( const OUString& rStr ); + + static OString convertToUtf8( std::u16string_view rStr ); + static DataType convertToDataType( std::u16string_view rStr ); + static FormatType convertToFormatType( std::u16string_view rStr ); + + static bool convertFromDec( sal_Int64& ornData, std::u16string_view rData ); + static bool convertFromHex( sal_Int64& ornData, std::u16string_view rData ); + + static bool convertStringToInt( sal_Int64& ornData, std::u16string_view rData ); + static bool convertStringToDouble( double& orfData, std::u16string_view rData ); + static bool convertStringToBool( std::u16string_view rData ); + + static OUStringPair convertStringToPair( const OUString& rString, sal_Unicode cSep = '=' ); + + // string to list conversion ---------------------------------------------- + + static void convertStringToStringList( OUStringVector& orVec, std::u16string_view rData, bool bIgnoreEmpty ); + static void convertStringToIntList( Int64Vector& orVec, std::u16string_view rData, bool bIgnoreEmpty ); +}; + + +template< typename Type > +void StringHelper::appendFix( OUStringBuffer& rStr, Type nData, sal_Int32 nWidth ) +{ + appendDec( rStr, static_cast< double >( nData ) / std::pow( 2.0, 4.0 * sizeof( Type ) ), nWidth ); +} + +template< typename Type > +void StringHelper::appendValue( OUStringBuffer& rStr, Type nData, FormatType eFmtType ) +{ + switch( eFmtType ) + { + case FORMATTYPE_DEC: appendDec( rStr, nData ); break; + case FORMATTYPE_HEX: appendHex( rStr, nData ); break; + case FORMATTYPE_SHORTHEX: appendShortHex( rStr, nData ); break; + case FORMATTYPE_BIN: appendBin( rStr, nData ); break; + case FORMATTYPE_FIX: appendFix( rStr, nData ); break; + case FORMATTYPE_BOOL: appendBool( rStr, static_cast<bool>(nData) ); break; // avoid loplugin:pointerbool warning + default:; + } +} + + +class String : public OUString +{ +public: + String() {} + /*implicit*/ String( const OUString& rStr ) : OUString( rStr ) {} + /*implicit*/ String( const char* pcStr ) : OUString( OUString::createFromAscii( pcStr ? pcStr : "" ) ) {} + /*implicit*/ String( sal_Unicode cChar ) : OUString( cChar ) {} + + bool has() const { return getLength() > 0; } + OUString operator()( const char* pcDefault ) const { if( has() ) return *this; return String( pcDefault ); } +}; + +const String EMPTY_STRING; + + +/** Base class for all dumper classes. + + Derived classes implement the virtual function implIsValid(). It should + check all members the other functions rely on. If the function + implIsValid() returns true, all references and pointers can be used without + further checking. + + Overview of all classes in this header file based on this Base class: + + Base + | + +----> NameListBase + | | + | +----> ConstList ------> MultiList + | | + | +----> FlagsList ------> CombiList + | | + | +----> UnitConverter + | + +----> SharedConfigData + | + +----> Config + | + +----> Output + | + +----> StorageIterator + | + +----> ObjectBase + | + +----> StorageObjectBase + | + +----> OutputObjectBase + | | + | +----> InputObjectBase + | | + | +----> BinaryStreamObject + | | + | +----> TextStreamObjectBase + | | | + | | +----> TextStreamObject + | | | + | | +----> XmlStreamObject + | | + | +----> RecordObjectBase + | | + | +----> SequenceRecordObjectBase + | + +----> DumperBase + */ +class Base +{ +public: + virtual ~Base(); + + Base(Base const &) = default; + Base(Base &&) = default; + Base & operator =(Base const &) = default; + Base & operator =(Base &&) = default; + + bool isValid() const { return implIsValid(); } + static bool isValid( const std::shared_ptr< Base >& rxBase ) { return rxBase && rxBase->isValid(); } + +protected: + Base() {} + + virtual bool implIsValid() const = 0; +}; + + +class ConfigItemBase +{ +public: + virtual ~ConfigItemBase(); + void readConfigBlock( TextInputStream& rStrm ); + +protected: + ConfigItemBase() {} + + virtual void implProcessConfigItemStr( + TextInputStream& rStrm, + const OUString& rKey, + const OUString& rData ); + + virtual void implProcessConfigItemInt( + TextInputStream& rStrm, + sal_Int64 nKey, + const OUString& rData ); + + void readConfigBlockContents( + TextInputStream& rStrm ); + +private: + enum LineType { LINETYPE_DATA, LINETYPE_END }; + + static LineType readConfigLine( + TextInputStream& rStrm, + OUString& orKey, + OUString& orData ); + + void processConfigItem( + TextInputStream& rStrm, + const OUString& rKey, + const OUString& rData ); +}; + + +class SharedConfigData; +class Config; + +class NameListBase; +typedef std::shared_ptr< NameListBase > NameListRef; + +/** Base class of all classes providing names for specific values (name lists). + + The idea is to provide a unique interface for all different methods to + write specific names for any values. This can be enumerations (dedicated + names for a subset of values), or names for bits in bit fields. Classes + derived from this base class implement the specific behaviour for the + desired purpose. + */ +class NameListBase : public Base, public ConfigItemBase +{ +public: + typedef ::std::map< sal_Int64, OUString > OUStringMap; + typedef OUStringMap::const_iterator const_iterator; + +public: + virtual ~NameListBase() override; + + /** Sets a name for the specified key. */ + void setName( sal_Int64 nKey, const String& rName ); + + /** Include all names of the passed list. */ + void includeList( const NameListRef& rxList ); + + /** Returns true, if the map contains an entry for the passed key. */ + template< typename Type > + bool hasName( Type nKey ) const + { return maMap.count( static_cast< sal_Int64 >( nKey ) ) != 0; } + + /** Returns the name for the passed key. */ + template< typename Type > + OUString getName( const Config& rCfg, Type nKey ) const + { return implGetName( rCfg, static_cast< sal_Int64 >( nKey ) ); } + + /** Returns a display name for the passed double value. */ + OUString getName( const Config& rCfg, double fValue ) const + { return implGetNameDbl( rCfg, fValue ); } + + /** Returns a map iterator pointing to the first contained name. */ + const_iterator begin() const { return maMap.begin(); } + /** Returns a map iterator pointing one past the last contained name. */ + const_iterator end() const { return maMap.end(); } + +protected: + explicit NameListBase( const SharedConfigData& rCfgData ) : mrCfgData( rCfgData ) {} + + virtual bool implIsValid() const override; + + virtual void implProcessConfigItemStr( + TextInputStream& rStrm, + const OUString& rKey, + const OUString& rData ) override; + + virtual void implProcessConfigItemInt( + TextInputStream& rStrm, + sal_Int64 nKey, + const OUString& rData ) override; + + /** Derived classes set the name for the passed key. */ + virtual void implSetName( sal_Int64 nKey, const OUString& rName ) = 0; + /** Derived classes generate and return the name for the passed key. */ + virtual OUString implGetName( const Config& rCfg, sal_Int64 nKey ) const = 0; + /** Derived classes generate and return the name for the passed double value. */ + virtual OUString implGetNameDbl( const Config& rCfg, double fValue ) const = 0; + /** Derived classes insert all names and other settings from the passed list. */ + virtual void implIncludeList( const NameListBase& rList ) = 0; + + /** Inserts the passed name into the internal map. */ + void insertRawName( sal_Int64 nKey, const OUString& rName ); + /** Returns the name for the passed key, or 0, if nothing found. */ + const OUString* findRawName( sal_Int64 nKey ) const; + +private: + /** Includes name lists, given in a comma separated list of names of the lists. */ + void include( std::u16string_view rListKeys ); + /** Excludes names from the list, given in a comma separated list of their keys. */ + void exclude( std::u16string_view rKeys ); + +private: + OUStringMap maMap; + const SharedConfigData& mrCfgData; +}; + + +class ConstList : public NameListBase +{ +public: + explicit ConstList( const SharedConfigData& rCfgData ); + + /** Enables or disables automatic quotation of returned names. */ + void setQuoteNames( bool bQuoteNames ) { mbQuoteNames = bQuoteNames; } + +protected: + virtual void implProcessConfigItemStr( + TextInputStream& rStrm, + const OUString& rKey, + const OUString& rData ) override; + + /** Sets the name for the passed key. */ + virtual void implSetName( sal_Int64 nKey, const OUString& rName ) override; + /** Returns the name for the passed key, or the default name, if key is not contained. */ + virtual OUString implGetName( const Config& rCfg, sal_Int64 nKey ) const override; + /** Returns the name for the passed double value. */ + virtual OUString implGetNameDbl( const Config& rCfg, double fValue ) const override; + /** Inserts all names from the passed list. */ + virtual void implIncludeList( const NameListBase& rList ) override; + +private: + OUString maDefName; + bool mbQuoteNames; +}; + + +class MultiList : public ConstList +{ +public: + explicit MultiList( const SharedConfigData& rCfgData ); + + void setNamesFromVec( sal_Int64 nStartKey, const OUStringVector& rNames ); + +protected: + virtual void implProcessConfigItemStr( + TextInputStream& rStrm, + const OUString& rKey, + const OUString& rData ) override; + + virtual void implSetName( sal_Int64 nKey, const OUString& rName ) override; + +private: + bool mbIgnoreEmpty; +}; + + +class FlagsList : public NameListBase +{ +public: + explicit FlagsList( const SharedConfigData& rCfgData ); + + /** Returns the flags to be ignored on output. */ + sal_Int64 getIgnoreFlags() const { return mnIgnore; } + /** Sets flags to be ignored on output. */ + void setIgnoreFlags( sal_Int64 nIgnore ) { mnIgnore = nIgnore; } + +protected: + virtual void implProcessConfigItemStr( + TextInputStream& rStrm, + const OUString& rKey, + const OUString& rData ) override; + + /** Sets the name for the passed key. */ + virtual void implSetName( sal_Int64 nKey, const OUString& rName ) override; + /** Returns the name for the passed key. */ + virtual OUString implGetName( const Config& rCfg, sal_Int64 nKey ) const override; + /** Returns the name for the passed double value. */ + virtual OUString implGetNameDbl( const Config& rCfg, double fValue ) const override; + /** Inserts all flags from the passed list. */ + virtual void implIncludeList( const NameListBase& rList ) override; + +private: + sal_Int64 mnIgnore; +}; + + +class CombiList : public FlagsList +{ +public: + explicit CombiList( const SharedConfigData& rCfgData ); + +protected: + /** Sets the name for the passed key. */ + virtual void implSetName( sal_Int64 nKey, const OUString& rName ) override; + /** Returns the name for the passed key. */ + virtual OUString implGetName( const Config& rCfg, sal_Int64 nKey ) const override; + /** Inserts all flags from the passed list. */ + virtual void implIncludeList( const NameListBase& rList ) override; + +private: + struct ExtItemFormatKey + { + sal_Int64 mnKey; + ::std::pair< sal_Int64, sal_Int64 > maFilter; + explicit ExtItemFormatKey( sal_Int64 nKey ) : mnKey( nKey ), maFilter( 0, 0 ) {} + bool operator<( const ExtItemFormatKey& rRight ) const; + + }; + struct ExtItemFormat : public ItemFormat + { + bool mbShiftValue; + ExtItemFormat() : mbShiftValue( true ) {} + }; + typedef ::std::map< ExtItemFormatKey, ExtItemFormat > ExtItemFormatMap; + ExtItemFormatMap maFmtMap; +}; + + +class UnitConverter : public NameListBase +{ +public: + explicit UnitConverter( const SharedConfigData& rCfgData ); + + void setUnitName( const String& rUnitName ) { maUnitName = rUnitName; } + void setFactor( double fFactor ) { mfFactor = fFactor; } + +protected: + /** Sets the name for the passed key. */ + virtual void implSetName( sal_Int64 nKey, const OUString& rName ) override; + /** Returns the converted value with appended unit name. */ + virtual OUString implGetName( const Config& rCfg, sal_Int64 nKey ) const override; + /** Returns the converted value with appended unit name. */ + virtual OUString implGetNameDbl( const Config& rCfg, double fValue ) const override; + /** Empty implementation. */ + virtual void implIncludeList( const NameListBase& rList ) override; + +private: + OUString maUnitName; + double mfFactor; +}; + + +class NameListWrapper +{ +public: + NameListWrapper() {} + /*implicit*/ NameListWrapper( const OUString& rListName ) : maName( rListName ) {} + /*implicit*/ NameListWrapper( const char* pcListName ) : maName( pcListName ) {} + /*implicit*/ NameListWrapper( NameListRef xList ) : mxList(std::move( xList )) {} + + bool isEmpty() const { return !mxList && !maName.has(); } + const NameListRef & getNameList( const Config& rCfg ) const; + +private: + String maName; + mutable NameListRef mxList; +}; + +const NameListWrapper NO_LIST; + + +class ItemFormatMap +{ +private: + ::std::map< sal_Int64, ItemFormat > maMap; + +public: + ItemFormatMap() {} + explicit ItemFormatMap( const NameListRef& rxNameList ) { insertFormats( rxNameList ); } + + ::std::map< sal_Int64, ItemFormat >::const_iterator end() const { return maMap.end(); } + ::std::map< sal_Int64, ItemFormat >::const_iterator find(sal_Int64 nId) const + { + return maMap.find(nId); + } + + void insertFormats( const NameListRef& rxNameList ); +}; + + +class SharedConfigData : public Base, public ConfigItemBase +{ +public: + explicit SharedConfigData( + const OUString& rFileName, + const css::uno::Reference< css::uno::XComponentContext >& rxContext, + StorageRef xRootStrg, + OUString aSysFileName ); + + virtual ~SharedConfigData() override; + + const css::uno::Reference< css::uno::XComponentContext >& getContext() const { return mxContext; } + const StorageRef& getRootStorage() const { return mxRootStrg; } + const OUString& getSysFileName() const { return maSysFileName; } + + const OUString* getOption( const OUString& rKey ) const; + + template< typename ListType > + std::shared_ptr< ListType > createNameList( const OUString& rListName ); + void setNameList( const OUString& rListName, const NameListRef& rxList ); + void eraseNameList( const OUString& rListName ); + NameListRef getNameList( const OUString& rListName ) const; + +protected: + virtual bool implIsValid() const override; + virtual void implProcessConfigItemStr( + TextInputStream& rStrm, + const OUString& rKey, + const OUString& rData ) override; + +private: + bool readConfigFile( const OUString& rFileUrl ); + template< typename ListType > + void readNameList( TextInputStream& rStrm, const OUString& rListName ); + void createShortList( std::u16string_view rData ); + void createUnitConverter( std::u16string_view rData ); + +private: + typedef ::std::set< OUString > ConfigFileSet; + typedef ::std::map< OUString, OUString > ConfigDataMap; + typedef ::std::map< OUString, NameListRef > NameListMap; + + css::uno::Reference< css::uno::XComponentContext > mxContext; + StorageRef mxRootStrg; + OUString maSysFileName; + ConfigFileSet maConfigFiles; + ConfigDataMap maConfigData; + NameListMap maNameLists; + OUString maConfigPath; + bool mbLoaded; +}; + + +template< typename ListType > +std::shared_ptr< ListType > SharedConfigData::createNameList( const OUString& rListName ) +{ + std::shared_ptr< ListType > xList; + if( !rListName.isEmpty() ) + { + xList = std::make_shared<ListType>( *this ); + setNameList( rListName, xList ); + } + return xList; +} + +template< typename ListType > +void SharedConfigData::readNameList( TextInputStream& rStrm, const OUString& rListName ) +{ + NameListRef xList = createNameList< ListType >( rListName ); + if( xList ) + xList->readConfigBlock( rStrm ); +} + + +class Config : public Base +{ +public: + explicit Config( + const char* pcEnvVar, + const ::oox::core::FilterBase& rFilter ); + explicit Config( + const char* pcEnvVar, + const css::uno::Reference< css::uno::XComponentContext >& rxContext, + const StorageRef& rxRootStrg, + const OUString& rSysFileName ); + + virtual ~Config() override; + + Config(Config const &) = default; + Config(Config &&) = default; + Config & operator =(Config const &) = default; + Config & operator =(Config &&) = default; + + const css::uno::Reference< css::uno::XComponentContext >& getContext() const { return mxCfgData->getContext(); } + const StorageRef& getRootStorage() const { return mxCfgData->getRootStorage(); } + const OUString& getSysFileName() const { return mxCfgData->getSysFileName(); } + + const OUString& getStringOption( const String& rKey, const OUString& rDefault ) const; + bool getBoolOption( const String& rKey, bool bDefault ) const; + template< typename Type > + Type getIntOption( const String& rKey, Type nDefault ) const; + + bool isDumperEnabled() const; + bool isImportEnabled() const; + + template< typename ListType > + std::shared_ptr< ListType > createNameList( const String& rListName ); + void eraseNameList( const String& rListName ); + NameListRef getNameList( const String& rListName ) const; + + /** Returns the name for the passed key from the passed name list. */ + template< typename Type > + OUString getName( const NameListWrapper& rListWrp, Type nKey ) const; + /** Returns true, if the passed name list contains an entry for the passed key. */ + template< typename Type > + bool hasName( const NameListWrapper& rListWrp, Type nKey ) const; + +protected: + Config() {} + void construct( + const char* pcEnvVar, + const ::oox::core::FilterBase& rFilter ); + void construct( + const char* pcEnvVar, + const css::uno::Reference< css::uno::XComponentContext >& rxContext, + const StorageRef& rxRootStrg, + const OUString& rSysFileName ); + + virtual bool implIsValid() const override; + const OUString* implGetOption( const OUString& rKey ) const; + +private: + std::shared_ptr< SharedConfigData > mxCfgData; +}; + +typedef std::shared_ptr< Config > ConfigRef; + + +template< typename Type > +Type Config::getIntOption( const String& rKey, Type nDefault ) const +{ + sal_Int64 nRawData; + const OUString* pData = implGetOption( rKey ); + return (pData && StringHelper::convertStringToInt( nRawData, *pData )) ? + static_cast< Type >( nRawData ) : nDefault; +} + +template< typename ListType > +std::shared_ptr< ListType > Config::createNameList( const String& rListName ) +{ + return mxCfgData->createNameList< ListType >( rListName ); +} + +template< typename Type > +OUString Config::getName( const NameListWrapper& rListWrp, Type nKey ) const +{ + NameListRef xList = rListWrp.getNameList( *this ); + return xList ? xList->getName( *this, nKey ) : OOX_DUMP_ERR_NOMAP; +} + +template< typename Type > +bool Config::hasName( const NameListWrapper& rListWrp, Type nKey ) const +{ + NameListRef xList = rListWrp.getNameList( *this ); + return xList.get() && xList->hasName( nKey ); +} + + +class Output : public Base +{ +public: + explicit Output( + const css::uno::Reference< css::uno::XComponentContext >& rxContext, + const OUString& rFileName ); + + + void newLine(); + void emptyLine( size_t nCount = 1 ); + + void incIndent(); + void decIndent(); + + void startTable( sal_Int32 nW1 ); + void startTable( sal_Int32 nW1, sal_Int32 nW2 ); + void startTable( sal_Int32 nW1, sal_Int32 nW2, sal_Int32 nW3, sal_Int32 nW4 ); + void startTable( size_t nColCount, const sal_Int32* pnColWidths ); + void tab(); + void tab( size_t nCol ); + void endTable(); + + void resetItemIndex( sal_Int64 nIdx = 0 ); + void startItem( const String& rItemName ); + void contItem(); + void endItem(); + + void startMultiItems(); + void endMultiItems(); + + void writeChar( sal_Unicode cChar, sal_Int32 nCount = 1 ); + void writeAscii( const char* pcStr ); + void writeString( std::u16string_view rStr ); + void writeArray( const sal_uInt8* pnData, std::size_t nSize, sal_Unicode cSep = OOX_DUMP_LISTSEP ); + void writeBool( bool bData ); + void writeDateTime( const css::util::DateTime& rDateTime ); + + template< typename Type > + void writeDec( Type nData, sal_Int32 nWidth = 0, sal_Unicode cFill = ' ' ) + { StringHelper::appendDec( maLine, nData, nWidth, cFill ); } + template< typename Type > + void writeHex( Type nData, bool bPrefix = true ) + { StringHelper::appendHex( maLine, nData, bPrefix ); } + template< typename Type > + void writeShortHex( Type nData, bool bPrefix = true ) + { StringHelper::appendShortHex( maLine, nData, bPrefix ); } + template< typename Type > + void writeBin( Type nData, bool bDots = true ) + { StringHelper::appendBin( maLine, nData, bDots ); } + template< typename Type > + void writeFix( Type nData, sal_Int32 nWidth ) + { StringHelper::appendFix( maLine, nData, nWidth ); } + template< typename Type > + void writeValue( Type nData, FormatType eFmtType ) + { StringHelper::appendValue( maLine, nData, eFmtType ); } + template< typename Type > + void writeName( const Config& rCfg, Type nData, const NameListWrapper& rListWrp ) + { writeString( rCfg.getName( rListWrp, nData ) ); } + + +protected: + virtual bool implIsValid() const override; + +private: + void writeItemName( const String& rItemName ); + +private: + css::uno::Reference< css::io::XTextOutputStream2 > mxStrm; + OUString maIndent; + OUStringBuffer maLine; + OUString maLastItem; + ::std::vector< sal_Int32 > + maColPos; + size_t mnCol; + size_t mnItemLevel; + size_t mnMultiLevel; + sal_Int64 mnItemIdx; + sal_Int32 mnLastItem; +}; + +typedef std::shared_ptr< Output > OutputRef; + + +class IndentGuard +{ +public: + explicit IndentGuard( const OutputRef& rxOut ) : mrOut( *rxOut ) { mrOut.incIndent(); } + ~IndentGuard() { mrOut.decIndent(); } +private: + IndentGuard( const IndentGuard& ) = delete; + IndentGuard& operator=( const IndentGuard& ) = delete; +private: + Output& mrOut; +}; + + +class TableGuard +{ +public: + explicit TableGuard( const OutputRef& rxOut, sal_Int32 nW1 ) : + mrOut( *rxOut ) { mrOut.startTable( nW1 ); } + explicit TableGuard( const OutputRef& rxOut, sal_Int32 nW1, sal_Int32 nW2 ) : + mrOut( *rxOut ) { mrOut.startTable( nW1, nW2 ); } + explicit TableGuard( const OutputRef& rxOut, sal_Int32 nW1, sal_Int32 nW2, sal_Int32 nW3, sal_Int32 nW4 ) : + mrOut( *rxOut ) { mrOut.startTable( nW1, nW2, nW3, nW4 ); } + explicit TableGuard( const OutputRef& rxOut, size_t nColCount, + const sal_Int32* pnColWidths ) : + mrOut( *rxOut ) { mrOut.startTable( nColCount, pnColWidths ); } + ~TableGuard() { mrOut.endTable(); } + void tab( size_t nCol ) { mrOut.tab( nCol ); } +private: + TableGuard( const TableGuard& ) = delete; + TableGuard& operator=( const TableGuard& ) = delete; +private: + Output& mrOut; +}; + + +class ItemGuard +{ +public: + explicit ItemGuard( const OutputRef& rxOut, const String& rName ) : + mrOut( *rxOut ) { mrOut.startItem( rName ); } + ~ItemGuard() { mrOut.endItem(); } + void cont() { mrOut.contItem(); } +private: + ItemGuard( const ItemGuard& ) = delete; + ItemGuard& operator=( const ItemGuard& ) = delete; +private: + Output& mrOut; +}; + + +class MultiItemsGuard +{ +public: + explicit MultiItemsGuard( const OutputRef& rxOut ) : mrOut( *rxOut ) { mrOut.startMultiItems(); } + ~MultiItemsGuard() { mrOut.endMultiItems(); } +private: + MultiItemsGuard( const MultiItemsGuard& ) = delete; + MultiItemsGuard& operator=( const MultiItemsGuard& ) = delete; +private: + Output& mrOut; +}; + + +class StorageIterator : public Base +{ +public: + explicit StorageIterator( StorageRef xStrg ); + virtual ~StorageIterator() override; + + StorageIterator& operator++(); + + OUString getName() const; + bool isStream() const; + bool isStorage() const; + +private: + virtual bool implIsValid() const override; + +private: + StorageRef mxStrg; + OUStringVector maNames; + OUStringVector::const_iterator maIt; +}; + + +class ObjectBase : public Base +{ +public: + virtual ~ObjectBase() override; + + ObjectBase(ObjectBase const &) = default; + ObjectBase(ObjectBase &&) = default; + ObjectBase & operator =(ObjectBase const &) = default; + ObjectBase & operator =(ObjectBase &&) = default; + + const css::uno::Reference< css::uno::XComponentContext >& + getContext() const { return mxConfig->getContext(); } + + void dump(); + + +protected: + ObjectBase() {} + + void construct( const ConfigRef& rxConfig ); + void construct( const ObjectBase& rParent ); + + virtual bool implIsValid() const override; + virtual void implDump(); + + + Config& cfg() const { return *mxConfig; } + +private: + ConfigRef mxConfig; +}; + +typedef std::shared_ptr< ObjectBase > ObjectRef; + + +class StorageObjectBase : public ObjectBase +{ +protected: + StorageObjectBase() {} + +protected: + using ObjectBase::construct; + void construct( const ObjectBase& rParent, const StorageRef& rxStrg, const OUString& rSysPath ); + void construct( const ObjectBase& rParent ); + + virtual bool implIsValid() const override; + virtual void implDump() override; + + virtual void implDumpStream( + const css::uno::Reference< css::io::XInputStream >& rxStrm, + const OUString& rStrgPath, + const OUString& rStrmName, + const OUString& rSysFileName ); + + virtual void implDumpStorage( + const StorageRef& rxStrg, + const OUString& rStrgPath, + const OUString& rSysPath ); + + virtual void implDumpBaseStream( + const BinaryInputStreamRef& rxStrm, + const OUString& rSysFileName ); + + void addPreferredStream( const String& rStrmName ); + void addPreferredStorage( const String& rStrgPath ); + +private: + static OUString getSysFileName( + std::u16string_view rStrmName, + std::u16string_view rSysOutPath ); + + void extractStream( + StorageBase& rStrg, + const OUString& rStrgPath, + const OUString& rStrmName, + const OUString& rSysFileName ); + void extractStorage( + const StorageRef& rxStrg, + const OUString& rStrgPath, + const OUString& rSysPath ); + + void extractItem( + const StorageRef& rxStrg, + const OUString& rStrgPath, + const OUString& rItemName, + std::u16string_view rSysPath, + bool bIsStrg, bool bIsStrm ); + +private: + struct PreferredItem + { + OUString maName; + bool mbStorage; + + explicit PreferredItem( OUString aName, bool bStorage ) : + maName(std::move( aName )), mbStorage( bStorage ) {} + }; + typedef ::std::vector< PreferredItem > PreferredItemVector; + + StorageRef mxStrg; + OUString maSysPath; + PreferredItemVector maPreferred; +}; + + +class OutputObjectBase : public ObjectBase +{ +public: + virtual ~OutputObjectBase() override; + + OutputObjectBase(OutputObjectBase const &) = default; + OutputObjectBase(OutputObjectBase &&) = default; + OutputObjectBase & operator =(OutputObjectBase const &) = default; + OutputObjectBase & operator =(OutputObjectBase &&) = default; + +protected: + OutputObjectBase() {} + + using ObjectBase::construct; + void construct( const ObjectBase& rParent, const OUString& rSysFileName ); + void construct( const OutputObjectBase& rParent ); + + virtual bool implIsValid() const override; + + + void writeEmptyItem( const String& rName ); + void writeInfoItem( const String& rName, const String& rData ); + void writeCharItem( const String& rName, sal_Unicode cData ); + void writeStringItem( const String& rName, std::u16string_view rData ); + void writeArrayItem( const String& rName, const sal_uInt8* pnData, std::size_t nSize, sal_Unicode cSep = OOX_DUMP_LISTSEP ); + void writeDateTimeItem( const String& rName, const css::util::DateTime& rDateTime ); + void writeGuidItem( const String& rName, const OUString& rGuid ); + + template< typename Type > + void addNameToItem( Type nData, const NameListWrapper& rListWrp ); + + template< typename Type > + void writeNameItem( const String& rName, Type nData, const NameListWrapper& rListWrp ); + template< typename Type > + void writeDecItem( const String& rName, Type nData, const NameListWrapper& rListWrp = NO_LIST ); + template< typename Type > + void writeHexItem( const String& rName, Type nData, const NameListWrapper& rListWrp = NO_LIST ); + template< typename Type > + void writeShortHexItem( const String& rName, Type nData, const NameListWrapper& rListWrp = NO_LIST ); + template< typename Type > + void writeBinItem( const String& rName, Type nData, const NameListWrapper& rListWrp = NO_LIST ); + template< typename Type > + void writeFixItem( const String& rName, Type nData, const NameListWrapper& rListWrp = NO_LIST ); + template< typename Type > + void writeDecBoolItem( const String& rName, Type nData, const NameListWrapper& rListWrp = NO_LIST ); + template< typename Type > + void writeValueItem( const String& rName, Type nData, FormatType eFmtType, const NameListWrapper& rListWrp = NO_LIST ); + + template< typename Type > + void writeValueItem( const ItemFormat& rItemFmt, Type nData ); + + template< typename Type > + void writeDecPairItem( const String& rName, Type nData1, Type nData2, sal_Unicode cSep = ',' ); + template< typename Type > + void writeHexPairItem( const String& rName, Type nData1, Type nData2, sal_Unicode cSep = ',' ); + +protected: + OutputRef mxOut; + OUString maSysFileName; +}; + + +template< typename Type > +void OutputObjectBase::addNameToItem( Type nData, const NameListWrapper& rListWrp ) +{ + if( !rListWrp.isEmpty() ) + { + mxOut->contItem(); + mxOut->writeName( cfg(), nData, rListWrp ); + } +} + +template< typename Type > +void OutputObjectBase::writeNameItem( const String& rName, Type nData, const NameListWrapper& rListWrp ) +{ + ItemGuard aItem( mxOut, rName ); + mxOut->writeName( cfg(), nData, rListWrp ); +} + +template< typename Type > +void OutputObjectBase::writeDecItem( const String& rName, Type nData, const NameListWrapper& rListWrp ) +{ + ItemGuard aItem( mxOut, rName ); + mxOut->writeDec( nData ); + addNameToItem( nData, rListWrp ); +} + +template< typename Type > +void OutputObjectBase::writeHexItem( const String& rName, Type nData, const NameListWrapper& rListWrp ) +{ + ItemGuard aItem( mxOut, rName ); + mxOut->writeHex( nData ); + addNameToItem( nData, rListWrp ); +} + +template< typename Type > +void OutputObjectBase::writeShortHexItem( const String& rName, Type nData, const NameListWrapper& rListWrp ) +{ + ItemGuard aItem( mxOut, rName ); + mxOut->writeShortHex( nData ); + addNameToItem( nData, rListWrp ); +} + +template< typename Type > +void OutputObjectBase::writeBinItem( const String& rName, Type nData, const NameListWrapper& rListWrp ) +{ + ItemGuard aItem( mxOut, rName ); + mxOut->writeBin( nData ); + addNameToItem( nData, rListWrp ); +} + +template< typename Type > +void OutputObjectBase::writeFixItem( const String& rName, Type nData, const NameListWrapper& rListWrp ) +{ + ItemGuard aItem( mxOut, rName ); + mxOut->writeFix( nData ); + addNameToItem( nData, rListWrp ); +} + +template< typename Type > +void OutputObjectBase::writeDecBoolItem( const String& rName, Type nData, const NameListWrapper& rListWrp ) +{ + ItemGuard aItem( mxOut, rName ); + mxOut->writeDec( nData ); + aItem.cont(); + mxOut->writeBool( nData != 0 ); + addNameToItem( nData, rListWrp ); +} + +template< typename Type > +void OutputObjectBase::writeValueItem( const String& rName, Type nData, FormatType eFmtType, const NameListWrapper& rListWrp ) +{ + if( eFmtType == FORMATTYPE_BOOL ) + writeDecBoolItem( rName, nData, rListWrp ); + else + { + ItemGuard aItem( mxOut, rName ); + mxOut->writeValue( nData, eFmtType ); + addNameToItem( nData, rListWrp ); + } +} + +template< typename Type > +void OutputObjectBase::writeValueItem( const ItemFormat& rItemFmt, Type nData ) +{ + OString aNameUtf8 = StringHelper::convertToUtf8( rItemFmt.maItemName ); + writeValueItem( aNameUtf8.getStr(), nData, rItemFmt.meFmtType, rItemFmt.maListName ); +} + +template< typename Type > +void OutputObjectBase::writeDecPairItem( const String& rName, Type nData1, Type nData2, sal_Unicode cSep ) +{ + ItemGuard aItem( mxOut, rName ); + mxOut->writeDec( nData1 ); + mxOut->writeChar( cSep ); + mxOut->writeDec( nData2 ); +} + +template< typename Type > +void OutputObjectBase::writeHexPairItem( const String& rName, Type nData1, Type nData2, sal_Unicode cSep ) +{ + ItemGuard aItem( mxOut, rName ); + mxOut->writeHex( nData1 ); + mxOut->writeChar( cSep ); + mxOut->writeHex( nData2 ); +} + + +class InputObjectBase : public OutputObjectBase +{ +public: + virtual ~InputObjectBase() override; + + InputObjectBase(InputObjectBase const &) = default; + InputObjectBase(InputObjectBase &&) = default; + InputObjectBase & operator =(InputObjectBase const &) = default; + InputObjectBase & operator =(InputObjectBase &&) = default; + +protected: + InputObjectBase() {} + + using OutputObjectBase::construct; + void construct( const ObjectBase& rParent, const BinaryInputStreamRef& rxStrm, const OUString& rSysFileName ); + void construct( const OutputObjectBase& rParent, const BinaryInputStreamRef& rxStrm ); + void construct( const InputObjectBase& rParent ); + + virtual bool implIsValid() const override; + + void skipBlock( sal_Int64 nBytes, bool bShowSize = true ); + void dumpRawBinary( sal_Int64 nBytes, bool bShowOffset, bool bStream = false ); + + void dumpBinary( const String& rName, sal_Int64 nBytes, bool bShowOffset = true ); + void dumpRemaining( sal_Int64 nBytes ); + void dumpRemainingTo( sal_Int64 nPos ); + void dumpRemainingStream(); + + void dumpArray( const String& rName, sal_Int32 nBytes, sal_Unicode cSep = OOX_DUMP_LISTSEP ); + void dumpUnused( sal_Int32 nBytes ) { dumpArray( OOX_DUMP_UNUSED, nBytes ); } + void dumpUnknown( sal_Int32 nBytes ) { dumpArray( OOX_DUMP_UNKNOWN, nBytes ); } + + sal_Unicode dumpUnicode( const String& rName ); + + OUString dumpCharArray( const String& rName, sal_Int32 nLen, rtl_TextEncoding eTextEnc, bool bHideTrailingNul = false ); + OUString dumpUnicodeArray( const String& rName, sal_Int32 nLen, bool bHideTrailingNul = false ); + + css::util::DateTime dumpFileTime( const String& rName = EMPTY_STRING ); + OUString dumpGuid( const String& rName = EMPTY_STRING ); + + void dumpItem( const ItemFormat& rItemFmt ); + + template< typename Type > + Type dumpName( const String& rName, const NameListWrapper& rListWrp ); + template< typename Type > + Type dumpDec( const String& rName, const NameListWrapper& rListWrp = NO_LIST ); + template< typename Type > + Type dumpHex( const String& rName, const NameListWrapper& rListWrp = NO_LIST ); + template< typename Type > + Type dumpBin( const String& rName, const NameListWrapper& rListWrp = NO_LIST ); + template< typename Type > + Type dumpFix( const String& rName, const NameListWrapper& rListWrp = NO_LIST ); + template< typename Type > + Type dumpBool( const String& rName, const NameListWrapper& rListWrp = NO_LIST ); + template< typename Type > + Type dumpValue( const ItemFormat& rItemFmt ); + + template< typename Type1, typename Type2 > + Type1 dumpName( bool bType1, const String& rName, const NameListWrapper& rListWrp = NO_LIST ); + template< typename Type1, typename Type2 > + Type1 dumpDec( bool bType1, const String& rName, const NameListWrapper& rListWrp = NO_LIST ); + template< typename Type1, typename Type2 > + Type1 dumpHex( bool bType1, const String& rName, const NameListWrapper& rListWrp = NO_LIST ); + template< typename Type1, typename Type2 > + Type1 dumpBin( bool bType1, const String& rName, const NameListWrapper& rListWrp = NO_LIST ); + template< typename Type1, typename Type2 > + Type1 dumpFix( bool bType1, const String& rName, const NameListWrapper& rListWrp = NO_LIST ); + template< typename Type1, typename Type2 > + Type1 dumpBool( bool bType1, const String& rName, const NameListWrapper& rListWrp = NO_LIST ); + template< typename Type1, typename Type2 > + Type1 dumpValue( bool bType1, const ItemFormat& rItemFmt ); + + template< typename Type > + void dumpDecPair( const String& rName, sal_Unicode cSep = ',' ); + template< typename Type > + void dumpHexPair( const String& rName, sal_Unicode cSep = ',' ); + +protected: + BinaryInputStreamRef mxStrm; +}; + + +template< typename Type > +Type InputObjectBase::dumpName( const String& rName, const NameListWrapper& rListWrp ) +{ + Type nData = mxStrm->readValue<Type>(); + writeNameItem( rName, nData, rListWrp ); + return nData; +} + +template< typename Type > +Type InputObjectBase::dumpDec( const String& rName, const NameListWrapper& rListWrp ) +{ + Type nData = mxStrm->readValue<Type>(); + writeDecItem( rName, nData, rListWrp ); + return nData; +} + +template< typename Type > +Type InputObjectBase::dumpHex( const String& rName, const NameListWrapper& rListWrp ) +{ + Type nData = mxStrm->readValue<Type>(); + writeHexItem( rName, nData, rListWrp ); + return nData; +} + +template< typename Type > +Type InputObjectBase::dumpBin( const String& rName, const NameListWrapper& rListWrp ) +{ + Type nData = mxStrm->readValue<Type>(); + writeBinItem( rName, nData, rListWrp ); + return nData; +} + +template< typename Type > +Type InputObjectBase::dumpFix( const String& rName, const NameListWrapper& rListWrp ) +{ + Type nData = mxStrm->readValue<Type>(); + writeFixItem( rName, nData, rListWrp ); + return nData; +} + +template< typename Type > +Type InputObjectBase::dumpBool( const String& rName, const NameListWrapper& rListWrp ) +{ + Type nData = mxStrm->readValue<Type>(); + writeDecBoolItem( rName, nData, rListWrp ); + return nData; +} + +template< typename Type > +Type InputObjectBase::dumpValue( const ItemFormat& rItemFmt ) +{ + Type nData = mxStrm->readValue<Type>(); + writeValueItem( rItemFmt, nData ); + return nData; +} + +template< typename Type1, typename Type2 > +Type1 InputObjectBase::dumpName( bool bType1, const String& rName, const NameListWrapper& rListWrp ) +{ + return bType1 ? dumpName< Type1 >( rName, rListWrp ) : static_cast< Type1 >( dumpName< Type2 >( rName, rListWrp ) ); +} + +template< typename Type1, typename Type2 > +Type1 InputObjectBase::dumpDec( bool bType1, const String& rName, const NameListWrapper& rListWrp ) +{ + return bType1 ? dumpDec< Type1 >( rName, rListWrp ) : static_cast< Type1 >( dumpDec< Type2 >( rName, rListWrp ) ); +} + +template< typename Type1, typename Type2 > +Type1 InputObjectBase::dumpHex( bool bType1, const String& rName, const NameListWrapper& rListWrp ) +{ + return bType1 ? dumpHex< Type1 >( rName, rListWrp ) : static_cast< Type1 >( dumpHex< Type2 >( rName, rListWrp ) ); +} + +template< typename Type1, typename Type2 > +Type1 InputObjectBase::dumpBin( bool bType1, const String& rName, const NameListWrapper& rListWrp ) +{ + return bType1 ? dumpBin< Type1 >( rName, rListWrp ) : static_cast< Type1 >( dumpBin< Type2 >( rName, rListWrp ) ); +} + +template< typename Type1, typename Type2 > +Type1 InputObjectBase::dumpFix( bool bType1, const String& rName, const NameListWrapper& rListWrp ) +{ + return bType1 ? dumpFix< Type1 >( rName, rListWrp ) : static_cast< Type1 >( dumpFix< Type2 >( rName, rListWrp ) ); +} + +template< typename Type1, typename Type2 > +Type1 InputObjectBase::dumpBool( bool bType1, const String& rName, const NameListWrapper& rListWrp ) +{ + return bType1 ? dumpBool< Type1 >( rName, rListWrp ) : static_cast< Type1 >( dumpBool< Type2 >( rName, rListWrp ) ); +} + +template< typename Type1, typename Type2 > +Type1 InputObjectBase::dumpValue( bool bType1, const ItemFormat& rItemFmt ) +{ + return bType1 ? dumpValue< Type1 >( rItemFmt ) : static_cast< Type1 >( dumpValue< Type2 >( rItemFmt ) ); +} + +template< typename Type > +void InputObjectBase::dumpDecPair( const String& rName, sal_Unicode cSep ) +{ + Type nData1, nData2; + *mxStrm >> nData1 >> nData2; + writeDecPairItem( rName, nData1, nData2, cSep ); +} + +template< typename Type > +void InputObjectBase::dumpHexPair( const String& rName, sal_Unicode cSep ) +{ + Type nData1, nData2; + *mxStrm >> nData1 >> nData2; + writeHexPairItem( rName, nData1, nData2, cSep ); +} + + +class BinaryStreamObject final : public InputObjectBase +{ +public: + explicit BinaryStreamObject( + const ObjectBase& rParent, + const BinaryInputStreamRef& rxStrm, + const OUString& rSysFileName ); + +private: + void dumpBinaryStream( bool bShowOffset = true ); + + virtual void implDump() override; +}; + + +class TextStreamObjectBase : public InputObjectBase +{ +protected: + TextStreamObjectBase() {} + + using InputObjectBase::construct; + void construct( + const ObjectBase& rParent, + const BinaryInputStreamRef& rxStrm, + rtl_TextEncoding eTextEnc, + const OUString& rSysFileName ); + void construct( + const OutputObjectBase& rParent, + const BinaryInputStreamRef& rxStrm, + rtl_TextEncoding eTextEnc ); + + virtual bool implIsValid() const override; + virtual void implDump() override; + + virtual void implDumpText( TextInputStream& rTextStrm ) = 0; + +private: + void constructTextStrmObj( rtl_TextEncoding eTextEnc ); + + std::shared_ptr< TextInputStream > mxTextStrm; +}; + + +class TextLineStreamObject final : public TextStreamObjectBase +{ +public: + explicit TextLineStreamObject( + const ObjectBase& rParent, + const BinaryInputStreamRef& rxStrm, + rtl_TextEncoding eTextEnc, + const OUString& rSysFileName ); + + explicit TextLineStreamObject( + const OutputObjectBase& rParent, + const BinaryInputStreamRef& rxStrm, + rtl_TextEncoding eTextEnc ); + +private: + virtual void implDumpText( TextInputStream& rTextStrm ) override; + void implDumpLine( std::u16string_view rLine, sal_uInt32 nLine ); +}; + + +class XmlStreamObject : public TextStreamObjectBase +{ +public: + explicit XmlStreamObject( + const ObjectBase& rParent, + const BinaryInputStreamRef& rxStrm, + const OUString& rSysFileName ); + +protected: + virtual void implDumpText( TextInputStream& rTextStrm ) override; +}; + + +class RecordObjectBase : public InputObjectBase +{ +protected: + RecordObjectBase() {} + + using InputObjectBase::construct; + void construct( + const ObjectBase& rParent, + const BinaryInputStreamRef& rxBaseStrm, + const OUString& rSysFileName, + const BinaryInputStreamRef& rxRecStrm, + const String& rRecNames, + const String& rSimpleRecs ); + + sal_Int64 getRecId() const { return mnRecId; } + sal_Int64 getRecSize() const { return mnRecSize; } + + virtual bool implIsValid() const override; + virtual void implDump() override; + + virtual bool implStartRecord( BinaryInputStream& rBaseStrm, sal_Int64& ornRecPos, sal_Int64& ornRecId, sal_Int64& ornRecSize ) = 0; + virtual void implWriteExtHeader(); + virtual void implDumpRecordBody(); + +private: + void constructRecObjBase( + const BinaryInputStreamRef& rxBaseStrm, + const String& rRecNames, + const String& rSimpleRecs ); + + void writeHeader(); + +private: + BinaryInputStreamRef mxBaseStrm; + NameListWrapper maRecNames; + NameListWrapper maSimpleRecs; + sal_Int64 mnRecPos; + sal_Int64 mnRecId; + sal_Int64 mnRecSize; + bool mbShowRecPos; + bool mbBinaryOnly; +}; + + +class SequenceRecordObjectBase : public RecordObjectBase +{ +protected: + SequenceRecordObjectBase() : mxRecData( std::make_shared<StreamDataSequence>() ) {} + + using RecordObjectBase::construct; + void construct( + const ObjectBase& rParent, + const BinaryInputStreamRef& rxBaseStrm, + const OUString& rSysFileName, + const String& rRecNames, + const String& rSimpleRecs ); + + virtual bool implStartRecord( BinaryInputStream& rBaseStrm, sal_Int64& ornRecPos, sal_Int64& ornRecId, sal_Int64& ornRecSize ) override; + virtual bool implReadRecordHeader( BinaryInputStream& rBaseStrm, sal_Int64& ornRecId, sal_Int64& ornRecSize ) = 0; + +private: + std::shared_ptr< StreamDataSequence > mxRecData; +}; + + +/** Base class for a file dumper. Derived classes implement the implDump() + function to add functionality. + */ +class DumperBase : public ObjectBase +{ +public: + virtual ~DumperBase() override; + + bool isImportEnabled() const; + +protected: + DumperBase() {} + + using ObjectBase::construct; + void construct( const ConfigRef& rxConfig ); +}; + + +} // namespace oox::dump + +#define OOX_DUMP_FILE( DumperClassName ) \ +do { \ + DumperClassName aDumper( *this ); \ + aDumper.dump(); \ + if( !aDumper.isImportEnabled() ) \ + return aDumper.isValid(); \ +} while( false ) + +#else // DBG_UTIL + +#define OOX_DUMP_FILE( DumperClassName ) (void)0 + +#endif // DBG_UTIL +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |