summaryrefslogtreecommitdiff
path: root/sax
diff options
context:
space:
mode:
Diffstat (limited to 'sax')
-rw-r--r--sax/prj/d.lst2
-rw-r--r--sax/source/expatwrap/attrlistimpl.cxx233
-rw-r--r--sax/source/expatwrap/attrlistimpl.hxx94
-rw-r--r--sax/source/expatwrap/factory.hxx67
-rw-r--r--sax/source/expatwrap/makefile.mk92
-rw-r--r--sax/source/expatwrap/sax_expat.cxx1043
-rw-r--r--sax/source/expatwrap/saxwriter.cxx736
-rw-r--r--sax/source/expatwrap/xml2utf.cxx607
-rw-r--r--sax/test/makefile.mk101
-rw-r--r--sax/test/sax/exports.dxp3
-rw-r--r--sax/test/sax/factory.hxx122
-rw-r--r--sax/test/sax/makefile.mk99
-rw-r--r--sax/test/sax/testsax.cxx902
-rw-r--r--sax/test/sax/testwriter.cxx714
-rw-r--r--sax/test/saxdemo.cxx693
-rw-r--r--sax/test/testcomponent.cxx267
-rw-r--r--sax/util/makefile.mk93
17 files changed, 5868 insertions, 0 deletions
diff --git a/sax/prj/d.lst b/sax/prj/d.lst
new file mode 100644
index 000000000000..a787c3a4c3c0
--- /dev/null
+++ b/sax/prj/d.lst
@@ -0,0 +1,2 @@
+..\%__SRC%\bin\*.dll %_DEST%\bin%_EXT%\*
+..\%__SRC%\lib\*.so %_DEST%\lib%_EXT%\*
diff --git a/sax/source/expatwrap/attrlistimpl.cxx b/sax/source/expatwrap/attrlistimpl.cxx
new file mode 100644
index 000000000000..1d4a36c6f699
--- /dev/null
+++ b/sax/source/expatwrap/attrlistimpl.cxx
@@ -0,0 +1,233 @@
+/*************************************************************************
+ *
+ * $RCSfile: attrlistimpl.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 16:43:12 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#include <vector>
+
+#include <assert.h>
+
+#include <cppuhelper/weak.hxx>
+
+#include <com/sun/star/xml/sax/XAttributeList.hpp>
+#include <com/sun/star/util/XCloneable.hpp>
+
+using namespace ::std;
+using namespace ::rtl;
+using namespace ::cppu;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::xml::sax;
+
+#include "attrlistimpl.hxx"
+
+struct TagAttribute
+{
+ TagAttribute()
+ {}
+ TagAttribute( const OUString &sName, const OUString &sType , const OUString &sValue )
+ {
+ this->sName = sName;
+ this->sType = sType;
+ this->sValue = sValue;
+ }
+
+ OUString sName;
+ OUString sType;
+ OUString sValue;
+};
+
+struct AttributeListImpl_impl
+{
+ AttributeListImpl_impl()
+ {
+ // performance improvement during adding
+ vecAttribute.reserve(20);
+ }
+ vector<struct TagAttribute> vecAttribute;
+};
+
+
+
+sal_Int16 AttributeListImpl::getLength(void) throw (RuntimeException)
+{
+ return m_pImpl->vecAttribute.size();
+}
+
+
+AttributeListImpl::AttributeListImpl( const AttributeListImpl &r )
+{
+ m_pImpl = new AttributeListImpl_impl;
+ *m_pImpl = *(r.m_pImpl);
+}
+
+OUString AttributeListImpl::getNameByIndex(sal_Int16 i) throw (RuntimeException)
+{
+ if( i < m_pImpl->vecAttribute.size() ) {
+ return m_pImpl->vecAttribute[i].sName;
+ }
+ return OUString();
+}
+
+
+OUString AttributeListImpl::getTypeByIndex(sal_Int16 i) throw (RuntimeException)
+{
+ if( i < m_pImpl->vecAttribute.size() ) {
+ return m_pImpl->vecAttribute[i].sType;
+ }
+ return OUString();
+}
+
+OUString AttributeListImpl::getValueByIndex(sal_Int16 i) throw (RuntimeException)
+{
+ if( i < m_pImpl->vecAttribute.size() ) {
+ return m_pImpl->vecAttribute[i].sValue;
+ }
+ return OUString();
+
+}
+
+OUString AttributeListImpl::getTypeByName( const OUString& sName ) throw (RuntimeException)
+{
+ vector<struct TagAttribute>::iterator ii = m_pImpl->vecAttribute.begin();
+
+ for( ; ii != m_pImpl->vecAttribute.end() ; ii ++ ) {
+ if( (*ii).sName == sName ) {
+ return (*ii).sType;
+ }
+ }
+ return OUString();
+}
+
+OUString AttributeListImpl::getValueByName(const OUString& sName) throw (RuntimeException)
+{
+ vector<struct TagAttribute>::iterator ii = m_pImpl->vecAttribute.begin();
+
+ for( ; ii != m_pImpl->vecAttribute.end() ; ii ++ ) {
+ if( (*ii).sName == sName ) {
+ return (*ii).sValue;
+ }
+ }
+ return OUString();
+}
+
+
+Reference< XCloneable > AttributeListImpl::createClone() throw (RuntimeException)
+{
+ AttributeListImpl *p = new AttributeListImpl( *this );
+ return Reference< XCloneable > ( (XCloneable * ) p );
+}
+
+
+
+AttributeListImpl::AttributeListImpl()
+{
+ m_pImpl = new AttributeListImpl_impl;
+}
+
+
+
+AttributeListImpl::~AttributeListImpl()
+{
+ delete m_pImpl;
+}
+
+
+void AttributeListImpl::addAttribute( const OUString &sName ,
+ const OUString &sType ,
+ const OUString &sValue )
+{
+ m_pImpl->vecAttribute.push_back( TagAttribute( sName , sType , sValue ) );
+}
+
+void AttributeListImpl::clear()
+{
+ m_pImpl->vecAttribute.clear();
+}
+
+void AttributeListImpl::removeAttribute( const OUString &sName )
+{
+ vector<struct TagAttribute>::iterator ii = m_pImpl->vecAttribute.begin();
+
+ for( ; ii != m_pImpl->vecAttribute.end() ; ii ++ ) {
+ if( (*ii).sName == sName ) {
+ m_pImpl->vecAttribute.erase( ii );
+ break;
+ }
+ }
+}
+
+
+void AttributeListImpl::setAttributeList( const Reference< XAttributeList > &r )
+{
+ assert( r.is() );
+
+ sal_Int16 nMax = r->getLength();
+ clear();
+ m_pImpl->vecAttribute.reserve( nMax );
+
+ for( int i = 0 ; i < nMax ; i ++ ) {
+ m_pImpl->vecAttribute.push_back( TagAttribute( r->getNameByIndex( i ) ,
+ r->getTypeByIndex( i ) ,
+ r->getValueByIndex( i ) ) );
+ }
+
+ assert( nMax == getLength() );
+}
+
diff --git a/sax/source/expatwrap/attrlistimpl.hxx b/sax/source/expatwrap/attrlistimpl.hxx
new file mode 100644
index 000000000000..d618e5259719
--- /dev/null
+++ b/sax/source/expatwrap/attrlistimpl.hxx
@@ -0,0 +1,94 @@
+/*************************************************************************
+ *
+ * $RCSfile: attrlistimpl.hxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 16:43:13 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#include <cppuhelper/implbase2.hxx>
+
+
+struct AttributeListImpl_impl;
+
+class AttributeListImpl :
+ public WeakImplHelper2< XAttributeList, XCloneable >
+{
+public:
+ AttributeListImpl();
+ AttributeListImpl( const AttributeListImpl & );
+ ~AttributeListImpl();
+
+public:
+ virtual sal_Int16 SAL_CALL getLength(void) throw(RuntimeException);
+ virtual OUString SAL_CALL getNameByIndex(sal_Int16 i) throw(RuntimeException);
+ virtual OUString SAL_CALL getTypeByIndex(sal_Int16 i) throw(RuntimeException);
+ virtual OUString SAL_CALL getTypeByName(const OUString& aName) throw(RuntimeException);
+ virtual OUString SAL_CALL getValueByIndex(sal_Int16 i) throw(RuntimeException);
+ virtual OUString SAL_CALL getValueByName(const OUString& aName) throw( RuntimeException);
+
+public:
+ virtual Reference< XCloneable > SAL_CALL createClone() throw(RuntimeException);
+
+public:
+ void addAttribute( const OUString &sName , const OUString &sType , const OUString &sValue );
+ void clear();
+ void removeAttribute( const OUString &sName );
+ void setAttributeList( const Reference< XAttributeList > & );
+
+private:
+ struct AttributeListImpl_impl *m_pImpl;
+};
+
diff --git a/sax/source/expatwrap/factory.hxx b/sax/source/expatwrap/factory.hxx
new file mode 100644
index 000000000000..57698321b574
--- /dev/null
+++ b/sax/source/expatwrap/factory.hxx
@@ -0,0 +1,67 @@
+/*************************************************************************
+ *
+ * $RCSfile: factory.hxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 16:43:13 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+Reference< XInterface > SAL_CALL SaxWriter_CreateInstance(
+ const Reference< XMultiServiceFactory > & rSMgr ) throw (Exception);
+OUString SaxWriter_getServiceName();
+OUString SaxWriter_getImplementationName();
+Sequence< OUString > SaxWriter_getSupportedServiceNames(void) throw();
+
+
diff --git a/sax/source/expatwrap/makefile.mk b/sax/source/expatwrap/makefile.mk
new file mode 100644
index 000000000000..19119165b1a1
--- /dev/null
+++ b/sax/source/expatwrap/makefile.mk
@@ -0,0 +1,92 @@
+#*************************************************************************
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.1.1.1 $
+#
+# last change: $Author: hr $ $Date: 2000-09-18 16:43:13 $
+#
+# The Contents of this file are made available subject to the terms of
+# either of the following licenses
+#
+# - GNU Lesser General Public License Version 2.1
+# - Sun Industry Standards Source License Version 1.1
+#
+# Sun Microsystems Inc., October, 2000
+#
+# GNU Lesser General Public License Version 2.1
+# =============================================
+# Copyright 2000 by Sun Microsystems, Inc.
+# 901 San Antonio Road, Palo Alto, CA 94303, USA
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License version 2.1, as published by the Free Software Foundation.
+#
+# This library 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 for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+#
+# Sun Industry Standards Source License Version 1.1
+# =================================================
+# The contents of this file are subject to the Sun Industry Standards
+# Source License Version 1.1 (the "License"); You may not use this file
+# except in compliance with the License. You may obtain a copy of the
+# License at http://www.openoffice.org/license.html.
+#
+# Software provided under this License is provided on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+# WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+# MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+# See the License for the specific provisions governing your rights and
+# obligations concerning the Software.
+#
+# The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+#
+# Copyright: 2000 by Sun Microsystems, Inc.
+#
+# All Rights Reserved.
+#
+# Contributor(s): _______________________________________
+#
+#
+#
+#*************************************************************************
+PRJ=..$/..
+
+PRJNAME=sax
+TARGET=expatwrap
+NO_BSYMBOLIC=TRUE
+ENABLE_EXCEPTIONS=TRUE
+# --- Settings -----------------------------------------------------
+.INCLUDE : svpre.mk
+.INCLUDE : settings.mk
+.INCLUDE : sv.mk
+#-----------------------------------------------------------
+CFLAGS += -DXML_UNICODE
+
+SLOFILES =\
+ $(SLO)$/xml2utf.obj\
+ $(SLO)$/attrlistimpl.obj\
+ $(SLO)$/sax_expat.obj \
+ $(SLO)$/saxwriter.obj
+
+# NETBSD: somewhere we have to instantiate the static data members.
+# NETBSD-1.2.1 doesn't know about weak symbols so the default mechanism for GCC won't work.
+# SCO and MACOSX: the linker does know about weak symbols, but we can't ignore multiple defined symbols
+.IF "$(OS)"=="NETBSD" || "$(OS)"=="SCO" || "$(OS)$(COM)"=="OS2GCC" || "$(OS)"=="MACOSX"
+SLOFILES+=$(SLO)$/staticmb.obj
+.ENDIF
+
+# --- Targets ------------------------------------------------------
+.INCLUDE : target.mk
+
+
+
diff --git a/sax/source/expatwrap/sax_expat.cxx b/sax/source/expatwrap/sax_expat.cxx
new file mode 100644
index 000000000000..8c9a6f170c31
--- /dev/null
+++ b/sax/source/expatwrap/sax_expat.cxx
@@ -0,0 +1,1043 @@
+/*************************************************************************
+ *
+ * $RCSfile: sax_expat.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 16:43:13 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#include <vector>
+
+#ifdef WIN32
+#include <malloc.h>
+#else
+#ifndef MACOSX
+#include <alloca.h>
+#endif
+#endif
+
+#include <osl/diagnose.h>
+
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/util/XCloneable.hpp>
+#include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp>
+#include <com/sun/star/xml/sax/XParser.hpp>
+#include <com/sun/star/xml/sax/SAXParseException.hpp>
+
+#include <cppuhelper/factory.hxx>
+#include <cppuhelper/weak.hxx>
+#include <cppuhelper/implbase1.hxx>
+#include <cppuhelper/implbase2.hxx>
+
+#include <assert.h>
+
+#include "expat/xmlparse.h"
+
+using namespace ::rtl;
+using namespace ::std;
+using namespace ::osl;
+using namespace ::cppu;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::registry;
+using namespace ::com::sun::star::xml::sax;
+using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::io;
+
+#include "factory.hxx"
+#include "attrlistimpl.hxx"
+#include "xml2utf.hxx"
+
+OUString XmlNChar2OUString( const XML_Char *p , int nLen )
+{
+ if( p ) {
+ if( sizeof( sal_Unicode ) == sizeof( XML_Char ) )
+ {
+ return OUString( (sal_Unicode*)p,nLen);
+ }
+ else
+ {
+ sal_Unicode *pWchar = (sal_Unicode *)alloca( sizeof( sal_Unicode ) * nLen );
+ for( int n = 0 ; n < nLen ; n++ ) {
+ pWchar[n] = (sal_Unicode) p[n];
+ }
+ return OUString( pWchar , nLen );
+ }
+ }
+ else {
+ return OUString();
+ }
+}
+
+OUString XmlChar2OUString( const XML_Char *p )
+{
+ if( p ) {
+ for( int nLen = 0 ; p[nLen] ; nLen ++ );
+ return XmlNChar2OUString( p , nLen );
+ }
+ else return OUString();
+}
+
+
+// Useful macros for correct String conversion depending on the choosen expat-mode
+#ifdef XML_UNICODE
+#define XML_CHAR_TO_OUSTRING(x) XmlChar2OUString(x)
+#define XML_CHAR_N_TO_USTRING(x,n) XmlNChar2OUString(x,n)
+#else
+#define XML_CHAR_TO_OUSTRING(x) OStringToOUString(OString(x), RTL_TEXTENCODING_UTF8)
+#define XML_CHAR_N_TO_OUSTRING(x,n) OStringToOUString(OString(x,n), RTL_TEXTENCODING_UTF8 )
+#endif
+
+
+/*
+* The following macro encapsulates any call to an event handler.
+* It ensures, that exceptions thrown by the event handler are
+* treated properly.
+*/
+#define CALL_ELEMENT_HANDLER_AND_CARE_FOR_EXCEPTIONS(pThis,call) \
+ if( ! pThis->bExceptionWasThrown ) { \
+ try {\
+ pThis->call;\
+ }\
+ catch( SAXParseException &e ) {\
+ pThis->callErrorHandler( pThis , e );\
+ }\
+ catch( SAXException &e ) {\
+ pThis->callErrorHandler( pThis , SAXParseException(\
+ e.Message, \
+ e.Context, \
+ e.WrappedException,\
+ pThis->rDocumentLocator->getPublicId(),\
+ pThis->rDocumentLocator->getSystemId(),\
+ pThis->rDocumentLocator->getLineNumber(),\
+ pThis->rDocumentLocator->getColumnNumber()\
+ ) );\
+ }\
+ }\
+ ((void)0)
+
+#define IMPLEMENTATION_NAME "com.sun.star.comp.extensions.xml.sax.ParserExpat"
+#define SERVICE_NAME "com.sun.star.xml.sax.Parser"
+
+class SaxExpatParser_Impl;
+
+
+// This class implements the external Parser interface
+class SaxExpatParser :
+ public WeakImplHelper2<
+ XParser,
+ XServiceInfo
+ >
+{
+
+public:
+ SaxExpatParser();
+ ~SaxExpatParser();
+
+public:
+
+ // The implementation details
+ static Sequence< OUString > getSupportedServiceNames_Static(void) throw ();
+ static OUString getImplementationName_Static() throw ();
+
+public:
+ // The SAX-Parser-Interface
+ virtual void SAL_CALL parseStream( const InputSource& structSource)
+ throw ( SAXException,
+ IOException,
+ RuntimeException);
+ virtual void SAL_CALL setDocumentHandler(const Reference< XDocumentHandler > & xHandler)
+ throw (RuntimeException);
+
+ virtual void SAL_CALL setErrorHandler(const Reference< XErrorHandler > & xHandler)
+ throw (RuntimeException);
+ virtual void SAL_CALL setDTDHandler(const Reference < XDTDHandler > & xHandler)
+ throw (RuntimeException);
+ virtual void SAL_CALL setEntityResolver(const Reference< XEntityResolver >& xResolver)
+ throw (RuntimeException);
+
+ virtual void SAL_CALL setLocale( const Locale &locale ) throw (RuntimeException);
+
+public: // XServiceInfo
+ OUString SAL_CALL getImplementationName() throw ();
+ Sequence< OUString > SAL_CALL getSupportedServiceNames(void) throw ();
+ sal_Bool SAL_CALL supportsService(const OUString& ServiceName) throw ();
+
+private:
+
+ SaxExpatParser_Impl *m_pImpl;
+
+};
+
+//--------------------------------------
+// the extern interface
+//---------------------------------------
+Reference< XInterface > SAL_CALL SaxExpatParser_CreateInstance(
+ const Reference< XMultiServiceFactory > & rSMgr ) throw(Exception)
+{
+ SaxExpatParser *p = new SaxExpatParser;
+
+ return Reference< XInterface > ( (OWeakObject * ) p );
+}
+
+
+
+Sequence< OUString > SaxExpatParser::getSupportedServiceNames_Static(void) throw ()
+{
+ Sequence<OUString> aRet(1);
+ aRet.getArray()[0] = SaxExpatParser::getImplementationName_Static();
+ return aRet;
+}
+
+
+//---------------------------------------------
+// the implementation part
+//---------------------------------------------
+
+
+// Entity binds all information neede for a single file
+struct Entity
+{
+ InputSource structSource;
+ XML_Parser pParser;
+ XMLFile2UTFConverter converter;
+};
+
+
+class SaxExpatParser_Impl
+{
+public: // module scope
+ Mutex aMutex;
+
+ Reference< XDocumentHandler > rDocumentHandler;
+ Reference< XExtendedDocumentHandler > rExtendedDocumentHandler;
+
+ Reference< XErrorHandler > rErrorHandler;
+ Reference< XDTDHandler > rDTDHandler;
+ Reference< XEntityResolver > rEntityResolver;
+ Reference < XLocator > rDocumentLocator;
+
+
+ Reference < XAttributeList > rAttrList;
+ AttributeListImpl *pAttrList;
+
+ // External entity stack
+ vector<struct Entity> vecEntity;
+ void pushEntity( const struct Entity &entity )
+ { vecEntity.push_back( entity ); }
+ void popEntity()
+ { vecEntity.pop_back( ); }
+ struct Entity &getEntity()
+ { return vecEntity.back(); }
+
+
+ // Exception cannot be thrown through the C-XmlParser (possible resource leaks),
+ // therefor the exception must be saved somewhere.
+ SAXParseException exception;
+ sal_Bool bExceptionWasThrown;
+
+ Locale locale;
+
+public:
+ // the C-Callbacks for the expat parser
+ void static callbackStartElement(void *userData, const XML_Char *name , const XML_Char **atts);
+ void static callbackEndElement(void *userData, const XML_Char *name);
+ void static callbackCharacters( void *userData , const XML_Char *s , int nLen );
+ void static callbackProcessingInstruction( void *userData ,
+ const XML_Char *sTarget ,
+ const XML_Char *sData );
+
+ void static callbackUnparsedEntityDecl( void *userData ,
+ const XML_Char *entityName,
+ const XML_Char *base,
+ const XML_Char *systemId,
+ const XML_Char *publicId,
+ const XML_Char *notationName);
+
+ void static callbackNotationDecl( void *userData,
+ const XML_Char *notationName,
+ const XML_Char *base,
+ const XML_Char *systemId,
+ const XML_Char *publicId);
+
+ int static callbackExternalEntityRef( XML_Parser parser,
+ const XML_Char *openEntityNames,
+ const XML_Char *base,
+ const XML_Char *systemId,
+ const XML_Char *publicId);
+
+ int static callbackUnknownEncoding(void *encodingHandlerData,
+ const XML_Char *name,
+ XML_Encoding *info);
+
+ void static callbackDefault( void *userData, const XML_Char *s, int len);
+
+ void static callbackStartCDATA( void *userData );
+ void static callbackEndCDATA( void *userData );
+ void static callbackComment( void *userData , const XML_Char *s );
+ void static callErrorHandler( SaxExpatParser_Impl *pImpl , const SAXParseException &e );
+
+public:
+ void parse();
+};
+
+
+//---------------------------------------------
+// LocatorImpl
+//---------------------------------------------
+class LocatorImpl :
+ public WeakImplHelper1< XLocator >
+{
+public:
+ LocatorImpl( SaxExpatParser_Impl *p )
+ {
+ m_pParser = p;
+ }
+
+public: //XLocator
+ virtual sal_Int32 SAL_CALL getColumnNumber(void) throw ()
+ {
+ return XML_GetCurrentColumnNumber( m_pParser->getEntity().pParser );
+ }
+ virtual sal_Int32 SAL_CALL getLineNumber(void) throw ()
+ {
+ return XML_GetCurrentLineNumber( m_pParser->getEntity().pParser );
+ }
+ virtual OUString SAL_CALL getPublicId(void) throw ()
+ {
+ return m_pParser->getEntity().structSource.sPublicId;
+ }
+ virtual OUString SAL_CALL getSystemId(void) throw ()
+ {
+ return m_pParser->getEntity().structSource.sSystemId;
+ }
+
+private:
+
+ SaxExpatParser_Impl *m_pParser;
+};
+
+
+
+
+SaxExpatParser::SaxExpatParser( )
+{
+ m_pImpl = new SaxExpatParser_Impl;
+
+ LocatorImpl *pLoc = new LocatorImpl( m_pImpl );
+ m_pImpl->rDocumentLocator = Reference< XLocator > ( pLoc );
+
+ // performance-Improvment. Reference is needed when calling the startTag callback.
+ // Handing out the same object with every call is allowed (see sax-specification)
+ m_pImpl->pAttrList = new AttributeListImpl;
+ m_pImpl->rAttrList = Reference< XAttributeList > ( m_pImpl->pAttrList );
+
+ m_pImpl->bExceptionWasThrown = sal_False;
+}
+
+SaxExpatParser::~SaxExpatParser()
+{
+ delete m_pImpl;
+}
+
+
+/***************
+*
+* parseStream does Parser-startup initializations. The SaxExpatParser_Impl::parse() method does
+* the file-specific initialization work. (During a parser run, external files may be opened)
+*
+****************/
+void SaxExpatParser::parseStream( const InputSource& structSource)
+ throw (SAXException,
+ IOException,
+ RuntimeException)
+{
+ // Only one text at one time
+ MutexGuard guard( m_pImpl->aMutex );
+
+
+ struct Entity entity;
+ entity.structSource = structSource;
+
+ if( ! entity.structSource.aInputStream.is() )
+ {
+ throw SAXException( OUString::createFromAscii( "No input source" ) ,
+ Reference< XInterface > () , Any() );
+ }
+
+ entity.converter.setInputStream( entity.structSource.aInputStream );
+ if( entity.structSource.sEncoding.len() )
+ {
+ entity.converter.setEncoding(
+ OUStringToOString( entity.structSource.sEncoding , RTL_TEXTENCODING_ASCII_US ) );
+ }
+
+ // create parser with proper encoding
+ entity.pParser = XML_ParserCreate( 0 );
+ if( ! entity.pParser )
+ {
+ throw SAXException( OUString::createFromAscii( "Couldn't create parser" ) ,
+ Reference< XInterface > (), Any() );
+ }
+
+ // set all necessary C-Callbacks
+ XML_SetUserData( entity.pParser , m_pImpl );
+ XML_SetElementHandler( entity.pParser ,
+ SaxExpatParser_Impl::callbackStartElement ,
+ SaxExpatParser_Impl::callbackEndElement );
+ XML_SetCharacterDataHandler( entity.pParser , SaxExpatParser_Impl::callbackCharacters );
+ XML_SetProcessingInstructionHandler(entity.pParser ,
+ SaxExpatParser_Impl::callbackProcessingInstruction );
+ XML_SetUnparsedEntityDeclHandler( entity.pParser,
+ SaxExpatParser_Impl::callbackUnparsedEntityDecl );
+ XML_SetNotationDeclHandler( entity.pParser, SaxExpatParser_Impl::callbackNotationDecl );
+ XML_SetExternalEntityRefHandler( entity.pParser,
+ SaxExpatParser_Impl::callbackExternalEntityRef);
+ XML_SetUnknownEncodingHandler( entity.pParser, SaxExpatParser_Impl::callbackUnknownEncoding ,0);
+
+ if( m_pImpl->rExtendedDocumentHandler.is() ) {
+
+ // These handlers just delegate calls to the ExtendedHandler. If no extended handler is
+ // given, these callbacks can be ignored
+ XML_SetDefaultHandlerExpand( entity.pParser, SaxExpatParser_Impl::callbackDefault );
+ XML_SetCommentHandler( entity.pParser, SaxExpatParser_Impl::callbackComment );
+ XML_SetCdataSectionHandler( entity.pParser ,
+ SaxExpatParser_Impl::callbackStartCDATA ,
+ SaxExpatParser_Impl::callbackEndCDATA );
+ }
+
+
+ m_pImpl->exception = SAXParseException();
+ m_pImpl->pushEntity( entity );
+ try
+ {
+ // start the document
+ if( m_pImpl->rDocumentHandler.is() ) {
+ m_pImpl->rDocumentHandler->setDocumentLocator( m_pImpl->rDocumentLocator );
+ m_pImpl->rDocumentHandler->startDocument();
+ }
+
+ m_pImpl->parse();
+
+ // finish document
+ if( m_pImpl->rDocumentHandler.is() ) {
+ m_pImpl->rDocumentHandler->endDocument();
+ }
+ }
+
+// catch( SAXParseException & )
+// {
+// m_pImpl->popEntity();
+// XML_ParserFree( entity.pParser );
+// throw;
+// }
+ catch( SAXException & )
+ {
+ m_pImpl->popEntity();
+ XML_ParserFree( entity.pParser );
+ throw;
+ }
+ catch( IOException & )
+ {
+ m_pImpl->popEntity();
+ XML_ParserFree( entity.pParser );
+ throw;
+ }
+ catch( RuntimeException & )
+ {
+ m_pImpl->popEntity();
+ XML_ParserFree( entity.pParser );
+ throw;
+ }
+
+ m_pImpl->popEntity();
+ XML_ParserFree( entity.pParser );
+}
+
+void SaxExpatParser::setDocumentHandler(const Reference< XDocumentHandler > & xHandler)
+ throw (RuntimeException)
+{
+ m_pImpl->rDocumentHandler = xHandler;
+ m_pImpl->rExtendedDocumentHandler =
+ Reference< XExtendedDocumentHandler >( xHandler , UNO_QUERY );
+}
+
+void SaxExpatParser::setErrorHandler(const Reference< XErrorHandler > & xHandler)
+ throw (RuntimeException)
+{
+ m_pImpl->rErrorHandler = xHandler;
+}
+
+void SaxExpatParser::setDTDHandler(const Reference< XDTDHandler > & xHandler)
+ throw (RuntimeException)
+{
+ m_pImpl->rDTDHandler = xHandler;
+}
+
+void SaxExpatParser::setEntityResolver(const Reference < XEntityResolver > & xResolver)
+ throw (RuntimeException)
+{
+ m_pImpl->rEntityResolver = xResolver;
+}
+
+
+void SaxExpatParser::setLocale( const Locale & locale ) throw (RuntimeException)
+{
+ m_pImpl->locale = locale;
+}
+
+OUString SaxExpatParser::getImplementationName_Static() throw ()
+{
+ return OUString::createFromAscii( IMPLEMENTATION_NAME );
+}
+
+// XServiceInfo
+OUString SaxExpatParser::getImplementationName() throw ()
+{
+ return OUString::createFromAscii( IMPLEMENTATION_NAME );
+}
+
+// XServiceInfo
+sal_Bool SaxExpatParser::supportsService(const OUString& ServiceName) throw ()
+{
+ Sequence< OUString > aSNL = getSupportedServiceNames();
+ const OUString * pArray = aSNL.getConstArray();
+
+ for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
+ if( pArray[i] == ServiceName )
+ return sal_True;
+
+ return sal_False;
+}
+
+// XServiceInfo
+Sequence< OUString > SaxExpatParser::getSupportedServiceNames(void) throw ()
+{
+
+ Sequence<OUString> seq(1);
+ seq.getArray()[0] = OUString::createFromAscii( SERVICE_NAME );
+ return seq;
+}
+
+
+/*---------------------------------------
+*
+* Helper functions and classes
+*
+*
+*-------------------------------------------*/
+OUString getErrorMessage( XML_Error xmlE, OUString sSystemId , sal_Int32 nLine )
+{
+ OUString Message;
+ if( XML_ERROR_NONE == xmlE ) {
+ Message = OUString::createFromAscii( "No" );
+ }
+ else if( XML_ERROR_NO_MEMORY == xmlE ) {
+ Message = OUString::createFromAscii( "no memory" );
+ }
+ else if( XML_ERROR_SYNTAX == xmlE ) {
+ Message = OUString::createFromAscii( "syntax" );
+ }
+ else if( XML_ERROR_NO_ELEMENTS == xmlE ) {
+ Message = OUString::createFromAscii( "no elements" );
+ }
+ else if( XML_ERROR_INVALID_TOKEN == xmlE ) {
+ Message = OUString::createFromAscii( "invalid token" );
+ }
+ else if( XML_ERROR_UNCLOSED_TOKEN == xmlE ) {
+ Message = OUString::createFromAscii( "unclosed token" );
+ }
+ else if( XML_ERROR_PARTIAL_CHAR == xmlE ) {
+ Message = OUString::createFromAscii( "partial char" );
+ }
+ else if( XML_ERROR_TAG_MISMATCH == xmlE ) {
+ Message = OUString::createFromAscii( "tag mismatch" );
+ }
+ else if( XML_ERROR_DUPLICATE_ATTRIBUTE == xmlE ) {
+ Message = OUString::createFromAscii( "duplicate attribute" );
+ }
+ else if( XML_ERROR_JUNK_AFTER_DOC_ELEMENT == xmlE ) {
+ Message = OUString::createFromAscii( "junk after doc element" );
+ }
+ else if( XML_ERROR_PARAM_ENTITY_REF == xmlE ) {
+ Message = OUString::createFromAscii( "parameter entity reference" );
+ }
+ else if( XML_ERROR_UNDEFINED_ENTITY == xmlE ) {
+ Message = OUString::createFromAscii( "undefined entity" );
+ }
+ else if( XML_ERROR_RECURSIVE_ENTITY_REF == xmlE ) {
+ Message = OUString::createFromAscii( "recursive entity reference" );
+ }
+ else if( XML_ERROR_ASYNC_ENTITY == xmlE ) {
+ Message = OUString::createFromAscii( "async entity" );
+ }
+ else if( XML_ERROR_BAD_CHAR_REF == xmlE ) {
+ Message = OUString::createFromAscii( "bad char reference" );
+ }
+ else if( XML_ERROR_BINARY_ENTITY_REF == xmlE ) {
+ Message = OUString::createFromAscii( "binary entity reference" );
+ }
+ else if( XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF == xmlE ) {
+ Message = OUString::createFromAscii( "attribute external entity reference" );
+ }
+ else if( XML_ERROR_MISPLACED_XML_PI == xmlE ) {
+ Message = OUString::createFromAscii( "misplaced xml processing instruction" );
+ }
+ else if( XML_ERROR_UNKNOWN_ENCODING == xmlE ) {
+ Message = OUString::createFromAscii( "unknown encoding" );
+ }
+ else if( XML_ERROR_INCORRECT_ENCODING == xmlE ) {
+ Message = OUString::createFromAscii( "incorrect encoding" );
+ }
+ else if( XML_ERROR_UNCLOSED_CDATA_SECTION == xmlE ) {
+ Message = OUString::createFromAscii( "unclosed cdata section" );
+ }
+ else if( XML_ERROR_EXTERNAL_ENTITY_HANDLING == xmlE ) {
+ Message = OUString::createFromAscii( "external entity reference" );
+ }
+ else if( XML_ERROR_NOT_STANDALONE == xmlE ) {
+ Message = OUString::createFromAscii( "not standalone" );
+ }
+
+ OUString str = OUString::createFromAscii( "[" );
+ str += sSystemId;
+ str += OUString::createFromAscii( " line " );
+ str += OUString::valueOf( nLine );
+ str += OUString::createFromAscii( "]: " );
+ str += Message;
+ str += OUString::createFromAscii( "error" );
+
+ return str;
+}
+
+
+// starts parsing with actual parser !
+void SaxExpatParser_Impl::parse( )
+{
+ const int nBufSize = 16*1024;
+
+ int nRead = nBufSize;
+ Sequence< sal_Int8 > seqOut(nBufSize);
+
+ while( nRead ) {
+ nRead = getEntity().converter.readAndConvert( seqOut , nBufSize );
+
+ if( ! nRead ) {
+ XML_Parse( getEntity().pParser , ( const char * ) seqOut.getArray() , 0 , 1 );
+ break;
+ }
+
+ sal_Bool bContinue = XML_Parse( getEntity().pParser ,(const char *) seqOut.getArray(),nRead,0);
+
+ if( ! bContinue || this->bExceptionWasThrown ) {
+
+ // Error during parsing !
+ XML_Error xmlE = XML_GetErrorCode( getEntity().pParser );
+ OUString sSystemId = rDocumentLocator->getSystemId();
+ sal_Int32 nLine = rDocumentLocator->getLineNumber();
+
+ SAXParseException aExcept(
+ getErrorMessage(xmlE , sSystemId, nLine) ,
+ Reference< XInterface >(),
+ Any( &exception , getCppuType( &exception) ),
+ rDocumentLocator->getPublicId(),
+ rDocumentLocator->getSystemId(),
+ rDocumentLocator->getLineNumber(),
+ rDocumentLocator->getColumnNumber()
+ );
+
+ if( rErrorHandler.is() ) {
+
+ // error handler is set, so the handler may throw the exception
+ Any a;
+ a <<= aExcept;
+ rErrorHandler->fatalError( a );
+ }
+
+ // Error handler has not thrown an exception, but parsing cannot go on,
+ // so an exception MUST be thrown.
+ throw aExcept;
+ } // if( ! bContinue )
+ } // while
+}
+
+//------------------------------------------
+//
+// The C-Callbacks
+//
+//-----------------------------------------
+void SaxExpatParser_Impl::callbackStartElement( void *pvThis ,
+ const XML_Char *pwName ,
+ const XML_Char **awAttributes )
+{
+ SaxExpatParser_Impl *pImpl = ((SaxExpatParser_Impl*)pvThis);
+
+ if( pImpl->rDocumentHandler.is() ) {
+
+ int i = 0;
+ pImpl->pAttrList->clear();
+
+ while( awAttributes[i] ) {
+ assert( awAttributes[i+1] );
+ pImpl->pAttrList->addAttribute(
+ XML_CHAR_TO_OUSTRING( awAttributes[i] ) ,
+ OUString( RTL_CONSTASCII_USTRINGPARAM("CDATA") ) , // expat doesn't know types
+ XML_CHAR_TO_OUSTRING( awAttributes[i+1] ) );
+ i +=2;
+ }
+
+ CALL_ELEMENT_HANDLER_AND_CARE_FOR_EXCEPTIONS(
+ pImpl ,
+ rDocumentHandler->startElement( XML_CHAR_TO_OUSTRING( pwName ) ,
+ pImpl->rAttrList ) );
+ }
+}
+
+void SaxExpatParser_Impl::callbackEndElement( void *pvThis , const XML_Char *pwName )
+{
+ SaxExpatParser_Impl *pImpl = ((SaxExpatParser_Impl*)pvThis);
+
+ if( pImpl->rDocumentHandler.is() ) {
+ CALL_ELEMENT_HANDLER_AND_CARE_FOR_EXCEPTIONS( pImpl,
+ rDocumentHandler->endElement( XML_CHAR_TO_OUSTRING( pwName ) ) );
+ }
+}
+
+
+void SaxExpatParser_Impl::callbackCharacters( void *pvThis , const XML_Char *s , int nLen )
+{
+ SaxExpatParser_Impl *pImpl = ((SaxExpatParser_Impl*)pvThis);
+
+ if( pImpl->rDocumentHandler.is() ) {
+ CALL_ELEMENT_HANDLER_AND_CARE_FOR_EXCEPTIONS( pImpl ,
+ rDocumentHandler->characters( XML_CHAR_N_TO_USTRING(s,nLen) ) );
+ }
+}
+
+void SaxExpatParser_Impl::callbackProcessingInstruction( void *pvThis,
+ const XML_Char *sTarget ,
+ const XML_Char *sData )
+{
+ SaxExpatParser_Impl *pImpl = ((SaxExpatParser_Impl*)pvThis);
+ if( pImpl->rDocumentHandler.is() ) {
+ CALL_ELEMENT_HANDLER_AND_CARE_FOR_EXCEPTIONS( pImpl ,
+ rDocumentHandler->processingInstruction( XML_CHAR_TO_OUSTRING( sTarget ),
+ XML_CHAR_TO_OUSTRING( sData ) ) );
+ }
+}
+
+
+void SaxExpatParser_Impl::callbackUnparsedEntityDecl(void *pvThis ,
+ const XML_Char *entityName,
+ const XML_Char *base,
+ const XML_Char *systemId,
+ const XML_Char *publicId,
+ const XML_Char *notationName)
+{
+ SaxExpatParser_Impl *pImpl = ((SaxExpatParser_Impl*)pvThis);
+ if( pImpl->rDTDHandler.is() ) {
+ CALL_ELEMENT_HANDLER_AND_CARE_FOR_EXCEPTIONS(
+ pImpl ,
+ rDTDHandler->unparsedEntityDecl(
+ XML_CHAR_TO_OUSTRING( entityName ),
+ XML_CHAR_TO_OUSTRING( publicId ) ,
+ XML_CHAR_TO_OUSTRING( systemId ) ,
+ XML_CHAR_TO_OUSTRING( notationName ) ) );
+ }
+}
+
+void SaxExpatParser_Impl::callbackNotationDecl( void *pvThis,
+ const XML_Char *notationName,
+ const XML_Char *base,
+ const XML_Char *systemId,
+ const XML_Char *publicId)
+{
+ SaxExpatParser_Impl *pImpl = ((SaxExpatParser_Impl*)pvThis);
+ if( pImpl->rDTDHandler.is() ) {
+ CALL_ELEMENT_HANDLER_AND_CARE_FOR_EXCEPTIONS( pImpl,
+ rDTDHandler->notationDecl( XML_CHAR_TO_OUSTRING( notationName ) ,
+ XML_CHAR_TO_OUSTRING( publicId ) ,
+ XML_CHAR_TO_OUSTRING( systemId ) ) );
+ }
+
+}
+
+
+
+int SaxExpatParser_Impl::callbackExternalEntityRef( XML_Parser parser,
+ const XML_Char *context,
+ const XML_Char *base,
+ const XML_Char *systemId,
+ const XML_Char *publicId)
+{
+ sal_Bool bOK = sal_True;
+ InputSource source;
+ SaxExpatParser_Impl *pImpl = ((SaxExpatParser_Impl*)XML_GetUserData( parser ));
+
+ struct Entity entity;
+
+ if( pImpl->rEntityResolver.is() ) {
+ try
+ {
+ entity.structSource = pImpl->rEntityResolver->resolveEntity(
+ XML_CHAR_TO_OUSTRING( publicId ) ,
+ XML_CHAR_TO_OUSTRING( systemId ) );
+ }
+ catch( SAXParseException & e )
+ {
+ pImpl->exception = e;
+ bOK = sal_False;
+ }
+ catch( SAXException & e )
+ {
+ pImpl->exception = SAXParseException(
+ e.Message , e.Context , e.WrappedException ,
+ pImpl->rDocumentLocator->getPublicId(),
+ pImpl->rDocumentLocator->getSystemId(),
+ pImpl->rDocumentLocator->getLineNumber(),
+ pImpl->rDocumentLocator->getColumnNumber() );
+ bOK = sal_False;
+ }
+ }
+
+ if( entity.structSource.aInputStream.is() ) {
+ entity.pParser = XML_ExternalEntityParserCreate( parser , context, 0 );
+ if( ! entity.pParser )
+ {
+ return sal_False;
+ }
+
+ entity.converter.setInputStream( entity.structSource.aInputStream );
+ pImpl->pushEntity( entity );
+ try
+ {
+ pImpl->parse();
+ }
+ catch( SAXParseException & e )
+ {
+ pImpl->exception = e;
+ bOK = sal_False;
+ }
+ catch( IOException &e )
+ {
+ pImpl->exception.WrappedException <<= e;
+ bOK = sal_False;
+ }
+ catch( RuntimeException &e )
+ {
+ pImpl->exception.WrappedException <<=e;
+ bOK = sal_False;
+ }
+
+ pImpl->popEntity();
+
+ XML_ParserFree( entity.pParser );
+ }
+
+ return bOK;
+}
+
+int SaxExpatParser_Impl::callbackUnknownEncoding(void *encodingHandlerData,
+ const XML_Char *name,
+ XML_Encoding *info)
+{
+ return 0;
+}
+
+void SaxExpatParser_Impl::callbackDefault( void *pvThis, const XML_Char *s, int len)
+{
+ SaxExpatParser_Impl *pImpl = ((SaxExpatParser_Impl*)pvThis);
+
+ CALL_ELEMENT_HANDLER_AND_CARE_FOR_EXCEPTIONS( pImpl,
+ rExtendedDocumentHandler->unknown( XML_CHAR_N_TO_USTRING( s ,len) ) );
+}
+
+void SaxExpatParser_Impl::callbackComment( void *pvThis , const XML_Char *s )
+{
+ SaxExpatParser_Impl *pImpl = ((SaxExpatParser_Impl*)pvThis);
+ CALL_ELEMENT_HANDLER_AND_CARE_FOR_EXCEPTIONS( pImpl,
+ rExtendedDocumentHandler->comment( XML_CHAR_TO_OUSTRING( s ) ) );
+}
+
+void SaxExpatParser_Impl::callbackStartCDATA( void *pvThis )
+{
+ SaxExpatParser_Impl *pImpl = ((SaxExpatParser_Impl*)pvThis);
+
+ CALL_ELEMENT_HANDLER_AND_CARE_FOR_EXCEPTIONS( pImpl, rExtendedDocumentHandler->startCDATA() );
+}
+
+
+void SaxExpatParser_Impl::callErrorHandler( SaxExpatParser_Impl *pImpl ,
+ const SAXParseException & e )
+{
+ try
+ {
+ if( pImpl->rErrorHandler.is() ) {
+ Any a;
+ a <<= e;
+ pImpl->rErrorHandler->error( a );
+ }
+ else {
+ pImpl->exception = e;
+ pImpl->bExceptionWasThrown = sal_True;
+ }
+ }
+ catch( SAXParseException & ex ) {
+ pImpl->exception = ex;
+ pImpl->bExceptionWasThrown = sal_True;
+ }
+ catch( SAXException & ex ) {
+ pImpl->exception = SAXParseException(
+ ex.Message,
+ ex.Context,
+ ex.WrappedException,
+ pImpl->rDocumentLocator->getPublicId(),
+ pImpl->rDocumentLocator->getSystemId(),
+ pImpl->rDocumentLocator->getLineNumber(),
+ pImpl->rDocumentLocator->getColumnNumber()
+ );
+ pImpl->bExceptionWasThrown = sal_True;
+ }
+}
+
+void SaxExpatParser_Impl::callbackEndCDATA( void *pvThis )
+{
+ SaxExpatParser_Impl *pImpl = ((SaxExpatParser_Impl*)pvThis);
+
+ CALL_ELEMENT_HANDLER_AND_CARE_FOR_EXCEPTIONS(pImpl,rExtendedDocumentHandler->endCDATA() );
+}
+
+
+
+extern "C"
+{
+
+void SAL_CALL component_getImplementationEnvironment(
+ const sal_Char ** ppEnvTypeName, uno_Environment ** ppEnv )
+{
+ *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
+}
+
+
+sal_Bool SAL_CALL component_writeInfo(
+ void * pServiceManager, void * pRegistryKey )
+{
+ if (pRegistryKey)
+ {
+ try
+ {
+ Reference< XRegistryKey > xKey(
+ reinterpret_cast< XRegistryKey * >( pRegistryKey ) );
+
+ Reference< XRegistryKey > xNewKey = xKey->createKey(
+ OUString::createFromAscii( "/" IMPLEMENTATION_NAME "/UNO/SERVICES" ) );
+ xNewKey->createKey( OUString::createFromAscii( SERVICE_NAME ) );
+
+ xNewKey = xKey->createKey( OUString::createFromAscii("/") +
+ SaxWriter_getImplementationName()+
+ OUString::createFromAscii( "/UNO/SERVICES" ) );
+ xNewKey->createKey( SaxWriter_getServiceName() );
+
+ return sal_True;
+ }
+ catch (InvalidRegistryException &)
+ {
+ OSL_ENSHURE( sal_False, "### InvalidRegistryException!" );
+ }
+ }
+ return sal_False;
+}
+
+
+void * SAL_CALL component_getFactory(
+ const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey )
+{
+ void * pRet = 0;
+
+ if (pServiceManager )
+ {
+ Reference< XSingleServiceFactory > xRet;
+ Reference< XMultiServiceFactory > xSMgr =
+ reinterpret_cast< XMultiServiceFactory * > ( pServiceManager );
+
+ OUString aImplementationName = OUString::createFromAscii( pImplName );
+
+ if (aImplementationName ==
+ OUString( RTL_CONSTASCII_USTRINGPARAM( IMPLEMENTATION_NAME ) ) )
+ {
+ xRet = createSingleFactory( xSMgr, aImplementationName,
+ SaxExpatParser_CreateInstance,
+ SaxExpatParser::getSupportedServiceNames_Static() );
+ }
+ else if ( aImplementationName == SaxWriter_getImplementationName() )
+ {
+ xRet = createSingleFactory( xSMgr, aImplementationName,
+ SaxWriter_CreateInstance,
+ SaxWriter_getSupportedServiceNames() );
+ }
+
+ if (xRet.is())
+ {
+ xRet->acquire();
+ pRet = xRet.get();
+ }
+ }
+
+ return pRet;
+}
+
+
+}
+
diff --git a/sax/source/expatwrap/saxwriter.cxx b/sax/source/expatwrap/saxwriter.cxx
new file mode 100644
index 000000000000..b4844d18c740
--- /dev/null
+++ b/sax/source/expatwrap/saxwriter.cxx
@@ -0,0 +1,736 @@
+/*************************************************************************
+ *
+ * $RCSfile: saxwriter.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 16:43:13 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#include <string.h>
+
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/util/XCloneable.hpp>
+#include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp>
+#include <com/sun/star/xml/sax/XParser.hpp>
+#include <com/sun/star/xml/sax/SAXParseException.hpp>
+
+#include <com/sun/star/io/XActiveDataSource.hpp>
+
+#include <cppuhelper/factory.hxx>
+#include <cppuhelper/weak.hxx>
+#include <cppuhelper/implbase3.hxx>
+
+#include <rtl/strbuf.hxx>
+
+#include <assert.h>
+
+using namespace ::rtl;
+using namespace ::std;
+using namespace ::osl;
+using namespace ::cppu;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::registry;
+using namespace ::com::sun::star::xml::sax;
+using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::io;
+
+#include "factory.hxx"
+#include "xml2utf.hxx"
+
+#define LINEFEED 10
+
+/******
+*
+*
+* Character conversion functions
+*
+*
+*****/
+
+
+/*****
+*
+* Does special conversions (beside encoding) that is needed for xml. E.g. &<>"' plus some more are
+* special characters in XML that need to be transformed
+*
+* @param bConvertAll For Attributes it is necessary to convert every symbol (including line feed and tab)
+* Set this to true, if you want to perform this special conversion
+*
+****/
+sal_Int32 CalcXMLLen( const Sequence<sal_Int8> & seq , sal_Bool bConvertAll )
+{
+ sal_Int32 nLen = 0;
+ const sal_Int8 *pArray = seq.getConstArray();
+
+
+ for( int i = 0 ; i < seq.getLength() ; i ++ ) {
+
+ sal_Int8 c = pArray[i];
+ if( '&' == c ) { // resemble to &amp;
+ nLen += 5;
+ }
+ else if( '<' == c ) {
+ nLen += 4; // &lt;
+ }
+ else if( '>' == c ) {
+ nLen += 4; // &gt;
+ }
+ else if( 39 == c ) { // 39 == '''
+ nLen += 6; // &apos;
+ }
+ else if( '"' == c ) {
+ nLen += 6; // &quot;
+ }
+ else if( 13 == c ) {
+ nLen += 6; // &#x0d;
+ }
+ else if( bConvertAll && LINEFEED == c ) {
+ nLen += 6;
+ }
+ else if( bConvertAll && 9 == c ) {
+ nLen += 6;
+ }
+ else {
+ nLen ++;
+ }
+ }
+
+ return nLen;
+}
+
+
+inline sal_Int32 getFirstLineBreak( const Sequence<sal_Int8> & seq)
+{
+ const sal_Int8 *pSource = seq.getConstArray();
+
+ sal_Int32 nLen = seq.getLength();
+ for( int n = 0; n < nLen ; n ++ )
+ {
+ if( LINEFEED == pSource[n] ) {
+ return n;
+ }
+ }
+ return -1;
+}
+
+inline sal_Int32 getLastLineBreak( const Sequence<sal_Int8> & seq)
+{
+ const sal_Int8 *pSource = seq.getConstArray();
+ sal_Int32 nLen = seq.getLength();
+
+ for( int n = nLen-1; n >= 0 ; n -- )
+ {
+ if( LINEFEED == pSource[n] ) {
+ return n;
+ }
+ }
+ return -1;
+}
+
+
+class SAXWriter :
+ public WeakImplHelper3<
+ XActiveDataSource,
+ XExtendedDocumentHandler,
+ XServiceInfo >
+{
+public:
+ SAXWriter( ) :
+ m_nMaxColumn(72),
+ m_bForceLineBreak(sal_False),
+ m_bAllowLineBreak(sal_False),
+ m_unicode2utf8( RTL_TEXTENCODING_UTF8 )
+ {}
+
+public: // XActiveDataSource
+ virtual void SAL_CALL setOutputStream(const Reference< XOutputStream > & aStream)
+ throw (RuntimeException)
+ {
+ m_out = aStream;
+ m_bDocStarted = sal_False;
+ m_nLevel = 0;
+ m_bIsCDATA = sal_False;
+ m_nColumn = 0;
+ }
+ virtual Reference< XOutputStream > SAL_CALL getOutputStream(void)
+ throw(RuntimeException)
+ { return m_out; }
+
+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);
+
+public: // XExtendedDocumentHandler
+ virtual void SAL_CALL startCDATA(void) throw(SAXException, RuntimeException);
+ virtual void SAL_CALL endCDATA(void) throw(RuntimeException);
+ virtual void SAL_CALL comment(const OUString& sComment)
+ throw(SAXException, RuntimeException);
+ virtual void SAL_CALL unknown(const OUString& sString)
+ throw(SAXException, RuntimeException);
+ virtual void SAL_CALL allowLineBreak(void)
+ throw(SAXException,RuntimeException);
+
+public: // XServiceInfo
+ OUString SAL_CALL getImplementationName() throw();
+ Sequence< OUString > SAL_CALL getSupportedServiceNames(void) throw();
+ sal_Bool SAL_CALL supportsService(const OUString& ServiceName) throw();
+
+private:
+
+ void doIndent( Sequence<sal_Int8> &);
+ void writeSequence( const Sequence<sal_Int8> & seq );
+
+ inline void pushStartElement()
+ {
+ if( m_seqStartElement.getLength() )
+ {
+ writeSequence( m_seqStartElement );
+ m_seqStartElement = Sequence < sal_Int8 > ();
+ }
+ }
+
+ Sequence < sal_Int8 > ustring2UTF8( const OUString &sValue )
+ {
+ return m_unicode2utf8.convert( sValue );
+ }
+
+ Sequence < sal_Int8 > utf8ToXML( const Sequence< sal_Int8 > & , sal_Bool bConvertAll );
+
+ /****
+ * @param bConvertAll TRUE, when LINEFEED plus tab shall also be normalized
+ * sal_False otherwise
+ *
+ ****/
+ Sequence < sal_Int8 > ustring2XML( const OUString &sValue , sal_Bool bConvertAll )
+ {
+ return utf8ToXML( ustring2UTF8( sValue ) , bConvertAll );
+ }
+
+
+ Unicode2TextConverter m_unicode2utf8;
+ Reference< XOutputStream > m_out;
+ Sequence < sal_Int8 > m_seqStartElement;
+
+ // Status information
+ sal_Bool m_bDocStarted;
+ sal_Bool m_bIsCDATA;
+ sal_Bool m_bForceLineBreak;
+ sal_Bool m_bAllowLineBreak;
+ sal_Int32 m_nLevel;
+ sal_Int32 m_nColumn;
+ sal_Int32 m_nMaxColumn;
+};
+
+
+//--------------------------------------
+// the extern interface
+//---------------------------------------
+Reference < XInterface > SAL_CALL SaxWriter_CreateInstance(
+ const Reference < XMultiServiceFactory > & rSMgr )
+ throw (Exception)
+{
+ SAXWriter *p = new SAXWriter;
+ return Reference< XInterface > ( SAL_STATIC_CAST(OWeakObject *, p ) );
+}
+
+OUString SaxWriter_getServiceName()
+{
+ return OUString::createFromAscii( "com.sun.star.xml.sax.Writer" );
+}
+
+OUString SaxWriter_getImplementationName()
+{
+ return OUString::createFromAscii( "com.sun.star.extensions.xml.sax.Writer" );
+}
+
+Sequence< OUString > SaxWriter_getSupportedServiceNames(void) throw()
+{
+ Sequence<OUString> aRet(1);
+ aRet.getArray()[0] = SaxWriter_getImplementationName();
+ return aRet;
+}
+
+
+Sequence < sal_Int8 > SAXWriter::utf8ToXML( const Sequence<sal_Int8> & seqSource , sal_Bool bConvertAll )
+{
+ Sequence< sal_Int8 > seqTarget( CalcXMLLen( seqSource , bConvertAll ) );
+ sal_Int32 nMaxSource = seqSource.getLength();
+ const sal_Int8 *pSource = seqSource.getConstArray();
+ sal_Int8 *pTarget = seqTarget.getArray();
+ sal_Int32 nTarget = 0;
+
+ for( int nSource = 0 ; nSource < nMaxSource ; nSource ++ ) {
+ sal_Int8 c = pSource[nSource];
+ if( '&' == c ) { // resemble to &amp;
+ memcpy( &(pTarget[nTarget]) , "&amp;" , 5 );
+ nTarget += 5;
+ }
+ else if( '<' == c ) {
+ memcpy( &(pTarget[nTarget]) , "&lt;" , 4 );
+ nTarget += 4; // &lt;
+ }
+ else if( '>' == c ) {
+ memcpy( &(pTarget[nTarget]) , "&gt;" , 4 );
+ nTarget += 4; // &gt;
+ }
+ else if( 39 == c ) { // 39 == '''
+ memcpy( &(pTarget[nTarget]) , "&apos;" , 6 );
+ nTarget += 6; // &apos;
+ }
+ else if( '"' == c ) {
+ memcpy( &(pTarget[nTarget]) , "&quot;" , 6 );
+ nTarget += 6; // &quot;
+ }
+ else if( 13 == c ) {
+ memcpy( &(pTarget[nTarget]) , "&#x0d;" , 6 );
+ nTarget += 6;
+ }
+ else if( LINEFEED == c && bConvertAll ) {
+ memcpy( &(pTarget[nTarget]) , "&#x0a;" , 6 );
+ nTarget += 6;
+ }
+ else if( 9 == c && bConvertAll ) {
+ memcpy( &(pTarget[nTarget]) , "&#x09;" , 6 );
+ nTarget += 6;
+ }
+ else {
+ pTarget[nTarget] = c;
+ nTarget ++;
+ }
+ }
+ return seqTarget;
+}
+
+
+void SAXWriter::doIndent( Sequence<sal_Int8> &seq )
+{
+ sal_Int32 nLength = getFirstLineBreak( seq );
+ nLength = ( nLength >= 0 ) ? nLength : seq.getLength();
+ if( ( m_bForceLineBreak ) ||
+ ( m_bAllowLineBreak && nLength + m_nColumn > m_nMaxColumn )
+ ) {
+
+ // write the linebreaks !
+ Sequence<sal_Int8> seqIndent( m_nLevel + 1 );
+ seqIndent.getArray()[0] = 10;
+ memset( &(seqIndent.getArray()[1] ) , 32 , m_nLevel );
+ writeSequence( seqIndent );
+
+ // remove one leading space in the sequence
+ if( seq.getLength() && 32 == seq.getArray()[0] ) {
+ memmove( seq.getArray() , &(seq.getArray()[1]) , seq.getLength() -1 );
+ seq.realloc( seq.getLength()-1 );
+ }
+
+ }
+
+ m_bForceLineBreak = sal_False;
+ m_bAllowLineBreak = sal_False;
+}
+
+
+/********
+* write through to the output stream and counts columns
+*
+*****/
+void SAXWriter::writeSequence( const Sequence<sal_Int8> & seq )
+{
+
+ sal_Int32 nPos = getLastLineBreak( seq );
+ try
+ {
+ m_out->writeBytes( seq );
+ }
+ catch( IOException & e )
+ {
+ Any a;
+ a <<= e;
+ throw SAXException(
+ OUString::createFromAscii( "io exception during writing" ),
+ Reference< XInterface > (),
+ a );
+ }
+
+ if( nPos >= 0 ) {
+ m_nColumn = seq.getLength() - (nPos+1);
+ }
+ else {
+ m_nColumn += seq.getLength();
+ }
+}
+
+
+
+
+// XServiceInfo
+OUString SAXWriter::getImplementationName() throw()
+{
+ return SaxWriter_getImplementationName();
+}
+
+// XServiceInfo
+sal_Bool SAXWriter::supportsService(const OUString& ServiceName) throw()
+{
+ Sequence< OUString > aSNL = getSupportedServiceNames();
+ const OUString * pArray = aSNL.getConstArray();
+
+ for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
+ if( pArray[i] == ServiceName )
+ return sal_True;
+
+ return sal_False;
+}
+
+// XServiceInfo
+Sequence< OUString > SAXWriter::getSupportedServiceNames(void) throw ()
+{
+ Sequence<OUString> seq(1);
+ seq.getArray()[0] = SaxWriter_getServiceName();
+ return seq;
+}
+
+
+
+void SAXWriter::startDocument() throw(SAXException, RuntimeException )
+{
+ if( m_bDocStarted || ! m_out.is() ) {
+ throw SAXException();
+ }
+ m_bDocStarted = sal_True;
+ const char pc[] = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
+ const int nLen = strlen( pc );
+ Sequence<sal_Int8> seqWrite( nLen+1 );
+ memcpy( seqWrite.getArray() , pc , nLen );
+ seqWrite.getArray()[nLen] = LINEFEED;
+ writeSequence( seqWrite );
+}
+
+
+void SAXWriter::endDocument(void) throw(SAXException, RuntimeException)
+{
+ if( ! m_bDocStarted )
+ {
+ throw SAXException();
+ }
+ if( m_nLevel ) {
+ throw SAXException(
+ OUString::createFromAscii( "unexpected end of document" ),
+ Reference< XInterface >() , Any() );
+ }
+ m_out->closeOutput();
+}
+
+
+void SAXWriter::startElement(const OUString& aName, const Reference< XAttributeList >& xAttribs)
+ throw(SAXException, RuntimeException)
+{
+ if( ! m_bDocStarted )
+ {
+ throw SAXException();
+ }
+ if( m_bIsCDATA )
+ {
+ throw SAXException();
+ }
+ pushStartElement();
+
+ sal_Int32 nAttribCount = xAttribs.is() ? xAttribs->getLength() : 0;
+
+ OStringBuffer str(64 *( nAttribCount+1) );
+ str.append( "<" );
+
+ // Tags may only contain ascii chars !
+ str.append( OUStringToOString( aName.getStr() , RTL_TEXTENCODING_UTF8 ) );
+
+ for( int n = 0 ; n < nAttribCount ; n ++ ) {
+ str.append( " " );
+ str.append( OUStringToOString( xAttribs->getNameByIndex( n ) , RTL_TEXTENCODING_UTF8 ) );
+ str.append( "=\"" );
+
+ Sequence<sal_Int8> seq = ustring2XML( xAttribs->getValueByIndex( n ) , sal_True );
+ str.append( ( const sal_Char * ) seq.getConstArray() , seq.getLength() );
+ str.append( "\"" );
+ }
+
+ // preparing for empty tag
+ str.append( ">" );
+
+ Sequence<sal_Int8> seqWrite( str.getLength() );
+ memcpy( seqWrite.getArray() , str.getStr() , str.getLength() );
+
+ doIndent( seqWrite );
+
+ m_seqStartElement = seqWrite;
+
+ m_nLevel ++;
+}
+
+void SAXWriter::endElement(const OUString& aName) throw (SAXException, RuntimeException)
+{
+ if( ! m_bDocStarted ) {
+ throw SAXException ();
+ }
+ m_nLevel --;
+
+ if( m_nLevel < 0 ) {
+ throw SAXException();
+ }
+
+ if( m_seqStartElement.getLength() )
+ {
+ m_seqStartElement.realloc( m_seqStartElement.getLength() + 1 );
+
+ sal_Int8 *p = m_seqStartElement.getArray();
+ p[m_seqStartElement.getLength()-2] = '/';
+ p[m_seqStartElement.getLength()-1] = '>';
+ writeSequence( m_seqStartElement );
+ m_seqStartElement = Sequence< sal_Int8 > ();
+ }
+ else {
+ // only ascii chars allowed
+ sal_Int32 nLen = aName.getLength();
+ Sequence< sal_Int8 > seqWrite( nLen + 3 );
+
+ sal_Int8 *p = seqWrite.getArray();
+ sal_Unicode *pStr = (sal_Unicode * )aName.getStr();
+
+ p[0] = '<';
+ p[1] = '/';
+ for( sal_Int32 i = 0 ; i < nLen ; i ++ )
+ {
+ p[2+i] = (sal_Int8) pStr[i];
+ }
+ p[nLen+2] = '>';
+
+ doIndent( seqWrite );
+ writeSequence( seqWrite );
+ }
+}
+
+void SAXWriter::characters(const OUString& aChars) throw(SAXException, RuntimeException)
+{
+ if( ! m_bDocStarted )
+ {
+ throw SAXException();
+ }
+ pushStartElement();
+
+ if( m_bIsCDATA ) {
+ Sequence<sal_Int8> seqWrite = ustring2UTF8( aChars);
+ writeSequence( seqWrite );
+ }
+ else {
+ Sequence<sal_Int8> seqWrite = ustring2XML( aChars , sal_False );
+ doIndent( seqWrite );
+ writeSequence( seqWrite );
+ }
+}
+
+
+void SAXWriter::ignorableWhitespace(const OUString& aWhitespaces) throw(SAXException, RuntimeException)
+{
+ if( ! m_bDocStarted )
+ {
+ throw SAXException ();
+ }
+
+ m_bForceLineBreak = sal_True;
+}
+
+void SAXWriter::processingInstruction(const OUString& aTarget, const OUString& aData)
+ throw (SAXException, RuntimeException)
+{
+ if( ! m_bDocStarted || m_bIsCDATA )
+ {
+ throw SAXException();
+ }
+
+ pushStartElement();
+
+ OStringBuffer str( 128 );
+ str.append( "<?" );
+ str.append( OUStringToOString( aTarget , RTL_TEXTENCODING_UTF8 ) );
+ str.append( " " );
+ str.append( OUStringToOString( aData , RTL_TEXTENCODING_UTF8 ) ); // only ascii chars allowed
+ str.append( "?>" );
+
+ Sequence<sal_Int8> seq( str.getLength() );
+ memcpy( seq.getArray() , str.getStr() , str.getLength() );
+
+ doIndent( seq );
+ writeSequence( seq );
+}
+
+
+void SAXWriter::setDocumentLocator(const Reference< XLocator >& xLocator)
+ throw (SAXException, RuntimeException)
+{
+
+}
+
+void SAXWriter::startCDATA(void) throw(SAXException, RuntimeException)
+{
+ if( ! m_bDocStarted || m_bIsCDATA)
+ {
+ throw SAXException ();
+ }
+
+ pushStartElement();
+
+ Sequence < sal_Int8 > seq( ( sal_Int8 * ) "<![CDATA[" , 9 );
+
+ doIndent( seq );
+ writeSequence( seq );
+ m_bIsCDATA = sal_True;
+}
+
+void SAXWriter::endCDATA(void) throw (RuntimeException)
+{
+ if( ! m_bDocStarted | ! m_bIsCDATA)
+ {
+ throw SAXException();
+ }
+
+ pushStartElement();
+ Sequence<sal_Int8> seq( ( sal_Int8 * ) "]]>" , 3 );
+
+ doIndent( seq );
+ writeSequence( seq );
+ m_bIsCDATA = sal_False;
+}
+
+
+void SAXWriter::comment(const OUString& sComment) throw(SAXException, RuntimeException)
+{
+ if( ! m_bDocStarted || m_bIsCDATA )
+ {
+ throw SAXException();
+ }
+
+ pushStartElement();
+
+ Sequence<sal_Int8> seq = ustring2XML( sComment , sal_False );
+
+ Sequence<sal_Int8> seqWrite( seq.getLength() + 7 );
+ sal_Int8 *p = seqWrite.getArray();
+ p[0] = '<';
+ p[1] = '!';
+ p[2] = '-';
+ p[3] = '-';
+ memcpy( &(p[4]) , seq.getConstArray() , seq.getLength() );
+ p[4+seq.getLength()] = '-';
+ p[5+seq.getLength()] = '-';
+ p[6+seq.getLength()] = '>';
+
+ doIndent( seqWrite );
+ writeSequence( seqWrite );
+}
+
+
+void SAXWriter::allowLineBreak( ) throw ( SAXException , RuntimeException)
+{
+ if( ! m_bDocStarted || m_bAllowLineBreak ) {
+ throw SAXException();
+ }
+
+ m_bAllowLineBreak = sal_True;
+}
+
+void SAXWriter::unknown(const OUString& sString) throw (SAXException, RuntimeException)
+{
+
+ if( ! m_bDocStarted )
+ {
+ throw SAXException ();
+ }
+ if( m_bIsCDATA )
+ {
+ throw SAXException();
+ }
+
+ pushStartElement();
+
+ OString str = OUStringToOString( sString , RTL_TEXTENCODING_UTF8 );
+
+ Sequence<sal_Int8> seq( str.getLength() );
+ memcpy( seq.getArray() , str.getStr() , str.getLength() );
+
+ doIndent( seq );
+ writeSequence( seq );
+}
+
+
diff --git a/sax/source/expatwrap/xml2utf.cxx b/sax/source/expatwrap/xml2utf.cxx
new file mode 100644
index 000000000000..a87cefab493a
--- /dev/null
+++ b/sax/source/expatwrap/xml2utf.cxx
@@ -0,0 +1,607 @@
+/*************************************************************************
+ *
+ * $RCSfile: xml2utf.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 16:43:13 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#include <string.h>
+#include <assert.h>
+
+#include <sal/types.h>
+
+#include <rtl/textenc.h>
+#include <rtl/tencinfo.h>
+
+
+#include <com/sun/star/io/XInputStream.hpp>
+
+using namespace rtl;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::io;
+
+#include "xml2utf.hxx"
+
+
+sal_Int32 XMLFile2UTFConverter::readAndConvert( Sequence<sal_Int8> &seq , sal_Int32 nMaxToRead )
+ throw ( IOException, NotConnectedException , BufferSizeExceededException , RuntimeException )
+{
+
+ Sequence<sal_Int8> seqIn;
+
+ if( ! m_in.is() ) {
+ throw NotConnectedException();
+ }
+ if( ! m_bStarted ) {
+ nMaxToRead = Max( 512 , nMaxToRead ); // it should be possible to find the encoding attribute
+ // within the first 512 bytes == 128 chars in UCS-4
+ }
+
+ sal_Int32 nRead;
+ Sequence< sal_Int8 > seqStart;
+ while( sal_True )
+ {
+ nRead = m_in->readSomeBytes( seq , nMaxToRead );
+
+ if( nRead + seqStart.getLength())
+ {
+ // if nRead is 0, the file is already eof.
+ if( ! m_bStarted && nRead )
+ {
+ // ensure that enough data is available to parse encoding
+ if( seqStart.getLength() )
+ {
+ seq.realloc( seqStart.getLength() + seq.getLength() );
+ memcpy( (sal_Int8*)seq.getConstArray() + seqStart.getLength() ,
+ seq.getConstArray() ,
+ seq.getLength() );
+ memcpy( (sal_Int8*)seq.getConstArray() ,
+ seqStart.getConstArray(),
+ seqStart.getLength() );
+ }
+
+ // autodetection with the first bytes
+ if( ! isEncodingRecognizable( seq ) )
+ {
+ seqStart.realloc( seqStart.getLength() + seq.getLength() );
+ memcpy( (sal_Int8*)seqStart.getConstArray() + seqStart.getLength(),
+ seq.getConstArray(),
+ seq.getLength());
+ // read more !
+ continue;
+ }
+ if( scanForEncoding( seq ) || m_sEncoding.getLength() ) {
+ // initialize decoding
+ initializeDecoding();
+ }
+ nRead = seq.getLength();
+ seqStart = Sequence < sal_Int8 > ();
+ }
+
+ // do the encoding
+ if( m_pText2Unicode && m_pUnicode2Text &&
+ m_pText2Unicode->canContinue() && m_pUnicode2Text->canContinue() ) {
+
+ Sequence<sal_Unicode> seqUnicode = m_pText2Unicode->convert( seq );
+ seq = m_pUnicode2Text->convert( seqUnicode.getConstArray(), seqUnicode.getLength() );
+ }
+
+ if( ! m_bStarted )
+ {
+ // it must now be ensured, that no encoding attribute exist anymore
+ // ( otherwise the expat-Parser will crash )
+ // This must be done after decoding !
+ // ( e.g. Files decoded in ucs-4 cannot be read properly )
+ m_bStarted = sal_True;
+ removeEncoding( seq );
+ }
+ nRead = seq.getLength();
+ }
+
+ break;
+ }
+ return nRead;
+}
+
+
+XMLFile2UTFConverter::~XMLFile2UTFConverter()
+{
+ if( m_pText2Unicode )
+ delete m_pText2Unicode;
+ if( m_pUnicode2Text )
+ delete m_pUnicode2Text;
+}
+
+
+void XMLFile2UTFConverter::removeEncoding( Sequence<sal_Int8> &seq )
+{
+ const sal_Int8 *pSource = seq.getArray();
+ if( ! strncmp( (const char * ) pSource , "<?xml" , 4) )
+ {
+
+ // scan for encoding
+ OString str( (sal_Char * ) pSource , seq.getLength() );
+
+ // cut sequence to first line break
+ // find first line break;
+ int nMax = str.indexOf( 10 );
+ if( nMax >= 0 )
+ {
+ str = str.copy( 0 , nMax );
+ }
+
+ int nFound = str.indexOf( " encoding" );
+ if( nFound < str.getLength() ) {
+ int nStop;
+ int nStart = str.indexOf( "\"" , nFound );
+ if( nStart < 0 || str.indexOf( "'" , nFound ) < nStart )
+ {
+ nStart = str.indexOf( "'" , nFound );
+ nStop = str.indexOf( "'" , nStart +1 );
+ }
+ else
+ {
+ int nStop = str.indexOf( "\"" , nStart +1);
+ }
+
+ if( nStart >= 0 && nStop >= 0 && nStart+1 < nStop )
+ {
+ // remove encoding tag from file
+ memmove( &( seq.getArray()[nFound] ) ,
+ &( seq.getArray()[nStop+1]) ,
+ seq.getLength() - nStop -1);
+ seq.realloc( seq.getLength() - ( nStop+1 - nFound ) );
+// str = String( (char * ) seq.getArray() , seq.getLen() );
+ }
+ }
+ }
+}
+
+// Checks, if enough data has been accumulated to recognize the encoding
+sal_Bool XMLFile2UTFConverter::isEncodingRecognizable( const Sequence< sal_Int8 > &seq)
+{
+ const sal_Int8 *pSource = seq.getConstArray();
+ sal_Bool bCheckIfFirstClosingBracketExsists = sal_False;
+
+ if( seq.getLength() < 8 ) {
+ // no recognition possible, when less than 8 bytes are available
+ return sal_False;
+ }
+
+ if( ! strncmp( (const char * ) pSource , "<?xml" , 4 ) ) {
+ // scan if the <?xml tag finishes within this buffer
+ bCheckIfFirstClosingBracketExsists = sal_True;
+ }
+ else if( ('<' == pSource[0] || '<' == pSource[2] ) &&
+ ( ('?' == pSource[4] || '?' == pSource[6] ) ) )
+ {
+ // check for utf-16
+ bCheckIfFirstClosingBracketExsists = sal_True;
+ }
+ else if( ( '<' == pSource[1] || '<' == pSource[3] ) &&
+ ( '?' == pSource[5] || '?' == pSource[7] ) )
+ {
+ // check for
+ bCheckIfFirstClosingBracketExsists = sal_True;
+ }
+
+ if( bCheckIfFirstClosingBracketExsists )
+ {
+ for( sal_Int32 i = 0; i < seq.getLength() ; i ++ )
+ {
+ // whole <?xml tag is valid
+ if( '>' == pSource[ i ] )
+ {
+ return sal_True;
+ }
+ }
+ return sal_False;
+ }
+
+ // No <? tag in front, no need for a bigger buffer
+ return sal_True;
+}
+
+sal_Bool XMLFile2UTFConverter::scanForEncoding( Sequence< sal_Int8 > &seq )
+{
+ const sal_Int8 *pSource = seq.getConstArray();
+ sal_Bool bReturn = sal_True;
+
+ if( seq.getLength() < 4 ) {
+ // no recognition possible, when less than 4 bytes are available
+ return sal_False;
+ }
+
+ // first level : detect possible file formats
+ if( ! strncmp( (const char * ) pSource , "<?xml" , 4 ) ) {
+
+ // scan for encoding
+ OString str( (const sal_Char *) pSource , seq.getLength() );
+
+ // cut sequence to first line break
+ //find first line break;
+ int nMax = str.indexOf( 10 );
+ if( nMax >= 0 )
+ {
+ str = str.copy( 0 , nMax );
+ }
+
+ int nFound = str.indexOf( " encoding" );
+ if( nFound < str.getLength() ) {
+ int nStop;
+ int nStart = str.indexOf( "\"" , nFound );
+ if( nStart < 0 || str.indexOf( "'" , nFound ) < nStart )
+ {
+ nStart = str.indexOf( "'" , nFound );
+ nStop = str.indexOf( "'" , nStart +1 );
+ }
+ else
+ {
+ int nStop = str.indexOf( "\"" , nStart +1);
+ }
+ if( nStart >= 0 && nStop >= 0 && nStart+1 < nStop )
+ {
+ // encoding found finally
+ m_sEncoding = str.copy( nStart+1 , nStop - nStart - 1 );
+ }
+ }
+ }
+ else if( 0xFE == pSource[0] && 0xFF == pSource[1] ) {
+ // UTF-16 big endian
+ // conversion is done so that encoding information can be easily extracted
+ m_sEncoding = "utf-16";
+ }
+ else if( 0xFF == pSource[0] && 0xFE == pSource[1] ) {
+ // UTF-16 little endian
+ // conversion is done so that encoding information can be easily extracted
+ m_sEncoding = "utf-16";
+ }
+ else if( 0x00 == pSource[0] && 0x3c == pSource[1] && 0x00 == pSource[2] && 0x3f == pSource[3] ) {
+ // UTF-16 big endian without byte order mark (this is (strictly speaking) an error.)
+ // The byte order mark is simply added
+
+ // simply add the byte order mark !
+ seq.realloc( seq.getLength() + 2 );
+ memmove( &( seq.getArray()[2] ) , seq.getArray() , seq.getLength() );
+ ((sal_uInt8*)seq.getArray())[0] = 0xFE;
+ ((sal_uInt8*)seq.getArray())[1] = 0xFF;
+
+ m_sEncoding = "utf-16";
+ }
+ else if( 0x3c == pSource[0] && 0x00 == pSource[1] && 0x3f == pSource[2] && 0x00 == pSource[3] ) {
+ // UTF-16 little endian without byte order mark (this is (strictly speaking) an error.)
+ // The byte order mark is simply added
+
+ seq.realloc( seq.getLength() + 2 );
+ memmove( &( seq.getArray()[2] ) , seq.getArray() , seq.getLength() );
+ ((sal_uInt8*)seq.getArray())[0] = 0xFF;
+ ((sal_uInt8*)seq.getArray())[1] = 0xFE;
+
+ m_sEncoding = "utf-16";
+ }
+ else if( 0x00 == pSource[0] && 0x00 == pSource[1] && 0x00 == pSource[2] && 0x3c == pSource[3] ) {
+ // UCS-4 big endian
+ m_sEncoding = "ucs-4";
+ }
+ else if( 0x3c == pSource[0] && 0x00 == pSource[1] && 0x00 == pSource[2] && 0x00 == pSource[3] ) {
+ // UCS-4 little endian
+ m_sEncoding = "ucs-4";
+ }
+ else if( 0x4c == pSource[0] && 0x6f == pSource[1] && 0xa7 == pSource[2] && 0x94 == pSource[3] ) {
+ // EBCDIC
+ bReturn = sal_False; // must be extended
+ }
+ else {
+ // other
+ // UTF8 is directly recognized by the parser.
+ bReturn = sal_False;
+ }
+
+ return bReturn;
+}
+
+void XMLFile2UTFConverter::initializeDecoding()
+{
+
+ if( m_sEncoding.getLength() )
+ {
+ rtl_TextEncoding encoding = rtl_getTextEncodingFromMimeCharset( m_sEncoding.getStr() );
+ if( encoding != RTL_TEXTENCODING_UTF8 )
+ {
+ m_pText2Unicode = new Text2UnicodeConverter( m_sEncoding );
+ m_pUnicode2Text = new Unicode2TextConverter( RTL_TEXTENCODING_UTF8 );
+ }
+ }
+}
+
+
+//----------------------------------------------
+//
+// Text2UnicodeConverter
+//
+//----------------------------------------------
+Text2UnicodeConverter::Text2UnicodeConverter( const OString &sEncoding )
+{
+ rtl_TextEncoding encoding = rtl_getTextEncodingFromMimeCharset( sEncoding.getStr() );
+ if( RTL_TEXTENCODING_DONTKNOW == encoding )
+ {
+ m_bCanContinue = sal_False;
+ m_bInitialized = sal_False;
+ }
+ else
+ {
+ init( encoding );
+ }
+}
+
+Text2UnicodeConverter::Text2UnicodeConverter( rtl_TextEncoding encoding )
+{
+ init( encoding );
+}
+
+
+Text2UnicodeConverter::~Text2UnicodeConverter()
+{
+ if( m_bInitialized )
+ {
+ rtl_destroyTextToUnicodeContext( m_convText2Unicode , m_contextText2Unicode );
+ rtl_destroyUnicodeToTextConverter( m_convText2Unicode );
+ }
+}
+
+void Text2UnicodeConverter::init( rtl_TextEncoding encoding )
+{
+ m_bCanContinue = sal_True;
+ m_bInitialized = sal_True;
+
+ m_convText2Unicode = rtl_createTextToUnicodeConverter(encoding);
+ m_contextText2Unicode = rtl_createTextToUnicodeContext( m_convText2Unicode );
+ m_rtlEncoding = encoding;
+}
+
+
+Sequence<sal_Unicode> Text2UnicodeConverter::convert( const Sequence<sal_Int8> &seqText )
+{
+ sal_uInt32 uiInfo;
+ sal_Size nSrcCvtBytes = 0;
+ sal_Size nTargetCount = 0;
+ sal_Size nSourceCount = 0;
+
+ // the whole source size
+ sal_Int32 nSourceSize = seqText.getLength() + m_seqSource.getLength();
+ Sequence<sal_Unicode> seqUnicode ( nSourceSize );
+
+ const sal_Int8 *pbSource = seqText.getConstArray();
+ sal_Int8 *pbTempMem = 0;
+
+ if( m_seqSource.getLength() ) {
+ // put old rest and new byte sequence into one array
+ pbTempMem = new sal_Int8[ nSourceSize ];
+ memcpy( pbTempMem , m_seqSource.getConstArray() , m_seqSource.getLength() );
+ memcpy( &(pbTempMem[ m_seqSource.getLength() ]) , seqText.getConstArray() , seqText.getLength() );
+ pbSource = pbTempMem;
+
+ // set to zero again
+ m_seqSource = Sequence< sal_Int8 >();
+ }
+
+ while( sal_True ) {
+
+ /* All invalid characters are transformed to the unicode undefined char */
+ nTargetCount += rtl_convertTextToUnicode(
+ m_convText2Unicode,
+ m_contextText2Unicode,
+ ( const sal_Char * ) &( pbSource[nSourceCount] ),
+ nSourceSize - nSourceCount ,
+ &( seqUnicode.getArray()[ nTargetCount ] ),
+ seqUnicode.getLength() - nTargetCount,
+ RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_DEFAULT |
+ RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_DEFAULT |
+ RTL_TEXTTOUNICODE_FLAGS_INVALID_DEFAULT,
+ &uiInfo,
+ &nSrcCvtBytes );
+ nSourceCount += nSrcCvtBytes;
+
+ if( uiInfo & RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL ) {
+ // save necessary bytes for next conversion
+ seqUnicode.realloc( seqUnicode.getLength() * 2 );
+ continue;
+ }
+ break;
+ }
+ if( uiInfo & RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOSMALL ) {
+ m_seqSource.realloc( nSourceSize - nSourceCount );
+ memcpy( m_seqSource.getArray() , &(pbSource[nSourceCount]) , nSourceSize-nSourceCount );
+ }
+
+
+ if( pbTempMem ) {
+ delete pbTempMem;
+ }
+
+ // set to correct unicode size
+ seqUnicode.realloc( nTargetCount );
+
+ return seqUnicode;
+}
+
+
+
+//----------------------------------------------
+//
+// Unicode2TextConverter
+//
+//----------------------------------------------
+Unicode2TextConverter::Unicode2TextConverter( const OString &sEncoding )
+{
+ rtl_TextEncoding encoding = rtl_getTextEncodingFromMimeCharset( sEncoding.getStr() );
+ if( RTL_TEXTENCODING_DONTKNOW == encoding ) {
+ m_bCanContinue = sal_False;
+ m_bInitialized = sal_False;
+ }
+ else {
+ init( encoding );
+ }
+
+}
+
+Unicode2TextConverter::Unicode2TextConverter( rtl_TextEncoding encoding )
+{
+ init( encoding );
+}
+
+
+Unicode2TextConverter::~Unicode2TextConverter()
+{
+ if( m_bInitialized ) {
+ rtl_destroyUnicodeToTextContext( m_convUnicode2Text , m_contextUnicode2Text );
+ rtl_destroyUnicodeToTextConverter( m_convUnicode2Text );
+ }
+}
+
+
+Sequence<sal_Int8> Unicode2TextConverter::convert(const sal_Unicode *puSource , sal_Int32 nSourceSize)
+{
+ sal_Unicode *puTempMem = 0;
+
+ if( m_seqSource.getLength() ) {
+ // For surrogates !
+ // put old rest and new byte sequence into one array
+ // In general when surrogates are used, they should be rarely
+ // cut off between two convert()-calls. So this code is used
+ // rarely and the extra copy is acceptable.
+ nSourceSize += m_seqSource.getLength();
+
+ puTempMem = new sal_Unicode[ nSourceSize ];
+ memcpy( puTempMem ,
+ m_seqSource.getConstArray() ,
+ m_seqSource.getLength() * sizeof( sal_Unicode ) );
+ memcpy(
+ &(puTempMem[ m_seqSource.getLength() ]) ,
+ puSource ,
+ nSourceSize*sizeof( sal_Unicode ) );
+ puSource = puTempMem;
+
+ m_seqSource = Sequence< sal_Unicode > ();
+ }
+
+
+ sal_Size nTargetCount = 0;
+ sal_Size nSourceCount = 0;
+
+ sal_uInt32 uiInfo;
+ sal_Size nSrcCvtChars;
+
+ // take nSourceSize * 3 as preference
+ // this is an upper boundary for converting to utf8,
+ // which most often used as the target.
+ sal_Int32 nSeqSize = nSourceSize * 3;
+
+ Sequence<sal_Int8> seqText( nSeqSize );
+ sal_Char *pTarget = (sal_Char *) seqText.getArray();
+ while( sal_True ) {
+
+ nTargetCount += rtl_convertUnicodeToText(
+ m_convUnicode2Text,
+ m_contextUnicode2Text,
+ &( puSource[nSourceCount] ),
+ nSourceSize - nSourceCount ,
+ &( pTarget[nTargetCount] ),
+ nSeqSize - nTargetCount,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_DEFAULT |
+ RTL_UNICODETOTEXT_FLAGS_INVALID_DEFAULT ,
+ &uiInfo,
+ &nSrcCvtChars);
+ nSourceCount += nSrcCvtChars;
+
+ if( uiInfo & RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL ) {
+ nSeqSize = nSeqSize *2;
+ seqText.realloc( nSeqSize ); // double array size
+ pTarget = ( sal_Char * ) seqText.getArray();
+ continue;
+ }
+ break;
+ }
+
+ // for surrogates
+ if( uiInfo & RTL_UNICODETOTEXT_INFO_SRCBUFFERTOSMALL ) {
+ m_seqSource.realloc( nSourceSize - nSourceCount );
+ memcpy( m_seqSource.getArray() ,
+ &(puSource[nSourceCount]),
+ (nSourceSize - nSourceCount) * sizeof( sal_Unicode ) );
+ }
+
+ if( puTempMem ) {
+ delete puTempMem;
+ }
+
+ // reduce the size of the buffer (fast, no copy necessary)
+ seqText.realloc( nTargetCount );
+
+ return seqText;
+}
+
+void Unicode2TextConverter::init( rtl_TextEncoding encoding )
+{
+ m_bCanContinue = sal_True;
+ m_bInitialized = sal_True;
+
+ m_convUnicode2Text = rtl_createUnicodeToTextConverter( encoding );
+ m_contextUnicode2Text = rtl_createUnicodeToTextContext( m_convUnicode2Text );
+ m_rtlEncoding = encoding;
+};
+
+
diff --git a/sax/test/makefile.mk b/sax/test/makefile.mk
new file mode 100644
index 000000000000..451e999f01ea
--- /dev/null
+++ b/sax/test/makefile.mk
@@ -0,0 +1,101 @@
+#*************************************************************************
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.1.1.1 $
+#
+# last change: $Author: hr $ $Date: 2000-09-18 16:43:13 $
+#
+# The Contents of this file are made available subject to the terms of
+# either of the following licenses
+#
+# - GNU Lesser General Public License Version 2.1
+# - Sun Industry Standards Source License Version 1.1
+#
+# Sun Microsystems Inc., October, 2000
+#
+# GNU Lesser General Public License Version 2.1
+# =============================================
+# Copyright 2000 by Sun Microsystems, Inc.
+# 901 San Antonio Road, Palo Alto, CA 94303, USA
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License version 2.1, as published by the Free Software Foundation.
+#
+# This library 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 for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+#
+# Sun Industry Standards Source License Version 1.1
+# =================================================
+# The contents of this file are subject to the Sun Industry Standards
+# Source License Version 1.1 (the "License"); You may not use this file
+# except in compliance with the License. You may obtain a copy of the
+# License at http://www.openoffice.org/license.html.
+#
+# Software provided under this License is provided on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+# WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+# MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+# See the License for the specific provisions governing your rights and
+# obligations concerning the Software.
+#
+# The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+#
+# Copyright: 2000 by Sun Microsystems, Inc.
+#
+# All Rights Reserved.
+#
+# Contributor(s): _______________________________________
+#
+#
+#
+#*************************************************************************
+
+PRJ=..
+
+PRJNAME=extensions
+TARGET=workben
+LIBTARGET=NO
+
+TARGETTYPE=CUI
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : svpre.mk
+.INCLUDE : settings.mk
+.INCLUDE : sv.mk
+# --- Files --------------------------------------------------------
+
+
+
+#
+# std testcomponent
+#
+APP1TARGET = testcomponent
+APP2TARGET = saxdemo
+
+APP1OBJS = $(OBJ)$/testcomponent.obj
+APP1STDLIBS = $(SALLIB) \
+ $(CPPULIB)\
+ $(CPPUHELPERLIB)
+
+
+APP2OBJS = $(OBJ)$/saxdemo.obj
+APP2STDLIBS = $(SALLIB) \
+ $(CPPULIB) \
+ $(CPPUHELPERLIB)
+
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/sax/test/sax/exports.dxp b/sax/test/sax/exports.dxp
new file mode 100644
index 000000000000..ce95ae0f8deb
--- /dev/null
+++ b/sax/test/sax/exports.dxp
@@ -0,0 +1,3 @@
+component_getImplementationEnvironment
+component_getFactory
+component_writeInfo \ No newline at end of file
diff --git a/sax/test/sax/factory.hxx b/sax/test/sax/factory.hxx
new file mode 100644
index 000000000000..a4fea3a5c20b
--- /dev/null
+++ b/sax/test/sax/factory.hxx
@@ -0,0 +1,122 @@
+/*************************************************************************
+ *
+ * $RCSfile: factory.hxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 16:43:13 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#include <rtl/strbuf.hxx>
+
+Reference< XInterface > SAL_CALL OSaxWriterTest_CreateInstance(
+ const Reference< XMultiServiceFactory > & rSMgr ) throw ( Exception );
+OUString OSaxWriterTest_getServiceName( ) throw();
+OUString OSaxWriterTest_getImplementationName( ) throw();
+Sequence<OUString> OSaxWriterTest_getSupportedServiceNames( ) throw();
+
+#define BUILD_ERROR(expr, Message)\
+ {\
+ m_seqErrors.realloc( m_seqErrors.getLength() + 1 ); \
+ m_seqExceptions.realloc( m_seqExceptions.getLength() + 1 ); \
+ OStringBuffer str(128); \
+ str.append( __FILE__ );\
+ str.append( " " ); \
+ str.append( "(" ); \
+ str.append( OString::valueOf( (sal_Int32)__LINE__) );\
+ str.append(")\n" );\
+ str.append( "[ " ); \
+ str.append( #expr ); \
+ str.append( " ] : " ); \
+ str.append( Message ); \
+ m_seqErrors.getArray()[ m_seqErrors.getLength()-1] =\
+ OStringToOUString( str.makeStringAndClear() , RTL_TEXTENCODING_ASCII_US ); \
+ }\
+ ((void)0)
+
+
+#define WARNING_ASSERT(expr, Message) \
+ if( ! (expr) ) { \
+ m_seqWarnings.realloc( m_seqErrors.getLength() +1 ); \
+ OStringBuffer str(128);\
+ str.append( __FILE__);\
+ str.append( " "); \
+ str.append( "(" ); \
+ str.append(OString::valueOf( (sal_Int32)__LINE__)) ;\
+ str.append( ")\n");\
+ str.append( "[ " ); \
+ str.append( #expr ); \
+ str.append( " ] : ") ; \
+ str.append( Message); \
+ m_seqWarnings.getArray()[ m_seqWarnings.getLength()-1] =\
+ OStringToOUString( str.makeStringAndClear() , RTL_TEXTENCODING_ASCII_US ); \
+ return; \
+ }\
+ ((void)0)
+
+#define ERROR_ASSERT(expr, Message) \
+ if( ! (expr) ) { \
+ BUILD_ERROR(expr, Message );\
+ return; \
+ }\
+ ((void)0)
+
+#define ERROR_EXCEPTION_ASSERT(expr, Message, Exception) \
+ if( !(expr)) { \
+ BUILD_ERROR(expr,Message);\
+ m_seqExceptions.getArray()[ m_seqExceptions.getLength()-1] = Any( Exception );\
+ return; \
+ } \
+ ((void)0)
+
diff --git a/sax/test/sax/makefile.mk b/sax/test/sax/makefile.mk
new file mode 100644
index 000000000000..062b3073243d
--- /dev/null
+++ b/sax/test/sax/makefile.mk
@@ -0,0 +1,99 @@
+#*************************************************************************
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.1.1.1 $
+#
+# last change: $Author: hr $ $Date: 2000-09-18 16:43:13 $
+#
+# The Contents of this file are made available subject to the terms of
+# either of the following licenses
+#
+# - GNU Lesser General Public License Version 2.1
+# - Sun Industry Standards Source License Version 1.1
+#
+# Sun Microsystems Inc., October, 2000
+#
+# GNU Lesser General Public License Version 2.1
+# =============================================
+# Copyright 2000 by Sun Microsystems, Inc.
+# 901 San Antonio Road, Palo Alto, CA 94303, USA
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License version 2.1, as published by the Free Software Foundation.
+#
+# This library 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 for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+#
+# Sun Industry Standards Source License Version 1.1
+# =================================================
+# The contents of this file are subject to the Sun Industry Standards
+# Source License Version 1.1 (the "License"); You may not use this file
+# except in compliance with the License. You may obtain a copy of the
+# License at http://www.openoffice.org/license.html.
+#
+# Software provided under this License is provided on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+# WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+# MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+# See the License for the specific provisions governing your rights and
+# obligations concerning the Software.
+#
+# The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+#
+# Copyright: 2000 by Sun Microsystems, Inc.
+#
+# All Rights Reserved.
+#
+# Contributor(s): _______________________________________
+#
+#
+#
+#*************************************************************************
+PRJ=..$/..
+
+PRJNAME=extensions
+TARGET=testsax
+USE_DEFFILE=TRUE
+ENABLE_EXCEPTIONS=TRUE
+# --- Settings -----------------------------------------------------
+.INCLUDE : svpre.mk
+.INCLUDE : settings.mk
+.INCLUDE : sv.mk
+
+# --- Files --------------------------------------------------------
+
+
+SLOFILES = $(SLO)$/testsax.obj \
+ $(SLO)$/testwriter.obj
+
+
+SHL1TARGET= $(TARGET)
+SHL1IMPLIB= i$(TARGET)
+
+SHL1STDLIBS= \
+ $(SALLIB) \
+ $(CPPULIB) \
+ $(CPPUHELPERLIB)
+
+
+SHL1LIBS= $(SLB)$/$(TARGET).lib
+SHL1DEPN= makefile.mk $(SHL1LIBS)
+SHL1DEF= $(MISC)$/$(SHL1TARGET).def
+
+DEF1NAME= $(SHL1TARGET)
+DEF1EXPORTFILE= exports.dxp
+
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/sax/test/sax/testsax.cxx b/sax/test/sax/testsax.cxx
new file mode 100644
index 000000000000..6de45e7acf38
--- /dev/null
+++ b/sax/test/sax/testsax.cxx
@@ -0,0 +1,902 @@
+/*************************************************************************
+ *
+ * $RCSfile: testsax.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 16:43:13 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+#include <osl/time.h>
+#include <osl/diagnose.h>
+
+
+#include <com/sun/star/test/XSimpleTest.hpp>
+
+#include <com/sun/star/io/XOutputStream.hpp>
+
+#include <com/sun/star/xml/sax/SAXParseException.hpp>
+#include <com/sun/star/xml/sax/XParser.hpp>
+#include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp>
+
+#include <cppuhelper/factory.hxx>
+#include <cppuhelper/implbase1.hxx>
+#include <cppuhelper/implbase3.hxx>
+
+using namespace ::rtl;
+using namespace ::cppu;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::test;
+using namespace ::com::sun::star::registry;
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::xml::sax;
+
+#include "factory.hxx"
+
+/****
+* test szenarios :
+*
+*
+*
+****/
+
+class OSaxParserTest : public WeakImplHelper1< XSimpleTest >
+{
+public:
+ OSaxParserTest( const Reference < XMultiServiceFactory > & rFactory ) : m_rFactory( rFactory )
+ {
+ }
+public:
+ virtual void SAL_CALL testInvariant(
+ const OUString& TestName,
+ const Reference < XInterface >& TestObject)
+ throw ( IllegalArgumentException, RuntimeException);
+
+ virtual sal_Int32 SAL_CALL test(
+ const OUString& TestName,
+ const Reference < XInterface >& TestObject,
+ sal_Int32 hTestHandle)
+ throw ( IllegalArgumentException,RuntimeException);
+
+ virtual sal_Bool SAL_CALL testPassed(void) throw ( RuntimeException);
+ virtual Sequence< OUString > SAL_CALL getErrors(void) throw (RuntimeException);
+ virtual Sequence< Any > SAL_CALL getErrorExceptions(void) throw (RuntimeException);
+ virtual Sequence< OUString > SAL_CALL getWarnings(void) throw (RuntimeException);
+
+private:
+ void testSimple( const Reference < XParser > &r );
+ void testNamespaces( const Reference < XParser > &r );
+ void testFile( const Reference < XParser > &r );
+ void testEncoding( const Reference < XParser > &rParser );
+ void testPerformance( const Reference < XParser > &rParser );
+
+private:
+ Sequence<Any> m_seqExceptions;
+ Sequence<OUString> m_seqErrors;
+ Sequence<OUString> m_seqWarnings;
+ Reference < XMultiServiceFactory > m_rFactory;
+};
+
+
+
+/**
+* for external binding
+*
+*
+**/
+Reference < XInterface > SAL_CALL OSaxParserTest_CreateInstance( const Reference < XMultiServiceFactory > & rSMgr ) throw(Exception)
+{
+ OSaxParserTest *p = new OSaxParserTest( rSMgr );
+ return Reference < XInterface > ( SAL_STATIC_CAST( OWeakObject * , p ) );
+}
+
+
+OUString OSaxParserTest_getServiceName( ) throw ()
+{
+ return OUString( RTL_CONSTASCII_USTRINGPARAM("test.com.sun.star.xml.sax.Parser" ));
+}
+
+OUString OSaxParserTest_getImplementationName( ) throw ()
+{
+ return OUString( RTL_CONSTASCII_USTRINGPARAM("test.extensions.xml.sax.Parser"));
+}
+
+Sequence<OUString> OSaxParserTest_getSupportedServiceNames( ) throw ()
+{
+ Sequence<OUString> aRet(1);
+
+ aRet.getArray()[0] = OSaxParserTest_getImplementationName( );
+
+ return aRet;
+}
+
+
+
+
+void OSaxParserTest::testInvariant(
+ const OUString& TestName,
+ const Reference < XInterface >& TestObject )
+ throw ( IllegalArgumentException, RuntimeException)
+{
+ if( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.sax.Parser")) == TestName ) {
+ Reference < XParser > parser( TestObject , UNO_QUERY );
+
+ ERROR_ASSERT( parser.is() , "XDataInputStream cannot be queried" );
+ }
+}
+
+
+sal_Int32 OSaxParserTest::test(
+ const OUString& TestName,
+ const Reference < XInterface >& TestObject,
+ sal_Int32 hTestHandle)
+ throw ( IllegalArgumentException, RuntimeException)
+{
+ if( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.sax.Parser")) == TestName ) {
+ try
+ {
+ if( 0 == hTestHandle ) {
+ testInvariant( TestName , TestObject );
+ }
+ else {
+
+ Reference < XParser > parser( TestObject , UNO_QUERY );
+
+ if( 1 == hTestHandle ) {
+ testSimple( parser );
+ }
+ else if( 2 == hTestHandle ) {
+ testNamespaces( parser );
+ }
+ else if( 3 == hTestHandle ) {
+ testEncoding( parser );
+ }
+ else if( 4 == hTestHandle ) {
+ testFile( parser );
+ }
+ else if( 5 == hTestHandle ) {
+ testPerformance( parser );
+ }
+ }
+ }
+ catch( Exception & e )
+ {
+ OString o = OUStringToOString( e.Message , RTL_TEXTENCODING_ASCII_US);
+ BUILD_ERROR( 0 , o.getStr() );
+ }
+ catch( ... )
+ {
+ BUILD_ERROR( 0 , "unknown exception (Exception is not base class)" );
+ }
+
+ hTestHandle ++;
+
+ if( hTestHandle >= 6) {
+ // all tests finished.
+ hTestHandle = -1;
+ }
+ }
+ else {
+ BUILD_ERROR( 0 , "service not supported by test." );
+ }
+ return hTestHandle;
+}
+
+
+
+sal_Bool OSaxParserTest::testPassed(void) throw (RuntimeException)
+{
+ return m_seqErrors.getLength() == 0;
+}
+
+
+Sequence< OUString > OSaxParserTest::getErrors(void) throw (RuntimeException)
+{
+ return m_seqErrors;
+}
+
+
+Sequence< Any > OSaxParserTest::getErrorExceptions(void) throw (RuntimeException)
+{
+ return m_seqExceptions;
+}
+
+
+Sequence< OUString > OSaxParserTest::getWarnings(void) throw (RuntimeException)
+{
+ return m_seqWarnings;
+}
+
+Reference < XInputStream > createStreamFromSequence(
+ const Sequence<sal_Int8> seqBytes ,
+ const Reference < XMultiServiceFactory > &xSMgr )
+{
+ Reference < XInterface > xOutStreamService =
+ xSMgr->createInstance( L"com.sun.star.io.Pipe" );
+ assert( xOutStreamService.is() );
+ Reference< XOutputStream > rOutStream( xOutStreamService , UNO_QUERY );
+ assert( rOutStream.is() );
+
+ Reference< XInputStream > rInStream( xOutStreamService , UNO_QUERY );
+ assert( rInStream.is() );
+
+ rOutStream->writeBytes( seqBytes );
+ rOutStream->flush();
+ rOutStream->closeOutput();
+
+ return rInStream;
+}
+
+Reference< XInputStream > createStreamFromFile(
+ const char *pcFile ,
+ const Reference < XMultiServiceFactory > &xSMgr )
+{
+ FILE *f = fopen( pcFile , "rb" );
+ Reference< XInputStream > r;
+
+ if( f ) {
+ fseek( f , 0 , SEEK_END );
+ int nLength = ftell( f );
+ fseek( f , 0 , SEEK_SET );
+
+ Sequence<sal_Int8> seqIn(nLength);
+ fread( seqIn.getArray() , nLength , 1 , f );
+
+ r = createStreamFromSequence( seqIn , xSMgr );
+ fclose( f );
+ }
+ return r;
+}
+
+
+
+
+
+
+
+
+
+// #define PCHAR_TO_OUSTRING(x) OStringToOUString(x,CHARSET_PC_1252)
+// #define USTRING_TO_PCHAR(x) UStringToString(x,CHARSET_PC_437).GetStr()
+
+
+
+class TestDocumentHandler :
+ public WeakImplHelper3< XExtendedDocumentHandler , XEntityResolver , XErrorHandler >
+{
+public:
+ TestDocumentHandler( const Reference < XMultiServiceFactory > &r , sal_Bool bPrint )
+ {
+ m_xSMgr = r;
+ m_bPrint = bPrint;
+ }
+
+public: // Error handler
+ virtual void SAL_CALL error(const Any& aSAXParseException) throw (SAXException, RuntimeException)
+ {
+ printf( "Error !\n" );
+ throw SAXException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("error from error handler")) ,
+ Reference < XInterface >() ,
+ aSAXParseException );
+ }
+ virtual void SAL_CALL fatalError(const Any& aSAXParseException) throw (SAXException, RuntimeException)
+ {
+ printf( "Fatal Error !\n" );
+ }
+ virtual void SAL_CALL warning(const Any& aSAXParseException) throw (SAXException, RuntimeException)
+ {
+ printf( "Warning !\n" );
+ }
+
+
+public: // ExtendedDocumentHandler
+
+ virtual void SAL_CALL startDocument(void) throw (SAXException, RuntimeException)
+ {
+ m_iLevel = 0;
+ m_iElementCount = 0;
+ m_iAttributeCount = 0;
+ m_iWhitespaceCount =0;
+ m_iCharCount=0;
+ if( m_bPrint ) {
+ printf( "document started\n" );
+ }
+ }
+ virtual void SAL_CALL endDocument(void) throw (SAXException, RuntimeException)
+ {
+ if( m_bPrint ) {
+ printf( "document finished\n" );
+ printf( "(ElementCount %d),(AttributeCount %d),(WhitespaceCount %d),(CharCount %d)\n",
+ m_iElementCount, m_iAttributeCount, m_iWhitespaceCount , m_iCharCount );
+ }
+ }
+ virtual void SAL_CALL startElement(const OUString& aName,
+ const Reference< XAttributeList > & xAttribs)
+ throw (SAXException,RuntimeException)
+ {
+
+ if( m_rLocator.is() ) {
+ if( m_bPrint )
+ {
+ OString o = OUStringToOString( m_rLocator->getSystemId() , RTL_TEXTENCODING_UTF8 );
+ printf( "%s(%d):" , o.getStr() , m_rLocator->getLineNumber() );
+ }
+ }
+ if( m_bPrint ) {
+ int i;
+ for( i = 0; i < m_iLevel ; i ++ ) {
+ printf( " " );
+ }
+ OString o = OUStringToOString(aName , RTL_TEXTENCODING_UTF8 );
+ printf( "<%s> " , aName.getStr() );
+
+ for( i = 0 ; i < xAttribs->getLength() ; i ++ )
+ {
+ OString o1 = OUStringToOString(xAttribs->getNameByIndex( i ), RTL_TEXTENCODING_UTF8 );
+ OString o2 = OUStringToOString(xAttribs->getTypeByIndex( i ), RTL_TEXTENCODING_UTF8 );
+ OString o3 = OUStringToOString(xAttribs->getValueByIndex( i ) , RTL_TEXTENCODING_UTF8 );
+ printf( "(%s,%s,'%s')" , o1.getStr(), o2.getStr(), o3.getStr() );
+ }
+ printf( "\n" );
+ }
+ m_iLevel ++;
+ m_iElementCount ++;
+ m_iAttributeCount += xAttribs->getLength();
+ }
+
+ virtual void SAL_CALL endElement(const OUString& aName) throw (SAXException,RuntimeException)
+ {
+ assert( m_iLevel );
+ m_iLevel --;
+ if( m_bPrint ) {
+ int i;
+ for( i = 0; i < m_iLevel ; i ++ ) {
+ printf( " " );
+ }
+ OString o = OUStringToOString(aName , RTL_TEXTENCODING_UTF8 );
+ printf( "</%s>\n" , o.getStr() );
+ }
+ }
+
+ virtual void SAL_CALL characters(const OUString& aChars) throw (SAXException,RuntimeException)
+ {
+ if( m_bPrint ) {
+ int i;
+ for( i = 0; i < m_iLevel ; i ++ ) {
+ printf( " " );
+ }
+ OString o = OUStringToOString(aChars , RTL_TEXTENCODING_UTF8 );
+ printf( "%s\n" , o.getStr() );
+ }
+ m_iCharCount += aChars.len();
+ }
+ virtual void SAL_CALL ignorableWhitespace(const OUString& aWhitespaces) throw (SAXException,RuntimeException)
+ {
+ m_iWhitespaceCount += aWhitespaces.len();
+ }
+
+ virtual void SAL_CALL processingInstruction(const OUString& aTarget, const OUString& aData) throw (SAXException,RuntimeException)
+ {
+ if( m_bPrint )
+ {
+ OString o1 = OUStringToOString(aTarget, RTL_TEXTENCODING_UTF8 );
+ OString o2 = OUStringToOString(aData, RTL_TEXTENCODING_UTF8 );
+ printf( "PI : %s,%s\n" , o1.getStr() , o2.getStr() );
+ }
+ }
+
+ virtual void SAL_CALL setDocumentLocator(const Reference< XLocator> & xLocator)
+ throw (SAXException,RuntimeException)
+ {
+ m_rLocator = xLocator;
+ }
+
+ virtual InputSource SAL_CALL resolveEntity(
+ const OUString& sPublicId,
+ const OUString& sSystemId)
+ throw (SAXException,RuntimeException)
+ {
+ InputSource source;
+ source.sSystemId = sSystemId;
+ source.sPublicId = sPublicId;
+
+ source.aInputStream = createStreamFromFile(
+ OUStringToOString( sSystemId , RTL_TEXTENCODING_ASCII_US) , m_xSMgr );
+
+ return source;
+ }
+
+ virtual void SAL_CALL startCDATA(void) throw (SAXException,RuntimeException)
+ {
+ if( m_bPrint ) {
+ printf( "CDataStart :\n" );
+ }
+ }
+ virtual void SAL_CALL endCDATA(void) throw (SAXException,RuntimeException)
+ {
+ if( m_bPrint ) {
+ printf( "CEndStart :\n" );
+ }
+ }
+ virtual void SAL_CALL comment(const OUString& sComment) throw (SAXException,RuntimeException)
+ {
+ if( m_bPrint ) {
+ OString o1 = OUStringToOString(sComment, RTL_TEXTENCODING_UTF8 );
+ printf( "<!--%s-->\n" , o1.getStr() );
+ }
+ }
+ virtual void SAL_CALL unknown(const OUString& sString) throw (SAXException,RuntimeException)
+ {
+ if( m_bPrint )
+ {
+ OString o1 = OUStringToOString(sString, RTL_TEXTENCODING_UTF8 );
+ printf( "UNKNOWN : {%s}\n" , o1.getStr() );
+ }
+ }
+
+ virtual void SAL_CALL allowLineBreak( void) throw (SAXException, RuntimeException )
+ {
+
+ }
+
+
+public:
+ int m_iLevel;
+ int m_iElementCount;
+ int m_iAttributeCount;
+ int m_iWhitespaceCount;
+ int m_iCharCount;
+ sal_Bool m_bPrint;
+
+ Reference < XMultiServiceFactory > m_xSMgr;
+ Reference < XLocator > m_rLocator;
+};
+
+
+void OSaxParserTest::testSimple( const Reference < XParser > &rParser )
+{
+
+ char TestString[] = "<!DOCTYPE personnel [\n"
+ "<!ENTITY testInternal \"internal Test!\">\n"
+ "<!ENTITY test SYSTEM \"external_entity.xml\">\n"
+ "]>\n"
+ "<personnel>\n"
+ "<person> fjklsfdklsdfkl\n"
+ "fjklsfdklsdfkl\n"
+ "<?testpi pidata?>\n"
+ "&testInternal;\n"
+ "<HUHU x='5' y='kjfd'> blahuhu\n"
+ "<HI> blahi\n"
+ " <![CDATA[<greeting>Hello, '+1+12world!</greeting>]]>\n"
+ " <!-- huhu <jdk> -->\n"
+ "<?testpi pidata?>\n"
+ "</HI>\n"
+ "aus XMLTest\n"
+ "</HUHU>\n"
+ "</person>\n"
+ "</personnel>\n\n\n";
+
+ Sequence< sal_Int8> seqBytes( strlen( TestString ) );
+ memcpy( seqBytes.getArray() , TestString , strlen( TestString ) );
+
+
+ Reference< XInputStream > rInStream;
+ OUString sInput;
+ rInStream = createStreamFromSequence( seqBytes , m_rFactory );
+ sInput = OUString( OUString( RTL_CONSTASCII_USTRINGPARAM("internal")) );
+
+ if( rParser.is() ) {
+ InputSource source;
+
+ source.aInputStream = rInStream;
+ source.sSystemId = sInput;
+
+ TestDocumentHandler *pDocHandler = new TestDocumentHandler( m_rFactory , sal_False );
+ Reference < XDocumentHandler > rDocHandler( (XDocumentHandler *) pDocHandler , UNO_QUERY );
+ Reference< XEntityResolver >
+ rEntityResolver( (XEntityResolver *) pDocHandler , UNO_QUERY );
+
+ rParser->setDocumentHandler( rDocHandler );
+ rParser->setEntityResolver( rEntityResolver );
+
+ try
+ {
+ rParser->parseStream( source );
+ ERROR_ASSERT( pDocHandler->m_iElementCount == 4 , "wrong element count" );
+ ERROR_ASSERT( pDocHandler->m_iAttributeCount == 2 , "wrong attribut count" );
+ ERROR_ASSERT( pDocHandler->m_iCharCount == 130 , "wrong char count" );
+ ERROR_ASSERT( pDocHandler->m_iWhitespaceCount == 0, "wrong whitespace count" );
+ }
+ catch( SAXParseException & e )
+ {
+ OString o1 = OUStringToOString(e.Message, RTL_TEXTENCODING_UTF8 );
+ BUILD_ERROR( 1 , o1.getStr() );
+ }
+ catch( SAXException & e )
+ {
+ OString o1 = OUStringToOString(e.Message, RTL_TEXTENCODING_UTF8 );
+ BUILD_ERROR( 1 , o1.getStr() );
+ }
+ catch( Exception & e )
+ {
+ OString o1 = OUStringToOString(e.Message, RTL_TEXTENCODING_UTF8 );
+ BUILD_ERROR( 1 , o1.getStr() );
+ }
+ catch( ... )
+ {
+ BUILD_ERROR( 1 , "unknown exception" );
+ }
+ }
+}
+
+void OSaxParserTest::testNamespaces( const Reference < XParser > &rParser )
+{
+
+ char TestString[] =
+ "<?xml version='1.0'?>\n"
+ "<!-- all elements here are explicitly in the HTML namespace -->\n"
+ "<html:html xmlns:html='http://www.w3.org/TR/REC-html40'>\n"
+ "<html:head><html:title>Frobnostication</html:title></html:head>\n"
+ "<html:body><html:p>Moved to \n"
+ "<html:a href='http://frob.com'>here.</html:a></html:p></html:body>\n"
+ "</html:html>\n";
+
+ Sequence<sal_Int8> seqBytes( strlen( TestString ) );
+ memcpy( seqBytes.getArray() , TestString , strlen( TestString ) );
+
+
+ Reference< XInputStream > rInStream;
+ OUString sInput;
+
+ rInStream = createStreamFromSequence( seqBytes , m_rFactory );
+ sInput = OUString( RTL_CONSTASCII_USTRINGPARAM( "internal" ));
+
+ if( rParser.is() ) {
+ InputSource source;
+
+ source.aInputStream = rInStream;
+ source.sSystemId = sInput;
+
+ TestDocumentHandler *pDocHandler = new TestDocumentHandler( m_rFactory , sal_False );
+ Reference < XDocumentHandler > rDocHandler( (XDocumentHandler *) pDocHandler , UNO_QUERY );
+ Reference< XEntityResolver > rEntityResolver(
+ (XEntityResolver *) pDocHandler , UNO_QUERY );
+
+ rParser->setDocumentHandler( rDocHandler );
+ rParser->setEntityResolver( rEntityResolver );
+
+ try
+ {
+ rParser->parseStream( source );
+ ERROR_ASSERT( pDocHandler->m_iElementCount == 6 , "wrong element count" );
+ ERROR_ASSERT( pDocHandler->m_iAttributeCount == 2 , "wrong attribut count" );
+ ERROR_ASSERT( pDocHandler->m_iCharCount == 33, "wrong char count" );
+ ERROR_ASSERT( pDocHandler->m_iWhitespaceCount == 0 , "wrong whitespace count" );
+ }
+ catch( Exception & e ) {
+ OString o1 = OUStringToOString(e.Message, RTL_TEXTENCODING_UTF8 );
+ BUILD_ERROR( 1 , o1.getStr() );
+ }
+ catch( ... )
+ {
+ BUILD_ERROR( 1 , "unknown exception" );
+ }
+ }
+}
+
+void OSaxParserTest::testEncoding( const Reference < XParser > &rParser )
+{
+ char TestString[] =
+ "<?xml version='1.0' encoding=\"iso-8859-1\"?>\n"
+ "<!-- all elements here are explicitly in the HTML namespace -->\n"
+ "<html:html xmlns:html='http://www.w3.org/TR/REC-html40'>\n"
+ "<html:head><html:title>Frobnostication</html:title></html:head>\n"
+ "<html:body><html:p>Moved to ß\n"
+ "<html:a href='http://frob.com'>here.</html:a></html:p></html:body>\n"
+ "</html:html>\n";
+
+ Sequence<sal_Int8> seqBytes( strlen( TestString ) );
+ memcpy( seqBytes.getArray() , TestString , strlen( TestString ) );
+
+
+ Reference< XInputStream > rInStream;
+ OUString sInput;
+
+ rInStream = createStreamFromSequence( seqBytes , m_rFactory );
+ sInput = OUString( RTL_CONSTASCII_USTRINGPARAM("internal") );
+
+ if( rParser.is() ) {
+ InputSource source;
+
+ source.aInputStream = rInStream;
+ source.sSystemId = sInput;
+
+ TestDocumentHandler *pDocHandler = new TestDocumentHandler( m_rFactory , sal_False );
+ Reference < XDocumentHandler > rDocHandler( (XDocumentHandler *) pDocHandler , UNO_QUERY );
+ Reference< XEntityResolver > rEntityResolver( (XEntityResolver *) pDocHandler , UNO_QUERY );
+
+ rParser->setDocumentHandler( rDocHandler );
+ rParser->setEntityResolver( rEntityResolver );
+ try
+ {
+ rParser->parseStream( source );
+ }
+ catch( Exception & e )
+ {
+ OString o1 = OUStringToOString(e.Message, RTL_TEXTENCODING_UTF8 );
+ BUILD_ERROR( 1 , o1.getStr() );
+ }
+ catch ( ... )
+ {
+ BUILD_ERROR( 1 , "unknown exception" );
+ }
+ }
+}
+
+void OSaxParserTest::testFile( const Reference < XParser > & rParser )
+{
+
+ Reference< XInputStream > rInStream = createStreamFromFile( "testsax.xml" , m_rFactory );
+ OUString sInput = OUString( RTL_CONSTASCII_USTRINGPARAM( "testsax.xml" ) );
+
+
+ if( rParser.is() && rInStream.is() ) {
+ InputSource source;
+
+ source.aInputStream = rInStream;
+ source.sSystemId = sInput;
+
+ TestDocumentHandler *pDocHandler = new TestDocumentHandler( m_rFactory , sal_True );
+ Reference < XDocumentHandler > rDocHandler( (XDocumentHandler *) pDocHandler , UNO_QUERY );
+ Reference < XEntityResolver > rEntityResolver( (XEntityResolver *) pDocHandler , UNO_QUERY );
+ Reference < XErrorHandler > rErrorHandler( ( XErrorHandler * )pDocHandler , UNO_QUERY );
+
+ rParser->setDocumentHandler( rDocHandler );
+ rParser->setEntityResolver( rEntityResolver );
+ rParser->setErrorHandler( rErrorHandler );
+
+ try
+ {
+ rParser->parseStream( source );
+ }
+ catch( SAXParseException & e ) {
+ Any any;
+ any <<= e;
+
+ while(sal_True) {
+ SAXParseException *pEx;
+ if( any.getValueType() == getCppuType( &e ) ) {
+ pEx = ( SAXParseException * ) any.getValue();
+ OString o1 = OUStringToOString(pEx->Message, RTL_TEXTENCODING_UTF8 );
+ printf( "%s\n" , o1.getStr() );
+ any = pEx->WrappedException;
+ }
+ else {
+ break;
+ }
+ }
+ }
+ catch( SAXException & e )
+ {
+ OString o1 = OUStringToOString(e.Message, RTL_TEXTENCODING_UTF8 );
+ BUILD_ERROR( 1 , o1.getStr() );
+
+ }
+ catch( Exception & e ) {
+ printf( "normal exception ! %s\n", e.Message );
+ }
+ catch ( ... )
+ {
+ printf( "any exception !!!!\n" );
+ }
+ }
+}
+
+void OSaxParserTest::testPerformance( const Reference < XParser > & rParser )
+{
+
+ Reference < XInputStream > rInStream =
+ createStreamFromFile( "testPerformance.xml" , m_rFactory );
+ OUString sInput = OUString( RTL_CONSTASCII_USTRINGPARAM( "testperformance.xml") );
+
+ if( rParser.is() && rInStream.is() ) {
+ InputSource source;
+
+ source.aInputStream = rInStream;
+ source.sSystemId = sInput;
+
+ TestDocumentHandler *pDocHandler = new TestDocumentHandler( m_rFactory , sal_False );
+ Reference < XDocumentHandler > rDocHandler( (XDocumentHandler *) pDocHandler , UNO_QUERY );
+ Reference < XEntityResolver > rEntityResolver( (XEntityResolver *) pDocHandler , UNO_QUERY );
+ Reference < XErrorHandler > rErrorHandler( ( XErrorHandler * )pDocHandler , UNO_QUERY );
+
+ rParser->setDocumentHandler( rDocHandler );
+ rParser->setEntityResolver( rEntityResolver );
+ rParser->setErrorHandler( rErrorHandler );
+
+ try
+ {
+ TimeValue aStartTime, aEndTime;
+ osl_getSystemTime( &aStartTime );
+ rParser->parseStream( source );
+ osl_getSystemTime( &aEndTime );
+
+ double fStart = (double)aStartTime.Seconds + ((double)aStartTime.Nanosec / 1000000000.0);
+ double fEnd = (double)aEndTime.Seconds + ((double)aEndTime.Nanosec / 1000000000.0);
+
+ printf( "Performance reading : %g s\n" , fEnd - fStart );
+
+ }
+ catch( SAXParseException &e ) {
+ Any any;
+ any <<= e;
+ while(sal_True) {
+ if( any.getValueType() == getCppuType( &e ) ) {
+ SAXParseException ex;
+ any >>= ex;
+ OString o = OUStringToOString( ex.Message , RTL_TEXTENCODING_ASCII_US );
+ printf( "%s\n" , o.getStr() );
+ any <<= ex.WrappedException;
+ }
+ else {
+ break;
+ }
+ }
+ }
+ catch( SAXException &e ) {
+ OString o = OUStringToOString( e.Message , RTL_TEXTENCODING_ASCII_US );
+ printf( "%s\n" , o.getStr() );
+
+ }
+ catch( ... )
+ {
+ printf( "any exception !!!!\n" );
+ }
+ }
+}
+
+
+extern "C"
+{
+
+
+void SAL_CALL component_getImplementationEnvironment(
+ const sal_Char ** ppEnvTypeName, uno_Environment ** ppEnv )
+{
+ *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
+}
+
+
+sal_Bool SAL_CALL component_writeInfo(
+ void * pServiceManager, void * pRegistryKey )
+{
+ if (pRegistryKey)
+ {
+ try
+ {
+ Reference< XRegistryKey > xKey(
+ reinterpret_cast< XRegistryKey * >( pRegistryKey ) );
+
+ OUString str =
+ OUString( L"/" ) +
+ OSaxParserTest_getImplementationName() +
+ OUString( L"/UNO/SERVICES" );
+ Reference< XRegistryKey > xNewKey = xKey->createKey( str );
+ xNewKey->createKey( OSaxParserTest_getServiceName() );
+
+ str =
+ OUString( L"/" ) +
+ OSaxWriterTest_getImplementationName() +
+ OUString( L"/UNO/SERVICES" );
+
+ xNewKey = xKey->createKey( str );
+ xNewKey->createKey( OSaxWriterTest_getServiceName() );
+
+ return sal_True;
+ }
+ catch (InvalidRegistryException &)
+ {
+ OSL_ENSHURE( sal_False, "### InvalidRegistryException!" );
+ }
+ }
+
+ return sal_False;
+}
+
+void * SAL_CALL component_getFactory(
+ const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey )
+{
+ void * pRet = 0;
+
+ if (pServiceManager )
+ {
+ Reference< XSingleServiceFactory > xRet;
+ Reference< XMultiServiceFactory > xSMgr =
+ reinterpret_cast< XMultiServiceFactory * > ( pServiceManager );
+
+ OUString aImplementationName = OUString::createFromAscii( pImplName );
+
+
+ if (aImplementationName == OSaxWriterTest_getImplementationName() )
+ {
+ xRet = createSingleFactory( xSMgr, aImplementationName,
+ OSaxWriterTest_CreateInstance,
+ OSaxWriterTest_getSupportedServiceNames() );
+ }
+ else if (aImplementationName == OSaxParserTest_getImplementationName() )
+ {
+ xRet = createSingleFactory( xSMgr, aImplementationName,
+ OSaxParserTest_CreateInstance,
+ OSaxParserTest_getSupportedServiceNames() );
+ }
+ if (xRet.is())
+ {
+ xRet->acquire();
+ pRet = xRet.get();
+ }
+ }
+
+ return pRet;
+}
+
+}
+
+
diff --git a/sax/test/sax/testwriter.cxx b/sax/test/sax/testwriter.cxx
new file mode 100644
index 000000000000..5f06cf602abe
--- /dev/null
+++ b/sax/test/sax/testwriter.cxx
@@ -0,0 +1,714 @@
+/*************************************************************************
+ *
+ * $RCSfile: testwriter.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 16:43:13 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#include <vector>
+#include <stdio.h>
+#include <assert.h>
+
+#include <com/sun/star/test/XSimpleTest.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp> // for the multiservice-factories
+
+#include <com/sun/star/io/XActiveDataSource.hpp>
+#include <com/sun/star/io/XOutputStream.hpp>
+#include <com/sun/star/xml/sax/SAXParseException.hpp>
+#include <com/sun/star/xml/sax/XParser.hpp>
+#include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp>
+
+#include <osl/time.h>
+
+#include <cppuhelper/factory.hxx>
+#include <cppuhelper/implbase1.hxx>
+#include <cppuhelper/implbase3.hxx>
+
+
+using namespace ::std;
+using namespace ::rtl;
+using namespace ::cppu;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::test;
+using namespace ::com::sun::star::registry;
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::xml::sax;
+
+#include "factory.hxx"
+
+class OFileWriter :
+ public WeakImplHelper1< XOutputStream >
+{
+public:
+ OFileWriter( char *pcFile ) { strcpy( m_pcFile , pcFile ); m_f = 0; }
+
+
+public:
+ virtual void SAL_CALL writeBytes(const Sequence< sal_Int8 >& aData)
+ throw (NotConnectedException, BufferSizeExceededException, RuntimeException);
+ virtual void SAL_CALL flush(void)
+ throw (NotConnectedException, BufferSizeExceededException, RuntimeException);
+ virtual void SAL_CALL closeOutput(void)
+ throw (NotConnectedException, BufferSizeExceededException, RuntimeException);
+private:
+ char m_pcFile[256];
+ FILE *m_f;
+};
+
+
+void OFileWriter::writeBytes(const Sequence< sal_Int8 >& aData)
+ throw (NotConnectedException, BufferSizeExceededException, RuntimeException)
+{
+ if( ! m_f ) {
+ m_f = fopen( m_pcFile , "w" );
+ }
+
+ fwrite( aData.getConstArray() , 1 , aData.getLength() , m_f );
+
+}
+
+
+void OFileWriter::flush(void)
+ throw (NotConnectedException, BufferSizeExceededException, RuntimeException)
+{
+ fflush( m_f );
+}
+
+void OFileWriter::closeOutput(void)
+ throw (NotConnectedException, BufferSizeExceededException, RuntimeException)
+{
+ fclose( m_f );
+ m_f = 0;
+}
+
+
+class OSaxWriterTest :
+ public WeakImplHelper1< XSimpleTest >
+{
+public:
+ OSaxWriterTest( const Reference < XMultiServiceFactory > & rFactory ) : m_rFactory( rFactory )
+ {
+
+ }
+ ~OSaxWriterTest() {}
+
+
+public:
+ virtual void SAL_CALL testInvariant(
+ const OUString& TestName,
+ const Reference < XInterface >& TestObject)
+ throw ( IllegalArgumentException,
+ RuntimeException);
+
+ virtual sal_Int32 SAL_CALL test(
+ const OUString& TestName,
+ const Reference < XInterface >& TestObject,
+ sal_Int32 hTestHandle)
+ throw ( IllegalArgumentException,RuntimeException);
+
+ virtual sal_Bool SAL_CALL testPassed(void)
+ throw ( RuntimeException);
+ virtual Sequence< OUString > SAL_CALL getErrors(void) throw (RuntimeException);
+ virtual Sequence< Any > SAL_CALL getErrorExceptions(void) throw (RuntimeException);
+ virtual Sequence< OUString > SAL_CALL getWarnings(void) throw (RuntimeException);
+
+private:
+ void testSimple( const Reference< XExtendedDocumentHandler > &r );
+ void testExceptions( const Reference< XExtendedDocumentHandler > &r );
+ void testDTD( const Reference< XExtendedDocumentHandler > &r );
+ void testPerformance( const Reference< XExtendedDocumentHandler > &r );
+ void writeParagraph( const Reference< XExtendedDocumentHandler > &r , const OUString & s);
+
+private:
+ Sequence<Any> m_seqExceptions;
+ Sequence<OUString> m_seqErrors;
+ Sequence<OUString> m_seqWarnings;
+ Reference < XMultiServiceFactory > m_rFactory;
+
+};
+
+
+
+/*----------------------------------------
+*
+* Attributlist implementation
+*
+*----------------------------------------*/
+struct AttributeListImpl_impl;
+class AttributeListImpl : public WeakImplHelper1< XAttributeList >
+{
+public:
+ AttributeListImpl();
+ AttributeListImpl( const AttributeListImpl & );
+ ~AttributeListImpl();
+
+public:
+ virtual sal_Int16 SAL_CALL getLength(void) throw (RuntimeException);
+ virtual OUString SAL_CALL getNameByIndex(sal_Int16 i) throw (RuntimeException);
+ virtual OUString SAL_CALL getTypeByIndex(sal_Int16 i) throw (RuntimeException);
+ virtual OUString SAL_CALL getTypeByName(const OUString& aName) throw (RuntimeException);
+ virtual OUString SAL_CALL getValueByIndex(sal_Int16 i) throw (RuntimeException);
+ virtual OUString SAL_CALL getValueByName(const OUString& aName) throw (RuntimeException);
+
+public:
+ void addAttribute( const OUString &sName ,
+ const OUString &sType ,
+ const OUString &sValue );
+ void clear();
+
+private:
+ struct AttributeListImpl_impl *m_pImpl;
+};
+
+
+struct TagAttribute
+{
+ TagAttribute(){}
+ TagAttribute( const OUString &sName,
+ const OUString &sType ,
+ const OUString &sValue )
+ {
+ this->sName = sName;
+ this->sType = sType;
+ this->sValue = sValue;
+ }
+
+ OUString sName;
+ OUString sType;
+ OUString sValue;
+};
+
+struct AttributeListImpl_impl
+{
+ AttributeListImpl_impl()
+ {
+ // performance improvement during adding
+ vecAttribute.reserve(20);
+ }
+ vector<struct TagAttribute> vecAttribute;
+};
+
+
+
+sal_Int16 AttributeListImpl::getLength(void) throw (RuntimeException)
+{
+ return m_pImpl->vecAttribute.size();
+}
+
+
+AttributeListImpl::AttributeListImpl( const AttributeListImpl &r )
+{
+ m_pImpl = new AttributeListImpl_impl;
+ *m_pImpl = *(r.m_pImpl);
+}
+
+OUString AttributeListImpl::getNameByIndex(sal_Int16 i) throw (RuntimeException)
+{
+ if( i < m_pImpl->vecAttribute.size() ) {
+ return m_pImpl->vecAttribute[i].sName;
+ }
+ return OUString();
+}
+
+
+OUString AttributeListImpl::getTypeByIndex(sal_Int16 i) throw (RuntimeException)
+{
+ if( i < m_pImpl->vecAttribute.size() ) {
+ return m_pImpl->vecAttribute[i].sType;
+ }
+ return OUString();
+}
+
+OUString AttributeListImpl::getValueByIndex(sal_Int16 i) throw (RuntimeException)
+{
+ if( i < m_pImpl->vecAttribute.size() ) {
+ return m_pImpl->vecAttribute[i].sValue;
+ }
+ return OUString();
+
+}
+
+OUString AttributeListImpl::getTypeByName( const OUString& sName ) throw (RuntimeException)
+{
+ vector<struct TagAttribute>::iterator ii = m_pImpl->vecAttribute.begin();
+
+ for( ; ii != m_pImpl->vecAttribute.end() ; ii ++ ) {
+ if( (*ii).sName == sName ) {
+ return (*ii).sType;
+ }
+ }
+ return OUString();
+}
+
+OUString AttributeListImpl::getValueByName(const OUString& sName) throw (RuntimeException)
+{
+ vector<struct TagAttribute>::iterator ii = m_pImpl->vecAttribute.begin();
+
+ for( ; ii != m_pImpl->vecAttribute.end() ; ii ++ ) {
+ if( (*ii).sName == sName ) {
+ return (*ii).sValue;
+ }
+ }
+ return OUString();
+}
+
+
+
+AttributeListImpl::AttributeListImpl()
+{
+ m_pImpl = new AttributeListImpl_impl;
+}
+
+
+
+AttributeListImpl::~AttributeListImpl()
+{
+ delete m_pImpl;
+}
+
+
+void AttributeListImpl::addAttribute( const OUString &sName ,
+ const OUString &sType ,
+ const OUString &sValue )
+{
+ m_pImpl->vecAttribute.push_back( TagAttribute( sName , sType , sValue ) );
+}
+
+void AttributeListImpl::clear()
+{
+ m_pImpl->vecAttribute.clear();
+
+}
+
+
+
+
+
+
+
+
+
+
+
+/**
+* for external binding
+*
+*
+**/
+Reference < XInterface > SAL_CALL OSaxWriterTest_CreateInstance( const Reference < XMultiServiceFactory > & rSMgr ) throw (Exception)
+{
+ OSaxWriterTest *p = new OSaxWriterTest( rSMgr );
+ Reference < XInterface > xService = *p;
+ return xService;
+}
+
+OUString OSaxWriterTest_getServiceName( ) throw ()
+{
+ return OUString( RTL_CONSTASCII_USTRINGPARAM("test.com.sun.star.xml.sax.Writer"));
+}
+
+OUString OSaxWriterTest_getImplementationName( ) throw ()
+{
+ return OUString( RTL_CONSTASCII_USTRINGPARAM("test.extensions.xml.sax.Writer"));
+}
+
+Sequence<OUString> OSaxWriterTest_getSupportedServiceNames( ) throw ()
+{
+ Sequence<OUString> aRet(1);
+
+ aRet.getArray()[0] = OSaxWriterTest_getImplementationName( );
+
+ return aRet;
+}
+
+
+
+void OSaxWriterTest::testInvariant( const OUString& TestName,
+ const Reference < XInterface >& TestObject )
+ throw ( IllegalArgumentException, RuntimeException)
+{
+ if( L"com.sun.star.xml.sax.Writer" == TestName ) {
+ Reference< XDocumentHandler > doc( TestObject , UNO_QUERY );
+ Reference< XExtendedDocumentHandler > ext( TestObject , UNO_QUERY );
+ Reference< XActiveDataSource > source( TestObject , UNO_QUERY );
+
+ ERROR_ASSERT( doc.is() , "XDocumentHandler cannot be queried" );
+ ERROR_ASSERT( ext.is() , "XExtendedDocumentHandler cannot be queried" );
+ ERROR_ASSERT( source.is() , "XActiveDataSource cannot be queried" );
+ }
+ else {
+ BUILD_ERROR( 0 , "wrong test" );
+ }
+}
+
+
+sal_Int32 OSaxWriterTest::test(
+ const OUString& TestName,
+ const Reference < XInterface >& TestObject,
+ sal_Int32 hTestHandle)
+ throw ( IllegalArgumentException,RuntimeException)
+{
+ if( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.sax.Writer")) == TestName )
+ {
+ try
+ {
+ if( 0 == hTestHandle )
+ {
+ testInvariant( TestName , TestObject );
+ }
+ else
+ {
+ Reference< XExtendedDocumentHandler > writer( TestObject , UNO_QUERY );
+
+ if( 1 == hTestHandle ) {
+ testSimple( writer );
+ }
+ else if( 2 == hTestHandle ) {
+ testExceptions( writer );
+ }
+ else if( 3 == hTestHandle ) {
+ testDTD( writer );
+ }
+ else if( 4 == hTestHandle ) {
+ testPerformance( writer );
+ }
+ }
+ }
+ catch( Exception & e ) {
+ OString o = OUStringToOString( e.Message , RTL_TEXTENCODING_ASCII_US );
+ BUILD_ERROR( 0 , o.getStr() );
+ }
+ catch( ... )
+ {
+ BUILD_ERROR( 0 , "unknown exception (Exception is not base class)" );
+ }
+
+ hTestHandle ++;
+
+ if( hTestHandle >= 5) {
+ // all tests finished.
+ hTestHandle = -1;
+ }
+ }
+ else {
+ BUILD_ERROR( 0 , "service not supported by test." );
+ }
+ return hTestHandle;
+}
+
+
+
+sal_Bool OSaxWriterTest::testPassed(void) throw (RuntimeException)
+{
+ return m_seqErrors.getLength() == 0;
+}
+
+
+Sequence< OUString > OSaxWriterTest::getErrors(void) throw (RuntimeException)
+{
+ return m_seqErrors;
+}
+
+
+Sequence< Any > OSaxWriterTest::getErrorExceptions(void) throw (RuntimeException)
+{
+ return m_seqExceptions;
+}
+
+
+Sequence< OUString > OSaxWriterTest::getWarnings(void) throw (RuntimeException)
+{
+ return m_seqWarnings;
+}
+
+void OSaxWriterTest::writeParagraph(
+ const Reference< XExtendedDocumentHandler > &r ,
+ const OUString & s)
+{
+ int nMax = s.len();
+ int nStart = 0;
+
+ Sequence<sal_uInt16> seq( s.len() );
+ memcpy( seq.getArray() , s.getStr() , s.len() * sizeof( sal_uInt16 ) );
+
+ for( int n = 1 ; n < nMax ; n++ ){
+ if( 32 == seq.getArray()[n] ) {
+ r->allowLineBreak();
+ r->characters( s.copy( nStart , n - nStart ) );
+ nStart = n;
+ }
+ }
+ r->allowLineBreak();
+ r->characters( s.copy( nStart , n - nStart ) );
+}
+
+
+
+void OSaxWriterTest::testSimple( const Reference< XExtendedDocumentHandler > &r )
+{
+ OUString testParagraph = OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "Dies ist ein bloeder Test um zu uberpruefen, ob der SAXWriter "
+ "wohl Zeilenumbrueche halbwegs richtig macht oder ob er die Zeile "
+ "bis zum bitteren Ende schreibt." ));
+
+ OFileWriter *pw = new OFileWriter("output.xml");
+ AttributeListImpl *pList = new AttributeListImpl;
+
+ Reference< XAttributeList > rList( (XAttributeList *) pList , UNO_QUERY );
+ Reference< XOutputStream > ref( ( XOutputStream * ) pw , UNO_QUERY );
+
+ Reference< XActiveDataSource > source( r , UNO_QUERY );
+
+ ERROR_ASSERT( ref.is() , "no output stream" );
+ ERROR_ASSERT( source.is() , "no active data source" );
+
+ source->setOutputStream( ref );
+
+ r->startDocument();
+
+ pList->addAttribute( OUString( RTL_CONSTASCII_USTRINGPARAM("Arg1" )),
+ OUString( RTL_CONSTASCII_USTRINGPARAM("CDATA")) ,
+ OUString( RTL_CONSTASCII_USTRINGPARAM("bla\n u")) );
+ pList->addAttribute( OUString( RTL_CONSTASCII_USTRINGPARAM("Arg2")) ,
+ OUString( RTL_CONSTASCII_USTRINGPARAM("CDATA")) ,
+ OUString( RTL_CONSTASCII_USTRINGPARAM("blub")) );
+
+ r->startElement( OUString( RTL_CONSTASCII_USTRINGPARAM("tag1")) , rList );
+ r->ignorableWhitespace( OUString() );
+
+ r->characters( OUString( RTL_CONSTASCII_USTRINGPARAM("huhu")) );
+ r->ignorableWhitespace( OUString() );
+
+ r->startElement( OUString( RTL_CONSTASCII_USTRINGPARAM("hi")) , rList );
+ r->ignorableWhitespace( OUString() );
+
+ // the enpassant must be converted & -> &amp;
+ r->characters( OUString( RTL_CONSTASCII_USTRINGPARAM("&#252;")) );
+
+ // Test added for mib. Tests if errors during conversions occurs
+ r->ignorableWhitespace( OUString() );
+ sal_Char array[256];
+ for( sal_Int32 n = 32 ; n < 254 ; n ++ ) {
+ array[n-32] = n;
+ }
+ array[254-32] = 0;
+ r->characters(
+ OStringToOUString( array , RTL_TEXTENCODING_SYMBOL )
+ );
+ r->ignorableWhitespace( OUString() );
+
+ // '>' must not be converted
+ r->startCDATA();
+ r->characters( OUString( RTL_CONSTASCII_USTRINGPARAM(">fsfsdf<")) );
+ r->endCDATA();
+ r->ignorableWhitespace( OUString() );
+
+ writeParagraph( r , testParagraph );
+
+
+ r->ignorableWhitespace( OUString() );
+ r->comment( OUString( RTL_CONSTASCII_USTRINGPARAM("Dies ist ein Kommentar !")) );
+ r->ignorableWhitespace( OUString() );
+
+ r->startElement( OUString( RTL_CONSTASCII_USTRINGPARAM("emptytagtest")) , rList );
+ r->endElement( OUString( RTL_CONSTASCII_USTRINGPARAM("emptytagtest")) );
+
+ r->endElement( OUString( RTL_CONSTASCII_USTRINGPARAM("hi")) );
+ r->ignorableWhitespace( OUString() );
+
+ r->endElement( OUString( RTL_CONSTASCII_USTRINGPARAM("tag1")) );
+ r->endDocument();
+
+}
+
+void OSaxWriterTest::testExceptions( const Reference< XExtendedDocumentHandler > & r )
+{
+
+ OFileWriter *pw = new OFileWriter("output2.xml");
+ AttributeListImpl *pList = new AttributeListImpl;
+
+ Reference< XAttributeList > rList( (XAttributeList *) pList , UNO_QUERY );
+ Reference< XOutputStream > ref( ( XOutputStream * ) pw , UNO_QUERY );
+
+ Reference< XActiveDataSource > source( r , UNO_QUERY );
+
+ ERROR_ASSERT( ref.is() , "no output stream" );
+ ERROR_ASSERT( source.is() , "no active data source" );
+
+ source->setOutputStream( ref );
+
+ { // startDocument must be called before start element
+ sal_Bool bException = sal_True;
+ try
+ {
+ r->startElement( L"huhu" , rList );
+ bException = sal_False;
+ }
+ catch( SAXException &e )
+ {
+
+ }
+ ERROR_ASSERT( bException , "expected exception not thrown !" );
+ }
+
+ r->startDocument();
+
+ r->startElement( OUString( RTL_CONSTASCII_USTRINGPARAM("huhu")) , rList );
+ r->startCDATA();
+
+ {
+ sal_Bool bException = sal_True;
+ try{
+ r->startElement( OUString( RTL_CONSTASCII_USTRINGPARAM("huhu")) , rList );
+ bException = sal_False;
+ }
+ catch( SAXException &e ) {
+
+ }
+ ERROR_ASSERT( bException , "expected exception not thrown !" );
+ }
+
+ r->endCDATA();
+ r->endElement( OUString( RTL_CONSTASCII_USTRINGPARAM("hi")) );
+
+ r->endDocument();
+}
+
+
+void OSaxWriterTest::testDTD(const Reference< XExtendedDocumentHandler > &r )
+{
+ OFileWriter *pw = new OFileWriter("outputDTD.xml");
+ AttributeListImpl *pList = new AttributeListImpl;
+
+ Reference< XAttributeList > rList( (XAttributeList *) pList , UNO_QUERY );
+ Reference< XOutputStream > ref( ( XOutputStream * ) pw , UNO_QUERY );
+
+ Reference< XActiveDataSource > source( r , UNO_QUERY );
+
+ ERROR_ASSERT( ref.is() , "no output stream" );
+ ERROR_ASSERT( source.is() , "no active data source" );
+
+ source->setOutputStream( ref );
+
+
+ r->startDocument();
+ r->unknown( OUString( RTL_CONSTASCII_USTRINGPARAM("<!DOCTYPE iCalendar >\n")) );
+ r->startElement( OUString( RTL_CONSTASCII_USTRINGPARAM("huhu")) , rList );
+
+ r->endElement( OUString( RTL_CONSTASCII_USTRINGPARAM("huhu")) );
+ r->endDocument();
+}
+
+void OSaxWriterTest::testPerformance(const Reference< XExtendedDocumentHandler > &r )
+{
+ OFileWriter *pw = new OFileWriter("testPerformance.xml");
+ AttributeListImpl *pList = new AttributeListImpl;
+
+ OUString testParagraph =
+ OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "Dies ist ein bloeder Test um zu uberpruefen, ob der SAXWriter "
+ "wohl Zeilenumbrueche halbwegs richtig macht oder ob er die Zeile "
+ "bis zum bitteren Ende schreibt." ));
+
+
+ Reference< XAttributeList > rList( (XAttributeList *) pList , UNO_QUERY );
+ Reference< XOutputStream > ref( ( XOutputStream * ) pw , UNO_QUERY );
+
+ Reference< XActiveDataSource > source( r , UNO_QUERY );
+
+ ERROR_ASSERT( ref.is() , "no output stream" );
+ ERROR_ASSERT( source.is() , "no active data source" );
+
+ source->setOutputStream( ref );
+
+ TimeValue aStartTime, aEndTime;
+ osl_getSystemTime( &aStartTime );
+
+
+ r->startDocument();
+ // just write a bunch of xml tags !
+ // for performance testing
+ sal_Int32 i2;
+ for( i2 = 0 ; i2 < 15 ; i2 ++ )
+ {
+ r->startElement( OUString( RTL_CONSTASCII_USTRINGPARAM("tag") ) +
+ OUString::valueOf( i2 ), rList );
+ for( sal_Int32 i = 0 ; i < 450 ; i ++ )
+ {
+ r->ignorableWhitespace( OUString());
+ r->startElement( OUString( RTL_CONSTASCII_USTRINGPARAM("huhu")) , rList );
+ r->characters( testParagraph );
+
+ r->ignorableWhitespace( OUString() );
+ r->endElement( OUString( RTL_CONSTASCII_USTRINGPARAM("huhu")) );
+ }
+ }
+ for( i2 = 14 ; i2 >= 0 ; i2-- )
+ {
+ r->ignorableWhitespace( OUString() );
+ r->endElement( OUString( RTL_CONSTASCII_USTRINGPARAM("tag") ) + OUString::valueOf( i2 ) );
+ }
+
+ r->endDocument();
+
+ osl_getSystemTime( &aEndTime );
+
+ double fStart = (double)aStartTime.Seconds + ((double)aStartTime.Nanosec / 1000000000.0);
+ double fEnd = (double)aEndTime.Seconds + ((double)aEndTime.Nanosec / 1000000000.0);
+
+ printf( "Performance writing : %g s\n" , fEnd - fStart );
+}
diff --git a/sax/test/saxdemo.cxx b/sax/test/saxdemo.cxx
new file mode 100644
index 000000000000..f4c57425864c
--- /dev/null
+++ b/sax/test/saxdemo.cxx
@@ -0,0 +1,693 @@
+/*************************************************************************
+ *
+ * $RCSfile: saxdemo.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 16:43:13 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+//------------------------------------------------------
+// testcomponent - Loads a service and its testcomponent from dlls performs a test.
+// Expands the dll-names depending on the actual environment.
+// Example : testcomponent stardiv.uno.io.Pipe stm
+//
+// Therefor the testcode must exist in teststm and the testservice must be named test.stardiv.uno.io.Pipe
+//
+
+#include <stdio.h>
+#include <vector>
+
+#include <com/sun/star/registry/XImplementationRegistration.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+
+#include <com/sun/star/xml/sax/SAXParseException.hpp>
+#include <com/sun/star/xml/sax/XParser.hpp>
+#include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp>
+
+#include <com/sun/star/io/XOutputStream.hpp>
+#include <com/sun/star/io/XActiveDataSource.hpp>
+
+#include <cppuhelper/servicefactory.hxx>
+#include <cppuhelper/implbase1.hxx>
+#include <cppuhelper/implbase3.hxx>
+
+#include <vos/dynload.hxx>
+#include <vos/diagnose.hxx>
+
+#include <assert.h>
+
+
+using namespace ::rtl;
+using namespace ::std;
+using namespace ::cppu;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::registry;
+using namespace ::com::sun::star::xml::sax;
+using namespace ::com::sun::star::io;
+
+
+/************
+ * Sequence of bytes -> InputStream
+ ************/
+class OInputStream : public WeakImplHelper1 < XInputStream >
+{
+public:
+ OInputStream( const Sequence< sal_Int8 >&seq ) :
+ m_seq( seq ),
+ nPos( 0 )
+ {}
+
+public:
+ virtual sal_Int32 SAL_CALL readBytes( Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead )
+ throw(NotConnectedException, BufferSizeExceededException, IOException, RuntimeException)
+ {
+ nBytesToRead = (nBytesToRead > m_seq.getLength() - nPos ) ?
+ m_seq.getLength() - nPos :
+ nBytesToRead;
+ aData = Sequence< sal_Int8 > ( &(m_seq.getConstArray()[nPos]) , nBytesToRead );
+ nPos += nBytesToRead;
+ return nBytesToRead;
+ }
+ virtual sal_Int32 SAL_CALL readSomeBytes(
+ ::com::sun::star::uno::Sequence< sal_Int8 >& aData,
+ sal_Int32 nMaxBytesToRead )
+ throw(NotConnectedException, BufferSizeExceededException, IOException, RuntimeException)
+ {
+ return readBytes( aData, nMaxBytesToRead );
+ }
+ virtual void SAL_CALL skipBytes( sal_Int32 nBytesToSkip )
+ throw(NotConnectedException, BufferSizeExceededException, IOException, RuntimeException)
+ {
+ // not implemented
+ }
+ virtual sal_Int32 SAL_CALL available( )
+ throw(NotConnectedException, IOException, RuntimeException)
+ {
+ return m_seq.getLength() - nPos;
+ }
+ virtual void SAL_CALL closeInput( )
+ throw(NotConnectedException, IOException, RuntimeException)
+ {
+ // not needed
+ }
+ sal_Int32 nPos;
+ Sequence< sal_Int8> m_seq;
+};
+
+//-------------------------------
+// Helper : create an input stream from a file
+//------------------------------
+Reference< XInputStream > createStreamFromFile(
+ const char *pcFile )
+{
+ FILE *f = fopen( pcFile , "rb" );
+ Reference< XInputStream > r;
+
+ if( f ) {
+ fseek( f , 0 , SEEK_END );
+ int nLength = ftell( f );
+ fseek( f , 0 , SEEK_SET );
+
+ Sequence<sal_Int8> seqIn(nLength);
+ fread( seqIn.getArray() , nLength , 1 , f );
+
+ r = Reference< XInputStream > ( new OInputStream( seqIn ) );
+ fclose( f );
+ }
+ return r;
+}
+
+//-----------------------------------------
+// The document handler, which is needed for the saxparser
+// The Documenthandler for reading sax
+//-----------------------------------------
+class TestDocumentHandler :
+ public WeakImplHelper3< XExtendedDocumentHandler , XEntityResolver , XErrorHandler >
+{
+public:
+ TestDocumentHandler( )
+ {
+ }
+
+public: // Error handler
+ virtual void SAL_CALL error(const Any& aSAXParseException) throw (SAXException, RuntimeException)
+ {
+ printf( "Error !\n" );
+ throw SAXException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("error from error handler")) ,
+ Reference < XInterface >() ,
+ aSAXParseException );
+ }
+ virtual void SAL_CALL fatalError(const Any& aSAXParseException) throw (SAXException, RuntimeException)
+ {
+ printf( "Fatal Error !\n" );
+ }
+ virtual void SAL_CALL warning(const Any& aSAXParseException) throw (SAXException, RuntimeException)
+ {
+ printf( "Warning !\n" );
+ }
+
+
+public: // ExtendedDocumentHandler
+
+ virtual void SAL_CALL startDocument(void) throw (SAXException, RuntimeException)
+ {
+ m_iElementCount = 0;
+ m_iAttributeCount = 0;
+ m_iWhitespaceCount =0;
+ m_iCharCount=0;
+ printf( "document started\n" );
+ }
+ virtual void SAL_CALL endDocument(void) throw (SAXException, RuntimeException)
+ {
+ printf( "document finished\n" );
+ printf( "(ElementCount %d),(AttributeCount %d),(WhitespaceCount %d),(CharCount %d)\n",
+ m_iElementCount, m_iAttributeCount, m_iWhitespaceCount , m_iCharCount );
+
+ }
+ virtual void SAL_CALL startElement(const OUString& aName,
+ const Reference< XAttributeList > & xAttribs)
+ throw (SAXException,RuntimeException)
+ {
+ m_iElementCount ++;
+ m_iAttributeCount += xAttribs->getLength();
+ }
+
+ virtual void SAL_CALL endElement(const OUString& aName) throw (SAXException,RuntimeException)
+ {
+ // ignored
+ }
+
+ virtual void SAL_CALL characters(const OUString& aChars) throw (SAXException,RuntimeException)
+ {
+ m_iCharCount += aChars.len();
+ }
+ virtual void SAL_CALL ignorableWhitespace(const OUString& aWhitespaces) throw (SAXException,RuntimeException)
+ {
+ m_iWhitespaceCount += aWhitespaces.len();
+ }
+
+ virtual void SAL_CALL processingInstruction(const OUString& aTarget, const OUString& aData) throw (SAXException,RuntimeException)
+ {
+ // ignored
+ }
+
+ virtual void SAL_CALL setDocumentLocator(const Reference< XLocator> & xLocator)
+ throw (SAXException,RuntimeException)
+ {
+ // ignored
+ }
+
+ virtual InputSource SAL_CALL resolveEntity(
+ const OUString& sPublicId,
+ const OUString& sSystemId)
+ throw (SAXException,RuntimeException)
+ {
+ InputSource source;
+ source.sSystemId = sSystemId;
+ source.sPublicId = sPublicId;
+
+ source.aInputStream = createStreamFromFile(
+ OUStringToOString( sSystemId , RTL_TEXTENCODING_ASCII_US) );
+
+ return source;
+ }
+
+ virtual void SAL_CALL startCDATA(void) throw (SAXException,RuntimeException)
+ {
+ }
+ virtual void SAL_CALL endCDATA(void) throw (SAXException,RuntimeException)
+ {
+ }
+ virtual void SAL_CALL comment(const OUString& sComment) throw (SAXException,RuntimeException)
+ {
+ }
+ virtual void SAL_CALL unknown(const OUString& sString) throw (SAXException,RuntimeException)
+ {
+ }
+
+ virtual void SAL_CALL allowLineBreak( void) throw (SAXException, RuntimeException )
+ {
+
+ }
+
+public:
+ int m_iElementCount;
+ int m_iAttributeCount;
+ int m_iWhitespaceCount;
+ int m_iCharCount;
+};
+
+//--------------------------------------
+// helper implementation for writing
+// implements an XAttributeList
+//-------------------------------------
+struct AttributeListImpl_impl;
+class AttributeListImpl : public WeakImplHelper1< XAttributeList >
+{
+public:
+ AttributeListImpl();
+ AttributeListImpl( const AttributeListImpl & );
+ ~AttributeListImpl();
+
+public:
+ virtual sal_Int16 SAL_CALL getLength(void) throw (RuntimeException);
+ virtual OUString SAL_CALL getNameByIndex(sal_Int16 i) throw (RuntimeException);
+ virtual OUString SAL_CALL getTypeByIndex(sal_Int16 i) throw (RuntimeException);
+ virtual OUString SAL_CALL getTypeByName(const OUString& aName) throw (RuntimeException);
+ virtual OUString SAL_CALL getValueByIndex(sal_Int16 i) throw (RuntimeException);
+ virtual OUString SAL_CALL getValueByName(const OUString& aName) throw (RuntimeException);
+
+public:
+ void addAttribute( const OUString &sName ,
+ const OUString &sType ,
+ const OUString &sValue );
+ void clear();
+
+private:
+ struct AttributeListImpl_impl *m_pImpl;
+};
+
+
+struct TagAttribute
+{
+ TagAttribute(){}
+ TagAttribute( const OUString &sName,
+ const OUString &sType ,
+ const OUString &sValue )
+ {
+ this->sName = sName;
+ this->sType = sType;
+ this->sValue = sValue;
+ }
+
+ OUString sName;
+ OUString sType;
+ OUString sValue;
+};
+
+struct AttributeListImpl_impl
+{
+ AttributeListImpl_impl()
+ {
+ // performance improvement during adding
+ vecAttribute.reserve(20);
+ }
+ vector<struct TagAttribute> vecAttribute;
+};
+
+
+
+sal_Int16 AttributeListImpl::getLength(void) throw (RuntimeException)
+{
+ return m_pImpl->vecAttribute.size();
+}
+
+
+AttributeListImpl::AttributeListImpl( const AttributeListImpl &r )
+{
+ m_pImpl = new AttributeListImpl_impl;
+ *m_pImpl = *(r.m_pImpl);
+}
+
+OUString AttributeListImpl::getNameByIndex(sal_Int16 i) throw (RuntimeException)
+{
+ if( i < m_pImpl->vecAttribute.size() ) {
+ return m_pImpl->vecAttribute[i].sName;
+ }
+ return OUString();
+}
+
+
+OUString AttributeListImpl::getTypeByIndex(sal_Int16 i) throw (RuntimeException)
+{
+ if( i < m_pImpl->vecAttribute.size() ) {
+ return m_pImpl->vecAttribute[i].sType;
+ }
+ return OUString();
+}
+
+OUString AttributeListImpl::getValueByIndex(sal_Int16 i) throw (RuntimeException)
+{
+ if( i < m_pImpl->vecAttribute.size() ) {
+ return m_pImpl->vecAttribute[i].sValue;
+ }
+ return OUString();
+
+}
+
+OUString AttributeListImpl::getTypeByName( const OUString& sName ) throw (RuntimeException)
+{
+ vector<struct TagAttribute>::iterator ii = m_pImpl->vecAttribute.begin();
+
+ for( ; ii != m_pImpl->vecAttribute.end() ; ii ++ ) {
+ if( (*ii).sName == sName ) {
+ return (*ii).sType;
+ }
+ }
+ return OUString();
+}
+
+OUString AttributeListImpl::getValueByName(const OUString& sName) throw (RuntimeException)
+{
+ vector<struct TagAttribute>::iterator ii = m_pImpl->vecAttribute.begin();
+
+ for( ; ii != m_pImpl->vecAttribute.end() ; ii ++ ) {
+ if( (*ii).sName == sName ) {
+ return (*ii).sValue;
+ }
+ }
+ return OUString();
+}
+
+
+
+AttributeListImpl::AttributeListImpl()
+{
+ m_pImpl = new AttributeListImpl_impl;
+}
+
+
+
+AttributeListImpl::~AttributeListImpl()
+{
+ delete m_pImpl;
+}
+
+
+void AttributeListImpl::addAttribute( const OUString &sName ,
+ const OUString &sType ,
+ const OUString &sValue )
+{
+ m_pImpl->vecAttribute.push_back( TagAttribute( sName , sType , sValue ) );
+}
+
+void AttributeListImpl::clear()
+{
+ m_pImpl->vecAttribute.clear();
+}
+
+
+//--------------------------------------
+// helper function for writing
+// ensures that linebreaks are inserted
+// when writing a long text.
+// Note: this implementation may be a bit slow,
+// but it shows, how the SAX-Writer handles the allowLineBreak calls.
+//--------------------------------------
+void writeParagraphHelper(
+ const Reference< XExtendedDocumentHandler > &r ,
+ const OUString & s)
+{
+ int nMax = s.len();
+ int nStart = 0;
+
+ Sequence<sal_uInt16> seq( s.len() );
+ memcpy( seq.getArray() , s.getStr() , s.len() * sizeof( sal_uInt16 ) );
+
+ for( int n = 1 ; n < nMax ; n++ ){
+ if( 32 == seq.getArray()[n] ) {
+ r->allowLineBreak();
+ r->characters( s.copy( nStart , n - nStart ) );
+ nStart = n;
+ }
+ }
+ r->allowLineBreak();
+ r->characters( s.copy( nStart , n - nStart ) );
+}
+
+
+//---------------------------------
+// helper implementation for SAX-Writer
+// writes data to a file
+//--------------------------------
+class OFileWriter :
+ public WeakImplHelper1< XOutputStream >
+{
+public:
+ OFileWriter( char *pcFile ) { strcpy( m_pcFile , pcFile ); m_f = 0; }
+
+
+public:
+ virtual void SAL_CALL writeBytes(const Sequence< sal_Int8 >& aData)
+ throw (NotConnectedException, BufferSizeExceededException, RuntimeException);
+ virtual void SAL_CALL flush(void)
+ throw (NotConnectedException, BufferSizeExceededException, RuntimeException);
+ virtual void SAL_CALL closeOutput(void)
+ throw (NotConnectedException, BufferSizeExceededException, RuntimeException);
+private:
+ char m_pcFile[256];
+ FILE *m_f;
+};
+
+
+void OFileWriter::writeBytes(const Sequence< sal_Int8 >& aData)
+ throw (NotConnectedException, BufferSizeExceededException, RuntimeException)
+{
+ if( ! m_f ) {
+ m_f = fopen( m_pcFile , "w" );
+ }
+
+ fwrite( aData.getConstArray() , 1 , aData.getLength() , m_f );
+}
+
+
+void OFileWriter::flush(void)
+ throw (NotConnectedException, BufferSizeExceededException, RuntimeException)
+{
+ fflush( m_f );
+}
+
+void OFileWriter::closeOutput(void)
+ throw (NotConnectedException, BufferSizeExceededException, RuntimeException)
+{
+ fclose( m_f );
+ m_f = 0;
+}
+
+
+
+// Needed to switch on solaris threads
+#ifdef SOLARIS
+extern "C" void ChangeGlobalInit();
+#endif
+int main (int argc, char **argv)
+{
+
+ if( argc < 3) {
+ printf( "usage : saxdemo inputfile outputfile\n" );
+ exit( 0 );
+ }
+#ifdef SOLARIS
+ // switch on threads in solaris
+ ChangeGlobalInit();
+#endif
+
+ // create service manager
+ Reference< XMultiServiceFactory > xSMgr = createRegistryServiceFactory(
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "applicat.rdb" )) );
+
+ Reference < XImplementationRegistration > xReg;
+ try
+ {
+ // Create registration service
+ Reference < XInterface > x = xSMgr->createInstance(
+ OUString::createFromAscii( "com.sun.star.registry.ImplementationRegistration" ) );
+ xReg = Reference< XImplementationRegistration > ( x , UNO_QUERY );
+ }
+ catch( Exception & ) {
+ printf( "Couldn't create ImplementationRegistration service\n" );
+ exit(1);
+ }
+
+ OString sTestName;
+ try
+ {
+ // Load dll for the tested component
+#ifdef SAL_W32
+ OUString aDllName = OStringToOUString( "sax" , RTL_TEXTENCODING_ASCII_US );
+#else
+ OUString aDllName = OUString::createFromAscii( "lib" );
+ aDllName += OStringToOUString( argv[n] , RTL_TEXTENCODING_ASCII_US );
+ aDllName += OUString::createFromAscii( ".so" );
+#endif
+ xReg->registerImplementation(
+ OUString::createFromAscii( "com.sun.star.loader.SharedLibrary" ),
+ aDllName,
+ Reference< XSimpleRegistry > () );
+ }
+ catch( Exception &e ) {
+ printf( "Couldn't reach sax dll\n" );
+ printf( "%s\n" , OUStringToOString( e.Message , RTL_TEXTENCODING_ASCII_US ).getStr() );
+
+ exit(1);
+ }
+
+
+ //--------------------------------
+ // parser demo
+ // read xml from a file and count elements
+ //--------------------------------
+ Reference< XInterface > x = xSMgr->createInstance(
+ OUString::createFromAscii( "com.sun.star.xml.sax.Parser" ) );
+ if( x.is() )
+ {
+ Reference< XParser > rParser( x , UNO_QUERY );
+
+ // create and connect the document handler to the parser
+ TestDocumentHandler *pDocHandler = new TestDocumentHandler( );
+
+ Reference < XDocumentHandler > rDocHandler( (XDocumentHandler *) pDocHandler );
+ Reference< XEntityResolver > rEntityResolver( (XEntityResolver *) pDocHandler );
+
+ rParser->setDocumentHandler( rDocHandler );
+ rParser->setEntityResolver( rEntityResolver );
+
+ // create the input stream
+ InputSource source;
+ source.aInputStream = createStreamFromFile( argv[1] );
+ source.sSystemId = OUString::createFromAscii( argv[1] );
+
+ try
+ {
+ // start parsing
+ rParser->parseStream( source );
+ }
+
+ catch( Exception & e )
+ {
+ OString o1 = OUStringToOString(e.Message, RTL_TEXTENCODING_UTF8 );
+ printf( "Exception during parsing : %s\n" , o1.getStr() );
+ }
+ }
+ else
+ {
+ printf( "couln't create sax-parser component\n" );
+ }
+
+
+ //----------------------
+ // The SAX-Writer demo
+ //----------------------
+ x= xSMgr->createInstance( OUString::createFromAscii( "com.sun.star.xml.sax.Writer" ) );
+ if( x.is() )
+ {
+ printf( "start writing to %s\n" , argv[2] );
+
+ OFileWriter *pw = new OFileWriter( argv[2] );
+ Reference< XActiveDataSource > source( x , UNO_QUERY );
+ source->setOutputStream( Reference< XOutputStream> ( (XOutputStream*) pw ) );
+
+ AttributeListImpl *pList = new AttributeListImpl;
+ Reference< XAttributeList > rList( (XAttributeList *) pList );
+
+ Reference< XExtendedDocumentHandler > r( x , UNO_QUERY );
+ r->startDocument();
+
+ pList->addAttribute( OUString( RTL_CONSTASCII_USTRINGPARAM("Arg1" )),
+ OUString( RTL_CONSTASCII_USTRINGPARAM("CDATA")) ,
+ OUString( RTL_CONSTASCII_USTRINGPARAM("foo\n u")) );
+ pList->addAttribute( OUString( RTL_CONSTASCII_USTRINGPARAM("Arg2")) ,
+ OUString( RTL_CONSTASCII_USTRINGPARAM("CDATA")) ,
+ OUString( RTL_CONSTASCII_USTRINGPARAM("foo2")) );
+
+ r->startElement( OUString( RTL_CONSTASCII_USTRINGPARAM("tag1")) , rList );
+ // tells the writer to insert a linefeed
+ r->ignorableWhitespace( OUString() );
+
+ r->characters( OUString( RTL_CONSTASCII_USTRINGPARAM("huhu")) );
+ r->ignorableWhitespace( OUString() );
+
+ r->startElement( OUString( RTL_CONSTASCII_USTRINGPARAM("hi")) , rList );
+ r->ignorableWhitespace( OUString() );
+
+ // the enpassant must be converted & -> &amp;
+ r->characters( OUString( RTL_CONSTASCII_USTRINGPARAM("&#252;")) );
+ r->ignorableWhitespace( OUString() );
+
+ // '>' must not be converted
+ r->startCDATA();
+ r->characters( OUString( RTL_CONSTASCII_USTRINGPARAM(" > foo < ")) );
+ r->endCDATA();
+ r->ignorableWhitespace( OUString() );
+
+ OUString testParagraph = OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "This is only a test to check, if the writer inserts line feeds "
+ "if needed or if the writer puts the whole text into one line." ));
+ writeParagraphHelper( r , testParagraph );
+
+ r->ignorableWhitespace( OUString() );
+ r->comment( OUString( RTL_CONSTASCII_USTRINGPARAM("This is a comment !")) );
+ r->ignorableWhitespace( OUString() );
+
+ r->startElement( OUString( RTL_CONSTASCII_USTRINGPARAM("emptytagtest")) , rList );
+ r->endElement( OUString( RTL_CONSTASCII_USTRINGPARAM("emptytagtest")) );
+ r->ignorableWhitespace( OUString() );
+
+ r->endElement( OUString( RTL_CONSTASCII_USTRINGPARAM("hi")) );
+ r->ignorableWhitespace( OUString() );
+
+ r->endElement( OUString( RTL_CONSTASCII_USTRINGPARAM("tag1")) );
+ r->endDocument();
+
+ printf( "finished writing\n" );
+ }
+ else
+ {
+ printf( "couln't create sax-writer component\n" );
+ }
+}
diff --git a/sax/test/testcomponent.cxx b/sax/test/testcomponent.cxx
new file mode 100644
index 000000000000..582bf423bc48
--- /dev/null
+++ b/sax/test/testcomponent.cxx
@@ -0,0 +1,267 @@
+/*************************************************************************
+ *
+ * $RCSfile: testcomponent.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 16:43:13 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+//------------------------------------------------------
+// testcomponent - Loads a service and its testcomponent from dlls performs a test.
+// Expands the dll-names depending on the actual environment.
+// Example : testcomponent stardiv.uno.io.Pipe stm
+//
+// Therefor the testcode must exist in teststm and the testservice must be named test.stardiv.uno.io.Pipe
+//
+
+#include <stdio.h>
+#include <com/sun/star/registry/XImplementationRegistration.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+
+#include <com/sun/star/test/XSimpleTest.hpp>
+
+#include <cppuhelper/servicefactory.hxx>
+
+#include <vos/dynload.hxx>
+#include <vos/diagnose.hxx>
+
+#include <assert.h>
+
+
+using namespace ::rtl;
+using namespace ::cppu;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::test;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::registry;
+
+// Needed to switch on solaris threads
+#ifdef SOLARIS
+extern "C" void ChangeGlobalInit();
+#endif
+
+int main (int argc, char **argv)
+{
+
+ if( argc < 3) {
+ printf( "usage : testcomponent service dll [additional dlls]\n" );
+ exit( 0 );
+ }
+#ifdef SOLARIS
+ // switch on threads in solaris
+ ChangeGlobalInit();
+#endif
+
+ // create service manager
+ Reference< XMultiServiceFactory > xSMgr =
+ createRegistryServiceFactory( OUString( RTL_CONSTASCII_USTRINGPARAM("applicat.rdb")) );
+
+ Reference < XImplementationRegistration > xReg;
+ Reference < XSimpleRegistry > xSimpleReg;
+
+ try
+ {
+ // Create registration service
+ Reference < XInterface > x = xSMgr->createInstance(
+ OUString::createFromAscii( "com.sun.star.registry.ImplementationRegistration" ) );
+ xReg = Reference< XImplementationRegistration > ( x , UNO_QUERY );
+ }
+ catch( Exception & ) {
+ printf( "Couldn't create ImplementationRegistration service\n" );
+ exit(1);
+ }
+
+ sal_Char szBuf[1024];
+ OString sTestName;
+
+ try
+ {
+ // Load dll for the tested component
+ for( int n = 2 ; n <argc ; n ++ ) {
+#ifdef SAL_W32
+ OUString aDllName = OStringToOUString( argv[n] , RTL_TEXTENCODING_ASCII_US );
+#else
+ OUString aDllName = L"lib";
+ aDllName += OStringToOUString( argv[n] , RTL_TEXTENCODING_ASCII_US );
+ aDllName += L".so";
+#endif
+ xReg->registerImplementation(
+ OUString::createFromAscii( "com.sun.star.loader.SharedLibrary" ),
+ aDllName,
+ xSimpleReg );
+ }
+ }
+ catch( Exception &e ) {
+ printf( "Couldn't reach dll %s\n" , szBuf );
+ printf( "%s\n" , OUStringToOString( e.Message , RTL_TEXTENCODING_ASCII_US ).getStr() );
+
+ exit(1);
+ }
+
+
+ try
+ {
+ // Load dll for the test component
+ sTestName = "test";
+ sTestName += argv[2];
+
+#ifdef SAL_W32
+ OUString aDllName = OStringToOUString( sTestName , RTL_TEXTENCODING_ASCII_US );
+#else
+ OUString aDllName = L"lib";
+ aDllName += OStringToOUString( sTestName , RTL_TEXTENCODING_ASCII_US );
+ aDllName += L".so";
+#endif
+
+ xReg->registerImplementation(
+ OUString::createFromAscii( "com.sun.star.loader.SharedLibrary" ) ,
+ aDllName,
+ xSimpleReg );
+ }
+ catch( Exception & e )
+ {
+ printf( "Couldn't reach dll %s\n" , szBuf );
+ exit(1);
+ }
+
+
+ // Instantiate test service
+ sTestName = "test.";
+ sTestName += argv[1];
+
+ Reference < XInterface > xIntTest =
+ xSMgr->createInstance( OStringToOUString( sTestName , RTL_TEXTENCODING_ASCII_US ) );
+ Reference< XSimpleTest > xTest( xIntTest , UNO_QUERY );
+
+ if( ! xTest.is() ) {
+ printf( "Couldn't instantiate test service \n" );
+ exit( 1 );
+ }
+
+
+ sal_Int32 nHandle = 0;
+ sal_Int32 nNewHandle;
+ sal_Int32 nErrorCount = 0;
+ sal_Int32 nWarningCount = 0;
+
+ // loop until all test are performed
+ while( nHandle != -1 )
+ {
+ // Instantiate serivce
+ Reference< XInterface > x =
+ xSMgr->createInstance( OStringToOUString( argv[1] , RTL_TEXTENCODING_ASCII_US ) );
+ if( ! x.is() )
+ {
+ printf( "Couldn't instantiate service !\n" );
+ exit( 1 );
+ }
+
+ // do the test
+ try
+ {
+ nNewHandle = xTest->test(
+ OStringToOUString( argv[1] , RTL_TEXTENCODING_ASCII_US ) , x , nHandle );
+ }
+ catch( Exception & e ) {
+ OString o = OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US );
+ printf( "testcomponent : uncaught exception %s\n" , o.getStr() );
+ exit(1);
+ }
+ catch( ... )
+ {
+ printf( "testcomponent : uncaught unknown exception\n" );
+ exit(1);
+ }
+
+
+ // print errors and warning
+ Sequence<OUString> seqErrors = xTest->getErrors();
+ Sequence<OUString> seqWarnings = xTest->getWarnings();
+ if( seqWarnings.getLength() > nWarningCount )
+ {
+ printf( "Warnings during test %d!\n" , nHandle );
+ for( ; nWarningCount < seqWarnings.getLength() ; nWarningCount ++ )
+ {
+ OString o = OUStringToOString(
+ seqWarnings.getArray()[nWarningCount], RTL_TEXTENCODING_ASCII_US );
+ printf( "Warning\n%s\n---------\n" , o.getStr() );
+ }
+ }
+
+
+ if( seqErrors.getLength() > nErrorCount ) {
+ printf( "Errors during test %d!\n" , nHandle );
+ for( ; nErrorCount < seqErrors.getLength() ; nErrorCount ++ ) {
+ OString o = OUStringToOString(
+ seqErrors.getArray()[nErrorCount], RTL_TEXTENCODING_ASCII_US );
+ printf( "%s\n" , o.getStr() );
+ }
+ }
+
+ nHandle = nNewHandle;
+ }
+
+ if( xTest->testPassed() ) {
+ printf( "Test passed !\n" );
+ }
+ else {
+ printf( "Test failed !\n" );
+ }
+
+ Reference <XComponent > rComp( xSMgr , UNO_QUERY );
+ rComp->dispose();
+ return 0;
+}
diff --git a/sax/util/makefile.mk b/sax/util/makefile.mk
new file mode 100644
index 000000000000..bb4599c4ef86
--- /dev/null
+++ b/sax/util/makefile.mk
@@ -0,0 +1,93 @@
+#*************************************************************************
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.1.1.1 $
+#
+# last change: $Author: hr $ $Date: 2000-09-18 16:43:13 $
+#
+# The Contents of this file are made available subject to the terms of
+# either of the following licenses
+#
+# - GNU Lesser General Public License Version 2.1
+# - Sun Industry Standards Source License Version 1.1
+#
+# Sun Microsystems Inc., October, 2000
+#
+# GNU Lesser General Public License Version 2.1
+# =============================================
+# Copyright 2000 by Sun Microsystems, Inc.
+# 901 San Antonio Road, Palo Alto, CA 94303, USA
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License version 2.1, as published by the Free Software Foundation.
+#
+# This library 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 for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+#
+# Sun Industry Standards Source License Version 1.1
+# =================================================
+# The contents of this file are subject to the Sun Industry Standards
+# Source License Version 1.1 (the "License"); You may not use this file
+# except in compliance with the License. You may obtain a copy of the
+# License at http://www.openoffice.org/license.html.
+#
+# Software provided under this License is provided on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+# WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+# MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+# See the License for the specific provisions governing your rights and
+# obligations concerning the Software.
+#
+# The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+#
+# Copyright: 2000 by Sun Microsystems, Inc.
+#
+# All Rights Reserved.
+#
+# Contributor(s): _______________________________________
+#
+#
+#
+#*************************************************************************
+PRJ=..
+
+PRJNAME=sax
+TARGET=sax
+NO_BSYMBOLIC=TRUE
+ENABLE_EXCEPTIONS=TRUE
+# --- Settings -----------------------------------------------------
+.INCLUDE : svpre.mk
+.INCLUDE : settings.mk
+.INCLUDE : sv.mk
+#-----------------------------------------------------------
+
+
+SHL1TARGET= $(TARGET)
+SHL1IMPLIB= i$(TARGET)
+
+
+SHL1STDLIBS= \
+ $(SALLIB) \
+ $(CPPULIB) \
+ $(CPPUHELPERLIB)\
+ $(EXPAT3RDLIB)
+
+SHL1LIBS= $(SLB)$/expatwrap.lib
+
+SHL1DEF= $(MISC)$/$(SHL1TARGET).def
+
+DEF1NAME= $(SHL1TARGET)
+DEF1EXPORTFILE= exports.dxp
+
+# --- Targets ------------------------------------------------------
+.INCLUDE : target.mk