summaryrefslogtreecommitdiff
path: root/sw/source/filter/basflt
diff options
context:
space:
mode:
authorJens-Heiner Rechtien <hr@openoffice.org>2009-01-05 14:06:42 +0000
committerJens-Heiner Rechtien <hr@openoffice.org>2009-01-05 14:06:42 +0000
commit48119ae05819132c6a4558dac23da8c70cad0814 (patch)
tree51c918f80b3e5295a591b829ddfbcb7be4ee03a4 /sw/source/filter/basflt
parentcbcc85a2f94bb35bbc5c56468bc71d991e2cafec (diff)
CWS-TOOLING: integrate CWS libmsword
2008-12-18 12:33:19 +0100 kendy r265681 : Export less symbols. 2008-12-17 19:26:56 +0100 kendy r265655 : Move libmsword to the -writer package. 2008-12-15 17:46:16 +0100 kendy r265516 : Enable exceptions for iodetect.cxx. 2008-12-15 15:17:53 +0100 kendy r265504 : Deliver the msword.dll. 2008-12-09 19:38:17 +0100 kendy r265138 : Remove accidentally added method. 2008-12-09 19:33:57 +0100 kendy r265137 : Fix linking on Win32. 2008-12-09 18:37:16 +0100 kendy r265135 : Move SwFltControlStack::Delete() to ww1/fltshell.cxx to fix linking. 2008-12-09 18:01:56 +0100 kendy r265127 : Visibility fixes. 2008-12-09 15:51:52 +0100 kendy r265109 : Fix ambiguous usage of class Color. 2008-12-09 14:54:27 +0100 kendy r265091 : Add #include "precompiled_sw.hxx" to fix --enable-pch build. 2008-12-09 14:44:59 +0100 kendy r265088 : Add #include "precompiled_sw.hxx" to fix --enable-pch build. 2008-12-08 19:14:49 +0100 kendy r265015 : #i96313# Get rid of inc/iodetect.cxx, it's a really bad idea to share code by #ifdefing parts of it, and #including a .cxx file ;-) This change moves it to iodetect.cxx, which is compiled to a .o/.obj that is used where needed. 2008-11-20 17:45:08 +0100 kendy r264083 : #i96313# Make the destruction of Readers consistent. 2008-11-20 17:18:11 +0100 kendy r264070 : #i96313# Added missing SW_DLLPUBLIC for (Import|Export)(DOC|RTF). 2008-11-18 19:21:07 +0100 kendy r263797 : #i96313# Remove accidentally added file. 2008-11-18 17:14:31 +0100 kendy r263790 : #i96313# Split doc and rtf filters into a separate library From: Radek Doulik <rodo@novell.com> fix SwFieldBookmark class visibility (suggested by kendy) 2008-11-18 17:14:01 +0100 kendy r263789 : #i96313# Split doc and rtf filters into a separate library From: Fridrich Strba <fstrba@novell.com> add visibility markup to allow linking 2008-11-18 17:13:29 +0100 kendy r263788 : #i96313# Split doc and rtf filters into a separate library From: Jan Holesovsky <kendy@suse.cz> Visibility markup for libmsword. This is the most trivial approach, every class that had a symbol that needed to be visible was marked with SW_DLLPUBLIC; the correct (but more time consuming) way would be to mark just the exact methods that were needed. To be done later if generally shows that the separate libmsword makes sense; and also now we have the upper limit of symbols that needed to be added, and we can only make it better [decrease the number] ;-) 2008-11-18 17:12:58 +0100 kendy r263787 : #i96313# Split doc and rtf filters into a separate library From: Jan Holesovsky <kendy@suse.cz> Added the missing msword.map. 2008-11-18 17:12:25 +0100 kendy r263786 : #i96313# Split doc and rtf filters into a separate library From: Jan Holesovsky <kendy@suse.cz> scp2 change for libmsword. 2008-11-18 17:11:55 +0100 kendy r263785 : #i96313# Split doc and rtf filters into a separate library From: Jan Holesovsky <kendy@suse.cz> Convert the binary .doc and .rtf filters into a separate library. It is called 'libmsword' and loaded on demand when either of the formats (.doc, .rtf) is loaded or saved.
Diffstat (limited to 'sw/source/filter/basflt')
-rw-r--r--sw/source/filter/basflt/fltini.cxx176
-rw-r--r--sw/source/filter/basflt/iodetect.cxx595
-rw-r--r--sw/source/filter/basflt/makefile.mk5
3 files changed, 721 insertions, 55 deletions
diff --git a/sw/source/filter/basflt/fltini.cxx b/sw/source/filter/basflt/fltini.cxx
index 131fca689dbc..05b1bb4eb97a 100644
--- a/sw/source/filter/basflt/fltini.cxx
+++ b/sw/source/filter/basflt/fltini.cxx
@@ -53,12 +53,8 @@
#include <pam.hxx>
#include <shellio.hxx>
#include <errhdl.hxx>
-#ifndef _DOCSH_HXX
#include <docsh.hxx>
-#endif
-#ifndef _WDOCSH_HXX
#include <wdocsh.hxx>
-#endif
#include <fltini.hxx>
#include <hints.hxx>
#include <frmatr.hxx>
@@ -70,22 +66,57 @@
#include <frmfmt.hxx>
#include <numrule.hxx>
#include <ndtxt.hxx>
-#ifndef _SWFLTOPT_HXX
#include <swfltopt.hxx>
-#endif
#include <swerror.h>
-
-#ifndef _IODETECT_CXX
-#include <iodetect.cxx>
-#endif
+#include <osl/module.hxx>
using namespace utl;
using rtl::OUString;
using namespace com::sun::star::uno;
-SwRead ReadRtf = 0, ReadAscii = 0, /*ReadSwg = 0, ReadSw3 = 0,*/
+SwRead ReadAscii = 0, /*ReadSwg = 0, ReadSw3 = 0,*/
ReadHTML = 0, ReadXML = 0;
+Reader* GetRTFReader();
+Reader* GetWW8Reader();
+
+// Note: if editing, please don't forget to modify also the enum
+// ReaderWriterEnum and aFilterDetect in shellio.hxx
+SwReaderWriterEntry aReaderWriter[] =
+{
+ SwReaderWriterEntry( &::GetRTFReader, &::GetRTFWriter, TRUE ),
+ SwReaderWriterEntry( 0, &::GetASCWriter, FALSE ),
+ SwReaderWriterEntry( &::GetWW8Reader, &::GetWW8Writer, TRUE ),
+ SwReaderWriterEntry( &::GetWW8Reader, &::GetWW8Writer, TRUE ),
+ SwReaderWriterEntry( &::GetRTFReader, &::GetRTFWriter, TRUE ),
+ SwReaderWriterEntry( 0, &::GetHTMLWriter, TRUE ),
+ SwReaderWriterEntry( 0, 0, TRUE ),
+ SwReaderWriterEntry( &::GetWW8Reader, 0, TRUE ),
+ SwReaderWriterEntry( 0, &::GetXMLWriter, TRUE ),
+ SwReaderWriterEntry( 0, &::GetASCWriter, TRUE ),
+ SwReaderWriterEntry( 0, &::GetASCWriter, TRUE )
+};
+
+Reader* SwReaderWriterEntry::GetReader()
+{
+ if ( pReader )
+ return pReader;
+ else if ( fnGetReader )
+ {
+ pReader = (*fnGetReader)();
+ return pReader;
+ }
+ return NULL;
+}
+
+void SwReaderWriterEntry::GetWriter( const String& rNm, const String& rBaseURL, WriterRef& xWrt ) const
+{
+ if ( fnGetWriter )
+ (*fnGetWriter)( rNm, rBaseURL, xWrt );
+ else
+ xWrt = WriterRef(0);
+}
+
/*SwRead SwGetReaderSw3() // SW_DLLPUBLIC
{
return ReadSw3;
@@ -101,89 +132,75 @@ bool IsDocShellRegistered()
return 0 != SwDocShell::_GetInterface();
}
-inline void _SetFltPtr( USHORT& rPos, SwRead pReader
- , const sal_Char*
-#if OSL_DEBUG_LEVEL > 1
- pNm
-#endif
- /* pNm optimiert der Compiler weg, wird nur in der nicht PRODUCT benoetigt! */
- )
+inline void _SetFltPtr( USHORT rPos, SwRead pReader )
{
-#if OSL_DEBUG_LEVEL > 1
- ASSERT( !strcmp( aReaderWriter[ rPos ].pName, pNm ), "falscher Filter" );
- (void) pNm;
-#endif
- aReaderWriter[ rPos++ ].pReader = pReader;
+ aReaderWriter[ rPos ].pReader = pReader;
}
void _InitFilter()
{
- SwRead pWW8Rd = new WW8Reader;
-
- USHORT nCnt = 0;
- _SetFltPtr( nCnt, (ReadRtf = new RtfReader), FILTER_RTF );
- _SetFltPtr( nCnt, (ReadAscii = new AsciiReader), FILTER_BAS );
- _SetFltPtr( nCnt, pWW8Rd, sWW6 );
- _SetFltPtr( nCnt, pWW8Rd, FILTER_WW8 );
- _SetFltPtr( nCnt, ReadRtf, sRtfWH );
- _SetFltPtr( nCnt, (ReadHTML = new HTMLReader), sHTML);
- _SetFltPtr( nCnt, new WW1Reader, sWW1 );
- _SetFltPtr( nCnt, pWW8Rd, sWW5 );
- _SetFltPtr( nCnt, (ReadXML = new XMLReader), FILTER_XML );
+ _SetFltPtr( READER_WRITER_BAS, (ReadAscii = new AsciiReader) );
+ _SetFltPtr( READER_WRITER_HTML, (ReadHTML = new HTMLReader) );
+ _SetFltPtr( READER_WRITER_WW1, new WW1Reader );
+ _SetFltPtr( READER_WRITER_XML, (ReadXML = new XMLReader) );
#ifdef NEW_WW97_EXPORT
- aReaderWriter[ 8-3 ].fnGetWriter = &::GetWW8Writer;
- aReaderWriter[ 9-3 ].fnGetWriter = &::GetWW8Writer;
+ aReaderWriter[ READER_WRITER_WW1 ].fnGetWriter = &::GetWW8Writer;
+ aReaderWriter[ READER_WRITER_WW5 ].fnGetWriter = &::GetWW8Writer;
#endif
- _SetFltPtr( nCnt, ReadAscii, FILTER_TEXT_DLG );
- _SetFltPtr( nCnt, ReadAscii, FILTER_TEXT );
-
- ASSERT( MAXFILTER == nCnt, "Anzahl Filter ungleich der Definierten" );
+ _SetFltPtr( READER_WRITER_TEXT_DLG, ReadAscii );
+ _SetFltPtr( READER_WRITER_TEXT, ReadAscii );
}
-
-
-
void _FinitFilter()
{
// die Reader vernichten
for( USHORT n = 0; n < MAXFILTER; ++n )
{
- SwIoDetect& rIo = aReaderWriter[n];
- if( rIo.bDelReader && rIo.pReader )
- delete rIo.pReader;
+ SwReaderWriterEntry& rEntry = aReaderWriter[n];
+ if( rEntry.bDelReader && rEntry.pReader )
+ delete rEntry.pReader, rEntry.pReader = NULL;
}
}
/* */
-void SwIoSystem::GetWriter( const String& rFltName, const String& rBaseURL, WriterRef& xRet )
+namespace SwReaderWriter {
+
+Reader* GetReader( ReaderWriterEnum eReader )
+{
+ return aReaderWriter[eReader].GetReader();
+}
+
+void GetWriter( const String& rFltName, const String& rBaseURL, WriterRef& xRet )
{
for( USHORT n = 0; n < MAXFILTER; ++n )
- if( aReaderWriter[n].IsFilter( rFltName ) )
+ if( aFilterDetect[n].IsFilter( rFltName ) )
{
aReaderWriter[n].GetWriter( rFltName, rBaseURL, xRet );
break;
}
}
-
-SwRead SwIoSystem::GetReader( const String& rFltName )
+SwRead GetReader( const String& rFltName )
{
SwRead pRead = 0;
for( USHORT n = 0; n < MAXFILTER; ++n )
- if( aReaderWriter[n].IsFilter( rFltName ) )
+ if( aFilterDetect[n].IsFilter( rFltName ) )
{
pRead = aReaderWriter[n].GetReader();
// fuer einige Reader noch eine Sonderbehandlung:
- pRead->SetFltName( rFltName );
+ if ( pRead )
+ pRead->SetFltName( rFltName );
break;
}
return pRead;
}
+} // namespace SwReaderWriter
+
/* */
/////////////// die Storage Reader/Writer ////////////////////////////////
@@ -937,4 +954,57 @@ void SwAsciiOptions::WriteUserData( String& rStr )
rStr += ',';
}
+extern "C" { static void SAL_CALL thisModule() {} }
+
+static oslGenericFunction GetMswordLibSymbol( const char *pSymbol )
+{
+ static ::osl::Module aModule;
+ if ( aModule.is() ||
+ aModule.loadRelative( &thisModule,
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SVLIBRARY( "msword" ) ) ) ) )
+ {
+ return aModule.getFunctionSymbol( ::rtl::OUString::createFromAscii( pSymbol ) );
+ }
+
+ return NULL;
+}
+
+Reader* GetRTFReader()
+{
+ FnGetReader pFunction = reinterpret_cast<FnGetReader>( GetMswordLibSymbol( "ImportRTF" ) );
+
+ if ( pFunction )
+ return (*pFunction)();
+
+ return NULL;
+}
+
+void GetRTFWriter( const String& rFltName, const String& rBaseURL, WriterRef& xRet )
+{
+ FnGetWriter pFunction = reinterpret_cast<FnGetWriter>( GetMswordLibSymbol( "ExportRTF" ) );
+
+ if ( pFunction )
+ (*pFunction)( rFltName, rBaseURL, xRet );
+ else
+ xRet = WriterRef(0);
+}
+
+Reader* GetWW8Reader()
+{
+ FnGetReader pFunction = reinterpret_cast<FnGetReader>( GetMswordLibSymbol( "ImportDOC" ) );
+
+ if ( pFunction )
+ return (*pFunction)();
+
+ return NULL;
+}
+
+void GetWW8Writer( const String& rFltName, const String& rBaseURL, WriterRef& xRet )
+{
+ FnGetWriter pFunction = reinterpret_cast<FnGetWriter>( GetMswordLibSymbol( "ExportDOC" ) );
+ if ( pFunction )
+ (*pFunction)( rFltName, rBaseURL, xRet );
+ else
+ xRet = WriterRef(0);
+}
diff --git a/sw/source/filter/basflt/iodetect.cxx b/sw/source/filter/basflt/iodetect.cxx
new file mode 100644
index 000000000000..71d5bddd7dc5
--- /dev/null
+++ b/sw/source/filter/basflt/iodetect.cxx
@@ -0,0 +1,595 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: iodetect.cxx,v $
+ * $Revision: 1.31 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sw.hxx"
+
+#include <iodetect.hxx>
+
+#include <errhdl.hxx>
+#include <osl/endian.h>
+#include <sot/storage.hxx>
+#include <svtools/parhtml.hxx>
+#include <tools/urlobj.hxx>
+
+bool IsDocShellRegistered();
+
+SwIoDetect aFilterDetect[] =
+{
+ SwIoDetect( FILTER_RTF, STRING_LEN ),
+ SwIoDetect( FILTER_BAS, STRING_LEN ),
+ SwIoDetect( sWW6, STRING_LEN ),
+ SwIoDetect( FILTER_WW8, STRING_LEN ),
+ SwIoDetect( sRtfWH, STRING_LEN ),
+ SwIoDetect( sHTML, 4 ),
+ SwIoDetect( sWW1, STRING_LEN ),
+ SwIoDetect( sWW5, STRING_LEN ),
+ SwIoDetect( FILTER_XML, 4 ),
+ SwIoDetect( FILTER_TEXT_DLG, 8 ),
+ SwIoDetect( FILTER_TEXT, 4 )
+};
+
+const sal_Char* SwIoDetect::IsReader(const sal_Char* pHeader, ULONG nLen_,
+ const String & /*rFileName*/, const String& /*rUserData*/) const
+{
+ // Filter erkennung
+ struct W1_FIB
+ {
+ SVBT16 wIdent; // 0x0 int magic number
+ SVBT16 nFib; // 0x2 FIB version written
+ SVBT16 nProduct; // 0x4 product version written by
+ SVBT16 nlocale; // 0x6 language stamp---localized version;
+ SVBT16 pnNext; // 0x8
+ SVBT16 fFlags;
+
+ USHORT nFibGet() { return SVBT16ToShort(nFib); }
+ USHORT wIdentGet() { return SVBT16ToShort(wIdent); }
+ USHORT fFlagsGet() { return SVBT16ToShort(fFlags); }
+ // SVBT16 fComplex :1;// 0004 when 1, file is in complex, fast-saved format.
+ BOOL fComplexGet() { return static_cast< BOOL >((fFlagsGet() >> 2) & 1); }
+ };
+
+ int bRet = FALSE;
+ rtl::OString aName( pName );
+ if ( sHTML == aName )
+ bRet = HTMLParser::IsHTMLFormat( pHeader, TRUE, RTL_TEXTENCODING_DONTKNOW );
+ else if ( FILTER_RTF == aName )
+ bRet = 0 == strncmp( "{\\rtf", pHeader, 5 );
+ else if ( sWW5 == aName )
+ {
+ W1_FIB *pW1Header = (W1_FIB*)pHeader;
+ if (pW1Header->wIdentGet() == 0xA5DC && pW1Header->nFibGet() == 0x65)
+ bRet = true; /*WW5*/
+ else if (pW1Header->wIdentGet() == 0xA5DB && pW1Header->nFibGet() == 0x2D)
+ bRet = true; /*WW2*/
+ }
+ else if ( sWW1 == aName )
+ {
+ bRet = (( ((W1_FIB*)pHeader)->wIdentGet() == 0xA59C
+ && ((W1_FIB*)pHeader)->nFibGet() == 0x21)
+ && ((W1_FIB*)pHeader)->fComplexGet() == 0);
+ }
+ else if ( FILTER_TEXT == aName )
+ bRet = SwIoSystem::IsDetectableText(pHeader, nLen_);
+ else if ( FILTER_TEXT_DLG == aName)
+ bRet = SwIoSystem::IsDetectableText( pHeader, nLen_, 0, 0, 0, true);
+ return bRet ? pName : 0;
+}
+
+const String SwIoSystem::GetSubStorageName( const SfxFilter& rFltr )
+{
+ /* bei den StorageFiltern noch den SubStorageNamen setzen */
+ const String& rUserData = rFltr.GetUserData();
+ if( rUserData.EqualsAscii(FILTER_XML) ||
+ rUserData.EqualsAscii(FILTER_XMLV) ||
+ rUserData.EqualsAscii(FILTER_XMLVW) )
+ return String::CreateFromAscii(
+ RTL_CONSTASCII_STRINGPARAM( "content.xml" ));
+ if( rUserData.EqualsAscii(sWW6) || rUserData.EqualsAscii(FILTER_WW8) )
+ return String::CreateFromAscii(
+ RTL_CONSTASCII_STRINGPARAM( "WordDocument" ));
+ return String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "" ));
+}
+
+const SfxFilter* SwIoSystem::GetFilterOfFormat(const String& rFmtNm,
+ const SfxFilterContainer* pCnt)
+{
+ SfxFilterContainer aCntSw( String::CreateFromAscii( sSWRITER ) );
+ SfxFilterContainer aCntSwWeb( String::CreateFromAscii( sSWRITERWEB ) );
+ const SfxFilterContainer* pFltCnt = pCnt ? pCnt : ( IsDocShellRegistered() ? &aCntSw : &aCntSwWeb );
+
+ do {
+ if( pFltCnt )
+ {
+ SfxFilterMatcher aMatcher( pFltCnt->GetName() );
+ SfxFilterMatcherIter aIter( &aMatcher );
+ const SfxFilter* pFilter = aIter.First();
+ while ( pFilter )
+ {
+ if( pFilter->GetUserData() == rFmtNm )
+ return pFilter;
+ pFilter = aIter.Next();
+ }
+ }
+ if( pCnt || pFltCnt == &aCntSwWeb )
+ break;
+ pFltCnt = &aCntSwWeb;
+ } while( TRUE );
+ return 0;
+}
+
+BOOL SwIoSystem::IsValidStgFilter( const com::sun::star::uno::Reference < com::sun::star::embed::XStorage >& rStg, const SfxFilter& rFilter)
+{
+ BOOL bRet = FALSE;
+ try
+ {
+ ULONG nStgFmtId = SotStorage::GetFormatID( rStg );
+ bRet = rStg->isStreamElement( ::rtl::OUString::createFromAscii("content.xml") );
+ if ( bRet )
+ bRet = ( nStgFmtId && ( rFilter.GetFormat() == nStgFmtId ) );
+ }
+ catch ( com::sun::star::uno::Exception& )
+ {
+ }
+
+ return bRet;
+}
+
+BOOL SwIoSystem::IsValidStgFilter(SotStorage& rStg, const SfxFilter& rFilter)
+{
+ ULONG nStgFmtId = rStg.GetFormat();
+ /*#i8409# We cannot trust the clipboard id anymore :-(*/
+ if( rFilter.GetUserData().EqualsAscii(FILTER_WW8) ||
+ rFilter.GetUserData().EqualsAscii(sWW6) )
+ {
+ nStgFmtId = 0;
+ }
+
+ BOOL bRet = SVSTREAM_OK == rStg.GetError() &&
+ ( !nStgFmtId || rFilter.GetFormat() == nStgFmtId ) &&
+ ( rStg.IsContained( SwIoSystem::GetSubStorageName( rFilter )) );
+ if( bRet )
+ {
+ /* Bug 53445 - es gibt Excel Docs ohne ClipBoardId! */
+ /* Bug 62703 - und auch WinWord Docs ohne ClipBoardId! */
+ if( rFilter.GetUserData().EqualsAscii(FILTER_WW8) ||
+ rFilter.GetUserData().EqualsAscii(sWW6) )
+ {
+ bRet = !((rStg.IsContained( String::CreateFromAscii("0Table" )) ||
+ rStg.IsContained( String::CreateFromAscii("1Table" ))) ^
+ rFilter.GetUserData().EqualsAscii(FILTER_WW8));
+ if (bRet && !rFilter.IsAllowedAsTemplate())
+ {
+ SotStorageStreamRef xRef =
+ rStg.OpenSotStream(String::CreateFromAscii("WordDocument"),
+ STREAM_STD_READ | STREAM_NOCREATE );
+ xRef->Seek(10);
+ BYTE nByte;
+ *xRef >> nByte;
+ bRet = !(nByte & 1);
+ }
+ }
+ // else if( !rFilter.GetUserData().EqualsAscii(sCExcel) )
+ // bRet = rFilter.GetFormat() == nStgFmtId;
+ }
+ return bRet;
+}
+
+void TerminateBuffer(sal_Char *pBuffer, ULONG nBytesRead, ULONG nBufferLen)
+{
+ ASSERT(nBytesRead <= nBufferLen - 2,
+ "what you read must be less than the max + null termination");
+ ASSERT(!(nBufferLen & 0x00000001), "nMaxReadBuf must be an even number");
+ if (nBytesRead <= nBufferLen - 2)
+ {
+ pBuffer[nBytesRead] = '\0';
+ pBuffer[nBytesRead+1] = '\0';
+ if (nBytesRead & 0x00000001)
+ pBuffer[nBytesRead+2] = '\0';
+ }
+}
+
+/* Feststellen ob das File in dem entsprechenden Format vorliegt. */
+/* Z.z werden nur unsere eigene Filter unterstuetzt */
+BOOL SwIoSystem::IsFileFilter( SfxMedium& rMedium, const String& rFmtName,
+ const SfxFilter** ppFilter )
+{
+ BOOL bRet = FALSE;
+
+ SfxFilterContainer aCntSw( String::CreateFromAscii( sSWRITER ) );
+ SfxFilterContainer aCntSwWeb( String::CreateFromAscii( sSWRITERWEB ) );
+ const SfxFilterContainer& rFltContainer = IsDocShellRegistered() ? aCntSw : aCntSwWeb;
+
+ com::sun::star::uno::Reference < com::sun::star::embed::XStorage > xStor;
+ SotStorageRef xStg;
+ if (rMedium.IsStorage())
+ xStor = rMedium.GetStorage();
+ else
+ {
+ SvStream* pStream = rMedium.GetInStream();
+ if ( pStream && SotStorage::IsStorageFile(pStream) )
+ xStg = new SotStorage( pStream, FALSE );
+ }
+
+ SfxFilterMatcher aMatcher( rFltContainer.GetName() );
+ SfxFilterMatcherIter aIter( &aMatcher );
+ const SfxFilter* pFltr = aIter.First();
+ while ( pFltr )
+ {
+ if( pFltr->GetUserData() == rFmtName )
+ {
+ const String& rUserData = pFltr->GetUserData();
+ if( 'C' == *rUserData.GetBuffer() )
+ {
+ if ( xStor.is() )
+ bRet = IsValidStgFilter( xStor, *pFltr );
+ else if ( xStg.Is() )
+ bRet = xStg.Is() && IsValidStgFilter( *xStg, *pFltr );
+ bRet = bRet && (pFltr->GetUserData() == rFmtName);
+ }
+ else if( !xStg.Is() && !xStor.is() )
+ {
+ SvStream* pStrm = rMedium.GetInStream();
+ if( pStrm && !pStrm->GetError() )
+ {
+ sal_Char aBuffer[4098];
+ const ULONG nMaxRead = sizeof(aBuffer) - 2;
+ ULONG nBytesRead = pStrm->Read(aBuffer, nMaxRead);
+ pStrm->Seek(STREAM_SEEK_TO_BEGIN);
+ TerminateBuffer(aBuffer, nBytesRead, sizeof(aBuffer));
+ for (USHORT i = 0; i < MAXFILTER; ++i)
+ {
+ if (aFilterDetect[i].IsFilter(rFmtName))
+ {
+ bRet = 0 != aFilterDetect[i].IsReader( aBuffer, nBytesRead,
+ rMedium.GetPhysicalName(), rUserData );
+ break;
+ }
+ }
+ }
+ }
+
+ if( bRet && ppFilter )
+ *ppFilter = pFltr;
+ }
+
+ pFltr = aIter.Next();
+ }
+
+ return bRet;
+}
+
+/* die Methode stellt fest, von welchem Typ der stream (File) ist. */
+/* Es wird versucht, eine dem Filter entsprechende Byte-Folge zu finden. */
+/* Wird kein entsprechender gefunden, wird zur Zeit der ASCII-Reader */
+/* returnt !! Der Returnwert ist der interne Filtername! */
+/* rPrefFltName ist der interne Name des Filters, den der Benutzer im */
+/* Open-Dialog eingestellt hat. */
+const SfxFilter* SwIoSystem::GetFileFilter(const String& rFileName,
+ const String& rPrefFltName, SfxMedium* pMedium)
+{
+ SfxFilterContainer aCntSw( String::CreateFromAscii( sSWRITER ) );
+ SfxFilterContainer aCntSwWeb( String::CreateFromAscii( sSWRITERWEB ) );
+ const SfxFilterContainer* pFCntnr = IsDocShellRegistered() ? &aCntSw : &aCntSwWeb;
+
+ if( !pFCntnr )
+ return 0;
+
+ SfxFilterMatcher aMatcher( pFCntnr->GetName() );
+ SfxFilterMatcherIter aIter( &aMatcher );
+ const SfxFilter* pFilter = aIter.First();
+ if ( !pFilter )
+ return 0;
+
+ if( pMedium ? ( pMedium->IsStorage() || SotStorage::IsStorageFile( pMedium->GetInStream() ) ) : SotStorage::IsStorageFile( rFileName ) )
+ {
+ // package storage or OLEStorage based format
+ SotStorageRef xStg;
+ BOOL bDeleteMedium = FALSE;
+ if (!pMedium )
+ {
+ INetURLObject aObj;
+ aObj.SetSmartProtocol( INET_PROT_FILE );
+ aObj.SetSmartURL( rFileName );
+ pMedium = new SfxMedium( aObj.GetMainURL( INetURLObject::NO_DECODE ), STREAM_STD_READ, FALSE );
+ bDeleteMedium = TRUE;
+ }
+
+ // templates should not get precedence over "normal" filters (#i35508, #i33168)
+ const SfxFilter* pTemplateFilter = 0;
+ const SfxFilter* pOldFilter = pFCntnr->GetFilter4FilterName( rPrefFltName );
+ BOOL bLookForTemplate = pOldFilter && pOldFilter->IsOwnTemplateFormat();
+ if ( pMedium->IsStorage() )
+ {
+ com::sun::star::uno::Reference < com::sun::star::embed::XStorage > xStor = pMedium->GetStorage();
+ if ( xStor.is() )
+ {
+ while ( pFilter )
+ {
+ if( 'C' == *pFilter->GetUserData().GetBuffer() && IsValidStgFilter( xStor, *pFilter ) )
+ {
+ if ( pFilter->IsOwnTemplateFormat() && !bLookForTemplate )
+ // found template filter; maybe there's a "normal" one also
+ pTemplateFilter = pFilter;
+ else
+ return pFilter;
+ }
+
+ pFilter = aIter.Next();
+ }
+
+ // there's only a template filter that could be found
+ if ( pTemplateFilter )
+ pFilter = pTemplateFilter;
+ }
+ }
+ else
+ {
+ SvStream* pStream = pMedium->GetInStream();
+ if ( pStream && SotStorage::IsStorageFile(pStream) )
+ xStg = new SotStorage( pStream, FALSE );
+
+ if( xStg.Is() && ( xStg->GetError() == SVSTREAM_OK ) )
+ {
+ while ( pFilter )
+ {
+ if( 'C' == *pFilter->GetUserData().GetBuffer() && IsValidStgFilter( *xStg, *pFilter ) )
+ {
+ if ( pFilter->IsOwnTemplateFormat() && !bLookForTemplate )
+ // found template filter; maybe there's a "normal" one also
+ pTemplateFilter = pFilter;
+ else
+ return pFilter;
+ }
+
+ pFilter = aIter.Next();
+ }
+
+ // there's only a template filter that could be found
+ if ( pTemplateFilter )
+ pFilter = pTemplateFilter;
+
+ }
+ }
+
+ return pFilter;
+ }
+
+ sal_Char aBuffer[4098];
+ const ULONG nMaxRead = sizeof(aBuffer) - 2;
+ ULONG nBytesRead = 0;
+ if (pMedium)
+ {
+ SvStream* pIStrm = pMedium->GetInStream();
+ if( !pIStrm || SVSTREAM_OK != pIStrm->GetError() )
+ return 0;
+ ULONG nCurrPos = pIStrm->Tell();
+ nBytesRead = pIStrm->Read(aBuffer, nMaxRead);
+ pIStrm->Seek( nCurrPos );
+ }
+ /*
+ else
+ {
+ SvFileStream aStrm( rFileName, STREAM_READ );
+
+ // ohne FileName oder ohne Stream gibts nur den ANSI-Filter
+ if( !rFileName.Len() || SVSTREAM_OK != aStrm.GetError() )
+ return 0;
+
+ nBytesRead = aStrm.Read(aBuffer, nMaxRead);
+ aStrm.Close();
+ }*/
+
+ TerminateBuffer(aBuffer, nBytesRead, sizeof(aBuffer));
+
+
+ /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
+ /* suche nach dem bestimmten Filter, falls kein entsprechender */
+ /* gefunden wird, so wird der ASCII-Filter returnt. */
+ /* Gibt es Filter ohne einen Identifizierungs-String, so werden diese */
+ /* nie erkannt und es wird auch der ASCII-Filter returnt. */
+ /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
+ {
+ const SfxFilter* pFilterTmp = 0;
+ const sal_Char* pNm;
+ for( USHORT n = 0; n < MAXFILTER; ++n )
+ {
+ String sEmptyUserData;
+ pNm = aFilterDetect[n].IsReader(aBuffer, nBytesRead, rFileName, sEmptyUserData);
+ pFilterTmp = pNm ? SwIoSystem::GetFilterOfFormat(String::CreateFromAscii(pNm), pFCntnr) : 0;
+ if (pNm && pFilterTmp)
+ {
+ return pFilterTmp;
+ }
+ }
+ }
+
+ /* Ok, bis jetzt kein Filter gefunden, also befrage mal die */
+ /* "WORD 4 WORD" Filter */
+ if( rFileName.Len() )
+ {
+ if( pMedium )
+ pMedium->CloseInStream();
+
+ }
+ return SwIoSystem::GetTextFilter( aBuffer, nBytesRead);
+}
+
+bool SwIoSystem::IsDetectableText(const sal_Char* pBuf, ULONG &rLen,
+ CharSet *pCharSet, bool *pSwap, LineEnd *pLineEnd, bool bEncodedFilter)
+{
+ bool bSwap = false;
+ CharSet eCharSet = RTL_TEXTENCODING_DONTKNOW;
+ bool bLE = true;
+ ULONG nHead=0;
+ /*See if its a known unicode type*/
+ if (rLen >= 2)
+ {
+ if (rLen > 2 && BYTE(pBuf[0]) == 0xEF && BYTE(pBuf[1]) == 0xBB &&
+ BYTE(pBuf[2]) == 0xBF)
+ {
+ eCharSet = RTL_TEXTENCODING_UTF8;
+ nHead = 3;
+ }
+ else if (BYTE(pBuf[0]) == 0xFE && BYTE(pBuf[1]) == 0xFF)
+ {
+ eCharSet = RTL_TEXTENCODING_UCS2;
+ bLE = false;
+ nHead = 2;
+ }
+ else if (BYTE(pBuf[1]) == 0xFE && BYTE(pBuf[0]) == 0xFF)
+ {
+ eCharSet = RTL_TEXTENCODING_UCS2;
+ nHead = 2;
+ }
+ pBuf+=nHead;
+ rLen-=nHead;
+ }
+
+ bool bCR = false, bLF = false, bNoNormalChar = false,
+ bIsBareUnicode = false;
+
+ if (eCharSet != RTL_TEXTENCODING_DONTKNOW)
+ {
+ String sWork;
+ sal_Unicode *pNewBuf = sWork.AllocBuffer( static_cast< xub_StrLen >(rLen));
+ sal_Size nNewLen;
+ if (eCharSet != RTL_TEXTENCODING_UCS2)
+ {
+ nNewLen = rLen;
+ rtl_TextToUnicodeConverter hConverter =
+ rtl_createTextToUnicodeConverter(eCharSet);
+ rtl_TextToUnicodeContext hContext =
+ rtl_createTextToUnicodeContext(hConverter);
+
+ sal_Size nCntBytes;
+ sal_uInt32 nInfo;
+ nNewLen = rtl_convertTextToUnicode( hConverter, hContext, pBuf,
+ rLen, pNewBuf, nNewLen,
+ (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_DEFAULT |
+ RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_DEFAULT |
+ RTL_TEXTTOUNICODE_FLAGS_INVALID_DEFAULT), &nInfo, &nCntBytes);
+
+ rtl_destroyTextToUnicodeContext(hConverter, hContext);
+ rtl_destroyTextToUnicodeConverter(hConverter);
+ }
+ else
+ {
+ nNewLen = rLen/2;
+ memcpy(pNewBuf, pBuf, rLen);
+#ifdef OSL_LITENDIAN
+ bool bNativeLE = true;
+#else
+ bool bNativeLE = false;
+#endif
+ if (bLE != bNativeLE)
+ {
+ bSwap = true;
+ sal_Char* pF = (sal_Char*)pNewBuf;
+ sal_Char* pN = pF+1;
+ for(xub_StrLen n = 0; n < nNewLen; ++n, pF+=2, pN+=2)
+ {
+ sal_Char c = *pF;
+ *pF = *pN;
+ *pN = c;
+ }
+ }
+ }
+
+ sWork.ReleaseBufferAccess( static_cast< xub_StrLen >(nNewLen) );
+ pNewBuf = sWork.GetBufferAccess();
+
+ for (ULONG nCnt = 0; nCnt < nNewLen; ++nCnt, ++pNewBuf)
+ {
+ switch (*pNewBuf)
+ {
+ case 0xA:
+ bLF = true;
+ break;
+ case 0xD:
+ bCR = true;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ else
+ {
+ for( ULONG nCnt = 0; nCnt < rLen; ++nCnt, ++pBuf )
+ {
+ switch (*pBuf)
+ {
+ case 0x0:
+ if( nCnt + 1 < rLen && !*(pBuf+1) )
+ return 0;
+ bIsBareUnicode = true;
+ break;
+ case 0xA:
+ bLF = true;
+ break;
+ case 0xD:
+ bCR = true;
+ break;
+ case 0xC:
+ case 0x1A:
+ case 0x9:
+ break;
+ default:
+ if (0x20 > (BYTE)*pBuf)
+ bNoNormalChar = true;
+ break;
+ }
+ }
+ }
+
+ LineEnd eSysLE = GetSystemLineEnd();
+ LineEnd eLineEnd;
+ if (!bCR && !bLF)
+ eLineEnd = eSysLE;
+ else
+ eLineEnd = bCR ? ( bLF ? LINEEND_CRLF : LINEEND_CR ) : LINEEND_LF;
+
+ if (pCharSet)
+ *pCharSet = eCharSet;
+ if (pSwap)
+ *pSwap = bSwap;
+ if (pLineEnd)
+ *pLineEnd = eLineEnd;
+
+ return bEncodedFilter || (!bIsBareUnicode && eSysLE == eLineEnd);
+}
+
+const SfxFilter* SwIoSystem::GetTextFilter( const sal_Char* pBuf, ULONG nLen)
+{
+ bool bAuto = IsDetectableText(pBuf, nLen);
+ const sal_Char* pNm = bAuto ? FILTER_TEXT : FILTER_TEXT_DLG;
+ return SwIoSystem::GetFilterOfFormat( String::CreateFromAscii(pNm), 0 );
+}
diff --git a/sw/source/filter/basflt/makefile.mk b/sw/source/filter/basflt/makefile.mk
index 480cbfe7f3ec..b2f848d33189 100644
--- a/sw/source/filter/basflt/makefile.mk
+++ b/sw/source/filter/basflt/makefile.mk
@@ -50,10 +50,11 @@ SLOFILES = \
$(SLO)$/docfact.obj \
$(SLO)$/fltini.obj \
$(SLO)$/shellio.obj \
-
+ $(SLO)$/iodetect.obj
EXCEPTIONSFILES = \
- $(SLO)$/fltini.obj
+ $(SLO)$/fltini.obj \
+ $(SLO)$/iodetect.obj
# --- Tagets -------------------------------------------------------