fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / svx / workben / msview / xmlconfig.cxx
bloba3324a3027c415e6db4be031813b229018e17dcc
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <com/sun/star/xml/sax/XDocumentHandler.hpp>
22 #include <com/sun/star/xml/sax/InputSource.hpp>
23 #include <com/sun/star/xml/sax/Parser.hpp>
24 #include <com/sun/star/xml/sax/SAXParseException.hpp>
25 #include <com/sun/star/io/IOException.hpp>
26 #include <cppuhelper/implbase1.hxx>
27 #include <comphelper/processfactory.hxx>
28 #include <unotools/ucbstreamhelper.hxx>
29 #include <unotools/streamwrap.hxx>
30 #include "comphelper/anytostring.hxx"
31 #include "cppuhelper/exc_hlp.hxx"
32 #include "rtl/ref.hxx"
34 #include <svx/msdffimp.hxx>
36 #include "xmlconfig.hxx"
38 #include <stdio.h>
39 #include <ctype.h>
40 #include <stack>
42 using ::com::sun::star::io::XInputStream;
43 using ::com::sun::star::io::IOException;
45 using namespace ::com::sun::star::uno;
46 using namespace ::com::sun::star::xml::sax;
50 AtomConfigMap gAtomConfigMap;
54 class ConfigHandler : public ::cppu::WeakAggImplHelper1<XDocumentHandler>
56 public:
57 // XDocumentHandler
58 virtual void SAL_CALL startDocument() throw( SAXException, RuntimeException );
59 virtual void SAL_CALL endDocument() throw( SAXException, RuntimeException );
60 virtual void SAL_CALL startElement(const OUString& aName, const Reference< XAttributeList > & xAttribs) throw( SAXException, RuntimeException );
61 virtual void SAL_CALL endElement(const OUString& aName) throw( SAXException, RuntimeException );
62 virtual void SAL_CALL characters(const OUString& aChars) throw( SAXException, RuntimeException );
63 virtual void SAL_CALL ignorableWhitespace(const OUString& aWhitespaces) throw( SAXException, RuntimeException );
64 virtual void SAL_CALL processingInstruction(const OUString& aTarget, const OUString& aData) throw( SAXException, RuntimeException );
65 virtual void SAL_CALL setDocumentLocator(const Reference< XLocator > & xLocator) throw( SAXException, RuntimeException );
67 private:
68 void errorThrow( const OUString& rErrorMessage ) throw (SAXException );
69 ElementConfigType parseType( const OUString& rErrorMessage ) throw ( SAXException );
70 void addElement( ElementConfigPtr& rElementConfig ) throw ( SAXException );
71 OUString getAttribute( const Reference< XAttributeList > & xAttribs, const sal_Char* pName ) throw( SAXException );
73 ElementConfigPtr importAtomConfig( const Reference< XAttributeList > & xAttribs, bool bIsContainer ) throw( SAXException );
74 ElementConfigPtr importElementConfig( const Reference< XAttributeList > & xAttribs ) throw( SAXException );
75 ElementConfigPtr importSwitchConfig( const Reference< XAttributeList > & xAttribs ) throw( SAXException );
76 ElementConfigPtr importCaseConfig( const Reference< XAttributeList > & xAttribs ) throw( SAXException );
77 ElementConfigPtr importValueElementConfig( const Reference< XAttributeList > & xAttribs ) throw( SAXException );
79 std::stack< ElementConfigPtr > maElementStack;
82 void ConfigHandler::errorThrow( const OUString& rErrorMessage ) throw (SAXException )
84 Reference< XInterface > aContext;
85 Any aWrappedException;
86 throw SAXException(rErrorMessage, aContext, aWrappedException);
89 ElementConfigType ConfigHandler::parseType( const OUString& sType ) throw (SAXException )
91 if ( sType == "uint" )
93 return ECT_UINT;
95 else if ( sType == "byte" )
97 return ECT_BYTE;
99 else if ( sType == "unistring" )
101 return ECT_UNISTRING;
103 else if ( sType == "float" )
105 return ETC_FLOAT;
107 else if ( sType == "hexdump" )
110 else
112 OUString aMessage( "unknown type: " );
113 aMessage += sType;
114 errorThrow( aMessage );
117 return ECT_HEXDUMP;
120 void ConfigHandler::addElement( ElementConfigPtr& rElementConfig ) throw ( SAXException )
122 ElementConfigContainer* pParent = dynamic_cast< ElementConfigContainer* >( maElementStack.top().get() );
124 if( !pParent )
125 errorThrow( OUString( "illegal parent for element" ) );
128 pParent->addElementConfig( rElementConfig );
131 OUString ConfigHandler::getAttribute( const Reference< XAttributeList > & xAttribs, const sal_Char* pName ) throw( SAXException )
133 OUString aName( OUString::createFromAscii( pName ) );
135 const sal_Int16 nAttrCount = xAttribs.is() ? xAttribs->getLength() : 0;
136 sal_Int16 i;
137 for(i=0; i < nAttrCount; i++)
139 if( xAttribs->getNameByIndex( i ) == aName )
140 return xAttribs->getValueByIndex( i );
143 OUString aMessage( "missing required attribute: " );
144 aMessage += aName;
145 errorThrow( aMessage );
147 return OUString();
150 void SAL_CALL ConfigHandler::startDocument() throw( SAXException, RuntimeException )
154 void SAL_CALL ConfigHandler::endDocument() throw( SAXException, RuntimeException )
158 void SAL_CALL ConfigHandler::startElement(const OUString& aName, const Reference< XAttributeList > & xAttribs) throw( SAXException, RuntimeException )
160 ElementConfigPtr pElement;
162 if ( aName == "config" )
164 return;
167 if ( aName == "container" )
169 pElement = importAtomConfig( xAttribs, true );
171 else if ( aName == "atom" )
173 pElement = importAtomConfig( xAttribs, false );
175 else if ( aName == "element" )
177 pElement = importElementConfig( xAttribs );
179 else if ( aName == "value" )
181 pElement = importValueElementConfig( xAttribs );
183 else if ( aName == "switch" )
185 pElement = importSwitchConfig( xAttribs );
187 else if ( aName == "case" )
189 pElement = importCaseConfig( xAttribs );
192 if( !pElement.get() )
194 OUString aMessage( "unknown config element: " );
195 aMessage += aName;
196 errorThrow( aMessage );
199 maElementStack.push( pElement );
202 sal_Int32 toInt( const OUString& rText )
204 if( rText.startsWith("0x"))
206 sal_Int32 nValue = 0;
207 const sal_Unicode *p = rText;
208 p += 2;
209 sal_Int32 nLength = rText.getLength() - 2;
210 while( (nLength--) > 0 )
212 nValue <<= 4;
213 if( *p >= '0' && *p <= '9' )
215 nValue += *p - '0';
217 else if( *p >= 'a' && *p <= 'f' )
219 nValue += *p - ('a' - 10);
221 else if( *p >= 'A' && *p <= 'F' )
223 nValue += *p - ('A' - 10 );
225 p++;
228 return nValue;
230 else
232 return rText.toInt32();
236 ElementConfigPtr ConfigHandler::importAtomConfig( const Reference< XAttributeList > & xAttribs, bool bIsContainer ) throw (SAXException)
238 if( !maElementStack.empty() )
239 errorThrow( OUString( "atom elements must be root" ) );
241 ElementConfigPtr aPtr( new AtomConfig( getAttribute(xAttribs,"name"), bIsContainer ) );
242 gAtomConfigMap[ (UINT16)toInt(getAttribute(xAttribs,"id"))] = aPtr;
243 return aPtr;
246 ElementConfigPtr ConfigHandler::importElementConfig( const Reference< XAttributeList > & xAttribs ) throw (SAXException)
248 ElementConfigType nType = parseType( getAttribute( xAttribs, "type" ) );
249 ElementConfigPtr pElementConfig( new ElementConfigContainer( getAttribute( xAttribs, "name" ), nType ) );
250 addElement( pElementConfig );
251 return pElementConfig;
254 ElementConfigPtr ConfigHandler::importValueElementConfig( const Reference< XAttributeList > & xAttribs ) throw (SAXException)
256 ElementConfigPtr pElementConfig( new ElementValueConfig( getAttribute( xAttribs, "name" ), getAttribute( xAttribs, "value" ) ) );
257 addElement( pElementConfig );
258 return pElementConfig;
261 ElementConfigPtr ConfigHandler::importSwitchConfig( const Reference< XAttributeList > & xAttribs ) throw (SAXException)
263 ElementConfigType nType = parseType( getAttribute( xAttribs, "type" ) );
264 ElementConfigPtr pElementConfig( new SwitchElementConfig( nType ) );
265 addElement( pElementConfig );
266 return pElementConfig;
269 ElementConfigPtr ConfigHandler::importCaseConfig( const Reference< XAttributeList > & xAttribs ) throw (SAXException)
271 ElementConfigPtr pElementConfig( new CaseElementConfig( getAttribute( xAttribs, "value" ) ) );
272 addElement( pElementConfig );
273 return pElementConfig;
276 void SAL_CALL ConfigHandler::endElement(const OUString& aName) throw( SAXException, RuntimeException )
278 if ( aName == "config" )
280 return;
283 maElementStack.pop();
286 void SAL_CALL ConfigHandler::characters(const OUString& aChars) throw( SAXException, RuntimeException )
290 void SAL_CALL ConfigHandler::ignorableWhitespace(const OUString& aWhitespaces) throw( SAXException, RuntimeException )
294 void SAL_CALL ConfigHandler::processingInstruction(const OUString& aTarget, const OUString& aData) throw( SAXException, RuntimeException )
298 void SAL_CALL ConfigHandler::setDocumentLocator(const Reference< XLocator > & xLocator) throw( SAXException, RuntimeException )
302 void load_config( const OUString& rPath )
306 // create stream
307 SvStream* pIStm = ::utl::UcbStreamHelper::CreateStream( rPath, StreamMode::READ );
308 Reference<XInputStream> xInputStream( new utl::OInputStreamWrapper( pIStm, sal_True ) );
310 // prepare ParserInputSrouce
311 InputSource aParserInput;
312 aParserInput.sSystemId = rPath;
313 aParserInput.aInputStream = xInputStream;
315 // get parser
316 Reference< XParser > xParser = Parser::create(comphelper::getProcessComponentContext());
318 // get filter
319 ConfigHandler* pConfigHandler = new ConfigHandler();
320 Reference< XDocumentHandler > xFilter( pConfigHandler );
322 // connect parser and filter
323 xParser->setDocumentHandler( xFilter );
325 // finally, parser the stream
326 xParser->parseStream( aParserInput );
328 catch( Exception& )
330 OSL_FAIL(
331 (OString("load_config(), "
332 "exception caught: ") +
333 OUStringToOString(
334 comphelper::anyToString( cppu::getCaughtException() ),
335 RTL_TEXTENCODING_UTF8 )).getStr() );
341 OUString ElementConfig::format( SvStream& rStream, sal_Size& nLength ) const
343 OUString aRet;
344 if( maName.getLength() )
346 aRet += maName + " = ";
349 switch( mnType )
351 case ECT_BYTE: aRet += dump_byte( rStream, nLength ); break;
352 case ECT_UINT: aRet += dump_uint( rStream, nLength ); break;
353 case ECT_UNISTRING: aRet += dump_unistring( rStream, nLength ); break;
354 case ETC_FLOAT: aRet += dump_float( rStream, nLength ); break;
355 case ECT_HEXDUMP:
356 default: aRet += dump_hex( rStream, nLength ); break;
359 return aRet;
362 OUString ElementConfig::dump_hex( SvStream& rStream, sal_Size& nLength )
364 char buffer[128];
365 OUString aOut, aEmpty;
366 OUString aHex, aAscii;
367 sal_Char c;
368 int nRow = 0;
369 while( nLength && (rStream.GetError() == 0) )
371 rStream >> c;
372 nLength--;
374 unsigned int i = c;
375 i &= 0xff;
376 sprintf( buffer, "%02x ", i );
377 aHex += OUString::createFromAscii( buffer );
379 if( !isprint( c ) )
380 c = '.';
382 aAscii += OUString( (sal_Unicode) c );
383 nRow++;
385 if( (nRow == 16) || (nLength==0) )
387 while( aHex.getLength() < (16*3) )
388 aHex += " ";
389 aOut += aHex;
390 aOut += aAscii;
391 aOut += "\n\r";
392 aHex = aEmpty;
393 aAscii = aEmpty;
394 nRow = 0;
398 aOut += aHex;
399 aOut += aAscii;
401 return aOut;
404 OUString ElementConfig::dump_byte( SvStream& rStream, sal_Size& nLength )
406 OUString aRet;
407 if( nLength >= sizeof(sal_Char) )
409 sal_Char c;
410 rStream >> c;
412 char buffer[128];
413 sprintf( buffer, "%u", (int)c );
414 aRet += OUString::createFromAscii( buffer );
415 nLength -= sizeof(sal_Char);
418 return aRet;
421 OUString ElementConfig::dump_uint( SvStream& rStream, sal_Size& nLength )
423 OUString aRet;
424 if( nLength >= sizeof( sal_uInt32 ) )
426 sal_uInt32 c;
427 rStream >> c;
429 char buffer[128];
430 sprintf( buffer, "%u", c );
431 aRet += OUString::createFromAscii( buffer );
432 nLength-= sizeof( sal_uInt32 );
435 return aRet;
438 OUString ElementConfig::dump_unistring( SvStream& rStream, sal_Size& nLength )
440 String aString = SvxMSDffManager::MSDFFReadZString( rStream, nLength, sal_True );
441 nLength = 0;
442 return aString;
445 OUString ElementConfig::dump_float( SvStream& rStream, sal_Size& nLength )
447 OUString aRet;
448 if( nLength >= sizeof( float ) )
450 float c;
451 rStream >> c;
453 char buffer[128];
454 sprintf( buffer, "%g", (double)c );
455 aRet += OUString::createFromAscii( buffer );
456 nLength-= sizeof( float );
459 return aRet;
464 OUString ElementConfigContainer::format( SvStream& rStream, sal_Size& nLength ) const
466 OUString aRet;
468 if( getType() == ETC_CONTAINER )
471 ElementConfigList::const_iterator aIter( maElementConfigList.begin() );
472 const ElementConfigList::const_iterator aEnd( maElementConfigList.end() );
473 while( (aIter != aEnd) && (nLength > 0) )
475 aRet += (*aIter++)->format( rStream, nLength );
476 if( (aIter != aEnd) || (nLength != 0) )
477 aRet += "\n\r";
480 if( nLength )
481 aRet += ElementConfig::dump_hex( rStream, nLength );
483 else
485 aRet = getName();
486 if( aRet.getLength() )
487 aRet += " = ";
489 OUString aValue;
490 switch( getType() )
492 case ECT_BYTE: aValue = dump_byte( rStream, nLength ); break;
493 case ECT_UINT: aValue = dump_uint( rStream, nLength ); break;
494 case ECT_UNISTRING: aValue = dump_unistring( rStream, nLength ); break;
495 case ETC_FLOAT: aValue = dump_float( rStream, nLength ); break;
496 case ECT_HEXDUMP:
497 default: aValue = dump_hex( rStream, nLength ); break;
500 if( aValue.getLength() )
502 if( !maElementConfigList.empty() )
504 ElementConfigList::const_iterator aIter( maElementConfigList.begin() );
505 const ElementConfigList::const_iterator aEnd( maElementConfigList.end() );
506 while( (aIter != aEnd) && (nLength > 0) )
508 ElementValueConfig* pValue = dynamic_cast< ElementValueConfig* >( (*aIter++).get() );
509 if( pValue && pValue->getValue() == aValue )
511 aValue = pValue->getName();
512 break;
517 else
519 aValue = "<empty!?>";
522 aRet += aValue;
525 return aRet;
530 OUString SwitchElementConfig::format( SvStream& rStream, sal_Size& nLength ) const
532 OUString aValue;
534 switch( getType() )
536 case ECT_BYTE: aValue = dump_byte( rStream, nLength ); break;
537 case ECT_UINT: aValue = dump_uint( rStream, nLength ); break;
538 case ETC_FLOAT: aValue = dump_float( rStream, nLength ); break;
539 case ECT_UNISTRING: aValue = dump_unistring( rStream, nLength ); break;
542 if( aValue.getLength() )
544 ElementConfigList::const_iterator aIter( maElementConfigList.begin() );
545 const ElementConfigList::const_iterator aEnd( maElementConfigList.end() );
546 while( (aIter != aEnd) && (nLength > 0) )
548 CaseElementConfig* pCase = dynamic_cast< CaseElementConfig* >( (*aIter++).get() );
549 if( pCase && pCase->getValue() == aValue )
550 return pCase->format( rStream, nLength );
554 return ElementConfig::dump_hex( rStream, nLength );
557 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */