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 .
22 * Implementation of the I/O interfaces based on stream and URI binding
24 #include "xmlstreamio.hxx"
25 #include <rtl/ustring.hxx>
26 #include "rtl/uri.hxx"
28 #include <libxml/uri.h>
29 #include <sal/types.h>
30 //For reasons that escape me, this is what xmlsec does when size_t is not 4
31 #if SAL_TYPES_SIZEOFPOINTER != 4
32 # define XMLSEC_NO_SIZE_T
34 #include <xmlsec/io.h>
36 #define XMLSTREAMIO_INITIALIZED 0x01
37 #define XMLSTREAMIO_REGISTERED 0x02
39 /* Global variables */
41 * Enable stream I/O or not.
43 static char enableXmlStreamIO
= 0x00 ;
45 ::com::sun::star::uno::Reference
< ::com::sun::star::xml::crypto::XUriBinding
> m_xUriBinding
;
48 int xmlStreamMatch( const char* uri
)
50 ::com::sun::star::uno::Reference
< com::sun::star::io::XInputStream
> xInputStream
;
52 if( ( enableXmlStreamIO
& XMLSTREAMIO_INITIALIZED
) &&
53 ( enableXmlStreamIO
& XMLSTREAMIO_REGISTERED
) ) {
54 if( uri
== NULL
|| !m_xUriBinding
.is() )
56 //XMLSec first unescapes the uri and calls this function. For example, we pass the Uri
57 //ObjectReplacements/Object%201 then XMLSec passes ObjectReplacements/Object 1
58 //first. If this failed it would try this
59 //again with the original escaped string. However, it does not get this far, because there
60 //is another callback registered by libxml which claims to be able to handle this uri.
61 ::rtl::OUString sUri
=
62 ::rtl::Uri::encode( ::rtl::OUString::createFromAscii( uri
),
63 rtl_UriCharClassUric
, rtl_UriEncodeKeepEscapes
, RTL_TEXTENCODING_UTF8
);
64 xInputStream
= m_xUriBinding
->getUriBinding( sUri
) ;
65 if (!xInputStream
.is())
67 //Try the the passed in uri directly.
68 //For old documents prior OOo 3.0. We did not use URIs then.
69 xInputStream
= m_xUriBinding
->getUriBinding(
70 ::rtl::OUString::createFromAscii(uri
));
73 if (xInputStream
.is())
80 void* xmlStreamOpen( const char* uri
)
82 ::com::sun::star::uno::Reference
< com::sun::star::io::XInputStream
> xInputStream
;
83 ::com::sun::star::io::XInputStream
* pInputStream
;
85 if( ( enableXmlStreamIO
& XMLSTREAMIO_INITIALIZED
) &&
86 ( enableXmlStreamIO
& XMLSTREAMIO_REGISTERED
) ) {
87 if( uri
== NULL
|| !m_xUriBinding
.is() )
91 ::rtl::OUString sUri
=
92 ::rtl::Uri::encode( ::rtl::OUString::createFromAscii( uri
),
93 rtl_UriCharClassUric
, rtl_UriEncodeKeepEscapes
, RTL_TEXTENCODING_UTF8
);
94 xInputStream
= m_xUriBinding
->getUriBinding( sUri
) ;
95 if (!xInputStream
.is())
98 //try the the passed in uri directly.
99 xInputStream
= m_xUriBinding
->getUriBinding(
100 ::rtl::OUString::createFromAscii(uri
));
103 if( xInputStream
.is() ) {
104 pInputStream
= xInputStream
.get() ;
105 pInputStream
->acquire() ;
106 return ( void* )pInputStream
;
114 int xmlStreamRead( void* context
, char* buffer
, int len
)
117 ::com::sun::star::uno::Reference
< com::sun::star::io::XInputStream
> xInputStream
;
118 ::com::sun::star::uno::Sequence
< sal_Int8
> outSeqs( len
) ;
121 if( ( enableXmlStreamIO
& XMLSTREAMIO_INITIALIZED
) &&
122 ( enableXmlStreamIO
& XMLSTREAMIO_REGISTERED
) ) {
123 if( context
!= NULL
) {
124 xInputStream
= ( com::sun::star::io::XInputStream
* )context
;
125 if( !xInputStream
.is() )
128 numbers
= xInputStream
->readBytes( outSeqs
, len
) ;
129 const sal_Int8
* readBytes
= ( const sal_Int8
* )outSeqs
.getArray() ;
130 for( int i
= 0 ; i
< numbers
; i
++ )
131 *( buffer
+ i
) = *( readBytes
+ i
) ;
139 int xmlStreamClose( void * context
)
141 ::com::sun::star::io::XInputStream
* pInputStream
;
143 if( ( enableXmlStreamIO
& XMLSTREAMIO_INITIALIZED
) &&
144 ( enableXmlStreamIO
& XMLSTREAMIO_REGISTERED
) ) {
145 if( context
!= NULL
) {
146 pInputStream
= ( ::com::sun::star::io::XInputStream
* )context
;
147 pInputStream
->release() ;
154 int xmlEnableStreamInputCallbacks()
157 if( !( enableXmlStreamIO
& XMLSTREAMIO_INITIALIZED
) ) {
158 //Register the callbacks into xmlSec
159 //In order to make the xmlsec io finding the callbacks firstly,
160 //I put the callbacks at the very begining.
162 //Cleanup the older callbacks.
163 //Notes: all none default callbacks will lose.
164 xmlSecIOCleanupCallbacks() ;
166 //Register my classbacks.
167 int cbs
= xmlSecIORegisterCallbacks(
176 //Register the default callbacks.
177 //Notes: the error will cause xmlsec working problems.
178 cbs
= xmlSecIORegisterDefaultCallbacks() ;
183 enableXmlStreamIO
|= XMLSTREAMIO_INITIALIZED
;
189 int xmlRegisterStreamInputCallbacks(
190 ::com::sun::star::uno::Reference
< ::com::sun::star::xml::crypto::XUriBinding
>& aUriBinding
192 if( !( enableXmlStreamIO
& XMLSTREAMIO_INITIALIZED
) ) {
193 if( xmlEnableStreamInputCallbacks() < 0 )
197 if( !( enableXmlStreamIO
& XMLSTREAMIO_REGISTERED
) ) {
198 enableXmlStreamIO
|= XMLSTREAMIO_REGISTERED
;
201 m_xUriBinding
= aUriBinding
;
206 int xmlUnregisterStreamInputCallbacks( void )
208 if( ( enableXmlStreamIO
& XMLSTREAMIO_REGISTERED
) ) {
209 //Clear the uir-stream binding
210 m_xUriBinding
.clear() ;
212 //disable the registered flag
213 enableXmlStreamIO
&= ~XMLSTREAMIO_REGISTERED
;
219 void xmlDisableStreamInputCallbacks() {
220 xmlUnregisterStreamInputCallbacks() ;
221 enableXmlStreamIO
&= ~XMLSTREAMIO_INITIALIZED
;
224 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */