1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sw.hxx"
26
27 #include <iodetect.hxx>
28
29 #include <errhdl.hxx>
30 #include <osl/endian.h>
31 #include <sot/storage.hxx>
32 #include <svtools/parhtml.hxx>
33 #include <tools/urlobj.hxx>
34
35 bool IsDocShellRegistered();
36
37 SwIoDetect aFilterDetect[] =
38 {
39 SwIoDetect( FILTER_RTF, STRING_LEN ),
40 SwIoDetect( FILTER_BAS, STRING_LEN ),
41 SwIoDetect( sWW6, STRING_LEN ),
42 SwIoDetect( FILTER_WW8, STRING_LEN ),
43 SwIoDetect( sRtfWH, STRING_LEN ),
44 SwIoDetect( sHTML, 4 ),
45 SwIoDetect( sWW1, STRING_LEN ),
46 SwIoDetect( sWW5, STRING_LEN ),
47 SwIoDetect( FILTER_XML, 4 ),
48 SwIoDetect( FILTER_TEXT_DLG, 8 ),
49 SwIoDetect( FILTER_TEXT, 4 )
50 };
51
IsReader(const sal_Char * pHeader,sal_uLong nLen_,const String &,const String &) const52 const sal_Char* SwIoDetect::IsReader(const sal_Char* pHeader, sal_uLong nLen_,
53 const String & /*rFileName*/, const String& /*rUserData*/) const
54 {
55 // Filter erkennung
56 struct W1_FIB
57 {
58 SVBT16 wIdent; // 0x0 int magic number
59 SVBT16 nFib; // 0x2 FIB version written
60 SVBT16 nProduct; // 0x4 product version written by
61 SVBT16 nlocale; // 0x6 language stamp---localized version;
62 SVBT16 pnNext; // 0x8
63 SVBT16 fFlags;
64
65 sal_uInt16 nFibGet() { return SVBT16ToShort(nFib); }
66 sal_uInt16 wIdentGet() { return SVBT16ToShort(wIdent); }
67 sal_uInt16 fFlagsGet() { return SVBT16ToShort(fFlags); }
68 // SVBT16 fComplex :1;// 0004 when 1, file is in complex, fast-saved format.
69 sal_Bool fComplexGet() { return static_cast< sal_Bool >((fFlagsGet() >> 2) & 1); }
70 };
71
72 int bRet = sal_False;
73 rtl::OString aName( pName );
74 if ( sHTML == aName )
75 bRet = HTMLParser::IsHTMLFormat( pHeader, sal_True, RTL_TEXTENCODING_DONTKNOW );
76 else if ( FILTER_RTF == aName )
77 bRet = 0 == strncmp( "{\\rtf", pHeader, 5 );
78 else if ( sWW5 == aName )
79 {
80 W1_FIB *pW1Header = (W1_FIB*)pHeader;
81 if (pW1Header->wIdentGet() == 0xA5DC && pW1Header->nFibGet() == 0x65)
82 bRet = true; /*WW5*/
83 else if (pW1Header->wIdentGet() == 0xA5DB && pW1Header->nFibGet() == 0x2D)
84 bRet = true; /*WW2*/
85 }
86 else if ( sWW1 == aName )
87 {
88 bRet = (( ((W1_FIB*)pHeader)->wIdentGet() == 0xA59C
89 && ((W1_FIB*)pHeader)->nFibGet() == 0x21)
90 && ((W1_FIB*)pHeader)->fComplexGet() == 0);
91 }
92 else if ( FILTER_TEXT == aName )
93 bRet = SwIoSystem::IsDetectableText(pHeader, nLen_);
94 else if ( FILTER_TEXT_DLG == aName)
95 bRet = SwIoSystem::IsDetectableText( pHeader, nLen_, 0, 0, 0, true);
96 return bRet ? pName : 0;
97 }
98
GetSubStorageName(const SfxFilter & rFltr)99 const String SwIoSystem::GetSubStorageName( const SfxFilter& rFltr )
100 {
101 /* bei den StorageFiltern noch den SubStorageNamen setzen */
102 const String& rUserData = rFltr.GetUserData();
103 if( rUserData.EqualsAscii(FILTER_XML) ||
104 rUserData.EqualsAscii(FILTER_XMLV) ||
105 rUserData.EqualsAscii(FILTER_XMLVW) )
106 return String::CreateFromAscii(
107 RTL_CONSTASCII_STRINGPARAM( "content.xml" ));
108 if( rUserData.EqualsAscii(sWW6) || rUserData.EqualsAscii(FILTER_WW8) )
109 return String::CreateFromAscii(
110 RTL_CONSTASCII_STRINGPARAM( "WordDocument" ));
111 return String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "" ));
112 }
113
GetFilterOfFormat(const String & rFmtNm,const SfxFilterContainer * pCnt)114 const SfxFilter* SwIoSystem::GetFilterOfFormat(const String& rFmtNm,
115 const SfxFilterContainer* pCnt)
116 {
117 SfxFilterContainer aCntSw( String::CreateFromAscii( sSWRITER ) );
118 SfxFilterContainer aCntSwWeb( String::CreateFromAscii( sSWRITERWEB ) );
119 const SfxFilterContainer* pFltCnt = pCnt ? pCnt : ( IsDocShellRegistered() ? &aCntSw : &aCntSwWeb );
120
121 do {
122 if( pFltCnt )
123 {
124 SfxFilterMatcher aMatcher( pFltCnt->GetName() );
125 SfxFilterMatcherIter aIter( &aMatcher );
126 const SfxFilter* pFilter = aIter.First();
127 while ( pFilter )
128 {
129 if( pFilter->GetUserData() == rFmtNm )
130 return pFilter;
131 pFilter = aIter.Next();
132 }
133 }
134 if( pCnt || pFltCnt == &aCntSwWeb )
135 break;
136 pFltCnt = &aCntSwWeb;
137 } while( sal_True );
138 return 0;
139 }
140
IsValidStgFilter(const com::sun::star::uno::Reference<com::sun::star::embed::XStorage> & rStg,const SfxFilter & rFilter)141 sal_Bool SwIoSystem::IsValidStgFilter( const com::sun::star::uno::Reference < com::sun::star::embed::XStorage >& rStg, const SfxFilter& rFilter)
142 {
143 sal_Bool bRet = sal_False;
144 try
145 {
146 sal_uLong nStgFmtId = SotStorage::GetFormatID( rStg );
147 bRet = rStg->isStreamElement( ::rtl::OUString::createFromAscii("content.xml") );
148 if ( bRet )
149 bRet = ( nStgFmtId && ( rFilter.GetFormat() == nStgFmtId ) );
150 }
151 catch ( com::sun::star::uno::Exception& )
152 {
153 }
154
155 return bRet;
156 }
157
IsValidStgFilter(SotStorage & rStg,const SfxFilter & rFilter)158 sal_Bool SwIoSystem::IsValidStgFilter(SotStorage& rStg, const SfxFilter& rFilter)
159 {
160 sal_uLong nStgFmtId = rStg.GetFormat();
161 /*#i8409# We cannot trust the clipboard id anymore :-(*/
162 if( rFilter.GetUserData().EqualsAscii(FILTER_WW8) ||
163 rFilter.GetUserData().EqualsAscii(sWW6) )
164 {
165 nStgFmtId = 0;
166 }
167
168 sal_Bool bRet = SVSTREAM_OK == rStg.GetError() &&
169 ( !nStgFmtId || rFilter.GetFormat() == nStgFmtId ) &&
170 ( rStg.IsContained( SwIoSystem::GetSubStorageName( rFilter )) );
171 if( bRet )
172 {
173 /* Bug 53445 - es gibt Excel Docs ohne ClipBoardId! */
174 /* Bug 62703 - und auch WinWord Docs ohne ClipBoardId! */
175 if( rFilter.GetUserData().EqualsAscii(FILTER_WW8) ||
176 rFilter.GetUserData().EqualsAscii(sWW6) )
177 {
178 bRet = !((rStg.IsContained( String::CreateFromAscii("0Table" )) ||
179 rStg.IsContained( String::CreateFromAscii("1Table" ))) ^
180 rFilter.GetUserData().EqualsAscii(FILTER_WW8));
181 if (bRet && !rFilter.IsAllowedAsTemplate())
182 {
183 SotStorageStreamRef xRef =
184 rStg.OpenSotStream(String::CreateFromAscii("WordDocument"),
185 STREAM_STD_READ | STREAM_NOCREATE );
186 xRef->Seek(10);
187 sal_uInt8 nByte;
188 *xRef >> nByte;
189 bRet = !(nByte & 1);
190 }
191 }
192 // else if( !rFilter.GetUserData().EqualsAscii(sCExcel) )
193 // bRet = rFilter.GetFormat() == nStgFmtId;
194 }
195 return bRet;
196 }
197
TerminateBuffer(sal_Char * pBuffer,sal_uLong nBytesRead,sal_uLong nBufferLen)198 void TerminateBuffer(sal_Char *pBuffer, sal_uLong nBytesRead, sal_uLong nBufferLen)
199 {
200 ASSERT(nBytesRead <= nBufferLen - 2,
201 "what you read must be less than the max + null termination");
202 ASSERT(!(nBufferLen & 0x00000001), "nMaxReadBuf must be an even number");
203 if (nBytesRead <= nBufferLen - 2)
204 {
205 pBuffer[nBytesRead] = '\0';
206 pBuffer[nBytesRead+1] = '\0';
207 if (nBytesRead & 0x00000001)
208 pBuffer[nBytesRead+2] = '\0';
209 }
210 }
211
212 /* Feststellen ob das File in dem entsprechenden Format vorliegt. */
213 /* Z.z werden nur unsere eigene Filter unterstuetzt */
IsFileFilter(SfxMedium & rMedium,const String & rFmtName,const SfxFilter ** ppFilter)214 sal_Bool SwIoSystem::IsFileFilter( SfxMedium& rMedium, const String& rFmtName,
215 const SfxFilter** ppFilter )
216 {
217 sal_Bool bRet = sal_False;
218
219 SfxFilterContainer aCntSw( String::CreateFromAscii( sSWRITER ) );
220 SfxFilterContainer aCntSwWeb( String::CreateFromAscii( sSWRITERWEB ) );
221 const SfxFilterContainer& rFltContainer = IsDocShellRegistered() ? aCntSw : aCntSwWeb;
222
223 com::sun::star::uno::Reference < com::sun::star::embed::XStorage > xStor;
224 SotStorageRef xStg;
225 if (rMedium.IsStorage())
226 xStor = rMedium.GetStorage();
227 else
228 {
229 SvStream* pStream = rMedium.GetInStream();
230 if ( pStream && SotStorage::IsStorageFile(pStream) )
231 xStg = new SotStorage( pStream, sal_False );
232 }
233
234 SfxFilterMatcher aMatcher( rFltContainer.GetName() );
235 SfxFilterMatcherIter aIter( &aMatcher );
236 const SfxFilter* pFltr = aIter.First();
237 while ( pFltr )
238 {
239 if( pFltr->GetUserData() == rFmtName )
240 {
241 const String& rUserData = pFltr->GetUserData();
242 if( 'C' == *rUserData.GetBuffer() )
243 {
244 if ( xStor.is() )
245 bRet = IsValidStgFilter( xStor, *pFltr );
246 else if ( xStg.Is() )
247 bRet = xStg.Is() && IsValidStgFilter( *xStg, *pFltr );
248 bRet = bRet && (pFltr->GetUserData() == rFmtName);
249 }
250 else if( !xStg.Is() && !xStor.is() )
251 {
252 SvStream* pStrm = rMedium.GetInStream();
253 if( pStrm && !pStrm->GetError() )
254 {
255 sal_Char aBuffer[4098];
256 const sal_uLong nMaxRead = sizeof(aBuffer) - 2;
257 sal_uLong nBytesRead = pStrm->Read(aBuffer, nMaxRead);
258 pStrm->Seek(STREAM_SEEK_TO_BEGIN);
259 TerminateBuffer(aBuffer, nBytesRead, sizeof(aBuffer));
260 for (sal_uInt16 i = 0; i < MAXFILTER; ++i)
261 {
262 if (aFilterDetect[i].IsFilter(rFmtName))
263 {
264 bRet = 0 != aFilterDetect[i].IsReader( aBuffer, nBytesRead,
265 rMedium.GetPhysicalName(), rUserData );
266 break;
267 }
268 }
269 }
270 }
271
272 if( bRet && ppFilter )
273 *ppFilter = pFltr;
274 }
275
276 pFltr = aIter.Next();
277 }
278
279 return bRet;
280 }
281
282 /* die Methode stellt fest, von welchem Typ der stream (File) ist. */
283 /* Es wird versucht, eine dem Filter entsprechende Byte-Folge zu finden. */
284 /* Wird kein entsprechender gefunden, wird zur Zeit der ASCII-Reader */
285 /* returnt !! Der Returnwert ist der interne Filtername! */
286 /* rPrefFltName ist der interne Name des Filters, den der Benutzer im */
287 /* Open-Dialog eingestellt hat. */
GetFileFilter(const String & rFileName,const String & rPrefFltName,SfxMedium * pMedium)288 const SfxFilter* SwIoSystem::GetFileFilter(const String& rFileName,
289 const String& rPrefFltName, SfxMedium* pMedium)
290 {
291 SfxFilterContainer aCntSw( String::CreateFromAscii( sSWRITER ) );
292 SfxFilterContainer aCntSwWeb( String::CreateFromAscii( sSWRITERWEB ) );
293 const SfxFilterContainer* pFCntnr = IsDocShellRegistered() ? &aCntSw : &aCntSwWeb;
294
295 if( !pFCntnr )
296 return 0;
297
298 SfxFilterMatcher aMatcher( pFCntnr->GetName() );
299 SfxFilterMatcherIter aIter( &aMatcher );
300 const SfxFilter* pFilter = aIter.First();
301 if ( !pFilter )
302 return 0;
303
304 if( pMedium ? ( pMedium->IsStorage() || SotStorage::IsStorageFile( pMedium->GetInStream() ) ) : SotStorage::IsStorageFile( rFileName ) )
305 {
306 // package storage or OLEStorage based format
307 SotStorageRef xStg;
308 sal_Bool bDeleteMedium = sal_False;
309 if (!pMedium )
310 {
311 INetURLObject aObj;
312 aObj.SetSmartProtocol( INET_PROT_FILE );
313 aObj.SetSmartURL( rFileName );
314 pMedium = new SfxMedium( aObj.GetMainURL( INetURLObject::NO_DECODE ), STREAM_STD_READ, sal_False );
315 bDeleteMedium = sal_True;
316 }
317
318 // templates should not get precedence over "normal" filters (#i35508, #i33168)
319 const SfxFilter* pTemplateFilter = 0;
320 const SfxFilter* pOldFilter = pFCntnr->GetFilter4FilterName( rPrefFltName );
321 sal_Bool bLookForTemplate = pOldFilter && pOldFilter->IsOwnTemplateFormat();
322 if ( pMedium->IsStorage() )
323 {
324 com::sun::star::uno::Reference < com::sun::star::embed::XStorage > xStor = pMedium->GetStorage();
325 if ( xStor.is() )
326 {
327 while ( pFilter )
328 {
329 if( 'C' == *pFilter->GetUserData().GetBuffer() && IsValidStgFilter( xStor, *pFilter ) )
330 {
331 if ( pFilter->IsOwnTemplateFormat() && !bLookForTemplate )
332 // found template filter; maybe there's a "normal" one also
333 pTemplateFilter = pFilter;
334 else
335 return pFilter;
336 }
337
338 pFilter = aIter.Next();
339 }
340
341 // there's only a template filter that could be found
342 if ( pTemplateFilter )
343 pFilter = pTemplateFilter;
344 }
345 }
346 else
347 {
348 SvStream* pStream = pMedium->GetInStream();
349 if ( pStream && SotStorage::IsStorageFile(pStream) )
350 xStg = new SotStorage( pStream, sal_False );
351
352 if( xStg.Is() && ( xStg->GetError() == SVSTREAM_OK ) )
353 {
354 while ( pFilter )
355 {
356 if( 'C' == *pFilter->GetUserData().GetBuffer() && IsValidStgFilter( *xStg, *pFilter ) )
357 {
358 if ( pFilter->IsOwnTemplateFormat() && !bLookForTemplate )
359 // found template filter; maybe there's a "normal" one also
360 pTemplateFilter = pFilter;
361 else
362 return pFilter;
363 }
364
365 pFilter = aIter.Next();
366 }
367
368 // there's only a template filter that could be found
369 if ( pTemplateFilter )
370 pFilter = pTemplateFilter;
371
372 }
373 }
374
375 return pFilter;
376 }
377
378 sal_Char aBuffer[4098];
379 const sal_uLong nMaxRead = sizeof(aBuffer) - 2;
380 sal_uLong nBytesRead = 0;
381 if (pMedium)
382 {
383 SvStream* pIStrm = pMedium->GetInStream();
384 if( !pIStrm || SVSTREAM_OK != pIStrm->GetError() )
385 return 0;
386 sal_uLong nCurrPos = pIStrm->Tell();
387 nBytesRead = pIStrm->Read(aBuffer, nMaxRead);
388 pIStrm->Seek( nCurrPos );
389 }
390 /*
391 else
392 {
393 SvFileStream aStrm( rFileName, STREAM_READ );
394
395 // ohne FileName oder ohne Stream gibts nur den ANSI-Filter
396 if( !rFileName.Len() || SVSTREAM_OK != aStrm.GetError() )
397 return 0;
398
399 nBytesRead = aStrm.Read(aBuffer, nMaxRead);
400 aStrm.Close();
401 }*/
402
403 TerminateBuffer(aBuffer, nBytesRead, sizeof(aBuffer));
404
405
406 /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
407 /* suche nach dem bestimmten Filter, falls kein entsprechender */
408 /* gefunden wird, so wird der ASCII-Filter returnt. */
409 /* Gibt es Filter ohne einen Identifizierungs-String, so werden diese */
410 /* nie erkannt und es wird auch der ASCII-Filter returnt. */
411 /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
412 {
413 const SfxFilter* pFilterTmp = 0;
414 const sal_Char* pNm;
415 for( sal_uInt16 n = 0; n < MAXFILTER; ++n )
416 {
417 String sEmptyUserData;
418 pNm = aFilterDetect[n].IsReader(aBuffer, nBytesRead, rFileName, sEmptyUserData);
419 pFilterTmp = pNm ? SwIoSystem::GetFilterOfFormat(String::CreateFromAscii(pNm), pFCntnr) : 0;
420 if (pNm && pFilterTmp)
421 {
422 return pFilterTmp;
423 }
424 }
425 }
426
427 /* Ok, bis jetzt kein Filter gefunden, also befrage mal die */
428 /* "WORD 4 WORD" Filter */
429 if( rFileName.Len() )
430 {
431 if( pMedium )
432 pMedium->CloseInStream();
433
434 }
435 return SwIoSystem::GetTextFilter( aBuffer, nBytesRead);
436 }
437
IsDetectableText(const sal_Char * pBuf,sal_uLong & rLen,CharSet * pCharSet,bool * pSwap,LineEnd * pLineEnd,bool bEncodedFilter)438 bool SwIoSystem::IsDetectableText(const sal_Char* pBuf, sal_uLong &rLen,
439 CharSet *pCharSet, bool *pSwap, LineEnd *pLineEnd, bool bEncodedFilter)
440 {
441 bool bSwap = false;
442 CharSet eCharSet = RTL_TEXTENCODING_DONTKNOW;
443 bool bLE = true;
444 sal_uLong nHead=0;
445 /*See if its a known unicode type*/
446 if (rLen >= 2)
447 {
448 if (rLen > 2 && sal_uInt8(pBuf[0]) == 0xEF && sal_uInt8(pBuf[1]) == 0xBB &&
449 sal_uInt8(pBuf[2]) == 0xBF)
450 {
451 eCharSet = RTL_TEXTENCODING_UTF8;
452 nHead = 3;
453 }
454 else if (sal_uInt8(pBuf[0]) == 0xFE && sal_uInt8(pBuf[1]) == 0xFF)
455 {
456 eCharSet = RTL_TEXTENCODING_UCS2;
457 bLE = false;
458 nHead = 2;
459 }
460 else if (sal_uInt8(pBuf[1]) == 0xFE && sal_uInt8(pBuf[0]) == 0xFF)
461 {
462 eCharSet = RTL_TEXTENCODING_UCS2;
463 nHead = 2;
464 }
465 pBuf+=nHead;
466 rLen-=nHead;
467 }
468
469 bool bCR = false, bLF = false, bNoNormalChar = false,
470 bIsBareUnicode = false;
471
472 if (eCharSet != RTL_TEXTENCODING_DONTKNOW)
473 {
474 String sWork;
475 sal_Unicode *pNewBuf = sWork.AllocBuffer( static_cast< xub_StrLen >(rLen));
476 sal_Size nNewLen;
477 if (eCharSet != RTL_TEXTENCODING_UCS2)
478 {
479 nNewLen = rLen;
480 rtl_TextToUnicodeConverter hConverter =
481 rtl_createTextToUnicodeConverter(eCharSet);
482 rtl_TextToUnicodeContext hContext =
483 rtl_createTextToUnicodeContext(hConverter);
484
485 sal_Size nCntBytes;
486 sal_uInt32 nInfo;
487 nNewLen = rtl_convertTextToUnicode( hConverter, hContext, pBuf,
488 rLen, pNewBuf, nNewLen,
489 (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_DEFAULT |
490 RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_DEFAULT |
491 RTL_TEXTTOUNICODE_FLAGS_INVALID_DEFAULT), &nInfo, &nCntBytes);
492
493 rtl_destroyTextToUnicodeContext(hConverter, hContext);
494 rtl_destroyTextToUnicodeConverter(hConverter);
495 }
496 else
497 {
498 nNewLen = rLen/2;
499 memcpy(pNewBuf, pBuf, rLen);
500 #ifdef OSL_LITENDIAN
501 bool bNativeLE = true;
502 #else
503 bool bNativeLE = false;
504 #endif
505 if (bLE != bNativeLE)
506 {
507 bSwap = true;
508 sal_Char* pF = (sal_Char*)pNewBuf;
509 sal_Char* pN = pF+1;
510 for(xub_StrLen n = 0; n < nNewLen; ++n, pF+=2, pN+=2)
511 {
512 sal_Char c = *pF;
513 *pF = *pN;
514 *pN = c;
515 }
516 }
517 }
518
519 sWork.ReleaseBufferAccess( static_cast< xub_StrLen >(nNewLen) );
520 pNewBuf = sWork.GetBufferAccess();
521
522 for (sal_uLong nCnt = 0; nCnt < nNewLen; ++nCnt, ++pNewBuf)
523 {
524 switch (*pNewBuf)
525 {
526 case 0xA:
527 bLF = true;
528 break;
529 case 0xD:
530 bCR = true;
531 break;
532 default:
533 break;
534 }
535 }
536 }
537 else
538 {
539 for( sal_uLong nCnt = 0; nCnt < rLen; ++nCnt, ++pBuf )
540 {
541 switch (*pBuf)
542 {
543 case 0x0:
544 if( nCnt + 1 < rLen && !*(pBuf+1) )
545 return 0;
546 bIsBareUnicode = true;
547 break;
548 case 0xA:
549 bLF = true;
550 break;
551 case 0xD:
552 bCR = true;
553 break;
554 case 0xC:
555 case 0x1A:
556 case 0x9:
557 break;
558 default:
559 if (0x20 > (sal_uInt8)*pBuf)
560 bNoNormalChar = true;
561 break;
562 }
563 }
564 }
565
566 LineEnd eSysLE = GetSystemLineEnd();
567 LineEnd eLineEnd;
568 if (!bCR && !bLF)
569 eLineEnd = eSysLE;
570 else
571 eLineEnd = bCR ? ( bLF ? LINEEND_CRLF : LINEEND_CR ) : LINEEND_LF;
572
573 if (pCharSet)
574 *pCharSet = eCharSet;
575 if (pSwap)
576 *pSwap = bSwap;
577 if (pLineEnd)
578 *pLineEnd = eLineEnd;
579
580 return bEncodedFilter || (!bIsBareUnicode && eSysLE == eLineEnd);
581 }
582
GetTextFilter(const sal_Char * pBuf,sal_uLong nLen)583 const SfxFilter* SwIoSystem::GetTextFilter( const sal_Char* pBuf, sal_uLong nLen)
584 {
585 bool bAuto = IsDetectableText(pBuf, nLen);
586 const sal_Char* pNm = bAuto ? FILTER_TEXT : FILTER_TEXT_DLG;
587 return SwIoSystem::GetFilterOfFormat( String::CreateFromAscii(pNm), 0 );
588 }
589