1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: iodetect.hxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
39 #include <shellio.hxx>
42 #ifndef _OSL_ENDIAN_H_
43 #include <osl/endian.h>
49 typedef void (*FnGetWriter
)( const String
&, WriterRef
& );
53 // eigentlich privat, aber der Compiler kann sonst die
54 // Tabelle nicht initialisieren
55 const sal_Char
* pName
;
58 inline int IsFilter( const String
& rNm
)
60 return rNm
.EqualsAscii( pName
, 0, nLen
);
65 FnGetWriter fnGetWriter
;
68 inline Reader
* GetReader() const { return pReader
; }
69 inline void GetWriter( const String
& rNm
, WriterRef
& xWrt
) const
70 { if( fnGetWriter
) (*fnGetWriter
)(rNm
,xWrt
); else xWrt
= WriterRef(0); }
73 const sal_Char
* IsReader(const sal_Char
* pHeader
, ULONG nLen
,
74 const String
&rFileName
) const;
79 #define SwIoEntry(sNm, cCharLen, pWrt, bDel) sNm, cCharLen, 0, pWrt, bDel
81 #define SwIoEntry(sNm, cCharLen, pWrt, bDel) sNm, cCharLen
86 #define DEB_SH_SwIoEntry(sNm, cCharLen, pWrt, bDel) , SwIoEntry(sNm, cCharLen, pWrt, bDel)
87 #define W4W_CHECK_FOR_INTERNAL_FILTER \
89 for( nCnt = 0; nCnt < nFltrCount; nCnt++ ) \
90 if( 0 == ( pFilter = pFCntnr->GetFilter( nCnt ))-> \
91 GetUserData().Search( sW4W_Int )) \
94 #define W4W_INFOBOX InfoBox(0, String("Textformat wurde nicht erkannt.")).Execute();
96 #define W4W_FILTER_NOT_FOUND \
97 aW4WName = String::CreateFromAscii("W4W-Filter Nr. "); \
98 aW4WName += String::CreateFromInt32(nW4WId); \
100 aW4WName += String::CreateFromInt32(nVersion); \
101 aW4WName.AppendAscii(" detected, ist aber nicht installiert");\
102 InfoBox( 0, aW4WName ).Execute();
106 #define DEB_SH_SwIoEntry(sNm, cCharLen, pWrt, bDel)
107 #define W4W_CHECK_FOR_INTERNAL_FILTER
109 #define W4W_FILTER_NOT_FOUND
113 #if !( defined(PRODUCT) || defined(PM2))
114 #define DEB_DBWRT_SwIoEntry(sNm, cCharLen, pWrt, bDel) , SwIoEntry(sNm, cCharLen, pWrt, bDel)
116 #define DEB_DBWRT_SwIoEntry(sNm, cCharLen, pWrt, bDel)
120 const USHORT MAXFILTER
=
121 #if !( defined(PRODUCT) || defined(PM2))
127 #define FORAMTNAME_SW4 "StarWriter 4.0"
128 #define FORAMTNAME_SW3 "StarWriter 3.0"
129 #define FORAMTNAME_SWGLOB "StarWriter/Global 4.0"
132 #define IO_DETECT_IMPL1 \
133 sal_Char __FAR_DATA FILTER_SWG[] = "SWG"; \
134 sal_Char __FAR_DATA FILTER_SW3[] = "CSW3"; \
135 sal_Char __FAR_DATA FILTER_SW4[] = "CSW4"; \
136 sal_Char __FAR_DATA FILTER_SW5[] = "CSW5"; \
137 sal_Char __FAR_DATA FILTER_BAS[] = "BAS"; \
138 sal_Char __FAR_DATA FILTER_RTF[] = "RTF"; \
139 sal_Char __FAR_DATA FILTER_W4W[] = "W4W"; \
140 sal_Char __FAR_DATA FILTER_SWGV[] = "SWGV"; \
141 sal_Char __FAR_DATA FILTER_SW3V[] = "CSW3V"; \
142 sal_Char __FAR_DATA FILTER_SW4V[] = "CSW4V"; \
143 sal_Char __FAR_DATA FILTER_SW5V[] = "CSW5V"; \
144 sal_Char __FAR_DATA FILTER_SWW4V[] = "CSW4VWEB"; \
145 sal_Char __FAR_DATA FILTER_SWW5V[] = "CSW5VWEB"; \
146 sal_Char __FAR_DATA sSwg1[] = "SWG1"; \
147 sal_Char __FAR_DATA sRtfWH[] = "WH_RTF"; \
148 sal_Char __FAR_DATA sCExcel[] = "CEXCEL"; \
149 sal_Char __FAR_DATA sExcel[] = "EXCEL"; \
150 sal_Char __FAR_DATA sLotusD[] = "LOTUSD"; \
151 sal_Char __FAR_DATA sLotusW[] = "LOTUSW"; \
152 sal_Char __FAR_DATA sHTML[] = "HTML"; \
153 sal_Char __FAR_DATA sWW1[] = "WW1"; \
154 sal_Char __FAR_DATA sWW5[] = "WW6"; \
155 sal_Char __FAR_DATA sWW6[] = "CWW6"; \
156 sal_Char __FAR_DATA FILTER_WW8[] = "CWW8"; \
157 sal_Char __FAR_DATA FILTER_TEXT_DLG[] = "TEXT_DLG"; \
158 sal_Char __FAR_DATA FILTER_TEXT[] = "TEXT"; \
159 sal_Char __FAR_DATA sW4W_Int[] = "W4_INT"; \
160 sal_Char __FAR_DATA sDebug[] = "DEBUG"; \
161 sal_Char __FAR_DATA sUndo[] = "UNDO"; \
162 sal_Char __FAR_DATA FILTER_XML[] = "CXML"; \
163 sal_Char __FAR_DATA FILTER_XMLV[] = "CXMLV"; \
164 sal_Char __FAR_DATA FILTER_XMLVW[] = "CXMLVWEB"; \
165 sal_Char __FAR_DATA sSwDos[] = "SW6"; \
168 SwIoDetect aReaderWriter[ MAXFILTER ] = { \
169 /* 0*/ SwIoEntry(FILTER_SW5, 4, &::binfilter::GetSw3Writer, TRUE), \
170 /* 1*/ SwIoEntry(FILTER_SW4, 4, &::binfilter::GetSw3Writer, FALSE), \
171 /* 2*/ SwIoEntry(FILTER_SW3, 4, &::binfilter::GetSw3Writer, FALSE), \
172 /* 3*/ SwIoEntry(FILTER_SWG, STRING_LEN, 0, TRUE), \
173 /* 4*/ SwIoEntry(FILTER_SWGV, 4, 0, FALSE), \
174 /* 5 SwIoEntry(FILTER_RTF, STRING_LEN, &::GetRTFWriter, TRUE), */\
175 /* 6*/ SwIoEntry(sSwDos, STRING_LEN, 0, TRUE), \
176 /* 7*/ SwIoEntry(FILTER_BAS, STRING_LEN, &::binfilter::GetASCWriter, FALSE), \
177 /* 8 SwIoEntry(sWW6, STRING_LEN, &::GetWW8Writer, TRUE), */\
178 /* 9 SwIoEntry(FILTER_WW8, STRING_LEN, &::GetWW8Writer, FALSE), */\
179 /* 10*/ SwIoEntry(FILTER_W4W, 3, &::binfilter::GetW4WWriter, TRUE), \
180 /* 11 SwIoEntry(sRtfWH, STRING_LEN, &::GetRTFWriter, FALSE), */\
181 /* 12*/ SwIoEntry(sCExcel, 5, 0, TRUE), \
182 /* 13*/ SwIoEntry(sExcel, 4, 0, FALSE), \
183 /* 14*/ SwIoEntry(sLotusD, 5, 0, TRUE), \
184 /* 15 SwIoEntry(sHTML, 4, &::GetHTMLWriter, TRUE), */\
185 /* 16 SwIoEntry(sWW1, STRING_LEN, 0, TRUE), */\
186 /* 17 SwIoEntry(sWW5, STRING_LEN, 0, FALSE), */\
187 /* 18*/ SwIoEntry(sSwg1, 4, 0, FALSE), \
188 /* 19*/ SwIoEntry(FILTER_XML, 4, &::binfilter::GetXMLWriter, TRUE) \
190 /* opt DEB_SH_SwIoEntry(sW4W_Int, STRING_LEN, 0, TRUE) */\
191 /* opt DEB_DBWRT_SwIoEntry(sDebug,STRING_LEN, &::GetDebugWriter, FALSE) */\
192 /* opt DEB_DBWRT_SwIoEntry(sUndo, STRING_LEN, &::GetUndoWriter, FALSE) */\
194 /*last*/ SwIoEntry(FILTER_TEXT, 4, &::binfilter::GetASCWriter, TRUE) \
202 SVBT16 wIdent
; // 0x0 int magic number
203 SVBT16 nFib
; // 0x2 FIB version written
204 SVBT16 nProduct
; // 0x4 product version written by
205 SVBT16 nlocale
; // 0x6 language stamp---localized version;
206 SVBT16 pnNext
; // 0x8
209 USHORT
nFibGet() { return SVBT16ToShort(nFib
); }
210 USHORT
wIdentGet() { return SVBT16ToShort(wIdent
); }
211 USHORT
fFlagsGet() { return SVBT16ToShort(fFlags
); }
212 // SVBT16 fComplex :1;// 0004 when 1, file is in complex, fast-saved format.
213 BOOL
fComplexGet() { return ((fFlagsGet() >> 2) & 1); }
215 #if OSL_DEBUG_LEVEL > 1
216 #define WW2B || ((W1_FIB*)pHeader)->wIdentGet() == 0xA5DB && \
217 ((W1_FIB*)pHeader)->nFibGet() == 0x2D
222 #if OSL_DEBUG_LEVEL > 1
223 #define WW3B || ((W1_FIB*)pHeader)->wIdentGet() == 0xA5DC && \
224 ((W1_FIB*)pHeader)->nFibGet() == 0x65
229 #define IO_DETECT_IMPL2 \
230 const sal_Char* SwIoDetect::IsReader(const sal_Char* pHeader, ULONG nLen, \
231 const String &rFileName) const \
234 if( FILTER_SWG == pName ) \
235 bRet = 0 == strncmp( FILTER_SWG, pHeader, 3 ) && \
236 '1' != *(pHeader + 3); \
237 else if( sSwg1 == pName ) \
238 bRet = 0 == strncmp( FILTER_SWG, pHeader, 3 ) && \
239 '1' == *(pHeader + 3); \
240 else if( sLotusD == pName ) \
241 bRet = 0 == *pHeader++ && 0 == *pHeader++ && \
242 2 == *pHeader++ && 0 == *pHeader++ && \
243 ( 4 == *pHeader || 6 == *pHeader ) && 4 == *++pHeader; \
244 else if( sExcel == pName ) \
246 if( 0x09 == *pHeader++ ) \
248 if( 0x00 == *pHeader ) \
249 bRet = 0x04 == *++pHeader && 0 == *++pHeader; \
250 else if( 0x02 == *pHeader || 0x04 == *pHeader ) \
251 bRet = 0x06 == *++pHeader && 0 == *++pHeader; \
254 else if( sWW5 == pName ) \
256 bRet = (( ((W1_FIB*)pHeader)->wIdentGet() == 0xA5DC \
257 && ((W1_FIB*)pHeader)->nFibGet() == 0x65 ) \
258 /*&& ((W1_FIB*)pHeader)->fComplexGet() == 0*/); \
260 else if( sWW1 == pName ) \
262 bRet = (( ((W1_FIB*)pHeader)->wIdentGet() == 0xA59C \
263 && ((W1_FIB*)pHeader)->nFibGet() == 0x21 \
264 WW2B ) && ((W1_FIB*)pHeader)->fComplexGet() == 0); \
266 else if( sSwDos == pName ) \
268 sal_Char __READONLY_DATA sSw6_FormatStt[] = ".\\\\\\ WRITER "; \
269 sal_Char __READONLY_DATA sSw6_FormatEnd[] = " \\\\\\"; \
271 bRet = 0 == strncmp( sSw6_FormatStt, pHeader, 12 ) && \
272 0 == strncmp( sSw6_FormatEnd, pHeader + 12 + 1, 4 ); \
274 else if (FILTER_TEXT == pName) \
275 bRet = SwIoSystem::IsDetectableText(pHeader, nLen); \
276 else if (FILTER_W4W == pName) \
277 bRet = SwIoSystem::IsDetectableW4W(rFileName); \
278 return bRet ? pName : 0; \
281 #define IO_DETECT_IMPL3 \
282 const String SwIoSystem::GetSubStorageName( const SfxFilter& rFltr ) \
284 /* bei den StorageFiltern noch den SubStorageNamen setzen */ \
285 const String& rUserData = rFltr.GetUserData(); \
286 if( rUserData.EqualsAscii(FILTER_SW5) || rUserData.EqualsAscii(FILTER_SW5V) || \
287 rUserData.EqualsAscii(FILTER_SWW5V) || \
288 rUserData.EqualsAscii(FILTER_SW4 )|| rUserData.EqualsAscii(FILTER_SW4V) || \
289 rUserData.EqualsAscii(FILTER_SWW4V) || \
290 rUserData.EqualsAscii(FILTER_SW3 )|| rUserData.EqualsAscii(FILTER_SW3V) ) \
291 return String::CreateFromAscii( \
292 RTL_CONSTASCII_STRINGPARAM( "StarWriterDocument" )); \
293 if( rUserData.EqualsAscii(FILTER_XML) || \
294 rUserData.EqualsAscii(FILTER_XMLV) || \
295 rUserData.EqualsAscii(FILTER_XMLVW) ) \
296 return String::CreateFromAscii( \
297 RTL_CONSTASCII_STRINGPARAM( "content.xml" )); \
298 if( rUserData.EqualsAscii(sWW6) || rUserData.EqualsAscii(FILTER_WW8) ) \
299 return String::CreateFromAscii( \
300 RTL_CONSTASCII_STRINGPARAM( "WordDocument" )); \
301 if( rUserData.EqualsAscii(sExcel) || rUserData.EqualsAscii(sCExcel) ) \
302 return String::CreateFromAscii( \
303 RTL_CONSTASCII_STRINGPARAM( "Book" )); \
304 return String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "" )); \
306 const SfxFilter* SwIoSystem::GetFilterOfFormat( const String& rFmtNm, \
307 const SfxFactoryFilterContainer* pCnt ) \
309 const SfxFactoryFilterContainer* pFltCnt = pCnt ? pCnt : \
310 ( IsDocShellRegistered() \
311 ? SwDocShell::Factory().GetFilterContainer() \
312 : SwWebDocShell::Factory().GetFilterContainer() ); \
317 const SfxFilter* pFilter; \
318 USHORT nCount = pFltCnt->GetFilterCount(); \
319 for( USHORT i = 0; i < nCount; ++i ) \
320 if( ( pFilter = pFltCnt->GetFilter( i ))->GetUserData() == rFmtNm ) \
323 if( pCnt || pFltCnt == SwWebDocShell::Factory().GetFilterContainer()) \
325 pFltCnt = SwWebDocShell::Factory().GetFilterContainer(); \
331 FASTBOOL SwIoSystem::IsValidStgFilter( SvStorage& rStg, const SfxFilter& rFilter ) \
333 ULONG nStgFmtId = rStg.GetFormat(); \
334 /*#i8409# We cannot trust the clipboard id anymore :-(*/ \
335 if( rFilter.GetUserData().EqualsAscii(FILTER_WW8) || \
336 rFilter.GetUserData().EqualsAscii(sWW6) ) \
341 BOOL bRet = SVSTREAM_OK == rStg.GetError() && \
342 ( !nStgFmtId || rFilter.GetFormat() == nStgFmtId ) && \
343 ( rStg.IsContained( SwIoSystem::GetSubStorageName( rFilter )) || \
344 (rFilter.GetUserData().EqualsAscii(FILTER_XML) && \
345 rStg.IsContained( String::CreateFromAscii("Content.xml") )) ); \
348 /* Bug 53445 - es gibt Excel Docs ohne ClipBoardId! */ \
349 /* Bug 62703 - und auch WinWord Docs ohne ClipBoardId! */ \
350 if( rFilter.GetUserData().EqualsAscii(FILTER_WW8) || \
351 rFilter.GetUserData().EqualsAscii(sWW6) ) \
353 bRet = !((rStg.IsContained( String::CreateFromAscii("0Table" )) || \
354 rStg.IsContained( String::CreateFromAscii("1Table" ))) ^ \
355 rFilter.GetUserData().EqualsAscii(FILTER_WW8)); \
356 if (bRet && !rFilter.IsAllowedAsTemplate()) \
358 SvStorageStreamRef xRef = \
359 rStg.OpenStream(String::CreateFromAscii("WordDocument"), \
360 STREAM_STD_READ | STREAM_NOCREATE ); \
364 bRet = !(nByte & 1); \
367 else if( rFilter.GetUserData().EqualsAscii(FILTER_XML, 0, sizeof(FILTER_XML)-1) ) \
368 bRet = !nStgFmtId || rFilter.GetFormat() == nStgFmtId; \
369 else if( !rFilter.GetUserData().EqualsAscii(sCExcel) ) \
370 bRet = rFilter.GetFormat() == nStgFmtId; \
375 /* Feststellen ob das File in dem entsprechenden Format vorliegt. */ \
376 /* Z.z werden nur unsere eigene Filter unterstuetzt */ \
377 FASTBOOL SwIoSystem::IsFileFilter( SfxMedium& rMedium, const String& rFmtName, \
378 const SfxFilter** ppFilter ) \
380 FASTBOOL bRet = FALSE; \
381 const SfxFilter* pFltr; \
382 const SfxFactoryFilterContainer& rFltContainer = IsDocShellRegistered() \
383 ? *SwDocShell::Factory().GetFilterContainer() \
384 : *SwWebDocShell::Factory().GetFilterContainer(); \
385 USHORT nFltCount = rFltContainer.GetFilterCount(); \
387 if( rMedium.IsStorage() ) \
388 xStg = rMedium.GetStorage(); \
389 for( USHORT n = 0; n < nFltCount; ++n ) \
390 if( ( pFltr = rFltContainer.GetFilter( n ))->GetUserData() == rFmtName ) \
392 if( 'C' == *pFltr->GetUserData().GetBuffer() ) \
394 bRet = xStg.Is() && IsValidStgFilter( *xStg, *pFltr ); \
396 else if( !xStg.Is() ) \
398 SvStream* pStrm = rMedium.GetInStream(); \
399 if( pStrm && !pStrm->GetError() ) \
401 sal_Char aBuffer[ 4097 ]; \
402 ULONG nBytesRead = pStrm->Read( aBuffer, 4096 ); \
403 pStrm->Seek( STREAM_SEEK_TO_BEGIN ); \
404 if( nBytesRead<=80 ) \
406 aBuffer[nBytesRead] = '\0'; \
407 aBuffer[nBytesRead+1] = '\0'; \
408 if( (nBytesRead & 0x00000001) != 0 ) \
409 aBuffer[nBytesRead+2] = '\0'; \
412 for( USHORT i = 0; i < MAXFILTER; ++i ) \
413 if( aReaderWriter[i].IsFilter( rFmtName ) ) \
415 bRet = 0 != aReaderWriter[i].IsReader( aBuffer, nBytesRead, rMedium.GetPhysicalName() ); \
421 if( bRet && ppFilter ) \
432 # define ENDHACK bool bNativeLE = true;
434 # define ENDHACK bool bNativeLE = false;
438 #define IO_DETECT_IMPL4 \
439 /* die Methode stellt fest, von welchem Typ der stream (File) ist. */ \
440 /* Es wird versucht, eine dem Filter entsprechende Byte-Folge zu finden. */ \
441 /* Wird kein entsprechender gefunden, wird zur Zeit der ASCII-Reader */ \
442 /* returnt !! Der Returnwert ist der interne Filtername! */ \
443 /* rPrefFltName ist der interne Name des Filters, den der Benutzer im */ \
444 /* Open-Dialog eingestellt hat. */ \
445 const SfxFilter* SwIoSystem::GetFileFilter( const String& rFileName, \
446 const String& rPrefFltName, \
447 SfxMedium* pMedium ) \
449 SfxFactoryFilterContainer* pFCntnr = IsDocShellRegistered() \
450 ? SwDocShell::Factory().GetFilterContainer() \
451 : SwWebDocShell::Factory().GetFilterContainer(); \
454 if( !pFCntnr || 0 == ( nFltrCount = pFCntnr->GetFilterCount() ) ) \
457 const SfxFilter* pFilter; \
458 if( pMedium ? pMedium->IsStorage() \
459 : SvStorage::IsStorageFile( rFileName ) ) \
461 /* Storage: Suchen nach einem Sub-Storage, dessen Name */ \
462 /* dem in einem Filter stehenden DLL-Namen entspricht */ \
465 xStg = pMedium->GetStorage(); \
467 xStg = new SvStorage( rFileName, STREAM_STD_READ ); \
469 if( xStg.Is() && ( xStg->GetError() == SVSTREAM_OK ) ) \
472 for( nCnt = 0; nCnt < nFltrCount; ++nCnt ) \
473 if( 'C' == *( pFilter = pFCntnr->GetFilter( nCnt ))-> \
474 GetUserData().GetBuffer() && \
475 IsValidStgFilter( *xStg, *pFilter )) \
478 if( IsDocShellRegistered() && 0 != ( pFCntnr = \
479 SwWebDocShell::Factory().GetFilterContainer() ) && \
480 0 != ( nFltrCount = pFCntnr->GetFilterCount() ) ) \
481 for( nCnt = 0; nCnt < nFltrCount; ++nCnt ) \
482 if( 'C' == *( pFilter = pFCntnr->GetFilter( nCnt ))-> \
483 GetUserData().GetBuffer() && \
484 IsValidStgFilter( *xStg, *pFilter )) \
490 sal_Char aBuffer[ 4098 ]; \
494 SvStream* pIStrm = pMedium->GetInStream(); \
495 if( !pIStrm || SVSTREAM_OK != pIStrm->GetError() ) \
497 ULONG nCurrPos = pIStrm->Tell(); \
498 nBytesRead = pIStrm->Read( aBuffer, 4096 ); \
499 pIStrm->Seek( nCurrPos ); \
503 SvFileStream aStrm( rFileName, STREAM_READ ); \
505 /* ohne FileName oder ohne Stream gibts nur den ANSI-Filter */ \
506 if( !rFileName.Len() || SVSTREAM_OK != aStrm.GetError() ) \
509 nBytesRead = aStrm.Read( aBuffer, 4096 ); \
512 DBG_ASSERT( nBytesRead<=4096, "zu viele Bytes gelesen?" ); \
513 if( nBytesRead <= 4096 ) \
515 aBuffer[nBytesRead] = '\0'; \
516 aBuffer[nBytesRead+1] = '\0'; \
517 if( (nBytesRead & 0x00000001) != 0 ) \
518 aBuffer[nBytesRead+2] = '\0'; \
521 /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ \
522 /* suche nach dem bestimmten Filter, falls kein entsprechender */ \
523 /* gefunden wird, so wird der ASCII-Filter returnt. */ \
524 /* Gibt es Filter ohne einen Identifizierungs-String, so werden diese */ \
525 /* nie erkannt und es wird auch der ASCII-Filter returnt. */ \
526 /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ \
528 const SfxFilter* pFilter; \
529 const sal_Char* pNm; \
530 for( USHORT n = 0; n < MAXFILTER; ++n ) \
531 if( 0 != ( pNm = aReaderWriter[n].IsReader(aBuffer, nBytesRead, rFileName)) && \
532 0 != ( pFilter = SwIoSystem::GetFilterOfFormat( \
533 String::CreateFromAscii(pNm), pFCntnr ))) \
537 /* Ok, bis jetzt kein Filter gefunden, also befrage mal die */ \
538 /* "WORD 4 WORD" Filter */ \
539 if( rFileName.Len() ) \
542 pMedium->CloseInStream(); \
543 USHORT nVersion, nW4WId = AutoDetec( rFileName, nVersion ); \
547 String aW4WName( String::CreateFromAscii(FILTER_W4W )); \
550 aW4WName += String::CreateFromInt32(nW4WId); \
552 aW4WName += String::CreateFromInt32(nVersion); \
554 for( USHORT nCnt = 0; nCnt < nFltrCount; ++nCnt ) \
555 if( 0 == ( pFilter = pFCntnr->GetFilter( nCnt ))-> \
556 GetUserData().Search( aW4WName )) \
559 W4W_CHECK_FOR_INTERNAL_FILTER \
560 W4W_FILTER_NOT_FOUND \
564 return SwIoSystem::GetTextFilter( aBuffer, nBytesRead); \
567 bool SwIoSystem::IsDetectableText(const sal_Char* pBuf, ULONG &rLen, \
568 CharSet *pCharSet, bool *pSwap, LineEnd *pLineEnd) \
570 bool bSwap = false; \
571 CharSet eCharSet = RTL_TEXTENCODING_DONTKNOW; \
574 /*See if its a known unicode type*/\
577 if (rLen > 2 && BYTE(pBuf[0]) == 0xEF && BYTE(pBuf[1]) == 0xBB && \
578 BYTE(pBuf[2]) == 0xBF)\
580 eCharSet = RTL_TEXTENCODING_UTF8;\
583 else if (BYTE(pBuf[0]) == 0xFE && BYTE(pBuf[1]) == 0xFF)\
585 eCharSet = RTL_TEXTENCODING_UCS2;\
589 else if (BYTE(pBuf[1]) == 0xFE && BYTE(pBuf[0]) == 0xFF)\
591 eCharSet = RTL_TEXTENCODING_UCS2;\
598 bool bCR = false, bLF = false, bNoNormalChar = false, \
599 bIsBareUnicode = false;\
601 if (eCharSet != RTL_TEXTENCODING_DONTKNOW)\
604 sal_Unicode *pNewBuf = sWork.AllocBuffer(rLen);\
606 if (eCharSet != RTL_TEXTENCODING_UCS2)\
609 rtl_TextToUnicodeConverter hConverter = \
610 rtl_createTextToUnicodeConverter(eCharSet);\
611 rtl_TextToUnicodeContext hContext = \
612 rtl_createTextToUnicodeContext(hConverter);\
616 nNewLen = rtl_convertTextToUnicode( hConverter, hContext, pBuf, \
617 rLen, pNewBuf, nNewLen, \
618 (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_DEFAULT | \
619 RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_DEFAULT | \
620 RTL_TEXTTOUNICODE_FLAGS_INVALID_DEFAULT), &nInfo, &nCntBytes);\
622 rtl_destroyTextToUnicodeContext(hConverter, hContext);\
623 rtl_destroyTextToUnicodeConverter(hConverter);\
628 memcpy(pNewBuf, pBuf, rLen);\
630 if (bLE != bNativeLE)\
633 sal_Char* pF = (sal_Char*)pNewBuf;\
634 sal_Char* pN = pF+1;\
635 for(xub_StrLen n = 0; n < nNewLen; ++n, pF+=2, pN+=2)\
644 sWork.ReleaseBufferAccess(nNewLen);\
645 pNewBuf = sWork.GetBufferAccess();\
647 for (ULONG nCnt = 0; nCnt < nNewLen; ++nCnt, ++pNewBuf)\
664 for( ULONG nCnt = 0; nCnt < rLen; ++nCnt, ++pBuf )\
669 if( nCnt + 1 < rLen && !*(pBuf+1) )\
671 bIsBareUnicode = true; \
684 if (0x20 > (BYTE)*pBuf)\
685 bNoNormalChar = true;\
691 LineEnd eSysLE = GetSystemLineEnd();\
696 eLineEnd = bCR ? ( bLF ? LINEEND_CRLF : LINEEND_CR ) : LINEEND_LF; \
699 *pCharSet = eCharSet;\
703 *pLineEnd = eLineEnd;\
705 return (!bIsBareUnicode && eSysLE == eLineEnd);\
709 const SfxFilter* SwIoSystem::GetTextFilter( const sal_Char* pBuf, ULONG nLen)\
711 bool bAuto = IsDetectableText(pBuf, nLen); \
712 const sal_Char* pNm = bAuto ? FILTER_TEXT : FILTER_TEXT_DLG; \
713 return SwIoSystem::GetFilterOfFormat( String::CreateFromAscii(pNm), 0 ); \
717 bool SwIoSystem::IsDetectableW4W(const String& rFileName) \
720 if (rFileName.Len()) \
722 USHORT nVersion, nW4WId = AutoDetec( rFileName, nVersion );\
729 } //namespace binfilter