summaryrefslogtreecommitdiff
path: root/stoc/source/uriproc/UriSchemeParser_vndDOTsunDOTstarDOTscript.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'stoc/source/uriproc/UriSchemeParser_vndDOTsunDOTstarDOTscript.cxx')
-rw-r--r--stoc/source/uriproc/UriSchemeParser_vndDOTsunDOTstarDOTscript.cxx488
1 files changed, 488 insertions, 0 deletions
diff --git a/stoc/source/uriproc/UriSchemeParser_vndDOTsunDOTstarDOTscript.cxx b/stoc/source/uriproc/UriSchemeParser_vndDOTsunDOTstarDOTscript.cxx
new file mode 100644
index 000000000000..310f3aa318b6
--- /dev/null
+++ b/stoc/source/uriproc/UriSchemeParser_vndDOTsunDOTstarDOTscript.cxx
@@ -0,0 +1,488 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_stoc.hxx"
+
+#include "stocservices.hxx"
+
+#include "UriReference.hxx"
+#include "supportsService.hxx"
+
+#include "com/sun/star/lang/IllegalArgumentException.hpp"
+#include "com/sun/star/lang/XServiceInfo.hpp"
+#include "com/sun/star/uno/Reference.hxx"
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include "com/sun/star/uno/Sequence.hxx"
+#include "com/sun/star/uno/XInterface.hpp"
+#include "com/sun/star/uri/XUriReference.hpp"
+#include "com/sun/star/uri/XUriSchemeParser.hpp"
+#include "com/sun/star/uri/XVndSunStarScriptUrlReference.hpp"
+#include "cppuhelper/implbase1.hxx"
+#include "cppuhelper/implbase2.hxx"
+#include "cppuhelper/weak.hxx"
+#include "osl/mutex.hxx"
+#include "rtl/uri.hxx"
+#include "rtl/ustrbuf.hxx"
+#include "rtl/ustring.hxx"
+#include "sal/types.h"
+
+#include <new>
+
+namespace css = com::sun::star;
+
+namespace {
+
+int getHexWeight(sal_Unicode c) {
+ return c >= '0' && c <= '9' ? static_cast< int >(c - '0')
+ : c >= 'A' && c <= 'F' ? static_cast< int >(c - 'A' + 10)
+ : c >= 'a' && c <= 'f' ? static_cast< int >(c - 'a' + 10)
+ : -1;
+}
+
+int parseEscaped(rtl::OUString const & part, sal_Int32 * index) {
+ if (part.getLength() - *index < 3 || part[*index] != '%') {
+ return -1;
+ }
+ int n1 = getHexWeight(part[*index + 1]);
+ int n2 = getHexWeight(part[*index + 2]);
+ if (n1 < 0 || n2 < 0) {
+ return -1;
+ }
+ *index += 3;
+ return (n1 << 4) | n2;
+}
+
+rtl::OUString parsePart(
+ rtl::OUString const & part, bool namePart, sal_Int32 * index)
+{
+ rtl::OUStringBuffer buf;
+ while (*index < part.getLength()) {
+ sal_Unicode c = part[*index];
+ if (namePart ? c == '?' : c == '&' || c == '=') {
+ break;
+ } else if (c == '%') {
+ sal_Int32 i = *index;
+ int n = parseEscaped(part, &i);
+ if (n >= 0 && n <= 0x7F) {
+ buf.append(static_cast< sal_Unicode >(n));
+ } else if (n >= 0xC0 && n <= 0xFC) {
+ sal_Int32 encoded;
+ int shift;
+ sal_Int32 min;
+ if (n <= 0xDF) {
+ encoded = (n & 0x1F) << 6;
+ shift = 0;
+ min = 0x80;
+ } else if (n <= 0xEF) {
+ encoded = (n & 0x0F) << 12;
+ shift = 6;
+ min = 0x800;
+ } else if (n <= 0xF7) {
+ encoded = (n & 0x07) << 18;
+ shift = 12;
+ min = 0x10000;
+ } else if (n <= 0xFB) {
+ encoded = (n & 0x03) << 24;
+ shift = 18;
+ min = 0x200000;
+ } else {
+ encoded = 0;
+ shift = 24;
+ min = 0x4000000;
+ }
+ bool utf8 = true;
+ for (; shift >= 0; shift -= 6) {
+ n = parseEscaped(part, &i);
+ if (n < 0x80 || n > 0xBF) {
+ utf8 = false;
+ break;
+ }
+ encoded |= (n & 0x3F) << shift;
+ }
+ if (!utf8 || encoded < min
+ || (encoded >= 0xD800 && encoded <= 0xDFFF)
+ || encoded > 0x10FFFF)
+ {
+ break;
+ }
+ if (encoded <= 0xFFFF) {
+ buf.append(static_cast< sal_Unicode >(encoded));
+ } else {
+ buf.append(static_cast< sal_Unicode >(
+ (encoded >> 10) | 0xD800));
+ buf.append(static_cast< sal_Unicode >(
+ (encoded & 0x3FF) | 0xDC00));
+ }
+ } else {
+ break;
+ }
+ *index = i;
+ } else {
+ buf.append(c);
+ ++*index;
+ }
+ }
+ return buf.makeStringAndClear();
+}
+
+namespace
+{
+ static rtl::OUString encodeNameOrParamFragment( rtl::OUString const & fragment )
+ {
+ static sal_Bool const aCharClass[] =
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* NameOrParamFragment */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, /* !"#$%&'()*+,-./*/
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, /*0123456789:;<=>?*/
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*@ABCDEFGHIJKLMNO*/
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, /*PQRSTUVWXYZ[\]^_*/
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*`abcdefghijklmno*/
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0 /*pqrstuvwxyz{|}~ */
+ };
+
+ return rtl::Uri::encode(
+ fragment,
+ aCharClass,
+ rtl_UriEncodeIgnoreEscapes,
+ RTL_TEXTENCODING_UTF8
+ );
+ }
+}
+
+bool parseSchemeSpecificPart(rtl::OUString const & part) {
+ sal_Int32 len = part.getLength();
+ sal_Int32 i = 0;
+ if (parsePart(part, true, &i).getLength() == 0 || part[0] == '/') {
+ return false;
+ }
+ if (i == len) {
+ return true;
+ }
+ for (;;) {
+ ++i; // skip '?' or '&'
+ if (parsePart(part, false, &i).getLength() == 0 || i == len
+ || part[i] != '=')
+ {
+ return false;
+ }
+ ++i;
+ parsePart(part, false, &i);
+ if (i == len) {
+ return true;
+ }
+ if (part[i] != '&') {
+ return false;
+ }
+ }
+}
+
+class UrlReference:
+ public cppu::WeakImplHelper1< css::uri::XVndSunStarScriptUrlReference >
+{
+public:
+ UrlReference(rtl::OUString const & scheme, rtl::OUString const & path):
+ m_base(
+ scheme, false, false, rtl::OUString(), path, false, rtl::OUString())
+ {}
+
+ virtual rtl::OUString SAL_CALL getUriReference()
+ throw (com::sun::star::uno::RuntimeException)
+ { return m_base.getUriReference(); }
+
+ virtual sal_Bool SAL_CALL isAbsolute()
+ throw (com::sun::star::uno::RuntimeException)
+ { return m_base.isAbsolute(); }
+
+ virtual rtl::OUString SAL_CALL getScheme()
+ throw (com::sun::star::uno::RuntimeException)
+ { return m_base.getScheme(); }
+
+ virtual rtl::OUString SAL_CALL getSchemeSpecificPart()
+ throw (com::sun::star::uno::RuntimeException)
+ { return m_base.getSchemeSpecificPart(); }
+
+ virtual sal_Bool SAL_CALL isHierarchical()
+ throw (com::sun::star::uno::RuntimeException)
+ { return m_base.isHierarchical(); }
+
+ virtual sal_Bool SAL_CALL hasAuthority()
+ throw (com::sun::star::uno::RuntimeException)
+ { return m_base.hasAuthority(); }
+
+ virtual rtl::OUString SAL_CALL getAuthority()
+ throw (com::sun::star::uno::RuntimeException)
+ { return m_base.getAuthority(); }
+
+ virtual rtl::OUString SAL_CALL getPath()
+ throw (com::sun::star::uno::RuntimeException)
+ { return m_base.getPath(); }
+
+ virtual sal_Bool SAL_CALL hasRelativePath()
+ throw (com::sun::star::uno::RuntimeException)
+ { return m_base.hasRelativePath(); }
+
+ virtual sal_Int32 SAL_CALL getPathSegmentCount()
+ throw (com::sun::star::uno::RuntimeException)
+ { return m_base.getPathSegmentCount(); }
+
+ virtual rtl::OUString SAL_CALL getPathSegment(sal_Int32 index)
+ throw (com::sun::star::uno::RuntimeException)
+ { return m_base.getPathSegment(index); }
+
+ virtual sal_Bool SAL_CALL hasQuery()
+ throw (com::sun::star::uno::RuntimeException)
+ { return m_base.hasQuery(); }
+
+ virtual rtl::OUString SAL_CALL getQuery()
+ throw (com::sun::star::uno::RuntimeException)
+ { return m_base.getQuery(); }
+
+ virtual sal_Bool SAL_CALL hasFragment()
+ throw (com::sun::star::uno::RuntimeException)
+ { return m_base.hasFragment(); }
+
+ virtual rtl::OUString SAL_CALL getFragment()
+ throw (com::sun::star::uno::RuntimeException)
+ { return m_base.getFragment(); }
+
+ virtual void SAL_CALL setFragment(rtl::OUString const & fragment)
+ throw (com::sun::star::uno::RuntimeException)
+ { m_base.setFragment(fragment); }
+
+ virtual void SAL_CALL clearFragment()
+ throw (com::sun::star::uno::RuntimeException)
+ { m_base.clearFragment(); }
+
+ virtual rtl::OUString SAL_CALL getName() throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL setName(rtl::OUString const & name)
+ throw (css::uno::RuntimeException, css::lang::IllegalArgumentException);
+
+ virtual sal_Bool SAL_CALL hasParameter(rtl::OUString const & key)
+ throw (css::uno::RuntimeException);
+
+ virtual rtl::OUString SAL_CALL getParameter(rtl::OUString const & key)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL setParameter(rtl::OUString const & key, rtl::OUString const & value)
+ throw (css::uno::RuntimeException, css::lang::IllegalArgumentException);
+
+private:
+ UrlReference(UrlReference &); // not implemented
+ void operator =(UrlReference); // not implemented
+
+ virtual ~UrlReference() {}
+
+ sal_Int32 findParameter(rtl::OUString const & key);
+
+ stoc::uriproc::UriReference m_base;
+};
+
+rtl::OUString UrlReference::getName() throw (css::uno::RuntimeException) {
+ osl::MutexGuard g(m_base.m_mutex);
+ sal_Int32 i = 0;
+ return parsePart(m_base.m_path, true, &i);
+}
+
+void SAL_CALL UrlReference::setName(rtl::OUString const & name) throw (css::uno::RuntimeException, css::lang::IllegalArgumentException)
+{
+ if (name.getLength() == 0)
+ throw css::lang::IllegalArgumentException(
+ ::rtl::OUString(), *this, 1);
+
+ osl::MutexGuard g(m_base.m_mutex);
+ sal_Int32 i = 0;
+ parsePart(m_base.m_path, true, &i);
+
+ rtl::OUStringBuffer newPath;
+ newPath.append(encodeNameOrParamFragment(name));
+ newPath.append(m_base.m_path.copy(i));
+ m_base.m_path = newPath.makeStringAndClear();
+}
+
+sal_Bool UrlReference::hasParameter(rtl::OUString const & key)
+ throw (css::uno::RuntimeException)
+{
+ osl::MutexGuard g(m_base.m_mutex);
+ return findParameter(key) >= 0;
+}
+
+rtl::OUString UrlReference::getParameter(rtl::OUString const & key)
+ throw (css::uno::RuntimeException)
+{
+ osl::MutexGuard g(m_base.m_mutex);
+ sal_Int32 i = findParameter(key);
+ return i >= 0 ? parsePart(m_base.m_path, false, &i) : rtl::OUString();
+}
+
+void UrlReference::setParameter(rtl::OUString const & key, rtl::OUString const & value)
+ throw (css::uno::RuntimeException, css::lang::IllegalArgumentException)
+{
+ if (key.getLength() == 0)
+ throw css::lang::IllegalArgumentException(
+ ::rtl::OUString(), *this, 1);
+
+ osl::MutexGuard g(m_base.m_mutex);
+ sal_Int32 i = findParameter(key);
+ bool bExistent = ( i>=0 );
+ if (!bExistent) {
+ i = m_base.m_path.getLength();
+ }
+
+ rtl::OUStringBuffer newPath;
+ newPath.append(m_base.m_path.copy(0, i));
+ if (!bExistent) {
+ newPath.append(sal_Unicode(m_base.m_path.indexOf('?') < 0 ? '?' : '&'));
+ newPath.append(encodeNameOrParamFragment(key));
+ newPath.append(sal_Unicode('='));
+ }
+ newPath.append(encodeNameOrParamFragment(value));
+ if (bExistent) {
+ /*oldValue = */
+ parsePart(m_base.m_path, false, &i); // skip key
+ newPath.append(m_base.m_path.copy(i));
+ }
+
+ m_base.m_path = newPath.makeStringAndClear();
+}
+
+sal_Int32 UrlReference::findParameter(rtl::OUString const & key) {
+ sal_Int32 i = 0;
+ parsePart(m_base.m_path, true, &i); // skip name
+ for (;;) {
+ if (i == m_base.m_path.getLength()) {
+ return -1;
+ }
+ ++i; // skip '?' or '&'
+ rtl::OUString k = parsePart(m_base.m_path, false, &i);
+ ++i; // skip '='
+ if (k == key) {
+ return i;
+ }
+ parsePart(m_base.m_path, false, &i); // skip value
+ }
+}
+
+class Parser: public cppu::WeakImplHelper2<
+ css::lang::XServiceInfo, css::uri::XUriSchemeParser >
+{
+public:
+ Parser() {}
+
+ virtual rtl::OUString SAL_CALL getImplementationName()
+ throw (css::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL supportsService(rtl::OUString const & serviceName)
+ throw (css::uno::RuntimeException);
+
+ virtual css::uno::Sequence< rtl::OUString > SAL_CALL
+ getSupportedServiceNames() throw (css::uno::RuntimeException);
+
+ virtual css::uno::Reference< css::uri::XUriReference > SAL_CALL
+ parse(
+ rtl::OUString const & scheme, rtl::OUString const & schemeSpecificPart)
+ throw (css::uno::RuntimeException);
+
+private:
+ Parser(Parser &); // not implemented
+ void operator =(Parser); // not implemented
+
+ virtual ~Parser() {}
+};
+
+rtl::OUString Parser::getImplementationName()
+ throw (css::uno::RuntimeException)
+{
+ return stoc_services::UriSchemeParser_vndDOTsunDOTstarDOTscript::
+ getImplementationName();
+}
+
+sal_Bool Parser::supportsService(rtl::OUString const & serviceName)
+ throw (css::uno::RuntimeException)
+{
+ return stoc::uriproc::supportsService(
+ getSupportedServiceNames(), serviceName);
+}
+
+css::uno::Sequence< rtl::OUString > Parser::getSupportedServiceNames()
+ throw (css::uno::RuntimeException)
+{
+ return stoc_services::UriSchemeParser_vndDOTsunDOTstarDOTscript::
+ getSupportedServiceNames();
+}
+
+css::uno::Reference< css::uri::XUriReference >
+Parser::parse(
+ rtl::OUString const & scheme, rtl::OUString const & schemeSpecificPart)
+ throw (css::uno::RuntimeException)
+{
+ if (!parseSchemeSpecificPart(schemeSpecificPart)) {
+ return 0;
+ }
+ try {
+ return new UrlReference(scheme, schemeSpecificPart);
+ } catch (std::bad_alloc &) {
+ throw css::uno::RuntimeException(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("std::bad_alloc")), 0);
+ }
+}
+
+}
+
+namespace stoc_services {
+namespace UriSchemeParser_vndDOTsunDOTstarDOTscript {
+
+css::uno::Reference< css::uno::XInterface > create(
+ css::uno::Reference< css::uno::XComponentContext > const &)
+ SAL_THROW((css::uno::Exception))
+{
+ //TODO: single instance
+ try {
+ return static_cast< cppu::OWeakObject * >(new Parser);
+ } catch (std::bad_alloc &) {
+ throw css::uno::RuntimeException(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("std::bad_alloc")), 0);
+ }
+}
+
+rtl::OUString getImplementationName() {
+ return rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.uri.UriSchemeParser_vndDOTsunDOTstarDOTscript"));
+}
+
+css::uno::Sequence< rtl::OUString > getSupportedServiceNames() {
+ css::uno::Sequence< rtl::OUString > s(1);
+ s[0] = rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uri.UriSchemeParser_vndDOTsunDOTstarDOTscript"));
+ return s;
+}
+
+} }
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */