1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 #include <UriBindingHelper.hxx>
22 #include <tools/stream.hxx>
23 #include <unotools/streamwrap.hxx>
25 #include <com/sun/star/embed/XStorage.hpp>
26 #include <com/sun/star/embed/ElementModes.hpp>
27 #include <osl/diagnose.h>
28 #include <rtl/uri.hxx>
29 #include <sal/log.hxx>
31 #include <documentsignaturehelper.hxx>
33 using namespace com::sun::star
;
37 UriBindingHelper::UriBindingHelper()
41 UriBindingHelper::UriBindingHelper( const css::uno::Reference
< css::embed::XStorage
>& rxStorage
, const uno::Reference
<io::XStream
>& xScriptingSignatureStream
)
43 mxStorage
= rxStorage
;
44 mxScriptingSignatureStream
= xScriptingSignatureStream
;
47 void SAL_CALL
UriBindingHelper::setUriBinding( const OUString
& /*uri*/, const uno::Reference
< io::XInputStream
>&)
51 uno::Reference
< io::XInputStream
> SAL_CALL
UriBindingHelper::getUriBinding( const OUString
& uri
)
53 uno::Reference
< io::XInputStream
> xInputStream
;
56 xInputStream
= OpenInputStream( mxStorage
, uri
, mxScriptingSignatureStream
);
60 std::unique_ptr
<SvFileStream
> pStream(new SvFileStream( uri
, StreamMode::READ
));
61 xInputStream
= new utl::OInputStreamWrapper( std::move(pStream
) );
66 uno::Reference
< io::XInputStream
> UriBindingHelper::OpenInputStream( const uno::Reference
< embed::XStorage
>& rxStore
, const OUString
& rURI
, const css::uno::Reference
<css::io::XStream
>& xScriptingSignatureStream
)
68 OSL_ASSERT(!rURI
.isEmpty());
69 uno::Reference
< io::XInputStream
> xInStream
;
72 // Ignore leading slash, don't attempt to open a storage with name "".
73 if (aURI
.startsWith("/"))
75 // Ignore query part of the URI.
76 sal_Int32 nQueryPos
= aURI
.indexOf('?');
78 aURI
= aURI
.copy(0, nQueryPos
);
81 sal_Int32 nSepPos
= aURI
.indexOf( '/' );
84 // Cloning because of I can't keep all storage references open
85 // MBA with think about a better API...
86 const OUString sName
= ::rtl::Uri::decode(
87 aURI
, rtl_UriDecodeStrict
, rtl_UriCharClassRelSegment
);
88 if (sName
.isEmpty() && !aURI
.isEmpty())
89 throw uno::Exception(u
"Could not decode URI for stream element."_ustr
, nullptr);
91 uno::Reference
< io::XStream
> xStream
;
92 if (!rxStore
->hasByName(sName
))
94 if (xScriptingSignatureStream
.is() && sName
== DocumentSignatureHelper::GetScriptingContentSignatureDefaultStreamName())
96 xStream
= xScriptingSignatureStream
;
97 uno::Reference
<io::XSeekable
> xSeekable(xScriptingSignatureStream
, uno::UNO_QUERY
);
100 // Cloned streams are always positioned at the start, do the same in the overlay
107 SAL_WARN("xmlsecurity.helper", "expected stream, but not found: " << sName
);
111 xStream
= rxStore
->cloneStreamElement( sName
);
113 throw uno::RuntimeException();
114 xInStream
= xStream
->getInputStream();
118 const OUString aStoreName
= ::rtl::Uri::decode(
119 aURI
.copy( 0, nSepPos
), rtl_UriDecodeStrict
, rtl_UriCharClassRelSegment
);
120 if (aStoreName
.isEmpty() && !aURI
.isEmpty())
121 throw uno::Exception(u
"Could not decode URI for stream element."_ustr
, nullptr);
123 OUString aElement
= aURI
.copy( nSepPos
+1 );
124 uno::Reference
< embed::XStorage
> xSubStore
= rxStore
->openStorageElement( aStoreName
, embed::ElementModes::READ
);
125 xInStream
= OpenInputStream( xSubStore
, aElement
, xScriptingSignatureStream
);
130 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */