update dev300-m58
[ooovba.git] / svx / workben / msview / xmlconfig.cxx
blob79473333d08612f7dbf17e46633208bc9d30570d
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: xmlconfig.cxx,v $
10 * $Revision: 1.5 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
32 // MARKER(update_precomp.py): autogen include statement, do not remove
33 #include "precompiled_svx.hxx"
34 #include <com/sun/star/xml/sax/XDocumentHandler.hpp>
35 #include <com/sun/star/xml/sax/InputSource.hpp>
36 #include <com/sun/star/xml/sax/XParser.hpp>
37 #include <com/sun/star/xml/sax/SAXParseException.hpp>
38 #include <com/sun/star/io/IOException.hpp>
39 #include <cppuhelper/implbase1.hxx>
40 #include <comphelper/processfactory.hxx>
41 #include <unotools/ucbstreamhelper.hxx>
42 #include <unotools/streamwrap.hxx>
43 #include <tools/debug.hxx>
44 #include "comphelper/anytostring.hxx"
45 #include "cppuhelper/exc_hlp.hxx"
46 #include "rtl/ref.hxx"
48 #include <svx/msdffimp.hxx>
50 #include "xmlconfig.hxx"
52 #include <stdio.h>
53 #include <ctype.h>
54 #include <stack>
56 using ::rtl::OUString;
57 using ::com::sun::star::io::XInputStream;
58 using ::com::sun::star::io::IOException;
60 using namespace ::com::sun::star::uno;
61 using namespace ::com::sun::star::xml::sax;
63 ///////////////////////////////////////////////////////////////////////
65 AtomConfigMap gAtomConfigMap;
67 ///////////////////////////////////////////////////////////////////////
69 class ConfigHandler : public ::cppu::WeakAggImplHelper1<XDocumentHandler>
71 public:
72 // XDocumentHandler
73 virtual void SAL_CALL startDocument(void) throw( SAXException, RuntimeException );
74 virtual void SAL_CALL endDocument(void) throw( SAXException, RuntimeException );
75 virtual void SAL_CALL startElement(const OUString& aName, const Reference< XAttributeList > & xAttribs) throw( SAXException, RuntimeException );
76 virtual void SAL_CALL endElement(const OUString& aName) throw( SAXException, RuntimeException );
77 virtual void SAL_CALL characters(const OUString& aChars) throw( SAXException, RuntimeException );
78 virtual void SAL_CALL ignorableWhitespace(const OUString& aWhitespaces) throw( SAXException, RuntimeException );
79 virtual void SAL_CALL processingInstruction(const OUString& aTarget, const OUString& aData) throw( SAXException, RuntimeException );
80 virtual void SAL_CALL setDocumentLocator(const Reference< XLocator > & xLocator) throw( SAXException, RuntimeException );
82 private:
83 void errorThrow( const OUString& rErrorMessage ) throw (SAXException );
84 ElementConfigType parseType( const OUString& rErrorMessage ) throw ( SAXException );
85 void addElement( ElementConfigPtr& rElementConfig ) throw ( SAXException );
86 OUString getAttribute( const Reference< XAttributeList > & xAttribs, const sal_Char* pName ) throw( SAXException );
88 ElementConfigPtr importAtomConfig( const Reference< XAttributeList > & xAttribs, bool bIsContainer ) throw( SAXException );
89 ElementConfigPtr importElementConfig( const Reference< XAttributeList > & xAttribs ) throw( SAXException );
90 ElementConfigPtr importSwitchConfig( const Reference< XAttributeList > & xAttribs ) throw( SAXException );
91 ElementConfigPtr importCaseConfig( const Reference< XAttributeList > & xAttribs ) throw( SAXException );
92 ElementConfigPtr importValueElementConfig( const Reference< XAttributeList > & xAttribs ) throw( SAXException );
94 std::stack< ElementConfigPtr > maElementStack;
97 void ConfigHandler::errorThrow( const OUString& rErrorMessage ) throw (SAXException )
99 Reference< XInterface > aContext;
100 Any aWrappedException;
101 throw SAXException(rErrorMessage, aContext, aWrappedException);
104 ElementConfigType ConfigHandler::parseType( const OUString& sType ) throw (SAXException )
106 if( sType.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("uint") ) )
108 return ECT_UINT;
110 else if( sType.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("byte") ) )
112 return ECT_BYTE;
114 else if( sType.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("unistring") ) )
116 return ECT_UNISTRING;
118 else if( sType.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("float") ) )
120 return ETC_FLOAT;
122 else if( sType.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("hexdump") ) )
125 else
127 OUString aMessage( RTL_CONSTASCII_USTRINGPARAM( "unknown type: " ) );
128 aMessage += sType;
129 errorThrow( aMessage );
132 return ECT_HEXDUMP;
135 void ConfigHandler::addElement( ElementConfigPtr& rElementConfig ) throw ( SAXException )
137 ElementConfigContainer* pParent = dynamic_cast< ElementConfigContainer* >( maElementStack.top().get() );
139 if( !pParent )
140 errorThrow( OUString( RTL_CONSTASCII_USTRINGPARAM( "illegal parent for element" ) ) );
143 pParent->addElementConfig( rElementConfig );
146 OUString ConfigHandler::getAttribute( const Reference< XAttributeList > & xAttribs, const sal_Char* pName ) throw( SAXException )
148 OUString aName( OUString::createFromAscii( pName ) );
150 const sal_Int16 nAttrCount = xAttribs.is() ? xAttribs->getLength() : 0;
151 sal_Int16 i;
152 for(i=0; i < nAttrCount; i++)
154 if( xAttribs->getNameByIndex( i ) == aName )
155 return xAttribs->getValueByIndex( i );
158 OUString aMessage( RTL_CONSTASCII_USTRINGPARAM( "missing required attribute: ") );
159 aMessage += aName;
160 errorThrow( aMessage );
162 return OUString();
165 void SAL_CALL ConfigHandler::startDocument(void) throw( SAXException, RuntimeException )
169 void SAL_CALL ConfigHandler::endDocument(void) throw( SAXException, RuntimeException )
173 void SAL_CALL ConfigHandler::startElement(const OUString& aName, const Reference< XAttributeList > & xAttribs) throw( SAXException, RuntimeException )
175 ElementConfigPtr pElement;
177 if( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "config" ) ) )
179 return;
182 if( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "container" ) ) )
184 pElement = importAtomConfig( xAttribs, true );
186 else if( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "atom" ) ) )
188 pElement = importAtomConfig( xAttribs, false );
190 else if( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "element" ) ) )
192 pElement = importElementConfig( xAttribs );
194 else if( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "value" ) ) )
196 pElement = importValueElementConfig( xAttribs );
198 else if( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "switch" ) ) )
200 pElement = importSwitchConfig( xAttribs );
202 else if( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "case" ) ) )
204 pElement = importCaseConfig( xAttribs );
207 if( !pElement.get() )
209 OUString aMessage( OUString( RTL_CONSTASCII_USTRINGPARAM("unknown config element: ")) );
210 aMessage += aName;
211 errorThrow( aMessage );
214 maElementStack.push( pElement );
217 sal_Int32 toInt( const OUString& rText )
219 if( rText.compareToAscii("0x",2) == 0)
221 sal_Int32 nValue = 0;
222 const sal_Unicode *p = rText;
223 p += 2;
224 sal_Int32 nLength = rText.getLength() - 2;
225 while( (nLength--) > 0 )
227 nValue <<= 4;
228 if( *p >= '0' && *p <= '9' )
230 nValue += *p - '0';
232 else if( *p >= 'a' && *p <= 'f' )
234 nValue += *p - ('a' - 10);
236 else if( *p >= 'A' && *p <= 'F' )
238 nValue += *p - ('A' - 10 );
240 p++;
243 return nValue;
245 else
247 return rText.toInt32();
251 ElementConfigPtr ConfigHandler::importAtomConfig( const Reference< XAttributeList > & xAttribs, bool bIsContainer ) throw (SAXException)
253 if( !maElementStack.empty() )
254 errorThrow( OUString( RTL_CONSTASCII_USTRINGPARAM("atom elements must be root" ) ) );
256 ElementConfigPtr aPtr( new AtomConfig( getAttribute(xAttribs,"name"), bIsContainer ) );
257 gAtomConfigMap[ (UINT16)toInt(getAttribute(xAttribs,"id"))] = aPtr;
258 return aPtr;
261 ElementConfigPtr ConfigHandler::importElementConfig( const Reference< XAttributeList > & xAttribs ) throw (SAXException)
263 ElementConfigType nType = parseType( getAttribute( xAttribs, "type" ) );
264 ElementConfigPtr pElementConfig( new ElementConfigContainer( getAttribute( xAttribs, "name" ), nType ) );
265 addElement( pElementConfig );
266 return pElementConfig;
269 ElementConfigPtr ConfigHandler::importValueElementConfig( const Reference< XAttributeList > & xAttribs ) throw (SAXException)
271 ElementConfigPtr pElementConfig( new ElementValueConfig( getAttribute( xAttribs, "name" ), getAttribute( xAttribs, "value" ) ) );
272 addElement( pElementConfig );
273 return pElementConfig;
276 ElementConfigPtr ConfigHandler::importSwitchConfig( const Reference< XAttributeList > & xAttribs ) throw (SAXException)
278 ElementConfigType nType = parseType( getAttribute( xAttribs, "type" ) );
279 ElementConfigPtr pElementConfig( new SwitchElementConfig( nType ) );
280 addElement( pElementConfig );
281 return pElementConfig;
284 ElementConfigPtr ConfigHandler::importCaseConfig( const Reference< XAttributeList > & xAttribs ) throw (SAXException)
286 ElementConfigPtr pElementConfig( new CaseElementConfig( getAttribute( xAttribs, "value" ) ) );
287 addElement( pElementConfig );
288 return pElementConfig;
291 void SAL_CALL ConfigHandler::endElement(const OUString& aName) throw( SAXException, RuntimeException )
293 if( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "config" ) ) )
295 return;
298 maElementStack.pop();
301 void SAL_CALL ConfigHandler::characters(const OUString& aChars) throw( SAXException, RuntimeException )
305 void SAL_CALL ConfigHandler::ignorableWhitespace(const OUString& aWhitespaces) throw( SAXException, RuntimeException )
309 void SAL_CALL ConfigHandler::processingInstruction(const OUString& aTarget, const OUString& aData) throw( SAXException, RuntimeException )
313 void SAL_CALL ConfigHandler::setDocumentLocator(const Reference< XLocator > & xLocator) throw( SAXException, RuntimeException )
317 void load_config( const OUString& rPath )
321 // create stream
322 SvStream* pIStm = ::utl::UcbStreamHelper::CreateStream( rPath, STREAM_READ );
323 Reference<XInputStream> xInputStream( new utl::OInputStreamWrapper( pIStm, sal_True ) );
325 // prepare ParserInputSrouce
326 InputSource aParserInput;
327 aParserInput.sSystemId = rPath;
328 aParserInput.aInputStream = xInputStream;
330 // get parser
331 Reference< XParser > xParser(
332 comphelper::getProcessServiceFactory()->createInstance(
333 OUString::createFromAscii("com.sun.star.xml.sax.Parser") ),
334 UNO_QUERY_THROW );
336 // get filter
337 ConfigHandler* pConfigHandler = new ConfigHandler();
338 Reference< XDocumentHandler > xFilter( pConfigHandler );
340 // connect parser and filter
341 xParser->setDocumentHandler( xFilter );
343 // finally, parser the stream
344 xParser->parseStream( aParserInput );
346 catch( Exception& r )
348 DBG_ERROR(
349 (rtl::OString("load_config(), "
350 "exception caught: ") +
351 rtl::OUStringToOString(
352 comphelper::anyToString( cppu::getCaughtException() ),
353 RTL_TEXTENCODING_UTF8 )).getStr() );
355 (void)r;
359 ///////////////////////////////////////////////////////////////////////
361 rtl::OUString ElementConfig::format( SvStream& rStream, sal_Size& nLength ) const
363 OUString aRet;
364 if( maName.getLength() )
366 aRet += maName;
367 aRet += OUString( RTL_CONSTASCII_USTRINGPARAM( " = " ) );
370 switch( mnType )
372 case ECT_BYTE: aRet += dump_byte( rStream, nLength ); break;
373 case ECT_UINT: aRet += dump_uint( rStream, nLength ); break;
374 case ECT_UNISTRING: aRet += dump_unistring( rStream, nLength ); break;
375 case ETC_FLOAT: aRet += dump_float( rStream, nLength ); break;
376 case ECT_HEXDUMP:
377 default: aRet += dump_hex( rStream, nLength ); break;
380 return aRet;
383 rtl::OUString ElementConfig::dump_hex( SvStream& rStream, sal_Size& nLength )
385 char buffer[128];
386 OUString aOut, aEmpty;
387 OUString aHex, aAscii;
388 sal_Char c;
389 int nRow = 0;
390 while( nLength && (rStream.GetError() == 0) )
392 rStream >> c;
393 nLength--;
395 unsigned int i = c;
396 i &= 0xff;
397 sprintf( buffer, "%02x ", i );
398 aHex += OUString::createFromAscii( buffer );
400 if( !isprint( c ) )
401 c = '.';
403 aAscii += OUString( (sal_Unicode) c );
404 nRow++;
406 if( (nRow == 16) || (nLength==0) )
408 while( aHex.getLength() < (16*3) )
409 aHex += OUString( RTL_CONSTASCII_USTRINGPARAM(" ") );
410 aOut += aHex;
411 aOut += aAscii;
412 aOut += OUString( RTL_CONSTASCII_USTRINGPARAM( "\n\r" ) );
413 aHex = aEmpty;
414 aAscii = aEmpty;
415 nRow = 0;
419 aOut += aHex;
420 aOut += aAscii;
422 return aOut;
425 rtl::OUString ElementConfig::dump_byte( SvStream& rStream, sal_Size& nLength )
427 OUString aRet;
428 if( nLength >= sizeof(sal_Char) )
430 sal_Char c;
431 rStream >> c;
433 char buffer[128];
434 sprintf( buffer, "%u", (int)c );
435 aRet += OUString::createFromAscii( buffer );
436 nLength -= sizeof(sal_Char);
439 return aRet;
442 rtl::OUString ElementConfig::dump_uint( SvStream& rStream, sal_Size& nLength )
444 OUString aRet;
445 if( nLength >= sizeof( sal_uInt32 ) )
447 sal_uInt32 c;
448 rStream >> c;
450 char buffer[128];
451 sprintf( buffer, "%u", c );
452 aRet += OUString::createFromAscii( buffer );
453 nLength-= sizeof( sal_uInt32 );
456 return aRet;
459 rtl::OUString ElementConfig::dump_unistring( SvStream& rStream, sal_Size& nLength )
461 String aString;
462 SvxMSDffManager::MSDFFReadZString( rStream, aString, nLength, sal_True );
463 nLength = 0;
464 return aString;
467 rtl::OUString ElementConfig::dump_float( SvStream& rStream, sal_Size& nLength )
469 OUString aRet;
470 if( nLength >= sizeof( float ) )
472 float c;
473 rStream >> c;
475 char buffer[128];
476 sprintf( buffer, "%g", (double)c );
477 aRet += OUString::createFromAscii( buffer );
478 nLength-= sizeof( float );
481 return aRet;
484 ///////////////////////////////////////////////////////////////////////
486 rtl::OUString ElementConfigContainer::format( SvStream& rStream, sal_Size& nLength ) const
488 OUString aRet;
490 if( getType() == ETC_CONTAINER )
493 ElementConfigList::const_iterator aIter( maElementConfigList.begin() );
494 const ElementConfigList::const_iterator aEnd( maElementConfigList.end() );
495 while( (aIter != aEnd) && (nLength > 0) )
497 aRet += (*aIter++)->format( rStream, nLength );
498 if( (aIter != aEnd) || (nLength != 0) )
499 aRet += OUString( RTL_CONSTASCII_USTRINGPARAM( "\n\r" ) );
502 if( nLength )
503 aRet += ElementConfig::dump_hex( rStream, nLength );
505 else
507 aRet = getName();
508 if( aRet.getLength() )
509 aRet += OUString( RTL_CONSTASCII_USTRINGPARAM( " = " ) );
511 OUString aValue;
512 switch( getType() )
514 case ECT_BYTE: aValue = dump_byte( rStream, nLength ); break;
515 case ECT_UINT: aValue = dump_uint( rStream, nLength ); break;
516 case ECT_UNISTRING: aValue = dump_unistring( rStream, nLength ); break;
517 case ETC_FLOAT: aValue = dump_float( rStream, nLength ); break;
518 case ECT_HEXDUMP:
519 default: aValue = dump_hex( rStream, nLength ); break;
522 if( aValue.getLength() )
524 if( !maElementConfigList.empty() )
526 ElementConfigList::const_iterator aIter( maElementConfigList.begin() );
527 const ElementConfigList::const_iterator aEnd( maElementConfigList.end() );
528 while( (aIter != aEnd) && (nLength > 0) )
530 ElementValueConfig* pValue = dynamic_cast< ElementValueConfig* >( (*aIter++).get() );
531 if( pValue && pValue->getValue() == aValue )
533 aValue = pValue->getName();
534 break;
539 else
541 aValue = OUString( RTL_CONSTASCII_USTRINGPARAM("<empty!?>") );
544 aRet += aValue;
547 return aRet;
550 ///////////////////////////////////////////////////////////////////////
552 rtl::OUString SwitchElementConfig::format( SvStream& rStream, sal_Size& nLength ) const
554 OUString aValue;
556 switch( getType() )
558 case ECT_BYTE: aValue = dump_byte( rStream, nLength ); break;
559 case ECT_UINT: aValue = dump_uint( rStream, nLength ); break;
560 case ETC_FLOAT: aValue = dump_float( rStream, nLength ); break;
561 case ECT_UNISTRING: aValue = dump_unistring( rStream, nLength ); break;
564 if( aValue.getLength() )
566 ElementConfigList::const_iterator aIter( maElementConfigList.begin() );
567 const ElementConfigList::const_iterator aEnd( maElementConfigList.end() );
568 while( (aIter != aEnd) && (nLength > 0) )
570 CaseElementConfig* pCase = dynamic_cast< CaseElementConfig* >( (*aIter++).get() );
571 if( pCase && pCase->getValue() == aValue )
572 return pCase->format( rStream, nLength );
576 return ElementConfig::dump_hex( rStream, nLength );