diff options
Diffstat (limited to 'svx/workben/msview/xmlconfig.cxx')
-rw-r--r-- | svx/workben/msview/xmlconfig.cxx | 575 |
1 files changed, 575 insertions, 0 deletions
diff --git a/svx/workben/msview/xmlconfig.cxx b/svx/workben/msview/xmlconfig.cxx new file mode 100644 index 000000000000..92ac7a402851 --- /dev/null +++ b/svx/workben/msview/xmlconfig.cxx @@ -0,0 +1,575 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svx.hxx" +#include <com/sun/star/xml/sax/XDocumentHandler.hpp> +#include <com/sun/star/xml/sax/InputSource.hpp> +#include <com/sun/star/xml/sax/XParser.hpp> +#include <com/sun/star/xml/sax/SAXParseException.hpp> +#include <com/sun/star/io/IOException.hpp> +#include <cppuhelper/implbase1.hxx> +#include <comphelper/processfactory.hxx> +#include <unotools/ucbstreamhelper.hxx> +#include <unotools/streamwrap.hxx> +#include <tools/debug.hxx> +#include "comphelper/anytostring.hxx" +#include "cppuhelper/exc_hlp.hxx" +#include "rtl/ref.hxx" + +#include <svx/msdffimp.hxx> + +#include "xmlconfig.hxx" + +#include <stdio.h> +#include <ctype.h> +#include <stack> + +using ::rtl::OUString; +using ::com::sun::star::io::XInputStream; +using ::com::sun::star::io::IOException; + +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::xml::sax; + +/////////////////////////////////////////////////////////////////////// + +AtomConfigMap gAtomConfigMap; + +/////////////////////////////////////////////////////////////////////// + +class ConfigHandler : public ::cppu::WeakAggImplHelper1<XDocumentHandler> +{ +public: + // XDocumentHandler + virtual void SAL_CALL startDocument(void) throw( SAXException, RuntimeException ); + virtual void SAL_CALL endDocument(void) throw( SAXException, RuntimeException ); + virtual void SAL_CALL startElement(const OUString& aName, const Reference< XAttributeList > & xAttribs) throw( SAXException, RuntimeException ); + virtual void SAL_CALL endElement(const OUString& aName) throw( SAXException, RuntimeException ); + virtual void SAL_CALL characters(const OUString& aChars) throw( SAXException, RuntimeException ); + virtual void SAL_CALL ignorableWhitespace(const OUString& aWhitespaces) throw( SAXException, RuntimeException ); + virtual void SAL_CALL processingInstruction(const OUString& aTarget, const OUString& aData) throw( SAXException, RuntimeException ); + virtual void SAL_CALL setDocumentLocator(const Reference< XLocator > & xLocator) throw( SAXException, RuntimeException ); + +private: + void errorThrow( const OUString& rErrorMessage ) throw (SAXException ); + ElementConfigType parseType( const OUString& rErrorMessage ) throw ( SAXException ); + void addElement( ElementConfigPtr& rElementConfig ) throw ( SAXException ); + OUString getAttribute( const Reference< XAttributeList > & xAttribs, const sal_Char* pName ) throw( SAXException ); + + ElementConfigPtr importAtomConfig( const Reference< XAttributeList > & xAttribs, bool bIsContainer ) throw( SAXException ); + ElementConfigPtr importElementConfig( const Reference< XAttributeList > & xAttribs ) throw( SAXException ); + ElementConfigPtr importSwitchConfig( const Reference< XAttributeList > & xAttribs ) throw( SAXException ); + ElementConfigPtr importCaseConfig( const Reference< XAttributeList > & xAttribs ) throw( SAXException ); + ElementConfigPtr importValueElementConfig( const Reference< XAttributeList > & xAttribs ) throw( SAXException ); + + std::stack< ElementConfigPtr > maElementStack; +}; + +void ConfigHandler::errorThrow( const OUString& rErrorMessage ) throw (SAXException ) +{ + Reference< XInterface > aContext; + Any aWrappedException; + throw SAXException(rErrorMessage, aContext, aWrappedException); +} + +ElementConfigType ConfigHandler::parseType( const OUString& sType ) throw (SAXException ) +{ + if( sType.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("uint") ) ) + { + return ECT_UINT; + } + else if( sType.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("byte") ) ) + { + return ECT_BYTE; + } + else if( sType.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("unistring") ) ) + { + return ECT_UNISTRING; + } + else if( sType.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("float") ) ) + { + return ETC_FLOAT; + } + else if( sType.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("hexdump") ) ) + { + } + else + { + OUString aMessage( RTL_CONSTASCII_USTRINGPARAM( "unknown type: " ) ); + aMessage += sType; + errorThrow( aMessage ); + } + + return ECT_HEXDUMP; +} + +void ConfigHandler::addElement( ElementConfigPtr& rElementConfig ) throw ( SAXException ) +{ + ElementConfigContainer* pParent = dynamic_cast< ElementConfigContainer* >( maElementStack.top().get() ); + + if( !pParent ) + errorThrow( OUString( RTL_CONSTASCII_USTRINGPARAM( "illegal parent for element" ) ) ); + + + pParent->addElementConfig( rElementConfig ); +} + +OUString ConfigHandler::getAttribute( const Reference< XAttributeList > & xAttribs, const sal_Char* pName ) throw( SAXException ) +{ + OUString aName( OUString::createFromAscii( pName ) ); + + const sal_Int16 nAttrCount = xAttribs.is() ? xAttribs->getLength() : 0; + sal_Int16 i; + for(i=0; i < nAttrCount; i++) + { + if( xAttribs->getNameByIndex( i ) == aName ) + return xAttribs->getValueByIndex( i ); + } + + OUString aMessage( RTL_CONSTASCII_USTRINGPARAM( "missing required attribute: ") ); + aMessage += aName; + errorThrow( aMessage ); + + return OUString(); +} + +void SAL_CALL ConfigHandler::startDocument(void) throw( SAXException, RuntimeException ) +{ +} + +void SAL_CALL ConfigHandler::endDocument(void) throw( SAXException, RuntimeException ) +{ +} + +void SAL_CALL ConfigHandler::startElement(const OUString& aName, const Reference< XAttributeList > & xAttribs) throw( SAXException, RuntimeException ) +{ + ElementConfigPtr pElement; + + if( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "config" ) ) ) + { + return; + } + + if( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "container" ) ) ) + { + pElement = importAtomConfig( xAttribs, true ); + } + else if( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "atom" ) ) ) + { + pElement = importAtomConfig( xAttribs, false ); + } + else if( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "element" ) ) ) + { + pElement = importElementConfig( xAttribs ); + } + else if( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "value" ) ) ) + { + pElement = importValueElementConfig( xAttribs ); + } + else if( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "switch" ) ) ) + { + pElement = importSwitchConfig( xAttribs ); + } + else if( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "case" ) ) ) + { + pElement = importCaseConfig( xAttribs ); + } + + if( !pElement.get() ) + { + OUString aMessage( OUString( RTL_CONSTASCII_USTRINGPARAM("unknown config element: ")) ); + aMessage += aName; + errorThrow( aMessage ); + } + + maElementStack.push( pElement ); +} + +sal_Int32 toInt( const OUString& rText ) +{ + if( rText.compareToAscii("0x",2) == 0) + { + sal_Int32 nValue = 0; + const sal_Unicode *p = rText; + p += 2; + sal_Int32 nLength = rText.getLength() - 2; + while( (nLength--) > 0 ) + { + nValue <<= 4; + if( *p >= '0' && *p <= '9' ) + { + nValue += *p - '0'; + } + else if( *p >= 'a' && *p <= 'f' ) + { + nValue += *p - ('a' - 10); + } + else if( *p >= 'A' && *p <= 'F' ) + { + nValue += *p - ('A' - 10 ); + } + p++; + } + + return nValue; + } + else + { + return rText.toInt32(); + } +} + +ElementConfigPtr ConfigHandler::importAtomConfig( const Reference< XAttributeList > & xAttribs, bool bIsContainer ) throw (SAXException) +{ + if( !maElementStack.empty() ) + errorThrow( OUString( RTL_CONSTASCII_USTRINGPARAM("atom elements must be root" ) ) ); + + ElementConfigPtr aPtr( new AtomConfig( getAttribute(xAttribs,"name"), bIsContainer ) ); + gAtomConfigMap[ (UINT16)toInt(getAttribute(xAttribs,"id"))] = aPtr; + return aPtr; +} + +ElementConfigPtr ConfigHandler::importElementConfig( const Reference< XAttributeList > & xAttribs ) throw (SAXException) +{ + ElementConfigType nType = parseType( getAttribute( xAttribs, "type" ) ); + ElementConfigPtr pElementConfig( new ElementConfigContainer( getAttribute( xAttribs, "name" ), nType ) ); + addElement( pElementConfig ); + return pElementConfig; +} + +ElementConfigPtr ConfigHandler::importValueElementConfig( const Reference< XAttributeList > & xAttribs ) throw (SAXException) +{ + ElementConfigPtr pElementConfig( new ElementValueConfig( getAttribute( xAttribs, "name" ), getAttribute( xAttribs, "value" ) ) ); + addElement( pElementConfig ); + return pElementConfig; +} + +ElementConfigPtr ConfigHandler::importSwitchConfig( const Reference< XAttributeList > & xAttribs ) throw (SAXException) +{ + ElementConfigType nType = parseType( getAttribute( xAttribs, "type" ) ); + ElementConfigPtr pElementConfig( new SwitchElementConfig( nType ) ); + addElement( pElementConfig ); + return pElementConfig; +} + +ElementConfigPtr ConfigHandler::importCaseConfig( const Reference< XAttributeList > & xAttribs ) throw (SAXException) +{ + ElementConfigPtr pElementConfig( new CaseElementConfig( getAttribute( xAttribs, "value" ) ) ); + addElement( pElementConfig ); + return pElementConfig; +} + +void SAL_CALL ConfigHandler::endElement(const OUString& aName) throw( SAXException, RuntimeException ) +{ + if( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "config" ) ) ) + { + return; + } + + maElementStack.pop(); +} + +void SAL_CALL ConfigHandler::characters(const OUString& aChars) throw( SAXException, RuntimeException ) +{ +} + +void SAL_CALL ConfigHandler::ignorableWhitespace(const OUString& aWhitespaces) throw( SAXException, RuntimeException ) +{ +} + +void SAL_CALL ConfigHandler::processingInstruction(const OUString& aTarget, const OUString& aData) throw( SAXException, RuntimeException ) +{ +} + +void SAL_CALL ConfigHandler::setDocumentLocator(const Reference< XLocator > & xLocator) throw( SAXException, RuntimeException ) +{ +} + +void load_config( const OUString& rPath ) +{ + try + { + // create stream + SvStream* pIStm = ::utl::UcbStreamHelper::CreateStream( rPath, STREAM_READ ); + Reference<XInputStream> xInputStream( new utl::OInputStreamWrapper( pIStm, sal_True ) ); + + // prepare ParserInputSrouce + InputSource aParserInput; + aParserInput.sSystemId = rPath; + aParserInput.aInputStream = xInputStream; + + // get parser + Reference< XParser > xParser( + comphelper::getProcessServiceFactory()->createInstance( + OUString::createFromAscii("com.sun.star.xml.sax.Parser") ), + UNO_QUERY_THROW ); + + // get filter + ConfigHandler* pConfigHandler = new ConfigHandler(); + Reference< XDocumentHandler > xFilter( pConfigHandler ); + + // connect parser and filter + xParser->setDocumentHandler( xFilter ); + + // finally, parser the stream + xParser->parseStream( aParserInput ); + } + catch( Exception& r ) + { + DBG_ERROR( + (rtl::OString("load_config(), " + "exception caught: ") + + rtl::OUStringToOString( + comphelper::anyToString( cppu::getCaughtException() ), + RTL_TEXTENCODING_UTF8 )).getStr() ); + + (void)r; + } +} + +/////////////////////////////////////////////////////////////////////// + +rtl::OUString ElementConfig::format( SvStream& rStream, sal_Size& nLength ) const +{ + OUString aRet; + if( maName.getLength() ) + { + aRet += maName; + aRet += OUString( RTL_CONSTASCII_USTRINGPARAM( " = " ) ); + } + + switch( mnType ) + { + case ECT_BYTE: aRet += dump_byte( rStream, nLength ); break; + case ECT_UINT: aRet += dump_uint( rStream, nLength ); break; + case ECT_UNISTRING: aRet += dump_unistring( rStream, nLength ); break; + case ETC_FLOAT: aRet += dump_float( rStream, nLength ); break; + case ECT_HEXDUMP: + default: aRet += dump_hex( rStream, nLength ); break; + } + + return aRet; +} + +rtl::OUString ElementConfig::dump_hex( SvStream& rStream, sal_Size& nLength ) +{ + char buffer[128]; + OUString aOut, aEmpty; + OUString aHex, aAscii; + sal_Char c; + int nRow = 0; + while( nLength && (rStream.GetError() == 0) ) + { + rStream >> c; + nLength--; + + unsigned int i = c; + i &= 0xff; + sprintf( buffer, "%02x ", i ); + aHex += OUString::createFromAscii( buffer ); + + if( !isprint( c ) ) + c = '.'; + + aAscii += OUString( (sal_Unicode) c ); + nRow++; + + if( (nRow == 16) || (nLength==0) ) + { + while( aHex.getLength() < (16*3) ) + aHex += OUString( RTL_CONSTASCII_USTRINGPARAM(" ") ); + aOut += aHex; + aOut += aAscii; + aOut += OUString( RTL_CONSTASCII_USTRINGPARAM( "\n\r" ) ); + aHex = aEmpty; + aAscii = aEmpty; + nRow = 0; + } + } + + aOut += aHex; + aOut += aAscii; + + return aOut; +} + +rtl::OUString ElementConfig::dump_byte( SvStream& rStream, sal_Size& nLength ) +{ + OUString aRet; + if( nLength >= sizeof(sal_Char) ) + { + sal_Char c; + rStream >> c; + + char buffer[128]; + sprintf( buffer, "%u", (int)c ); + aRet += OUString::createFromAscii( buffer ); + nLength -= sizeof(sal_Char); + } + + return aRet; +} + +rtl::OUString ElementConfig::dump_uint( SvStream& rStream, sal_Size& nLength ) +{ + OUString aRet; + if( nLength >= sizeof( sal_uInt32 ) ) + { + sal_uInt32 c; + rStream >> c; + + char buffer[128]; + sprintf( buffer, "%u", c ); + aRet += OUString::createFromAscii( buffer ); + nLength-= sizeof( sal_uInt32 ); + } + + return aRet; +} + +rtl::OUString ElementConfig::dump_unistring( SvStream& rStream, sal_Size& nLength ) +{ + String aString; + SvxMSDffManager::MSDFFReadZString( rStream, aString, nLength, sal_True ); + nLength = 0; + return aString; +} + +rtl::OUString ElementConfig::dump_float( SvStream& rStream, sal_Size& nLength ) +{ + OUString aRet; + if( nLength >= sizeof( float ) ) + { + float c; + rStream >> c; + + char buffer[128]; + sprintf( buffer, "%g", (double)c ); + aRet += OUString::createFromAscii( buffer ); + nLength-= sizeof( float ); + } + + return aRet; +} + +/////////////////////////////////////////////////////////////////////// + +rtl::OUString ElementConfigContainer::format( SvStream& rStream, sal_Size& nLength ) const +{ + OUString aRet; + + if( getType() == ETC_CONTAINER ) + { + + ElementConfigList::const_iterator aIter( maElementConfigList.begin() ); + const ElementConfigList::const_iterator aEnd( maElementConfigList.end() ); + while( (aIter != aEnd) && (nLength > 0) ) + { + aRet += (*aIter++)->format( rStream, nLength ); + if( (aIter != aEnd) || (nLength != 0) ) + aRet += OUString( RTL_CONSTASCII_USTRINGPARAM( "\n\r" ) ); + } + + if( nLength ) + aRet += ElementConfig::dump_hex( rStream, nLength ); + } + else + { + aRet = getName(); + if( aRet.getLength() ) + aRet += OUString( RTL_CONSTASCII_USTRINGPARAM( " = " ) ); + + OUString aValue; + switch( getType() ) + { + case ECT_BYTE: aValue = dump_byte( rStream, nLength ); break; + case ECT_UINT: aValue = dump_uint( rStream, nLength ); break; + case ECT_UNISTRING: aValue = dump_unistring( rStream, nLength ); break; + case ETC_FLOAT: aValue = dump_float( rStream, nLength ); break; + case ECT_HEXDUMP: + default: aValue = dump_hex( rStream, nLength ); break; + } + + if( aValue.getLength() ) + { + if( !maElementConfigList.empty() ) + { + ElementConfigList::const_iterator aIter( maElementConfigList.begin() ); + const ElementConfigList::const_iterator aEnd( maElementConfigList.end() ); + while( (aIter != aEnd) && (nLength > 0) ) + { + ElementValueConfig* pValue = dynamic_cast< ElementValueConfig* >( (*aIter++).get() ); + if( pValue && pValue->getValue() == aValue ) + { + aValue = pValue->getName(); + break; + } + } + } + } + else + { + aValue = OUString( RTL_CONSTASCII_USTRINGPARAM("<empty!?>") ); + } + + aRet += aValue; + } + + return aRet; +} + +/////////////////////////////////////////////////////////////////////// + +rtl::OUString SwitchElementConfig::format( SvStream& rStream, sal_Size& nLength ) const +{ + OUString aValue; + + switch( getType() ) + { + case ECT_BYTE: aValue = dump_byte( rStream, nLength ); break; + case ECT_UINT: aValue = dump_uint( rStream, nLength ); break; + case ETC_FLOAT: aValue = dump_float( rStream, nLength ); break; + case ECT_UNISTRING: aValue = dump_unistring( rStream, nLength ); break; + } + + if( aValue.getLength() ) + { + ElementConfigList::const_iterator aIter( maElementConfigList.begin() ); + const ElementConfigList::const_iterator aEnd( maElementConfigList.end() ); + while( (aIter != aEnd) && (nLength > 0) ) + { + CaseElementConfig* pCase = dynamic_cast< CaseElementConfig* >( (*aIter++).get() ); + if( pCase && pCase->getValue() == aValue ) + return pCase->format( rStream, nLength ); + } + } + + return ElementConfig::dump_hex( rStream, nLength ); +} + |