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