1 /*************************************************************************
2 *
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
6 *
7 * OpenOffice.org - a multi-platform office productivity suite
8 *
9 * This file is part of OpenOffice.org.
10 *
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
14 *
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
20 *
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org.  If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
25 *
26 ************************************************************************/
27 
28 #include "precompiled_stoc.hxx"
29 #include "sal/config.h"
30 
31 #include <cstddef>
32 #include <cstdlib>
33 #include <map>
34 #include <vector>
35 
36 #include "boost/noncopyable.hpp"
37 #include "com/sun/star/container/NoSuchElementException.hpp"
38 #include "com/sun/star/registry/InvalidRegistryException.hpp"
39 #include "com/sun/star/registry/XRegistryKey.hpp"
40 #include "com/sun/star/uno/Reference.hxx"
41 #include "com/sun/star/uno/XInterface.hpp"
42 #include "cppuhelper/implbase1.hxx"
43 #include "osl/diagnose.h"
44 #include "rtl/malformeduriexception.hxx"
45 #include "rtl/ref.hxx"
46 #include "rtl/string.h"
47 #include "rtl/uri.hxx"
48 #include "rtl/ustrbuf.hxx"
49 #include "rtl/ustring.h"
50 #include "rtl/ustring.hxx"
51 #include "salhelper/simplereferenceobject.hxx"
52 #include "xmlreader/span.hxx"
53 #include "xmlreader/xmlreader.hxx"
54 
55 #include "textualservices.hxx"
56 
57 namespace stoc { namespace simpleregistry {
58 
59 namespace {
60 
61 namespace css = com::sun::star;
62 
63 struct Implementation {
64     rtl::OUString uri;
65     rtl::OUString loader;
66     std::vector< rtl::OUString > services;
67     std::vector< rtl::OUString > singletons;
68 };
69 
70 typedef std::map< rtl::OUString, Implementation > Implementations;
71 
72 typedef std::map< rtl::OUString, std::vector< rtl::OUString > >
73     ImplementationMap;
74 
75 }
76 
77 class Data: public salhelper::SimpleReferenceObject, private boost::noncopyable
78 {
79 public:
80     Implementations implementations;
81     ImplementationMap services;
82     ImplementationMap singletons;
83 };
84 
85 namespace {
86 
87 class Parser: private boost::noncopyable {
88 public:
89     Parser(rtl::OUString const & uri, rtl::Reference< Data > const & data);
90 
91 private:
92     void handleComponent();
93 
94     void handleImplementation();
95 
96     void handleService();
97 
98     void handleSingleton();
99 
100     rtl::OUString getNameAttribute();
101 
102     xmlreader::XmlReader reader_;
103     rtl::Reference< Data > data_;
104     rtl::OUString attrUri_;
105     rtl::OUString attrLoader_;
106     rtl::OUString attrImplementation_;
107 };
108 
109 Parser::Parser(rtl::OUString const & uri, rtl::Reference< Data > const & data):
110     reader_(uri), data_(data)
111 {
112     OSL_ASSERT(data.is());
113     int ucNsId = reader_.registerNamespaceIri(
114         xmlreader::Span(
115             RTL_CONSTASCII_STRINGPARAM(
116                 "http://openoffice.org/2010/uno-components")));
117     enum State {
118         STATE_BEGIN, STATE_END, STATE_COMPONENTS, STATE_COMPONENT_INITIAL,
119         STATE_COMPONENT, STATE_IMPLEMENTATION, STATE_SERVICE, STATE_SINGLETON };
120     for (State state = STATE_BEGIN;;) {
121         xmlreader::Span name;
122         int nsId;
123         xmlreader::XmlReader::Result res = reader_.nextItem(
124             xmlreader::XmlReader::TEXT_NONE, &name, &nsId);
125         switch (state) {
126         case STATE_BEGIN:
127             if (res == xmlreader::XmlReader::RESULT_BEGIN && nsId == ucNsId &&
128                 name.equals(RTL_CONSTASCII_STRINGPARAM("components")))
129             {
130                 state = STATE_COMPONENTS;
131                 break;
132             }
133             throw css::registry::InvalidRegistryException(
134                 (reader_.getUrl() +
135                  rtl::OUString(
136                      RTL_CONSTASCII_USTRINGPARAM(
137                          ": unexpected item in outer level"))),
138                 css::uno::Reference< css::uno::XInterface >());
139         case STATE_END:
140             if (res == xmlreader::XmlReader::RESULT_DONE) {
141                 return;
142             }
143             throw css::registry::InvalidRegistryException(
144                 (reader_.getUrl() +
145                  rtl::OUString(
146                      RTL_CONSTASCII_USTRINGPARAM(
147                          ": unexpected item in outer level"))),
148                 css::uno::Reference< css::uno::XInterface >());
149         case STATE_COMPONENTS:
150             if (res == xmlreader::XmlReader::RESULT_END) {
151                 state = STATE_END;
152                 break;
153             }
154             if (res == xmlreader::XmlReader::RESULT_BEGIN && nsId == ucNsId &&
155                 name.equals(RTL_CONSTASCII_STRINGPARAM("component")))
156             {
157                 handleComponent();
158                 state = STATE_COMPONENT_INITIAL;
159                 break;
160             }
161             throw css::registry::InvalidRegistryException(
162                 (reader_.getUrl() +
163                  rtl::OUString(
164                      RTL_CONSTASCII_USTRINGPARAM(
165                          ": unexpected item in <components>"))),
166                 css::uno::Reference< css::uno::XInterface >());
167         case STATE_COMPONENT:
168             if (res == xmlreader::XmlReader::RESULT_END) {
169                 state = STATE_COMPONENTS;
170                 break;
171             }
172             // fall through
173         case STATE_COMPONENT_INITIAL:
174             if (res == xmlreader::XmlReader::RESULT_BEGIN && nsId == ucNsId &&
175                 name.equals(RTL_CONSTASCII_STRINGPARAM("implementation")))
176             {
177                 handleImplementation();
178                 state = STATE_IMPLEMENTATION;
179                 break;
180             }
181             throw css::registry::InvalidRegistryException(
182                 (reader_.getUrl() +
183                  rtl::OUString(
184                      RTL_CONSTASCII_USTRINGPARAM(
185                          ": unexpected item in <component>"))),
186                 css::uno::Reference< css::uno::XInterface >());
187         case STATE_IMPLEMENTATION:
188             if (res == xmlreader::XmlReader::RESULT_END) {
189                 state = STATE_COMPONENT;
190                 break;
191             }
192             if (res == xmlreader::XmlReader::RESULT_BEGIN && nsId == ucNsId &&
193                 name.equals(RTL_CONSTASCII_STRINGPARAM("service")))
194             {
195                 handleService();
196                 state = STATE_SERVICE;
197                 break;
198             }
199             if (res == xmlreader::XmlReader::RESULT_BEGIN && nsId == ucNsId &&
200                 name.equals(RTL_CONSTASCII_STRINGPARAM("singleton")))
201             {
202                 handleSingleton();
203                 state = STATE_SINGLETON;
204                 break;
205             }
206             throw css::registry::InvalidRegistryException(
207                 (reader_.getUrl() +
208                  rtl::OUString(
209                      RTL_CONSTASCII_USTRINGPARAM(
210                          ": unexpected item in <implementation>"))),
211                 css::uno::Reference< css::uno::XInterface >());
212         case STATE_SERVICE:
213             if (res == xmlreader::XmlReader::RESULT_END) {
214                 state = STATE_IMPLEMENTATION;
215                 break;
216             }
217             throw css::registry::InvalidRegistryException(
218                 (reader_.getUrl() +
219                  rtl::OUString(
220                      RTL_CONSTASCII_USTRINGPARAM(
221                          ": unexpected item in <service>"))),
222                 css::uno::Reference< css::uno::XInterface >());
223         case STATE_SINGLETON:
224             if (res == xmlreader::XmlReader::RESULT_END) {
225                 state = STATE_IMPLEMENTATION;
226                 break;
227             }
228             throw css::registry::InvalidRegistryException(
229                 (reader_.getUrl() +
230                  rtl::OUString(
231                      RTL_CONSTASCII_USTRINGPARAM(
232                          ": unexpected item in <service>"))),
233                 css::uno::Reference< css::uno::XInterface >());
234         }
235     }
236 }
237 
238 void Parser::handleComponent() {
239     attrUri_ = rtl::OUString();
240     attrLoader_ = rtl::OUString();
241     xmlreader::Span name;
242     int nsId;
243     while (reader_.nextAttribute(&nsId, &name)) {
244         if (nsId == xmlreader::XmlReader::NAMESPACE_NONE &&
245             name.equals(RTL_CONSTASCII_STRINGPARAM("uri")))
246         {
247             if (attrUri_.getLength() != 0) {
248                 throw css::registry::InvalidRegistryException(
249                     (reader_.getUrl() +
250                      rtl::OUString(
251                          RTL_CONSTASCII_USTRINGPARAM(
252                              ": <component> has multiple \"uri\" attributes"))),
253                     css::uno::Reference< css::uno::XInterface >());
254             }
255             attrUri_ = reader_.getAttributeValue(false).convertFromUtf8();
256             if (attrUri_.getLength() == 0) {
257                 throw css::registry::InvalidRegistryException(
258                     (reader_.getUrl() +
259                      rtl::OUString(
260                          RTL_CONSTASCII_USTRINGPARAM(
261                              ": <component> has empty \"uri\" attribute"))),
262                     css::uno::Reference< css::uno::XInterface >());
263             }
264         } else if (nsId == xmlreader::XmlReader::NAMESPACE_NONE &&
265                    name.equals(RTL_CONSTASCII_STRINGPARAM("loader")))
266         {
267             if (attrLoader_.getLength() != 0) {
268                 throw css::registry::InvalidRegistryException(
269                     (reader_.getUrl() +
270                      rtl::OUString(
271                          RTL_CONSTASCII_USTRINGPARAM(
272                              ": <component> has multiple \"loader\""
273                              " attributes"))),
274                     css::uno::Reference< css::uno::XInterface >());
275             }
276             attrLoader_ = reader_.getAttributeValue(false).convertFromUtf8();
277             if (attrLoader_.getLength() == 0) {
278                 throw css::registry::InvalidRegistryException(
279                     (reader_.getUrl() +
280                      rtl::OUString(
281                          RTL_CONSTASCII_USTRINGPARAM(
282                              ": <component> has empty \"loader\" attribute"))),
283                     css::uno::Reference< css::uno::XInterface >());
284             }
285         } else {
286             throw css::registry::InvalidRegistryException(
287                 (reader_.getUrl() +
288                  rtl::OUString(
289                      RTL_CONSTASCII_USTRINGPARAM(
290                          ": expected <component> attribute \"uri\" or"
291                          " \"loader\""))),
292                 css::uno::Reference< css::uno::XInterface >());
293         }
294     }
295     if (attrUri_.getLength() == 0) {
296         throw css::registry::InvalidRegistryException(
297             (reader_.getUrl() +
298              rtl::OUString(
299                  RTL_CONSTASCII_USTRINGPARAM(
300                      ": <component> is missing \"uri\" attribute"))),
301             css::uno::Reference< css::uno::XInterface >());
302     }
303     if (attrLoader_.getLength() == 0) {
304         throw css::registry::InvalidRegistryException(
305             (reader_.getUrl() +
306              rtl::OUString(
307                  RTL_CONSTASCII_USTRINGPARAM(
308                      ": <component> is missing \"loader\" attribute"))),
309             css::uno::Reference< css::uno::XInterface >());
310     }
311     try {
312         attrUri_ = rtl::Uri::convertRelToAbs(reader_.getUrl(), attrUri_);
313     } catch (rtl::MalformedUriException & e) {
314         throw css::registry::InvalidRegistryException(
315             (reader_.getUrl() +
316              rtl::OUString(
317                  RTL_CONSTASCII_USTRINGPARAM(": bad \"uri\" attribute: ")) +
318              e.getMessage()),
319             css::uno::Reference< css::uno::XInterface >());
320     }
321 }
322 
323 void Parser::handleImplementation() {
324     attrImplementation_ = getNameAttribute();
325     if (data_->implementations.find(attrImplementation_) !=
326         data_->implementations.end())
327     {
328         throw css::registry::InvalidRegistryException(
329             (reader_.getUrl() +
330              rtl::OUString(
331                  RTL_CONSTASCII_USTRINGPARAM(
332                      ": duplicate <implementation name=\"")) +
333              attrImplementation_ +
334              rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\">"))),
335             css::uno::Reference< css::uno::XInterface >());
336     }
337     data_->implementations[attrImplementation_].uri = attrUri_;
338     data_->implementations[attrImplementation_].loader = attrLoader_;
339 }
340 
341 void Parser::handleService() {
342     rtl::OUString name = getNameAttribute();
343     data_->implementations[attrImplementation_].services.push_back(name);
344     data_->services[name].push_back(attrImplementation_);
345 }
346 
347 void Parser::handleSingleton() {
348     rtl::OUString name = getNameAttribute();
349     data_->implementations[attrImplementation_].singletons.push_back(name);
350     data_->singletons[name].push_back(attrImplementation_);
351 }
352 
353 rtl::OUString Parser::getNameAttribute() {
354     rtl::OUString attrName;
355     xmlreader::Span name;
356     int nsId;
357     while (reader_.nextAttribute(&nsId, &name)) {
358         if (nsId == xmlreader::XmlReader::NAMESPACE_NONE &&
359             name.equals(RTL_CONSTASCII_STRINGPARAM("name")))
360         {
361             if (attrName.getLength() != 0) {
362                 throw css::registry::InvalidRegistryException(
363                     (reader_.getUrl() +
364                      rtl::OUString(
365                          RTL_CONSTASCII_USTRINGPARAM(
366                              ": element has multiple \"name\" attributes"))),
367                     css::uno::Reference< css::uno::XInterface >());
368             }
369             attrName = reader_.getAttributeValue(false).convertFromUtf8();
370             if (attrName.getLength() == 0) {
371                 throw css::registry::InvalidRegistryException(
372                     (reader_.getUrl() +
373                      rtl::OUString(
374                          RTL_CONSTASCII_USTRINGPARAM(
375                              ": element has empty \"name\" attribute"))),
376                     css::uno::Reference< css::uno::XInterface >());
377             }
378         } else {
379             throw css::registry::InvalidRegistryException(
380                 (reader_.getUrl() +
381                  rtl::OUString(
382                      RTL_CONSTASCII_USTRINGPARAM(
383                          ": expected element attribute \"name\""))),
384                 css::uno::Reference< css::uno::XInterface >());
385         }
386     }
387     if (attrName.getLength() == 0) {
388         throw css::registry::InvalidRegistryException(
389             (reader_.getUrl() +
390              rtl::OUString(
391                  RTL_CONSTASCII_USTRINGPARAM(
392                      ": element is missing \"name\" attribute"))),
393             css::uno::Reference< css::uno::XInterface >());
394     }
395     return attrName;
396 }
397 
398 rtl::OUString pathToString(std::vector< rtl::OUString > const & path) {
399     rtl::OUStringBuffer buf;
400     for (std::vector< rtl::OUString >::const_iterator i(path.begin());
401          i != path.end(); ++i)
402     {
403         buf.append(sal_Unicode('/'));
404         buf.append(*i);
405     }
406     if (buf.getLength() == 0) {
407         buf.append(sal_Unicode('/'));
408     }
409     return buf.makeStringAndClear();
410 }
411 
412 class Key: public cppu::WeakImplHelper1< css::registry::XRegistryKey > {
413 public:
414     Key(
415         rtl::Reference< Data > const & data,
416         std::vector< rtl::OUString > const & path):
417         data_(data), path_(path) { OSL_ASSERT(data.is());
418  }
419 
420 private:
421     /*
422       /
423         IMPLEMENTATIONS
424           <implementation>
425             UNO
426               LOCATION utf-8
427               ACTIVATOR utf-8
428               SERVICES
429                 <service>
430                 ...
431               SINGLETONS
432                 <singleton> utf-16
433                 ...
434           ...
435         SERVICES
436           <service> utf-8-list
437           ...
438         SINGLETONS
439           <singleton> utf-16
440             REGISTERED_BY utf-8-list
441           ...
442     */
443     enum State {
444         STATE_ROOT, STATE_IMPLEMENTATIONS, STATE_IMPLEMENTATION, STATE_UNO,
445         STATE_LOCATION, STATE_ACTIVATOR, STATE_IMPLEMENTATION_SERVICES,
446         STATE_IMPLEMENTATION_SERVICE, STATE_IMPLEMENTATION_SINGLETONS,
447         STATE_IMPLEMENTATION_SINGLETON, STATE_SERVICES, STATE_SERVICE,
448         STATE_SINGLETONS, STATE_SINGLETON, STATE_REGISTEREDBY };
449 
450     virtual rtl::OUString SAL_CALL getKeyName()
451         throw (css::uno::RuntimeException);
452 
453     virtual sal_Bool SAL_CALL isReadOnly() throw (
454         css::registry::InvalidRegistryException, css::uno::RuntimeException);
455 
456     virtual sal_Bool SAL_CALL isValid() throw(css::uno::RuntimeException);
457 
458     virtual css::registry::RegistryKeyType SAL_CALL getKeyType(
459         rtl::OUString const & rKeyName)
460         throw (
461             css::registry::InvalidRegistryException,
462             css::uno::RuntimeException);
463 
464     virtual css::registry::RegistryValueType SAL_CALL getValueType() throw(
465         css::registry::InvalidRegistryException, css::uno::RuntimeException);
466 
467     virtual sal_Int32 SAL_CALL getLongValue() throw (
468         css::registry::InvalidRegistryException,
469         css::registry::InvalidValueException, css::uno::RuntimeException);
470 
471     virtual void SAL_CALL setLongValue(sal_Int32 value) throw (
472         css::registry::InvalidRegistryException, css::uno::RuntimeException);
473 
474     virtual css::uno::Sequence< sal_Int32 > SAL_CALL getLongListValue() throw(
475         css::registry::InvalidRegistryException,
476         css::registry::InvalidValueException, css::uno::RuntimeException);
477 
478     virtual void SAL_CALL setLongListValue(
479         com::sun::star::uno::Sequence< sal_Int32 > const & seqValue)
480         throw (
481             css::registry::InvalidRegistryException,
482             css::uno::RuntimeException);
483 
484     virtual rtl::OUString SAL_CALL getAsciiValue() throw (
485         css::registry::InvalidRegistryException,
486         css::registry::InvalidValueException, css::uno::RuntimeException);
487 
488     virtual void SAL_CALL setAsciiValue(rtl::OUString const & value) throw (
489         css::registry::InvalidRegistryException, css::uno::RuntimeException);
490 
491     virtual css::uno::Sequence< rtl::OUString > SAL_CALL getAsciiListValue()
492         throw (
493             css::registry::InvalidRegistryException,
494             css::registry::InvalidValueException, css::uno::RuntimeException);
495 
496     virtual void SAL_CALL setAsciiListValue(
497         css::uno::Sequence< rtl::OUString > const & seqValue)
498         throw (
499             css::registry::InvalidRegistryException,
500             css::uno::RuntimeException);
501 
502     virtual rtl::OUString SAL_CALL getStringValue() throw(
503         css::registry::InvalidRegistryException,
504         css::registry::InvalidValueException, css::uno::RuntimeException);
505 
506     virtual void SAL_CALL setStringValue(rtl::OUString const & value) throw (
507         css::registry::InvalidRegistryException, css::uno::RuntimeException);
508 
509     virtual css::uno::Sequence< rtl::OUString > SAL_CALL getStringListValue()
510         throw (
511             css::registry::InvalidRegistryException,
512             css::registry::InvalidValueException, css::uno::RuntimeException);
513 
514     virtual void SAL_CALL setStringListValue(
515         css::uno::Sequence< rtl::OUString > const & seqValue)
516         throw (
517             css::registry::InvalidRegistryException,
518             css::uno::RuntimeException);
519 
520     virtual css::uno::Sequence< sal_Int8 > SAL_CALL getBinaryValue() throw (
521         css::registry::InvalidRegistryException,
522         css::registry::InvalidValueException, css::uno::RuntimeException);
523 
524     virtual void SAL_CALL setBinaryValue(
525         css::uno::Sequence< sal_Int8 > const & value)
526         throw (
527             css::registry::InvalidRegistryException,
528             css::uno::RuntimeException);
529 
530     virtual css::uno::Reference< css::registry::XRegistryKey > SAL_CALL openKey(
531         rtl::OUString const & aKeyName)
532         throw (
533             css::registry::InvalidRegistryException,
534             css::uno::RuntimeException);
535 
536     virtual css::uno::Reference< css::registry::XRegistryKey > SAL_CALL
537     createKey(rtl::OUString const & aKeyName) throw (
538         css::registry::InvalidRegistryException, css::uno::RuntimeException);
539 
540     virtual void SAL_CALL closeKey() throw (
541         css::registry::InvalidRegistryException, css::uno::RuntimeException);
542 
543     virtual void SAL_CALL deleteKey(rtl::OUString const & rKeyName) throw (
544         css::registry::InvalidRegistryException, css::uno::RuntimeException);
545 
546     virtual
547     css::uno::Sequence< css::uno::Reference< css::registry::XRegistryKey > >
548     SAL_CALL openKeys() throw (
549         css::registry::InvalidRegistryException, css::uno::RuntimeException);
550 
551     virtual css::uno::Sequence< rtl::OUString > SAL_CALL getKeyNames() throw (
552         css::registry::InvalidRegistryException, css::uno::RuntimeException);
553 
554     virtual sal_Bool SAL_CALL createLink(
555         rtl::OUString const & aLinkName, rtl::OUString const & aLinkTarget)
556         throw (
557             css::registry::InvalidRegistryException,
558             css::uno::RuntimeException);
559 
560     virtual void SAL_CALL deleteLink(rtl::OUString const & rLinkName) throw (
561         css::registry::InvalidRegistryException, css::uno::RuntimeException);
562 
563     virtual rtl::OUString SAL_CALL getLinkTarget(
564         rtl::OUString const & rLinkName)
565         throw (
566             css::registry::InvalidRegistryException,
567             css::uno::RuntimeException);
568 
569     virtual rtl::OUString SAL_CALL getResolvedName(
570         rtl::OUString const & aKeyName)
571         throw (
572             css::registry::InvalidRegistryException,
573             css::uno::RuntimeException);
574 
575     bool find(
576         rtl::OUString const & relative, std::vector< rtl::OUString > * path,
577         State * state, css::registry::RegistryValueType * type) const;
578 
579     css::uno::Sequence< rtl::OUString > getChildren();
580 
581     rtl::Reference< Data > data_;
582     std::vector< rtl::OUString > path_;
583 };
584 
585 rtl::OUString Key::getKeyName() throw (css::uno::RuntimeException) {
586     return pathToString(path_);
587 }
588 
589 sal_Bool Key::isReadOnly()
590     throw (css::registry::InvalidRegistryException, css::uno::RuntimeException)
591 {
592     return true;
593 }
594 
595 sal_Bool Key::isValid() throw(css::uno::RuntimeException) {
596     return true;
597 }
598 
599 css::registry::RegistryKeyType Key::getKeyType(rtl::OUString const & rKeyName)
600     throw (css::registry::InvalidRegistryException, css::uno::RuntimeException)
601 {
602     if (!find(rtl::OUString(), 0, 0, 0)) {
603         throw css::registry::InvalidRegistryException(
604             (rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("unknown key ")) +
605              rKeyName),
606             static_cast< cppu::OWeakObject * >(this));
607     }
608     return css::registry::RegistryKeyType_KEY;
609 }
610 
611 css::registry::RegistryValueType Key::getValueType()
612     throw (css::registry::InvalidRegistryException, css::uno::RuntimeException)
613 {
614     css::registry::RegistryValueType type =
615         css::registry::RegistryValueType_NOT_DEFINED;
616     OSL_VERIFY(find(rtl::OUString(), 0, 0, &type));
617     return type;
618 }
619 
620 sal_Int32 Key::getLongValue() throw (
621     css::registry::InvalidRegistryException,
622     css::registry::InvalidValueException, css::uno::RuntimeException)
623 {
624     throw css::registry::InvalidValueException(
625         rtl::OUString(
626             RTL_CONSTASCII_USTRINGPARAM(
627                 "com.sun.star.registry.SimpleRegistry textual services key"
628                 " getLongValue not supported")),
629         static_cast< OWeakObject * >(this));
630 }
631 
632 void Key::setLongValue(sal_Int32)
633     throw (css::registry::InvalidRegistryException, css::uno::RuntimeException)
634 {
635     throw css::registry::InvalidRegistryException(
636         rtl::OUString(
637             RTL_CONSTASCII_USTRINGPARAM(
638                 "com.sun.star.registry.SimpleRegistry textual services key"
639                 " setLongValue not supported")),
640         static_cast< OWeakObject * >(this));
641 }
642 
643 css::uno::Sequence< sal_Int32 > Key::getLongListValue() throw (
644     css::registry::InvalidRegistryException,
645     css::registry::InvalidValueException, css::uno::RuntimeException)
646 {
647     throw css::registry::InvalidValueException(
648         rtl::OUString(
649             RTL_CONSTASCII_USTRINGPARAM(
650                 "com.sun.star.registry.SimpleRegistry textual services key"
651                 " getLongListValue not supported")),
652         static_cast< OWeakObject * >(this));
653 }
654 
655 void Key::setLongListValue(css::uno::Sequence< sal_Int32 > const &)
656     throw (css::registry::InvalidRegistryException, css::uno::RuntimeException)
657 {
658     throw css::registry::InvalidRegistryException(
659         rtl::OUString(
660             RTL_CONSTASCII_USTRINGPARAM(
661                 "com.sun.star.registry.SimpleRegistry textual services key"
662                 " setLongListValue not supported")),
663         static_cast< OWeakObject * >(this));
664 }
665 
666 rtl::OUString Key::getAsciiValue() throw (
667     css::registry::InvalidRegistryException,
668     css::registry::InvalidValueException, css::uno::RuntimeException)
669 {
670     State state = STATE_ROOT;
671     OSL_VERIFY(find(rtl::OUString(), 0, &state, 0));
672     switch (state) {
673     case STATE_LOCATION:
674         return data_->implementations[path_[1]].uri;
675     case STATE_ACTIVATOR:
676         return data_->implementations[path_[1]].loader;
677     default:
678         throw css::registry::InvalidValueException(
679             rtl::OUString(
680                 RTL_CONSTASCII_USTRINGPARAM(
681                     "com.sun.star.registry.SimpleRegistry textual services key"
682                     " getAsciiValue: wrong type")),
683             static_cast< OWeakObject * >(this));
684     }
685 }
686 
687 void Key::setAsciiValue(rtl::OUString const &)
688     throw (css::registry::InvalidRegistryException, css::uno::RuntimeException)
689 {
690     throw css::registry::InvalidRegistryException(
691         rtl::OUString(
692             RTL_CONSTASCII_USTRINGPARAM(
693                 "com.sun.star.registry.SimpleRegistry textual services key"
694                 " setAsciiValue not supported")),
695         static_cast< OWeakObject * >(this));
696 }
697 
698 css::uno::Sequence< rtl::OUString > Key::getAsciiListValue() throw (
699     css::registry::InvalidRegistryException,
700     css::registry::InvalidValueException, css::uno::RuntimeException)
701 {
702     State state = STATE_ROOT;
703     OSL_VERIFY(find(rtl::OUString(), 0, &state, 0));
704     std::vector< rtl::OUString > const * list;
705     switch (state) {
706     case STATE_SERVICE:
707         list = &data_->services[path_[1]];
708         break;
709     case STATE_REGISTEREDBY:
710         list = &data_->singletons[path_[1]];
711         break;
712     default:
713         throw css::registry::InvalidValueException(
714             rtl::OUString(
715                 RTL_CONSTASCII_USTRINGPARAM(
716                     "com.sun.star.registry.SimpleRegistry textual services key"
717                     " getAsciiListValue: wrong type")),
718             static_cast< OWeakObject * >(this));
719     }
720     if (list->size() > SAL_MAX_INT32) {
721         throw css::registry::InvalidValueException(
722             rtl::OUString(
723                 RTL_CONSTASCII_USTRINGPARAM(
724                     "com.sun.star.registry.SimpleRegistry textual services key"
725                     " getAsciiListValue: too large")),
726             static_cast< OWeakObject * >(this));
727     }
728     css::uno::Sequence< rtl::OUString > seq(
729         static_cast< sal_Int32 >(list->size()));
730     sal_Int32 i = 0;
731     for (std::vector< rtl::OUString >::const_iterator j(list->begin());
732          j != list->end(); ++j)
733     {
734         seq[i++] = *j;
735     }
736     return seq;
737 }
738 
739 void Key::setAsciiListValue(css::uno::Sequence< rtl::OUString > const &)
740     throw (css::registry::InvalidRegistryException, css::uno::RuntimeException)
741 {
742     throw css::registry::InvalidRegistryException(
743         rtl::OUString(
744             RTL_CONSTASCII_USTRINGPARAM(
745                 "com.sun.star.registry.SimpleRegistry textual services key"
746                 " setAsciiListValue not supported")),
747         static_cast< OWeakObject * >(this));
748 }
749 
750 rtl::OUString Key::getStringValue() throw (
751     css::registry::InvalidRegistryException,
752     css::registry::InvalidValueException, css::uno::RuntimeException)
753 {
754     State state = STATE_ROOT;
755     OSL_VERIFY(find(rtl::OUString(), 0, &state, 0));
756     switch (state) {
757     case STATE_IMPLEMENTATION_SINGLETON:
758     case STATE_SINGLETON:
759         throw css::registry::InvalidRegistryException(
760             rtl::OUString(
761                 RTL_CONSTASCII_USTRINGPARAM(
762                     "com.sun.star.registry.SimpleRegistry textual services key"
763                     " getStringValue: does not associate singletons with"
764                     " services")),
765             static_cast< OWeakObject * >(this));
766     default:
767         break;
768     }
769     // default case extracted from switch to avoid erroneous compiler warnings
770     // on Solaris:
771     throw css::registry::InvalidValueException(
772         rtl::OUString(
773             RTL_CONSTASCII_USTRINGPARAM(
774                 "com.sun.star.registry.SimpleRegistry textual services key"
775                 " getStringValue: wrong type")),
776         static_cast< OWeakObject * >(this));
777 }
778 
779 void Key::setStringValue(rtl::OUString const &)
780     throw (css::registry::InvalidRegistryException, css::uno::RuntimeException)
781 {
782     throw css::registry::InvalidRegistryException(
783         rtl::OUString(
784             RTL_CONSTASCII_USTRINGPARAM(
785                 "com.sun.star.registry.SimpleRegistry textual services key"
786                 " setStringValue not supported")),
787         static_cast< OWeakObject * >(this));
788 }
789 
790 css::uno::Sequence< rtl::OUString > Key::getStringListValue() throw (
791     css::registry::InvalidRegistryException,
792     css::registry::InvalidValueException, css::uno::RuntimeException)
793 {
794     throw css::registry::InvalidValueException(
795         rtl::OUString(
796             RTL_CONSTASCII_USTRINGPARAM(
797                 "com.sun.star.registry.SimpleRegistry textual services key"
798                 " getStringListValue not supported")),
799         static_cast< OWeakObject * >(this));
800 }
801 
802 void Key::setStringListValue(css::uno::Sequence< rtl::OUString > const &)
803     throw (css::registry::InvalidRegistryException, css::uno::RuntimeException)
804 {
805     throw css::registry::InvalidRegistryException(
806         rtl::OUString(
807             RTL_CONSTASCII_USTRINGPARAM(
808                 "com.sun.star.registry.SimpleRegistry textual services key"
809                 " setStringListValue not supported")),
810         static_cast< OWeakObject * >(this));
811 }
812 
813 css::uno::Sequence< sal_Int8 > Key::getBinaryValue()
814     throw (
815         css::registry::InvalidRegistryException,
816         css::registry::InvalidValueException, css::uno::RuntimeException)
817 {
818     throw css::registry::InvalidValueException(
819         rtl::OUString(
820             RTL_CONSTASCII_USTRINGPARAM(
821                 "com.sun.star.registry.SimpleRegistry textual services key"
822                 " getBinarValue not supported")),
823         static_cast< OWeakObject * >(this));
824 }
825 
826 void Key::setBinaryValue(css::uno::Sequence< sal_Int8 > const &)
827     throw (css::registry::InvalidRegistryException, css::uno::RuntimeException)
828 {
829     throw css::registry::InvalidRegistryException(
830         rtl::OUString(
831             RTL_CONSTASCII_USTRINGPARAM(
832                 "com.sun.star.registry.SimpleRegistry textual services key"
833                 " setBinaryValue not supported")),
834         static_cast< OWeakObject * >(this));
835 }
836 
837 css::uno::Reference< css::registry::XRegistryKey > Key::openKey(
838     rtl::OUString const & aKeyName)
839     throw (css::registry::InvalidRegistryException, css::uno::RuntimeException)
840 {
841     std::vector< rtl::OUString > path;
842     if (!find(aKeyName, &path, 0, 0)) {
843         return css::uno::Reference< css::registry::XRegistryKey >();
844     }
845     return new Key(data_, path);
846 }
847 
848 css::uno::Reference< css::registry::XRegistryKey > Key::createKey(
849     rtl::OUString const &)
850     throw (css::registry::InvalidRegistryException, css::uno::RuntimeException)
851 {
852     throw css::registry::InvalidRegistryException(
853         rtl::OUString(
854             RTL_CONSTASCII_USTRINGPARAM(
855                 "com.sun.star.registry.SimpleRegistry textual services key"
856                 " createKey not supported")),
857         static_cast< OWeakObject * >(this));
858 }
859 
860 void Key::closeKey()
861     throw (css::registry::InvalidRegistryException, css::uno::RuntimeException)
862 {}
863 
864 void Key::deleteKey(rtl::OUString const &)
865     throw (css::registry::InvalidRegistryException, css::uno::RuntimeException)
866 {
867     throw css::registry::InvalidRegistryException(
868         rtl::OUString(
869             RTL_CONSTASCII_USTRINGPARAM(
870                 "com.sun.star.registry.SimpleRegistry textual services key"
871                 " deleteKey not supported")),
872         static_cast< OWeakObject * >(this));
873 }
874 
875 css::uno::Sequence< css::uno::Reference< css::registry::XRegistryKey > >
876 Key::openKeys()
877     throw (css::registry::InvalidRegistryException, css::uno::RuntimeException)
878 {
879     css::uno::Sequence< rtl::OUString > names(getChildren());
880     css::uno::Sequence< css::uno::Reference< css::registry::XRegistryKey > >
881         keys(names.getLength());
882     for (sal_Int32 i = 0; i < keys.getLength(); ++i) {
883         keys[i] = openKey(names[i]);
884         OSL_ASSERT(keys[i].is());
885     }
886     return keys;
887 }
888 
889 css::uno::Sequence< rtl::OUString > Key::getKeyNames()
890     throw (css::registry::InvalidRegistryException, css::uno::RuntimeException)
891 {
892     css::uno::Sequence< rtl::OUString > names(getChildren());
893     rtl::OUString prefix(pathToString(path_));
894     prefix += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/"));
895     for (sal_Int32 i = 0; i < names.getLength(); ++i) {
896         names[i] = prefix + names[i];
897     }
898     return names;
899 }
900 
901 sal_Bool Key::createLink(rtl::OUString const &, rtl::OUString const &)
902     throw (css::registry::InvalidRegistryException, css::uno::RuntimeException)
903 {
904     throw css::registry::InvalidRegistryException(
905         rtl::OUString(
906             RTL_CONSTASCII_USTRINGPARAM(
907                 "com.sun.star.registry.SimpleRegistry textual services key"
908                 " createLink not supported")),
909         static_cast< OWeakObject * >(this));
910 }
911 
912 void Key::deleteLink(rtl::OUString const &)
913     throw (css::registry::InvalidRegistryException, css::uno::RuntimeException)
914 {
915     throw css::registry::InvalidRegistryException(
916         rtl::OUString(
917             RTL_CONSTASCII_USTRINGPARAM(
918                 "com.sun.star.registry.SimpleRegistry textual services key"
919                 " deleteLink not supported")),
920         static_cast< OWeakObject * >(this));
921 }
922 
923 rtl::OUString Key::getLinkTarget(rtl::OUString const &)
924     throw (css::registry::InvalidRegistryException, css::uno::RuntimeException)
925 {
926     throw css::registry::InvalidRegistryException(
927         rtl::OUString(
928             RTL_CONSTASCII_USTRINGPARAM(
929                 "com.sun.star.registry.SimpleRegistry textual services key"
930                 " getLinkTarget not supported")),
931         static_cast< OWeakObject * >(this));
932 }
933 
934 rtl::OUString Key::getResolvedName(rtl::OUString const & aKeyName)
935     throw (css::registry::InvalidRegistryException, css::uno::RuntimeException)
936 {
937     std::vector< rtl::OUString > path;
938     find(aKeyName, &path, 0, 0);
939     return pathToString(path);
940 }
941 
942 bool Key::find(
943     rtl::OUString const & relative, std::vector< rtl::OUString > * path,
944     State * state, css::registry::RegistryValueType * type) const
945 {
946     std::vector< rtl::OUString > p(path_);
947     sal_Int32 i = 0;
948     do {
949         rtl::OUString seg(relative.getToken(0, '/', i));
950         if (seg.getLength() != 0) {
951             p.push_back(seg);
952         }
953     } while (i >= 0);
954     if (path != 0) {
955         *path = p;
956     }
957     std::size_t const MAX_TRANSITIONS = 4;
958     struct StateInfo {
959         css::registry::RegistryValueType type;
960         std::size_t count;
961         struct { char const * segment; State state; }
962             transitions[MAX_TRANSITIONS];
963     };
964     static StateInfo const info[] = {
965         // STATE_ROOT:
966         { css::registry::RegistryValueType_NOT_DEFINED, 3,
967           { { "IMPLEMENTATIONS", STATE_IMPLEMENTATIONS },
968             { "SERVICES", STATE_SERVICES },
969             { "SINGLETONS", STATE_SINGLETONS } } },
970         // STATE_IMPLEMENTATIONS:
971         { css::registry::RegistryValueType_NOT_DEFINED, 1,
972           { { 0, STATE_IMPLEMENTATION } } },
973         // STATE_IMPLEMENTATION:
974         { css::registry::RegistryValueType_NOT_DEFINED, 1,
975           { { "UNO", STATE_UNO } } },
976         // STATE_UNO:
977         { css::registry::RegistryValueType_NOT_DEFINED, 4,
978           { { "LOCATION", STATE_LOCATION },
979             { "ACTIVATOR", STATE_ACTIVATOR },
980             { "SERVICES", STATE_IMPLEMENTATION_SERVICES },
981             { "SINGLETONS", STATE_IMPLEMENTATION_SINGLETONS } } },
982         // STATE_LOCATION:
983         { css::registry::RegistryValueType_ASCII, 0, {} },
984         // STATE_ACTIVATOR:
985         { css::registry::RegistryValueType_ASCII, 0, {} },
986         // STATE_IMPLEMENTATION_SERVICES:
987         { css::registry::RegistryValueType_NOT_DEFINED, 1,
988           { { 0, STATE_IMPLEMENTATION_SERVICE } } },
989         // STATE_IMPLEMENTATION_SERVICE:
990         { css::registry::RegistryValueType_NOT_DEFINED, 0, {} },
991         // STATE_IMPLEMENTATION_SINGLETONS:
992         { css::registry::RegistryValueType_NOT_DEFINED, 1,
993           { { 0, STATE_IMPLEMENTATION_SINGLETON } } },
994         // STATE_IMPLEMENTATION_SINGLETON:
995         { css::registry::RegistryValueType_STRING, 0, {} },
996         // STATE_SERVICES:
997         { css::registry::RegistryValueType_NOT_DEFINED, 1,
998           { { 0, STATE_SERVICE } } },
999         // STATE_SERVICE:
1000         { css::registry::RegistryValueType_ASCIILIST, 0, {} },
1001         // STATE_SINGLETONS:
1002         { css::registry::RegistryValueType_NOT_DEFINED, 1,
1003           { { 0, STATE_SINGLETON } } },
1004         // STATE_SINGLETON:
1005         { css::registry::RegistryValueType_STRING, 1,
1006           { { "REGISTERED_BY", STATE_REGISTEREDBY } } },
1007         // STATE_REGISTEREDBY:
1008         { css::registry::RegistryValueType_ASCIILIST, 0, {} } };
1009     State s = STATE_ROOT;
1010     for (std::vector< rtl::OUString >::iterator j(p.begin()); j != p.end(); ++j)
1011     {
1012         bool found = false;
1013         for (std::size_t k = 0; k < info[s].count; ++k) {
1014             if (info[s].transitions[k].segment == 0) {
1015                 switch (info[s].transitions[k].state) {
1016                 case STATE_IMPLEMENTATION:
1017                     found = data_->implementations.find(*j) !=
1018                         data_->implementations.end();
1019                     break;
1020                 case STATE_IMPLEMENTATION_SERVICE:
1021                 case STATE_IMPLEMENTATION_SINGLETON:
1022                     found = true; //TODO
1023                     break;
1024                 case STATE_SERVICE:
1025                     found = data_->services.find(*j) != data_->services.end();
1026                     break;
1027                 case STATE_SINGLETON:
1028                     found = data_->singletons.find(*j) !=
1029                         data_->singletons.end();
1030                     break;
1031                 default:
1032                     std::abort(); // this cannot happen
1033                 }
1034             } else {
1035                 found = j->equalsAscii(info[s].transitions[k].segment);
1036             }
1037             if (found) {
1038                 s = info[s].transitions[k].state;
1039                 break;
1040             }
1041         }
1042         if (!found) {
1043             return false;
1044         }
1045     }
1046     if (state != 0) {
1047         *state = s;
1048     }
1049     if (type != 0) {
1050         *type = info[s].type;
1051     }
1052     return true;
1053 }
1054 
1055 css::uno::Sequence< rtl::OUString > Key::getChildren() {
1056     State state = STATE_ROOT;
1057     OSL_VERIFY(find(rtl::OUString(), 0, &state, 0));
1058     switch (state) {
1059     default:
1060         std::abort(); // this cannot happen
1061         // pseudo-fall-through to avoid warnings on MSC
1062     case STATE_ROOT:
1063         {
1064             css::uno::Sequence< rtl::OUString > seq(3);
1065             seq[0] = rtl::OUString(
1066                 RTL_CONSTASCII_USTRINGPARAM("IMPLEMENTATIONS"));
1067             seq[1] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SERVICES"));
1068             seq[2] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SINGLETONS"));
1069             return seq;
1070         }
1071     case STATE_IMPLEMENTATIONS:
1072         {
1073             if (data_->implementations.size() > SAL_MAX_INT32) {
1074                 throw css::registry::InvalidValueException(
1075                     rtl::OUString(
1076                         RTL_CONSTASCII_USTRINGPARAM(
1077                             "com.sun.star.registry.SimpleRegistry textual"
1078                             " services key openKeys: too large")),
1079                     static_cast< OWeakObject * >(this));
1080             }
1081             css::uno::Sequence< rtl::OUString > seq(
1082                     static_cast< sal_Int32 >(data_->implementations.size()));
1083             sal_Int32 i = 0;
1084             for (Implementations::iterator j(data_->implementations.begin());
1085                  j != data_->implementations.end(); ++j)
1086             {
1087                 seq[i++] = j->first;
1088             }
1089             return seq;
1090         }
1091     case STATE_UNO:
1092         {
1093             css::uno::Sequence< rtl::OUString > seq(4);
1094             seq[0] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("LOCATION"));
1095             seq[1] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ACTIVATOR"));
1096             seq[2] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SERVICES"));
1097             seq[3] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SINGLETONS"));
1098             return seq;
1099         }
1100     case STATE_LOCATION:
1101     case STATE_ACTIVATOR:
1102     case STATE_IMPLEMENTATION_SERVICE:
1103     case STATE_IMPLEMENTATION_SINGLETON:
1104     case STATE_SERVICE:
1105     case STATE_REGISTEREDBY:
1106         return css::uno::Sequence< rtl::OUString >();
1107     case STATE_IMPLEMENTATION_SERVICES:
1108         {
1109             if (data_->implementations[path_[1]].services.size() >
1110                 SAL_MAX_INT32)
1111             {
1112                 throw css::registry::InvalidValueException(
1113                     rtl::OUString(
1114                         RTL_CONSTASCII_USTRINGPARAM(
1115                             "com.sun.star.registry.SimpleRegistry textual"
1116                             " services key openKeys: too large")),
1117                     static_cast< OWeakObject * >(this));
1118             }
1119             css::uno::Sequence< rtl::OUString > seq(
1120                 static_cast< sal_Int32 >(
1121                     data_->implementations[path_[1]].services.size()));
1122             sal_Int32 i = 0;
1123             for (std::vector< rtl::OUString >::iterator j(
1124                      data_->implementations[path_[1]].services.begin());
1125                  j != data_->implementations[path_[1]].services.end(); ++j)
1126             {
1127                 seq[i++] = *j;
1128             }
1129             return seq;
1130         }
1131     case STATE_IMPLEMENTATION_SINGLETONS:
1132         {
1133             if (data_->implementations[path_[1]].singletons.size() >
1134                 SAL_MAX_INT32)
1135             {
1136                 throw css::registry::InvalidValueException(
1137                     rtl::OUString(
1138                         RTL_CONSTASCII_USTRINGPARAM(
1139                             "com.sun.star.registry.SimpleRegistry textual"
1140                             " services key openKeys: too large")),
1141                     static_cast< OWeakObject * >(this));
1142             }
1143             css::uno::Sequence< rtl::OUString > seq(
1144                 static_cast< sal_Int32 >(
1145                     data_->implementations[path_[1]].singletons.size()));
1146             sal_Int32 i = 0;
1147             for (std::vector< rtl::OUString >::iterator j(
1148                      data_->implementations[path_[1]].singletons.begin());
1149                  j != data_->implementations[path_[1]].singletons.end(); ++j)
1150             {
1151                 seq[i++] = *j;
1152             }
1153             return seq;
1154         }
1155     case STATE_SERVICES:
1156         {
1157             if (data_->services.size() > SAL_MAX_INT32) {
1158                 throw css::registry::InvalidValueException(
1159                     rtl::OUString(
1160                         RTL_CONSTASCII_USTRINGPARAM(
1161                             "com.sun.star.registry.SimpleRegistry textual"
1162                             " services key openKeys: too large")),
1163                     static_cast< OWeakObject * >(this));
1164             }
1165             css::uno::Sequence< rtl::OUString > seq(
1166                 static_cast< sal_Int32 >(data_->services.size()));
1167             sal_Int32 i = 0;
1168             for (ImplementationMap::iterator j(data_->services.begin());
1169                  j != data_->services.end(); ++j)
1170             {
1171                 seq[i++] = j->first;
1172             }
1173             return seq;
1174         }
1175     case STATE_SINGLETONS:
1176         {
1177             if (data_->singletons.size() > SAL_MAX_INT32) {
1178                 throw css::registry::InvalidValueException(
1179                     rtl::OUString(
1180                         RTL_CONSTASCII_USTRINGPARAM(
1181                             "com.sun.star.registry.SimpleRegistry textual"
1182                             " services key openKeys: too large")),
1183                     static_cast< OWeakObject * >(this));
1184             }
1185             css::uno::Sequence< rtl::OUString > seq(
1186                 static_cast< sal_Int32 >(data_->singletons.size()));
1187             sal_Int32 i = 0;
1188             for (ImplementationMap::iterator j(data_->singletons.begin());
1189                  j != data_->singletons.end(); ++j)
1190             {
1191                 seq[i++] = j->first;
1192             }
1193             return seq;
1194         }
1195     case STATE_SINGLETON:
1196         {
1197             css::uno::Sequence< rtl::OUString > seq(1);
1198             seq[0] = rtl::OUString(
1199                 RTL_CONSTASCII_USTRINGPARAM("REGISTERED_BY"));
1200             return seq;
1201         }
1202     }
1203 }
1204 
1205 }
1206 
1207 TextualServices::TextualServices(rtl::OUString const & uri):
1208     uri_(uri), data_(new Data)
1209 {
1210     try {
1211         Parser(uri, data_);
1212     } catch (css::container::NoSuchElementException &) {
1213         throw css::registry::InvalidRegistryException(
1214             (uri +
1215              rtl::OUString(
1216                 RTL_CONSTASCII_USTRINGPARAM(": no such file"))),
1217             css::uno::Reference< css::uno::XInterface >());
1218     }
1219 }
1220 
1221 TextualServices::~TextualServices() {}
1222 
1223 css::uno::Reference< css::registry::XRegistryKey > TextualServices::getRootKey()
1224 {
1225     return new Key(data_, std::vector< rtl::OUString >());
1226 }
1227 
1228 } }
1229