? sax/sax.vpj
Index: sax/inc/xml2utf.hxx
===================================================================
RCS file: sax/inc/xml2utf.hxx
diff -N sax/inc/xml2utf.hxx
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sax/inc/xml2utf.hxx	8 May 2006 14:23:39 -0000	1.1.2.1
@@ -0,0 +1,157 @@
+/*************************************************************************
+ *
+ *  OpenOffice.org - a multi-platform office productivity suite
+ *
+ *  $RCSfile: xml2utf.hxx,v $
+ *
+ *  $Revision: 1.1.2.1 $
+ *
+ *  last change: $Author: cl $ $Date: 2006/05/08 14:23:39 $
+ *
+ *  The Contents of this file are made available subject to
+ *  the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ *    GNU Lesser General Public License Version 2.1
+ *    =============================================
+ *    Copyright 2005 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
+ *
+ ************************************************************************/
+
+// TODO: Woher?
+#define Max( a, b )		(((a)>(b)) ? (a) : (b) )
+#define Min( a, b )		(((a)<(b)) ? (a) : (b) )
+
+/*
+* 
+* Text2UnicodeConverter
+*
+**/
+namespace sax_expatwrap {
+	
+class Text2UnicodeConverter 
+{
+
+public:
+	Text2UnicodeConverter( const ::rtl::OString & sEncoding );
+	Text2UnicodeConverter( rtl_TextEncoding encoding );
+	~Text2UnicodeConverter();
+
+	::com::sun::star::uno::Sequence < sal_Unicode > convert( const ::com::sun::star::uno::Sequence<sal_Int8> & );
+	sal_Bool canContinue() {  return m_bCanContinue; }
+
+private:
+	void init( rtl_TextEncoding encoding );
+
+	rtl_TextToUnicodeConverter 	m_convText2Unicode;
+	rtl_TextToUnicodeContext   	m_contextText2Unicode;
+	sal_Bool					m_bCanContinue;
+	sal_Bool					m_bInitialized;
+	rtl_TextEncoding			m_rtlEncoding;
+	::com::sun::star::uno::Sequence<sal_Int8> m_seqSource;
+};
+
+/*----------------------------------------
+*
+* Unicode2TextConverter
+*
+**-----------------------------------------*/
+class Unicode2TextConverter 
+{
+public:
+	Unicode2TextConverter( const ::rtl::OString & sEncoding );
+	Unicode2TextConverter( rtl_TextEncoding encoding );
+	~Unicode2TextConverter();
+
+	inline ::com::sun::star::uno::Sequence<sal_Int8> convert( const ::rtl::OUString &s )
+		{
+			return convert( s.getStr() , s.getLength() );
+		}
+	::com::sun::star::uno::Sequence<sal_Int8> convert( const sal_Unicode * , sal_Int32 nLength );
+	sal_Bool canContinue() {  return m_bCanContinue; }
+
+private:
+	void init( rtl_TextEncoding encoding );
+
+	rtl_UnicodeToTextConverter 	m_convUnicode2Text;
+	rtl_UnicodeToTextContext   	m_contextUnicode2Text;
+	sal_Bool					m_bCanContinue;
+	sal_Bool					m_bInitialized;
+	rtl_TextEncoding			m_rtlEncoding;
+	::com::sun::star::uno::Sequence<sal_Unicode>		m_seqSource;
+};
+
+
+
+/*----------------------------------------
+*
+* XMLFile2UTFConverter
+*
+**-----------------------------------------*/
+class XMLFile2UTFConverter
+{
+public:
+	XMLFile2UTFConverter( ):
+		m_bStarted( sal_False ),
+		m_pText2Unicode( 0 ),
+		m_pUnicode2Text( 0 )
+		{}
+
+	~XMLFile2UTFConverter();
+	
+	void setInputStream( ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > &r ) { m_in = r; }
+	void setEncoding( const ::rtl::OString &s ) { m_sEncoding = s; }
+
+
+	
+	// @param nMaxToRead The number of chars, that should be read. Note that this is no exact number. There
+	//                   may be returned less or more bytes than ordered.
+	sal_Int32 readAndConvert( ::com::sun::star::uno::Sequence<sal_Int8> &seq , sal_Int32 nMaxToRead ) 
+		throw ( ::com::sun::star::io::IOException,
+				::com::sun::star::io::NotConnectedException ,
+				::com::sun::star::io::BufferSizeExceededException ,
+				::com::sun::star::uno::RuntimeException );
+
+private:
+
+	// Called only on first Sequence of bytes. Tries to figure out file format and encoding information.
+	// @return TRUE, when encoding information could be retrieved
+	// @return FALSE, when no encoding information was found in file
+	sal_Bool scanForEncoding( ::com::sun::star::uno::Sequence<sal_Int8> &seq );
+
+	// Called only on first Sequence of bytes. Tries to figure out
+	// if enough data is available to scan encoding
+	// @return TRUE, when encoding is retrievable
+	// @return FALSE, when more data is needed
+	sal_Bool isEncodingRecognizable( const ::com::sun::star::uno::Sequence< sal_Int8 > & seq );
+
+	// When encoding attribute is within the text (in the first line), it is removed.
+	void removeEncoding( ::com::sun::star::uno::Sequence<sal_Int8> &seq );
+	
+	// Initializes decoding depending on m_sEncoding setting
+	void initializeDecoding();
+private:
+	::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >  m_in;
+		
+	sal_Bool m_bStarted;
+	::rtl::OString m_sEncoding;
+
+	Text2UnicodeConverter *m_pText2Unicode;
+	Unicode2TextConverter *m_pUnicode2Text;	
+};
+}
Index: sax/inc/sax/dllapi.h
===================================================================
RCS file: sax/inc/sax/dllapi.h
diff -N sax/inc/sax/dllapi.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sax/inc/sax/dllapi.h	14 Feb 2006 18:39:21 -0000	1.1.2.1
@@ -0,0 +1,49 @@
+/*************************************************************************
+ *
+ *  OpenOffice.org - a multi-platform office productivity suite
+ *
+ *  $RCSfile: dllapi.h,v $
+ *
+ *  $Revision: 1.1.2.1 $
+ *
+ *  last change: $Author: cl $ $Date: 2006/02/14 18:39:21 $
+ *
+ *  The Contents of this file are made available subject to
+ *  the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ *    GNU Lesser General Public License Version 2.1
+ *    =============================================
+ *    Copyright 2005 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
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_SAX_DLLAPI_H
+#define INCLUDED_SAX_DLLAPI_H
+
+#ifndef _SAL_TYPES_H_
+#include "sal/types.h"
+#endif
+
+#if defined SAX_DLLIMPLEMENTATION
+#define SAX_DLLPUBLIC SAL_DLLPUBLIC_EXPORT
+#else
+#define SAX_DLLPUBLIC SAL_DLLPUBLIC_IMPORT
+#endif
+
+#endif
Index: sax/inc/sax/parser/saxparser.hxx
===================================================================
RCS file: sax/inc/sax/parser/saxparser.hxx
diff -N sax/inc/sax/parser/saxparser.hxx
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sax/inc/sax/parser/saxparser.hxx	10 May 2006 15:39:33 -0000	1.1.2.4
@@ -0,0 +1,174 @@
+/*************************************************************************
+ *
+ *  OpenOffice.org - a multi-platform office productivity suite
+ *
+ *  $RCSfile: saxparser.hxx,v $
+ *
+ *  $Revision: 1.1.2.4 $
+ *
+ *  last change: $Author: cl $ $Date: 2006/05/10 15:39:33 $
+ *
+ *  The Contents of this file are made available subject to
+ *  the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ *    GNU Lesser General Public License Version 2.1
+ *    =============================================
+ *    Copyright 2005 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
+ *
+ ************************************************************************/
+
+#ifndef _SAX_SAXPARSER_HXX_
+#define _SAX_SAXPARSER_HXX_
+
+#ifndef INCLUDED_SAX_DLLAPI_H
+#include "sax/dllapi.h"
+#endif
+
+#ifndef _COM_SUN_STAR_XML_SAX_INPUTSOURCE_HPP_
+#include <com/sun/star/xml/sax/InputSource.hpp>
+#endif
+#ifndef _COM_SUN_STAR_XML_SAX_SAXEXCEPTION_HPP_
+#include <com/sun/star/xml/sax/SAXException.hpp>
+#endif
+
+#ifndef _RTL_REF_HXX_
+#include <rtl/ref.hxx>
+#endif
+
+#ifndef BOOST_SHARED_PTR_HPP_INCLUDED
+#include <boost/shared_ptr.hpp>
+#endif
+
+#include <map>
+#include <memory>
+
+#ifndef _SAX_OBJECT_HXX_
+#include "sax/tools/saxobject.hxx"
+#endif
+
+#ifndef _SAX_ATTRIBUTEMAP_HXX_
+#include "sax/tools/attributemap.hxx"
+#endif
+
+#include <boost/scoped_ptr.hpp>
+
+namespace sax
+{
+
+// --------------------------------------------------------------------
+
+class SaxParser;
+class SaxContext;
+
+typedef rtl::Reference< SaxParser > SaxParserRef;
+typedef rtl::Reference< SaxContext > SaxContextRef;
+
+/** base class for each implementation that handles all sax calls for an element */
+class SAX_DLLPUBLIC SaxContext : public SaxObject
+{
+public:
+	SaxContext( const SaxParserRef& xParser );
+	virtual ~SaxContext();
+
+	/** receives notification of the beginning of an element .
+	 */
+	virtual void StartElement( sal_uInt32 aElementToken, const AttributeMap& rAttributes );
+
+	/** receives notification of character data.
+	 */
+	virtual void Characters( const sal_Char *pCharacters, sal_uInt32 nLength );
+
+	/** receives notification of the end of an element.
+	 */
+	virtual void EndElement( sal_uInt32 aElementToken );
+
+	/** is called by the SaxParser for each child element inside this instances element */
+	virtual SaxContextRef CreateContext( sal_uInt32 aElementToken, const AttributeMap& rAttributes );
+
+	const SaxParserRef& getParser() const { return mxParser; }
+private:
+	SaxParserRef	mxParser;
+};
+
+// --------------------------------------------------------------------
+
+class SaxParserImpl;
+
+/** base class for loading a single xml stream. Derived classes must call
+	parseStream to start parsing and are notified through virtual methods
+	for sax events. */
+class SAX_DLLPUBLIC SaxParser : public SaxObject
+{
+public:
+	SaxParser();
+	virtual ~SaxParser();
+
+	/** returns the unicode representation of a token from the xml stream
+		that was unknown to the SaxTokenMap from the derived class. */
+	rtl::OUString GetCustomToken( sal_uInt32 nToken );
+
+	/** returns the unicode representation of a namespace from the xml stream
+		that was unknown to the SaxTokenMap from the derived class. */
+	rtl::OUString GetCustomNamespace( sal_uInt32 nToken );
+
+	/** returns the system id of the currently parsed stream */
+	const rtl::OUString& GetSystemId() const;
+
+	/** starts parsing of the source xml stream provided in the given sax InputSource */
+	virtual void parseStream( const ::com::sun::star::xml::sax::InputSource& rInputSource ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+
+	/** is called once when parsing of the xml stream starts */
+	virtual void StartDocument();
+
+	/** is called once for each element in the xml stream.
+		Default implementation calls StartElement() on the topmost contex. */
+	virtual void StartElement( sal_uInt32 aElementToken, const AttributeMap& rAttributes );
+
+	/** is called for characters betwen elements in the xml stream.
+		Default implementation calls Characters() on the topmost contex.
+		@param pCharacters The characters in utf-8 encoding	
+		@param nLength the size in bytes of the utf-8 string
+	*/
+	virtual void Characters( const sal_Char *pCharacters, sal_uInt32 nLength );
+
+	/** is called once at the end of each element in the xml stream.
+		Default implementation calls EndElement() on the topmost contex. */
+	virtual void EndElement( sal_uInt32 aElementToken );
+
+	/** is called once after parsing the xml stream is finished */
+	virtual void EndDocument();
+
+	/** is called once for each element in the xml stream and before StartElement() is called.
+		Default implementation calls CreateContext at the topmost context.
+		Returned contexts are pushed on a stack and removed after the corresponding EndElement call. */
+	virtual SaxContextRef CreateContext( sal_uInt32 aElementToken, const AttributeMap& rAttributes );
+
+	/** must be implemented from derived classes. The returned SaxTokenMap is used to convert
+		element names and attribute names and values to tokens. */
+	virtual const SaxTokenMapRef& getTokenMap() = 0;
+
+private:
+	void AddNamespace( sal_uInt32 nNamespaceId, sal_uInt32 nNamespaceURIToken );
+
+	boost::scoped_ptr< SaxParserImpl > mpImpl;
+};
+
+}
+
+#endif // _SAX_SAXPARSER_HXX_
Index: sax/inc/sax/tools/attributemap.hxx
===================================================================
RCS file: sax/inc/sax/tools/attributemap.hxx
diff -N sax/inc/sax/tools/attributemap.hxx
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sax/inc/sax/tools/attributemap.hxx	10 May 2006 15:39:50 -0000	1.1.2.4
@@ -0,0 +1,83 @@
+/*************************************************************************
+ *
+ *  OpenOffice.org - a multi-platform office productivity suite
+ *
+ *  $RCSfile: attributemap.hxx,v $
+ *
+ *  $Revision: 1.1.2.4 $
+ *
+ *  last change: $Author: cl $ $Date: 2006/05/10 15:39:50 $
+ *
+ *  The Contents of this file are made available subject to
+ *  the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ *    GNU Lesser General Public License Version 2.1
+ *    =============================================
+ *    Copyright 2005 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
+ *
+ ************************************************************************/
+
+#ifndef _SAX_ATTRIBUTEMAP_HXX_
+#define _SAX_ATTRIBUTEMAP_HXX_
+
+#ifndef INCLUDED_SAX_DLLAPI_H
+#include "sax/dllapi.h"
+#endif
+
+#include <map>
+
+#ifndef _SAX_TOKENMAP_HXX_
+#include "sax/tools/tokenmap.hxx"
+#endif
+
+namespace sax
+{
+	class SaxTokenMap;
+
+	typedef std::map< sal_uInt32, rtl::OString > AttributeMapBase;
+
+	/** a map for a set of xml attributes, identified with integer tokens.
+		Attribute values are stored in utf-8 encoding. */
+	class SAX_DLLPUBLIC AttributeMap : public AttributeMapBase
+	{
+	public:
+		AttributeMap( const SaxTokenMap& rTokenMap );
+		~AttributeMap();
+
+		/** returns a unicode string, if the token does not exists the string is empty */
+		::rtl::OUString getString( SaxToken nToken ) const;
+
+		/** returns true if the attribute with the token nToken is part of this map */
+		bool has( SaxToken nToken ) const;
+
+		/** converts the attribute with the token nToken to sal_Int32 or returns
+			nDefault if this attribute does not exists */
+		sal_Int32 getInt32( SaxToken nToken, sal_Int32 nDefault = 0 ) const;
+
+		/** converts the attribute with the token nToken to a token or returns
+			nDefault if this attribute does not exists */
+		sal_uInt32 getToken( SaxToken nToken, SaxToken nDefault ) const;
+
+	private:
+		const SaxTokenMap& mrTokenMap;
+	};
+
+}
+
+#endif // _SAX_ATTRIBUTEMAP_HXX_
Index: sax/inc/sax/tools/converter.hxx
===================================================================
RCS file: sax/inc/sax/tools/converter.hxx
diff -N sax/inc/sax/tools/converter.hxx
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sax/inc/sax/tools/converter.hxx	10 May 2007 15:50:14 -0000	1.1.2.3
@@ -0,0 +1,205 @@
+/*************************************************************************
+ *
+ *  OpenOffice.org - a multi-platform office productivity suite
+ *
+ *  $RCSfile: converter.hxx,v $
+ *
+ *  $Revision: 1.1.2.3 $
+ *
+ *  last change: $Author: hub $ $Date: 2007/05/10 15:50:14 $
+ *
+ *  The Contents of this file are made available subject to
+ *  the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ *    GNU Lesser General Public License Version 2.1
+ *    =============================================
+ *    Copyright 2005 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
+ *
+ ************************************************************************/
+
+#ifndef _SAX_CONVERTER_HXX
+#define _SAX_CONVERTER_HXX
+
+#include <sal/types.h>
+
+#ifndef INCLUDED_SAX_DLLAPI_H
+#include "sax/dllapi.h"
+#endif
+
+#ifndef _COM_SUN_STAR_UTIL_DATE_HPP_
+#include <com/sun/star/util/Date.hpp>
+#endif
+#ifndef _COM_SUN_STAR_UTIL_MEASUREUNIT_HPP_
+#include <com/sun/star/util/MeasureUnit.hpp>
+#endif
+
+namespace rtl
+{
+class OUString;
+class OUStringBuffer;
+}
+
+namespace com { namespace sun { namespace star {
+	namespace util { struct DateTime; }
+}}}
+
+namespace sax { 
+
+/** the Converter converts values of various types from
+	their internal represantation to the textual form used in xml
+	and back.
+
+	All unit types are expressed as com::sun::star::util::MeasureUnit
+*/
+
+
+class SAX_DLLPUBLIC Converter
+{
+public:
+	/** convert string to measure using optional min and max values*/
+	static bool convertMeasure(	sal_Int32& rValue, 
+								const ::rtl::OUString& rString,
+								sal_Int16 nTargetUnit = ::com::sun::star::util::MeasureUnit::MM_100TH,
+								sal_Int32 nMin = SAL_MIN_INT32,
+								sal_Int32 nMax = SAL_MAX_INT32 );
+
+	/** convert measure to string */
+	static void convertMeasure( ::rtl::OUStringBuffer& rBuffer,
+								sal_Int32 nMeasure,
+								sal_Int16 SourceUnit = ::com::sun::star::util::MeasureUnit::MM_100TH,
+								sal_Int16 nTargetUnit = ::com::sun::star::util::MeasureUnit::INCH  );
+
+	/** convert string to boolean */
+	static bool convertBool( bool& rBool,
+							 const ::rtl::OUString& rString );
+
+	/** convert boolean to string */
+	static void convertBool( ::rtl::OUStringBuffer& rBuffer,
+							 bool bValue );
+
+	/** convert string to percent */
+	static bool convertPercent( sal_Int32& rValue,
+								const ::rtl::OUString& rString );
+
+	/** convert percent to string */
+	static void convertPercent( ::rtl::OUStringBuffer& rBuffer,
+								sal_Int32 nValue );
+
+	/** convert string to pixel measure unite */
+	static bool convertMeasurePx( sal_Int32& rValue,
+								  const ::rtl::OUString& rString );
+
+	/** convert pixel measure unit to string */
+	static void convertMeasurePx( ::rtl::OUStringBuffer& rBuffer,
+								  sal_Int32 nValue );
+
+	/** convert string to color */
+	static bool convertColor( sal_Int32& rColor,
+							  const ::rtl::OUString&rValue );
+
+	/** convert color to string */
+	static void convertColor( ::rtl::OUStringBuffer &rBuffer,
+							  sal_Int32 nColor );
+
+	/** convert number to string */
+	static void convertNumber( ::rtl::OUStringBuffer& rBuffer,
+							   sal_Int32 nNumber );
+
+	/** convert string to number with optional min and max values */
+	static bool convertNumber( sal_Int32& rValue,
+							   const ::rtl::OUString& rString,
+							   sal_Int32 nMin = SAL_MIN_INT32,
+							   sal_Int32 nMax = SAL_MAX_INT32 );
+
+	/** convert double number to string (using ::rtl::math) and
+		DO convert from source unit to target unit */
+	static void convertDouble( ::rtl::OUStringBuffer& rBuffer,
+							   double fNumber,
+							   bool bWriteUnits,
+							   sal_Int16 nSourceUnit,
+							   sal_Int16 nTargetUnit );
+
+	/** convert double number to string (using ::rtl::math) without unit conversion */
+	static void convertDouble( ::rtl::OUStringBuffer& rBuffer, double fNumber);
+
+	/** convert string to double number (using ::rtl::math) and DO convert from
+		source unit to target unit. */
+	static bool convertDouble(	double& rValue,
+								const ::rtl::OUString& rString,
+								sal_Int16 nSourceUnit,
+								sal_Int16 nTargetUnit );
+
+	/** convert string to double number (using ::rtl::math) without unit conversion */
+	static bool convertDouble(double& rValue, const ::rtl::OUString& rString);
+
+	/** convert string to double number (using ::rtl::math) with unit conversion */
+	static bool convertDouble(double& rValue, const ::rtl::OUString& rString, sal_Int16 nTargetUnit );
+
+	/** convert double to ISO Time String */
+	static void convertTime( ::rtl::OUStringBuffer& rBuffer,
+								const double& fTime);
+
+	/** convert util::DateTime to ISO Time String */
+	static void convertTime( ::rtl::OUStringBuffer& rBuffer,
+								const ::com::sun::star::util::DateTime& rDateTime );
+
+	/** convert ISO Time String to double */
+	static bool convertTime( double& fTime,
+								const ::rtl::OUString& rString);
+
+	/** convert ISO Time String to util::DateTime */
+	static bool convertTime( ::com::sun::star::util::DateTime& rDateTime,
+								 const ::rtl::OUString& rString );
+
+	/** convert util::DateTime to ISO Date String */
+	static void convertDateTime( ::rtl::OUStringBuffer& rBuffer,
+								const com::sun::star::util::DateTime& rDateTime,
+		   						bool bAddTimeIf0AM = false );
+
+	/** convert ISO Date String to util::DateTime */
+	static bool convertDateTime( com::sun::star::util::DateTime& rDateTime,
+								 const ::rtl::OUString& rString );
+
+	/** gets the position of the first comma after npos in the string
+		rStr. Commas inside '"' pairs are not matched */
+	static sal_Int32 indexOfComma( const ::rtl::OUString& rStr,
+								   sal_Int32 nPos );
+
+	/** encodes the given byte sequence into Base64 */
+	static void encodeBase64(rtl::OUStringBuffer& aStrBuffer, const com::sun::star::uno::Sequence<sal_Int8>& aPass);
+
+	// Decode a base 64 encoded string into a sequence of bytes. The first
+	// version can be used for attribute values only, bacause it does not
+	// return any chars left from conversion.
+	// For text submitted throgh the SAX characters call, the later method
+	// must be used!
+	static void decodeBase64(com::sun::star::uno::Sequence<sal_Int8>& aPass, const rtl::OUString& sBuffer);
+
+	static sal_Int32 decodeBase64SomeChars(com::sun::star::uno::Sequence<sal_Int8>& aPass, const rtl::OUString& sBuffer);
+
+	static void clearUndefinedChars(rtl::OUString& rTarget, const rtl::OUString& rSource);
+
+	static double GetConversionFactor(::rtl::OUStringBuffer& rUnit, sal_Int16 nSourceUnit, sal_Int16 nTargetUnit);
+	static sal_Int16 GetUnitFromString(const ::rtl::OUString& rString, sal_Int16 nDefaultUnit);
+
+};
+
+}
+
+#endif	//  _SAX_CONVERTER_HXX
Index: sax/inc/sax/tools/saxobject.hxx
===================================================================
RCS file: sax/inc/sax/tools/saxobject.hxx
diff -N sax/inc/sax/tools/saxobject.hxx
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sax/inc/sax/tools/saxobject.hxx	8 May 2006 14:24:30 -0000	1.1.2.1
@@ -0,0 +1,63 @@
+/*************************************************************************
+ *
+ *  OpenOffice.org - a multi-platform office productivity suite
+ *
+ *  $RCSfile: saxobject.hxx,v $
+ *
+ *  $Revision: 1.1.2.1 $
+ *
+ *  last change: $Author: cl $ $Date: 2006/05/08 14:24:30 $
+ *
+ *  The Contents of this file are made available subject to
+ *  the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ *    GNU Lesser General Public License Version 2.1
+ *    =============================================
+ *    Copyright 2005 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
+ *
+ ************************************************************************/
+
+#ifndef _SAX_OBJECT_HXX_
+#define _SAX_OBJECT_HXX_
+
+#ifndef _SAL_TYPES_H_
+#include <sal/types.h>
+#endif
+
+#ifndef INCLUDED_SAX_DLLAPI_H
+#include "sax/dllapi.h"
+#endif
+
+namespace sax
+{
+
+	/** simple base class to allow refcounting with rtl::Reference or css::uno::Reference */
+	class SAX_DLLPUBLIC SaxObject
+	{
+	public:
+		SaxObject();
+		virtual ~SaxObject();
+		virtual void SAL_CALL acquire() throw ();
+		virtual void SAL_CALL release() throw ();
+	private:
+		sal_uInt32 mnRefCount;
+	};
+}
+
+#endif // _SAX_OBJECT_HXX_
Index: sax/inc/sax/tools/tokenmap.hxx
===================================================================
RCS file: sax/inc/sax/tools/tokenmap.hxx
diff -N sax/inc/sax/tools/tokenmap.hxx
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sax/inc/sax/tools/tokenmap.hxx	10 May 2006 15:39:50 -0000	1.1.2.4
@@ -0,0 +1,84 @@
+/*************************************************************************
+ *
+ *  OpenOffice.org - a multi-platform office productivity suite
+ *
+ *  $RCSfile: tokenmap.hxx,v $
+ *
+ *  $Revision: 1.1.2.4 $
+ *
+ *  last change: $Author: cl $ $Date: 2006/05/10 15:39:50 $
+ *
+ *  The Contents of this file are made available subject to
+ *  the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ *    GNU Lesser General Public License Version 2.1
+ *    =============================================
+ *    Copyright 2005 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
+ *
+ ************************************************************************/
+
+#ifndef _SAX_TOKENMAP_HXX_
+#define _SAX_TOKENMAP_HXX_
+
+#ifndef _RTL_REF_HXX_
+#include <rtl/ref.hxx>
+#endif
+
+#ifndef _RTL_USTRING_HXX_
+#include <rtl/ustring.hxx>
+#endif
+
+#ifndef INCLUDED_SAX_DLLAPI_H
+#include "sax/dllapi.h"
+#endif
+
+#ifndef _SAX_OBJECT_HXX_
+#include "sax/tools/saxobject.hxx"
+#endif
+
+namespace sax
+{
+	/** type for a token identifier */
+	typedef sal_uInt32 SaxToken;
+
+	/** this class maps a set of ascii/utf-8 strings to token identifier */
+	class SAX_DLLPUBLIC SaxTokenMap : public SaxObject
+	{
+	public:
+		/** constant do indicate an unknown token */
+		const static SaxToken InvalidToken = (SaxToken)-1;
+
+		/** returns the token identifier for the given ascii string or SaxTokenMap::InvalidToken */
+		virtual SaxToken GetToken( const sal_Char* pChar, sal_uInt32 nLength  = 0 ) const = 0;
+
+		/** returns the token identifier for the given unicode string or SaxTokenMap::InvalidToken */
+		virtual SaxToken GetToken( const ::rtl::OUString& rToken ) const = 0;
+
+		/** returns the unicode string for the given token identifier */
+		virtual const ::rtl::OUString& GetToken( SaxToken nToken ) const = 0;
+
+		/** returns if the given unicode string equals the given token identifier */
+		bool IsToken( const ::rtl::OUString& rToken, SaxToken nToken ) const { return GetToken( rToken ) == nToken; }
+	};
+
+	/** reference type to a SaxTokenMap */
+	typedef rtl::Reference< SaxTokenMap > SaxTokenMapRef;
+}
+
+#endif // _SAX_TOKENMAP_HXX_
Index: sax/prj/build.lst
===================================================================
RCS file: /cvs/xml/sax/prj/build.lst,v
retrieving revision 1.7
retrieving revision 1.6.10.3
diff -u -b -I $Revision.*$ -I $Author.*$ -r1.7 -r1.6.10.3
--- sax/prj/build.lst	24 May 2006 13:33:13 -0000	1.7
+++ sax/prj/build.lst	24 Jul 2007 12:20:12 -0000	1.6.10.3
@@ -1,4 +1,6 @@
-ax	sax	:	offapi cppuhelper EXPAT:expat NULL
+ax	sax	:	offapi cppuhelper EXPAT:expat comphelper NULL
 ax	sax										usr1	-	all	ax_mkout NULL
 ax	sax\source\expatwrap					nmake	-	all	ax_expatwrap NULL
-ax	sax\util								nmake	-	all	ax_util ax_expatwrap NULL
+ax	sax\source\tools						nmake	-	all ax_tools  NULL
+ax  sax\source\fastparser					nmake	-	all ax_fastparser ax_tools NULL
+ax	sax\util								nmake	-	all	ax_util ax_expatwrap ax_tools ax_fastparser NULL
Index: sax/prj/d.lst
===================================================================
RCS file: /cvs/xml/sax/prj/d.lst,v
retrieving revision 1.11
retrieving revision 1.8.44.8
diff -u -b -I $Revision.*$ -I $Author.*$ -r1.11 -r1.8.44.8
--- sax/prj/d.lst	12 Dec 2006 16:21:16 -0000	1.11
+++ sax/prj/d.lst	8 May 2007 14:46:22 -0000	1.8.44.8
@@ -1,3 +1,11 @@
-..\%__SRC%\bin\sax.uno.dll %_DEST%\bin%_EXT%\sax.uno.dll
-..\%__SRC%\lib\sax.uno.so %_DEST%\lib%_EXT%\sax.uno.so
+..\%__SRC%\bin\*.dll %_DEST%\bin%_EXT%\*.dll
+..\%__SRC%\lib\*.so %_DEST%\lib%_EXT%\*.so
 ..\%__SRC%\lib\*.dylib %_DEST%\lib%_EXT%\*.dylib
+..\%__SRC%\lib\*.lib %_DEST%\lib%_EXT%\*.lib
+
+mkdir: %_DEST%\inc%_EXT%\sax
+mkdir: %_DEST%\inc%_EXT%\sax\tools
+..\inc\sax\dllapi.h %_DEST%\inc%_EXT%\sax\dllapi.h
+..\inc\sax\tools\converter.hxx %_DEST%\inc%_EXT%\sax\tools\converter.hxx
+
+dos: sh -c "if test %OS% = MACOSX; then macosx-create-bundle %_DEST%\lib%_EXT%\*.dylib; fi"
Index: sax/source/expatwrap/makefile.mk
===================================================================
RCS file: /cvs/xml/sax/source/expatwrap/makefile.mk,v
retrieving revision 1.10
retrieving revision 1.9.12.2
diff -u -b -I $Revision.*$ -I $Author.*$ -r1.10 -r1.9.12.2
--- sax/source/expatwrap/makefile.mk	6 Feb 2007 12:56:43 -0000	1.10
+++ sax/source/expatwrap/makefile.mk	20 Feb 2007 14:13:28 -0000	1.9.12.2
@@ -35,25 +35,49 @@
 PRJ=..$/..
 
 PRJNAME=sax
-TARGET=expatwrap
-NO_BSYMBOLIC=TRUE
+TARGET=sax.uno
 ENABLE_EXCEPTIONS=TRUE
+
 # --- Settings -----------------------------------------------------
+
 .INCLUDE :  settings.mk
-#-----------------------------------------------------------
+DLLPRE =
+
+.IF "$(SYSTEM_ZLIB)" == "YES"
+CFLAGS+=-DSYSTEM_ZLIB
+.ENDIF
+
 .IF "$(SYSTEM_EXPAT)" == "YES"
 CFLAGS+=-DSYSTEM_EXPAT
 .ELSE
 CFLAGS += -DXML_UNICODE
 .ENDIF
 
+#-----------------------------------------------------------
+
 SLOFILES =\
 		$(SLO)$/xml2utf.obj\
 		$(SLO)$/attrlistimpl.obj\
 		$(SLO)$/sax_expat.obj \
 		$(SLO)$/saxwriter.obj
 
+SHL1TARGET= $(TARGET)
+SHL1IMPLIB= i$(TARGET)
+
+SHL1STDLIBS= \
+		$(SALLIB)  \
+		$(CPPULIB) \
+		$(CPPUHELPERLIB)\
+		$(EXPAT3RDLIB)
+
+SHL1DEPN=
+SHL1VERSIONMAP=	$(SOLARENV)$/src$/component.map
+SHL1LIBS=		$(SLB)$/$(TARGET).lib
+SHL1DEF=		$(MISC)$/$(SHL1TARGET).def
+DEF1NAME=		$(SHL1TARGET)
+
 # --- Targets ------------------------------------------------------
+
 .INCLUDE :	target.mk
 
 
Index: sax/source/expatwrap/xml2utf.hxx
===================================================================
RCS file: sax/source/expatwrap/xml2utf.hxx
diff -N sax/source/expatwrap/xml2utf.hxx
--- sax/source/expatwrap/xml2utf.hxx	8 Sep 2005 12:05:37 -0000	1.3
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,157 +0,0 @@
-/*************************************************************************
- *
- *  OpenOffice.org - a multi-platform office productivity suite
- *
- *  $RCSfile: xml2utf.hxx,v $
- *
- *  $Revision: 1.3 $
- *
- *  last change: $Author: rt $ $Date: 2005/09/08 12:05:37 $
- *
- *  The Contents of this file are made available subject to
- *  the terms of GNU Lesser General Public License Version 2.1.
- *
- *
- *    GNU Lesser General Public License Version 2.1
- *    =============================================
- *    Copyright 2005 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
- *
- ************************************************************************/
-
-// TODO: Woher?
-#define Max( a, b )		(((a)>(b)) ? (a) : (b) )
-#define Min( a, b )		(((a)<(b)) ? (a) : (b) )
-
-/*
-* 
-* Text2UnicodeConverter
-*
-**/
-namespace sax_expatwrap {
-	
-class Text2UnicodeConverter 
-{
-
-public:
-	Text2UnicodeConverter( const OString & sEncoding );
-	Text2UnicodeConverter( rtl_TextEncoding encoding );
-	~Text2UnicodeConverter();
-
-	Sequence < sal_Unicode > convert( const Sequence<sal_Int8> & );
-	sal_Bool canContinue() {  return m_bCanContinue; }
-
-private:
-	void init( rtl_TextEncoding encoding );
-
-	rtl_TextToUnicodeConverter 	m_convText2Unicode;
-	rtl_TextToUnicodeContext   	m_contextText2Unicode;
-	sal_Bool					m_bCanContinue;
-	sal_Bool					m_bInitialized;
-	rtl_TextEncoding			m_rtlEncoding;
-	Sequence<sal_Int8>				m_seqSource;
-};
-
-/*----------------------------------------
-*
-* Unicode2TextConverter
-*
-**-----------------------------------------*/
-class Unicode2TextConverter 
-{
-public:
-	Unicode2TextConverter( const OString & sEncoding );
-	Unicode2TextConverter( rtl_TextEncoding encoding );
-	~Unicode2TextConverter();
-
-	inline Sequence<sal_Int8> convert( const OUString &s )
-		{
-			return convert( s.getStr() , s.getLength() );
-		}
-	Sequence<sal_Int8> convert( const sal_Unicode * , sal_Int32 nLength );
-	sal_Bool canContinue() {  return m_bCanContinue; }
-
-private:
-	void init( rtl_TextEncoding encoding );
-
-	rtl_UnicodeToTextConverter 	m_convUnicode2Text;
-	rtl_UnicodeToTextContext   	m_contextUnicode2Text;
-	sal_Bool					m_bCanContinue;
-	sal_Bool					m_bInitialized;
-	rtl_TextEncoding			m_rtlEncoding;
-	Sequence<sal_Unicode>		m_seqSource;
-};
-
-
-
-/*----------------------------------------
-*
-* XMLFile2UTFConverter
-*
-**-----------------------------------------*/
-class XMLFile2UTFConverter
-{
-public:
-	XMLFile2UTFConverter( ):
-		m_bStarted( sal_False ),
-		m_pText2Unicode( 0 ),
-		m_pUnicode2Text( 0 )
-		{}
-
-	~XMLFile2UTFConverter();
-	
-	void setInputStream( Reference< XInputStream > &r ) { m_in = r; }
-	void setEncoding( const OString &s ) { m_sEncoding = s; }
-
-
-	
-	// @param nMaxToRead The number of chars, that should be read. Note that this is no exact number. There
-	//                   may be returned less or more bytes than ordered.
-	sal_Int32 readAndConvert( Sequence<sal_Int8> &seq , sal_Int32 nMaxToRead ) 
-		throw ( IOException,
-				NotConnectedException ,
-				BufferSizeExceededException ,
-				RuntimeException );
-
-private:
-
-	// Called only on first Sequence of bytes. Tries to figure out file format and encoding information.
-	// @return TRUE, when encoding information could be retrieved
-	// @return FALSE, when no encoding information was found in file
-	sal_Bool scanForEncoding( Sequence<sal_Int8> &seq );
-
-	// Called only on first Sequence of bytes. Tries to figure out
-	// if enough data is available to scan encoding
-	// @return TRUE, when encoding is retrievable
-	// @return FALSE, when more data is needed
-	sal_Bool isEncodingRecognizable( const Sequence< sal_Int8 > & seq );
-
-	// When encoding attribute is within the text (in the first line), it is removed.
-	void removeEncoding( Sequence<sal_Int8> &seq );
-	
-	// Initializes decoding depending on m_sEncoding setting
-	void initializeDecoding();
-private:
-	Reference< XInputStream >  m_in;
-		
-	sal_Bool m_bStarted;
-	OString m_sEncoding;
-
-	Text2UnicodeConverter *m_pText2Unicode;
-	Unicode2TextConverter *m_pUnicode2Text;	
-};
-}
Index: sax/source/fastparser/fastattribs.cxx
===================================================================
RCS file: sax/source/fastparser/fastattribs.cxx
diff -N sax/source/fastparser/fastattribs.cxx
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sax/source/fastparser/fastattribs.cxx	1 Mar 2007 17:33:41 -0000	1.1.2.3
@@ -0,0 +1,177 @@
+/*************************************************************************
+ *
+ *  OpenOffice.org - a multi-platform office productivity suite
+ *
+ *  $RCSfile: fastattribs.cxx,v $
+ *
+ *  $Revision: 1.1.2.3 $
+ *
+ *  last change: $Author: cl $ $Date: 2007/03/01 17:33:41 $
+ *
+ *  The Contents of this file are made available subject to
+ *  the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ *    GNU Lesser General Public License Version 2.1
+ *    =============================================
+ *    Copyright 2005 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
+ *
+ ************************************************************************/
+
+#include <algorithm>
+#include <boost/bind.hpp>
+
+#include "fastattribs.hxx"
+
+using ::rtl::OUString;
+using ::rtl::OString;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::xml;
+using namespace ::com::sun::star::xml::sax;
+namespace sax_fastparser
+{
+
+struct UnknownAttribute
+{
+	OUString maNamespaceURL;
+	OString maName;
+	OString maValue;
+
+	UnknownAttribute( const OUString& rNamespaceURL, const OString& rName, const OString& rValue )
+		: maNamespaceURL( rNamespaceURL ), maName( rName ), maValue( rValue ) {}
+
+	UnknownAttribute( const OString& rName, const OString& rValue )
+		: maName( rName ), maValue( rValue ) {}
+
+/*
+	UnknownAttribute( const UnknownAttribute& r )
+		: maNamespaceURL( r.maNamespaceURL ), maName( r.maName ), maValue( r.maValue ) {}
+
+	const UnknownAttribute& operator=( const UnknownAttribute& r )
+	{
+		maNamespaceURL = r.maNamespaceURL;
+		maName = r.maName;
+		maValue = r.maValue;
+		return *this;
+	}
+*/
+	void FillAttribute( Attribute* pAttrib ) const
+	{
+		if( pAttrib )
+		{
+			pAttrib->Name = OStringToOUString( maName, RTL_TEXTENCODING_UTF8 );
+			pAttrib->NamespaceURL = maNamespaceURL;
+			pAttrib->Value = OStringToOUString( maValue, RTL_TEXTENCODING_UTF8 );
+		}
+	}
+};
+
+FastAttributeList::FastAttributeList( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastTokenHandler >& xTokenHandler )
+: mxTokenHandler( xTokenHandler )
+{
+	maLastIter = maAttributes.end();
+}
+
+FastAttributeList::~FastAttributeList()
+{
+}
+
+void FastAttributeList::clear()
+{
+	maAttributes.clear();
+	maUnknownAttributes.clear();
+	maLastIter = maAttributes.end();
+}
+
+void FastAttributeList::add( sal_Int32 nToken, const OString& rValue )
+{
+	maAttributes[nToken] = rValue;
+}
+
+void FastAttributeList::addUnknown( const OUString& rNamespaceURL, const OString& rName, const OString& rValue )
+{
+	maUnknownAttributes.push_back( UnknownAttribute( rNamespaceURL, rName, rValue ) );
+}
+
+void FastAttributeList::addUnknown( const OString& rName, const OString& rValue )
+{
+	maUnknownAttributes.push_back( UnknownAttribute( rName, rValue ) );
+}
+
+// XFastAttributeList
+sal_Bool FastAttributeList::hasAttribute( ::sal_Int32 Token ) throw (RuntimeException)
+{
+	maLastIter = maAttributes.find( Token );
+	return ( maLastIter != maAttributes.end() ) ? sal_True : sal_False;
+}
+
+sal_Int32 FastAttributeList::getValueToken( ::sal_Int32 Token ) throw (SAXException, RuntimeException)
+{
+	if( ( maLastIter == maAttributes.end() ) || ( ( *maLastIter ).first != Token ) )
+		maLastIter = maAttributes.find( Token );
+
+	if( maLastIter == maAttributes.end() )
+		throw SAXException();
+
+	Sequence< sal_Int8 > aSeq( (sal_Int8*)(*maLastIter).second.getStr(), (*maLastIter).second.getLength() ) ;
+	return mxTokenHandler->getTokenFromUTF8( aSeq );
+}
+
+sal_Int32 FastAttributeList::getOptionalValueToken( ::sal_Int32 Token, ::sal_Int32 Default ) throw (RuntimeException)
+{
+	if( ( maLastIter == maAttributes.end() ) || ( ( *maLastIter ).first != Token ) )
+		maLastIter = maAttributes.find( Token );
+
+	if( maLastIter == maAttributes.end() )
+		return Default;
+
+	Sequence< sal_Int8 > aSeq( (sal_Int8*)(*maLastIter).second.getStr(), (*maLastIter).second.getLength() ) ;
+	return mxTokenHandler->getTokenFromUTF8( aSeq );
+}
+
+OUString FastAttributeList::getValue( ::sal_Int32 Token ) throw (SAXException, RuntimeException)
+{
+	if( ( maLastIter == maAttributes.end() ) || ( ( *maLastIter ).first != Token ) )
+		maLastIter = maAttributes.find( Token );
+
+	if( maLastIter == maAttributes.end() )
+		throw SAXException();
+
+	return OStringToOUString( (*maLastIter).second, RTL_TEXTENCODING_UTF8 );
+}
+
+OUString FastAttributeList::getOptionalValue( ::sal_Int32 Token ) throw (RuntimeException)
+{
+	if( ( maLastIter == maAttributes.end() ) || ( ( *maLastIter ).first != Token ) )
+		maLastIter = maAttributes.find( Token );
+
+	OUString aRet;
+	if( maLastIter != maAttributes.end() )
+		aRet = OStringToOUString( (*maLastIter).second, RTL_TEXTENCODING_UTF8 );
+
+	return aRet;
+}
+Sequence< Attribute > FastAttributeList::getUnknownAttributes(  ) throw (RuntimeException)
+{
+	Sequence< Attribute > aSeq( maUnknownAttributes.size() );
+	Attribute* pAttr = aSeq.getArray();
+	std::for_each( maUnknownAttributes.begin(), maUnknownAttributes.end(), bind(&UnknownAttribute::FillAttribute, _1, pAttr++ ) );
+	return aSeq;
+}
+
+}
Index: sax/source/fastparser/fastattribs.hxx
===================================================================
RCS file: sax/source/fastparser/fastattribs.hxx
diff -N sax/source/fastparser/fastattribs.hxx
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sax/source/fastparser/fastattribs.hxx	1 Mar 2007 17:33:42 -0000	1.1.2.2
@@ -0,0 +1,85 @@
+/*************************************************************************
+ *
+ *  OpenOffice.org - a multi-platform office productivity suite
+ *
+ *  $RCSfile: fastattribs.hxx,v $
+ *
+ *  $Revision: 1.1.2.2 $
+ *
+ *  last change: $Author: cl $ $Date: 2007/03/01 17:33:42 $
+ *
+ *  The Contents of this file are made available subject to
+ *  the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ *    GNU Lesser General Public License Version 2.1
+ *    =============================================
+ *    Copyright 2005 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
+ *
+ ************************************************************************/
+
+#ifndef _SAX_FASTATTRIBS_HXX_
+#define _SAX_FASTATTRIBS_HXX_
+
+#include <com/sun/star/xml/sax/XFastAttributeList.hpp>
+#include <com/sun/star/xml/sax/XFastTokenHandler.hpp>
+#include <com/sun/star/xml/Attribute.hpp>
+
+#include <cppuhelper/implbase1.hxx>
+
+#include <map>
+#include <vector>
+
+namespace sax_fastparser
+{
+
+struct UnknownAttribute;
+
+typedef std::map< sal_Int32, ::rtl::OString > FastAttributeMap;
+typedef std::vector< UnknownAttribute > UnknownAttributeList;
+
+class FastAttributeList : public ::cppu::WeakImplHelper1< ::com::sun::star::xml::sax::XFastAttributeList > 
+{
+public:
+	FastAttributeList( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastTokenHandler >& xTokenHandler );
+	virtual ~FastAttributeList();
+
+	void clear();
+	void add( sal_Int32 nToken, const ::rtl::OString& rValue );
+	void addUnknown( const ::rtl::OUString& rNamespaceURL, const ::rtl::OString& rName, const ::rtl::OString& rValue );
+	void addUnknown( const ::rtl::OString& rName, const ::rtl::OString& rValue );
+
+    // XFastAttributeList
+    virtual ::sal_Bool SAL_CALL hasAttribute( ::sal_Int32 Token ) throw (::com::sun::star::uno::RuntimeException);
+    virtual ::sal_Int32 SAL_CALL getValueToken( ::sal_Int32 Token ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+    virtual ::sal_Int32 SAL_CALL getOptionalValueToken( ::sal_Int32 Token, ::sal_Int32 Default ) throw (::com::sun::star::uno::RuntimeException);
+    virtual ::rtl::OUString SAL_CALL getValue( ::sal_Int32 Token ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+    virtual ::rtl::OUString SAL_CALL getOptionalValue( ::sal_Int32 Token ) throw (::com::sun::star::uno::RuntimeException);
+    virtual ::com::sun::star::uno::Sequence< ::com::sun::star::xml::Attribute > SAL_CALL getUnknownAttributes(  ) throw (::com::sun::star::uno::RuntimeException);
+
+private:
+	FastAttributeMap maAttributes;
+	UnknownAttributeList maUnknownAttributes;
+	FastAttributeMap::iterator maLastIter;
+	::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastTokenHandler > mxTokenHandler;
+
+};
+
+}
+
+#endif
Index: sax/source/fastparser/fastparser.cxx
===================================================================
RCS file: sax/source/fastparser/fastparser.cxx
diff -N sax/source/fastparser/fastparser.cxx
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sax/source/fastparser/fastparser.cxx	5 Feb 2007 13:07:46 -0000	1.1.2.3
@@ -0,0 +1,1134 @@
+/*************************************************************************
+ *
+ *  OpenOffice.org - a multi-platform office productivity suite
+ *
+ *  $RCSfile: fastparser.cxx,v $
+ *
+ *  $Revision: 1.1.2.3 $
+ *
+ *  last change: $Author: cl $ $Date: 2007/02/05 13:07:46 $
+ *
+ *  The Contents of this file are made available subject to
+ *  the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ *    GNU Lesser General Public License Version 2.1
+ *    =============================================
+ *    Copyright 2005 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
+ *
+ ************************************************************************/
+
+//#include <stdlib.h>
+//#include <sal/alloca.h>
+
+#include <stack>
+#include <vector>
+#include <hash_map>
+#include <boost/scoped_ptr.hpp>
+#include <boost/shared_ptr.hpp>
+
+#include <osl/diagnose.h>
+#include <rtl/ref.hxx>
+
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/xml/sax/XFastDocumentHandler.hpp>
+#include <com/sun/star/xml/sax/XFastParser.hpp>
+#include <com/sun/star/xml/sax/XFastContextHandler.hpp>
+#include <com/sun/star/xml/sax/SAXParseException.hpp>
+#include <com/sun/star/xml/sax/FastToken.hpp>
+
+#include <cppuhelper/factory.hxx>
+#include <cppuhelper/weak.hxx>
+#include <cppuhelper/implbase2.hxx>
+
+#include "fastattribs.hxx"
+#include "xml2utf.hxx"
+
+#ifdef SYSTEM_EXPAT
+#include <expat.h>
+#else
+#include "expat/xmlparse.h"
+#endif
+
+using ::rtl::OUString;
+using ::rtl::OString;
+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;
+namespace sax_fastparser
+{
+	
+// --------------------------------------------------------------------
+
+struct SaxContextImpl;
+typedef boost::shared_ptr< SaxContextImpl > SaxContextImplPtr;
+
+// --------------------------------------------------------------------
+
+struct SaxContextImpl
+{
+	Reference< XFastContextHandler >	mxContext;
+	sal_uInt32		mnNamespaceCount;
+	sal_Int32		mnElementToken;
+	OUString		maNamespace;
+	OUString		maElementName;
+
+	SaxContextImpl() { mnNamespaceCount = 0; mnElementToken = 0; }
+	SaxContextImpl( const SaxContextImplPtr& p ) { mnNamespaceCount = p->mnNamespaceCount; mnElementToken = p->mnElementToken; maNamespace = p->maNamespace; }
+};
+
+// --------------------------------------------------------------------
+
+// Entity binds all information neede for a single file
+struct Entity
+{
+	InputSource			maStructSource;
+	XML_Parser			mpParser;	
+	sax_expatwrap::XMLFile2UTFConverter maConverter;
+};
+
+// --------------------------------------------------------------------
+
+struct NamespaceDefine
+{
+	OString		maPrefix;
+	sal_Int32	mnToken;
+	OUString	maNamespaceURL;
+
+	NamespaceDefine( const OString& rPrefix, sal_Int32 nToken, const OUString& rNamespaceURL ) : maPrefix( rPrefix ), mnToken( nToken ), maNamespaceURL( rNamespaceURL ) {}
+};
+
+typedef ::std::hash_map< ::rtl::OUString, sal_Int32,
+						 ::rtl::OUStringHash, ::std::equal_to< ::rtl::OUString >
+					   > NamespaceMap;
+
+// --------------------------------------------------------------------
+// FastLocatorImpl
+// --------------------------------------------------------------------
+
+class FastSaxParser;
+
+class FastLocatorImpl : public WeakImplHelper1< XLocator > 
+{
+public:
+	FastLocatorImpl( FastSaxParser *p ) : mpParser(p) {}
+	
+	void dispose() { mpParser = 0; }
+	void checkDispose() throw (RuntimeException) { if( !mpParser ) throw DisposedException(); }
+
+	//XLocator
+    virtual sal_Int32 SAL_CALL getColumnNumber(void) throw (RuntimeException);
+	virtual sal_Int32 SAL_CALL getLineNumber(void) throw (RuntimeException);
+    virtual OUString SAL_CALL getPublicId(void) throw (RuntimeException);
+    virtual OUString SAL_CALL getSystemId(void) throw (RuntimeException);
+
+private:
+	FastSaxParser *mpParser;
+};		
+
+// --------------------------------------------------------------------
+// FastSaxParser
+// --------------------------------------------------------------------
+
+#define IMPLEMENTATION_NAME	"com.sun.star.comp.extensions.xml.sax.FastParser"
+#define SERVICE_NAME		"com.sun.star.xml.sax.FastParser"
+
+
+// This class implements the external Parser interface
+class FastSaxParser : public WeakImplHelper2< XFastParser, XServiceInfo >
+{
+public:	
+	FastSaxParser();
+	~FastSaxParser();
+
+	// The implementation details
+    static Sequence< OUString > 	getSupportedServiceNames_Static(void);
+	static OUString 				getImplementationName_Static();
+
+	// XFastParser
+    virtual void SAL_CALL parseStream( const InputSource& aInputSource ) throw (SAXException, IOException, RuntimeException);
+    virtual void SAL_CALL setFastDocumentHandler( const Reference< XFastDocumentHandler >& Handler ) throw (RuntimeException);
+    virtual void SAL_CALL setTokenHandler( const Reference< XFastTokenHandler >& Handler ) throw (RuntimeException);
+    virtual void SAL_CALL registerNamespace( const OUString& NamespaceURL, sal_Int32 NamespaceToken ) throw (IllegalArgumentException, RuntimeException);
+    virtual void SAL_CALL setErrorHandler( const Reference< XErrorHandler >& Handler ) throw (RuntimeException);
+    virtual void SAL_CALL setEntityResolver( const Reference< XEntityResolver >& Resolver ) throw (RuntimeException);
+    virtual void SAL_CALL setLocale( const Locale& Locale ) throw (RuntimeException);
+
+	// XServiceInfo
+    virtual OUString SAL_CALL getImplementationName(  ) throw (RuntimeException);
+    virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) throw (RuntimeException);
+    virtual Sequence< OUString > SAL_CALL getSupportedServiceNames(  ) throw (RuntimeException);
+
+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 );
+	int static callbackExternalEntityRef( XML_Parser parser, const XML_Char *openEntityNames, const XML_Char *base, const XML_Char *systemId, const XML_Char *publicId);
+
+public:
+	void pushEntity( const struct Entity &entity )	{ vecEntity.push_back( entity ); }
+	void popEntity()								{ vecEntity.pop_back( ); }
+	struct Entity &getEntity()						{ return vecEntity.back(); }
+
+private:
+	void parse();
+
+	sal_Int32 GetToken( const sal_Char* pToken, sal_Int32 nTokenLen = 0 );
+	sal_Int32 GetTokenWithPrefix( const sal_Char*pPrefix, int nPrefixLen, const sal_Char* pName, int nNameLen ) throw (SAXException);
+	OUString  GetNamespaceURL( const sal_Char*pPrefix, int nPrefixLen ) throw (SAXException);
+	sal_Int32 GetNamespaceToken( const OUString& rNamespaceURL );
+	sal_Int32 GetTokenWithNamespaceURL( const OUString& rNamespaceURL, const sal_Char* pName, int nNameLen );
+	void DefineNamespace( const OString& rPrefix, const sal_Char* pNamespaceURL );
+	sal_Int32 CreateCustomToken( const sal_Char* pToken, int len = 0 );
+
+	void pushContext();
+	void popContext();
+
+	void splitName( const XML_Char *pwName, const XML_Char *&rpPrefix, sal_Int32 &rPrefixLen, const XML_Char *&rpName, sal_Int32 &rNameLen );
+
+private:
+	Mutex				maMutex;
+
+	Reference< XFastDocumentHandler >		mxDocumentHandler;
+	Reference< XFastTokenHandler >			mxTokenHandler;
+	Reference< XErrorHandler >				mxErrorHandler;
+	Reference< XEntityResolver >			mxEntityResolver;
+	rtl::Reference < FastLocatorImpl >		mxDocumentLocator;
+
+	rtl::Reference < FastAttributeList >	mxAttributes;
+
+	// External entity stack 
+	vector<struct Entity> 	vecEntity;
+
+	// Exception cannot be thrown through the C-XmlParser (possible resource leaks), 
+	// therefor the maSavedException must be saved somewhere.
+	Any				 	maSavedException;
+	sal_Bool 			mbExceptionWasThrown;
+
+	Locale				maLocale;
+
+	std::stack< SaxContextImplPtr >	maContextStack;
+	std::vector< boost::shared_ptr< NamespaceDefine > >	maNamespaceDefines;
+	NamespaceMap maNamespaceMap;
+};
+
+//--------------------------------------
+// the extern interface 
+//---------------------------------------
+Reference< XInterface > SAL_CALL FastSaxParser_CreateInstance( const Reference< XMultiServiceFactory  >  & ) throw(Exception)
+{	
+	FastSaxParser *p = new FastSaxParser;
+	return Reference< XInterface > ( (OWeakObject * ) p );
+}
+
+Sequence< OUString > FastSaxParser::getSupportedServiceNames_Static(void)
+{
+	Sequence<OUString> aRet(1);
+	aRet.getArray()[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(SERVICE_NAME) );
+	return aRet;
+}
+
+//---------------------------------------------
+// the implementation part
+//---------------------------------------------
+
+extern "C"
+{
+    static void call_callbackStartElement(void *userData, const XML_Char *name , const XML_Char **atts)
+    {
+        FastSaxParser::callbackStartElement(userData,name,atts);
+    }
+	static void call_callbackEndElement(void *userData, const XML_Char *name)
+    {
+        FastSaxParser::callbackEndElement(userData,name);
+    }
+	static void call_callbackCharacters( void *userData , const XML_Char *s , int nLen )
+    {
+        FastSaxParser::callbackCharacters(userData,s,nLen);
+    }
+	static int call_callbackExternalEntityRef(XML_Parser parser,
+					    					  const XML_Char *openEntityNames,
+                                              const XML_Char *base,
+                                              const XML_Char *systemId,
+                                              const XML_Char *publicId)
+    {
+        return FastSaxParser::callbackExternalEntityRef(parser,openEntityNames,base,systemId,publicId);
+    }
+}
+
+// --------------------------------------------------------------------
+// FastLocatorImpl implementation
+// --------------------------------------------------------------------
+
+sal_Int32 SAL_CALL FastLocatorImpl::getColumnNumber(void) throw (RuntimeException)
+{
+	checkDispose();
+	return XML_GetCurrentColumnNumber( mpParser->getEntity().mpParser );
+}
+
+// --------------------------------------------------------------------
+
+sal_Int32 SAL_CALL FastLocatorImpl::getLineNumber(void) throw (RuntimeException)
+{
+	checkDispose();
+	return XML_GetCurrentLineNumber( mpParser->getEntity().mpParser );
+}
+
+// --------------------------------------------------------------------
+
+OUString SAL_CALL FastLocatorImpl::getPublicId(void) throw (RuntimeException)
+{
+	checkDispose();
+	return mpParser->getEntity().maStructSource.sPublicId;
+}
+// --------------------------------------------------------------------
+
+OUString SAL_CALL FastLocatorImpl::getSystemId(void) throw (RuntimeException)
+{
+	checkDispose();
+	return mpParser->getEntity().maStructSource.sSystemId;
+}
+
+// --------------------------------------------------------------------
+// FastSaxParser implementation
+// --------------------------------------------------------------------
+
+FastSaxParser::FastSaxParser(  )
+{
+	mxDocumentLocator.set( new FastLocatorImpl( this ) );
+	 
+	// performance-Improvment. Reference is needed when calling the startTag callback.
+	// Handing out the same object with every call is allowed (see sax-specification)
+	mxAttributes.set( new FastAttributeList( mxTokenHandler ) );
+	
+	mbExceptionWasThrown = sal_False;
+}
+
+// --------------------------------------------------------------------
+
+FastSaxParser::~FastSaxParser()
+{
+	if( mxDocumentLocator.is() )
+		mxDocumentLocator->dispose();
+}
+
+// --------------------------------------------------------------------
+
+void FastSaxParser::pushContext()
+{
+	bool bRootContext = false;
+	SaxContextImplPtr p;
+	if( maContextStack.empty() )
+	{
+		p.reset( new SaxContextImpl() );
+		bRootContext = true;
+	}
+	else
+	{ 
+		p.reset( new SaxContextImpl( maContextStack.top() ) );
+	}
+	maContextStack.push( p );
+
+	if( bRootContext )
+		DefineNamespace( OString("xml"), "http://www.w3.org/XML/1998/namespace");
+}
+
+// --------------------------------------------------------------------
+
+void FastSaxParser::popContext()
+{
+	OSL_ENSURE( !maContextStack.empty(), "sax::FastSaxParser::popContext(), pop without push?" );
+	if( !maContextStack.empty() )
+		maContextStack.pop();
+}
+
+// --------------------------------------------------------------------
+
+void FastSaxParser::DefineNamespace( const OString& rPrefix, const sal_Char* pNamespaceURL )
+{
+	OSL_ENSURE( !maContextStack.empty(), "sax::FastSaxParser::DefineNamespace(), I need a context!" );
+	if( !maContextStack.empty() )
+	{
+		sal_uInt32 nOffset = maContextStack.top()->mnNamespaceCount++;
+
+		if( maNamespaceDefines.size() <= nOffset )
+			maNamespaceDefines.resize( maNamespaceDefines.size() + 64 );
+
+		const OUString aNamespaceURL( pNamespaceURL, strlen( pNamespaceURL ), RTL_TEXTENCODING_UTF8 );
+		maNamespaceDefines[nOffset].reset( new NamespaceDefine( rPrefix, GetNamespaceToken( aNamespaceURL ), aNamespaceURL ) );
+	}
+}
+
+// --------------------------------------------------------------------
+
+sal_Int32 FastSaxParser::GetToken( const sal_Char* pToken, sal_Int32 nLen /* = 0 */ )
+{
+	if( !nLen )
+		nLen = strlen( pToken );
+
+	Sequence< sal_Int8 > aSeq( (sal_Int8*)pToken, nLen );
+
+	return mxTokenHandler->getTokenFromUTF8( aSeq );
+}
+
+// --------------------------------------------------------------------
+
+sal_Int32 FastSaxParser::GetTokenWithPrefix( const sal_Char*pPrefix, int nPrefixLen, const sal_Char* pName, int nNameLen ) throw (SAXException)
+{
+	sal_Int32 nNamespaceToken = FastToken::DONTKNOW;
+
+	sal_uInt32 nNamespace = maContextStack.top()->mnNamespaceCount;
+	while( nNamespace-- )
+	{
+		const OString& rPrefix( maNamespaceDefines[nNamespace]->maPrefix );
+		if( (rPrefix.getLength() == nPrefixLen) &&
+			(strncmp( rPrefix.getStr(), pPrefix, nPrefixLen ) == 0 ) )
+		{
+			nNamespaceToken = maNamespaceDefines[nNamespace]->mnToken;
+			break;
+		}
+
+		if( !nNamespace )
+			throw SAXException(); // prefix that has no defined namespace url
+	}
+
+	if( nNamespaceToken != FastToken::DONTKNOW )
+	{
+		sal_Int32 nNameToken = GetToken( pName, nNameLen );
+		if( nNameToken != FastToken::DONTKNOW )
+			return nNamespaceToken | nNameToken;
+	}
+
+	return FastToken::DONTKNOW;
+}
+
+// --------------------------------------------------------------------
+
+sal_Int32 FastSaxParser::GetNamespaceToken( const OUString& rNamespaceURL )
+{
+	NamespaceMap::iterator aIter( maNamespaceMap.find( rNamespaceURL ) );
+	if( aIter != maNamespaceMap.end() )
+		return (*aIter).second;
+	else
+		return FastToken::DONTKNOW;
+}
+
+// --------------------------------------------------------------------
+
+OUString FastSaxParser::GetNamespaceURL( const sal_Char*pPrefix, int nPrefixLen ) throw(SAXException)
+{
+	if( pPrefix && !maContextStack.empty() )
+	{
+		sal_uInt32 nNamespace = maContextStack.top()->mnNamespaceCount;
+		while( nNamespace-- )
+		{
+			const OString& rPrefix( maNamespaceDefines[nNamespace]->maPrefix );
+			if( (rPrefix.getLength() == nPrefixLen) &&
+				(strncmp( rPrefix.getStr(), pPrefix, nPrefixLen ) == 0 ) )
+			{
+				return maNamespaceDefines[nNamespace]->maNamespaceURL;
+			}
+		}
+	}
+
+	throw SAXException(); // prefix that has no defined namespace url
+}
+
+// --------------------------------------------------------------------
+
+sal_Int32 FastSaxParser::GetTokenWithNamespaceURL( const OUString& rNamespaceURL, const sal_Char* pName, int nNameLen )
+{
+	sal_Int32 nNamespaceToken = GetNamespaceToken( rNamespaceURL );
+
+	if( nNamespaceToken != FastToken::DONTKNOW )
+	{
+		sal_Int32 nNameToken = GetToken( pName, nNameLen );
+		if( nNameToken != FastToken::DONTKNOW )
+			return nNamespaceToken | nNameToken;
+	}
+
+	return FastToken::DONTKNOW;
+}
+
+// --------------------------------------------------------------------
+
+void FastSaxParser::splitName( const XML_Char *pwName, const XML_Char *&rpPrefix, sal_Int32 &rPrefixLen, const XML_Char *&rpName, sal_Int32 &rNameLen )
+{
+	XML_Char *p;
+	for( p = const_cast< XML_Char* >( pwName ), rNameLen = 0, rPrefixLen = 0; *p; p++ )
+	{
+		if( *p == ':' )
+		{
+			rPrefixLen = p - pwName;
+			rNameLen = 0;
+		}
+		else
+		{
+			rNameLen++;
+		}
+	}
+	if( rPrefixLen )
+	{
+		rpPrefix = pwName;
+		rpName = &pwName[ rPrefixLen + 1 ];
+	}
+	else
+	{
+		rpPrefix = 0;
+		rpName = pwName;
+	}
+}
+
+/***************
+*
+* parseStream does Parser-startup initializations. The FastSaxParser::parse() method does
+* the file-specific initialization work. (During a parser run, external files may be opened)
+* 
+****************/
+void FastSaxParser::parseStream( const InputSource& maStructSource)	throw (SAXException, IOException, RuntimeException)
+{
+	// Only one text at one time
+	MutexGuard guard( maMutex );
+	
+	struct Entity entity;
+	entity.maStructSource = maStructSource;
+
+	if( ! entity.maStructSource.aInputStream.is() )
+	{
+		throw SAXException( OUString::createFromAscii( "No input source" ), Reference< XInterface > () , Any() );
+	}
+
+	entity.maConverter.setInputStream( entity.maStructSource.aInputStream );
+	if( entity.maStructSource.sEncoding.getLength() )
+	{
+		entity.maConverter.setEncoding(	OUStringToOString( entity.maStructSource.sEncoding , RTL_TEXTENCODING_ASCII_US ) );	
+	}
+	
+	// create parser with proper encoding
+	entity.mpParser = XML_ParserCreate( 0 );
+	if( ! entity.mpParser )
+	{
+		throw SAXException( OUString::createFromAscii( "Couldn't create parser" ), Reference< XInterface > (), Any() );
+	}
+
+	// set all necessary C-Callbacks 
+	XML_SetUserData( entity.mpParser , this );
+	XML_SetElementHandler( 	entity.mpParser , 
+							call_callbackStartElement , 
+							call_callbackEndElement );
+	XML_SetCharacterDataHandler( entity.mpParser , call_callbackCharacters );
+	XML_SetExternalEntityRefHandler( 	entity.mpParser, 
+										call_callbackExternalEntityRef);	
+
+	maSavedException.clear();
+	pushEntity( entity );
+	try
+	{
+		// start the document
+		if( mxDocumentHandler.is() )
+		{
+			Reference< XLocator > xLoc( mxDocumentLocator.get() );
+			mxDocumentHandler->setDocumentLocator( xLoc );
+			mxDocumentHandler->startDocument();
+		}
+
+		parse();
+
+		// finish document
+		if( mxDocumentHandler.is() )
+		{
+			mxDocumentHandler->endDocument();	
+		}
+	}
+	catch( SAXException & )
+	{
+		popEntity();
+		XML_ParserFree( entity.mpParser );
+  		throw;
+	}
+	catch( IOException & )
+	{
+		popEntity();
+		XML_ParserFree( entity.mpParser );
+		throw;
+	}
+	catch( RuntimeException & )
+	{
+		popEntity();
+		XML_ParserFree( entity.mpParser );
+		throw;
+	}
+
+	popEntity();
+	XML_ParserFree( entity.mpParser );
+}
+    																			
+void FastSaxParser::setFastDocumentHandler( const Reference< XFastDocumentHandler >& Handler ) throw (RuntimeException)
+{
+	mxDocumentHandler = Handler;
+}
+
+void SAL_CALL FastSaxParser::setTokenHandler( const Reference< XFastTokenHandler >& Handler ) throw (RuntimeException)
+{
+	mxTokenHandler = Handler;
+	mxAttributes.set( new FastAttributeList( mxTokenHandler ) );
+}
+
+void SAL_CALL FastSaxParser::registerNamespace( const OUString& NamespaceURL, sal_Int32 NamespaceToken ) throw (IllegalArgumentException, RuntimeException)
+{
+	if( NamespaceToken >= FastToken::NAMESPACE )
+	{
+		if( GetNamespaceToken( NamespaceURL ) == FastToken::DONTKNOW )
+		{
+			maNamespaceMap[ NamespaceURL ] = NamespaceToken;
+			return;
+		}
+	}
+	throw IllegalArgumentException();
+}
+
+void FastSaxParser::setErrorHandler(const Reference< XErrorHandler > & Handler) throw (RuntimeException)
+{
+	mxErrorHandler = Handler;
+}
+
+void FastSaxParser::setEntityResolver(const Reference < XEntityResolver > & Resolver) throw (RuntimeException)
+{
+	mxEntityResolver = Resolver;
+}
+
+void FastSaxParser::setLocale( const Locale & Locale ) throw (RuntimeException)
+{
+	maLocale = Locale;	
+}
+
+OUString FastSaxParser::getImplementationName_Static()
+{
+	return OUString::createFromAscii( IMPLEMENTATION_NAME );
+}
+
+// XServiceInfo
+OUString FastSaxParser::getImplementationName() throw (RuntimeException)
+{
+    return OUString::createFromAscii( IMPLEMENTATION_NAME );
+}
+
+// XServiceInfo
+sal_Bool FastSaxParser::supportsService(const OUString& ServiceName) throw (RuntimeException)
+{
+    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 > FastSaxParser::getSupportedServiceNames(void) throw (RuntimeException)
+{
+    
+    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 FastSaxParser::parse( )
+{
+	const int nBufSize = 16*1024;
+
+	int nRead = nBufSize;
+	Sequence< sal_Int8 > seqOut(nBufSize);
+
+	while( nRead )
+	{
+		nRead = getEntity().maConverter.readAndConvert( seqOut, nBufSize );
+
+		if( ! nRead )
+		{				
+			XML_Parse( getEntity().mpParser, ( const char * ) seqOut.getArray(), 0 , 1 );	
+			break;
+		}		
+
+		sal_Bool bContinue = ( XML_Parse( getEntity().mpParser, (const char *) seqOut.getArray(), nRead, 0 ) != 0 );
+		
+		if( !bContinue || mbExceptionWasThrown )
+		{
+			// Error during parsing !
+			XML_Error xmlE = XML_GetErrorCode( getEntity().mpParser );
+			OUString sSystemId = mxDocumentLocator->getSystemId();
+			sal_Int32 nLine = mxDocumentLocator->getLineNumber();
+
+			SAXParseException aExcept( 	
+				getErrorMessage(xmlE , sSystemId, nLine) , 
+				Reference< XInterface >(), 
+				Any( &maSavedException , getCppuType( &maSavedException) ),
+				mxDocumentLocator->getPublicId(),
+				mxDocumentLocator->getSystemId(),
+				mxDocumentLocator->getLineNumber(),
+				mxDocumentLocator->getColumnNumber()
+				);
+			
+			if( mxErrorHandler.is() )
+			{
+				// error handler is set, so the handler may throw the maSavedException
+				mxErrorHandler->fatalError( Any( aExcept ) );
+			}
+
+			// Error handler has not thrown an maSavedException, but parsing cannot go on,
+			// so an maSavedException MUST be thrown.
+			throw aExcept;
+		}
+	}
+}
+
+//------------------------------------------
+//
+// The C-Callbacks
+//
+//-----------------------------------------
+void FastSaxParser::callbackStartElement( void *pvThis, const XML_Char *pwName, const XML_Char **awAttributes )
+{
+ 	FastSaxParser *pThis = (FastSaxParser*)pvThis;
+
+	Reference< XFastContextHandler > xParentContext;
+	if( !pThis->maContextStack.empty() )
+	{
+		xParentContext = pThis->maContextStack.top()->mxContext;
+		if( !xParentContext.is() )
+		{
+			// we ignore current elements, so no processing needed
+			pThis->pushContext();
+			return;
+		}
+	}
+
+	pThis->pushContext();
+
+	pThis->mxAttributes->clear();
+
+	// create attribute map and process namespace instructions
+	int i = 0;
+	sal_Int32 nNameLen, nPrefixLen;
+	const XML_Char *pName;
+	const XML_Char *pPrefix;
+	for( ; awAttributes[i]; i += 2 )
+	{
+		OSL_ASSERT( awAttributes[i+1] );
+
+		pThis->splitName( awAttributes[i], pPrefix, nPrefixLen, pName, nNameLen );
+		if( nPrefixLen )
+		{
+			if( (nPrefixLen == 5) && (strncmp( pPrefix, "xmlns", 5 ) == 0) )
+			{
+				pThis->DefineNamespace( OString( pName, nNameLen ), awAttributes[i+1] );
+			}
+			else
+			{
+				const sal_Int32 nAttributeToken = pThis->GetTokenWithPrefix( pPrefix, nPrefixLen, pName, nNameLen );
+				if( nAttributeToken != FastToken::DONTKNOW )
+				{
+					pThis->mxAttributes->add( nAttributeToken, OString( awAttributes[i+1] ) );
+				}
+				else
+				{
+					pThis->mxAttributes->addUnknown( pThis->GetNamespaceURL( pPrefix, nPrefixLen ), OString( pName, nNameLen ), OString( awAttributes[i+1] ) );
+				}
+			}
+		}
+		else
+		{
+			if( (nNameLen == 5) && (strcmp( pName, "xmlns" ) == 0) )
+			{
+				// namespace of the element found
+				pThis->maContextStack.top()->maNamespace = OUString( awAttributes[i+1], strlen( awAttributes[i+1] ), RTL_TEXTENCODING_UTF8 );
+			}
+			else
+			{
+				const sal_Int32 nAttributeToken = pThis->GetToken( pName, nNameLen );
+				if( nAttributeToken != FastToken::DONTKNOW )
+				{
+					pThis->mxAttributes->add( nAttributeToken, OString( awAttributes[i+1] ) );
+				}
+				else
+				{
+					pThis->mxAttributes->addUnknown( OString( pName, nNameLen ), OString( awAttributes[i+1] ) );
+				}
+			}
+		}
+	}
+
+	sal_Int32 nElementToken;
+	pThis->splitName( pwName, pPrefix, nPrefixLen, pName, nNameLen );
+	if( nPrefixLen )
+	{
+		nElementToken = pThis->GetTokenWithPrefix( pPrefix, nPrefixLen, pName, nNameLen );
+	}
+	else if( pThis->maContextStack.top()->maNamespace.getLength() )
+	{
+		nElementToken = pThis->GetTokenWithNamespaceURL( pThis->maContextStack.top()->maNamespace, pName, nNameLen );
+	}
+	else
+	{
+		nElementToken = pThis->GetToken( pName );
+	}
+	pThis->maContextStack.top()->mnElementToken = nElementToken;
+	
+	try
+	{
+		Reference< XFastAttributeList > xAttr( pThis->mxAttributes.get() );
+		Reference< XFastContextHandler > xContext;
+		if( nElementToken == FastToken::DONTKNOW )
+		{
+			if( nPrefixLen )
+			{
+				pThis->maContextStack.top()->maNamespace = pThis->GetNamespaceURL( pPrefix, nPrefixLen );
+			}
+
+			const OUString aNamespace( pThis->maContextStack.top()->maNamespace );
+			const OUString aElementName( pPrefix, nPrefixLen, RTL_TEXTENCODING_UTF8 );
+			pThis->maContextStack.top()->maElementName = aElementName;
+
+			if( xParentContext.is() )
+				xContext = xParentContext->createUnknownChildContext( aNamespace, aElementName, xAttr );
+			else
+				xContext = pThis->mxDocumentHandler->createUnknownChildContext( aNamespace, aElementName, xAttr );
+
+			if( xContext.is() )
+			{
+				pThis->maContextStack.top()->mxContext = xContext;
+				xContext->startUnknownElement( aNamespace, aElementName, xAttr );
+			}
+		}
+		else
+		{
+			if( xParentContext.is() )
+				xContext = xParentContext->createFastChildContext( nElementToken, xAttr );
+			else
+				xContext = pThis->mxDocumentHandler->createFastChildContext( nElementToken, xAttr );
+
+
+			if( xContext.is() )
+			{
+				pThis->maContextStack.top()->mxContext = xContext;
+				xContext->startFastElement( nElementToken, xAttr );
+			}
+		}
+	}
+	catch( Exception& e )
+	{
+		pThis->maSavedException <<= e;
+	}
+}
+
+void FastSaxParser::callbackEndElement( void *pvThis , const XML_Char *  )
+{
+	FastSaxParser *pThis = (FastSaxParser*)pvThis;
+
+	if( !pThis->maContextStack.empty() )
+	{
+		SaxContextImplPtr pContext( pThis->maContextStack.top() );
+		const Reference< XFastContextHandler >& xContext( pContext->mxContext );
+		if( xContext.is() ) try
+		{
+			sal_Int32 nElementToken = pContext->mnElementToken;
+			if( nElementToken != FastToken::DONTKNOW )
+			{
+				xContext->endFastElement( nElementToken );
+			}
+			else
+			{
+				xContext->endUnknownElement( pContext->maNamespace, pContext->maElementName );
+			}
+		}
+		catch( Exception& e )
+		{
+			pThis->maSavedException <<= e;
+		}
+
+		pThis->popContext();
+	}
+	else
+	{
+		OSL_ENSURE( false, "no context on sax::FastSaxParser::callbackEndElement() ??? ");
+	}
+}
+
+
+void FastSaxParser::callbackCharacters( void *pvThis , const XML_Char *s , int nLen )
+{
+	FastSaxParser *pThis = (FastSaxParser*)pvThis;
+
+	const Reference< XFastContextHandler >& xContext( pThis->maContextStack.top()->mxContext );
+	if( xContext.is() ) try
+	{
+		xContext->characters( OUString( s, nLen, RTL_TEXTENCODING_UTF8 ) );
+	}
+	catch( Exception& e )
+	{
+		pThis->maSavedException <<= e;
+	}
+}		      					
+
+int FastSaxParser::callbackExternalEntityRef( XML_Parser parser,
+                                                    const XML_Char *context,
+                                                    const XML_Char * /*base*/,
+                                                    const XML_Char *systemId,
+                                                    const XML_Char *publicId)
+{
+	bool bOK = true;
+	InputSource source;
+	FastSaxParser *pImpl = ((FastSaxParser*)XML_GetUserData( parser ));
+
+	struct Entity entity;
+	
+	if( pImpl->mxEntityResolver.is() ) {
+		try
+		{
+	    	entity.maStructSource = pImpl->mxEntityResolver->resolveEntity(
+				OUString( publicId, strlen( publicId ), RTL_TEXTENCODING_UTF8 ) ,
+				OUString( systemId, strlen( systemId ), RTL_TEXTENCODING_UTF8 ) );
+	    }
+	    catch( SAXParseException & e )
+		{
+	    	pImpl->maSavedException <<= e;
+	    	bOK = false;
+	    }
+	    catch( SAXException & e )
+		{
+	    	pImpl->maSavedException <<= SAXParseException(
+				e.Message , e.Context , e.WrappedException ,
+				pImpl->mxDocumentLocator->getPublicId(),
+				pImpl->mxDocumentLocator->getSystemId(),
+				pImpl->mxDocumentLocator->getLineNumber(),
+				pImpl->mxDocumentLocator->getColumnNumber() );
+			bOK = false;
+	    }
+	}
+
+	if( entity.maStructSource.aInputStream.is() )
+	{
+		entity.mpParser = XML_ExternalEntityParserCreate( parser , context, 0 );
+		if( ! entity.mpParser )
+		{
+			return false;
+		}
+
+		entity.maConverter.setInputStream( entity.maStructSource.aInputStream );
+		pImpl->pushEntity( entity );
+		try
+		{
+			pImpl->parse();
+		}
+		catch( SAXParseException & e )
+		{
+			pImpl->maSavedException <<= e;
+			bOK = false;
+		}
+		catch( IOException &e )
+		{
+			SAXException aEx;
+			aEx.WrappedException <<= e;
+			pImpl->maSavedException <<= aEx;
+			bOK = false;
+		}
+		catch( RuntimeException &e )
+		{
+			SAXException aEx;
+			aEx.WrappedException <<= e;
+			pImpl->maSavedException <<= aEx;
+			bOK = false;
+		}
+
+		pImpl->popEntity();
+		
+		XML_ParserFree( entity.mpParser );
+	}
+
+	return bOK;
+}
+
+}
+
+using namespace sax_fastparser;
+
+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 ) );
+				
+			return sal_True;
+		}
+		catch (InvalidRegistryException &)
+		{
+			OSL_ENSURE( 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,
+										FastSaxParser_CreateInstance,
+										FastSaxParser::getSupportedServiceNames_Static() );
+		}
+
+		if (xRet.is())
+		{
+			xRet->acquire();
+			pRet = xRet.get();
+		}
+	}
+	
+	return pRet;
+}
+		
+
+}
Index: sax/source/fastparser/makefile.mk
===================================================================
RCS file: sax/source/fastparser/makefile.mk
diff -N sax/source/fastparser/makefile.mk
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sax/source/fastparser/makefile.mk	2 Mar 2007 11:24:30 -0000	1.1.2.3
@@ -0,0 +1,81 @@
+#*************************************************************************
+#
+#   OpenOffice.org - a multi-platform office productivity suite
+#
+#   $RCSfile: makefile.mk,v $
+#
+#   $Revision: 1.1.2.3 $
+#
+#   last change: $Author: dr $ $Date: 2007/03/02 11:24:30 $
+#
+#   The Contents of this file are made available subject to
+#   the terms of GNU Lesser General Public License Version 2.1.
+#
+#
+#     GNU Lesser General Public License Version 2.1
+#     =============================================
+#     Copyright 2005 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
+#
+#*************************************************************************
+PRJ=..$/..
+
+PRJNAME=sax
+TARGET=fastsax.uno
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE :  settings.mk
+DLLPRE =
+
+.IF "$(SYSTEM_ZLIB)" == "YES"
+CFLAGS+=-DSYSTEM_ZLIB
+.ENDIF
+
+.IF "$(SYSTEM_EXPAT)" == "YES"
+CFLAGS+=-DSYSTEM_EXPAT
+.ENDIF
+
+#-----------------------------------------------------------
+
+SLOFILES =\
+		$(SLO)$/fastparser.obj\
+		$(SLO)$/fastattribs.obj\
+		$(SLO)$/xml2utf.obj
+
+SHL1TARGET= $(TARGET)
+SHL1IMPLIB= i$(TARGET)
+
+SHL1STDLIBS= \
+		$(SALLIB)  \
+		$(CPPULIB) \
+		$(CPPUHELPERLIB)\
+		$(EXPATASCII3RDLIB)
+
+SHL1DEPN=
+SHL1VERSIONMAP=	$(SOLARENV)$/src$/component.map
+SHL1LIBS=		$(SLB)$/$(TARGET).lib
+SHL1DEF=		$(MISC)$/$(SHL1TARGET).def
+DEF1NAME=		$(SHL1TARGET)
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE :	target.mk
+
+
+
Index: sax/source/tools/converter.cxx
===================================================================
RCS file: sax/source/tools/converter.cxx
diff -N sax/source/tools/converter.cxx
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sax/source/tools/converter.cxx	10 May 2007 15:50:14 -0000	1.1.2.8
@@ -0,0 +1,1603 @@
+/*************************************************************************
+ *
+ *  OpenOffice.org - a multi-platform office productivity suite
+ *
+ *  $RCSfile: converter.cxx,v $
+ *
+ *  $Revision: 1.1.2.8 $
+ *
+ *  last change: $Author: hub $ $Date: 2007/05/10 15:50:14 $
+ *
+ *  The Contents of this file are made available subject to
+ *  the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ *    GNU Lesser General Public License Version 2.1
+ *    =============================================
+ *    Copyright 2005 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
+ *
+ ************************************************************************/
+
+
+#ifndef _COM_SUN_STAR_I18N_UNICODETYPE_HPP_
+#include <com/sun/star/i18n/UnicodeType.hpp>
+#endif
+#ifndef _COM_SUN_STAR_UTIL_DATETIME_HPP_
+#include <com/sun/star/util/DateTime.hpp>
+#endif
+#ifndef _COM_SUN_STAR_UTIL_DATE_HPP_
+#include <com/sun/star/util/Date.hpp>
+#endif
+#ifndef _COM_SUN_STAR_UTIL_TIME_HPP_
+#include <com/sun/star/util/Time.hpp>
+#endif
+#ifndef _COM_SUN_STAR_UNO_SEQUENCE_HXX_
+#include <com/sun/star/uno/Sequence.hxx>
+#endif
+
+#ifndef _RTL_USTRBUF_HXX_
+#include <rtl/ustrbuf.hxx>
+#endif
+#ifndef INCLUDED_RTL_MATH_HXX
+#include <rtl/math.hxx>
+#endif
+
+#ifndef _SAX_CONVERTER_HXX
+#include "sax/tools/converter.hxx"
+#endif
+
+using namespace rtl;
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::util;
+//using namespace com::sun::star::text;
+//using namespace com::sun::star::style;
+using namespace ::com::sun::star::i18n;
+
+namespace sax {
+
+static const sal_Char* gpsMM = "mm";
+static const sal_Char* gpsCM = "cm";
+static const sal_Char* gpsPT = "pt";
+static const sal_Char* gpsINCH = "in";
+static const sal_Char* gpsPC = "pc";
+
+const sal_Int8 XML_MAXDIGITSCOUNT_TIME = 11;
+const sal_Int8 XML_MAXDIGITSCOUNT_DATETIME = 6;
+#define XML_NULLDATE "NullDate"
+
+/** convert string to measure using optional min and max values*/
+bool Converter::convertMeasure(	sal_Int32& rValue,
+								const OUString& rString,
+								sal_Int16 nTargetUnit /* = MeasureUnit::MM_100TH */,
+								sal_Int32 nMin /* = SAL_MIN_INT32 */,
+								sal_Int32 nMax /* = SAL_MAX_INT32 */ )
+{
+    bool bNeg = false;
+    double nVal = 0;
+
+    sal_Int32 nPos = 0L;
+    sal_Int32 nLen = rString.getLength();
+
+    // skip white space
+    while( (nPos < nLen) && (rString[nPos] <= sal_Unicode(' ')) )
+        nPos++;
+
+    if( nPos < nLen && sal_Unicode('-') == rString[nPos] )
+    {
+        bNeg = true;
+        nPos++;
+    }
+
+    // get number
+    while( nPos < nLen &&
+           sal_Unicode('0') <= rString[nPos] &&
+           sal_Unicode('9') >= rString[nPos] )
+    {
+        // TODO: check overflow!
+        nVal *= 10;
+        nVal += (rString[nPos] - sal_Unicode('0'));
+        nPos++;
+    }
+    double nDiv = 1.;
+    if( nPos < nLen && sal_Unicode('.') == rString[nPos] )
+    {
+        nPos++;
+
+        while( nPos < nLen &&
+               sal_Unicode('0') <= rString[nPos] &&
+               sal_Unicode('9') >= rString[nPos] )
+        {
+            // TODO: check overflow!
+            nDiv *= 10;
+            nVal += ( ((double)(rString[nPos] - sal_Unicode('0'))) / nDiv );
+            nPos++;
+        }
+    }
+
+    // skip white space
+    while( (nPos < nLen) && (rString[nPos] <= sal_Unicode(' ')) )
+        nPos++;
+
+    if( nPos < nLen )
+    {
+
+		if( MeasureUnit::PERCENT == nTargetUnit )
+        {
+            if( sal_Unicode('%') != rString[nPos] )
+                return false;
+        }
+		else if( MeasureUnit::PIXEL == nTargetUnit )
+        {
+            if( nPos + 1 >= nLen ||
+                (sal_Unicode('p') != rString[nPos] &&
+                 sal_Unicode('P') != rString[nPos])||
+                (sal_Unicode('x') != rString[nPos+1] &&
+                 sal_Unicode('X') != rString[nPos+1]) )
+                return false;
+        }
+        else
+        {
+            OSL_ENSURE( MeasureUnit::TWIP == nTargetUnit || MeasureUnit::POINT == nTargetUnit ||
+                        MeasureUnit::MM_100TH == nTargetUnit || MeasureUnit::MM_10TH == nTargetUnit, "unit is not supported");
+            const sal_Char *aCmpsL[2] = { 0, 0 };
+            const sal_Char *aCmpsU[2] = { 0, 0 };
+            double aScales[2] = { 1., 1. };
+
+            if( MeasureUnit::TWIP == nTargetUnit )
+            {
+                switch( rString[nPos] )
+                {
+                case sal_Unicode('c'):
+                case sal_Unicode('C'):
+                    aCmpsL[0] = "cm";
+                    aCmpsU[0] = "CM";
+                    aScales[0] = (72.*20.)/2.54; // twip
+                    break;
+                case sal_Unicode('i'):
+                case sal_Unicode('I'):
+                    aCmpsL[0] = "in";
+                    aCmpsU[0] = "IN";
+                    aScales[0] = 72.*20.; // twip
+                    break;
+                case sal_Unicode('m'):
+                case sal_Unicode('M'):
+                    aCmpsL[0] = "mm";
+                    aCmpsU[0] = "MM";
+                    aScales[0] = (72.*20.)/25.4; // twip
+                    break;
+                case sal_Unicode('p'):
+                case sal_Unicode('P'):
+                    aCmpsL[0] = "pt";
+                    aCmpsU[0] = "PT";
+                    aScales[0] = 20.; // twip
+
+                    aCmpsL[1] = "pc";
+                    aCmpsU[1] = "PC";
+                    aScales[1] = 12.*20.; // twip
+                    break;
+                }
+            }
+            else if( MeasureUnit::MM_100TH == nTargetUnit || MeasureUnit::MM_10TH == nTargetUnit )
+            {
+				double nScaleFactor = (MeasureUnit::MM_100TH == nTargetUnit) ? 100.0 : 10.0;
+                switch( rString[nPos] )
+                {
+                case sal_Unicode('c'):
+                case sal_Unicode('C'):
+                    aCmpsL[0] = "cm";
+                    aCmpsU[0] = "CM";
+                    aScales[0] = 10.0 * nScaleFactor; // mm/100
+                    break;
+                case sal_Unicode('i'):
+                case sal_Unicode('I'):
+                    aCmpsL[0] = "in";
+                    aCmpsU[0] = "IN";
+                    aScales[0] = 1000.*2.54; // mm/100
+                    break;
+                case sal_Unicode('m'):
+                case sal_Unicode('M'):
+                    aCmpsL[0] = "mm";
+                    aCmpsU[0] = "MM";
+                    aScales[0] = 1.0 * nScaleFactor; // mm/100
+                    break;
+                case sal_Unicode('p'):
+                case sal_Unicode('P'):
+                    aCmpsL[0] = "pt";
+                    aCmpsU[0] = "PT";
+                    aScales[0] = (10.0 * nScaleFactor*2.54)/72.; // mm/100
+
+                    aCmpsL[1] = "pc";
+                    aCmpsU[1] = "PC";
+                    aScales[1] = (10.0 * nScaleFactor*2.54)/12.; // mm/100
+                    break;
+                }
+            }
+            else if( MeasureUnit::POINT == nTargetUnit )
+            {
+                if( rString[nPos] == 'p' || rString[nPos] == 'P' )
+                {
+                    aCmpsL[0] = "pt";
+                    aCmpsU[0] = "PT";
+                    aScales[0] = 1;
+                }
+            }
+
+            if( aCmpsL[0] == NULL )
+                return false;
+
+            double nScale = 0.;
+            for( sal_uInt16 i= 0; i < 2; i++ )
+            {
+                const sal_Char *pL = aCmpsL[i];
+                if( pL )
+                {
+                    const sal_Char *pU = aCmpsU[i];
+                    while( nPos < nLen && *pL )
+                    {
+                        sal_Unicode c = rString[nPos];
+                        if( c != *pL && c != *pU )
+                            break;
+                        pL++;
+                        pU++;
+                        nPos++;
+                    }
+                    if( !*pL && (nPos == nLen || ' ' == rString[nPos]) )
+                    {
+                        nScale = aScales[i];
+                        break;
+                    }
+                }
+            }
+
+            if( 0. == nScale )
+                return false;
+
+            // TODO: check overflow
+            if( nScale != 1. )
+                nVal *= nScale;
+        }
+    }
+
+    nVal += .5;
+    if( bNeg )
+        nVal = -nVal;
+
+    if( nVal <= (double)nMin )
+        rValue = nMin;
+    else if( nVal >= (double)nMax )
+        rValue = nMax;
+    else
+        rValue = (sal_Int32)nVal;
+
+    return true;
+}
+
+/** convert measure in given unit to string with given unit */
+void Converter::convertMeasure( OUStringBuffer& rBuffer,
+								sal_Int32 nMeasure,
+								sal_Int16 nSourceUnit /* = MeasureUnit::MM_100TH */,
+								sal_Int16 nTargetUnit /* = MeasureUnit::INCH */  )
+{
+    OSL_ENSURE( false, "Converter::convertMeasure - not implemented, tools/BigInt needs replacement" );
+    (void)rBuffer;
+    (void)nMeasure;
+    (void)nSourceUnit;
+    (void)nTargetUnit;
+#if 0
+    if( nSourceUnit == MeasureUnit::PERCENT )
+    {
+        OSL_ENSURE( nTargetUnit == MeasureUnit::PERCENT,
+                    "MeasureUnit::PERCENT only maps to MeasureUnit::PERCENT!" );
+
+        rBuffer.append( nMeasure );
+        rBuffer.append( sal_Unicode('%' ) );
+    }
+    else
+    {
+	// the sign is processed seperatly
+	if( nMeasure < 0 )
+	{
+		nMeasure = -nMeasure;
+		rBuffer.append( sal_Unicode('-') );
+	}
+
+	// The new length is (nVal * nMul)/(nDiv*nFac*10)
+	long nMul = 1000;
+	long nDiv = 1;
+	long nFac = 100;
+	const sal_Char* psUnit = 0;
+	switch( nSourceUnit )
+	{
+	case MeasureUnit::TWIP:
+		switch( nTargetUnit )
+		{
+		case MeasureUnit::MM_100TH:
+		case MeasureUnit::MM_10TH:
+            OSL_ENSURE( MeasureUnit::INCH == nTargetUnit,"output unit not supported for twip values" );
+		case MeasureUnit::MM:
+			// 0.01mm = 0.57twip (exactly)
+			nMul = 25400;	// 25.4 * 1000
+			nDiv = 1440;	// 72 * 20;
+			nFac = 100;
+			psUnit = gpsMM;
+			break;
+
+		case MeasureUnit::CM:
+			// 0.001cm = 0.57twip (exactly)
+			nMul = 25400;	// 2.54 * 10000
+			nDiv = 1440;	// 72 * 20;
+			nFac = 1000;
+			psUnit = gpsCM;
+			break;
+
+		case MeasureUnit::POINT:
+			// 0.01pt = 0.2twip (exactly)
+			nMul = 1000;
+			nDiv = 20;
+			nFac = 100;
+			psUnit = gpsPT;
+			break;
+
+		case MeasureUnit::INCH:
+		default:
+            OSL_ENSURE( MeasureUnit::INCH == nTargetUnit,
+						"output unit not supported for twip values" );
+			// 0.0001in = 0.144twip (exactly)
+			nMul = 100000;
+			nDiv = 1440;	// 72 * 20;
+			nFac = 10000;
+			psUnit = gpsINCH;
+			break;
+		}
+		break;
+
+	case MeasureUnit::POINT:
+		// 1pt = 1pt (exactly)
+        OSL_ENSURE( MeasureUnit::POINT == nTargetUnit,
+					"output unit not supported for pt values" );
+		nMul = 10;
+		nDiv = 1;
+		nFac = 1;
+		psUnit = gpsPT;
+		break;
+    case MeasureUnit::MM_10TH:
+	case MeasureUnit::MM_100TH:
+        {
+            long nFac2 = (MeasureUnit::MM_100TH == nSourceUnit) ? 100 : 10;
+		    switch( nTargetUnit )
+		    {
+		    case MeasureUnit::MM_100TH:
+		    case MeasureUnit::MM_10TH:
+                OSL_ENSURE( MeasureUnit::INCH == nTargetUnit,
+						    "output unit not supported for 1/100mm values" );
+		    case MeasureUnit::MM:
+			    // 0.01mm = 1 mm/100 (exactly)
+			    nMul = 10;
+			    nDiv = 1;
+			    nFac = nFac2;
+			    psUnit = gpsMM;
+			    break;
+
+		    case MeasureUnit::CM:
+			    // 0.001mm = 1 mm/100 (exactly)
+			    nMul = 10;
+			    nDiv = 1;	// 72 * 20;
+			    nFac = 10*nFac2;
+			    psUnit = gpsCM;
+			    break;
+
+		    case MeasureUnit::POINT:
+			    // 0.01pt = 0.35 mm/100 (exactly)
+			    nMul = 72000;
+			    nDiv = 2540;
+			    nFac = nFac2;
+			    psUnit = gpsPT;
+			    break;
+
+		    case MeasureUnit::INCH:
+		    default:
+                OSL_ENSURE( MeasureUnit::INCH == nTargetUnit,
+						    "output unit not supported for 1/100mm values" );
+			    // 0.0001in = 0.254 mm/100 (exactly)
+			    nMul = 100000;
+			    nDiv = 2540;
+			    nFac = 100*nFac2;
+			    psUnit = gpsINCH;
+			    break;
+		    }
+		    break;
+        }
+	}
+
+	long nLongVal = 0;
+	bool bOutLongVal = true;
+	if( nMeasure > SAL_INT32_MAX / nMul )
+	{
+		// A big int is required for calculation
+		BigInt nBigVal( nMeasure );
+		BigInt nBigFac( nFac );
+		nBigVal *= nMul;
+		nBigVal /= nDiv;
+		nBigVal += 5;
+		nBigVal /= 10;
+
+		if( nBigVal.IsLong() )
+		{
+			// To convert the value into a string a long is sufficient
+			nLongVal = (long)nBigVal;
+		}
+		else
+		{
+			BigInt nBigFac2( nFac );
+			BigInt nBig10( 10 );
+			rBuffer.append( (sal_Int32)(nBigVal / nBigFac2) );
+			if( !(nBigVal % nBigFac2).IsZero() )
+			{
+				rBuffer.append( sal_Unicode('.') );
+				while( nFac > 1 && !(nBigVal % nBigFac2).IsZero() )
+				{
+					nFac /= 10;
+					nBigFac2 = nFac;
+					rBuffer.append( (sal_Int32)((nBigVal / nBigFac2) % nBig10 ) );
+				}
+			}
+			bOutLongVal = false;
+		}
+	}
+	else
+	{
+		nLongVal = nMeasure * nMul;
+		nLongVal /= nDiv;
+		nLongVal += 5;
+		nLongVal /= 10;
+	}
+
+	if( bOutLongVal )
+	{
+		rBuffer.append( (sal_Int32)(nLongVal / nFac) );
+		if( nFac > 1 && (nLongVal % nFac) != 0 )
+		{
+			rBuffer.append( sal_Unicode('.') );
+			while( nFac > 1 && (nLongVal % nFac) != 0 )
+			{
+				nFac /= 10;
+				rBuffer.append( (sal_Int32)((nLongVal / nFac) % 10) );
+			}
+		}
+	}
+
+	if( psUnit )
+		rBuffer.appendAscii( psUnit );
+    }
+#endif
+}
+
+static const OUString& getTrueString()
+{
+	static const OUString sTrue( RTL_CONSTASCII_USTRINGPARAM( "true" ) );
+	return sTrue;
+}
+
+static const OUString& getFalseString()
+{
+	static const OUString sFalse( RTL_CONSTASCII_USTRINGPARAM( "false" ) );
+	return sFalse;
+}
+
+/** convert string to boolean */
+bool Converter::convertBool( bool& rBool, const OUString& rString )
+{
+    rBool = rString == getTrueString();
+
+    return rBool || (rString == getFalseString());
+}
+
+/** convert boolean to string */
+void Converter::convertBool( OUStringBuffer& rBuffer, bool bValue )
+{
+    rBuffer.append( bValue ? getTrueString() : getFalseString() );
+}
+
+/** convert string to percent */
+bool Converter::convertPercent( sal_Int32& rPercent, const OUString& rString )
+{
+    return convertMeasure( rPercent, rString, MeasureUnit::PERCENT );
+}
+
+/** convert percent to string */
+void Converter::convertPercent( OUStringBuffer& rBuffer, sal_Int32 nValue )
+{
+    rBuffer.append( nValue );
+    rBuffer.append( sal_Unicode('%' ) );
+}
+
+/** convert string to pixel measure */
+bool Converter::convertMeasurePx( sal_Int32& rPixel, const OUString& rString )
+{
+    return convertMeasure( rPixel, rString, MeasureUnit::PIXEL );
+}
+
+/** convert pixel measure to string */
+void Converter::convertMeasurePx( OUStringBuffer& rBuffer, sal_Int32 nValue )
+{
+    rBuffer.append( nValue );
+    rBuffer.append( sal_Unicode('p' ) );
+    rBuffer.append( sal_Unicode('x' ) );
+}
+
+int lcl_gethex( int nChar )
+{
+    if( nChar >= '0' && nChar <= '9' )
+        return nChar - '0';
+    else if( nChar >= 'a' && nChar <= 'f' )
+        return nChar - 'a' + 10;
+    else if( nChar >= 'A' && nChar <= 'F' )
+        return nChar - 'A' + 10;
+    else
+        return 0;
+}
+
+/** convert string to color */
+bool Converter::convertColor( sal_Int32& rColor, const OUString& rValue )
+{
+    if( rValue.getLength() != 7 || rValue[0] != '#' )
+        return false;
+
+	rColor = lcl_gethex( rValue[1] ) * 16 + lcl_gethex( rValue[2] );
+	rColor <<= 8;
+
+	rColor |= ( lcl_gethex( rValue[3] ) * 16 + lcl_gethex( rValue[4] ) );
+	rColor <<= 8;
+
+	rColor |= ( lcl_gethex( rValue[5] ) * 16 + lcl_gethex( rValue[6] ) );
+
+    return true;
+}
+
+static sal_Char aHexTab[] = "0123456789abcdef";
+
+/** convert color to string */
+void Converter::convertColor( OUStringBuffer& rBuffer, sal_Int32 nColor )
+{
+    rBuffer.append( sal_Unicode( '#' ) );
+
+    sal_uInt8 nCol = (sal_uInt8)(nColor >> 16);
+    rBuffer.append( sal_Unicode( aHexTab[ nCol >> 4 ] ) );
+    rBuffer.append( sal_Unicode( aHexTab[ nCol & 0xf ] ) );
+
+    nCol = (sal_uInt8)(nColor >> 8);
+    rBuffer.append( sal_Unicode( aHexTab[ nCol >> 4 ] ) );
+    rBuffer.append( sal_Unicode( aHexTab[ nCol & 0xf ] ) );
+
+    nCol = (sal_uInt8)nColor;
+    rBuffer.append( sal_Unicode( aHexTab[ nCol >> 4 ] ) );
+    rBuffer.append( sal_Unicode( aHexTab[ nCol & 0xf ] ) );
+}
+
+/** convert number to string */
+void Converter::convertNumber( OUStringBuffer& rBuffer, sal_Int32 nNumber )
+{
+    rBuffer.append( nNumber );
+}
+
+/** convert string to number with optional min and max values */
+bool Converter::convertNumber(	sal_Int32& rValue,
+								const OUString& rString,
+								sal_Int32 nMin, sal_Int32 nMax )
+{
+    bool bNeg = false;
+    rValue = 0;
+
+    sal_Int32 nPos = 0L;
+    sal_Int32 nLen = rString.getLength();
+
+    // skip white space
+    while( (nPos < nLen) && (rString[nPos] <= sal_Unicode(' ')) )
+        nPos++;
+
+    if( nPos < nLen && sal_Unicode('-') == rString[nPos] )
+    {
+        bNeg = true;
+        nPos++;
+    }
+
+    // get number
+    while( nPos < nLen &&
+           sal_Unicode('0') <= rString[nPos] &&
+           sal_Unicode('9') >= rString[nPos] )
+    {
+        // TODO: check overflow!
+        rValue *= 10;
+        rValue += (rString[nPos] - sal_Unicode('0'));
+        nPos++;
+    }
+
+    if( bNeg )
+        rValue *= -1;
+
+	if( rValue < nMin )
+		rValue = nMin;
+	else if( rValue > nMax )
+		rValue = nMax;
+
+    return nPos == nLen;
+}
+
+/** convert double number to string (using ::rtl::math) */
+void Converter::convertDouble(  OUStringBuffer& rBuffer,
+								double fNumber,
+								bool bWriteUnits,
+								sal_Int16 nSourceUnit,
+								sal_Int16 nTargetUnit)
+{
+    if(MeasureUnit::PERCENT == nSourceUnit)
+    {
+        OSL_ENSURE( nTargetUnit == MeasureUnit::PERCENT, "MeasureUnit::PERCENT only maps to MeasureUnit::PERCENT!" );
+        ::rtl::math::doubleToUStringBuffer( rBuffer, fNumber, rtl_math_StringFormat_Automatic, rtl_math_DecimalPlaces_Max, '.', true);
+        if(bWriteUnits)
+            rBuffer.append(sal_Unicode('%'));
+    }
+    else
+    {
+        OUStringBuffer sUnit;
+        double fFactor = GetConversionFactor(sUnit, nSourceUnit, nTargetUnit);
+        if(fFactor != 1.0)
+            fNumber *= fFactor;
+        ::rtl::math::doubleToUStringBuffer( rBuffer, fNumber, rtl_math_StringFormat_Automatic, rtl_math_DecimalPlaces_Max, '.', true);
+        if(bWriteUnits)
+            rBuffer.append(sUnit);
+    }
+}
+
+/** convert double number to string (using ::rtl::math) */
+void Converter::convertDouble( ::rtl::OUStringBuffer& rBuffer, double fNumber)
+{
+    ::rtl::math::doubleToUStringBuffer( rBuffer, fNumber, rtl_math_StringFormat_Automatic, rtl_math_DecimalPlaces_Max, '.', true);
+}
+
+/** convert string to double number (using ::rtl::math) */
+bool Converter::convertDouble(double& rValue,
+    const ::rtl::OUString& rString, sal_Int16 nTargetUnit)
+{
+	sal_Int16 nSourceUnit = GetUnitFromString(rString, nTargetUnit);
+
+	return convertDouble(rValue, rString, nSourceUnit, nTargetUnit );
+}
+
+/** convert string to double number (using ::rtl::math) */
+bool Converter::convertDouble(double& rValue,
+    const ::rtl::OUString& rString, sal_Int16 nSourceUnit, sal_Int16 nTargetUnit)
+{
+    rtl_math_ConversionStatus eStatus;
+    rValue = ::rtl::math::stringToDouble( rString, (sal_Unicode)('.'), (sal_Unicode)(','), &eStatus, NULL );
+
+    if(eStatus == rtl_math_ConversionStatus_Ok)
+    {
+		OUStringBuffer sUnit;
+        double fFactor = GetConversionFactor(sUnit, nSourceUnit, nTargetUnit);
+        if(fFactor != 1.0 && fFactor != 0.0)
+            rValue /= fFactor;
+    }
+
+    return ( eStatus == rtl_math_ConversionStatus_Ok );
+}
+
+/** convert string to double number (using ::rtl::math) */
+bool Converter::convertDouble(double& rValue, const ::rtl::OUString& rString)
+{
+    rtl_math_ConversionStatus eStatus;
+    rValue = ::rtl::math::stringToDouble( rString, (sal_Unicode)('.'), (sal_Unicode)(','), &eStatus, NULL );
+    return ( eStatus == rtl_math_ConversionStatus_Ok );
+}
+
+/** convert double to ISO Time String; negative durations allowed */
+void Converter::convertTime( ::rtl::OUStringBuffer& rBuffer,
+                            const double& fTime)
+{
+
+    double fValue = fTime;
+
+    // take care of negative durations as specified in:
+    // XML Schema, W3C Working Draft 07 April 2000, section 3.2.6.1
+    if (fValue < 0.0)
+    {
+        rBuffer.append(sal_Unicode('-'));
+        fValue = - fValue;
+    }
+
+    rBuffer.appendAscii(RTL_CONSTASCII_STRINGPARAM( "PT" ));
+    fValue *= 24;
+    double fHoursValue = ::rtl::math::approxFloor (fValue);
+    fValue -= fHoursValue;
+    fValue *= 60;
+    double fMinsValue = ::rtl::math::approxFloor (fValue);
+    fValue -= fMinsValue;
+    fValue *= 60;
+    double fSecsValue = ::rtl::math::approxFloor (fValue);
+    fValue -= fSecsValue;
+    double f100SecsValue;
+    if (fValue > 0.00001)
+        f100SecsValue = ::rtl::math::round( fValue, XML_MAXDIGITSCOUNT_TIME - 5);
+    else
+        f100SecsValue = 0.0;
+
+    if (f100SecsValue == 1.0)
+    {
+        f100SecsValue = 0.0;
+        fSecsValue += 1.0;
+    }
+    if (fSecsValue >= 60.0)
+    {
+        fSecsValue -= 60.0;
+        fMinsValue += 1.0;
+    }
+    if (fMinsValue >= 60.0)
+    {
+        fMinsValue -= 60.0;
+        fHoursValue += 1.0;
+    }
+
+    if (fHoursValue < 10)
+        rBuffer.append( sal_Unicode('0'));
+    rBuffer.append( sal_Int32( fHoursValue));
+    rBuffer.append( sal_Unicode('H'));
+    if (fMinsValue < 10)
+        rBuffer.append( sal_Unicode('0'));
+    rBuffer.append( sal_Int32( fMinsValue));
+    rBuffer.append( sal_Unicode('M'));
+    if (fSecsValue < 10)
+        rBuffer.append( sal_Unicode('0'));
+    rBuffer.append( sal_Int32( fSecsValue));
+    if (f100SecsValue > 0.0)
+    {
+        ::rtl::OUString a100th( ::rtl::math::doubleToUString( fValue,
+                    rtl_math_StringFormat_F, XML_MAXDIGITSCOUNT_TIME - 5, '.',
+                    true));
+        if ( a100th.getLength() > 2 )
+        {
+            rBuffer.append( sal_Unicode('.'));
+            rBuffer.append( a100th.copy( 2 ) );     // strip 0.
+        }
+    }
+    rBuffer.append( sal_Unicode('S'));
+}
+
+/** convert ISO Time String to double; negative durations allowed */
+bool Converter::convertTime( double& fTime,
+                            const ::rtl::OUString& rString)
+{
+    rtl::OUString aTrimmed = rString.trim().toAsciiUpperCase();
+    const sal_Unicode* pStr = aTrimmed.getStr();
+
+    // negative time duration?
+    bool bIsNegativeDuration = false;
+    if ( sal_Unicode('-') == (*pStr) )
+    {
+        bIsNegativeDuration = true;
+        pStr++;
+    }
+
+    if ( *(pStr++) != sal_Unicode('P') )            // duration must start with "P"
+        return false;
+
+    rtl::OUString sDoubleStr;
+    bool bSuccess = true;
+    bool bDone = false;
+    bool bTimePart = false;
+    bool bIsFraction = false;
+    sal_Int32 nDays  = 0;
+    sal_Int32 nHours = 0;
+    sal_Int32 nMins  = 0;
+    sal_Int32 nSecs  = 0;
+    sal_Int32 nTemp = 0;
+
+    while ( bSuccess && !bDone )
+    {
+        sal_Unicode c = *(pStr++);
+        if ( !c )                               // end
+            bDone = true;
+        else if ( sal_Unicode('0') <= c && sal_Unicode('9') >= c )
+        {
+            if ( nTemp >= SAL_MAX_INT32 / 10 )
+                bSuccess = false;
+            else
+            {
+                if ( !bIsFraction )
+                {
+                    nTemp *= 10;
+                    nTemp += (c - sal_Unicode('0'));
+                }
+                else
+                {
+                    sDoubleStr += OUString::valueOf(c);
+                }
+            }
+        }
+        else if ( bTimePart )
+        {
+            if ( c == sal_Unicode('H') )
+            {
+                nHours = nTemp;
+                nTemp = 0;
+            }
+            else if ( c == sal_Unicode('M') )
+            {
+                nMins = nTemp;
+                nTemp = 0;
+            }
+            else if ( (c == sal_Unicode(',')) || (c == sal_Unicode('.')) )
+            {
+                nSecs = nTemp;
+                nTemp = 0;
+                bIsFraction = true;
+                sDoubleStr = OUString(RTL_CONSTASCII_USTRINGPARAM("0."));
+            }
+            else if ( c == sal_Unicode('S') )
+            {
+                if ( !bIsFraction )
+                {
+                    nSecs = nTemp;
+                    nTemp = 0;
+                    sDoubleStr = OUString(RTL_CONSTASCII_USTRINGPARAM("0.0"));
+                }
+            }
+            else
+                bSuccess = false;               // invalid character
+        }
+        else
+        {
+            if ( c == sal_Unicode('T') )            // "T" starts time part
+                bTimePart = true;
+            else if ( c == sal_Unicode('D') )
+            {
+                nDays = nTemp;
+                nTemp = 0;
+            }
+            else if ( c == sal_Unicode('Y') || c == sal_Unicode('M') )
+            {
+                //! how many days is a year or month?
+
+                OSL_ENSURE( false, "years or months in duration: not implemented");
+                bSuccess = false;
+            }
+            else
+                bSuccess = false;               // invalid character
+        }
+    }
+
+    if ( bSuccess )
+    {
+        if ( nDays )
+            nHours += nDays * 24;               // add the days to the hours part
+        double fTempTime = 0.0;
+        double fHour = nHours;
+        double fMin = nMins;
+        double fSec = nSecs;
+        double fSec100 = 0.0;
+        double fFraction = sDoubleStr.toDouble();
+        fTempTime = fHour / 24;
+        fTempTime += fMin / (24 * 60);
+        fTempTime += fSec / (24 * 60 * 60);
+        fTempTime += fSec100 / (24 * 60 * 60 * 60);
+        fTempTime += fFraction / (24 * 60 * 60);
+
+        // negative duration?
+        if ( bIsNegativeDuration )
+        {
+            fTempTime = -fTempTime;
+        }
+
+        fTime = fTempTime;
+    }
+    return bSuccess;
+}
+
+/** convert util::DateTime to ISO Time String */
+void Converter::convertTime( ::rtl::OUStringBuffer& rBuffer,
+                            const ::com::sun::star::util::DateTime& rDateTime )
+{
+    double fHour = rDateTime.Hours;
+    double fMin = rDateTime.Minutes;
+    double fSec = rDateTime.Seconds;
+    double fSec100 = rDateTime.HundredthSeconds;
+    double fTempTime = fHour / 24;
+    fTempTime += fMin / (24 * 60);
+    fTempTime += fSec / (24 * 60 * 60);
+    fTempTime += fSec100 / (24 * 60 * 60 * 100);
+    convertTime( rBuffer, fTempTime );
+}
+
+/** convert ISO Time String to util::DateTime */
+bool Converter::convertTime( ::com::sun::star::util::DateTime& rDateTime,
+                             const ::rtl::OUString& rString )
+{
+    double fCalculatedTime = 0.0;
+    if( convertTime( fCalculatedTime, rString ) )
+    {
+        // #101357# declare as volatile to prevent optimization
+        // (gcc 3.0.1 Linux)
+        volatile double fTempTime = fCalculatedTime;
+        fTempTime *= 24;
+        double fHoursValue = ::rtl::math::approxFloor (fTempTime);
+        fTempTime -= fHoursValue;
+        fTempTime *= 60;
+        double fMinsValue = ::rtl::math::approxFloor (fTempTime);
+        fTempTime -= fMinsValue;
+        fTempTime *= 60;
+        double fSecsValue = ::rtl::math::approxFloor (fTempTime);
+        fTempTime -= fSecsValue;
+        double f100SecsValue = 0.0;
+
+        if( fTempTime > 0.00001 )
+            f100SecsValue = fTempTime;
+
+        rDateTime.Year = 0;
+        rDateTime.Month = 0;
+        rDateTime.Day = 0;
+        rDateTime.Hours = static_cast < sal_uInt16 > ( fHoursValue );
+        rDateTime.Minutes = static_cast < sal_uInt16 > ( fMinsValue );
+        rDateTime.Seconds = static_cast < sal_uInt16 > ( fSecsValue );
+        rDateTime.HundredthSeconds = static_cast < sal_uInt16 > ( f100SecsValue * 100.0 );
+
+        return true;
+    }
+    return false;
+}
+
+/** convert util::DateTime to ISO Date String */
+void Converter::convertDateTime(
+				::rtl::OUStringBuffer& rBuffer,
+                const com::sun::star::util::DateTime& rDateTime,
+				bool bAddTimeIf0AM )
+{
+    OSL_ENSURE( false, "Converter::convertDateTime - not implemented, tools/String needs replacement" );
+    (void)rBuffer;
+    (void)rDateTime;
+    (void)bAddTimeIf0AM;
+#if 0
+    String aString( String::CreateFromInt32( rDateTime.Year ) );
+    aString += '-';
+    if( rDateTime.Month < 10 )
+        aString += '0';
+    aString += String::CreateFromInt32( rDateTime.Month );
+    aString += '-';
+    if( rDateTime.Day < 10 )
+        aString += '0';
+    aString += String::CreateFromInt32( rDateTime.Day );
+
+    if( rDateTime.Seconds != 0 ||
+        rDateTime.Minutes != 0 ||
+        rDateTime.Hours   != 0 ||
+		bAddTimeIf0AM )
+    {
+        aString += 'T';
+        if( rDateTime.Hours < 10 )
+            aString += '0';
+        aString += String::CreateFromInt32( rDateTime.Hours );
+        aString += ':';
+        if( rDateTime.Minutes < 10 )
+            aString += '0';
+        aString += String::CreateFromInt32( rDateTime.Minutes );
+        aString += ':';
+        if( rDateTime.Seconds < 10 )
+            aString += '0';
+        aString += String::CreateFromInt32( rDateTime.Seconds );
+		if ( rDateTime.HundredthSeconds > 0)
+		{
+	        aString += '.';
+			if (rDateTime.HundredthSeconds < 10)
+				aString += '0';
+			aString += String::CreateFromInt32( rDateTime.HundredthSeconds );
+		}
+    }
+
+    rBuffer.append( aString );
+#endif
+}
+
+/** convert ISO Date String to util::DateTime */
+bool Converter::convertDateTime( com::sun::star::util::DateTime& rDateTime,
+                                     const ::rtl::OUString& rString )
+{
+    bool bSuccess = true;
+
+    rtl::OUString aDateStr, aTimeStr, sDoubleStr;
+    sal_Int32 nPos = rString.indexOf( (sal_Unicode) 'T' );
+    sal_Int32 nPos2 = rString.indexOf( (sal_Unicode) ',' );
+    if (nPos2 < 0)
+        nPos2 = rString.indexOf( (sal_Unicode) '.' );
+    if ( nPos >= 0 )
+    {
+        aDateStr = rString.copy( 0, nPos );
+        if ( nPos2 >= 0 )
+        {
+            aTimeStr = rString.copy( nPos + 1, nPos2 - nPos - 1 );
+            sDoubleStr = OUString(RTL_CONSTASCII_USTRINGPARAM("0."));
+            sDoubleStr += rString.copy( nPos2 + 1 );
+        }
+        else
+        {
+            aTimeStr = rString.copy(nPos + 1);
+            sDoubleStr = OUString(RTL_CONSTASCII_USTRINGPARAM("0.0"));
+        }
+    }
+    else
+        aDateStr = rString;         // no separator: only date part
+
+    sal_Int32 nYear  = 1899;
+    sal_Int32 nMonth = 12;
+    sal_Int32 nDay   = 30;
+    sal_Int32 nHour  = 0;
+    sal_Int32 nMin   = 0;
+    sal_Int32 nSec   = 0;
+
+    const sal_Unicode* pStr = aDateStr.getStr();
+    sal_Int32 nDateTokens = 1;
+    while ( *pStr )
+    {
+        if ( *pStr == '-' )
+            nDateTokens++;
+        pStr++;
+    }
+    if ( nDateTokens > 3 || aDateStr.getLength() == 0 )
+        bSuccess = false;
+    else
+    {
+        sal_Int32 n = 0;
+        if ( !convertNumber( nYear, aDateStr.getToken( 0, '-', n ), 0, 9999 ) )
+            bSuccess = false;
+        if ( nDateTokens >= 2 )
+            if ( !convertNumber( nMonth, aDateStr.getToken( 0, '-', n ), 0, 12 ) )
+                bSuccess = false;
+        if ( nDateTokens >= 3 )
+            if ( !convertNumber( nDay, aDateStr.getToken( 0, '-', n ), 0, 31 ) )
+                bSuccess = false;
+    }
+
+    if ( aTimeStr.getLength() > 0 )           // time is optional
+    {
+        pStr = aTimeStr.getStr();
+        sal_Int32 nTimeTokens = 1;
+        while ( *pStr )
+        {
+            if ( *pStr == ':' )
+                nTimeTokens++;
+            pStr++;
+        }
+        if ( nTimeTokens > 3 )
+            bSuccess = false;
+        else
+        {
+            sal_Int32 n = 0;
+            if ( !convertNumber( nHour, aTimeStr.getToken( 0, ':', n ), 0, 23 ) )
+                bSuccess = false;
+            if ( nTimeTokens >= 2 )
+                if ( !convertNumber( nMin, aTimeStr.getToken( 0, ':', n ), 0, 59 ) )
+                    bSuccess = false;
+            if ( nTimeTokens >= 3 )
+                if ( !convertNumber( nSec, aTimeStr.getToken( 0, ':', n ), 0, 59 ) )
+                    bSuccess = false;
+        }
+    }
+
+    if (bSuccess)
+    {
+        rDateTime.Year = (sal_uInt16)nYear;
+        rDateTime.Month = (sal_uInt16)nMonth;
+        rDateTime.Day = (sal_uInt16)nDay;
+        rDateTime.Hours = (sal_uInt16)nHour;
+        rDateTime.Minutes = (sal_uInt16)nMin;
+        rDateTime.Seconds = (sal_uInt16)nSec;
+        rDateTime.HundredthSeconds = (sal_uInt16)(sDoubleStr.toDouble() * 100);
+    }
+    return bSuccess;
+}
+
+/** gets the position of the first comma after npos in the string
+    rStr. Commas inside '"' pairs are not matched */
+sal_Int32 Converter::indexOfComma( const OUString& rStr,
+                                            sal_Int32 nPos )
+{
+    sal_Unicode cQuote = 0;
+    sal_Int32 nLen = rStr.getLength();
+    for( ; nPos < nLen; nPos++ )
+    {
+        sal_Unicode c = rStr[nPos];
+        switch( c )
+        {
+        case sal_Unicode('\''):
+            if( 0 == cQuote )
+                cQuote = c;
+            else if( '\'' == cQuote )
+                cQuote = 0;
+            break;
+
+        case sal_Unicode('"'):
+            if( 0 == cQuote )
+                cQuote = c;
+            else if( '\"' == cQuote )
+                cQuote = 0;
+            break;
+
+        case sal_Unicode(','):
+            if( 0 == cQuote )
+                return nPos;
+            break;
+        }
+    }
+
+    return -1;
+}
+
+const
+  sal_Char aBase64EncodeTable[] =
+    { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
+      'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
+      'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
+      'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
+      '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/' };
+
+const
+  sal_uInt8 aBase64DecodeTable[]  =
+    {											 62,255,255,255, 63, // 43-47
+//                                                +               /
+
+     52, 53, 54, 55, 56, 57, 58, 59, 60, 61,255,255,255,  0,255,255, // 48-63
+//    0   1   2   3   4   5   6   7   8   9               =
+
+    255,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, // 64-79
+//        A   B   C   D   E   F   G   H   I   J   K   L   M   N   O
+
+     15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,255,255,255,255,255, // 80-95
+//    P   Q   R   S   T   U   V   W   X   Y   Z
+
+      0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, // 96-111
+//        a   b   c   d   e   f   g   h   i   j   k   l   m   n   o
+
+     41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51 }; // 112-123
+//    p   q   r   s   t   u   v   w   x   y   z
+
+
+
+void ThreeByteToFourByte (const sal_Int8* pBuffer, const sal_Int32 nStart, const sal_Int32 nFullLen, rtl::OUStringBuffer& sBuffer)
+{
+    sal_Int32 nLen(nFullLen - nStart);
+    if (nLen > 3)
+        nLen = 3;
+    if (nLen == 0)
+    {
+        sBuffer.setLength(0);
+        return;
+    }
+
+    sal_Int32 nBinaer;
+    switch (nLen)
+    {
+        case 1:
+        {
+            nBinaer = ((sal_uInt8)pBuffer[nStart + 0]) << 16;
+        }
+        break;
+        case 2:
+        {
+            nBinaer = (((sal_uInt8)pBuffer[nStart + 0]) << 16) +
+                    (((sal_uInt8)pBuffer[nStart + 1]) <<  8);
+        }
+        break;
+        default:
+        {
+            nBinaer = (((sal_uInt8)pBuffer[nStart + 0]) << 16) +
+                    (((sal_uInt8)pBuffer[nStart + 1]) <<  8) +
+                    ((sal_uInt8)pBuffer[nStart + 2]);
+        }
+        break;
+    }
+
+    sBuffer.appendAscii("====");
+
+    sal_uInt8 nIndex (static_cast<sal_uInt8>((nBinaer & 0xFC0000) >> 18));
+    sBuffer.setCharAt(0, aBase64EncodeTable [nIndex]);
+
+    nIndex = static_cast<sal_uInt8>((nBinaer & 0x3F000) >> 12);
+    sBuffer.setCharAt(1, aBase64EncodeTable [nIndex]);
+    if (nLen == 1)
+        return;
+
+    nIndex = static_cast<sal_uInt8>((nBinaer & 0xFC0) >> 6);
+    sBuffer.setCharAt(2, aBase64EncodeTable [nIndex]);
+    if (nLen == 2)
+        return;
+
+    nIndex = static_cast<sal_uInt8>((nBinaer & 0x3F));
+    sBuffer.setCharAt(3, aBase64EncodeTable [nIndex]);
+}
+
+void Converter::encodeBase64(rtl::OUStringBuffer& aStrBuffer, const uno::Sequence<sal_Int8>& aPass)
+{
+	sal_Int32 i(0);
+	sal_Int32 nBufferLength(aPass.getLength());
+	const sal_Int8* pBuffer = aPass.getConstArray();
+	while (i < nBufferLength)
+	{
+		rtl::OUStringBuffer sBuffer;
+		ThreeByteToFourByte (pBuffer, i, nBufferLength, sBuffer);
+		aStrBuffer.append(sBuffer);
+		i += 3;
+	}
+}
+
+void Converter::decodeBase64(uno::Sequence<sal_Int8>& aBuffer, const rtl::OUString& sBuffer)
+{
+#if OSL_DEBUG_LEVEL > 0
+	sal_Int32 nCharsDecoded =
+#endif
+	decodeBase64SomeChars( aBuffer, sBuffer );
+	OSL_ENSURE( nCharsDecoded == sBuffer.getLength(), "some bytes left in base64 decoding!" );
+}
+
+sal_Int32 Converter::decodeBase64SomeChars(
+		uno::Sequence<sal_Int8>& rOutBuffer,
+		const rtl::OUString& rInBuffer)
+{
+	sal_Int32 nInBufferLen = rInBuffer.getLength();
+	sal_Int32 nMinOutBufferLen = (nInBufferLen / 4) * 3;
+	if( rOutBuffer.getLength() < nMinOutBufferLen )
+		rOutBuffer.realloc( nMinOutBufferLen );
+
+	const sal_Unicode *pInBuffer = rInBuffer.getStr();
+	sal_Int8 *pOutBuffer = rOutBuffer.getArray();
+	sal_Int8 *pOutBufferStart = pOutBuffer;
+	sal_Int32 nCharsDecoded = 0;
+
+	sal_uInt8 aDecodeBuffer[4];
+	sal_Int32 nBytesToDecode = 0;
+	sal_Int32 nBytesGotFromDecoding = 3;
+	sal_Int32 nInBufferPos= 0;
+	while( nInBufferPos < nInBufferLen )
+	{
+		sal_Unicode cChar = *pInBuffer;
+		if( cChar >= '+' && cChar <= 'z' )
+		{
+			sal_uInt8 nByte = aBase64DecodeTable[cChar-'+'];
+			if( nByte != 255 )
+			{
+				// We have found a valid character!
+				aDecodeBuffer[nBytesToDecode++] = nByte;
+
+				// One '=' character at the end means 2 out bytes
+				// Two '=' characters at the end mean 1 out bytes
+				if( '=' == cChar && nBytesToDecode > 2 )
+					nBytesGotFromDecoding--;
+				if( 4 == nBytesToDecode )
+				{
+					// Four characters found, so we may convert now!
+					sal_uInt32 nOut = (aDecodeBuffer[0] << 18) +
+									  (aDecodeBuffer[1] << 12) +
+									  (aDecodeBuffer[2] << 6) +
+									   aDecodeBuffer[3];
+
+					*pOutBuffer++  = (sal_Int8)((nOut & 0xff0000) >> 16);
+					if( nBytesGotFromDecoding > 1 )
+						*pOutBuffer++  = (sal_Int8)((nOut & 0xff00) >> 8);
+					if( nBytesGotFromDecoding > 2 )
+						*pOutBuffer++  = (sal_Int8)(nOut & 0xff);
+					nCharsDecoded = nInBufferPos + 1;
+					nBytesToDecode = 0;
+					nBytesGotFromDecoding = 3;
+				}
+			}
+			else
+			{
+				nCharsDecoded++;
+			}
+		}
+		else
+		{
+			nCharsDecoded++;
+		}
+
+		nInBufferPos++;
+		pInBuffer++;
+	}
+	if( (pOutBuffer - pOutBufferStart) != rOutBuffer.getLength() )
+		rOutBuffer.realloc( pOutBuffer - pOutBufferStart );
+
+	return nCharsDecoded;
+}
+
+void Converter::clearUndefinedChars(rtl::OUString& rTarget, const rtl::OUString& rSource)
+{
+	sal_uInt32 nLength(rSource.getLength());
+	rtl::OUStringBuffer sBuffer(nLength);
+	for (sal_uInt32 i = 0; i < nLength; i++)
+	{
+		sal_Unicode cChar = rSource[i];
+		if (!(cChar < 0x0020) ||
+			(cChar == 0x0009) ||		// TAB
+			(cChar == 0x000A) ||		// LF
+			(cChar == 0x000D))			// legal character
+			sBuffer.append(cChar);
+	}
+	rTarget = sBuffer.makeStringAndClear();
+}
+
+double Converter::GetConversionFactor(::rtl::OUStringBuffer& rUnit, sal_Int16 nSourceUnit, sal_Int16 nTargetUnit)
+{
+	double fRetval(1.0);
+	rUnit.setLength(0L);
+
+	const sal_Char* psUnit = 0;
+
+	if(nSourceUnit != nTargetUnit)
+	{
+		switch(nSourceUnit)
+		{
+			case MeasureUnit::TWIP:
+			{
+				switch(nTargetUnit)
+				{
+					case MeasureUnit::MM_100TH:
+					case MeasureUnit::MM_10TH:
+					{
+                        OSL_ENSURE( MeasureUnit::INCH == nTargetUnit, "output unit not supported for twip values");
+					}
+					case MeasureUnit::MM:
+					{
+						// 0.01mm = 0.57twip (exactly)
+						fRetval = ((25400.0 / 1440.0) / 1000.0);
+						psUnit = gpsMM;
+						break;
+					}
+					case MeasureUnit::CM:
+					{
+						// 0.001cm = 0.57twip (exactly)
+						fRetval = ((25400.0 / 1440.0) / 10000.0);
+						psUnit = gpsCM;
+						break;
+					}
+					case MeasureUnit::POINT:
+					{
+						// 0.01pt = 0.2twip (exactly)
+						fRetval = ((1000.0 / 20.0) / 1000.0);
+						psUnit = gpsPT;
+						break;
+					}
+					case MeasureUnit::INCH:
+					default:
+					{
+                        OSL_ENSURE( MeasureUnit::INCH == nTargetUnit, "output unit not supported for twip values");
+						// 0.0001in = 0.144twip (exactly)
+						fRetval = ((100000.0 / 1440.0) / 100000.0);
+						psUnit = gpsINCH;
+						break;
+					}
+				}
+				break;
+			}
+			case MeasureUnit::POINT:
+			{
+                switch(nTargetUnit)
+                {
+                    case MeasureUnit::MM:
+                        // 1mm = 72 / 25.4 pt (exactly)
+                        fRetval = ( 25.4 / 72.0 );
+                        psUnit = gpsMM;
+                        break;
+
+                    case MeasureUnit::CM:
+                        // 1cm = 72 / 2.54 pt (exactly)
+                        fRetval = ( 2.54 / 72.0 );
+                        psUnit = gpsCM;
+                        break;
+
+                    case MeasureUnit::TWIP:
+                        // 1twip = 72 / 1440 pt (exactly)
+                        fRetval = 20.0;     // 1440.0 / 72.0
+                        psUnit = gpsPC;
+                        break;
+
+                    case MeasureUnit::INCH:
+                    default:
+                        OSL_ENSURE( MeasureUnit::INCH == nTargetUnit, "output unit not supported for pt values");
+                        // 1in = 72 pt (exactly)
+                        fRetval = ( 1.0 / 72.0 );
+                        psUnit = gpsINCH;
+                        break;
+                }
+                break;
+			}
+            case MeasureUnit::MM_10TH:
+			{
+				switch(nTargetUnit)
+				{
+					case MeasureUnit::MM_100TH:
+					case MeasureUnit::MM_10TH:
+					{
+                        OSL_ENSURE( MeasureUnit::INCH == nTargetUnit, "output unit not supported for 1/100mm values");
+					}
+					case MeasureUnit::MM:
+					{
+						// 0.01mm = 1 mm/100 (exactly)
+						fRetval = ((10.0 / 1.0) / 100.0);
+						psUnit = gpsMM;
+						break;
+					}
+					case MeasureUnit::CM:
+					{
+						// 0.001mm = 1 mm/100 (exactly)
+						fRetval = ((10.0 / 1.0) / 1000.0);
+						psUnit = gpsCM;
+						break;
+					}
+					case MeasureUnit::POINT:
+					{
+						// 0.01pt = 0.35 mm/100 (exactly)
+						fRetval = ((72000.0 / 2540.0) / 100.0);
+						psUnit = gpsPT;
+						break;
+					}
+					case MeasureUnit::INCH:
+					default:
+					{
+                        OSL_ENSURE( MeasureUnit::INCH == nTargetUnit, "output unit not supported for 1/100mm values");
+						// 0.0001in = 0.254 mm/100 (exactly)
+						fRetval = ((100000.0 / 2540.0) / 10000.0);
+						psUnit = gpsINCH;
+						break;
+					}
+				}
+				break;
+            }
+			case MeasureUnit::MM_100TH:
+			{
+				switch(nTargetUnit)
+				{
+					case MeasureUnit::MM_100TH:
+					case MeasureUnit::MM_10TH:
+					{
+                        OSL_ENSURE( MeasureUnit::INCH == nTargetUnit, "output unit not supported for 1/100mm values");
+					}
+					case MeasureUnit::MM:
+					{
+						// 0.01mm = 1 mm/100 (exactly)
+						fRetval = ((10.0 / 1.0) / 1000.0);
+						psUnit = gpsMM;
+						break;
+					}
+					case MeasureUnit::CM:
+					{
+						// 0.001mm = 1 mm/100 (exactly)
+						fRetval = ((10.0 / 1.0) / 10000.0);
+						psUnit = gpsCM;
+						break;
+					}
+					case MeasureUnit::POINT:
+					{
+						// 0.01pt = 0.35 mm/100 (exactly)
+						fRetval = ((72000.0 / 2540.0) / 1000.0);
+						psUnit = gpsPT;
+						break;
+					}
+					case MeasureUnit::INCH:
+					default:
+					{
+                        OSL_ENSURE( MeasureUnit::INCH == nTargetUnit, "output unit not supported for 1/100mm values");
+						// 0.0001in = 0.254 mm/100 (exactly)
+						fRetval = ((100000.0 / 2540.0) / 100000.0);
+						psUnit = gpsINCH;
+						break;
+					}
+				}
+				break;
+			}
+		}
+
+		if( psUnit )
+			rUnit.appendAscii( psUnit );
+	}
+
+	return fRetval;
+}
+
+sal_Int16 Converter::GetUnitFromString(const ::rtl::OUString& rString, sal_Int16 nDefaultUnit)
+{
+	sal_Int32 nPos = 0L;
+	sal_Int32 nLen = rString.getLength();
+	sal_Int16 nRetUnit = nDefaultUnit;
+
+	// skip white space
+	while( nPos < nLen && sal_Unicode(' ') == rString[nPos] )
+		nPos++;
+
+	// skip negative
+	if( nPos < nLen && sal_Unicode('-') == rString[nPos] )
+		nPos++;
+
+	// skip number
+	while( nPos < nLen && sal_Unicode('0') <= rString[nPos] && sal_Unicode('9') >= rString[nPos] )
+		nPos++;
+
+	if( nPos < nLen && sal_Unicode('.') == rString[nPos] )
+	{
+		nPos++;
+		while( nPos < nLen && sal_Unicode('0') <= rString[nPos] && sal_Unicode('9') >= rString[nPos] )
+			nPos++;
+	}
+
+	// skip white space
+	while( nPos < nLen && sal_Unicode(' ') == rString[nPos] )
+		nPos++;
+
+	if( nPos < nLen )
+	{
+		switch(rString[nPos])
+		{
+			case sal_Unicode('%') :
+			{
+				nRetUnit = MeasureUnit::PERCENT;
+				break;
+			}
+			case sal_Unicode('c'):
+			case sal_Unicode('C'):
+			{
+				if(nPos+1 < nLen && (rString[nPos+1] == sal_Unicode('m')
+					|| rString[nPos+1] == sal_Unicode('M')))
+					nRetUnit = MeasureUnit::CM;
+				break;
+			}
+			case sal_Unicode('e'):
+			case sal_Unicode('E'):
+			{
+				// CSS1_EMS or CSS1_EMX later
+				break;
+			}
+			case sal_Unicode('i'):
+			case sal_Unicode('I'):
+			{
+				if(nPos+1 < nLen && (rString[nPos+1] == sal_Unicode('n')
+					|| rString[nPos+1] == sal_Unicode('n')))
+					nRetUnit = MeasureUnit::INCH;
+				break;
+			}
+			case sal_Unicode('m'):
+			case sal_Unicode('M'):
+			{
+				if(nPos+1 < nLen && (rString[nPos+1] == sal_Unicode('m')
+					|| rString[nPos+1] == sal_Unicode('M')))
+					nRetUnit = MeasureUnit::MM;
+				break;
+			}
+			case sal_Unicode('p'):
+			case sal_Unicode('P'):
+			{
+				if(nPos+1 < nLen && (rString[nPos+1] == sal_Unicode('t')
+					|| rString[nPos+1] == sal_Unicode('T')))
+					nRetUnit = MeasureUnit::POINT;
+				if(nPos+1 < nLen && (rString[nPos+1] == sal_Unicode('c')
+					|| rString[nPos+1] == sal_Unicode('C')))
+					nRetUnit = MeasureUnit::TWIP;
+				break;
+			}
+		}
+	}
+
+	return nRetUnit;
+}
+
+}
Index: sax/source/tools/makefile.mk
===================================================================
RCS file: sax/source/tools/makefile.mk
diff -N sax/source/tools/makefile.mk
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sax/source/tools/makefile.mk	24 Jan 2007 14:31:40 -0000	1.1.2.2
@@ -0,0 +1,54 @@
+#*************************************************************************
+#
+#   OpenOffice.org - a multi-platform office productivity suite
+#
+#   $RCSfile: makefile.mk,v $
+#
+#   $Revision: 1.1.2.2 $
+#
+#   last change: $Author: cl $ $Date: 2007/01/24 14:31:40 $
+#
+#   The Contents of this file are made available subject to
+#   the terms of GNU Lesser General Public License Version 2.1.
+#
+#
+#     GNU Lesser General Public License Version 2.1
+#     =============================================
+#     Copyright 2005 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
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJNAME=sax
+TARGET=saxtools
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE :  settings.mk
+.INCLUDE :  $(PRJ)$/util$/makefile.pmk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES =	\
+		$(SLO)$/converter.obj
+
+# --- Targets -------------------------------------------------------
+
+.INCLUDE :  target.mk
Index: sax/util/makefile.mk
===================================================================
RCS file: /cvs/xml/sax/util/makefile.mk,v
retrieving revision 1.5
retrieving revision 1.4.12.8
diff -u -b -I $Revision.*$ -I $Author.*$ -r1.5 -r1.4.12.8
--- sax/util/makefile.mk	6 Feb 2007 12:57:23 -0000	1.5
+++ sax/util/makefile.mk	22 Mar 2007 15:19:21 -0000	1.4.12.8
@@ -32,31 +32,45 @@
 #     MA  02111-1307  USA
 #
 #*************************************************************************
