22#include <com/sun/star/lang/IllegalArgumentException.hpp>
23#include <com/sun/star/lang/XServiceInfo.hpp>
24#include <com/sun/star/uno/Reference.hxx>
25#include <com/sun/star/uno/Sequence.hxx>
26#include <com/sun/star/uri/XUriSchemeParser.hpp>
27#include <com/sun/star/uri/XVndSunStarScriptUrlReference.hpp>
31#include <rtl/character.hxx>
33#include <rtl/ustrbuf.hxx>
34#include <rtl/ustring.hxx>
47 return c >=
'0' && c <= '9' ? static_cast< int >(c -
'0')
48 : c >=
'A' && c <=
'F' ? static_cast<
int >(c -
'A' + 10)
49 : c >=
'a' && c <=
'f' ? static_cast<
int >(c -
'a' + 10)
53int parseEscaped(std::u16string_view part, sal_Int32 * index) {
54 if (part.size() - *index < 3 || part[*index] !=
'%') {
57 int n1 = getHexWeight(part[*index + 1]);
58 int n2 = getHexWeight(part[*index + 2]);
59 if (n1 < 0 || n2 < 0) {
63 return (n1 << 4) |
n2;
67 std::u16string_view part,
bool namePart, sal_Int32 * index)
69 OUStringBuffer buf(64);
72 if (namePart ? c ==
'?' : c ==
'&' || c ==
'=') {
74 }
else if (c ==
'%') {
76 int n = parseEscaped(part, &i);
77 if (n >= 0 && n <= 0x7F) {
79 }
else if (n >= 0xC0 && n <= 0xFC) {
84 encoded = (
n & 0x1F) << 6;
87 }
else if (n <= 0xEF) {
88 encoded = (
n & 0x0F) << 12;
91 }
else if (n <= 0xF7) {
92 encoded = (
n & 0x07) << 18;
95 }
else if (n <= 0xFB) {
96 encoded = (
n & 0x03) << 24;
106 n = parseEscaped(part, &i);
107 if (n < 0x80 || n > 0xBF) {
111 encoded |= (
n & 0x3F) << shift;
113 if (!utf8 || !rtl::isUnicodeScalarValue(encoded)
118 buf.appendUtf32(encoded);
128 return buf.makeStringAndClear();
131OUString encodeNameOrParamFragment(OUString
const & fragment) {
132 static constexpr auto nameOrParamFragment = rtl::createUriCharClass(
133 u8
"!$'()*+,-.0123456789:;@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]_abcdefghijklmnopqrstuvwxyz~");
134 return rtl::Uri::encode(
135 fragment, nameOrParamFragment.data(), rtl_UriEncodeIgnoreEscapes,
136 RTL_TEXTENCODING_UTF8);
139bool parseSchemeSpecificPart(std::u16string_view part) {
140 size_t len = part.size();
142 if (parsePart(part,
true, &i).isEmpty() || part[0] ==
'/') {
156 parsePart(part,
false, &i);
160 if (part[i] !=
'&') {
167 public cppu::WeakImplHelper<css::uri::XVndSunStarScriptUrlReference>
170 UrlReference(OUString
const & scheme, OUString
const & path):
172 scheme, false, OUString(), path, false, OUString())
175 UrlReference(
const UrlReference&) =
delete;
176 UrlReference& operator=(
const UrlReference&) =
delete;
178 virtual OUString SAL_CALL getUriReference()
override
179 {
return m_base.getUriReference(); }
181 virtual sal_Bool SAL_CALL isAbsolute()
override
182 {
return m_base.isAbsolute(); }
184 virtual OUString SAL_CALL getScheme()
override
185 {
return m_base.getScheme(); }
187 virtual OUString SAL_CALL getSchemeSpecificPart()
override
188 {
return m_base.getSchemeSpecificPart(); }
190 virtual sal_Bool SAL_CALL isHierarchical()
override
191 {
return m_base.isHierarchical(); }
193 virtual sal_Bool SAL_CALL hasAuthority()
override
194 {
return m_base.hasAuthority(); }
196 virtual OUString SAL_CALL getAuthority()
override
197 {
return m_base.getAuthority(); }
199 virtual OUString SAL_CALL getPath()
override
200 {
return m_base.getPath(); }
202 virtual sal_Bool SAL_CALL hasRelativePath()
override
203 {
return m_base.hasRelativePath(); }
205 virtual sal_Int32 SAL_CALL getPathSegmentCount()
override
206 {
return m_base.getPathSegmentCount(); }
208 virtual OUString SAL_CALL getPathSegment(sal_Int32 index)
override
209 {
return m_base.getPathSegment(index); }
211 virtual sal_Bool SAL_CALL hasQuery()
override
212 {
return m_base.hasQuery(); }
214 virtual OUString SAL_CALL getQuery()
override
215 {
return m_base.getQuery(); }
217 virtual sal_Bool SAL_CALL hasFragment()
override
218 {
return m_base.hasFragment(); }
220 virtual OUString SAL_CALL getFragment()
override
221 {
return m_base.getFragment(); }
223 virtual void SAL_CALL setFragment(OUString
const & fragment)
override
224 { m_base.setFragment(fragment); }
226 virtual void SAL_CALL clearFragment()
override
227 { m_base.clearFragment(); }
229 virtual OUString SAL_CALL getName()
override;
231 virtual void SAL_CALL setName(OUString
const & name)
override;
233 virtual sal_Bool SAL_CALL hasParameter(OUString
const & key)
override;
235 virtual OUString SAL_CALL getParameter(OUString
const & key)
override;
237 virtual void SAL_CALL setParameter(OUString
const & key, OUString
const & value)
override;
240 virtual ~UrlReference()
override {}
242 sal_Int32 findParameter(std::u16string_view key)
const;
247OUString UrlReference::getName() {
248 std::lock_guard g(m_base.m_mutex);
250 return parsePart(m_base.m_path,
true, &i);
253void SAL_CALL UrlReference::setName(OUString
const & name)
256 throw css::lang::IllegalArgumentException(
257 OUString(), *
this, 1);
259 std::lock_guard g(m_base.m_mutex);
261 parsePart(m_base.m_path,
true, &i);
263 m_base.m_path = encodeNameOrParamFragment(name) + m_base.m_path.subView(i);
266sal_Bool UrlReference::hasParameter(OUString
const & key)
268 std::lock_guard g(m_base.m_mutex);
269 return findParameter(key) >= 0;
272OUString UrlReference::getParameter(OUString
const & key)
274 std::lock_guard g(m_base.m_mutex);
275 sal_Int32
i = findParameter(key);
276 return i >= 0 ? parsePart(m_base.m_path,
false, &i) : OUString();
279void UrlReference::setParameter(OUString
const & key, OUString
const & value)
282 throw css::lang::IllegalArgumentException(
283 OUString(), *
this, 1);
285 std::lock_guard g(m_base.m_mutex);
286 sal_Int32
i = findParameter(key);
287 bool bExistent = (
i>=0 );
289 i = m_base.m_path.getLength();
292 OUStringBuffer newPath(128);
293 newPath.append(m_base.m_path.subView(0, i));
295 newPath.append( m_base.m_path.indexOf(
'?') < 0 ?
'?' :
'&' );
296 newPath.append(encodeNameOrParamFragment(key) +
"=");
298 newPath.append(encodeNameOrParamFragment(value));
301 parsePart(m_base.m_path,
false, &i);
302 newPath.append(m_base.m_path.subView(i));
305 m_base.m_path = newPath.makeStringAndClear();
308sal_Int32 UrlReference::findParameter(std::u16string_view key)
const {
310 parsePart(m_base.m_path,
true, &i);
312 if (i == m_base.m_path.getLength()) {
316 OUString k = parsePart(m_base.m_path,
false, &i);
321 parsePart(m_base.m_path,
false, &i);
326 public cppu::WeakImplHelper<
327 css::lang::XServiceInfo, css::uri::XUriSchemeParser>
332 Parser(
const Parser&) =
delete;
333 Parser& operator=(
const Parser&) =
delete;
339 virtual css::uno::Sequence< OUString > SAL_CALL
342 virtual css::uno::Reference< css::uri::XUriReference > SAL_CALL
344 OUString
const & scheme, OUString
const & schemeSpecificPart)
override;
347 virtual ~Parser()
override {}
350OUString Parser::getImplementationName()
352 return "com.sun.star.comp.uri.UriSchemeParser_vndDOTsunDOTstarDOTscript";
355sal_Bool Parser::supportsService(OUString
const & serviceName)
360css::uno::Sequence< OUString > Parser::getSupportedServiceNames()
362 return {
"com.sun.star.uri.UriSchemeParser_vndDOTsunDOTstarDOTscript" };
365css::uno::Reference< css::uri::XUriReference >
367 OUString
const & scheme, OUString
const & schemeSpecificPart)
369 if (!parseSchemeSpecificPart(schemeSpecificPart)) {
372 return new UrlReference(scheme, schemeSpecificPart);
377extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
379 css::uno::Sequence<css::uno::Any>
const &)
382 return ::cppu::acquire(
new Parser());
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * com_sun_star_comp_uri_UriSchemeParser_vndDOTsunDOTstarDOTscript_get_implementation(css::uno::XComponentContext *, css::uno::Sequence< css::uno::Any > const &)
css::uno::Sequence< OUString > getSupportedServiceNames()
OUString getImplementationName()
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
bool parse(OUString const &uri, SourceProviderScannerData *data)
SwNodeOffset min(const SwNodeOffset &a, const SwNodeOffset &b)
const wchar_t *typedef int(__stdcall *DllNativeUnregProc)(int