Coverage Report

Created: 2025-11-16 09:57

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/unotools/source/ucbhelper/ucbstreamhelper.cxx
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
 * 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
#include <rtl/ustring.hxx>
21
#include <unotools/ucbstreamhelper.hxx>
22
#include <comphelper/processfactory.hxx>
23
#include <com/sun/star/task/InteractionHandler.hpp>
24
#include <com/sun/star/ucb/ContentCreationException.hpp>
25
#include <com/sun/star/ucb/CommandAbortedException.hpp>
26
#include <com/sun/star/ucb/InsertCommandArgument.hpp>
27
#include <com/sun/star/beans/PropertyValue.hpp>
28
29
#include <comphelper/simplefileaccessinteraction.hxx>
30
#include <ucbhelper/content.hxx>
31
#include <unotools/streamwrap.hxx>
32
#include "ucblockbytes.hxx"
33
34
namespace com::sun::star::ucb { class XCommandEnvironment; }
35
36
using namespace ::com::sun::star::uno;
37
using namespace ::com::sun::star::io;
38
using namespace ::com::sun::star::ucb;
39
using namespace ::com::sun::star::task;
40
using namespace ::com::sun::star::lang;
41
using namespace ::com::sun::star::beans;
42
43
namespace utl
44
{
45
46
static std::unique_ptr<SvStream> lcl_CreateStream( const OUString& rFileName, StreamMode eOpenMode,
47
                                   const Reference < XInteractionHandler >& xInteractionHandler,
48
                                   bool bEnsureFileExists )
49
112k
{
50
112k
    std::unique_ptr<SvStream> pStream;
51
112k
    UcbLockBytesRef xLockBytes;
52
112k
    if ( eOpenMode & StreamMode::WRITE )
53
38.7k
    {
54
38.7k
        bool bTruncate = bool( eOpenMode & StreamMode::TRUNC );
55
38.7k
        if ( bTruncate )
56
305
        {
57
305
            try
58
305
            {
59
                // truncate is implemented with deleting the original file
60
305
                ::ucbhelper::Content aCnt(
61
305
                    rFileName, Reference < XCommandEnvironment >(),
62
305
                    comphelper::getProcessComponentContext() );
63
305
                aCnt.executeCommand( u"delete"_ustr, css::uno::Any( true ) );
64
305
            }
65
66
305
            catch ( const CommandAbortedException& )
67
305
            {
68
                // couldn't truncate/delete
69
0
            }
70
305
            catch ( const ContentCreationException& )
71
305
            {
72
305
            }
73
305
            catch ( const Exception& )
74
305
            {
75
0
            }
76
305
        }
77
78
38.7k
        if ( bEnsureFileExists || bTruncate )
79
305
        {
80
305
            try
81
305
            {
82
                // make sure that the desired file exists before trying to open
83
305
                SvMemoryStream aStream(0,0);
84
305
                rtl::Reference<::utl::OInputStreamWrapper> xInput = new ::utl::OInputStreamWrapper( aStream );
85
86
305
                ::ucbhelper::Content aContent(
87
305
                    rFileName, Reference < XCommandEnvironment >(),
88
305
                    comphelper::getProcessComponentContext() );
89
305
                InsertCommandArgument aInsertArg;
90
305
                aInsertArg.Data = xInput;
91
92
305
                aInsertArg.ReplaceExisting = false;
93
305
                Any aCmdArg;
94
305
                aCmdArg <<= aInsertArg;
95
305
                aContent.executeCommand( u"insert"_ustr, aCmdArg );
96
305
            }
97
98
            // it is NOT an error when the stream already exists and no truncation was desired
99
305
            catch ( const CommandAbortedException& )
100
305
            {
101
                // currently never an error is detected !
102
0
            }
103
305
            catch ( const ContentCreationException& )
104
305
            {
105
305
            }
106
305
            catch ( const Exception& )
107
305
            {
108
0
            }
109
305
        }
110
38.7k
    }
111
112
112k
    try
113
112k
    {
114
        // create LockBytes using UCB
115
112k
        ::ucbhelper::Content aContent(
116
112k
            rFileName, Reference < XCommandEnvironment >(),
117
112k
            comphelper::getProcessComponentContext() );
118
112k
        xLockBytes = UcbLockBytes::CreateLockBytes( aContent.get(), Sequence < PropertyValue >(),
119
112k
                                                    eOpenMode, xInteractionHandler );
120
112k
        if ( xLockBytes.is() )
121
42.0k
        {
122
42.0k
            pStream.reset( new SvStream( xLockBytes.get() ) );
123
42.0k
            pStream->SetBufferSize( 4096 );
124
42.0k
            pStream->SetError( xLockBytes->GetError() );
125
42.0k
        }
126
112k
    }
127
112k
    catch ( const CommandAbortedException& )
128
112k
    {
129
0
    }
130
112k
    catch ( const ContentCreationException& )
131
112k
    {
132
45.0k
    }
133
112k
    catch ( const Exception& )
134
112k
    {
135
25.8k
    }
136
137
112k
    return pStream;
138
112k
}
139
140
std::unique_ptr<SvStream>
141
UcbStreamHelper::CreateStream(const OUString& rFileName, StreamMode eOpenMode,
142
                              const css::uno::Reference<css::awt::XWindow>& xParentWin,
143
                              bool bUseSimpleFileAccessInteraction)
144
74.5k
{
145
    // related tdf#99312
146
    // create a specialized interaction handler to manages Web certificates and Web credentials when needed
147
74.5k
    Reference< XInteractionHandler > xIH(
148
74.5k
        css::task::InteractionHandler::createWithParent(comphelper::getProcessComponentContext(), xParentWin));
149
150
74.5k
    if (!bUseSimpleFileAccessInteraction)
151
0
        return lcl_CreateStream(rFileName, eOpenMode, xIH, true /* bEnsureFileExists */);
152
153
74.5k
    Reference<XInteractionHandler> xIHScoped(new comphelper::SimpleFileAccessInteraction(xIH));
154
155
74.5k
    return lcl_CreateStream( rFileName, eOpenMode, xIHScoped, true /* bEnsureFileExists */ );
156
74.5k
}
157
158
std::unique_ptr<SvStream>
159
UcbStreamHelper::CreateStream(const OUString& rFileName, StreamMode eOpenMode, bool bFileExists,
160
                              const css::uno::Reference<css::awt::XWindow> & xParentWin,
161
                              bool bUseSimpleFileAccessInteraction)
162
38.4k
{
163
    // related tdf#99312
164
    // create a specialized interaction handler to manages Web certificates and Web credentials when needed
165
38.4k
    Reference< XInteractionHandler > xIH(
166
38.4k
        css::task::InteractionHandler::createWithParent(comphelper::getProcessComponentContext(), xParentWin));
167
168
38.4k
    if (!bUseSimpleFileAccessInteraction)
169
0
        return lcl_CreateStream(rFileName, eOpenMode, xIH, !bFileExists);
170
171
38.4k
    Reference<XInteractionHandler> xIHScoped(new comphelper::SimpleFileAccessInteraction(xIH));
172
38.4k
    return lcl_CreateStream( rFileName, eOpenMode, xIHScoped,!bFileExists );
173
38.4k
}
174
175
176
std::unique_ptr<SvStream> UcbStreamHelper::CreateStream( const Reference < XInputStream >& xStream )
177
37.9k
{
178
37.9k
    std::unique_ptr<SvStream> pStream;
179
37.9k
    UcbLockBytesRef xLockBytes = UcbLockBytes::CreateInputLockBytes( xStream );
180
37.9k
    if ( xLockBytes.is() )
181
37.9k
    {
182
37.9k
        pStream.reset( new SvStream( xLockBytes.get() ) );
183
37.9k
        pStream->SetBufferSize( 4096 );
184
37.9k
        pStream->SetError( xLockBytes->GetError() );
185
37.9k
    }
186
187
37.9k
    return pStream;
188
37.9k
}
189
190
std::unique_ptr<SvStream> UcbStreamHelper::CreateStream( const Reference < XStream >& xStream )
191
200
{
192
200
    std::unique_ptr<SvStream> pStream;
193
200
    if ( xStream->getOutputStream().is() )
194
200
    {
195
200
        UcbLockBytesRef xLockBytes = UcbLockBytes::CreateLockBytes( xStream );
196
200
        if ( xLockBytes.is() )
197
200
        {
198
200
            pStream.reset( new SvStream( xLockBytes.get() ) );
199
200
            pStream->SetBufferSize( 4096 );
200
200
            pStream->SetError( xLockBytes->GetError() );
201
200
        }
202
200
    }
203
0
    else
204
0
        return CreateStream( xStream->getInputStream() );
205
206
200
    return pStream;
207
200
}
208
209
std::unique_ptr<SvStream> UcbStreamHelper::CreateStream( const Reference < XInputStream >& xStream, bool bCloseStream )
210
11.2k
{
211
11.2k
    std::unique_ptr<SvStream> pStream;
212
11.2k
    UcbLockBytesRef xLockBytes = UcbLockBytes::CreateInputLockBytes( xStream );
213
11.2k
    if ( xLockBytes.is() )
214
11.2k
    {
215
11.2k
        if ( !bCloseStream )
216
8.23k
            xLockBytes->setDontClose();
217
218
11.2k
        pStream.reset( new SvStream( xLockBytes.get() ) );
219
11.2k
        pStream->SetBufferSize( 4096 );
220
11.2k
        pStream->SetError( xLockBytes->GetError() );
221
11.2k
    }
222
223
11.2k
    return pStream;
224
11.2k
};
225
226
std::unique_ptr<SvStream> UcbStreamHelper::CreateStream( const Reference < XStream >& xStream, bool bCloseStream )
227
163k
{
228
163k
    std::unique_ptr<SvStream> pStream;
229
163k
    if ( xStream->getOutputStream().is() )
230
163k
    {
231
163k
        UcbLockBytesRef xLockBytes = UcbLockBytes::CreateLockBytes( xStream );
232
163k
        if ( xLockBytes.is() )
233
163k
        {
234
163k
            if ( !bCloseStream )
235
163k
                xLockBytes->setDontClose();
236
237
163k
            pStream.reset( new SvStream( xLockBytes.get() ) );
238
163k
            pStream->SetBufferSize( 4096 );
239
163k
            pStream->SetError( xLockBytes->GetError() );
240
163k
        }
241
163k
    }
242
1
    else
243
1
        return CreateStream( xStream->getInputStream(), bCloseStream );
244
245
163k
    return pStream;
246
163k
};
247
248
}
249
250
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */