LCOV - code coverage report
Current view: top level - sw/source/filter/basflt - iodetect.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 48 171 28.1 %
Date: 2014-11-03 Functions: 7 10 70.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <iodetect.hxx>
      21             : #include <boost/scoped_array.hpp>
      22             : #include <osl/endian.h>
      23             : #include <sot/storage.hxx>
      24             : #include <svtools/parhtml.hxx>
      25             : #include <tools/urlobj.hxx>
      26             : #include <unotools/moduleoptions.hxx>
      27             : 
      28             : 
      29             : using namespace ::com::sun::star;
      30             : 
      31           4 : static bool IsDocShellRegistered()
      32             : {
      33           4 :     return SvtModuleOptions().IsWriter();
      34             : }
      35             : 
      36         180 : SwIoDetect aFilterDetect[] =
      37             : {
      38             :     SwIoDetect( FILTER_RTF ),
      39             :     SwIoDetect( FILTER_BAS ),
      40             :     SwIoDetect( sWW6 ),
      41             :     SwIoDetect( FILTER_WW8 ),
      42             :     SwIoDetect( sRtfWH ),
      43             :     SwIoDetect( sHTML ),
      44             :     SwIoDetect( sWW5 ),
      45             :     SwIoDetect( FILTER_XML ),
      46             :     SwIoDetect( FILTER_TEXT_DLG ),
      47             :     SwIoDetect( FILTER_TEXT )
      48          90 : };
      49             : 
      50           0 : const OUString SwIoSystem::GetSubStorageName( const SfxFilter& rFltr )
      51             : {
      52             :     // for StorageFilters also set the SubStorageName
      53           0 :     const OUString& rUserData = rFltr.GetUserData();
      54           0 :     if (rUserData == FILTER_XML ||
      55           0 :         rUserData == FILTER_XMLV ||
      56           0 :         rUserData == FILTER_XMLVW)
      57           0 :         return OUString("content.xml");
      58           0 :     if (rUserData == sWW6 || rUserData == FILTER_WW8)
      59           0 :         return OUString("WordDocument");
      60           0 :     return OUString();
      61             : }
      62             : 
      63           4 : const SfxFilter* SwIoSystem::GetFilterOfFormat(const OUString& rFmtNm,
      64             :     const SfxFilterContainer* pCnt)
      65             : {
      66           4 :     SfxFilterContainer aCntSw( OUString(sSWRITER) );
      67           8 :     SfxFilterContainer aCntSwWeb( OUString(sSWRITERWEB) );
      68           4 :     const SfxFilterContainer* pFltCnt = pCnt ? pCnt : ( IsDocShellRegistered() ? &aCntSw : &aCntSwWeb );
      69             : 
      70             :     do {
      71           4 :         if( pFltCnt )
      72             :         {
      73           4 :             SfxFilterMatcher aMatcher( pFltCnt->GetName() );
      74           4 :             SfxFilterMatcherIter aIter( aMatcher );
      75           4 :             const SfxFilter* pFilter = aIter.First();
      76           8 :             while ( pFilter )
      77             :             {
      78           4 :                 if( pFilter->GetUserData().equals(rFmtNm) )
      79           4 :                     return pFilter;
      80           0 :                 pFilter = aIter.Next();
      81           0 :             }
      82             :         }
      83           0 :         if( pCnt || pFltCnt == &aCntSwWeb )
      84             :             break;
      85           0 :         pFltCnt = &aCntSwWeb;
      86             :     } while( true );
      87           4 :     return 0;
      88             : }
      89             : 
      90           4 : bool SwIoSystem::IsValidStgFilter( const com::sun::star::uno::Reference < com::sun::star::embed::XStorage >& rStg, const SfxFilter& rFilter)
      91             : {
      92           4 :     bool bRet = false;
      93             :     try
      94             :     {
      95           4 :         sal_uLong nStgFmtId = SotStorage::GetFormatID( rStg );
      96           4 :         bRet = rStg->isStreamElement( OUString("content.xml") );
      97           4 :         if ( bRet )
      98           4 :             bRet = ( nStgFmtId && ( rFilter.GetFormat() == nStgFmtId ) );
      99             :     }
     100           0 :     catch (const com::sun::star::uno::Exception& )
     101             :     {
     102             :     }
     103             : 
     104           4 :     return bRet;
     105             : }
     106             : 
     107           0 : bool SwIoSystem::IsValidStgFilter(SotStorage& rStg, const SfxFilter& rFilter)
     108             : {
     109           0 :     sal_uLong nStgFmtId = rStg.GetFormat();
     110             :     /*#i8409# We cannot trust the clipboard id anymore :-(*/
     111           0 :     if (rFilter.GetUserData() == FILTER_WW8 || rFilter.GetUserData() == sWW6)
     112           0 :         nStgFmtId = 0;
     113             : 
     114           0 :     bool bRet = SVSTREAM_OK == rStg.GetError() &&
     115           0 :         ( !nStgFmtId || rFilter.GetFormat() == nStgFmtId ) &&
     116           0 :         ( rStg.IsContained( SwIoSystem::GetSubStorageName( rFilter )) );
     117           0 :     if( bRet )
     118             :     {
     119             :         /* Bug 53445 - there are Excel Docs w/o ClipBoardId! */
     120             :         /* Bug 62703 - and also WinWord Docs w/o ClipBoardId! */
     121           0 :         if (rFilter.GetUserData() == FILTER_WW8 || rFilter.GetUserData() == sWW6)
     122             :         {
     123           0 :             bRet = (rStg.IsContained(OUString("0Table"))
     124           0 :                     || rStg.IsContained(OUString("1Table")))
     125           0 :                 == (rFilter.GetUserData() == FILTER_WW8);
     126           0 :             if (bRet && !rFilter.IsAllowedAsTemplate())
     127             :             {
     128             :                 SotStorageStreamRef xRef =
     129             :                     rStg.OpenSotStream(OUString("WordDocument"),
     130           0 :                             STREAM_STD_READ | STREAM_NOCREATE );
     131           0 :                 xRef->Seek(10);
     132             :                 sal_uInt8 nByte;
     133           0 :                 xRef->ReadUChar( nByte );
     134           0 :                 bRet = !(nByte & 1);
     135             :             }
     136             :         }
     137             :     }
     138           0 :     return bRet;
     139             : }
     140             : 
     141             : // Check the type of the stream (file) by searching for corresponding set of bytes.
     142             : // If no known type is found, return ASCII for now!
     143             : // Returns the internal FilterName.
     144           4 : const SfxFilter* SwIoSystem::GetFileFilter(const OUString& rFileName)
     145             : {
     146           4 :     SfxFilterContainer aCntSw( OUString(sSWRITER) );
     147           8 :     SfxFilterContainer aCntSwWeb( OUString(sSWRITERWEB) );
     148           4 :     const SfxFilterContainer* pFCntnr = IsDocShellRegistered() ? &aCntSw : &aCntSwWeb;
     149             : 
     150           8 :     SfxFilterMatcher aMatcher( pFCntnr->GetName() );
     151           4 :     SfxFilterMatcherIter aIter( aMatcher );
     152           4 :     const SfxFilter* pFilter = aIter.First();
     153           4 :     if ( !pFilter )
     154           0 :         return 0;
     155             : 
     156           4 :     if (SotStorage::IsStorageFile(rFileName))
     157             :     {
     158             :         // package storage or OLEStorage based format
     159           4 :         SotStorageRef xStg;
     160           8 :         INetURLObject aObj;
     161           4 :         aObj.SetSmartProtocol( INET_PROT_FILE );
     162           4 :         aObj.SetSmartURL( rFileName );
     163           8 :         SfxMedium aMedium(aObj.GetMainURL(INetURLObject::NO_DECODE), STREAM_STD_READ);
     164             : 
     165             :         // templates should not get precedence over "normal" filters (#i35508, #i33168)
     166           4 :         const SfxFilter* pTemplateFilter = 0;
     167           4 :         if (aMedium.IsStorage())
     168             :         {
     169           4 :             uno::Reference<embed::XStorage> const xStor = aMedium.GetStorage();
     170           4 :             if ( xStor.is() )
     171             :             {
     172           8 :                 while ( pFilter )
     173             :                 {
     174           4 :                     if (pFilter->GetUserData().startsWith("C") && IsValidStgFilter(xStor, *pFilter ))
     175             :                     {
     176           4 :                         if (pFilter->IsOwnTemplateFormat())
     177             :                         {
     178             :                             // found template filter; maybe there's a "normal" one also
     179           0 :                             pTemplateFilter = pFilter;
     180             :                         }
     181             :                         else
     182           4 :                             return pFilter;
     183             :                     }
     184             : 
     185           0 :                     pFilter = aIter.Next();
     186             :                 }
     187             : 
     188             :                 // there's only a template filter that could be found
     189           0 :                 if ( pTemplateFilter )
     190           0 :                     pFilter = pTemplateFilter;
     191           0 :             }
     192             :         }
     193             :         else
     194             :         {
     195             :             try
     196             :             {
     197           0 :                 SvStream *const pStream = aMedium.GetInStream();
     198           0 :                 if ( pStream && SotStorage::IsStorageFile(pStream) )
     199           0 :                     xStg = new SotStorage( pStream, false );
     200             :             }
     201           0 :             catch (const css::ucb::ContentCreationException &)
     202             :             {
     203             :             }
     204             : 
     205           0 :             if( xStg.Is() && ( xStg->GetError() == SVSTREAM_OK ) )
     206             :             {
     207           0 :                 while ( pFilter )
     208             :                 {
     209           0 :                     if (pFilter->GetUserData().startsWith("C") && IsValidStgFilter(*xStg, *pFilter))
     210             :                     {
     211           0 :                         if (pFilter->IsOwnTemplateFormat())
     212             :                         {
     213             :                             // found template filter; maybe there's a "normal" one also
     214           0 :                             pTemplateFilter = pFilter;
     215             :                         }
     216             :                         else
     217           0 :                             return pFilter;
     218             :                     }
     219             : 
     220           0 :                     pFilter = aIter.Next();
     221             :                 }
     222             : 
     223             :                 // there's only a template filter that could be found
     224           0 :                 if ( pTemplateFilter )
     225           0 :                     pFilter = pTemplateFilter;
     226             : 
     227             :             }
     228             :         }
     229             : 
     230           4 :         return pFilter;
     231             :     }
     232             : 
     233           4 :     return SwIoSystem::GetFilterOfFormat(OUString::createFromAscii(FILTER_TEXT), 0);
     234             : }
     235             : 
     236           0 : bool SwIoSystem::IsDetectableText(const sal_Char* pBuf, sal_uLong &rLen,
     237             :     rtl_TextEncoding *pCharSet, bool *pSwap, LineEnd *pLineEnd, bool bEncodedFilter)
     238             : {
     239           0 :     bool bSwap = false;
     240           0 :     rtl_TextEncoding eCharSet = RTL_TEXTENCODING_DONTKNOW;
     241           0 :     bool bLE = true;
     242             :     /*See if it's a known unicode type*/
     243           0 :     if (rLen >= 2)
     244             :     {
     245           0 :         sal_uLong nHead=0;
     246           0 :         if (rLen > 2 && sal_uInt8(pBuf[0]) == 0xEF && sal_uInt8(pBuf[1]) == 0xBB &&
     247           0 :             sal_uInt8(pBuf[2]) == 0xBF)
     248             :         {
     249           0 :             eCharSet = RTL_TEXTENCODING_UTF8;
     250           0 :             nHead = 3;
     251             :         }
     252           0 :         else if (sal_uInt8(pBuf[0]) == 0xFE && sal_uInt8(pBuf[1]) == 0xFF)
     253             :         {
     254           0 :             eCharSet = RTL_TEXTENCODING_UCS2;
     255           0 :             bLE = false;
     256           0 :             nHead = 2;
     257             :         }
     258           0 :         else if (sal_uInt8(pBuf[1]) == 0xFE && sal_uInt8(pBuf[0]) == 0xFF)
     259             :         {
     260           0 :             eCharSet = RTL_TEXTENCODING_UCS2;
     261           0 :             nHead = 2;
     262             :         }
     263           0 :         pBuf+=nHead;
     264           0 :         rLen-=nHead;
     265             :     }
     266             : 
     267           0 :     bool bCR = false, bLF = false, bIsBareUnicode = false;
     268             : 
     269           0 :     if (eCharSet != RTL_TEXTENCODING_DONTKNOW)
     270             :     {
     271           0 :         boost::scoped_array<sal_Unicode> aWork(new sal_Unicode[rLen+1]);
     272           0 :         sal_Unicode *pNewBuf = aWork.get();
     273             :         sal_Size nNewLen;
     274           0 :         if (eCharSet != RTL_TEXTENCODING_UCS2)
     275             :         {
     276           0 :             nNewLen = rLen;
     277             :             rtl_TextToUnicodeConverter hConverter =
     278           0 :                 rtl_createTextToUnicodeConverter(eCharSet);
     279             :             rtl_TextToUnicodeContext hContext =
     280           0 :                 rtl_createTextToUnicodeContext(hConverter);
     281             : 
     282             :             sal_Size nCntBytes;
     283             :             sal_uInt32 nInfo;
     284             :             nNewLen = rtl_convertTextToUnicode( hConverter, hContext, pBuf,
     285             :                 rLen, pNewBuf, nNewLen,
     286             :                 (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_DEFAULT |
     287             :                   RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_DEFAULT |
     288           0 :                   RTL_TEXTTOUNICODE_FLAGS_INVALID_DEFAULT), &nInfo, &nCntBytes);
     289             : 
     290           0 :             rtl_destroyTextToUnicodeContext(hConverter, hContext);
     291           0 :             rtl_destroyTextToUnicodeConverter(hConverter);
     292             :         }
     293             :         else
     294             :         {
     295           0 :             nNewLen = rLen/2;
     296           0 :             memcpy(pNewBuf, pBuf, rLen);
     297             : #ifdef OSL_LITENDIAN
     298           0 :             bool bNativeLE = true;
     299             : #else
     300             :             bool bNativeLE = false;
     301             : #endif
     302           0 :             if (bLE != bNativeLE)
     303             :             {
     304           0 :                 bSwap = true;
     305           0 :                 sal_Char* pF = (sal_Char*)pNewBuf;
     306           0 :                 sal_Char* pN = pF+1;
     307           0 :                 for(sal_uLong n = 0; n < nNewLen; ++n, pF+=2, pN+=2 )
     308             :                 {
     309           0 :                     sal_Char c = *pF;
     310           0 :                     *pF = *pN;
     311           0 :                     *pN = c;
     312             :                 }
     313             :             }
     314             :         }
     315             : 
     316           0 :         for (sal_uLong nCnt = 0; nCnt < nNewLen; ++nCnt, ++pNewBuf)
     317             :         {
     318           0 :             switch (*pNewBuf)
     319             :             {
     320             :                 case 0xA:
     321           0 :                     bLF = true;
     322           0 :                     break;
     323             :                 case 0xD:
     324           0 :                     bCR = true;
     325           0 :                     break;
     326             :                 default:
     327           0 :                     break;
     328             :             }
     329           0 :         }
     330             :     }
     331             :     else
     332             :     {
     333           0 :         for( sal_uLong nCnt = 0; nCnt < rLen; ++nCnt, ++pBuf )
     334             :         {
     335           0 :             switch (*pBuf)
     336             :             {
     337             :                 case 0x0:
     338           0 :                     if( nCnt + 1 < rLen && !*(pBuf+1) )
     339           0 :                         return false;
     340           0 :                     bIsBareUnicode = true;
     341           0 :                     break;
     342             :                 case 0xA:
     343           0 :                     bLF = true;
     344           0 :                     break;
     345             :                 case 0xD:
     346           0 :                     bCR = true;
     347           0 :                     break;
     348             :                 case 0xC:
     349             :                 case 0x1A:
     350             :                 case 0x9:
     351           0 :                     break;
     352             :                 default:
     353           0 :                     break;
     354             :             }
     355             :         }
     356             :     }
     357             : 
     358           0 :     LineEnd eSysLE = GetSystemLineEnd();
     359             :     LineEnd eLineEnd;
     360           0 :     if (!bCR && !bLF)
     361           0 :         eLineEnd = eSysLE;
     362             :     else
     363           0 :         eLineEnd = bCR ? ( bLF ? LINEEND_CRLF : LINEEND_CR ) : LINEEND_LF;
     364             : 
     365           0 :     if (pCharSet)
     366           0 :         *pCharSet = eCharSet;
     367           0 :     if (pSwap)
     368           0 :         *pSwap = bSwap;
     369           0 :     if (pLineEnd)
     370           0 :         *pLineEnd = eLineEnd;
     371             : 
     372           0 :     return bEncodedFilter || (!bIsBareUnicode && eSysLE == eLineEnd);
     373         270 : }
     374             : 
     375             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10