+
 PRJ=..
 
 PRJNAME=sax
-TARGET = sax.uno
-NO_BSYMBOLIC=TRUE
-ENABLE_EXCEPTIONS=TRUE
+TARGET=sax
+
+USE_DEFFILE=TRUE
+
 # --- Settings -----------------------------------------------------
+
 .INCLUDE :  settings.mk
-DLLPRE =
-#-----------------------------------------------------------
 
+# ------------------------------------------------------------------
+
+LIB1TARGET= $(SLB)$/$(TARGET).lib
+LIB1FILES=\
+			$(SLB)$/saxtools.lib
 
-SHL1TARGET= $(TARGET)
+# sax
+
+SHL1TARGET= $(TARGET)$(UPD)$(DLLPOSTFIX)
 SHL1IMPLIB= i$(TARGET)
+SHL1USE_EXPORTS=ordinal
 
+SHL1LIBS=	$(LIB1TARGET)
 SHL1STDLIBS= \
-		$(SALLIB)  \
+				$(VOSLIB)		\
 		$(CPPULIB) \
 		$(CPPUHELPERLIB)\
-			$(EXPAT3RDLIB)
+				$(COMPHELPERLIB)\
+				$(RTLLIB)		\
+				$(SALLIB)		\
+				$(ONELIB)		\
+				$(SALHELPERLIB)
 
