diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:06:44 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:06:44 +0000 |
commit | ed5640d8b587fbcfed7dd7967f3de04b37a76f26 (patch) | |
tree | 7a5f7c6c9d02226d7471cb3cc8fbbf631b415303 /include/oox/helper | |
parent | Initial commit. (diff) | |
download | libreoffice-upstream/4%7.4.7.tar.xz libreoffice-upstream/4%7.4.7.zip |
Adding upstream version 4:7.4.7.upstream/4%7.4.7upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'include/oox/helper')
-rw-r--r-- | include/oox/helper/addtosequence.hxx | 41 | ||||
-rw-r--r-- | include/oox/helper/attributelist.hxx | 192 | ||||
-rw-r--r-- | include/oox/helper/binaryinputstream.hxx | 385 | ||||
-rw-r--r-- | include/oox/helper/binaryoutputstream.hxx | 208 | ||||
-rw-r--r-- | include/oox/helper/binarystreambase.hxx | 179 | ||||
-rw-r--r-- | include/oox/helper/containerhelper.hxx | 298 | ||||
-rw-r--r-- | include/oox/helper/grabbagstack.hxx | 61 | ||||
-rw-r--r-- | include/oox/helper/graphichelper.hxx | 161 | ||||
-rw-r--r-- | include/oox/helper/helper.hxx | 301 | ||||
-rw-r--r-- | include/oox/helper/modelobjecthelper.hxx | 131 | ||||
-rw-r--r-- | include/oox/helper/progressbar.hxx | 132 | ||||
-rw-r--r-- | include/oox/helper/propertymap.hxx | 130 | ||||
-rw-r--r-- | include/oox/helper/propertyset.hxx | 151 | ||||
-rw-r--r-- | include/oox/helper/refmap.hxx | 144 | ||||
-rw-r--r-- | include/oox/helper/refvector.hxx | 163 | ||||
-rw-r--r-- | include/oox/helper/storagebase.hxx | 192 | ||||
-rw-r--r-- | include/oox/helper/textinputstream.hxx | 121 | ||||
-rw-r--r-- | include/oox/helper/zipstorage.hxx | 94 |
18 files changed, 3084 insertions, 0 deletions
diff --git a/include/oox/helper/addtosequence.hxx b/include/oox/helper/addtosequence.hxx new file mode 100644 index 000000000..dbb271ca0 --- /dev/null +++ b/include/oox/helper/addtosequence.hxx @@ -0,0 +1,41 @@ +/* -*- 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_HELPER_ADDTOSEQUENCE_HXX +#define INCLUDED_OOX_HELPER_ADDTOSEQUENCE_HXX + +#include <com/sun/star/uno/Any.hxx> +#include <oox/dllapi.h> + +namespace oox +{ + +/** this adds an any to another any. + if rNewValue is empty, rOldValue is returned. + if rOldValue is empty, rNewValue is returned. + if rOldValue contains a value, a sequence with rOldValue and rNewValue is returned. + if rOldValue contains a sequence, a new sequence with the old sequence and rNewValue is returned. +*/ +OOX_DLLPUBLIC css::uno::Any addToSequence( const css::uno::Any& rOldValue, const css::uno::Any& rNewValue ); + +} // namespace oox + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/oox/helper/attributelist.hxx b/include/oox/helper/attributelist.hxx new file mode 100644 index 000000000..27101657f --- /dev/null +++ b/include/oox/helper/attributelist.hxx @@ -0,0 +1,192 @@ +/* -*- 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_HELPER_ATTRIBUTELIST_HXX +#define INCLUDED_OOX_HELPER_ATTRIBUTELIST_HXX + +#include <sal/config.h> + +#include <string_view> +#include <vector> + +#include <com/sun/star/uno/Reference.hxx> +#include <com/sun/star/util/DateTime.hpp> +#include <oox/helper/helper.hxx> +#include <oox/dllapi.h> +#include <rtl/ustring.hxx> +#include <sal/types.h> +#include <oox/drawingml/color.hxx> + +namespace com::sun::star { + namespace xml::sax { class XFastAttributeList; } +} + +namespace sax_fastparser { + class FastAttributeList; +}; + +namespace oox { + + /* Get the color tokens from their string representatives. */ + sal_Int32 getHighlightColorTokenFromString(std::u16string_view sColorName); + +/** Static helpers for conversion of strings to attribute values of various + different data types. + */ +class OOX_DLLPUBLIC AttributeConversion +{ +public: + /** Returns the XML token identifier from the passed string. */ + static sal_Int32 decodeToken( std::u16string_view rValue ); + + /** Returns the decoded string value. All characters in the format + '_xHHHH_' (H being a hexadecimal digit), will be decoded. */ + static OUString decodeXString( const OUString& rValue ); + + /** Returns the 32-bit signed integer value from the passed string (decimal). */ + static sal_Int32 decodeInteger( std::u16string_view rValue ); + + /** Returns the 32-bit unsigned integer value from the passed string (decimal). */ + static sal_uInt32 decodeUnsigned( std::u16string_view rValue ); + + /** Returns the 64-bit signed integer value from the passed string (decimal). */ + static sal_Int64 decodeHyper( std::u16string_view rValue ); + + /** Returns the 32-bit signed integer value from the passed string (hexadecimal). */ + static sal_Int32 decodeIntegerHex( std::u16string_view rValue ); +}; + + +/** Provides access to attribute values of an element. + + Wraps a com.sun.star.xml.sax.XFastAttributeList object. Provides + convenience functions that convert the string value of an attribute to + various other data types. + */ +class OOX_DLLPUBLIC AttributeList +{ +public: + explicit AttributeList( + const css::uno::Reference< css::xml::sax::XFastAttributeList >& rxAttribs ); + + /** Returns the wrapped com.sun.star.xml.sax.XFastAttributeList object. */ + const css::uno::Reference< css::xml::sax::XFastAttributeList >& + getFastAttributeList() const { return mxAttribs; } + + /** Returns true, if the specified attribute is present. */ + bool hasAttribute( sal_Int32 nAttrToken ) const; + + // optional return values ------------------------------------------------- + + /** Returns the token identifier of the value of the specified attribute. */ + OptValue< sal_Int32 > getToken( sal_Int32 nAttrToken ) const; + + /** Returns the Color object of highlight of the text. */ + oox::drawingml::Color getHighlightColor(sal_Int32 nAttrToken) const; + + /** Returns the string value of the specified attribute. */ + OptValue< OUString > getString( sal_Int32 nAttrToken ) const; + + /** Returns the string value of the specified attribute. All characters in + the format '_xHHHH_' (H being a hexadecimal digit), will be decoded. */ + OptValue< OUString > getXString( sal_Int32 nAttrToken ) const; + + /** Returns the double value of the specified attribute. */ + OptValue< double > getDouble( sal_Int32 nAttrToken ) const; + + /** Returns the 32-bit signed integer value of the specified attribute (decimal). */ + OptValue< sal_Int32 > getInteger( sal_Int32 nAttrToken ) const; + + /** Returns the 32-bit unsigned integer value of the specified attribute (decimal). */ + OptValue< sal_uInt32 > getUnsigned( sal_Int32 nAttrToken ) const; + + /** Returns the 64-bit signed integer value of the specified attribute (decimal). */ + OptValue< sal_Int64 > getHyper( sal_Int32 nAttrToken ) const; + + /** Returns the 32-bit signed integer value of the specified attribute (hexadecimal). */ + OptValue< sal_Int32 > getIntegerHex( sal_Int32 nAttrToken ) const; + + /** Returns the boolean value of the specified attribute. */ + OptValue< bool > getBool( sal_Int32 nAttrToken ) const; + + /** Returns the date/time value of the specified attribute. */ + OptValue< css::util::DateTime > getDateTime( sal_Int32 nAttrToken ) const; + + // defaulted return values ------------------------------------------------ + + /** Returns the token identifier of the value of the specified attribute, + or the passed default identifier if the attribute is missing. */ + sal_Int32 getToken( sal_Int32 nAttrToken, sal_Int32 nDefault ) const; + + /** Returns the string value of the specified attribute, or the passed + default string if the attribute is missing. */ + OUString getString( sal_Int32 nAttrToken, const OUString& rDefault ) const; + + /** Returns the decoded string value of the specified attribute, or the + passed default string if the attribute is missing. */ + OUString getXString( sal_Int32 nAttrToken, const OUString& rDefault ) const; + + const char* getChar( sal_Int32 nAttrToken ) const; + + + /** Returns the double value of the specified attribute, or the passed + default value if the attribute is missing or not convertible to a double. */ + double getDouble( sal_Int32 nAttrToken, double fDefault ) const; + + /** Returns the 32-bit signed integer value of the specified attribute, or the + passed default value if the attribute is missing or not convertible to integer. */ + sal_Int32 getInteger( sal_Int32 nAttrToken, sal_Int32 nDefault ) const; + + /** Returns the 32-bit unsigned integer value of the specified attribute, or the + passed default value if the attribute is missing or not convertible to unsigned. */ + sal_uInt32 getUnsigned( sal_Int32 nAttrToken, sal_uInt32 nDefault ) const; + + /** Returns the 64-bit signed integer value of the specified attribute, or the + passed default value if the attribute is missing or not convertible to integer. */ + sal_Int64 getHyper( sal_Int32 nAttrToken, sal_Int64 nDefault ) const; + + /** Returns the 32-bit signed integer value of the specified attribute (hexadecimal), + or the passed default value if the attribute is missing or not convertible. */ + sal_Int32 getIntegerHex( sal_Int32 nAttrToken, sal_Int32 nDefault ) const; + + sal_uInt32 getUnsignedHex( sal_Int32 nAttrToken, sal_uInt32 nDefault ) const; + + /** Returns the boolean value of the specified attribute, or the passed + default value if the attribute is missing or not convertible to bool. */ + bool getBool( sal_Int32 nAttrToken, bool bDefault ) const; + + /** Returns the date/time value of the specified attribute, or the default + value if the attribute is missing or not convertible to a date/time value. */ + css::util::DateTime getDateTime( sal_Int32 nAttrToken, const css::util::DateTime& rDefault ) const; + + std::vector<sal_Int32> getTokenList(sal_Int32 nAttrToken) const; + +private: + css::uno::Reference< css::xml::sax::XFastAttributeList > + mxAttribs; + mutable sax_fastparser::FastAttributeList *mpAttribList; + sax_fastparser::FastAttributeList *getAttribList() const; +}; + + +} // namespace oox + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/oox/helper/binaryinputstream.hxx b/include/oox/helper/binaryinputstream.hxx new file mode 100644 index 000000000..e27b2def9 --- /dev/null +++ b/include/oox/helper/binaryinputstream.hxx @@ -0,0 +1,385 @@ +/* -*- 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_HELPER_BINARYINPUTSTREAM_HXX +#define INCLUDED_OOX_HELPER_BINARYINPUTSTREAM_HXX + +#include <cstddef> +#include <memory> +#include <vector> + +#include <com/sun/star/uno/Reference.hxx> +#include <oox/dllapi.h> +#include <oox/helper/binarystreambase.hxx> +#include <oox/helper/helper.hxx> +#include <rtl/string.hxx> +#include <rtl/textenc.h> +#include <rtl/ustring.hxx> +#include <sal/types.h> + +namespace com::sun::star { + namespace io { class XInputStream; } +} + +namespace oox { + +class BinaryOutputStream; + + +/** Interface for binary input stream classes. + + The binary data in the stream is assumed to be in little-endian format. + */ +class OOX_DLLPUBLIC BinaryInputStream : public virtual BinaryStreamBase +{ +public: + /** Derived classes implement reading nBytes bytes to the passed sequence. + The sequence will be reallocated internally. + + @param nAtomSize + The size of the elements in the memory block, if available. Derived + classes may be interested in this information. + + @return + Number of bytes really read. + */ + virtual sal_Int32 readData( StreamDataSequence& orData, sal_Int32 nBytes, size_t nAtomSize = 1 ) = 0; + + /** Derived classes implement reading nBytes bytes to the (preallocated!) + memory buffer opMem. + + @param nAtomSize + The size of the elements in the memory block, if available. Derived + classes may be interested in this information. + + @return + Number of bytes really read. + */ + virtual sal_Int32 readMemory( void* opMem, sal_Int32 nBytes, size_t nAtomSize = 1 ) = 0; + + /** Derived classes implement seeking the stream forward by the passed + number of bytes. This should work for non-seekable streams too. + + @param nAtomSize + The size of the elements in the memory block, if available. Derived + classes may be interested in this information. + */ + virtual void skip( sal_Int32 nBytes, size_t nAtomSize = 1 ) = 0; + + /** Reads a value from the stream and converts it to platform byte order. + All data types supported by the ByteOrderConverter class can be used. + */ + template< typename Type > + [[nodiscard]] + Type readValue(); + + [[nodiscard]] + sal_Int8 readInt8() { return readValue<sal_Int8>(); } + [[nodiscard]] + sal_uInt8 readuInt8() { return readValue<sal_uInt8>(); } + [[nodiscard]] + sal_Int16 readInt16() { return readValue<sal_Int16>(); } + [[nodiscard]] + sal_uInt16 readuInt16() { return readValue<sal_uInt16>(); } + [[nodiscard]] + sal_Int32 readInt32() { return readValue<sal_Int32>(); } + [[nodiscard]] + sal_uInt32 readuInt32() { return readValue<sal_uInt32>(); } + [[nodiscard]] + sal_Int64 readInt64() { return readValue<sal_Int64>(); } + [[nodiscard]] + float readFloat() { return readValue<float>(); } + [[nodiscard]] + double readDouble() { return readValue<double>(); } + [[nodiscard]] + unsigned char readuChar() { return readValue<unsigned char>(); } + + /** Reads a (preallocated!) C array of values from the stream. + + Converts all values in the array to platform byte order. All data types + supported by the ByteOrderConverter class can be used. + + @param nElemCount + Number of array elements to read (NOT byte count). + + @return + Number of array elements really read (NOT byte count). + */ + template< typename Type > + sal_Int32 readArray( Type* opnArray, sal_Int32 nElemCount ); + + /** Reads a vector of values from the stream. + + The vector will be resized internally. Converts all values in the + vector to platform byte order. All data types supported by the + ByteOrderConverter class can be used. + + @param nElemCount + Number of elements to put into the vector (NOT byte count). + + @return + Number of vector elements really read (NOT byte count). + */ + template< typename Type > + sal_Int32 readArray( ::std::vector< Type >& orVector, sal_Int32 nElemCount ); + + /** Reads a NUL-terminated Unicode character array and returns the string. + */ + OUString readNulUnicodeArray(); + + /** Reads a byte character array and returns the string. + NUL characters are replaced by question marks. + + @param nChars + Number of characters (bytes) to read from the stream. + */ + OString readCharArray( sal_Int32 nChars ); + + /** Reads a byte character array and returns a Unicode string. + NUL characters are replaced by question marks. + + @param nChars + Number of characters (bytes) to read from the stream. + + @param eTextEnc + The text encoding used to create the Unicode string. + */ + OUString readCharArrayUC( sal_Int32 nChars, rtl_TextEncoding eTextEnc ); + + /** Reads a Unicode character array and returns the string. + NUL characters are replaced by question marks (default). + + @param nChars + Number of 16-bit characters to read from the stream. + */ + OUString readUnicodeArray( sal_Int32 nChars ); + + /** Reads a Unicode character array (may be compressed) and returns the + string. + NUL characters are replaced by question marks (default). + + @param nChars + Number of 8-bit or 16-bit characters to read from the stream. + + @param bCompressed + True = Character array is compressed (stored as 8-bit characters). + False = Character array is not compressed (stored as 16-bit characters). + */ + OUString readCompressedUnicodeArray( sal_Int32 nChars, bool bCompressed ); + + /** Copies bytes from the current position to the passed output stream. + */ + void copyToStream( BinaryOutputStream& rOutStrm ); + +protected: + /** This dummy default c'tor will never call the c'tor of the virtual base + class BinaryStreamBase as this class cannot be instantiated directly. */ + BinaryInputStream() : BinaryStreamBase( false ) {} + +private: + BinaryInputStream( BinaryInputStream const& ) = delete; + BinaryInputStream& operator=( BinaryInputStream const& ) = delete; +}; + +typedef std::shared_ptr< BinaryInputStream > BinaryInputStreamRef; + + +template< typename Type > +Type BinaryInputStream::readValue() +{ + Type ornValue = Type(); + readMemory( &ornValue, static_cast< sal_Int32 >( sizeof( Type ) ), sizeof( Type ) ); + ByteOrderConverter::convertLittleEndian( ornValue ); + return ornValue; +} + +template< typename Type > +sal_Int32 BinaryInputStream::readArray( Type* opnArray, sal_Int32 nElemCount ) +{ + sal_Int32 nRet = 0; + if( !mbEof ) + { + sal_Int32 nReadSize = getLimitedValue< sal_Int32, sal_Int32 >( nElemCount, 0, SAL_MAX_INT32 / sizeof( Type ) ) * sizeof( Type ); + nRet = readMemory( opnArray, nReadSize, sizeof( Type ) ) / sizeof( Type ); + ByteOrderConverter::convertLittleEndianArray( opnArray, static_cast< size_t >( nRet ) ); + } + return nRet; +} + +template< typename Type > +sal_Int32 BinaryInputStream::readArray( ::std::vector< Type >& orVector, sal_Int32 nElemCount ) +{ + orVector.resize( static_cast< size_t >( nElemCount ) ); + return orVector.empty() ? 0 : readArray(orVector.data(), nElemCount); +} + + +/** Wraps a UNO input stream and provides convenient access functions. + + The binary data in the stream is assumed to be in little-endian format. + */ +class OOX_DLLPUBLIC BinaryXInputStream final : public BinaryXSeekableStream, public BinaryInputStream +{ +public: + /** Constructs the wrapper object for the passed input stream. + + @param rxInStream + The com.sun.star.io.XInputStream interface of the UNO input stream + to be wrapped. + + @param bAutoClose + True = automatically close the wrapped input stream on destruction + of this wrapper or when close() is called. + */ + explicit BinaryXInputStream( + const css::uno::Reference< css::io::XInputStream >& rxInStrm, + bool bAutoClose ); + + virtual ~BinaryXInputStream() override; + + /** Closes the input stream. Does also close the wrapped UNO input stream + if bAutoClose has been set to true in the constructor. */ + virtual void close() override; + + /** Reads nBytes bytes to the passed sequence. + @return Number of bytes really read. */ + virtual sal_Int32 readData( StreamDataSequence& orData, sal_Int32 nBytes, size_t nAtomSize = 1 ) override; + + /** Reads nBytes bytes to the (existing) buffer opMem. + @return Number of bytes really read. */ + virtual sal_Int32 readMemory( void* opMem, sal_Int32 nBytes, size_t nAtomSize = 1 ) override; + + /** Seeks the stream forward by the passed number of bytes. This works for + non-seekable streams too. */ + virtual void skip( sal_Int32 nBytes, size_t nAtomSize = 1 ) override; + +private: + StreamDataSequence maBuffer; ///< Data buffer used in readMemory() function. + css::uno::Reference< css::io::XInputStream > + mxInStrm; ///< Reference to the input stream. + bool mbAutoClose; ///< True = automatically close stream on destruction. +}; + + +/** Wraps a StreamDataSequence and provides convenient access functions. + + The binary data in the stream is assumed to be in little-endian format. + */ +class OOX_DLLPUBLIC SequenceInputStream final : public SequenceSeekableStream, public BinaryInputStream +{ +public: + /** Constructs the wrapper object for the passed data sequence. + + @attention + The passed data sequence MUST live at least as long as this stream + wrapper. The data sequence MUST NOT be changed from outside as long + as this stream wrapper is used to read from it. + */ + explicit SequenceInputStream( const StreamDataSequence& rData ); + + /** Reads nBytes bytes to the passed sequence. + @return Number of bytes really read. */ + virtual sal_Int32 readData( StreamDataSequence& orData, sal_Int32 nBytes, size_t nAtomSize = 1 ) override; + + /** Reads nBytes bytes to the (existing) buffer opMem. + @return Number of bytes really read. */ + virtual sal_Int32 readMemory( void* opMem, sal_Int32 nBytes, size_t nAtomSize = 1 ) override; + + /** Seeks the stream forward by the passed number of bytes. This works for + non-seekable streams too. */ + virtual void skip( sal_Int32 nBytes, size_t nAtomSize = 1 ) override; + +private: + /** Returns the number of bytes available in the sequence for the passed byte count. */ + sal_Int32 getMaxBytes( sal_Int32 nBytes ) const + { return getLimitedValue< sal_Int32, sal_Int32 >( nBytes, 0, mpData->getLength() - mnPos ); } +}; + + +/** Wraps a BinaryInputStream and provides access to a specific part of the + stream data. + + Provides access to the stream data block starting at the current position + of the stream, and with a specific length. If the wrapped stream is + seekable, this wrapper will treat the position of the wrapped stream at + construction time as position "0" (therefore the class name). + + The passed input stream MUST live at least as long as this stream wrapper. + The stream MUST NOT be changed from outside as long as this stream wrapper + is used to read from it. + */ +class RelativeInputStream final : public BinaryInputStream +{ +public: + /** Constructs the wrapper object for the passed stream. + + @param nSize + If specified, restricts the amount of data that can be read from + the passed input stream. + */ + explicit RelativeInputStream( + BinaryInputStream& rInStrm, + sal_Int64 nSize ); + + /** Returns the size of the data block in the wrapped stream offered by + this wrapper. */ + virtual sal_Int64 size() const override; + + /** Returns the current relative stream position. */ + virtual sal_Int64 tell() const override; + + /** Seeks the stream to the passed relative position, if the wrapped stream + is seekable. */ + virtual void seek( sal_Int64 nPos ) override; + + /** Closes the input stream but not the wrapped stream. */ + virtual void close() override; + + /** Reads nBytes bytes to the passed sequence. Does not read out of the + data block whose size has been specified on construction. + @return Number of bytes really read. */ + virtual sal_Int32 readData( StreamDataSequence& orData, sal_Int32 nBytes, size_t nAtomSize = 1 ) override; + + /** Reads nBytes bytes to the (existing) buffer opMem. Does not read out of + the data block whose size has been specified on construction. + @return Number of bytes really read. */ + virtual sal_Int32 readMemory( void* opMem, sal_Int32 nBytes, size_t nAtomSize = 1 ) override; + + /** Seeks the stream forward by the passed number of bytes. This works for + non-seekable streams too. Does not seek out of the data block. */ + virtual void skip( sal_Int32 nBytes, size_t nAtomSize = 1 ) override; + +private: + /** Returns the number of bytes available in the sequence for the passed byte count. */ + sal_Int32 getMaxBytes( sal_Int32 nBytes ) const + { return getLimitedValue< sal_Int32, sal_Int64 >( nBytes, 0, mnSize - mnRelPos ); } + +private: + BinaryInputStream* mpInStrm; + sal_Int64 mnStartPos; + sal_Int64 mnRelPos; + sal_Int64 mnSize; +}; + + +} // namespace oox + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/oox/helper/binaryoutputstream.hxx b/include/oox/helper/binaryoutputstream.hxx new file mode 100644 index 000000000..c1dc8ebb0 --- /dev/null +++ b/include/oox/helper/binaryoutputstream.hxx @@ -0,0 +1,208 @@ +/* -*- 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_HELPER_BINARYOUTPUTSTREAM_HXX +#define INCLUDED_OOX_HELPER_BINARYOUTPUTSTREAM_HXX + +#include <cstddef> +#include <memory> + +#include <com/sun/star/uno/Reference.hxx> +#include <oox/dllapi.h> +#include <oox/helper/binarystreambase.hxx> +#include <oox/helper/helper.hxx> +#include <rtl/textenc.h> +#include <rtl/ustring.hxx> +#include <sal/types.h> + +namespace com::sun::star { + namespace io { class XOutputStream; } +} + +namespace oox { + + +/** Interface for binary output stream classes. + + The binary data in the stream is written in little-endian format. + */ +class BinaryOutputStream : public virtual BinaryStreamBase +{ +public: + /** Derived classes implement writing the contents of the passed data + sequence. + + @param nAtomSize + The size of the elements in the memory block, if available. Derived + classes may be interested in this information. + */ + virtual void writeData( const StreamDataSequence& rData, size_t nAtomSize = 1 ) = 0; + + /** Derived classes implement writing the contents of the (preallocated!) + memory buffer pMem. + + @param nAtomSize + The size of the elements in the memory block, if available. Derived + classes may be interested in this information. + */ + virtual void writeMemory( const void* pMem, sal_Int32 nBytes, size_t nAtomSize = 1 ) = 0; + + template< typename Type > + void writeArray( Type* opnArray, sal_Int32 nElemCount ); + + template< typename Type > + void writeArray( const Type* opnArray, sal_Int32 nElemCount ); + + /** Writes a value to the stream and converts it to platform byte order. + All data types supported by the ByteOrderConverter class can be used. + */ + template< typename Type > + void writeValue( Type nValue ); + + BinaryOutputStream& WriteInt16(sal_Int16 x) { writeValue(x); return *this; } + BinaryOutputStream& WriteUInt16(sal_uInt16 x) { writeValue(x); return *this; } + BinaryOutputStream& WriteInt32(sal_Int32 x) { writeValue(x); return *this; } + BinaryOutputStream& WriteUInt32(sal_uInt32 x) { writeValue(x); return *this; } + BinaryOutputStream& WriteInt64(sal_Int64 x) { writeValue(x); return *this; } + + void writeCompressedUnicodeArray( const OUString& rString, bool bCompressed ); + + void writeCharArrayUC( std::u16string_view rString, rtl_TextEncoding eTextEnc ); + + void writeUnicodeArray( const OUString& rString ); + +protected: + /** This dummy default c'tor will never call the c'tor of the virtual base + class BinaryStreamBase as this class cannot be instantiated directly. */ + BinaryOutputStream() : BinaryStreamBase( false ) {} + +private: + BinaryOutputStream( BinaryOutputStream const& ) = delete; + BinaryOutputStream& operator=( BinaryOutputStream const& ) = delete; +}; + +template< typename Type > +void BinaryOutputStream::writeArray( Type* opnArray, sal_Int32 nElemCount ) +{ + sal_Int32 nWriteSize = getLimitedValue< sal_Int32, sal_Int32 >( nElemCount, 0, SAL_MAX_INT32 / sizeof( Type ) ) * sizeof( Type ); + ByteOrderConverter::convertLittleEndianArray( opnArray, static_cast< size_t >( nElemCount ) ); + writeMemory( opnArray, nWriteSize, sizeof( Type ) ); +} + +template< typename Type > +void BinaryOutputStream::writeArray( const Type* opnArray, sal_Int32 nElemCount ) +{ + std::unique_ptr<Type[]> xArray(new Type[nElemCount]); + std::uninitialized_copy(opnArray, opnArray + nElemCount, xArray.get()); + writeArray(xArray.get(), nElemCount); +} + +template< typename Type > +void BinaryOutputStream::writeValue( Type nValue ) +{ + ByteOrderConverter::convertLittleEndian( nValue ); + writeMemory( &nValue, static_cast< sal_Int32 >( sizeof( Type ) ), sizeof( Type ) ); +} + + +/** Wraps a UNO output stream and provides convenient access functions. + + The binary data in the stream is written in little-endian format. + */ +class OOX_DLLPUBLIC BinaryXOutputStream final : public BinaryXSeekableStream, public BinaryOutputStream +{ +public: + /** Constructs the wrapper object for the passed output stream. + + @param rxOutStream + The com.sun.star.io.XOutputStream interface of the output stream to + be wrapped. + + @param bAutoClose + True = automatically close the wrapped output stream on destruction + of this wrapper or when close() is called. + */ + explicit BinaryXOutputStream( + const css::uno::Reference< css::io::XOutputStream >& rxOutStrm, + bool bAutoClose ); + + virtual ~BinaryXOutputStream() override; + + /** Flushes and closes the output stream. Does also close the wrapped UNO + output stream if bAutoClose has been set to true in the constructor. */ + void close() override; + + /** Writes the passed data sequence. */ + virtual void writeData( const StreamDataSequence& rData, size_t nAtomSize = 1 ) override; + + /** Write nBytes bytes from the (preallocated!) buffer pMem. */ + virtual void writeMemory( const void* pMem, sal_Int32 nBytes, size_t nAtomSize = 1 ) override; + +private: + StreamDataSequence maBuffer; ///< Data buffer used in writeMemory() function. + css::uno::Reference< css::io::XOutputStream > + mxOutStrm; ///< Reference to the output stream. + bool mbAutoClose; ///< True = automatically close stream on destruction. +}; + + +/** Wraps a StreamDataSequence and provides convenient access functions. + + The binary data in the stream is written in little-endian format. After + construction, the stream points to the beginning of the passed data + sequence. The data sequence is expanded automatically while writing to it. + */ +class SequenceOutputStream final : public BinaryOutputStream +{ +public: + /** Constructs the wrapper object for the passed data sequence. + + @attention + The passed data sequence MUST live at least as long as this stream + wrapper. The data sequence MUST NOT be changed from outside as long + as this stream wrapper is used to write to it. + */ + explicit SequenceOutputStream( StreamDataSequence & rData ); + + /** Writes the passed data sequence. */ + virtual void writeData( const StreamDataSequence& rData, size_t nAtomSize = 1 ) override; + + /** Write nBytes bytes from the (preallocated!) buffer pMem. */ + virtual void writeMemory( const void* pMem, sal_Int32 nBytes, size_t nAtomSize = 1 ) override; + + /** Returns the size of the wrapped data sequence. */ + virtual sal_Int64 size() const override; + /** Returns the current stream position. */ + virtual sal_Int64 tell() const override; + /** Seeks the stream to the passed position. */ + virtual void seek( sal_Int64 nPos ) override; + /** Releases the reference to the data sequence. */ + virtual void close() override; + +private: + StreamDataSequence* mpData; ///< Wrapped data sequence. + sal_Int32 mnPos; ///< Current position in the sequence. +}; + + +} // namespace oox + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/oox/helper/binarystreambase.hxx b/include/oox/helper/binarystreambase.hxx new file mode 100644 index 000000000..8e93d1458 --- /dev/null +++ b/include/oox/helper/binarystreambase.hxx @@ -0,0 +1,179 @@ +/* -*- 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_HELPER_BINARYSTREAMBASE_HXX +#define INCLUDED_OOX_HELPER_BINARYSTREAMBASE_HXX + +#include <com/sun/star/uno/Reference.hxx> +#include <com/sun/star/uno/Sequence.hxx> +#include <oox/dllapi.h> +#include <sal/types.h> + +namespace com::sun::star { + namespace io { class XSeekable; } +} + +namespace oox { + +typedef css::uno::Sequence< sal_Int8 > StreamDataSequence; + + +/** Base class for binary stream classes. + */ +class OOX_DLLPUBLIC BinaryStreamBase +{ +public: + virtual ~BinaryStreamBase(); + + /** Implementations return the size of the stream, if possible. + + This function may be implemented for some types of unseekable streams, + and MUST be implemented for all seekable streams. + + @return + The size of the stream in bytes, or -1, if not implemented. + */ + virtual sal_Int64 size() const = 0; + + /** Implementations return the current stream position, if possible. + + This function may be implemented for some types of unseekable streams, + and MUST be implemented for all seekable streams. + + @return + The current position in the stream, or -1, if not implemented. + */ + virtual sal_Int64 tell() const = 0; + + /** Implementations seek the stream to the passed position, if + the stream is seekable. + */ + virtual void seek( sal_Int64 nPos ) = 0; + + /** Implementations close the stream. + */ + virtual void close() = 0; + + /** Returns true, if the implementation supports the seek() operation. + + Implementations may still implement size() and tell() even if the + stream is not seekable. + */ + bool isSeekable() const { return mbSeekable; } + + /** Returns true, if the stream position is invalid (EOF). This flag turns + true *after* the first attempt to seek/read beyond the stream end. + */ + bool isEof() const { return mbEof; } + + /** Returns the size of the remaining data available in the stream, if + stream supports size() and tell(), otherwise -1. + */ + sal_Int64 getRemaining() const; + + /** Seeks the stream to the beginning, if stream is seekable. + */ + void seekToStart() { seek( 0 ); } + + /** Seeks the stream forward to a position that is a multiple of the passed + block size, if stream is seekable. + + @param nBlockSize + The size of the data blocks the streams needs to be aligned to. + + @param nAnchorPos + Position in the stream the data blocks are aligned to. + */ + void alignToBlock( sal_Int32 nBlockSize, sal_Int64 nAnchorPos ); + +protected: + explicit BinaryStreamBase( bool bSeekable ) : mbEof( false ), mbSeekable( bSeekable ) {} + +private: + BinaryStreamBase( const BinaryStreamBase& ) = delete; + BinaryStreamBase& operator=( const BinaryStreamBase& ) = delete; + +protected: + bool mbEof; ///< End of stream flag. + +private: + const bool mbSeekable; ///< True = implementation supports seeking. +}; + + +/** Base class for binary input and output streams wrapping a UNO stream, + seekable via the com.sun.star.io.XSeekable interface. + */ +class BinaryXSeekableStream : public virtual BinaryStreamBase +{ +public: + virtual ~BinaryXSeekableStream() override; + + /** Returns the size of the stream, if wrapped stream is seekable, otherwise -1. */ + virtual sal_Int64 size() const override; + /** Returns the current stream position, if wrapped stream is seekable, otherwise -1. */ + virtual sal_Int64 tell() const override; + /** Seeks the stream to the passed position, if wrapped stream is seekable. */ + virtual void seek( sal_Int64 nPos ) override; + /** Releases the reference to the UNO XSeekable interface. */ + virtual void close() override; + +protected: + explicit BinaryXSeekableStream( + const css::uno::Reference< css::io::XSeekable >& rxSeekable ); + +private: + css::uno::Reference< css::io::XSeekable > + mxSeekable; ///< Stream seeking interface. +}; + + +/** Base class for binary input and output streams wrapping a + StreamDataSequence, which is always seekable. + + The wrapped data sequence MUST live at least as long as this stream + wrapper. The data sequence MUST NOT be changed from outside as long as this + stream wrapper is used to modify it. + */ +class OOX_DLLPUBLIC SequenceSeekableStream : public virtual BinaryStreamBase +{ +public: + /** Returns the size of the wrapped data sequence. */ + virtual sal_Int64 size() const override; + /** Returns the current stream position. */ + virtual sal_Int64 tell() const override; + /** Seeks the stream to the passed position. */ + virtual void seek( sal_Int64 nPos ) override; + /** Releases the reference to the data sequence. */ + virtual void close() override; + +protected: + explicit SequenceSeekableStream( const StreamDataSequence& rData ); + +protected: + const StreamDataSequence* mpData; ///< Wrapped data sequence. + sal_Int32 mnPos; ///< Current position in the sequence. +}; + + +} // namespace oox + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/oox/helper/containerhelper.hxx b/include/oox/helper/containerhelper.hxx new file mode 100644 index 000000000..3b725d509 --- /dev/null +++ b/include/oox/helper/containerhelper.hxx @@ -0,0 +1,298 @@ +/* -*- 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_HELPER_CONTAINERHELPER_HXX +#define INCLUDED_OOX_HELPER_CONTAINERHELPER_HXX + +#include <cstddef> +#include <vector> + +#include <com/sun/star/uno/Reference.hxx> +#include <com/sun/star/uno/Sequence.hxx> +#include <oox/dllapi.h> +#include <rtl/ustring.hxx> +#include <sal/types.h> + +namespace com::sun::star { + namespace container { class XNameAccess; } + namespace container { class XNameContainer; } + namespace uno { class Any; } +} + +namespace oox { + + +/** A range of signed 32-bit integer values. */ +struct ValueRange +{ + sal_Int32 mnFirst; + sal_Int32 mnLast; + + explicit ValueRange( sal_Int32 nValue ) : mnFirst( nValue ), mnLast( nValue ) {} + explicit ValueRange( sal_Int32 nFirst, sal_Int32 nLast ) : mnFirst( nFirst ), mnLast( nLast ) {} + + bool operator==( const ValueRange& rRange ) const { return (mnFirst == rRange.mnFirst) && (mnLast == rRange.mnLast); } + bool operator!=( const ValueRange& rRange ) const { return !(*this == rRange); } + bool contains( const ValueRange& rRange ) const { return (mnFirst <= rRange.mnFirst) && (rRange.mnLast <= mnLast); } + bool intersects( const ValueRange& rRange ) const { return (mnFirst <= rRange.mnLast) && (rRange.mnFirst <= mnLast); } +}; + + +typedef ::std::vector< ValueRange > ValueRangeVector; + + +/** An ordered list of value ranges. The insertion operation will merge + consecutive value ranges. + */ +class OOX_DLLPUBLIC ValueRangeSet +{ +public: + ValueRangeSet() {} + + /** Inserts the passed value range into the range list. */ + void insert( const ValueRange& rRange ); + + /** Returns the ordered list of all value ranges. */ + const ValueRangeVector& getRanges() const { return maRanges; } + +private: + ValueRangeVector maRanges; +}; + + +/** Template for a 2-dimensional array of objects. + + This class template provides a similar interface to the ::std::vector + template. + */ +template< typename Type > +class Matrix +{ +public: + typedef ::std::vector< Type > container_type; + typedef typename container_type::value_type value_type; + typedef typename container_type::pointer pointer; + typedef typename container_type::reference reference; + typedef typename container_type::const_reference const_reference; + typedef typename container_type::size_type size_type; + typedef typename container_type::iterator iterator; + typedef typename container_type::const_iterator const_iterator; + + Matrix() : mnWidth( 0 ) {} + explicit Matrix( size_type nWidth, size_type nHeight ) { resize( nWidth, nHeight ); } + explicit Matrix( size_type nWidth, size_type nHeight, const_reference rData ) { resize( nWidth, nHeight, rData ); } + + bool empty() const { return maData.empty(); } + size_type size() const { return maData.size(); } + size_type width() const { return mnWidth; } + size_type height() const { return empty() ? 0 : (size() / width()); } + + void clear() { resize( 0, 0 ); } + void resize( size_type nWidth, size_type nHeight ) { mnWidth = nWidth; maData.resize( nWidth * nHeight ); } + void resize( size_type nWidth, size_type nHeight, const_reference rData ) { mnWidth = nWidth; maData.resize( nWidth * nHeight, rData ); } + + iterator at( size_type nX, size_type nY ) { return maData.begin() + mnWidth * nY + nX; } + const_iterator at( size_type nX, size_type nY ) const { return maData.begin() + mnWidth * nY + nX; } + + reference operator()( size_type nX, size_type nY ) { return *at( nX, nY ); } + const_reference operator()( size_type nX, size_type nY ) const { return *at( nX, nY ); } + + iterator begin() { return maData.begin(); } + const_iterator begin() const { return maData.begin(); } + iterator end() { return maData.end(); } + const_iterator end() const { return maData.end(); } + + iterator row_begin( size_type nY ) { return at( 0, nY ); } + const_iterator row_begin( size_type nY ) const { return at( 0, nY ); } + iterator row_end( size_type nY ) { return at( mnWidth, nY ); } + const_iterator row_end( size_type nY ) const { return at( mnWidth, nY ); } + + reference row_front( size_type nY ) { return (*this)( 0, nY ); } + const_reference row_front( size_type nY ) const { return (*this)( 0, nY ); } + +private: + container_type maData; + size_type mnWidth; +}; + + +/** Static helper functions for improved API container handling. */ +class OOX_DLLPUBLIC ContainerHelper +{ +public: + + /** Returns a name that is not used in the passed name container. + + @param rxNameAccess com.sun.star.container.XNameAccess interface of + the name container. + + @param rSuggestedName Suggested name for the object. + + @return An unused name. Will be equal to the suggested name, if not + contained, otherwise a numerical index will be appended. + */ + static OUString getUnusedName( + const css::uno::Reference< css::container::XNameAccess >& rxNameAccess, + const OUString& rSuggestedName, + sal_Unicode cSeparator ); + + /** Inserts an object into a name container. + + @param rxNameContainer com.sun.star.container.XNameContainer interface + of the name container. + + @param rName Exact name for the object. + + @param rObject The object to be inserted. + + @return True = object successfully inserted. + */ + static bool insertByName( + const css::uno::Reference< css::container::XNameContainer >& rxNameContainer, + const OUString& rName, + const css::uno::Any& rObject ); + + /** Inserts an object into a name container. + + The function will use an unused name to insert the object, based on the + suggested object name. It is possible to specify whether the existing + object or the new inserted object will be renamed, if the container + already has an object with the name suggested for the new object. + + @param rxNameContainer com.sun.star.container.XNameContainer interface + of the name container. + + @param rSuggestedName Suggested name for the object. + + @param rObject The object to be inserted. + + The new object + will be inserted with a name not yet extant in the container (this + is done by appending a numerical index to the suggested name). + + @return The final name the object is inserted with. Will always be + equal to the suggested name, if parameter bRenameOldExisting is + true. + */ + static OUString insertByUnusedName( + const css::uno::Reference< css::container::XNameContainer >& rxNameContainer, + const OUString& rSuggestedName, + sal_Unicode cSeparator, + const css::uno::Any& rObject ); + + // std::vector and std::map element access -------------------------------- + + /** Returns the pointer to an existing element of the passed vector, or a + null pointer, if the passed index is out of bounds. */ + template< typename VectorType > + static const typename VectorType::value_type* + getVectorElement( const VectorType& rVector, sal_Int32 nIndex ); + + /** Returns the pointer to an existing element of the passed vector, or a + null pointer, if the passed index is out of bounds. */ + template< typename VectorType > + static typename VectorType::value_type* + getVectorElementAccess( VectorType& rVector, sal_Int32 nIndex ); + + /** Returns the reference to an existing element of the passed vector, or + the passed default value, if the passed index is out of bounds. */ + template< typename VectorType > + static const typename VectorType::value_type& + getVectorElement( const VectorType& rVector, sal_Int32 nIndex, const typename VectorType::value_type& rDefault ); + + /** Returns the pointer to an existing element of the passed map, or a null + pointer, if an element with the passed key does not exist. */ + template< typename MapType > + static const typename MapType::mapped_type* + getMapElement( const MapType& rMap, const typename MapType::key_type& rKey ); + + /** Returns the reference to an existing element of the passed map, or the + passed default value, if an element with the passed key does not exist. */ + template< typename MapType > + static const typename MapType::mapped_type& + getMapElement( const MapType& rMap, const typename MapType::key_type& rKey, const typename MapType::mapped_type& rDefault ); + + /** Creates a UNO sequence of sequences from a matrix with copies of all elements. + + @param rMatrix The matrix to be converted to a sequence of sequences. + + @return A com.sun.star.uno.Sequence object containing + com.sun.star.uno.Sequence objects with copies of all objects + contained in the passed matrix. + */ + template< typename MatrixType > + static css::uno::Sequence< css::uno::Sequence< typename MatrixType::value_type > > + matrixToSequenceSequence( const MatrixType& rMatrix ); +}; + + +template< typename VectorType > +/*static*/ const typename VectorType::value_type* ContainerHelper::getVectorElement( const VectorType& rVector, sal_Int32 nIndex ) +{ + return ((0 <= nIndex) && (static_cast< size_t >( nIndex ) < rVector.size())) ? &rVector[ static_cast< size_t >( nIndex ) ] : nullptr; +} + +template< typename VectorType > +/*static*/ typename VectorType::value_type* ContainerHelper::getVectorElementAccess( VectorType& rVector, sal_Int32 nIndex ) +{ + return ((0 <= nIndex) && (static_cast< size_t >( nIndex ) < rVector.size())) ? &rVector[ static_cast< size_t >( nIndex ) ] : nullptr; +} + +template< typename VectorType > +/*static*/ const typename VectorType::value_type& ContainerHelper::getVectorElement( const VectorType& rVector, sal_Int32 nIndex, const typename VectorType::value_type& rDefault ) +{ + return ((0 <= nIndex) && (static_cast< size_t >( nIndex ) < rVector.size())) ? rVector[ static_cast< size_t >( nIndex ) ] : rDefault; +} + +template< typename MapType > +/*static*/ const typename MapType::mapped_type* ContainerHelper::getMapElement( const MapType& rMap, const typename MapType::key_type& rKey ) +{ + typename MapType::const_iterator aIt = rMap.find( rKey ); + return (aIt == rMap.end()) ? nullptr : &aIt->second; +} + +template< typename MapType > +/*static*/ const typename MapType::mapped_type& ContainerHelper::getMapElement( const MapType& rMap, const typename MapType::key_type& rKey, const typename MapType::mapped_type& rDefault ) +{ + typename MapType::const_iterator aIt = rMap.find( rKey ); + return (aIt == rMap.end()) ? rDefault : aIt->second; +} + +template< typename MatrixType > +/*static*/ css::uno::Sequence< css::uno::Sequence< typename MatrixType::value_type > > ContainerHelper::matrixToSequenceSequence( const MatrixType& rMatrix ) +{ + typedef typename MatrixType::value_type ValueType; + css::uno::Sequence< css::uno::Sequence< ValueType > > aSeq; + if( !rMatrix.empty() ) + { + aSeq.realloc( static_cast< sal_Int32 >( rMatrix.height() ) ); + auto pSeq = aSeq.getArray(); + for( size_t nRow = 0, nHeight = rMatrix.height(); nRow < nHeight; ++nRow ) + pSeq[ static_cast< sal_Int32 >( nRow ) ] = + css::uno::Sequence< ValueType >( &rMatrix.row_front( nRow ), static_cast< sal_Int32 >( rMatrix.width() ) ); + } + return aSeq; +} + + +} // namespace oox + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/oox/helper/grabbagstack.hxx b/include/oox/helper/grabbagstack.hxx new file mode 100644 index 000000000..bd03535c9 --- /dev/null +++ b/include/oox/helper/grabbagstack.hxx @@ -0,0 +1,61 @@ +/* -*- 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/. + * + */ + +#ifndef INCLUDED_OOX_HELPER_GRABBAGSTACK_HXX +#define INCLUDED_OOX_HELPER_GRABBAGSTACK_HXX + +#include <stack> +#include <vector> + +#include <com/sun/star/beans/PropertyValue.hpp> +#include <oox/dllapi.h> +#include <rtl/ustring.hxx> +#include <sal/types.h> + +namespace com::sun::star { + namespace uno { class Any; } +} + +namespace oox { + +struct GrabBagStackElement +{ + OUString maElementName; + std::vector<css::beans::PropertyValue> maPropertyList; +}; + +/// Tool that is useful for construction of a nested Sequence/PropertyValue hierarchy +class OOX_DLLPUBLIC GrabBagStack final +{ +private: + std::stack<GrabBagStackElement> mStack; + GrabBagStackElement mCurrentElement; + +public: + GrabBagStack(const OUString& aElementName); + ~GrabBagStack(); + + const OUString& getCurrentName() const { return mCurrentElement.maElementName;} + + css::beans::PropertyValue getRootProperty(); + + void appendElement(const OUString& aName, const css::uno::Any& aAny); + void push(const OUString& aKey); + void pop(); + void addInt32(const OUString& aElementName, sal_Int32 aIntValue); + void addString(const OUString& aElementName, const OUString& aStringValue); + bool isStackEmpty() const; +}; + +} // namespace oox + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/oox/helper/graphichelper.hxx b/include/oox/helper/graphichelper.hxx new file mode 100644 index 000000000..eab39beff --- /dev/null +++ b/include/oox/helper/graphichelper.hxx @@ -0,0 +1,161 @@ +/* -*- 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_HELPER_GRAPHICHELPER_HXX +#define INCLUDED_OOX_HELPER_GRAPHICHELPER_HXX + +#include <map> + +#include <com/sun/star/awt/DeviceInfo.hpp> +#include <com/sun/star/uno/Reference.hxx> +#include <oox/dllapi.h> +#include <oox/helper/binarystreambase.hxx> +#include <oox/helper/helper.hxx> +#include <oox/helper/storagebase.hxx> +#include <rtl/ustring.hxx> +#include <sal/types.h> +#include <com/sun/star/graphic/XGraphicProvider2.hpp> +#include <com/sun/star/graphic/XGraphicMapper.hpp> +#include <vcl/vclptr.hxx> + +struct WmfExternal; +class OutputDevice; + +namespace com::sun::star { + namespace awt { struct Point; } + namespace awt { struct Size; } + namespace awt { class XUnitConversion; } + namespace io { class XInputStream; } + namespace frame { class XFrame; } + namespace graphic { class XGraphic; } + namespace graphic { class XGraphicObject; } + namespace graphic { class XGraphicProvider; } + namespace uno { class XComponentContext; } +} + +namespace oox { + + +/** Provides helper functions for colors, device measurement conversion, + graphics, and graphic objects handling. + */ +class OOX_DLLPUBLIC GraphicHelper +{ +public: + explicit GraphicHelper( + const css::uno::Reference< css::uno::XComponentContext >& rxContext, + const css::uno::Reference< css::frame::XFrame >& rxTargetFrame, + const StorageRef& rxStorage ); + virtual ~GraphicHelper(); + + // Avoid implicitly defined copy constructors/assignments for the DLLPUBLIC class (they may + // require forward-declared classes used internally to be defined in places using GraphicHelper) + GraphicHelper(const GraphicHelper&) = delete; + GraphicHelper(GraphicHelper&&) = delete; + GraphicHelper& operator=(const GraphicHelper&) = delete; + GraphicHelper& operator=(GraphicHelper&&) = delete; + + // System colors and predefined colors ------------------------------------ + + /** Returns a system color specified by the passed XML token identifier. */ + ::Color getSystemColor( sal_Int32 nToken, ::Color nDefaultRgb = API_RGB_TRANSPARENT ) const; + /** Derived classes may implement to resolve a scheme color from the passed XML token identifier. */ + virtual ::Color getSchemeColor( sal_Int32 nToken ) const; + /** Derived classes may implement to resolve a palette index to an RGB color. */ + virtual ::Color getPaletteColor( sal_Int32 nPaletteIdx ) const; + + virtual sal_Int32 getDefaultChartAreaFillStyle() const; + + /** Returns chartspace automatic default border style */ + static sal_Int32 getDefaultChartAreaLineStyle(); + + /** Returns chartspace automatic default border width in Emu */ + static sal_Int16 getDefaultChartAreaLineWidth(); + + // Device info and device dependent unit conversion ----------------------- + + /** Returns information about the output device. */ + const css::awt::DeviceInfo& getDeviceInfo() const { return maDeviceInfo;} + + /** Converts the passed value from horizontal screen pixels to 1/100 mm. */ + sal_Int32 convertScreenPixelXToHmm( double fPixelX ) const; + /** Converts the passed value from vertical screen pixels to 1/100 mm. */ + sal_Int32 convertScreenPixelYToHmm( double fPixelY ) const; + /** Converts the passed size from screen pixels to 1/100 mm. */ + css::awt::Size convertScreenPixelToHmm( const css::awt::Size& rPixel ) const; + + /** Converts the passed value from 1/100 mm to horizontal screen pixels. */ + double convertHmmToScreenPixelX( sal_Int32 nHmmX ) const; + /** Converts the passed value from 1/100 mm to vertical screen pixels. */ + double convertHmmToScreenPixelY( sal_Int32 nHmmY ) const; + /** Converts the passed point from 1/100 mm to screen pixels. */ + css::awt::Point convertHmmToScreenPixel( const css::awt::Point& rHmm ) const; + /** Converts the passed size from 1/100 mm to screen pixels. */ + css::awt::Size convertHmmToScreenPixel( const css::awt::Size& rHmm ) const; + + /** Converts the passed point from 1/100 mm to AppFont units. */ + css::awt::Point convertHmmToAppFont( const css::awt::Point& rHmm ) const; + /** Converts the passed size from 1/100 mm to AppFont units. */ + css::awt::Size convertHmmToAppFont( const css::awt::Size& rHmm ) const; + + + // Graphics and graphic objects ------------------------------------------ + + /** Imports a graphic from the passed input stream. */ + css::uno::Reference< css::graphic::XGraphic > + importGraphic( + const css::uno::Reference< css::io::XInputStream >& rxInStrm, + const WmfExternal* pExtHeader = nullptr ) const; + + /** Imports a graphic from the passed binary memory block. */ + css::uno::Reference< css::graphic::XGraphic > + importGraphic( const StreamDataSequence& rGraphicData ) const; + + /** Imports a graphic from the storage stream with the passed path and name. */ + css::uno::Reference< css::graphic::XGraphic > + importEmbeddedGraphic( + const OUString& rStreamName, + const WmfExternal* pExtHeader = nullptr ) const; + + /** calculates the original size of a graphic which is necessary to be able to calculate cropping values + @return The original Graphic size in 100thmm */ + css::awt::Size getOriginalSize( const css::uno::Reference< css::graphic::XGraphic >& rxGraphic ) const; + + void setGraphicMapper(css::uno::Reference<css::graphic::XGraphicMapper> const & rxGraphicMapper); + + void initializeGraphicMapperIfNeeded() const; +private: + + css::uno::Reference< css::uno::XComponentContext > mxContext; + css::uno::Reference< css::graphic::XGraphicProvider2 > mxGraphicProvider; + VclPtr<OutputDevice> mxDefaultOutputDevice; + css::awt::DeviceInfo maDeviceInfo; ///< Current output device info. + ::std::map< sal_Int32, ::Color > maSystemPalette; ///< Maps system colors (XML tokens) to RGB color values. + StorageRef mxStorage; ///< Storage containing embedded graphics. + double mfPixelPerHmmX; ///< Number of screen pixels per 1/100 mm in X direction. + double mfPixelPerHmmY; ///< Number of screen pixels per 1/100 mm in Y direction. + css::uno::Reference<css::graphic::XGraphicMapper> mxGraphicMapper; +}; + + +} // namespace oox + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/oox/helper/helper.hxx b/include/oox/helper/helper.hxx new file mode 100644 index 000000000..63718ca0e --- /dev/null +++ b/include/oox/helper/helper.hxx @@ -0,0 +1,301 @@ +/* -*- 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_HELPER_HELPER_HXX +#define INCLUDED_OOX_HELPER_HELPER_HXX + +#include <sal/config.h> + +#include <cstring> +#include <limits> + +#include <o3tl/safeint.hxx> +#include <osl/endian.h> +#include <rtl/math.hxx> +#include <sal/macros.h> +#include <sal/types.h> +#include <tools/color.hxx> + +namespace oox { + +// Helper macros ============================================================== + +namespace detail { + +//TODO: Temporary helper for STATIC_ARRAY_SELECT; ultimately, the latter should be replaced by a +// proper function (template): +template<typename T> constexpr std::make_unsigned_t<T> make_unsigned(T value) { + if constexpr (std::is_signed_v<T>) { + return o3tl::make_unsigned(value); + } else { + return value; + } +} + +} + +/** Expands to the 'index'-th element of a STATIC data array, or to 'def', if + 'index' is out of the array limits. */ +#define STATIC_ARRAY_SELECT( array, index, def ) \ + ((detail::make_unsigned(index) < SAL_N_ELEMENTS(array)) ? ((array)[static_cast<size_t>(index)]) : (def)) + +// Common constants =========================================================== + +const sal_uInt8 WINDOWS_CHARSET_ANSI = 0; +const sal_uInt8 WINDOWS_CHARSET_DEFAULT = 1; +const sal_uInt8 WINDOWS_CHARSET_SYMBOL = 2; +const sal_uInt8 WINDOWS_CHARSET_APPLE_ROMAN = 77; +const sal_uInt8 WINDOWS_CHARSET_SHIFTJIS = 128; +const sal_uInt8 WINDOWS_CHARSET_HANGEUL = 129; +const sal_uInt8 WINDOWS_CHARSET_JOHAB = 130; +const sal_uInt8 WINDOWS_CHARSET_GB2312 = 134; +const sal_uInt8 WINDOWS_CHARSET_BIG5 = 136; +const sal_uInt8 WINDOWS_CHARSET_GREEK = 161; +const sal_uInt8 WINDOWS_CHARSET_TURKISH = 162; +const sal_uInt8 WINDOWS_CHARSET_VIETNAMESE = 163; +const sal_uInt8 WINDOWS_CHARSET_HEBREW = 177; +const sal_uInt8 WINDOWS_CHARSET_ARABIC = 178; +const sal_uInt8 WINDOWS_CHARSET_BALTIC = 186; +const sal_uInt8 WINDOWS_CHARSET_RUSSIAN = 204; +const sal_uInt8 WINDOWS_CHARSET_THAI = 222; +const sal_uInt8 WINDOWS_CHARSET_EASTERN = 238; +const sal_uInt8 WINDOWS_CHARSET_OEM = 255; + + +const ::Color API_RGB_TRANSPARENT (ColorTransparency, 0xffffffff); ///< Transparent color for API calls. +const sal_uInt32 UNSIGNED_RGB_TRANSPARENT = static_cast<sal_uInt32>(-1); ///< Transparent color for unsigned int32 places. +const ::Color API_RGB_BLACK (0x000000); ///< Black color for API calls. +const ::Color API_RGB_GRAY (0x808080); ///< Gray color for API calls. +const ::Color API_RGB_WHITE (0xFFFFFF); ///< White color for API calls. + +const sal_Int16 API_LINE_SOLID = 0; +const sal_Int16 API_LINE_DOTTED = 1; +const sal_Int16 API_LINE_DASHED = 2; +const sal_Int16 API_FINE_LINE_DASHED = 14; + +const sal_Int16 API_LINE_NONE = 0; +const sal_Int16 API_LINE_HAIR = 2; +const sal_Int16 API_LINE_THIN = 35; +const sal_Int16 API_LINE_MEDIUM = 88; +const sal_Int16 API_LINE_THICK = 141; + +const sal_Int16 API_ESCAPE_NONE = 0; ///< No escapement. +const sal_Int16 API_ESCAPE_SUPERSCRIPT = 101; ///< Superscript: raise characters automatically (magic value 101). +const sal_Int16 API_ESCAPE_SUBSCRIPT = -101; ///< Subscript: lower characters automatically (magic value -101). + +const sal_Int8 API_ESCAPEHEIGHT_NONE = 100; ///< Relative character height if not escaped. +const sal_Int8 API_ESCAPEHEIGHT_DEFAULT = 58; ///< Relative character height if escaped. + + +// Limitate values ------------------------------------------------------------ + +template< typename ReturnType, typename Type > +inline ReturnType getLimitedValue( Type nValue, Type nMin, Type nMax ) +{ + return static_cast< ReturnType >( ::std::clamp( nValue, nMin, nMax ) ); +} + +template< typename ReturnType, typename Type > +inline ReturnType getIntervalValue( Type nValue, Type nBegin, Type nEnd ) +{ + static_assert(::std::numeric_limits< Type >::is_integer, "is integer"); + Type nInterval = nEnd - nBegin; + Type nCount = (nValue < nBegin) ? -((nBegin - nValue - 1) / nInterval + 1) : ((nValue - nBegin) / nInterval); + return static_cast< ReturnType >( nValue - nCount * nInterval ); +} + +template< typename ReturnType > +inline ReturnType getDoubleIntervalValue( double fValue, double fBegin, double fEnd ) +{ + double fInterval = fEnd - fBegin; + double fCount = (fValue < fBegin) ? -(::rtl::math::approxFloor( (fBegin - fValue - 1.0) / fInterval ) + 1.0) : ::rtl::math::approxFloor( (fValue - fBegin) / fInterval ); + return static_cast< ReturnType >( fValue - fCount * fInterval ); +} + +// Read from bitfields -------------------------------------------------------- + +/** Returns true, if at least one of the bits set in nMask is set in nBitField. */ +template< typename Type > +inline bool getFlag( Type nBitField, Type nMask ) +{ + return (nBitField & nMask) != 0; +} + +/** Returns nSet, if at least one bit of nMask is set in nBitField, otherwise nUnset. */ +template< typename ReturnType, typename Type > +inline ReturnType getFlagValue( Type nBitField, Type nMask, ReturnType nSet, ReturnType nUnset ) +{ + return getFlag( nBitField, nMask ) ? nSet : nUnset; +} + +/** Extracts a value from a bit field. + + Returns the data fragment from nBitField, that starts at bit nStartBit + (0-based, bit 0 is rightmost) with the width of nBitCount. The returned + value will be right-aligned (normalized). + For instance: extractValue<T>(0x4321,8,4) returns 3 (value in bits 8-11). + */ +template< typename ReturnType, typename Type > +inline ReturnType extractValue( Type nBitField, sal_uInt8 nStartBit, sal_uInt8 nBitCount ) +{ + sal_uInt64 nMask = 1; nMask <<= nBitCount; --nMask; + return static_cast< ReturnType >( nMask & (nBitField >> nStartBit) ); +} + +// Write to bitfields --------------------------------------------------------- + +/** Sets or clears (according to bSet) all set bits of nMask in ornBitField. */ +template< typename Type > +inline void setFlag( Type& ornBitField, Type nMask, bool bSet = true ) +{ + if( bSet ) ornBitField |= nMask; else ornBitField &= ~nMask; +} + + +/** Optional value, similar to ::std::optional<>, with convenience accessors. + */ +template< typename Type > +class OptValue +{ +public: + OptValue() : maValue(), mbHasValue( false ) {} + explicit OptValue( const Type& rValue ) : maValue( rValue ), mbHasValue( true ) {} + explicit OptValue( bool bHasValue, const Type& rValue ) : maValue( rValue ), mbHasValue( bHasValue ) {} + + bool has() const { return mbHasValue; } + bool operator!() const { return !mbHasValue; } + bool differsFrom( const Type& rValue ) const { return mbHasValue && (maValue != rValue); } + + const Type& get() const { return maValue; } + const Type& get( const Type& rDefValue ) const { return mbHasValue ? maValue : rDefValue; } + + void set( const Type& rValue ) { maValue = rValue; mbHasValue = true; } + Type& use() { mbHasValue = true; return maValue; } + + OptValue& operator=( const Type& rValue ) { set( rValue ); return *this; } + bool operator==( const OptValue& rValue ) const { + return ( ( !mbHasValue && rValue.mbHasValue == false ) || + ( mbHasValue == rValue.mbHasValue && maValue == rValue.maValue ) ); + } + void assignIfUsed( const OptValue& rValue ) { if( rValue.mbHasValue ) set( rValue.maValue ); } + +private: + Type maValue; + bool mbHasValue; +}; + + +/** Provides platform independent functions to convert from or to little-endian + byte order, e.g. for reading data from or writing data to memory or a + binary stream. + + On big-endian platforms, the byte order in the passed values is swapped, + this can be used for converting big-endian to and from little-endian data. + + On little-endian platforms, the conversion functions are implemented empty, + thus compilers should completely optimize away the function call. + */ +class ByteOrderConverter +{ +public: +#ifdef OSL_BIGENDIAN + static void convertLittleEndian( sal_Int8& ) {} // present for usage in templates + static void convertLittleEndian( sal_uInt8& ) {} // present for usage in templates + static void convertLittleEndian( char16_t& rnValue ) { swap2( reinterpret_cast< sal_uInt8* >( &rnValue ) ); } + static void convertLittleEndian( sal_Int16& rnValue ) { swap2( reinterpret_cast< sal_uInt8* >( &rnValue ) ); } + static void convertLittleEndian( sal_uInt16& rnValue ) { swap2( reinterpret_cast< sal_uInt8* >( &rnValue ) ); } + static void convertLittleEndian( sal_Int32& rnValue ) { swap4( reinterpret_cast< sal_uInt8* >( &rnValue ) ); } + static void convertLittleEndian( sal_uInt32& rnValue ) { swap4( reinterpret_cast< sal_uInt8* >( &rnValue ) ); } + static void convertLittleEndian( sal_Int64& rnValue ) { swap8( reinterpret_cast< sal_uInt8* >( &rnValue ) ); } + static void convertLittleEndian( sal_uInt64& rnValue ) { swap8( reinterpret_cast< sal_uInt8* >( &rnValue ) ); } + static void convertLittleEndian( float& rfValue ) { swap4( reinterpret_cast< sal_uInt8* >( &rfValue ) ); } + static void convertLittleEndian( double& rfValue ) { swap8( reinterpret_cast< sal_uInt8* >( &rfValue ) ); } + + template< typename Type > + inline static void convertLittleEndianArray( Type* pnArray, size_t nElemCount ); + + static void convertLittleEndianArray( sal_Int8*, size_t ) {} + static void convertLittleEndianArray( sal_uInt8*, size_t ) {} + +#else + template< typename Type > + static void convertLittleEndian( Type& ) {} + + template< typename Type > + static void convertLittleEndianArray( Type*, size_t ) {} + +#endif + + /** Writes a value to memory, while converting it to little-endian. + @param pDstBuffer The memory buffer to write the value to. + @param nValue The value to be written to memory in little-endian. + */ + template< typename Type > + inline static void writeLittleEndian( void* pDstBuffer, Type nValue ); + +#ifdef OSL_BIGENDIAN +private: + inline static void swap2( sal_uInt8* pnData ); + inline static void swap4( sal_uInt8* pnData ); + inline static void swap8( sal_uInt8* pnData ); +#endif +}; + + +template< typename Type > +inline void ByteOrderConverter::writeLittleEndian( void* pDstBuffer, Type nValue ) +{ + convertLittleEndian( nValue ); + memcpy( pDstBuffer, &nValue, sizeof( Type ) ); +} + +#ifdef OSL_BIGENDIAN +template< typename Type > +inline void ByteOrderConverter::convertLittleEndianArray( Type* pnArray, size_t nElemCount ) +{ + for( Type* pnArrayEnd = pnArray + nElemCount; pnArray != pnArrayEnd; ++pnArray ) + convertLittleEndian( *pnArray ); +} + +inline void ByteOrderConverter::swap2( sal_uInt8* pnData ) +{ + ::std::swap( pnData[ 0 ], pnData[ 1 ] ); +} + +inline void ByteOrderConverter::swap4( sal_uInt8* pnData ) +{ + ::std::swap( pnData[ 0 ], pnData[ 3 ] ); + ::std::swap( pnData[ 1 ], pnData[ 2 ] ); +} + +inline void ByteOrderConverter::swap8( sal_uInt8* pnData ) +{ + ::std::swap( pnData[ 0 ], pnData[ 7 ] ); + ::std::swap( pnData[ 1 ], pnData[ 6 ] ); + ::std::swap( pnData[ 2 ], pnData[ 5 ] ); + ::std::swap( pnData[ 3 ], pnData[ 4 ] ); +} +#endif + + +} // namespace oox + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/oox/helper/modelobjecthelper.hxx b/include/oox/helper/modelobjecthelper.hxx new file mode 100644 index 000000000..dd6100b33 --- /dev/null +++ b/include/oox/helper/modelobjecthelper.hxx @@ -0,0 +1,131 @@ +/* -*- 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_HELPER_MODELOBJECTHELPER_HXX +#define INCLUDED_OOX_HELPER_MODELOBJECTHELPER_HXX + +#include <com/sun/star/uno/Any.hxx> +#include <com/sun/star/uno/Reference.hxx> +#include <oox/dllapi.h> +#include <rtl/ustring.hxx> +#include <sal/types.h> + +namespace com::sun::star { + namespace awt { struct Gradient; + class XBitmap; } + namespace graphic { class XGraphic; } + namespace container { class XNameContainer; } + namespace drawing { struct LineDash; } + namespace drawing { struct Hatch; } + namespace drawing { struct PolyPolygonBezierCoords; } + namespace lang { class XMultiServiceFactory; } +} + +namespace oox { + + +/** This helper manages named objects in a container, which is created on demand. + */ +class OOX_DLLPUBLIC ObjectContainer +{ +public: + explicit ObjectContainer( + const css::uno::Reference< css::lang::XMultiServiceFactory >& rxModelFactory, + const OUString& rServiceName ); + ~ObjectContainer(); + + /** Returns true, if the object with the passed name exists in the container. */ + bool hasObject( const OUString& rObjName ) const; + + css::uno::Any getObject( const OUString& rObjName ) const; + + /** Inserts the passed object into the container, returns its final name. */ + OUString insertObject( + const OUString& rObjName, + const css::uno::Any& rObj, + bool bInsertByUnusedName ); + +private: + void createContainer() const; + +private: + mutable css::uno::Reference< css::lang::XMultiServiceFactory > + mxModelFactory; ///< Factory to create the container. + mutable css::uno::Reference< css::container::XNameContainer > + mxContainer; ///< Container for the objects. + OUString maServiceName; ///< Service name to create the container. + sal_Int32 mnIndex; ///< Index to create unique identifiers. +}; + + +/** Contains tables for named drawing objects for a document model. + + Contains tables for named line markers, line dashes, fill gradients, and + fill bitmap URLs. The class is needed to handle different document models + in the same filter (e.g. embedded charts) which carry their own drawing + object tables. + */ +class OOX_DLLPUBLIC ModelObjectHelper +{ +public: + explicit ModelObjectHelper( + const css::uno::Reference< css::lang::XMultiServiceFactory >& rxModelFactory ); + + /** Returns true, if the model contains a line marker with the passed name. */ + bool hasLineMarker( const OUString& rMarkerName ) const; + + /** Inserts a new named line marker, overwrites an existing line marker + with the same name. Returns true, if the marker could be inserted. */ + bool insertLineMarker( + const OUString& rMarkerName, + const css::drawing::PolyPolygonBezierCoords& rMarker ); + + /** Inserts a new named line dash, returns the line dash name, based on an + internal constant name with a new unused index appended. */ + OUString insertLineDash( const css::drawing::LineDash& rDash ); + + /** Inserts a new named fill gradient, returns the gradient name, based on + an internal constant name with a new unused index appended. */ + OUString insertFillGradient( const css::awt::Gradient& rGradient ); + + OUString insertTransGrandient( const css::awt::Gradient& rGradient ); + + OUString insertFillHatch( const css::drawing::Hatch& rHatch ); + + /** Inserts a new named fill graphic, returns the bitmap name, based on + an internal constant name with a new unused index appended. */ + OUString insertFillBitmapXGraphic(css::uno::Reference<css::graphic::XGraphic> const & rxGraphic); + + css::uno::Reference<css::awt::XBitmap> getFillBitmap(OUString const & rGraphicName); + +private: + ObjectContainer maMarkerContainer; ///< Contains all named line markers (line end polygons). + ObjectContainer maDashContainer; ///< Contains all named line dashes. + ObjectContainer maGradientContainer; ///< Contains all named fill gradients. + ObjectContainer maTransGradContainer; ///< Contains all named transparency Gradients. + ObjectContainer maBitmapUrlContainer; ///< Contains all named fill bitmap URLs. + ObjectContainer maHatchContainer; ///< Contains all named fill hatches. +}; + + +} // namespace oox + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/oox/helper/progressbar.hxx b/include/oox/helper/progressbar.hxx new file mode 100644 index 000000000..e1c5c0a99 --- /dev/null +++ b/include/oox/helper/progressbar.hxx @@ -0,0 +1,132 @@ +/* -*- 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_HELPER_PROGRESSBAR_HXX +#define INCLUDED_OOX_HELPER_PROGRESSBAR_HXX + +#include <memory> + +#include <com/sun/star/uno/Reference.hxx> +#include <oox/dllapi.h> +#include <rtl/ustring.hxx> + +namespace com::sun::star { + namespace task { class XStatusIndicator; } +} + +namespace oox { + +// Interfaces ================================================================= + +/** Interface for progress bar classes. + */ +class OOX_DLLPUBLIC IProgressBar +{ +public: + virtual ~IProgressBar(); + + /** Returns the current position of the progress bar. + + @return Position of the progress bar, in the range from 0.0 (beginning + of the progress bar) to 1.0 (end of the progress bar) inclusive. + */ + virtual double getPosition() const = 0; + + /** Sets the current position of the progress bar. + + @param fPosition New position of the progress bar, in the range from + 0.0 (beginning of the progress bar) to 1.0 (end of the progress bar) + inclusive. + */ + virtual void setPosition( double fPosition ) = 0; +}; + + +class ISegmentProgressBar; +typedef std::shared_ptr< ISegmentProgressBar > ISegmentProgressBarRef; + +/** Interface for a segment in a progress bar, that is able to create sub + segments from itself. + */ +class OOX_DLLPUBLIC ISegmentProgressBar : public IProgressBar +{ +public: + virtual ~ISegmentProgressBar() override; + + /** Returns the length that is still free for creating sub segments. */ + virtual double getFreeLength() const = 0; + + /** Adds a new segment with the specified length. */ + virtual ISegmentProgressBarRef createSegment( double fLength ) = 0; +}; + + +/** A simple progress bar. + */ +class OOX_DLLPUBLIC ProgressBar final : public IProgressBar +{ +public: + explicit ProgressBar( + const css::uno::Reference< css::task::XStatusIndicator >& rxIndicator, + const OUString& rText ); + + virtual ~ProgressBar() override; + + /** Returns the current position of the progress bar. */ + virtual double getPosition() const override; + /** Sets the current position of the progress bar. */ + virtual void setPosition( double fPosition ) override; + +private: + css::uno::Reference< css::task::XStatusIndicator > + mxIndicator; + double mfPosition; +}; + + +/** A progress bar containing several independent segments. + */ +class OOX_DLLPUBLIC SegmentProgressBar final : public ISegmentProgressBar +{ +public: + explicit SegmentProgressBar( + const css::uno::Reference< css::task::XStatusIndicator >& rxIndicator, + const OUString& rText ); + + /** Returns the current position of the progress bar segment. */ + virtual double getPosition() const override; + /** Sets the current position of the progress bar segment. */ + virtual void setPosition( double fPosition ) override; + + /** Returns the length that is still free for creating sub segments. */ + virtual double getFreeLength() const override; + /** Adds a new segment with the specified length. */ + virtual ISegmentProgressBarRef createSegment( double fLength ) override; + +private: + ProgressBar maProgress; + double mfFreeStart; +}; + + +} // namespace oox + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/oox/helper/propertymap.hxx b/include/oox/helper/propertymap.hxx new file mode 100644 index 000000000..423bb11fc --- /dev/null +++ b/include/oox/helper/propertymap.hxx @@ -0,0 +1,130 @@ +/* -*- 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_HELPER_PROPERTYMAP_HXX +#define INCLUDED_OOX_HELPER_PROPERTYMAP_HXX + +#include <map> +#include <utility> +#include <vector> + +#include <com/sun/star/uno/Any.hxx> +#include <com/sun/star/uno/Reference.hxx> +#include <com/sun/star/uno/Sequence.hxx> +#include <oox/dllapi.h> +#include <rtl/ustring.hxx> +#include <sal/types.h> + +namespace com::sun::star::beans { + struct PropertyValue; + class XPropertySet; +} + +namespace oox { + + +typedef ::std::map< OUString, css::uno::Any > PropertyNameMap; + +/** A helper that maps property identifiers to property values. + + The property identifiers are generated on compile time and refer to the + property name strings that are held by a static vector. The identifier to + name mapping is done internally while the properties are written to + property sets. + */ +class OOX_DLLPUBLIC PropertyMap +{ +public: + PropertyMap(); + + /** Returns the name of the passed property identifier. */ + static const OUString& getPropertyName( sal_Int32 nPropId ); + + /** Returns the property identifier of the passed name. */ + static sal_Int32 getPropertyId( std::u16string_view sPropName ); + + /** Returns true, if the map contains a property with the passed identifier. */ + bool hasProperty( sal_Int32 nPropId ) const; + + /** Sets the specified property to the passed value. Does nothing, if the + identifier is invalid. */ + bool setAnyProperty( sal_Int32 nPropId, const css::uno::Any& rValue ); + + /** Sets the specified property to the passed value. Does nothing, if the + identifier is invalid. */ + template< typename Type > + bool setProperty( sal_Int32 nPropId, Type&& rValue ) + { + if( nPropId < 0 ) + return false; + + maProperties[ nPropId ] <<= std::forward<Type>(rValue); + return true; + } + + /** setAnyProperty should be used */ + bool setProperty( sal_Int32, const css::uno::Any& ) = delete; + + css::uno::Any getProperty( sal_Int32 nPropId ); + + void erase( sal_Int32 nPropId ); + + bool empty() const; + + /** Inserts all properties contained in the passed property map. */ + void assignUsed( const PropertyMap& rPropMap ); + + /** Inserts all properties contained in the passed property map */ + void assignAll( const PropertyMap& rPropMap ); + + /** Returns a sequence of property values, filled with all contained properties. */ + css::uno::Sequence< css::beans::PropertyValue > + makePropertyValueSequence() const; + + /** Fills the passed sequences of names and anys with all contained properties. */ + void fillSequences( + css::uno::Sequence< OUString >& rNames, + css::uno::Sequence< css::uno::Any >& rValues ) const; + + void fillPropertyNameMap(PropertyNameMap& rMap) const; + + /** Creates a property set supporting the XPropertySet interface and inserts all properties. */ + css::uno::Reference< css::beans::XPropertySet > + makePropertySet() const; + +#if OSL_DEBUG_LEVEL > 0 +#ifdef DBG_UTIL + static void dump( const css::uno::Reference< css::beans::XPropertySet >& rXPropSet); +#endif + static void dumpCode( const css::uno::Reference< css::beans::XPropertySet >& rXPropSet); + static void dumpData( const css::uno::Reference<css::beans::XPropertySet>& rXPropSet); +#endif +private: + const std::vector<OUString>* mpPropNames; + +protected: + std::map< sal_Int32, css::uno::Any > maProperties; +}; + + +} // namespace oox + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/oox/helper/propertyset.hxx b/include/oox/helper/propertyset.hxx new file mode 100644 index 000000000..676ec4ceb --- /dev/null +++ b/include/oox/helper/propertyset.hxx @@ -0,0 +1,151 @@ +/* -*- 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_HELPER_PROPERTYSET_HXX +#define INCLUDED_OOX_HELPER_PROPERTYSET_HXX + +#include <com/sun/star/uno/Any.hxx> +#include <com/sun/star/uno/Reference.hxx> +#include <com/sun/star/uno/Sequence.hxx> +#include <oox/dllapi.h> +#include <rtl/ustring.hxx> +#include <sal/types.h> +#include <tools/color.hxx> + +namespace com::sun::star { + namespace beans { class XMultiPropertySet; } + namespace beans { class XPropertySet; } + namespace beans { class XPropertySetInfo; } +} + +namespace oox { + +class PropertyMap; + + +/** A wrapper for a UNO property set. + + This class provides functions to silently get and set properties (without + exceptions, without the need to check validity of the UNO property set). + + An instance is constructed with the reference to a UNO property set or any + other interface (the constructor will query for the + com.sun.star.beans.XPropertySet interface then). The reference to the + property set will be kept as long as the instance of this class is alive. + + The functions setProperties() tries to handle all passed values at once, + using the com.sun.star.beans.XMultiPropertySet interface. If the + implementation does not support the XMultiPropertySet interface, all + properties are handled separately in a loop. + */ +class OOX_DLLPUBLIC PropertySet +{ +public: + PropertySet() {} + + /** Constructs a property set wrapper with the passed UNO property set. */ + explicit PropertySet( + const css::uno::Reference< css::beans::XPropertySet >& rxPropSet ) + { set( rxPropSet ); } + + /** Constructs a property set wrapper after querying the XPropertySet interface. */ + template< typename Type > + explicit PropertySet( const Type& rObject ) { set( rObject ); } + + /** Sets the passed UNO property set and releases the old UNO property set. */ + void set( const css::uno::Reference< css::beans::XPropertySet >& rxPropSet ); + + /** Queries the passed object (interface or any) for an XPropertySet and releases the old UNO property set. */ + template< typename Type > + void set( const Type& rObject ) + { set( css::uno::Reference< css::beans::XPropertySet >( rObject, css::uno::UNO_QUERY ) ); } + + /** Returns true, if the contained XPropertySet interface is valid. */ + bool is() const { return mxPropSet.is(); } + + /** Returns true, if the specified property is supported by the property set. */ + bool hasProperty( sal_Int32 nPropId ) const; + + // Get properties --------------------------------------------------------- + + /** Gets the specified property from the property set. + @return the property value, or an empty Any, if the property is missing. */ + css::uno::Any getAnyProperty( sal_Int32 nPropId ) const; + + /** Gets the specified property from the property set. + @return true, if the passed variable could be filled with the property value. */ + template< typename Type > + bool getProperty( Type& orValue, sal_Int32 nPropId ) const + { return getAnyProperty( nPropId ) >>= orValue; } + + /** Gets the specified boolean property from the property set. + @return true = property contains true; false = property contains false or error occurred. */ + bool getBoolProperty( sal_Int32 nPropId ) const + { bool bValue = false; return getProperty( bValue, nPropId ) && bValue; } + // Set properties --------------------------------------------------------- + + /** Puts the passed any into the property set. */ + bool setAnyProperty( sal_Int32 nPropId, const css::uno::Any& rValue ); + + /** Puts the passed value into the property set. */ + template< typename Type > + bool setProperty( sal_Int32 nPropId, const Type& rValue ) + { return setAnyProperty( nPropId, css::uno::Any( rValue ) ); } + bool setProperty( sal_Int32 nPropId, ::Color rValue ) + { return setAnyProperty( nPropId, css::uno::Any( rValue ) ); } + + /** Puts the passed properties into the property set. Tries to use the XMultiPropertySet interface. + @param rPropNames The property names. MUST be ordered alphabetically. + @param rValues The related property values. */ + void setProperties( + const css::uno::Sequence< OUString >& rPropNames, + const css::uno::Sequence< css::uno::Any >& rValues ); + + /** Puts the passed property map into the property set. Tries to use the XMultiPropertySet interface. + @param rPropertyMap The property map. */ + void setProperties( const PropertyMap& rPropertyMap ); + +#ifdef DBG_UTIL + void dump(); +#endif + + +private: + /** Gets the specified property from the property set. + @return true, if the any could be filled with the property value. */ + bool implGetPropertyValue( css::uno::Any& orValue, const OUString& rPropName ) const; + + /** Puts the passed any into the property set. */ + bool implSetPropertyValue( const OUString& rPropName, const css::uno::Any& rValue ); + +private: + css::uno::Reference< css::beans::XPropertySet > + mxPropSet; ///< The mandatory property set interface. + css::uno::Reference< css::beans::XMultiPropertySet > + mxMultiPropSet; ///< The optional multi property set interface. + css::uno::Reference< css::beans::XPropertySetInfo > + mxPropSetInfo; ///< Property information. +}; + + +} // namespace oox + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/oox/helper/refmap.hxx b/include/oox/helper/refmap.hxx new file mode 100644 index 000000000..2e63af512 --- /dev/null +++ b/include/oox/helper/refmap.hxx @@ -0,0 +1,144 @@ +/* -*- 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_HELPER_REFMAP_HXX +#define INCLUDED_OOX_HELPER_REFMAP_HXX + +#include <algorithm> +#include <functional> +#include <map> +#include <memory> + +namespace oox { + + +/** Template for a map of ref-counted objects with additional accessor functions. + + An instance of the class RefMap< Type > stores elements of the type + std::shared_ptr< Type >. The new accessor functions has() and get() + work correctly for nonexisting keys, there is no need to check the passed + key before. + */ +template< typename KeyType, typename ObjType, typename CompType = std::less< KeyType > > +class RefMap : public std::map< KeyType, std::shared_ptr< ObjType >, CompType > +{ +public: + typedef std::map< KeyType, std::shared_ptr< ObjType >, CompType > container_type; + typedef typename container_type::key_type key_type; + typedef typename container_type::mapped_type mapped_type; + typedef typename container_type::value_type value_type; + typedef typename container_type::key_compare key_compare; + +public: + /** Returns true, if the object associated to the passed key exists. + Returns false, if the key exists but points to an empty reference. */ + bool has( key_type nKey ) const + { + const mapped_type* pxRef = getRef( nKey ); + return pxRef && pxRef->get(); + } + + /** Returns a reference to the object associated to the passed key, or an + empty reference on error. */ + mapped_type get( key_type nKey ) const + { + if( const mapped_type* pxRef = getRef( nKey ) ) return *pxRef; + return mapped_type(); + } + + /** Calls the passed functor for every contained object, automatically + skips all elements that are empty references. */ + template< typename FunctorType > + void forEach( const FunctorType& rFunctor ) const + { + std::for_each( this->begin(), this->end(), ForEachFunctor< FunctorType >( rFunctor ) ); + } + + /** Calls the passed member function of ObjType on every contained object, + automatically skips all elements that are empty references. */ + template< typename FuncType > + void forEachMem( FuncType pFunc ) const + { + forEach( ::std::bind( pFunc, std::placeholders::_1 ) ); + } + + /** Calls the passed member function of ObjType on every contained object, + automatically skips all elements that are empty references. */ + template< typename FuncType, typename ParamType1, typename ParamType2 > + void forEachMem( FuncType pFunc, ParamType1 aParam1, ParamType2 aParam2 ) const + { + forEach( ::std::bind( pFunc, std::placeholders::_1, aParam1, aParam2 ) ); + } + + /** Calls the passed member function of ObjType on every contained object, + automatically skips all elements that are empty references. */ + template< typename FuncType, typename ParamType1, typename ParamType2, typename ParamType3 > + void forEachMem( FuncType pFunc, ParamType1 aParam1, ParamType2 aParam2, ParamType3 aParam3 ) const + { + forEach( ::std::bind( pFunc, std::placeholders::_1, aParam1, aParam2, aParam3 ) ); + } + + + /** Calls the passed functor for every contained object. Passes the key as + first argument and the object reference as second argument to rFunctor. */ + template< typename FunctorType > + void forEachWithKey( const FunctorType& rFunctor ) const + { + std::for_each( this->begin(), this->end(), ForEachFunctorWithKey< FunctorType >( rFunctor ) ); + } + + /** Calls the passed member function of ObjType on every contained object. + Passes the object key as argument to the member function. */ + template< typename FuncType > + void forEachMemWithKey( FuncType pFunc ) const + { + forEachWithKey( ::std::bind( pFunc, std::placeholders::_2, std::placeholders::_1 ) ); + } + + +private: + template< typename FunctorType > + struct ForEachFunctor + { + FunctorType maFunctor; + explicit ForEachFunctor( const FunctorType& rFunctor ) : maFunctor( rFunctor ) {} + void operator()( const value_type& rValue ) { if( rValue.second.get() ) maFunctor( *rValue.second ); } + }; + + template< typename FunctorType > + struct ForEachFunctorWithKey + { + FunctorType maFunctor; + explicit ForEachFunctorWithKey( const FunctorType& rFunctor ) : maFunctor( rFunctor ) {} + void operator()( const value_type& rValue ) { if( rValue.second.get() ) maFunctor( rValue.first, *rValue.second ); } + }; + + const mapped_type* getRef( key_type nKey ) const + { + typename container_type::const_iterator aIt = this->find( nKey ); + return (aIt == this->end()) ? nullptr : &aIt->second; + } +}; + + +} // namespace oox + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/oox/helper/refvector.hxx b/include/oox/helper/refvector.hxx new file mode 100644 index 000000000..018940836 --- /dev/null +++ b/include/oox/helper/refvector.hxx @@ -0,0 +1,163 @@ +/* -*- 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_HELPER_REFVECTOR_HXX +#define INCLUDED_OOX_HELPER_REFVECTOR_HXX + +#include <algorithm> +#include <functional> +#include <memory> +#include <vector> + +#include <sal/types.h> + +namespace oox { + + +/** Template for a vector of ref-counted objects with additional accessor functions. + + An instance of the class RefVector< Type > stores elements of the type + std::shared_ptr< Type >. The new accessor functions has() and get() + work correctly for indexes out of the current range, there is no need to + check the passed index before. + */ +template< typename ObjType > +class RefVector : public ::std::vector< std::shared_ptr< ObjType > > +{ +public: + typedef ::std::vector< std::shared_ptr< ObjType > > container_type; + typedef typename container_type::value_type value_type; + typedef typename container_type::size_type size_type; + +public: + + /** Returns a reference to the object with the passed index, or 0 on error. */ + value_type get( sal_Int32 nIndex ) const + { + if( const value_type* pxRef = getRef( nIndex ) ) return *pxRef; + return value_type(); + } + + /** Calls the passed functor for every contained object, automatically + skips all elements that are empty references. */ + template< typename FunctorType > + void forEach( FunctorType aFunctor ) const + { + ::std::for_each( this->begin(), this->end(), ForEachFunctor< FunctorType >( aFunctor ) ); + } + + /** Calls the passed member function of ObjType on every contained object, + automatically skips all elements that are empty references. */ + template< typename FuncType > + void forEachMem( FuncType pFunc ) const + { + forEach( ::std::bind( pFunc, std::placeholders::_1 ) ); + } + + /** Calls the passed member function of ObjType on every contained object, + automatically skips all elements that are empty references. */ + template< typename FuncType, typename ParamType > + void forEachMem( FuncType pFunc, ParamType aParam ) const + { + forEach( ::std::bind( pFunc, std::placeholders::_1, aParam ) ); + } + + /** Calls the passed member function of ObjType on every contained object, + automatically skips all elements that are empty references. */ + template< typename FuncType, typename ParamType1, typename ParamType2 > + void forEachMem( FuncType pFunc, ParamType1 aParam1, ParamType2 aParam2 ) const + { + forEach( ::std::bind( pFunc, std::placeholders::_1, aParam1, aParam2 ) ); + } + + /** Calls the passed member function of ObjType on every contained object, + automatically skips all elements that are empty references. */ + template< typename FuncType, typename ParamType1, typename ParamType2, typename ParamType3 > + void forEachMem( FuncType pFunc, ParamType1 aParam1, ParamType2 aParam2, ParamType3 aParam3 ) const + { + forEach( ::std::bind( pFunc, std::placeholders::_1, aParam1, aParam2, aParam3 ) ); + } + + /** Calls the passed functor for every contained object. Passes the index as + first argument and the object reference as second argument to rFunctor. */ + template< typename FunctorType > + void forEachWithIndex( const FunctorType& rFunctor ) const + { + ::std::for_each( this->begin(), this->end(), ForEachFunctorWithIndex< FunctorType >( rFunctor ) ); + } + + /** Calls the passed member function of ObjType on every contained object. + Passes the vector index as first argument to the member function. */ + template< typename FuncType, typename ParamType1, typename ParamType2 > + void forEachMemWithIndex( FuncType pFunc, ParamType1 aParam1, ParamType2 aParam2 ) const + { + forEachWithIndex( ::std::bind( pFunc, std::placeholders::_2, std::placeholders::_1, aParam1, aParam2 ) ); + } + + /** Searches for an element by using the passed functor that takes a + constant reference of the object type (const ObjType&). */ + template< typename FunctorType > + value_type findIf( const FunctorType& rFunctor ) const + { + typename container_type::const_iterator aIt = ::std::find_if( this->begin(), this->end(), FindFunctor< FunctorType >( rFunctor ) ); + return (aIt == this->end()) ? value_type() : *aIt; + } + +private: + template< typename FunctorType > + struct ForEachFunctor + { + FunctorType maFunctor; + explicit ForEachFunctor( const FunctorType& rFunctor ) : maFunctor( rFunctor ) {} + void operator()( const value_type& rxValue ) { if( rxValue.get() ) maFunctor( *rxValue ); } + }; + + template< typename FunctorType > + struct ForEachFunctorWithIndex + { + FunctorType maFunctor; + sal_Int32 mnIndex; + explicit ForEachFunctorWithIndex( const FunctorType& rFunctor ) : maFunctor( rFunctor ), mnIndex( 0 ) {} + void operator()( const value_type& rxValue ) { + if( rxValue.get() ) maFunctor( mnIndex, *rxValue ); + ++mnIndex; + } + }; + + template< typename FunctorType > + struct FindFunctor + { + FunctorType maFunctor; + explicit FindFunctor( const FunctorType& rFunctor ) : maFunctor( rFunctor ) {} + bool operator()( const value_type& rxValue ) { return rxValue.get() && maFunctor( *rxValue ); } + }; + + const value_type* getRef( sal_Int32 nIndex ) const + { + return ((0 <= nIndex) && (static_cast< size_type >( nIndex ) < this->size())) ? + &(*this)[ static_cast< size_type >( nIndex ) ] : nullptr; + } +}; + + +} // namespace oox + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/oox/helper/storagebase.hxx b/include/oox/helper/storagebase.hxx new file mode 100644 index 000000000..2722ed80b --- /dev/null +++ b/include/oox/helper/storagebase.hxx @@ -0,0 +1,192 @@ +/* -*- 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_HELPER_STORAGEBASE_HXX +#define INCLUDED_OOX_HELPER_STORAGEBASE_HXX + +#include <functional> +#include <memory> +#include <vector> + +#include <com/sun/star/uno/Reference.hxx> +#include <oox/dllapi.h> +#include <oox/helper/refmap.hxx> +#include <rtl/ustring.hxx> + +namespace com::sun::star { + namespace embed { class XStorage; } + namespace io { class XInputStream; } + namespace io { class XOutputStream; } + namespace io { class XStream; } +} + +namespace oox { + + +class StorageBase; +typedef std::shared_ptr< StorageBase > StorageRef; + +/** Base class for storage access implementations. + + Derived classes will be used to encapsulate storage access implementations + for ZIP storages containing XML streams, and OLE storages containing binary + data streams. + */ +class OOX_DLLPUBLIC StorageBase +{ +public: + explicit StorageBase( + const css::uno::Reference< css::io::XInputStream >& rxInStream, + bool bBaseStreamAccess ); + + explicit StorageBase( + const css::uno::Reference< css::io::XStream >& rxOutStream, + bool bBaseStreamAccess ); + + virtual ~StorageBase(); + + /** Returns true, if the object represents a valid storage. */ + bool isStorage() const; + + /** Returns true, if the object represents the root storage. */ + bool isRootStorage() const; + + /** Returns true, if the storage operates in read-only mode (based on an + input stream). */ + bool isReadOnly() const { return mbReadOnly;} + + /** Returns the com.sun.star.embed.XStorage interface of the current storage. */ + css::uno::Reference< css::embed::XStorage > + getXStorage() const; + + /** Returns the element name of this storage. */ + const OUString& getName() const { return maStorageName;} + + /** Returns the full path of this storage. */ + OUString getPath() const; + + /** Fills the passed vector with the names of all direct elements of this + storage. */ + void getElementNames( ::std::vector< OUString >& orElementNames ) const; + + /** Opens and returns the specified sub storage from the storage. + + @param rStorageName + The name of the embedded storage. The name may contain slashes to + open storages from embedded substorages. + @param bCreateMissing + True = create missing sub storages (for export filters). Must be + false for storages based on input streams. + */ + StorageRef openSubStorage( const OUString& rStorageName, bool bCreateMissing ); + + /** Opens and returns the specified input stream from the storage. + + @param rStreamName + The name of the embedded storage stream. The name may contain + slashes to open streams from embedded substorages. If base stream + access has been enabled in the constructor, the base stream can be + accessed by passing an empty string as stream name. + */ + css::uno::Reference< css::io::XInputStream > + openInputStream( const OUString& rStreamName ); + + /** Opens and returns the specified output stream from the storage. + + @param rStreamName + The name of the embedded storage stream. The name may contain + slashes to create and open streams in embedded substorages. If base + stream access has been enabled in the constructor, the base stream + can be accessed by passing an empty string as stream name. + */ + css::uno::Reference< css::io::XOutputStream > + openOutputStream( const OUString& rStreamName ); + + /** Copies the specified element from this storage to the passed + destination storage. + + @param rElementName + The name of the embedded storage or stream. The name may contain + slashes to specify an element in an embedded substorage. In this + case, the element will be copied to the same substorage in the + destination storage. + */ + void copyToStorage( StorageBase& rDestStrg, const OUString& rElementName ); + + /** Copies all streams of this storage and of all substorages to the passed + destination. */ + void copyStorageToStorage( StorageBase& rDestStrg ); + + /** Commits the changes to the storage and all substorages. */ + void commit(); + +protected: + /** Special constructor for sub storage objects. */ + explicit StorageBase( const StorageBase& rParentStorage, const OUString& rStorageName, bool bReadOnly ); + +private: + StorageBase( const StorageBase& ) = delete; + StorageBase& operator=( const StorageBase& ) = delete; + + /** Returns true, if the object represents a valid storage. */ + virtual bool implIsStorage() const = 0; + + /** Returns the com.sun.star.embed.XStorage interface of the current storage. */ + virtual css::uno::Reference< css::embed::XStorage > + implGetXStorage() const = 0; + + /** Returns the names of all elements of this storage. */ + virtual void implGetElementNames( ::std::vector< OUString >& orElementNames ) const = 0; + + /** Implementation of opening a storage element. */ + virtual StorageRef implOpenSubStorage( const OUString& rElementName, bool bCreate ) = 0; + + /** Implementation of opening an input stream element. */ + virtual css::uno::Reference< css::io::XInputStream > + implOpenInputStream( const OUString& rElementName ) = 0; + + /** Implementation of opening an output stream element. */ + virtual css::uno::Reference< css::io::XOutputStream > + implOpenOutputStream( const OUString& rElementName ) = 0; + + /** Commits the current storage. */ + virtual void implCommit() const = 0; + + /** Helper that opens and caches the specified direct substorage. */ + StorageRef getSubStorage( const OUString& rElementName, bool bCreateMissing ); + +private: + RefMap< OUString, StorageBase > + maSubStorages; ///< Map of direct sub storages. + css::uno::Reference< css::io::XInputStream > + mxInStream; ///< Cached base input stream (to keep it alive). + css::uno::Reference< css::io::XStream > + mxOutStream; ///< Cached base output stream (to keep it alive). + OUString maParentPath; ///< Full path of parent storage. + OUString maStorageName; ///< Name of this storage, if it is a substorage. + bool mbBaseStreamAccess; ///< True = access base streams with empty stream name. + bool mbReadOnly; ///< True = storage opened read-only (based on input stream). +}; + + +} // namespace oox + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/oox/helper/textinputstream.hxx b/include/oox/helper/textinputstream.hxx new file mode 100644 index 000000000..4a5bcdbfe --- /dev/null +++ b/include/oox/helper/textinputstream.hxx @@ -0,0 +1,121 @@ +/* -*- 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_HELPER_TEXTINPUTSTREAM_HXX +#define INCLUDED_OOX_HELPER_TEXTINPUTSTREAM_HXX + +#include <com/sun/star/uno/Reference.hxx> +#include <rtl/textenc.h> +#include <rtl/ustring.hxx> +#include <sal/types.h> + +namespace com::sun::star { + namespace io { class XInputStream; } + namespace io { class XTextInputStream2; } + namespace uno { class XComponentContext; } +} + +namespace oox { + +class BinaryInputStream; + + +class TextInputStream +{ +public: + explicit TextInputStream( + const css::uno::Reference< css::uno::XComponentContext >& rxContext, + const css::uno::Reference< css::io::XInputStream >& rxInStrm, + rtl_TextEncoding eTextEnc ); + + explicit TextInputStream( + const css::uno::Reference< css::uno::XComponentContext >& rxContext, + BinaryInputStream& rInStrm, + rtl_TextEncoding eTextEnc ); + + ~TextInputStream(); + + /** Returns true, if no more text is available in the stream. + */ + bool isEof() const; + + /** Reads a text line from the stream. + + If the last line in the stream is not terminated with line-end + character(s), the stream will immediately go into EOF state and return + the text line. Otherwise, if the last character in the stream is a + line-end character, the next call to this function will turn the stream + into EOF state and return an empty string. + */ + OUString readLine(); + + /** Reads a text portion from the stream until the specified character is + found. + + If the end of the stream is not terminated with the specified + character, the stream will immediately go into EOF state and return the + remaining text portion. Otherwise, if the last character in the stream + is the specified character (and caller specifies to read and return it, + see parameter bIncludeChar), the next call to this function will turn + the stream into EOF state and return an empty string. + + @param cChar + The separator character to be read to. + + @param bIncludeChar + True = if found, the specified character will be read from stream + and included in the returned string. + False = the specified character will neither be read from the + stream nor included in the returned string, but will be + returned as first character in the next call of this function + or readLine(). + */ + OUString readToChar( sal_Unicode cChar, bool bIncludeChar ); + + + /** Creates a UNO text input stream object from the passed UNO input stream. + */ + static css::uno::Reference< css::io::XTextInputStream2 > + createXTextInputStream( + const css::uno::Reference< css::uno::XComponentContext >& rxContext, + const css::uno::Reference< css::io::XInputStream >& rxInStrm, + rtl_TextEncoding eTextEnc ); + + +private: + void init( + const css::uno::Reference< css::uno::XComponentContext >& rxContext, + const css::uno::Reference< css::io::XInputStream >& rxInStrm, + rtl_TextEncoding eTextEnc ); + + /** Adds the pending character in front of the passed string, if existing. */ + OUString createFinalString( const OUString& rString ); + +private: + css::uno::Reference< css::io::XTextInputStream2 > + mxTextStrm; + sal_Unicode mcPendingChar; +}; + + +} // namespace oox + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/oox/helper/zipstorage.hxx b/include/oox/helper/zipstorage.hxx new file mode 100644 index 000000000..dec4b483e --- /dev/null +++ b/include/oox/helper/zipstorage.hxx @@ -0,0 +1,94 @@ +/* -*- 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_HELPER_ZIPSTORAGE_HXX +#define INCLUDED_OOX_HELPER_ZIPSTORAGE_HXX + +#include <vector> + +#include <com/sun/star/uno/Reference.hxx> +#include <oox/helper/storagebase.hxx> +#include <rtl/ustring.hxx> + +namespace com::sun::star { + namespace embed { class XStorage; } + namespace io { class XInputStream; } + namespace io { class XOutputStream; } + namespace io { class XStream; } + namespace uno { class XComponentContext; } +} + +namespace oox { + + +/** Implements stream access for ZIP storages containing XML streams. */ +class ZipStorage final : public StorageBase +{ +public: + explicit ZipStorage( + const css::uno::Reference< css::uno::XComponentContext >& rxContext, + const css::uno::Reference< css::io::XInputStream >& rxInStream ); + + explicit ZipStorage( + const css::uno::Reference< css::uno::XComponentContext >& rxContext, + const css::uno::Reference< css::io::XStream >& rxStream ); + + virtual ~ZipStorage() override; + +private: + explicit ZipStorage( + const ZipStorage& rParentStorage, + const css::uno::Reference< css::embed::XStorage >& rxStorage, + const OUString& rElementName ); + + /** Returns true, if the object represents a valid storage. */ + virtual bool implIsStorage() const override; + + /** Returns the com.sun.star.embed.XStorage interface of the current storage. */ + virtual css::uno::Reference< css::embed::XStorage > + implGetXStorage() const override; + + /** Returns the names of all elements of this storage. */ + virtual void implGetElementNames( ::std::vector< OUString >& orElementNames ) const override; + + /** Opens and returns the specified sub storage from the storage. */ + virtual StorageRef implOpenSubStorage( const OUString& rElementName, bool bCreateMissing ) override; + + /** Opens and returns the specified input stream from the storage. */ + virtual css::uno::Reference< css::io::XInputStream > + implOpenInputStream( const OUString& rElementName ) override; + + /** Opens and returns the specified output stream from the storage. */ + virtual css::uno::Reference< css::io::XOutputStream > + implOpenOutputStream( const OUString& rElementName ) override; + + /** Commits the current storage. */ + virtual void implCommit() const override; + +private: + css::uno::Reference< css::embed::XStorage > + mxStorage; ///< Storage based on input or output stream. +}; + + +} // namespace oox + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |