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 .
21 #include "stocservices.hxx"
23 #include "supportsService.hxx"
25 #include "com/sun/star/lang/XServiceInfo.hpp"
26 #include "com/sun/star/uno/Exception.hpp"
27 #include "com/sun/star/uno/Reference.hxx"
28 #include "com/sun/star/uno/RuntimeException.hpp"
29 #include "com/sun/star/uno/Sequence.hxx"
30 #include "com/sun/star/uno/XComponentContext.hpp"
31 #include "com/sun/star/uno/XInterface.hpp"
32 #include "com/sun/star/uri/XExternalUriReferenceTranslator.hpp"
33 #include "cppuhelper/implbase2.hxx"
34 #include "cppuhelper/weak.hxx"
35 #include "osl/thread.h"
36 #include "rtl/string.h"
37 #include "rtl/textenc.h"
39 #include "rtl/uri.hxx"
40 #include "rtl/ustrbuf.hxx"
41 #include "rtl/ustring.hxx"
42 #include "sal/types.h"
48 class Translator
: public cppu::WeakImplHelper2
<
49 css::lang::XServiceInfo
, css::uri::XExternalUriReferenceTranslator
>
53 css::uno::Reference
< css::uno::XComponentContext
> const & context
):
56 virtual OUString SAL_CALL
getImplementationName()
57 throw (css::uno::RuntimeException
);
59 virtual sal_Bool SAL_CALL
supportsService(OUString
const & serviceName
)
60 throw (css::uno::RuntimeException
);
62 virtual css::uno::Sequence
< OUString
> SAL_CALL
63 getSupportedServiceNames() throw (css::uno::RuntimeException
);
65 virtual OUString SAL_CALL
66 translateToInternal(OUString
const & externalUriReference
)
67 throw (css::uno::RuntimeException
);
69 virtual OUString SAL_CALL
70 translateToExternal(OUString
const & internalUriReference
)
71 throw (css::uno::RuntimeException
);
74 Translator(Translator
&); // not implemented
75 void operator =(Translator
); // not implemented
77 virtual ~Translator() {}
79 css::uno::Reference
< css::uno::XComponentContext
> m_context
;
82 OUString
Translator::getImplementationName()
83 throw (css::uno::RuntimeException
)
86 stoc_services::ExternalUriReferenceTranslator::getImplementationName();
89 sal_Bool
Translator::supportsService(OUString
const & serviceName
)
90 throw (css::uno::RuntimeException
)
92 return stoc::uriproc::supportsService(
93 getSupportedServiceNames(), serviceName
);
96 css::uno::Sequence
< OUString
> Translator::getSupportedServiceNames()
97 throw (css::uno::RuntimeException
)
99 return stoc_services::ExternalUriReferenceTranslator::
100 getSupportedServiceNames();
103 OUString
Translator::translateToInternal(
104 OUString
const & externalUriReference
)
105 throw (css::uno::RuntimeException
)
107 if (!externalUriReference
.matchIgnoreAsciiCaseAsciiL(
108 RTL_CONSTASCII_STRINGPARAM("file:/")))
110 return externalUriReference
;
112 sal_Int32 i
= RTL_CONSTASCII_LENGTH("file:");
114 buf
.append(externalUriReference
.getStr(), i
);
115 // Some environments (e.g., Java) produce illegal file URLs without an
116 // authority part; treat them as having an empty authority part:
117 if (!externalUriReference
.matchAsciiL(RTL_CONSTASCII_STRINGPARAM("//"), i
))
119 buf
.appendAscii(RTL_CONSTASCII_STRINGPARAM("//"));
121 rtl_TextEncoding encoding
= osl_getThreadTextEncoding();
122 for (bool path
= true;;) {
124 while (j
!= externalUriReference
.getLength()
125 && externalUriReference
[j
] != '#'
126 && (!path
|| externalUriReference
[j
] != '/'))
134 externalUriReference
.copy(i
, j
- i
),
135 rtl_UriDecodeStrict
, encoding
),
136 rtl_UriCharClassPchar
, rtl_UriEncodeStrict
,
137 RTL_TEXTENCODING_UTF8
));
143 if (j
== externalUriReference
.getLength()) {
146 buf
.append(externalUriReference
[j
]);
147 path
= externalUriReference
[j
] == '/';
150 return buf
.makeStringAndClear();
153 OUString
Translator::translateToExternal(
154 OUString
const & internalUriReference
)
155 throw (css::uno::RuntimeException
)
157 if (!internalUriReference
.matchIgnoreAsciiCaseAsciiL(
158 RTL_CONSTASCII_STRINGPARAM("file://")))
160 return internalUriReference
;
162 sal_Int32 i
= RTL_CONSTASCII_LENGTH("file://");
164 buf
.append(internalUriReference
.getStr(), i
);
165 rtl_TextEncoding encoding
= osl_getThreadTextEncoding();
166 for (bool path
= true;;) {
168 while (j
!= internalUriReference
.getLength()
169 && internalUriReference
[j
] != '#'
170 && (!path
|| internalUriReference
[j
] != '/'))
175 // Use rtl_UriDecodeToIuri -> rtl_UriEncodeStrictKeepEscapes instead
176 // of rtl_UriDecodeStrict -> rtl_UriEncodeStrict, so that spurious
177 // non--UTF-8 octets like "%FE" are copied verbatim:
181 internalUriReference
.copy(i
, j
- i
),
182 rtl_UriDecodeToIuri
, RTL_TEXTENCODING_UTF8
),
183 rtl_UriCharClassPchar
, rtl_UriEncodeStrictKeepEscapes
,
190 if (j
== internalUriReference
.getLength()) {
193 buf
.append(internalUriReference
[j
]);
194 path
= internalUriReference
[j
] == '/';
197 return buf
.makeStringAndClear();
202 namespace stoc_services
{ namespace ExternalUriReferenceTranslator
{
204 css::uno::Reference
< css::uno::XInterface
> create(
205 css::uno::Reference
< css::uno::XComponentContext
> const & context
)
206 SAL_THROW((css::uno::Exception
))
209 return static_cast< cppu::OWeakObject
* >(new Translator(context
));
210 } catch (std::bad_alloc
&) {
211 throw css::uno::RuntimeException(
212 OUString("std::bad_alloc"), 0);
216 OUString
getImplementationName() {
217 return OUString("com.sun.star.comp.uri.ExternalUriReferenceTranslator");
220 css::uno::Sequence
< OUString
> getSupportedServiceNames() {
221 css::uno::Sequence
< OUString
> s(1);
222 s
[0] = OUString("com.sun.star.uri.ExternalUriReferenceTranslator");
228 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */