LibreOffice Module sax (master) 1
fastserializer.hxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#ifndef INCLUDED_SAX_SOURCE_TOOLS_FASTSERIALIZER_HXX
21#define INCLUDED_SAX_SOURCE_TOOLS_FASTSERIALIZER_HXX
22
23#include <com/sun/star/xml/sax/XFastTokenHandler.hpp>
24#include <com/sun/star/io/XOutputStream.hpp>
25
26#include <sax/fastattribs.hxx>
27#include <sax/fshelper.hxx>
29
30#include <stack>
31#include <string_view>
32#include <map>
33#include <memory>
34
35namespace sax_fastparser {
36
38{
39 sal_Int32 nToken;
40 const char *pValue;
41 TokenValue(sal_Int32 _nToken, const char *_pValue) : nToken(_nToken), pValue(_pValue) {}
42};
43typedef std::vector<TokenValue> TokenValueList;
44
47{
48 typedef css::uno::Sequence< ::sal_Int8 > Int8Sequence;
49 typedef css::uno::Sequence< ::sal_Int32 > Int32Sequence;
50
51public:
52 explicit FastSaxSerializer(const css::uno::Reference< css::io::XOutputStream >& xOutputStream);
54
55 css::uno::Reference< css::io::XOutputStream > const & getOutputStream() const;
58
61 void startDocument();
62
65 void endDocument();
66
84 void startFastElement( ::sal_Int32 Element, FastAttributeList const * pAttrList = nullptr );
85
89 void endFastElement( ::sal_Int32 Element );
90
108 void singleFastElement( ::sal_Int32 Element, FastAttributeList const * pAttrList = nullptr );
109
110 // C++ helpers
111 void writeId( ::sal_Int32 Element );
112 OString getId( ::sal_Int32 Element );
113
114 void write( double value );
115 void write( std::u16string_view s, bool bEscape = false );
116 void write( std::string_view s, bool bEscape = false );
117 void write( const char* pStr, sal_Int32 nLen, bool bEscape = false );
118
119 // strings with _xHHHH_ are escaped with _x005F unless this is disabled
120 void setAllowXEscape(bool bSet) { mbXescape = bSet; }
121
122public:
137 void mark(sal_Int32 nTag, const Int32Sequence& rOrder);
138
156 void mergeTopMarks(sal_Int32 nTag,
157 sax_fastparser::MergeMarks eMergeType);
158
159private:
165 css::uno::Reference< css::xml::sax::XFastTokenHandler > mxFastTokenHandler;
166
167 class ForMerge : public ForMergeBase
168 {
171
172 public:
173 sal_Int32 const m_Tag;
174#ifdef DBG_UTIL
175 // pending close tags, followed by pending open tags
176 std::deque<sal_Int32> m_DebugEndedElements;
177 std::deque<sal_Int32> m_DebugStartedElements;
178 // ... and another buffer for maPostponed ...
179 std::deque<sal_Int32> m_DebugPostponedEndedElements;
180 std::deque<sal_Int32> m_DebugPostponedStartedElements;
181#endif
182
183 explicit ForMerge(sal_Int32 const nTag) : m_Tag(nTag) {}
184
185 virtual void setCurrentElement( ::sal_Int32 /*nToken*/ ) {}
186 virtual Int8Sequence& getData();
187#if OSL_DEBUG_LEVEL > 0
188 virtual void print();
189#endif
190
191 virtual void prepend( const Int8Sequence &rWhat );
192 virtual void append( const css::uno::Sequence<sal_Int8> &rWhat ) override;
193 void postpone( const Int8Sequence &rWhat );
194
195 protected:
196 void resetData( );
197 static void merge( Int8Sequence &rTop, const Int8Sequence &rMerge, bool bAppend );
198 };
199
200 class ForSort : public ForMerge
201 {
202 std::map< ::sal_Int32, Int8Sequence > maData;
204
206
207 public:
208 ForSort(sal_Int32 const nTag, const Int32Sequence& rOrder)
209 : ForMerge(nTag)
210 , mnCurrentElement( 0 )
211 , maOrder( rOrder )
212 {}
213
214 void setCurrentElement( ::sal_Int32 nToken ) override;
215
216 virtual Int8Sequence& getData() override;
217
218#if OSL_DEBUG_LEVEL > 0
219 virtual void print() override;
220#endif
221
222 virtual void prepend( const Int8Sequence &rWhat ) override;
223 virtual void append( const css::uno::Sequence<sal_Int8> &rWhat ) override;
224 private:
225 void sort();
226 };
227
228 std::stack< std::shared_ptr< ForMerge > > maMarkStack;
230 // Would be better to use OStringBuffer instead of these two
231 // but then we couldn't get the rtl_String* member :-(
232 rtl_String *mpDoubleStr;
236
237
238#ifdef DBG_UTIL
239 std::stack<sal_Int32> m_DebugStartedElements;
240#endif
241
242 void writeTokenValueList();
243 void writeFastAttributeList(FastAttributeList const & rAttrList);
244
249 void writeBytes( const css::uno::Sequence< ::sal_Int8 >& aData );
250 void writeBytes( const char* pStr, size_t nLen );
251};
252
253} // namespace sax_fastparser
254
255#endif
256
257/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual void append(const css::uno::Sequence< sal_Int8 > &rWhat) override
void postpone(const Int8Sequence &rWhat)
std::deque< sal_Int32 > m_DebugPostponedEndedElements
virtual void prepend(const Int8Sequence &rWhat)
static void merge(Int8Sequence &rTop, const Int8Sequence &rMerge, bool bAppend)
std::deque< sal_Int32 > m_DebugPostponedStartedElements
virtual Int8Sequence & getData() override
virtual void prepend(const Int8Sequence &rWhat) override
void setCurrentElement(::sal_Int32 nToken) override
virtual void append(const css::uno::Sequence< sal_Int8 > &rWhat) override
std::map< ::sal_Int32, Int8Sequence > maData
ForSort(sal_Int32 const nTag, const Int32Sequence &rOrder)
Receives notification of sax document events to write into an XOutputStream.
std::stack< std::shared_ptr< ForMerge > > maMarkStack
OString getId(::sal_Int32 Element)
std::stack< sal_Int32 > m_DebugStartedElements
void endDocument()
called by the parser after the last XML element of a stream is processed.
void writeFastAttributeList(FastAttributeList const &rAttrList)
void startFastElement(::sal_Int32 Element, FastAttributeList const *pAttrList=nullptr)
receives notification of the beginning of an element.
void mergeTopMarks(sal_Int32 nTag, sax_fastparser::MergeMarks eMergeType)
Merge 2 topmost marks.
FastSaxSerializer(const css::uno::Reference< css::io::XOutputStream > &xOutputStream)
void singleFastElement(::sal_Int32 Element, FastAttributeList const *pAttrList=nullptr)
receives notification of the beginning of a single element.
css::uno::Sequence< ::sal_Int8 > Int8Sequence
void endFastElement(::sal_Int32 Element)
receives notification of the end of a known element.
CachedOutputStream maCachedOutputStream
Helper class to cache data and write in chunks to XOutputStream or ForMerge::append.
css::uno::Reference< css::xml::sax::XFastTokenHandler > mxFastTokenHandler
bool mbXescape
whether to escape invalid XML characters as xHHHH in write(const char*,sal_Int32,true)
TokenValueList & getTokenValueList()
called by FSHelper to put data in for writeTokenValueList
css::uno::Sequence< ::sal_Int32 > Int32Sequence
css::uno::Reference< css::io::XOutputStream > const & getOutputStream() const
void writeBytes(const css::uno::Sequence< ::sal_Int8 > &aData)
Forward the call to the output stream, or write to the stack.
void writeId(::sal_Int32 Element)
void mark(sal_Int32 nTag, const Int32Sequence &rOrder)
From now on, don't write directly to the stream, but to top of a stack.
void startDocument()
called by the parser when parsing of an XML stream is started.
std::vector< TokenValue > TokenValueList
TokenValue(sal_Int32 _nToken, const char *_pValue)