Coverage Report

Created: 2025-11-16 09:57

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