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