1*647a425cSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*647a425cSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*647a425cSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*647a425cSAndrew Rist  * distributed with this work for additional information
6*647a425cSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*647a425cSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*647a425cSAndrew Rist  * "License"); you may not use this file except in compliance
9*647a425cSAndrew Rist  * with the License.  You may obtain a copy of the License at
10*647a425cSAndrew Rist  *
11*647a425cSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*647a425cSAndrew Rist  *
13*647a425cSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*647a425cSAndrew Rist  * software distributed under the License is distributed on an
15*647a425cSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*647a425cSAndrew Rist  * KIND, either express or implied.  See the License for the
17*647a425cSAndrew Rist  * specific language governing permissions and limitations
18*647a425cSAndrew Rist  * under the License.
19*647a425cSAndrew Rist  *
20*647a425cSAndrew Rist  *************************************************************/
21*647a425cSAndrew Rist 
22*647a425cSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_stoc.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include "stocservices.hxx"
28cdf0e10cSrcweir 
29cdf0e10cSrcweir #include "UriReference.hxx"
30cdf0e10cSrcweir #include "supportsService.hxx"
31cdf0e10cSrcweir 
32cdf0e10cSrcweir #include "com/sun/star/lang/IllegalArgumentException.hpp"
33cdf0e10cSrcweir #include "com/sun/star/lang/XServiceInfo.hpp"
34cdf0e10cSrcweir #include "com/sun/star/uno/Reference.hxx"
35cdf0e10cSrcweir #include "com/sun/star/uno/RuntimeException.hpp"
36cdf0e10cSrcweir #include "com/sun/star/uno/Sequence.hxx"
37cdf0e10cSrcweir #include "com/sun/star/uno/XInterface.hpp"
38cdf0e10cSrcweir #include "com/sun/star/uri/XUriReference.hpp"
39cdf0e10cSrcweir #include "com/sun/star/uri/XUriSchemeParser.hpp"
40cdf0e10cSrcweir #include "com/sun/star/uri/XVndSunStarScriptUrlReference.hpp"
41cdf0e10cSrcweir #include "cppuhelper/implbase1.hxx"
42cdf0e10cSrcweir #include "cppuhelper/implbase2.hxx"
43cdf0e10cSrcweir #include "cppuhelper/weak.hxx"
44cdf0e10cSrcweir #include "osl/mutex.hxx"
45cdf0e10cSrcweir #include "rtl/uri.hxx"
46cdf0e10cSrcweir #include "rtl/ustrbuf.hxx"
47cdf0e10cSrcweir #include "rtl/ustring.hxx"
48cdf0e10cSrcweir #include "sal/types.h"
49cdf0e10cSrcweir 
50cdf0e10cSrcweir #include <new>
51cdf0e10cSrcweir 
52cdf0e10cSrcweir namespace css = com::sun::star;
53cdf0e10cSrcweir 
54cdf0e10cSrcweir namespace {
55cdf0e10cSrcweir 
getHexWeight(sal_Unicode c)56cdf0e10cSrcweir int getHexWeight(sal_Unicode c) {
57cdf0e10cSrcweir     return c >= '0' && c <= '9' ? static_cast< int >(c - '0')
58cdf0e10cSrcweir         : c >= 'A' && c <= 'F' ? static_cast< int >(c - 'A' + 10)
59cdf0e10cSrcweir         : c >= 'a' && c <= 'f' ? static_cast< int >(c - 'a' + 10)
60cdf0e10cSrcweir         : -1;
61cdf0e10cSrcweir }
62cdf0e10cSrcweir 
parseEscaped(rtl::OUString const & part,sal_Int32 * index)63cdf0e10cSrcweir int parseEscaped(rtl::OUString const & part, sal_Int32 * index) {
64cdf0e10cSrcweir     if (part.getLength() - *index < 3 || part[*index] != '%') {
65cdf0e10cSrcweir         return -1;
66cdf0e10cSrcweir     }
67cdf0e10cSrcweir     int n1 = getHexWeight(part[*index + 1]);
68cdf0e10cSrcweir     int n2 = getHexWeight(part[*index + 2]);
69cdf0e10cSrcweir     if (n1 < 0 || n2 < 0) {
70cdf0e10cSrcweir         return -1;
71cdf0e10cSrcweir     }
72cdf0e10cSrcweir     *index += 3;
73cdf0e10cSrcweir     return (n1 << 4) | n2;
74cdf0e10cSrcweir }
75cdf0e10cSrcweir 
parsePart(rtl::OUString const & part,bool namePart,sal_Int32 * index)76cdf0e10cSrcweir rtl::OUString parsePart(
77cdf0e10cSrcweir     rtl::OUString const & part, bool namePart, sal_Int32 * index)
78cdf0e10cSrcweir {
79cdf0e10cSrcweir     rtl::OUStringBuffer buf;
80cdf0e10cSrcweir     while (*index < part.getLength()) {
81cdf0e10cSrcweir         sal_Unicode c = part[*index];
82cdf0e10cSrcweir         if (namePart ? c == '?' : c == '&' || c == '=') {
83cdf0e10cSrcweir             break;
84cdf0e10cSrcweir         } else if (c == '%') {
85cdf0e10cSrcweir             sal_Int32 i = *index;
86cdf0e10cSrcweir             int n = parseEscaped(part, &i);
87cdf0e10cSrcweir             if (n >= 0 && n <= 0x7F) {
88cdf0e10cSrcweir                 buf.append(static_cast< sal_Unicode >(n));
89cdf0e10cSrcweir             } else if (n >= 0xC0 && n <= 0xFC) {
90cdf0e10cSrcweir                 sal_Int32 encoded;
91cdf0e10cSrcweir                 int shift;
92cdf0e10cSrcweir                 sal_Int32 min;
93cdf0e10cSrcweir                 if (n <= 0xDF) {
94cdf0e10cSrcweir                     encoded = (n & 0x1F) << 6;
95cdf0e10cSrcweir                     shift = 0;
96cdf0e10cSrcweir                     min = 0x80;
97cdf0e10cSrcweir                 } else if (n <= 0xEF) {
98cdf0e10cSrcweir                     encoded = (n & 0x0F) << 12;
99cdf0e10cSrcweir                     shift = 6;
100cdf0e10cSrcweir                     min = 0x800;
101cdf0e10cSrcweir                 } else if (n <= 0xF7) {
102cdf0e10cSrcweir                     encoded = (n & 0x07) << 18;
103cdf0e10cSrcweir                     shift = 12;
104cdf0e10cSrcweir                     min = 0x10000;
105cdf0e10cSrcweir                 } else if (n <= 0xFB) {
106cdf0e10cSrcweir                     encoded = (n & 0x03) << 24;
107cdf0e10cSrcweir                     shift = 18;
108cdf0e10cSrcweir                     min = 0x200000;
109cdf0e10cSrcweir                 } else {
110cdf0e10cSrcweir                     encoded = 0;
111cdf0e10cSrcweir                     shift = 24;
112cdf0e10cSrcweir                     min = 0x4000000;
113cdf0e10cSrcweir                 }
114cdf0e10cSrcweir                 bool utf8 = true;
115cdf0e10cSrcweir                 for (; shift >= 0; shift -= 6) {
116cdf0e10cSrcweir                     n = parseEscaped(part, &i);
117cdf0e10cSrcweir                     if (n < 0x80 || n > 0xBF) {
118cdf0e10cSrcweir                         utf8 = false;
119cdf0e10cSrcweir                         break;
120cdf0e10cSrcweir                     }
121cdf0e10cSrcweir                     encoded |= (n & 0x3F) << shift;
122cdf0e10cSrcweir                 }
123cdf0e10cSrcweir                 if (!utf8 || encoded < min
124cdf0e10cSrcweir                     || (encoded >= 0xD800 && encoded <= 0xDFFF)
125cdf0e10cSrcweir                     || encoded > 0x10FFFF)
126cdf0e10cSrcweir                 {
127cdf0e10cSrcweir                     break;
128cdf0e10cSrcweir                 }
129cdf0e10cSrcweir                 if (encoded <= 0xFFFF) {
130cdf0e10cSrcweir                     buf.append(static_cast< sal_Unicode >(encoded));
131cdf0e10cSrcweir                 } else {
132cdf0e10cSrcweir                     buf.append(static_cast< sal_Unicode >(
133cdf0e10cSrcweir                         (encoded >> 10) | 0xD800));
134cdf0e10cSrcweir                     buf.append(static_cast< sal_Unicode >(
135cdf0e10cSrcweir                         (encoded & 0x3FF) | 0xDC00));
136cdf0e10cSrcweir                 }
137cdf0e10cSrcweir             } else {
138cdf0e10cSrcweir                 break;
139cdf0e10cSrcweir             }
140cdf0e10cSrcweir             *index = i;
141cdf0e10cSrcweir         } else {
142cdf0e10cSrcweir             buf.append(c);
143cdf0e10cSrcweir             ++*index;
144cdf0e10cSrcweir         }
145cdf0e10cSrcweir     }
146cdf0e10cSrcweir     return buf.makeStringAndClear();
147cdf0e10cSrcweir }
148cdf0e10cSrcweir 
149cdf0e10cSrcweir namespace
150cdf0e10cSrcweir {
encodeNameOrParamFragment(rtl::OUString const & fragment)151cdf0e10cSrcweir     static rtl::OUString encodeNameOrParamFragment( rtl::OUString const & fragment )
152cdf0e10cSrcweir     {
153cdf0e10cSrcweir         static sal_Bool const aCharClass[] =
154cdf0e10cSrcweir         { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* NameOrParamFragment */
155cdf0e10cSrcweir           0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
156cdf0e10cSrcweir           0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, /* !"#$%&'()*+,-./*/
157cdf0e10cSrcweir           1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, /*0123456789:;<=>?*/
158cdf0e10cSrcweir           1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*@ABCDEFGHIJKLMNO*/
159cdf0e10cSrcweir           1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, /*PQRSTUVWXYZ[\]^_*/
160cdf0e10cSrcweir           0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*`abcdefghijklmno*/
161cdf0e10cSrcweir           1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0  /*pqrstuvwxyz{|}~ */
162cdf0e10cSrcweir         };
163cdf0e10cSrcweir 
164cdf0e10cSrcweir         return rtl::Uri::encode(
165cdf0e10cSrcweir             fragment,
166cdf0e10cSrcweir             aCharClass,
167cdf0e10cSrcweir             rtl_UriEncodeIgnoreEscapes,
168cdf0e10cSrcweir             RTL_TEXTENCODING_UTF8
169cdf0e10cSrcweir         );
170cdf0e10cSrcweir     }
171cdf0e10cSrcweir }
172cdf0e10cSrcweir 
parseSchemeSpecificPart(rtl::OUString const & part)173cdf0e10cSrcweir bool parseSchemeSpecificPart(rtl::OUString const & part) {
174cdf0e10cSrcweir     sal_Int32 len = part.getLength();
175cdf0e10cSrcweir     sal_Int32 i = 0;
176cdf0e10cSrcweir     if (parsePart(part, true, &i).getLength() == 0 || part[0] == '/') {
177cdf0e10cSrcweir         return false;
178cdf0e10cSrcweir     }
179cdf0e10cSrcweir     if (i == len) {
180cdf0e10cSrcweir         return true;
181cdf0e10cSrcweir     }
182cdf0e10cSrcweir     for (;;) {
183cdf0e10cSrcweir         ++i; // skip '?' or '&'
184cdf0e10cSrcweir         if (parsePart(part, false, &i).getLength() == 0 || i == len
185cdf0e10cSrcweir             || part[i] != '=')
186cdf0e10cSrcweir         {
187cdf0e10cSrcweir             return false;
188cdf0e10cSrcweir         }
189cdf0e10cSrcweir         ++i;
190cdf0e10cSrcweir         parsePart(part, false, &i);
191cdf0e10cSrcweir         if (i == len) {
192cdf0e10cSrcweir             return true;
193cdf0e10cSrcweir         }
194cdf0e10cSrcweir         if (part[i] != '&') {
195cdf0e10cSrcweir             return false;
196cdf0e10cSrcweir         }
197cdf0e10cSrcweir     }
198cdf0e10cSrcweir }
199cdf0e10cSrcweir 
200cdf0e10cSrcweir class UrlReference:
201cdf0e10cSrcweir     public cppu::WeakImplHelper1< css::uri::XVndSunStarScriptUrlReference >
202cdf0e10cSrcweir {
203cdf0e10cSrcweir public:
UrlReference(rtl::OUString const & scheme,rtl::OUString const & path)204cdf0e10cSrcweir     UrlReference(rtl::OUString const & scheme, rtl::OUString const & path):
205cdf0e10cSrcweir         m_base(
206cdf0e10cSrcweir             scheme, false, false, rtl::OUString(), path, false, rtl::OUString())
207cdf0e10cSrcweir     {}
208cdf0e10cSrcweir 
getUriReference()209cdf0e10cSrcweir     virtual rtl::OUString SAL_CALL getUriReference()
210cdf0e10cSrcweir         throw (com::sun::star::uno::RuntimeException)
211cdf0e10cSrcweir     { return m_base.getUriReference(); }
212cdf0e10cSrcweir 
isAbsolute()213cdf0e10cSrcweir     virtual sal_Bool SAL_CALL isAbsolute()
214cdf0e10cSrcweir         throw (com::sun::star::uno::RuntimeException)
215cdf0e10cSrcweir     { return m_base.isAbsolute(); }
216cdf0e10cSrcweir 
getScheme()217cdf0e10cSrcweir     virtual rtl::OUString SAL_CALL getScheme()
218cdf0e10cSrcweir         throw (com::sun::star::uno::RuntimeException)
219cdf0e10cSrcweir     { return m_base.getScheme(); }
220cdf0e10cSrcweir 
getSchemeSpecificPart()221cdf0e10cSrcweir     virtual rtl::OUString SAL_CALL getSchemeSpecificPart()
222cdf0e10cSrcweir         throw (com::sun::star::uno::RuntimeException)
223cdf0e10cSrcweir     { return m_base.getSchemeSpecificPart(); }
224cdf0e10cSrcweir 
isHierarchical()225cdf0e10cSrcweir     virtual sal_Bool SAL_CALL isHierarchical()
226cdf0e10cSrcweir         throw (com::sun::star::uno::RuntimeException)
227cdf0e10cSrcweir     { return m_base.isHierarchical(); }
228cdf0e10cSrcweir 
hasAuthority()229cdf0e10cSrcweir     virtual sal_Bool SAL_CALL hasAuthority()
230cdf0e10cSrcweir         throw (com::sun::star::uno::RuntimeException)
231cdf0e10cSrcweir     { return m_base.hasAuthority(); }
232cdf0e10cSrcweir 
getAuthority()233cdf0e10cSrcweir     virtual rtl::OUString SAL_CALL getAuthority()
234cdf0e10cSrcweir         throw (com::sun::star::uno::RuntimeException)
235cdf0e10cSrcweir     { return m_base.getAuthority(); }
236cdf0e10cSrcweir 
getPath()237cdf0e10cSrcweir     virtual rtl::OUString SAL_CALL getPath()
238cdf0e10cSrcweir         throw (com::sun::star::uno::RuntimeException)
239cdf0e10cSrcweir     { return m_base.getPath(); }
240cdf0e10cSrcweir 
hasRelativePath()241cdf0e10cSrcweir     virtual sal_Bool SAL_CALL hasRelativePath()
242cdf0e10cSrcweir         throw (com::sun::star::uno::RuntimeException)
243cdf0e10cSrcweir     { return m_base.hasRelativePath(); }
244cdf0e10cSrcweir 
getPathSegmentCount()245cdf0e10cSrcweir     virtual sal_Int32 SAL_CALL getPathSegmentCount()
246cdf0e10cSrcweir         throw (com::sun::star::uno::RuntimeException)
247cdf0e10cSrcweir     { return m_base.getPathSegmentCount(); }
248cdf0e10cSrcweir 
getPathSegment(sal_Int32 index)249cdf0e10cSrcweir     virtual rtl::OUString SAL_CALL getPathSegment(sal_Int32 index)
250cdf0e10cSrcweir         throw (com::sun::star::uno::RuntimeException)
251cdf0e10cSrcweir     { return m_base.getPathSegment(index); }
252cdf0e10cSrcweir 
hasQuery()253cdf0e10cSrcweir     virtual sal_Bool SAL_CALL hasQuery()
254cdf0e10cSrcweir         throw (com::sun::star::uno::RuntimeException)
255cdf0e10cSrcweir     { return m_base.hasQuery(); }
256cdf0e10cSrcweir 
getQuery()257cdf0e10cSrcweir     virtual rtl::OUString SAL_CALL getQuery()
258cdf0e10cSrcweir         throw (com::sun::star::uno::RuntimeException)
259cdf0e10cSrcweir     { return m_base.getQuery(); }
260cdf0e10cSrcweir 
hasFragment()261cdf0e10cSrcweir     virtual sal_Bool SAL_CALL hasFragment()
262cdf0e10cSrcweir         throw (com::sun::star::uno::RuntimeException)
263cdf0e10cSrcweir     { return m_base.hasFragment(); }
264cdf0e10cSrcweir 
getFragment()265cdf0e10cSrcweir     virtual rtl::OUString SAL_CALL getFragment()
266cdf0e10cSrcweir         throw (com::sun::star::uno::RuntimeException)
267cdf0e10cSrcweir     { return m_base.getFragment(); }
268cdf0e10cSrcweir 
setFragment(rtl::OUString const & fragment)269cdf0e10cSrcweir     virtual void SAL_CALL setFragment(rtl::OUString const & fragment)
270cdf0e10cSrcweir         throw (com::sun::star::uno::RuntimeException)
271cdf0e10cSrcweir     { m_base.setFragment(fragment); }
272cdf0e10cSrcweir 
clearFragment()273cdf0e10cSrcweir     virtual void SAL_CALL clearFragment()
274cdf0e10cSrcweir         throw (com::sun::star::uno::RuntimeException)
275cdf0e10cSrcweir     { m_base.clearFragment(); }
276cdf0e10cSrcweir 
277cdf0e10cSrcweir     virtual rtl::OUString SAL_CALL getName() throw (css::uno::RuntimeException);
278cdf0e10cSrcweir 
279cdf0e10cSrcweir     virtual void SAL_CALL setName(rtl::OUString const & name)
280cdf0e10cSrcweir         throw (css::uno::RuntimeException, css::lang::IllegalArgumentException);
281cdf0e10cSrcweir 
282cdf0e10cSrcweir     virtual sal_Bool SAL_CALL hasParameter(rtl::OUString const & key)
283cdf0e10cSrcweir         throw (css::uno::RuntimeException);
284cdf0e10cSrcweir 
285cdf0e10cSrcweir     virtual rtl::OUString SAL_CALL getParameter(rtl::OUString const & key)
286cdf0e10cSrcweir         throw (css::uno::RuntimeException);
287cdf0e10cSrcweir 
288cdf0e10cSrcweir     virtual void SAL_CALL setParameter(rtl::OUString const & key, rtl::OUString const & value)
289cdf0e10cSrcweir         throw (css::uno::RuntimeException, css::lang::IllegalArgumentException);
290cdf0e10cSrcweir 
291cdf0e10cSrcweir private:
292cdf0e10cSrcweir     UrlReference(UrlReference &); // not implemented
293cdf0e10cSrcweir     void operator =(UrlReference); // not implemented
294cdf0e10cSrcweir 
~UrlReference()295cdf0e10cSrcweir     virtual ~UrlReference() {}
296cdf0e10cSrcweir 
297cdf0e10cSrcweir     sal_Int32 findParameter(rtl::OUString const & key);
298cdf0e10cSrcweir 
299cdf0e10cSrcweir     stoc::uriproc::UriReference m_base;
300cdf0e10cSrcweir };
301cdf0e10cSrcweir 
getName()302cdf0e10cSrcweir rtl::OUString UrlReference::getName() throw (css::uno::RuntimeException) {
303cdf0e10cSrcweir     osl::MutexGuard g(m_base.m_mutex);
304cdf0e10cSrcweir     sal_Int32 i = 0;
305cdf0e10cSrcweir     return parsePart(m_base.m_path, true, &i);
306cdf0e10cSrcweir }
307cdf0e10cSrcweir 
setName(rtl::OUString const & name)308cdf0e10cSrcweir void SAL_CALL UrlReference::setName(rtl::OUString const & name) throw (css::uno::RuntimeException, css::lang::IllegalArgumentException)
309cdf0e10cSrcweir {
310cdf0e10cSrcweir     if (name.getLength() == 0)
311cdf0e10cSrcweir         throw css::lang::IllegalArgumentException(
312cdf0e10cSrcweir             ::rtl::OUString(), *this, 1);
313cdf0e10cSrcweir 
314cdf0e10cSrcweir     osl::MutexGuard g(m_base.m_mutex);
315cdf0e10cSrcweir     sal_Int32 i = 0;
316cdf0e10cSrcweir     parsePart(m_base.m_path, true, &i);
317cdf0e10cSrcweir 
318cdf0e10cSrcweir     rtl::OUStringBuffer newPath;
319cdf0e10cSrcweir     newPath.append(encodeNameOrParamFragment(name));
320cdf0e10cSrcweir     newPath.append(m_base.m_path.copy(i));
321cdf0e10cSrcweir     m_base.m_path = newPath.makeStringAndClear();
322cdf0e10cSrcweir }
323cdf0e10cSrcweir 
hasParameter(rtl::OUString const & key)324cdf0e10cSrcweir sal_Bool UrlReference::hasParameter(rtl::OUString const & key)
325cdf0e10cSrcweir     throw (css::uno::RuntimeException)
326cdf0e10cSrcweir {
327cdf0e10cSrcweir     osl::MutexGuard g(m_base.m_mutex);
328cdf0e10cSrcweir     return findParameter(key) >= 0;
329cdf0e10cSrcweir }
330cdf0e10cSrcweir 
getParameter(rtl::OUString const & key)331cdf0e10cSrcweir rtl::OUString UrlReference::getParameter(rtl::OUString const & key)
332cdf0e10cSrcweir     throw (css::uno::RuntimeException)
333cdf0e10cSrcweir {
334cdf0e10cSrcweir     osl::MutexGuard g(m_base.m_mutex);
335cdf0e10cSrcweir     sal_Int32 i = findParameter(key);
336cdf0e10cSrcweir     return i >= 0 ? parsePart(m_base.m_path, false, &i) : rtl::OUString();
337cdf0e10cSrcweir }
338cdf0e10cSrcweir 
setParameter(rtl::OUString const & key,rtl::OUString const & value)339cdf0e10cSrcweir void UrlReference::setParameter(rtl::OUString const & key, rtl::OUString const & value)
340cdf0e10cSrcweir     throw (css::uno::RuntimeException, css::lang::IllegalArgumentException)
341cdf0e10cSrcweir {
342cdf0e10cSrcweir     if (key.getLength() == 0)
343cdf0e10cSrcweir         throw css::lang::IllegalArgumentException(
344cdf0e10cSrcweir             ::rtl::OUString(), *this, 1);
345cdf0e10cSrcweir 
346cdf0e10cSrcweir     osl::MutexGuard g(m_base.m_mutex);
347cdf0e10cSrcweir     sal_Int32 i = findParameter(key);
348cdf0e10cSrcweir     bool bExistent = ( i>=0 );
349cdf0e10cSrcweir     if (!bExistent) {
350cdf0e10cSrcweir         i = m_base.m_path.getLength();
351cdf0e10cSrcweir     }
352cdf0e10cSrcweir 
353cdf0e10cSrcweir     rtl::OUStringBuffer newPath;
354cdf0e10cSrcweir     newPath.append(m_base.m_path.copy(0, i));
355cdf0e10cSrcweir     if (!bExistent) {
356cdf0e10cSrcweir         newPath.append(sal_Unicode(m_base.m_path.indexOf('?') < 0 ? '?' : '&'));
357cdf0e10cSrcweir         newPath.append(encodeNameOrParamFragment(key));
358cdf0e10cSrcweir         newPath.append(sal_Unicode('='));
359cdf0e10cSrcweir     }
360cdf0e10cSrcweir     newPath.append(encodeNameOrParamFragment(value));
361cdf0e10cSrcweir     if (bExistent) {
362cdf0e10cSrcweir         /*oldValue = */
363cdf0e10cSrcweir         parsePart(m_base.m_path, false, &i); // skip key
364cdf0e10cSrcweir         newPath.append(m_base.m_path.copy(i));
365cdf0e10cSrcweir     }
366cdf0e10cSrcweir 
367cdf0e10cSrcweir     m_base.m_path = newPath.makeStringAndClear();
368cdf0e10cSrcweir }
369cdf0e10cSrcweir 
findParameter(rtl::OUString const & key)370cdf0e10cSrcweir sal_Int32 UrlReference::findParameter(rtl::OUString const & key) {
371cdf0e10cSrcweir     sal_Int32 i = 0;
372cdf0e10cSrcweir     parsePart(m_base.m_path, true, &i); // skip name
373cdf0e10cSrcweir     for (;;) {
374cdf0e10cSrcweir         if (i == m_base.m_path.getLength()) {
375cdf0e10cSrcweir             return -1;
376cdf0e10cSrcweir         }
377cdf0e10cSrcweir         ++i; // skip '?' or '&'
378cdf0e10cSrcweir         rtl::OUString k = parsePart(m_base.m_path, false, &i);
379cdf0e10cSrcweir         ++i; // skip '='
380cdf0e10cSrcweir         if (k == key) {
381cdf0e10cSrcweir             return i;
382cdf0e10cSrcweir         }
383cdf0e10cSrcweir         parsePart(m_base.m_path, false, &i); // skip value
384cdf0e10cSrcweir     }
385cdf0e10cSrcweir }
386cdf0e10cSrcweir 
387cdf0e10cSrcweir class Parser: public cppu::WeakImplHelper2<
388cdf0e10cSrcweir     css::lang::XServiceInfo, css::uri::XUriSchemeParser >
389cdf0e10cSrcweir {
390cdf0e10cSrcweir public:
Parser()391cdf0e10cSrcweir     Parser() {}
392cdf0e10cSrcweir 
393cdf0e10cSrcweir     virtual rtl::OUString SAL_CALL getImplementationName()
394cdf0e10cSrcweir         throw (css::uno::RuntimeException);
395cdf0e10cSrcweir 
396cdf0e10cSrcweir     virtual sal_Bool SAL_CALL supportsService(rtl::OUString const & serviceName)
397cdf0e10cSrcweir         throw (css::uno::RuntimeException);
398cdf0e10cSrcweir 
399cdf0e10cSrcweir     virtual css::uno::Sequence< rtl::OUString > SAL_CALL
400cdf0e10cSrcweir     getSupportedServiceNames() throw (css::uno::RuntimeException);
401cdf0e10cSrcweir 
402cdf0e10cSrcweir     virtual css::uno::Reference< css::uri::XUriReference > SAL_CALL
403cdf0e10cSrcweir     parse(
404cdf0e10cSrcweir         rtl::OUString const & scheme, rtl::OUString const & schemeSpecificPart)
405cdf0e10cSrcweir         throw (css::uno::RuntimeException);
406cdf0e10cSrcweir 
407cdf0e10cSrcweir private:
408cdf0e10cSrcweir     Parser(Parser &); // not implemented
409cdf0e10cSrcweir     void operator =(Parser); // not implemented
410cdf0e10cSrcweir 
~Parser()411cdf0e10cSrcweir     virtual ~Parser() {}
412cdf0e10cSrcweir };
413cdf0e10cSrcweir 
getImplementationName()414cdf0e10cSrcweir rtl::OUString Parser::getImplementationName()
415cdf0e10cSrcweir     throw (css::uno::RuntimeException)
416cdf0e10cSrcweir {
417cdf0e10cSrcweir     return stoc_services::UriSchemeParser_vndDOTsunDOTstarDOTscript::
418cdf0e10cSrcweir         getImplementationName();
419cdf0e10cSrcweir }
420cdf0e10cSrcweir 
supportsService(rtl::OUString const & serviceName)421cdf0e10cSrcweir sal_Bool Parser::supportsService(rtl::OUString const & serviceName)
422cdf0e10cSrcweir     throw (css::uno::RuntimeException)
423cdf0e10cSrcweir {
424cdf0e10cSrcweir     return stoc::uriproc::supportsService(
425cdf0e10cSrcweir         getSupportedServiceNames(), serviceName);
426cdf0e10cSrcweir }
427cdf0e10cSrcweir 
getSupportedServiceNames()428cdf0e10cSrcweir css::uno::Sequence< rtl::OUString > Parser::getSupportedServiceNames()
429cdf0e10cSrcweir     throw (css::uno::RuntimeException)
430cdf0e10cSrcweir {
431cdf0e10cSrcweir     return stoc_services::UriSchemeParser_vndDOTsunDOTstarDOTscript::
432cdf0e10cSrcweir         getSupportedServiceNames();
433cdf0e10cSrcweir }
434cdf0e10cSrcweir 
435cdf0e10cSrcweir css::uno::Reference< css::uri::XUriReference >
parse(rtl::OUString const & scheme,rtl::OUString const & schemeSpecificPart)436cdf0e10cSrcweir Parser::parse(
437cdf0e10cSrcweir     rtl::OUString const & scheme, rtl::OUString const & schemeSpecificPart)
438cdf0e10cSrcweir     throw (css::uno::RuntimeException)
439cdf0e10cSrcweir {
440cdf0e10cSrcweir     if (!parseSchemeSpecificPart(schemeSpecificPart)) {
441cdf0e10cSrcweir         return 0;
442cdf0e10cSrcweir     }
443cdf0e10cSrcweir     try {
444cdf0e10cSrcweir         return new UrlReference(scheme, schemeSpecificPart);
445cdf0e10cSrcweir     } catch (std::bad_alloc &) {
446cdf0e10cSrcweir         throw css::uno::RuntimeException(
447cdf0e10cSrcweir             rtl::OUString::createFromAscii("std::bad_alloc"), 0);
448cdf0e10cSrcweir     }
449cdf0e10cSrcweir }
450cdf0e10cSrcweir 
451cdf0e10cSrcweir }
452cdf0e10cSrcweir 
453cdf0e10cSrcweir namespace stoc_services {
454cdf0e10cSrcweir namespace UriSchemeParser_vndDOTsunDOTstarDOTscript {
455cdf0e10cSrcweir 
create(css::uno::Reference<css::uno::XComponentContext> const &)456cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface > create(
457cdf0e10cSrcweir     css::uno::Reference< css::uno::XComponentContext > const &)
458cdf0e10cSrcweir     SAL_THROW((css::uno::Exception))
459cdf0e10cSrcweir {
460cdf0e10cSrcweir     //TODO: single instance
461cdf0e10cSrcweir     try {
462cdf0e10cSrcweir         return static_cast< cppu::OWeakObject * >(new Parser);
463cdf0e10cSrcweir     } catch (std::bad_alloc &) {
464cdf0e10cSrcweir         throw css::uno::RuntimeException(
465cdf0e10cSrcweir             rtl::OUString::createFromAscii("std::bad_alloc"), 0);
466cdf0e10cSrcweir     }
467cdf0e10cSrcweir }
468cdf0e10cSrcweir 
getImplementationName()469cdf0e10cSrcweir rtl::OUString getImplementationName() {
470cdf0e10cSrcweir     return rtl::OUString::createFromAscii(
471cdf0e10cSrcweir         "com.sun.star.comp.uri.UriSchemeParser_vndDOTsunDOTstarDOTscript");
472cdf0e10cSrcweir }
473cdf0e10cSrcweir 
getSupportedServiceNames()474cdf0e10cSrcweir css::uno::Sequence< rtl::OUString > getSupportedServiceNames() {
475cdf0e10cSrcweir     css::uno::Sequence< rtl::OUString > s(1);
476cdf0e10cSrcweir     s[0] = rtl::OUString::createFromAscii(
477cdf0e10cSrcweir         "com.sun.star.uri.UriSchemeParser_vndDOTsunDOTstarDOTscript");
478cdf0e10cSrcweir     return s;
479cdf0e10cSrcweir }
480cdf0e10cSrcweir 
481cdf0e10cSrcweir } }
482