Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / include / oox / core / contexthandler2.hxx
blob1414db7f242dc0d4f502e326faadaaf4d758be79
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #ifndef INCLUDED_OOX_CORE_CONTEXTHANDLER2_HXX
21 #define INCLUDED_OOX_CORE_CONTEXTHANDLER2_HXX
23 #include <cstddef>
24 #include <memory>
25 #include <vector>
27 #include <com/sun/star/uno/Reference.hxx>
28 #include <oox/core/contexthandler.hxx>
29 #include <oox/dllapi.h>
30 #include <rtl/ustring.hxx>
31 #include <sal/types.h>
33 namespace com::sun::star {
34 namespace xml::sax { class XFastAttributeList; }
35 namespace xml::sax { class XFastContextHandler; }
38 namespace oox {
39 class AttributeList;
40 class SequenceInputStream;
43 namespace oox::core {
45 const sal_Int32 XML_ROOT_CONTEXT = SAL_MAX_INT32;
47 struct ElementInfo;
49 /** Helper class that provides a context stack.
51 Fragment handlers and context handlers derived from this helper class will
52 track the identifiers of the visited elements in a stack. The idea is to
53 use the same instance of a fragment handler or context handler to process
54 several nested elements in an XML stream. For that, the abstract function
55 onCreateContext() has to return 'this' for the passed element.
57 Derived classes have to implement the createFastChildContext(),
58 startFastElement(), characters(), and endFastElement() functions from the
59 com.sun.star.xml.sax.XFastContextHandler interface by simply forwarding
60 them to the respective implCreateChildContext(), implStartElement(),
61 implCharacters(), and implEndElement() functions of this helper. This is
62 implemented already in the classes ContextHandler2 and FragmentHandler2.
63 The new abstract functions have to be implemented according to the elements
64 to be processed.
66 Similarly, for binary import, derived classes have to forward the
67 createRecordContext(), startRecord(), and endRecord() functions from the
68 ContextHandler class to the implCreateRecordContext(), implStartRecord(),
69 and implEndRecord() functions of this helper. Again, this is implemented
70 already in the classes ContextHandler2 and FragmentHandler2.
72 class OOX_DLLPUBLIC SAL_LOPLUGIN_ANNOTATE("crosscast") ContextHandler2Helper
74 public:
75 explicit ContextHandler2Helper( bool bEnableTrimSpace, XmlFilterBase& rFilter );
76 explicit ContextHandler2Helper( const ContextHandler2Helper& rParent );
77 virtual ~ContextHandler2Helper();
79 // allow instances to be stored in ::rtl::Reference
80 virtual void SAL_CALL acquire() noexcept = 0;
81 virtual void SAL_CALL release() noexcept = 0;
83 // interface --------------------------------------------------------------
85 /** Will be called to create a context handler for the passed element.
87 Usually 'this' can be returned to improve performance by reusing the
88 same instance to process several elements. Used by OOXML import only.
90 virtual ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs ) = 0;
92 /** Will be called when a new element has been started.
94 This function is called at the context handler returned from
95 onCreateContext(), or, for root elements of an XML stream, at the
96 fragment handler itself.
98 The current element identifier can be accessed with getCurrentElement()
99 or isCurrentElement(). Used by OOXML import only.
101 virtual void onStartElement( const AttributeList& rAttribs ) = 0;
103 /** Will be called before a new child element starts, or if the current
104 element is about to be left.
106 This helper function collects all text fragments received by the
107 characters() function (such as encoded characters which are passed in
108 separate calls to the characters() function), and passes the
109 concatenated and trimmed string.
111 The current element identifier can be accessed with getCurrentElement()
112 or isCurrentElement(). Used by OOXML import only.
114 virtual void onCharacters( const OUString& rChars ) = 0;
116 /** Will be called when the current element is about to be left.
118 The current element identifier can be accessed with getCurrentElement()
119 or isCurrentElement(). Used by OOXML import only.
121 virtual void onEndElement() = 0;
123 /** Will be called to create a context handler for the passed record.
125 Usually 'this' can be returned to improve performance by reusing the
126 same instance to process several records. Used by BIFF import only.
128 virtual ContextHandlerRef onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm ) = 0;
130 /** Will be called when a new record block in a binary stream has been
131 started.
133 The current record identifier can be accessed with getCurrentElement()
134 or isCurrentElement(). Used by BIFF import only.
136 virtual void onStartRecord( SequenceInputStream& rStrm ) = 0;
138 /** Will be called when the current record block is about to be left.
140 The current record identifier can be accessed with getCurrentElement()
141 or isCurrentElement(). Used by BIFF import only.
143 virtual void onEndRecord() = 0;
145 // helpers ----------------------------------------------------------------
147 /** Returns the identifier of the currently processed element. Ignores MCE elements in stack */
148 sal_Int32 getCurrentElement() const;
150 /** Returns the identifier of the currently processed element - Including MCE root elements */
151 sal_Int32 getCurrentElementWithMce() const;
153 /** Returns true, if nElement contains the identifier of the currently
154 processed element. */
155 bool isCurrentElement( sal_Int32 nElement ) const
156 { return getCurrentElement() == nElement; }
158 /** Returns true, if either nElement1 or nElement2 contain the identifier
159 of the currently processed element. */
160 bool isCurrentElement( sal_Int32 nElement1, sal_Int32 nElement2 ) const
161 { return isCurrentElement( nElement1 ) || isCurrentElement( nElement2 ); }
163 /** Returns the identifier of the specified parent element. */
164 sal_Int32 getParentElement( sal_Int32 nCountBack = 1 ) const;
166 /** Returns true, if nElement contains the identifier of the specified
167 parent element. */
168 bool isParentElement( sal_Int32 nElement, sal_Int32 nCountBack = 1 ) const
169 { return getParentElement( nCountBack ) == nElement; }
171 /** Returns true, if the element currently processed is the root element of
172 the context or fragment handler. */
173 bool isRootElement() const;
175 // implementation ---------------------------------------------------------
177 protected:
178 /** Must be called from createFastChildContext() in derived classes. */
179 css::uno::Reference< css::xml::sax::XFastContextHandler >
180 implCreateChildContext(
181 sal_Int32 nElement,
182 const css::uno::Reference< css::xml::sax::XFastAttributeList >& rxAttribs );
184 /** Must be called from startFastElement() in derived classes. */
185 void implStartElement(
186 sal_Int32 nElement,
187 const css::uno::Reference< css::xml::sax::XFastAttributeList >& rxAttribs );
189 /** Must be called from characters() in derived classes. */
190 void implCharacters( std::u16string_view rChars );
192 /** Must be called from endFastElement() in derived classes. */
193 void implEndElement( sal_Int32 nElement );
195 /** Must be called from createRecordContext() in derived classes. */
196 ContextHandlerRef implCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm );
198 /** Must be called from startRecord() in derived classes. */
199 void implStartRecord( sal_Int32 nRecId, SequenceInputStream& rStrm );
201 /** Must be called from endRecord() in derived classes. */
202 void implEndRecord( sal_Int32 nRecId );
204 bool prepareMceContext( sal_Int32 nElement, const AttributeList& rAttribs );
205 XmlFilterBase& getDocFilter() const { return mrFilter; }
207 enum class MCE_STATE
209 Started,
210 FoundChoice
213 MCE_STATE getMCEState() const { return aMceState.back(); }
214 void setMCEState( MCE_STATE aState ) { aMceState.back() = aState; }
215 void addMCEState( MCE_STATE aState ) { aMceState.push_back( aState ); }
216 void removeMCEState() { aMceState.pop_back(); }
217 bool isMCEStateEmpty() const { return aMceState.empty(); }
219 private:
220 ContextHandler2Helper& operator=( const ContextHandler2Helper& ) = delete;
222 ElementInfo& pushElementInfo( sal_Int32 nElement );
223 void popElementInfo();
224 void processCollectedChars();
226 private:
227 typedef std::vector< ElementInfo > ContextStack;
228 typedef std::shared_ptr< ContextStack > ContextStackRef;
230 ContextStackRef mxContextStack; ///< Stack of all processed elements.
231 size_t mnRootStackSize; ///< Stack size on construction time.
232 std::vector<MCE_STATE> aMceState;
234 protected:
235 bool mbEnableTrimSpace; ///< True = trim whitespace in characters().
236 XmlFilterBase& mrFilter;
239 class OOX_DLLPUBLIC ContextHandler2 : public ContextHandler, public ContextHandler2Helper
241 public:
242 explicit ContextHandler2( ContextHandler2Helper const & rParent );
243 virtual ~ContextHandler2() override;
245 ContextHandler2(ContextHandler2 const &) = default;
246 ContextHandler2(ContextHandler2 &&) = default;
247 ContextHandler2 & operator =(ContextHandler2 const &) = delete; // due to ContextHandler
248 ContextHandler2 & operator =(ContextHandler2 &&) = delete; // due to ContextHandler
250 // resolve ambiguity from base classes
251 virtual void SAL_CALL acquire() noexcept override { ContextHandler::acquire(); }
252 virtual void SAL_CALL release() noexcept override { ContextHandler::release(); }
254 // com.sun.star.xml.sax.XFastContextHandler interface ---------------------
256 virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL
257 createFastChildContext(
258 sal_Int32 nElement,
259 const css::uno::Reference< css::xml::sax::XFastAttributeList >& rxAttribs ) final override;
261 virtual void SAL_CALL startFastElement(
262 sal_Int32 nElement,
263 const css::uno::Reference< css::xml::sax::XFastAttributeList >& rxAttribs ) final override;
265 virtual void SAL_CALL characters( const OUString& rChars ) final override;
267 virtual void SAL_CALL endFastElement( sal_Int32 nElement ) final override;
269 // oox.core.ContextHandler interface --------------------------------------
271 virtual ContextHandlerRef createRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm ) override;
272 virtual void startRecord( sal_Int32 nRecId, SequenceInputStream& rStrm ) override;
273 virtual void endRecord( sal_Int32 nRecId ) override;
275 // oox.core.ContextHandler2Helper interface -------------------------------
277 virtual ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs ) override;
278 virtual void onStartElement( const AttributeList& rAttribs ) override;
279 virtual void onCharacters( const OUString& rChars ) override;
280 virtual void onEndElement() override;
282 virtual ContextHandlerRef onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm ) override;
283 virtual void onStartRecord( SequenceInputStream& rStrm ) override;
284 virtual void onEndRecord() override;
287 } // namespace oox::core
289 #endif
291 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */