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