-SHL1LIBS=		$(SLB)$/expatwrap.lib 
-SHL1VERSIONMAP=		$(SOLARENV)$/src$/component.map
 SHL1DEF=		$(MISC)$/$(SHL1TARGET).def
 DEF1NAME=		$(SHL1TARGET)
+DEFLIB1NAME=$(TARGET)
 
 # --- Targets ------------------------------------------------------
+
 .INCLUDE :	target.mk
Index: sax/util/makefile.pmk
===================================================================
RCS file: sax/util/makefile.pmk
diff -N sax/util/makefile.pmk
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sax/util/makefile.pmk	14 Feb 2006 18:42:49 -0000	1.1.2.1
@@ -0,0 +1,42 @@
+#*************************************************************************
+#
+#   OpenOffice.org - a multi-platform office productivity suite
+#
+#   $RCSfile: makefile.pmk,v $
+#
+#   $Revision: 1.1.2.1 $
+#
+#   last change: $Author: cl $ $Date: 2006/02/14 18:42:49 $
+#
+#   The Contents of this file are made available subject to
+#   the terms of GNU Lesser General Public License Version 2.1.
+#
+#
+#     GNU Lesser General Public License Version 2.1
+#     =============================================
+#     Copyright 2005 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
+#
+#*************************************************************************
+
+# Reduction of exported symbols:
+CDEFS += -DSAX_DLLIMPLEMENTATION
+.IF "$(COMNAME)" == "gcc3" && "$(HAVE_GCC_VISIBILITY_FEATURE)" == "TRUE"
+CFLAGS += -fvisibility=hidden
+.ELIF "$(COMNAME)" == "sunpro5" && "$(CCNUMVER)" >= "00050005"
+CFLAGS += -xldscope=hidden
+.ENDIF
