1*3a7cf181SAndrew Rist /**************************************************************
2*3a7cf181SAndrew Rist  *
3*3a7cf181SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*3a7cf181SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*3a7cf181SAndrew Rist  * distributed with this work for additional information
6*3a7cf181SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*3a7cf181SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*3a7cf181SAndrew Rist  * "License"); you may not use this file except in compliance
9*3a7cf181SAndrew Rist  * with the License.  You may obtain a copy of the License at
10*3a7cf181SAndrew Rist  *
11*3a7cf181SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*3a7cf181SAndrew Rist  *
13*3a7cf181SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*3a7cf181SAndrew Rist  * software distributed under the License is distributed on an
15*3a7cf181SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*3a7cf181SAndrew Rist  * KIND, either express or implied.  See the License for the
17*3a7cf181SAndrew Rist  * specific language governing permissions and limitations
18*3a7cf181SAndrew Rist  * under the License.
19*3a7cf181SAndrew Rist  *
20*3a7cf181SAndrew Rist  *************************************************************/
21*3a7cf181SAndrew Rist 
22*3a7cf181SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir #include "precompiled_configmgr.hxx"
25cdf0e10cSrcweir #include "sal/config.h"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include "com/sun/star/uno/Any.hxx"
28cdf0e10cSrcweir #include "com/sun/star/uno/Reference.hxx"
29cdf0e10cSrcweir #include "com/sun/star/uno/RuntimeException.hpp"
30cdf0e10cSrcweir #include "com/sun/star/uno/Sequence.hxx"
31cdf0e10cSrcweir #include "com/sun/star/uno/XInterface.hpp"
32cdf0e10cSrcweir #include "comphelper/sequenceasvector.hxx"
33cdf0e10cSrcweir #include "osl/diagnose.h"
34cdf0e10cSrcweir #include "rtl/string.h"
35cdf0e10cSrcweir #include "rtl/string.hxx"
36cdf0e10cSrcweir #include "rtl/ustring.h"
37cdf0e10cSrcweir #include "rtl/ustring.hxx"
38cdf0e10cSrcweir #include "sal/types.h"
39cdf0e10cSrcweir #include "xmlreader/span.hxx"
40cdf0e10cSrcweir #include "xmlreader/xmlreader.hxx"
41cdf0e10cSrcweir 
42cdf0e10cSrcweir #include "localizedvaluenode.hxx"
43cdf0e10cSrcweir #include "node.hxx"
44cdf0e10cSrcweir #include "nodemap.hxx"
45cdf0e10cSrcweir #include "parsemanager.hxx"
46cdf0e10cSrcweir #include "propertynode.hxx"
47cdf0e10cSrcweir #include "type.hxx"
48cdf0e10cSrcweir #include "valueparser.hxx"
49cdf0e10cSrcweir #include "xmldata.hxx"
50cdf0e10cSrcweir 
51cdf0e10cSrcweir namespace configmgr {
52cdf0e10cSrcweir 
53cdf0e10cSrcweir namespace {
54cdf0e10cSrcweir 
55cdf0e10cSrcweir namespace css = com::sun::star;
56cdf0e10cSrcweir 
parseHexDigit(char c,int * value)57cdf0e10cSrcweir bool parseHexDigit(char c, int * value) {
58cdf0e10cSrcweir     OSL_ASSERT(value != 0);
59cdf0e10cSrcweir     if (c >= '0' && c <= '9') {
60cdf0e10cSrcweir         *value = c - '0';
61cdf0e10cSrcweir         return true;
62cdf0e10cSrcweir     }
63cdf0e10cSrcweir     if (c >= 'A' && c <= 'F') {
64cdf0e10cSrcweir         *value = c - 'A' + 10;
65cdf0e10cSrcweir         return true;
66cdf0e10cSrcweir     }
67cdf0e10cSrcweir     if (c >= 'a' && c <= 'f') {
68cdf0e10cSrcweir         *value = c - 'a' + 10;
69cdf0e10cSrcweir         return true;
70cdf0e10cSrcweir     }
71cdf0e10cSrcweir     return false;
72cdf0e10cSrcweir }
73cdf0e10cSrcweir 
parseValue(xmlreader::Span const & text,sal_Bool * value)74cdf0e10cSrcweir bool parseValue(xmlreader::Span const & text, sal_Bool * value) {
75cdf0e10cSrcweir     OSL_ASSERT(text.is() && value != 0);
76cdf0e10cSrcweir     if (text.equals(RTL_CONSTASCII_STRINGPARAM("true")) ||
77cdf0e10cSrcweir         text.equals(RTL_CONSTASCII_STRINGPARAM("1")))
78cdf0e10cSrcweir     {
79cdf0e10cSrcweir         *value = true;
80cdf0e10cSrcweir         return true;
81cdf0e10cSrcweir     }
82cdf0e10cSrcweir     if (text.equals(RTL_CONSTASCII_STRINGPARAM("false")) ||
83cdf0e10cSrcweir         text.equals(RTL_CONSTASCII_STRINGPARAM("0")))
84cdf0e10cSrcweir     {
85cdf0e10cSrcweir         *value = false;
86cdf0e10cSrcweir         return true;
87cdf0e10cSrcweir     }
88cdf0e10cSrcweir     return false;
89cdf0e10cSrcweir }
90cdf0e10cSrcweir 
parseValue(xmlreader::Span const & text,sal_Int16 * value)91cdf0e10cSrcweir bool parseValue(xmlreader::Span const & text, sal_Int16 * value) {
92cdf0e10cSrcweir     OSL_ASSERT(text.is() && value != 0);
93cdf0e10cSrcweir     // For backwards compatibility, support hexadecimal values:
94cdf0e10cSrcweir     sal_Int32 n =
95cdf0e10cSrcweir         rtl_str_shortenedCompareIgnoreAsciiCase_WithLength(
96cdf0e10cSrcweir             text.begin, text.length, RTL_CONSTASCII_STRINGPARAM("0X"),
97cdf0e10cSrcweir             RTL_CONSTASCII_LENGTH("0X")) == 0 ?
98cdf0e10cSrcweir         rtl::OString(
99cdf0e10cSrcweir             text.begin + RTL_CONSTASCII_LENGTH("0X"),
100cdf0e10cSrcweir             text.length - RTL_CONSTASCII_LENGTH("0X")).toInt32(16) :
101cdf0e10cSrcweir         rtl::OString(text.begin, text.length).toInt32();
102cdf0e10cSrcweir         //TODO: check valid lexical representation
103cdf0e10cSrcweir     if (n >= SAL_MIN_INT16 && n <= SAL_MAX_INT16) {
104cdf0e10cSrcweir         *value = static_cast< sal_Int16 >(n);
105cdf0e10cSrcweir         return true;
106cdf0e10cSrcweir     }
107cdf0e10cSrcweir     return false;
108cdf0e10cSrcweir }
109cdf0e10cSrcweir 
parseValue(xmlreader::Span const & text,sal_Int32 * value)110cdf0e10cSrcweir bool parseValue(xmlreader::Span const & text, sal_Int32 * value) {
111cdf0e10cSrcweir     OSL_ASSERT(text.is() && value != 0);
112cdf0e10cSrcweir     // For backwards compatibility, support hexadecimal values:
113cdf0e10cSrcweir     *value =
114cdf0e10cSrcweir         rtl_str_shortenedCompareIgnoreAsciiCase_WithLength(
115cdf0e10cSrcweir             text.begin, text.length, RTL_CONSTASCII_STRINGPARAM("0X"),
116cdf0e10cSrcweir             RTL_CONSTASCII_LENGTH("0X")) == 0 ?
117cdf0e10cSrcweir         rtl::OString(
118cdf0e10cSrcweir             text.begin + RTL_CONSTASCII_LENGTH("0X"),
119cdf0e10cSrcweir             text.length - RTL_CONSTASCII_LENGTH("0X")).toInt32(16) :
120cdf0e10cSrcweir         rtl::OString(text.begin, text.length).toInt32();
121cdf0e10cSrcweir         //TODO: check valid lexical representation
122cdf0e10cSrcweir     return true;
123cdf0e10cSrcweir }
124cdf0e10cSrcweir 
parseValue(xmlreader::Span const & text,sal_Int64 * value)125cdf0e10cSrcweir bool parseValue(xmlreader::Span const & text, sal_Int64 * value) {
126cdf0e10cSrcweir     OSL_ASSERT(text.is() && value != 0);
127cdf0e10cSrcweir     // For backwards compatibility, support hexadecimal values:
128cdf0e10cSrcweir     *value =
129cdf0e10cSrcweir         rtl_str_shortenedCompareIgnoreAsciiCase_WithLength(
130cdf0e10cSrcweir             text.begin, text.length, RTL_CONSTASCII_STRINGPARAM("0X"),
131cdf0e10cSrcweir             RTL_CONSTASCII_LENGTH("0X")) == 0 ?
132cdf0e10cSrcweir         rtl::OString(
133cdf0e10cSrcweir             text.begin + RTL_CONSTASCII_LENGTH("0X"),
134cdf0e10cSrcweir             text.length - RTL_CONSTASCII_LENGTH("0X")).toInt64(16) :
135cdf0e10cSrcweir         rtl::OString(text.begin, text.length).toInt64();
136cdf0e10cSrcweir         //TODO: check valid lexical representation
137cdf0e10cSrcweir     return true;
138cdf0e10cSrcweir }
139cdf0e10cSrcweir 
parseValue(xmlreader::Span const & text,double * value)140cdf0e10cSrcweir bool parseValue(xmlreader::Span const & text, double * value) {
141cdf0e10cSrcweir     OSL_ASSERT(text.is() && value != 0);
142cdf0e10cSrcweir     *value = rtl::OString(text.begin, text.length).toDouble();
143cdf0e10cSrcweir         //TODO: check valid lexical representation
144cdf0e10cSrcweir     return true;
145cdf0e10cSrcweir }
146cdf0e10cSrcweir 
parseValue(xmlreader::Span const & text,rtl::OUString * value)147cdf0e10cSrcweir bool parseValue(xmlreader::Span const & text, rtl::OUString * value) {
148cdf0e10cSrcweir     OSL_ASSERT(text.is() && value != 0);
149cdf0e10cSrcweir     *value = text.convertFromUtf8();
150cdf0e10cSrcweir     return true;
151cdf0e10cSrcweir }
152cdf0e10cSrcweir 
parseValue(xmlreader::Span const & text,css::uno::Sequence<sal_Int8> * value)153cdf0e10cSrcweir bool parseValue(
154cdf0e10cSrcweir     xmlreader::Span const & text, css::uno::Sequence< sal_Int8 > * value)
155cdf0e10cSrcweir {
156cdf0e10cSrcweir     OSL_ASSERT(text.is() && value != 0);
157cdf0e10cSrcweir     if ((text.length & 1) != 0) {
158cdf0e10cSrcweir         return false;
159cdf0e10cSrcweir     }
160cdf0e10cSrcweir     comphelper::SequenceAsVector< sal_Int8 > seq;
161cdf0e10cSrcweir     for (sal_Int32 i = 0; i != text.length;) {
162cdf0e10cSrcweir         int n1;
163cdf0e10cSrcweir         int n2;
164cdf0e10cSrcweir         if (!parseHexDigit(text.begin[i++], &n1) ||
165cdf0e10cSrcweir             !parseHexDigit(text.begin[i++], &n2))
166cdf0e10cSrcweir         {
167cdf0e10cSrcweir             return false;
168cdf0e10cSrcweir         }
169cdf0e10cSrcweir         seq.push_back(static_cast< sal_Int8 >((n1 << 4) | n2));
170cdf0e10cSrcweir     }
171cdf0e10cSrcweir     *value = seq.getAsConstList();
172cdf0e10cSrcweir     return true;
173cdf0e10cSrcweir }
174cdf0e10cSrcweir 
parseSingleValue(xmlreader::Span const & text)175cdf0e10cSrcweir template< typename T > css::uno::Any parseSingleValue(
176cdf0e10cSrcweir     xmlreader::Span const & text)
177cdf0e10cSrcweir {
178cdf0e10cSrcweir     T val;
179cdf0e10cSrcweir     if (!parseValue(text, &val)) {
180cdf0e10cSrcweir         throw css::uno::RuntimeException(
181cdf0e10cSrcweir             rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("invalid value")),
182cdf0e10cSrcweir             css::uno::Reference< css::uno::XInterface >());
183cdf0e10cSrcweir     }
184cdf0e10cSrcweir     return css::uno::makeAny(val);
185cdf0e10cSrcweir }
186cdf0e10cSrcweir 
parseListValue(rtl::OString const & separator,xmlreader::Span const & text)187cdf0e10cSrcweir template< typename T > css::uno::Any parseListValue(
188cdf0e10cSrcweir     rtl::OString const & separator, xmlreader::Span const & text)
189cdf0e10cSrcweir {
190cdf0e10cSrcweir     comphelper::SequenceAsVector< T > seq;
191cdf0e10cSrcweir     xmlreader::Span sep;
192cdf0e10cSrcweir     if (separator.getLength() == 0) {
193cdf0e10cSrcweir         sep = xmlreader::Span(RTL_CONSTASCII_STRINGPARAM(" "));
194cdf0e10cSrcweir     } else {
195cdf0e10cSrcweir         sep = xmlreader::Span(separator.getStr(), separator.getLength());
196cdf0e10cSrcweir     }
197cdf0e10cSrcweir     if (text.length != 0) {
198cdf0e10cSrcweir         for (xmlreader::Span t(text);;) {
199cdf0e10cSrcweir             sal_Int32 i = rtl_str_indexOfStr_WithLength(
200cdf0e10cSrcweir                 t.begin, t.length, sep.begin, sep.length);
201cdf0e10cSrcweir             T val;
202cdf0e10cSrcweir             if (!parseValue(
203cdf0e10cSrcweir                     xmlreader::Span(t.begin, i == -1 ? t.length : i), &val))
204cdf0e10cSrcweir             {
205cdf0e10cSrcweir                 throw css::uno::RuntimeException(
206cdf0e10cSrcweir                     rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("invalid value")),
207cdf0e10cSrcweir                     css::uno::Reference< css::uno::XInterface >());
208cdf0e10cSrcweir             }
209cdf0e10cSrcweir             seq.push_back(val);
210cdf0e10cSrcweir             if (i < 0) {
211cdf0e10cSrcweir                 break;
212cdf0e10cSrcweir             }
213cdf0e10cSrcweir             t.begin += i + sep.length;
214cdf0e10cSrcweir             t.length -= i + sep.length;
215cdf0e10cSrcweir         }
216cdf0e10cSrcweir     }
217cdf0e10cSrcweir     return css::uno::makeAny(seq.getAsConstList());
218cdf0e10cSrcweir }
219cdf0e10cSrcweir 
parseValue(rtl::OString const & separator,xmlreader::Span const & text,Type type)220cdf0e10cSrcweir css::uno::Any parseValue(
221cdf0e10cSrcweir     rtl::OString const & separator, xmlreader::Span const & text, Type type)
222cdf0e10cSrcweir {
223cdf0e10cSrcweir     switch (type) {
224cdf0e10cSrcweir     case TYPE_ANY:
225cdf0e10cSrcweir         throw css::uno::RuntimeException(
226cdf0e10cSrcweir             rtl::OUString(
227cdf0e10cSrcweir                 RTL_CONSTASCII_USTRINGPARAM("invalid value of type any")),
228cdf0e10cSrcweir             css::uno::Reference< css::uno::XInterface >());
229cdf0e10cSrcweir     case TYPE_BOOLEAN:
230cdf0e10cSrcweir         return parseSingleValue< sal_Bool >(text);
231cdf0e10cSrcweir     case TYPE_SHORT:
232cdf0e10cSrcweir         return parseSingleValue< sal_Int16 >(text);
233cdf0e10cSrcweir     case TYPE_INT:
234cdf0e10cSrcweir         return parseSingleValue< sal_Int32 >(text);
235cdf0e10cSrcweir     case TYPE_LONG:
236cdf0e10cSrcweir         return parseSingleValue< sal_Int64 >(text);
237cdf0e10cSrcweir     case TYPE_DOUBLE:
238cdf0e10cSrcweir         return parseSingleValue< double >(text);
239cdf0e10cSrcweir     case TYPE_STRING:
240cdf0e10cSrcweir         return parseSingleValue< rtl::OUString >(text);
241cdf0e10cSrcweir     case TYPE_HEXBINARY:
242cdf0e10cSrcweir         return parseSingleValue< css::uno::Sequence< sal_Int8 > >(text);
243cdf0e10cSrcweir     case TYPE_BOOLEAN_LIST:
244cdf0e10cSrcweir         return parseListValue< sal_Bool >(separator, text);
245cdf0e10cSrcweir     case TYPE_SHORT_LIST:
246cdf0e10cSrcweir         return parseListValue< sal_Int16 >(separator, text);
247cdf0e10cSrcweir     case TYPE_INT_LIST:
248cdf0e10cSrcweir         return parseListValue< sal_Int32 >(separator, text);
249cdf0e10cSrcweir     case TYPE_LONG_LIST:
250cdf0e10cSrcweir         return parseListValue< sal_Int64 >(separator, text);
251cdf0e10cSrcweir     case TYPE_DOUBLE_LIST:
252cdf0e10cSrcweir         return parseListValue< double >(separator, text);
253cdf0e10cSrcweir     case TYPE_STRING_LIST:
254cdf0e10cSrcweir         return parseListValue< rtl::OUString >(separator, text);
255cdf0e10cSrcweir     case TYPE_HEXBINARY_LIST:
256cdf0e10cSrcweir         return parseListValue< css::uno::Sequence< sal_Int8 > >(
257cdf0e10cSrcweir             separator, text);
258cdf0e10cSrcweir     default:
259cdf0e10cSrcweir         OSL_ASSERT(false);
260cdf0e10cSrcweir         throw css::uno::RuntimeException(
261cdf0e10cSrcweir             rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("this cannot happen")),
262cdf0e10cSrcweir             css::uno::Reference< css::uno::XInterface >());
263cdf0e10cSrcweir     }
264cdf0e10cSrcweir }
265cdf0e10cSrcweir 
266cdf0e10cSrcweir }
267cdf0e10cSrcweir 
ValueParser(int layer)268cdf0e10cSrcweir ValueParser::ValueParser(int layer): layer_(layer) {}
269cdf0e10cSrcweir 
~ValueParser()270cdf0e10cSrcweir ValueParser::~ValueParser() {}
271cdf0e10cSrcweir 
getTextMode() const272cdf0e10cSrcweir xmlreader::XmlReader::Text ValueParser::getTextMode() const {
273cdf0e10cSrcweir     if (node_.is()) {
274cdf0e10cSrcweir         switch (state_) {
275cdf0e10cSrcweir         case STATE_TEXT:
276cdf0e10cSrcweir             if (!items_.empty()) {
277cdf0e10cSrcweir                 break;
278cdf0e10cSrcweir             }
279cdf0e10cSrcweir             // fall through
280cdf0e10cSrcweir         case STATE_IT:
281cdf0e10cSrcweir             return
282cdf0e10cSrcweir                 (type_ == TYPE_STRING || type_ == TYPE_STRING_LIST ||
283cdf0e10cSrcweir                  separator_.getLength() != 0)
284cdf0e10cSrcweir                 ? xmlreader::XmlReader::TEXT_RAW
285cdf0e10cSrcweir                 : xmlreader::XmlReader::TEXT_NORMALIZED;
286cdf0e10cSrcweir         default:
287cdf0e10cSrcweir             break;
288cdf0e10cSrcweir         }
289cdf0e10cSrcweir     }
290cdf0e10cSrcweir     return xmlreader::XmlReader::TEXT_NONE;
291cdf0e10cSrcweir }
292cdf0e10cSrcweir 
startElement(xmlreader::XmlReader & reader,int nsId,xmlreader::Span const & name)293cdf0e10cSrcweir bool ValueParser::startElement(
294cdf0e10cSrcweir     xmlreader::XmlReader & reader, int nsId, xmlreader::Span const & name)
295cdf0e10cSrcweir {
296cdf0e10cSrcweir     if (!node_.is()) {
297cdf0e10cSrcweir         return false;
298cdf0e10cSrcweir     }
299cdf0e10cSrcweir     switch (state_) {
300cdf0e10cSrcweir     case STATE_TEXT:
301cdf0e10cSrcweir         if (nsId == xmlreader::XmlReader::NAMESPACE_NONE &&
302cdf0e10cSrcweir             name.equals(RTL_CONSTASCII_STRINGPARAM("it")) &&
303cdf0e10cSrcweir             isListType(type_) && separator_.getLength() == 0)
304cdf0e10cSrcweir         {
305cdf0e10cSrcweir             pad_.clear();
306cdf0e10cSrcweir                 // before first <it>, characters are not ignored; assume they
307cdf0e10cSrcweir                 // are only whitespace
308cdf0e10cSrcweir             state_ = STATE_IT;
309cdf0e10cSrcweir             return true;
310cdf0e10cSrcweir         }
311cdf0e10cSrcweir         // fall through
312cdf0e10cSrcweir     case STATE_IT:
313cdf0e10cSrcweir         if (nsId == xmlreader::XmlReader::NAMESPACE_NONE &&
314cdf0e10cSrcweir             name.equals(RTL_CONSTASCII_STRINGPARAM("unicode")) &&
315cdf0e10cSrcweir             (type_ == TYPE_STRING || type_ == TYPE_STRING_LIST))
316cdf0e10cSrcweir         {
317cdf0e10cSrcweir             sal_Int32 scalar = -1;
318cdf0e10cSrcweir             for (;;) {
319cdf0e10cSrcweir                 int attrNsId;
320cdf0e10cSrcweir                 xmlreader::Span attrLn;
321cdf0e10cSrcweir                 if (!reader.nextAttribute(&attrNsId, &attrLn)) {
322cdf0e10cSrcweir                     break;
323cdf0e10cSrcweir                 }
324cdf0e10cSrcweir                 if (attrNsId == ParseManager::NAMESPACE_OOR &&
325cdf0e10cSrcweir                     attrLn.equals(RTL_CONSTASCII_STRINGPARAM("scalar")))
326cdf0e10cSrcweir                 {
327cdf0e10cSrcweir                     if (!parseValue(reader.getAttributeValue(true), &scalar)) {
328cdf0e10cSrcweir                         scalar = -1;
329cdf0e10cSrcweir                     }
330cdf0e10cSrcweir                     break;
331cdf0e10cSrcweir                 }
332cdf0e10cSrcweir             }
333cdf0e10cSrcweir             if (scalar >= 0 && scalar < 0x20 && scalar != 0x09 &&
334cdf0e10cSrcweir                 scalar != 0x0A && scalar != 0x0D)
335cdf0e10cSrcweir             {
336cdf0e10cSrcweir                 char c = static_cast< char >(scalar);
337cdf0e10cSrcweir                 pad_.add(&c, 1);
338cdf0e10cSrcweir             } else if (scalar == 0xFFFE) {
339cdf0e10cSrcweir                 pad_.add(RTL_CONSTASCII_STRINGPARAM("\xEF\xBF\xBE"));
340cdf0e10cSrcweir             } else if (scalar == 0xFFFF) {
341cdf0e10cSrcweir                 pad_.add(RTL_CONSTASCII_STRINGPARAM("\xEF\xBF\xBF"));
342cdf0e10cSrcweir             } else {
343cdf0e10cSrcweir                 throw css::uno::RuntimeException(
344cdf0e10cSrcweir                     (rtl::OUString(
345cdf0e10cSrcweir                         RTL_CONSTASCII_USTRINGPARAM(
346cdf0e10cSrcweir                             "bad unicode scalar attribute in ")) +
347cdf0e10cSrcweir                      reader.getUrl()),
348cdf0e10cSrcweir                     css::uno::Reference< css::uno::XInterface >());
349cdf0e10cSrcweir             }
350cdf0e10cSrcweir             state_ = State(state_ + 1);
351cdf0e10cSrcweir             return true;
352cdf0e10cSrcweir         }
353cdf0e10cSrcweir         break;
354cdf0e10cSrcweir     default:
355cdf0e10cSrcweir         break;
356cdf0e10cSrcweir     }
357cdf0e10cSrcweir     throw css::uno::RuntimeException(
358cdf0e10cSrcweir         (rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("bad member <")) +
359cdf0e10cSrcweir          name.convertFromUtf8() +
360cdf0e10cSrcweir          rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("> in ")) + reader.getUrl()),
361cdf0e10cSrcweir         css::uno::Reference< css::uno::XInterface >());
362cdf0e10cSrcweir }
363cdf0e10cSrcweir 
endElement()364cdf0e10cSrcweir bool ValueParser::endElement() {
365cdf0e10cSrcweir     if (!node_.is()) {
366cdf0e10cSrcweir         return false;
367cdf0e10cSrcweir     }
368cdf0e10cSrcweir     switch (state_) {
369cdf0e10cSrcweir     case STATE_TEXT:
370cdf0e10cSrcweir         {
371cdf0e10cSrcweir             css::uno::Any value;
372cdf0e10cSrcweir             if (items_.empty()) {
373cdf0e10cSrcweir                 value = parseValue(separator_, pad_.get(), type_);
374cdf0e10cSrcweir                 pad_.clear();
375cdf0e10cSrcweir             } else {
376cdf0e10cSrcweir                 switch (type_) {
377cdf0e10cSrcweir                 case TYPE_BOOLEAN_LIST:
378cdf0e10cSrcweir                     value = convertItems< sal_Bool >();
379cdf0e10cSrcweir                     break;
380cdf0e10cSrcweir                 case TYPE_SHORT_LIST:
381cdf0e10cSrcweir                     value = convertItems< sal_Int16 >();
382cdf0e10cSrcweir                     break;
383cdf0e10cSrcweir                 case TYPE_INT_LIST:
384cdf0e10cSrcweir                     value = convertItems< sal_Int32 >();
385cdf0e10cSrcweir                     break;
386cdf0e10cSrcweir                 case TYPE_LONG_LIST:
387cdf0e10cSrcweir                     value = convertItems< sal_Int64 >();
388cdf0e10cSrcweir                     break;
389cdf0e10cSrcweir                 case TYPE_DOUBLE_LIST:
390cdf0e10cSrcweir                     value = convertItems< double >();
391cdf0e10cSrcweir                     break;
392cdf0e10cSrcweir                 case TYPE_STRING_LIST:
393cdf0e10cSrcweir                     value = convertItems< rtl::OUString >();
394cdf0e10cSrcweir                     break;
395cdf0e10cSrcweir                 case TYPE_HEXBINARY_LIST:
396cdf0e10cSrcweir                     value = convertItems< css::uno::Sequence< sal_Int8 > >();
397cdf0e10cSrcweir                     break;
398cdf0e10cSrcweir                 default:
399cdf0e10cSrcweir                     OSL_ASSERT(false); // this cannot happen
400cdf0e10cSrcweir                     break;
401cdf0e10cSrcweir                 }
402cdf0e10cSrcweir                 items_.clear();
403cdf0e10cSrcweir             }
404cdf0e10cSrcweir             switch (node_->kind()) {
405cdf0e10cSrcweir             case Node::KIND_PROPERTY:
406cdf0e10cSrcweir                 dynamic_cast< PropertyNode * >(node_.get())->setValue(
407cdf0e10cSrcweir                     layer_, value);
408cdf0e10cSrcweir                 break;
409cdf0e10cSrcweir             case Node::KIND_LOCALIZED_PROPERTY:
410cdf0e10cSrcweir                 {
411cdf0e10cSrcweir                     NodeMap::iterator i(
412cdf0e10cSrcweir                         node_->getMembers().find(localizedName_));
413cdf0e10cSrcweir                     if (i == node_->getMembers().end()) {
414cdf0e10cSrcweir                         node_->getMembers().insert(
415cdf0e10cSrcweir                             NodeMap::value_type(
416cdf0e10cSrcweir                                 localizedName_,
417cdf0e10cSrcweir                                 new LocalizedValueNode(layer_, value)));
418cdf0e10cSrcweir                     } else {
419cdf0e10cSrcweir                         dynamic_cast< LocalizedValueNode * >(i->second.get())->
420cdf0e10cSrcweir                             setValue(layer_, value);
421cdf0e10cSrcweir                     }
422cdf0e10cSrcweir                 }
423cdf0e10cSrcweir                 break;
424cdf0e10cSrcweir             default:
425cdf0e10cSrcweir                 OSL_ASSERT(false); // this cannot happen
426cdf0e10cSrcweir                 break;
427cdf0e10cSrcweir             }
428cdf0e10cSrcweir             separator_ = rtl::OString();
429cdf0e10cSrcweir             node_.clear();
430cdf0e10cSrcweir         }
431cdf0e10cSrcweir         break;
432cdf0e10cSrcweir     case STATE_TEXT_UNICODE:
433cdf0e10cSrcweir     case STATE_IT_UNICODE:
434cdf0e10cSrcweir         state_ = State(state_ - 1);
435cdf0e10cSrcweir         break;
436cdf0e10cSrcweir     case STATE_IT:
437cdf0e10cSrcweir         items_.push_back(
438cdf0e10cSrcweir             parseValue(rtl::OString(), pad_.get(), elementType(type_)));
439cdf0e10cSrcweir         pad_.clear();
440cdf0e10cSrcweir         state_ = STATE_TEXT;
441cdf0e10cSrcweir         break;
442cdf0e10cSrcweir     }
443cdf0e10cSrcweir     return true;
444cdf0e10cSrcweir }
445cdf0e10cSrcweir 
characters(xmlreader::Span const & text)446cdf0e10cSrcweir void ValueParser::characters(xmlreader::Span const & text) {
447cdf0e10cSrcweir     if (node_.is()) {
448cdf0e10cSrcweir         OSL_ASSERT(state_ == STATE_TEXT || state_ == STATE_IT);
449cdf0e10cSrcweir         pad_.add(text.begin, text.length);
450cdf0e10cSrcweir     }
451cdf0e10cSrcweir }
452cdf0e10cSrcweir 
start(rtl::Reference<Node> const & node,rtl::OUString const & localizedName)453cdf0e10cSrcweir void ValueParser::start(
454cdf0e10cSrcweir     rtl::Reference< Node > const & node, rtl::OUString const & localizedName)
455cdf0e10cSrcweir {
456cdf0e10cSrcweir     OSL_ASSERT(node.is() && !node_.is());
457cdf0e10cSrcweir     node_ = node;
458cdf0e10cSrcweir     localizedName_ = localizedName;
459cdf0e10cSrcweir     state_ = STATE_TEXT;
460cdf0e10cSrcweir }
461cdf0e10cSrcweir 
getLayer() const462cdf0e10cSrcweir int ValueParser::getLayer() const {
463cdf0e10cSrcweir     return layer_;
464cdf0e10cSrcweir }
465cdf0e10cSrcweir 
convertItems()466cdf0e10cSrcweir template< typename T > css::uno::Any ValueParser::convertItems() {
467cdf0e10cSrcweir     css::uno::Sequence< T > seq(items_.size());
468cdf0e10cSrcweir     for (sal_Int32 i = 0; i < seq.getLength(); ++i) {
469cdf0e10cSrcweir         OSL_VERIFY(items_[i] >>= seq[i]);
470cdf0e10cSrcweir     }
471cdf0e10cSrcweir     return css::uno::makeAny(seq);
472cdf0e10cSrcweir }
473cdf0e10cSrcweir 
474cdf0e10cSrcweir }
475