Line data Source code
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 :
10 : #ifndef INCLUDED_SAX_SOURCE_TOOLS_CACHEDOUTPUTSTREAM_HXX
11 : #define INCLUDED_SAX_SOURCE_TOOLS_CACHEDOUTPUTSTREAM_HXX
12 :
13 : #include <sal/types.h>
14 :
15 : #include <com/sun/star/io/XOutputStream.hpp>
16 : #include <com/sun/star/uno/Sequence.hxx>
17 :
18 : #include <cstring>
19 : #include <cstdlib>
20 : #include <boost/shared_ptr.hpp>
21 :
22 : namespace sax_fastparser {
23 :
24 121899 : class ForMergeBase
25 : {
26 : public:
27 121899 : virtual ~ForMergeBase() {}
28 : virtual void append( const css::uno::Sequence<sal_Int8>& rWhat ) = 0;
29 : };
30 :
31 : class CachedOutputStream
32 : {
33 : /// When buffer hits this size, it's written to mxOutputStream
34 : static const sal_Int32 mnMaximumSize = 0x10000;
35 :
36 : /// Output stream, usually writing data into files.
37 : css::uno::Reference< css::io::XOutputStream > mxOutputStream;
38 : sal_Int32 mnCacheWrittenSize;
39 : const css::uno::Sequence<sal_Int8> mpCache;
40 : uno_Sequence *pSeq;
41 : bool mbWriteToOutStream;
42 : /// ForMerge structure is used for sorting elements in Writer
43 : boost::shared_ptr< ForMergeBase > mpForMerge;
44 :
45 : public:
46 4656 : CachedOutputStream() : mnCacheWrittenSize(0)
47 : , mpCache(mnMaximumSize)
48 4656 : , pSeq(mpCache.get())
49 : , mbWriteToOutStream(true)
50 9312 : , mpForMerge(nullptr)
51 4656 : {}
52 4656 : ~CachedOutputStream() {}
53 :
54 4385 : css::uno::Reference< css::io::XOutputStream > getOutputStream() const
55 : {
56 4385 : return mxOutputStream;
57 : }
58 :
59 4656 : void setOutputStream( const css::uno::Reference< css::io::XOutputStream >& xOutputStream )
60 : {
61 4656 : mxOutputStream = xOutputStream;
62 4656 : }
63 :
64 217510 : void setOutput( boost::shared_ptr< ForMergeBase > pForMerge )
65 : {
66 217510 : flush();
67 217510 : mbWriteToOutStream = false;
68 217510 : mpForMerge = pForMerge;
69 217510 : }
70 :
71 26288 : void resetOutputToStream()
72 : {
73 26288 : flush();
74 26288 : mbWriteToOutStream = true;
75 26288 : mpForMerge.reset();
76 26288 : }
77 :
78 : /// cache string and if limit is hit, flush
79 12916017 : void writeBytes( const sal_Int8* pStr, sal_Int32 nLen )
80 : {
81 : // Write when the buffer gets big enough
82 12916017 : if (mnCacheWrittenSize + nLen > mnMaximumSize)
83 : {
84 17 : flush();
85 :
86 : // Writer does some elements sorting, so it can accumulate
87 : // pretty big strings in FastSaxSerializer::ForMerge.
88 : // In that case, just flush data and write immediately.
89 17 : if (nLen > mnMaximumSize)
90 : {
91 3 : if (mbWriteToOutStream)
92 3 : mxOutputStream->writeBytes( css::uno::Sequence<sal_Int8>(pStr, nLen) );
93 : else
94 0 : mpForMerge->append( css::uno::Sequence<sal_Int8>(pStr, nLen) );
95 12916020 : return;
96 : }
97 : }
98 :
99 12916014 : memcpy(pSeq->elements + mnCacheWrittenSize, pStr, nLen);
100 12916014 : mnCacheWrittenSize += nLen;
101 : }
102 :
103 : /// immediately write buffer into mxOutputStream and clear
104 563817 : void flush()
105 : {
106 : // resize the Sequence to written size
107 563817 : pSeq->nElements = mnCacheWrittenSize;
108 563817 : if (mbWriteToOutStream)
109 30961 : mxOutputStream->writeBytes( mpCache );
110 : else
111 532856 : mpForMerge->append( mpCache );
112 : // and next time write to the beginning
113 563817 : mnCacheWrittenSize = 0;
114 563817 : }
115 : };
116 :
117 : }
118 :
119 : #endif
120 :
121 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|