LCOV - code coverage report
Current view: top level - libreoffice/writerfilter/source/ooxml - OOXMLStreamImpl.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 128 136 94.1 %
Date: 2012-12-27 Functions: 18 19 94.7 %
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 "OOXMLStreamImpl.hxx"
      21             : #include "OOXMLFastTokenHandler.hxx"
      22             : #include "ooxmlLoggers.hxx"
      23             : #include <iostream>
      24             : 
      25             : #include <com/sun/star/embed/XHierarchicalStorageAccess.hpp>
      26             : #include <com/sun/star/uri/UriReferenceFactory.hpp>
      27             : #include <com/sun/star/xml/sax/Parser.hpp>
      28             : 
      29             : //#define DEBUG_STREAM
      30             : 
      31             : namespace writerfilter {
      32             : namespace ooxml
      33             : {
      34             : 
      35             : using namespace ::std;
      36             : 
      37          94 : OOXMLStreamImpl::OOXMLStreamImpl
      38             : (uno::Reference<uno::XComponentContext> xContext,
      39             :  uno::Reference<io::XInputStream> xStorageStream,
      40             :  StreamType_t nType, bool bRepairStorage)
      41          94 : : mxContext(xContext), mxStorageStream(xStorageStream), mnStreamType(nType)
      42             : {
      43             :     mxStorage.set
      44             :         (comphelper::OStorageHelper::GetStorageOfFormatFromInputStream
      45          94 :          (OFOPXML_STORAGE_FORMAT_STRING, mxStorageStream, xContext, bRepairStorage));
      46          94 :     mxRelationshipAccess.set(mxStorage, uno::UNO_QUERY_THROW);
      47             : 
      48          94 :     init();
      49          94 : }
      50             : 
      51         701 : OOXMLStreamImpl::OOXMLStreamImpl
      52             : (OOXMLStreamImpl & rOOXMLStream, StreamType_t nStreamType)
      53             : : mxContext(rOOXMLStream.mxContext),
      54             :   mxStorageStream(rOOXMLStream.mxStorageStream),
      55             :   mxStorage(rOOXMLStream.mxStorage),
      56             :   mnStreamType(nStreamType),
      57         701 :   msPath(rOOXMLStream.msPath)
      58             : {
      59         701 :     mxRelationshipAccess.set(rOOXMLStream.mxDocumentStream, uno::UNO_QUERY_THROW);
      60             : 
      61         701 :     init();
      62         701 : }
      63             : 
      64          26 : OOXMLStreamImpl::OOXMLStreamImpl
      65             : (OOXMLStreamImpl & rOOXMLStream, const OUString & rId)
      66             : : mxContext(rOOXMLStream.mxContext),
      67             :   mxStorageStream(rOOXMLStream.mxStorageStream),
      68             :   mxStorage(rOOXMLStream.mxStorage),
      69             :   mnStreamType(UNKNOWN),
      70             :   msId(rId),
      71          26 :   msPath(rOOXMLStream.msPath)
      72             : {
      73          26 :     mxRelationshipAccess.set(rOOXMLStream.mxDocumentStream, uno::UNO_QUERY_THROW);
      74             : 
      75          26 :     init();
      76          26 : }
      77             : 
      78        1642 : OOXMLStreamImpl::~OOXMLStreamImpl()
      79             : {
      80             : #ifdef DEBUG_STREAM
      81             :     debug_logger->endElement("stream");
      82             : #endif
      83        1642 : }
      84             : 
      85          36 : const OUString & OOXMLStreamImpl::getTarget() const
      86             : {
      87          36 :     return msTarget;
      88             : }
      89             : 
      90         822 : bool OOXMLStreamImpl::lcl_getTarget(uno::Reference<embed::XRelationshipAccess>
      91             :                                     xRelationshipAccess,
      92             :                                     StreamType_t nStreamType,
      93             :                                     const OUString & rId,
      94             :                                     OUString & rDocumentTarget)
      95             : {
      96         822 :     bool bFound = false;
      97         822 :     static uno::Reference< com::sun::star::uri::XUriReferenceFactory > xFac =  ::com::sun::star::uri::UriReferenceFactory::create( mxContext );
      98             :     // use '/' to representent the root of the zip package ( and provide a 'file' scheme to
      99             :     // keep the XUriReference implementation happy )
     100             :     // add mspath to represent the 'source' of this stream
     101         822 :     uno::Reference< com::sun::star::uri::XUriReference > xBase = xFac->parse( OUString( "file:///"  ) + msPath );
     102             : 
     103         822 :     static OUString sType("Type");
     104         822 :     static OUString sId("Id");
     105         822 :     static OUString sDocumentType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument");
     106         822 :     static OUString sStylesType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles");
     107         822 :     static OUString sNumberingType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering");
     108         822 :     static OUString sFonttableType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/fontTable");
     109         822 :     static OUString sFootnotesType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes");
     110         822 :     static OUString sEndnotesType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/endnotes");
     111         822 :     static OUString sCommentsType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments");
     112         822 :     static OUString sThemeType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme");
     113         822 :     static OUString sSettingsType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings");
     114         822 :     static OUString sTarget("Target");
     115         822 :     static OUString sTargetMode("TargetMode");
     116         822 :     static OUString sExternal("External");
     117         822 :     static OUString sVBAProjectType("http://schemas.microsoft.com/office/2006/relationships/vbaProject");
     118             : 
     119         822 :     OUString sStreamType;
     120             : 
     121         822 :     switch (nStreamType)
     122             :     {
     123             :         case VBAPROJECT:
     124          94 :             sStreamType = sVBAProjectType;
     125          94 :             break;
     126             :         case DOCUMENT:
     127          94 :             sStreamType = sDocumentType;
     128          94 :             break;
     129             :         case STYLES:
     130         121 :             sStreamType = sStylesType;
     131         121 :             break;
     132             :         case NUMBERING:
     133         121 :             sStreamType = sNumberingType;
     134         121 :             break;
     135             :         case FONTTABLE:
     136         121 :             sStreamType = sFonttableType;
     137         121 :             break;
     138             :         case FOOTNOTES:
     139           0 :             sStreamType = sFootnotesType;
     140           0 :             break;
     141             :         case ENDNOTES:
     142           0 :             sStreamType = sEndnotesType;
     143           0 :             break;
     144             :         case COMMENTS:
     145           2 :             sStreamType = sCommentsType;
     146           2 :             break;
     147             :         case THEME:
     148         121 :             sStreamType = sThemeType;
     149         121 :             break;
     150             :         case SETTINGS:
     151         121 :             sStreamType = sSettingsType;
     152         121 :             break;
     153             :         default:
     154          27 :             break;
     155             :     }
     156             : 
     157         822 :     if (xRelationshipAccess.is())
     158             :     {
     159             :         uno::Sequence< uno::Sequence< beans::StringPair > >aSeqs =
     160         822 :             xRelationshipAccess->getAllRelationships();
     161             : 
     162        2959 :         for (sal_Int32 j = 0; j < aSeqs.getLength(); j++)
     163             :         {
     164        2587 :             uno::Sequence< beans::StringPair > aSeq = aSeqs[j];
     165             : 
     166        2587 :             bool bExternalTarget = false;
     167        2587 :             OUString sMyTarget;
     168       10354 :             for (sal_Int32 i = 0; i < aSeq.getLength(); i++)
     169             :             {
     170        7767 :                 beans::StringPair aPair = aSeq[i];
     171             : 
     172       10354 :                 if (aPair.First.compareTo(sType) == 0 &&
     173        2587 :                     aPair.Second.compareTo(sStreamType) == 0)
     174         423 :                     bFound = true;
     175        9931 :                 else if (aPair.First.compareTo(sId) == 0 &&
     176        2587 :                          aPair.Second.compareTo(rId) == 0)
     177          27 :                     bFound = true;
     178        7317 :                 else if (aPair.First.compareTo(sTarget) == 0)
     179        2587 :                     sMyTarget = aPair.Second;
     180        4736 :                 else if (aPair.First.compareTo(sTargetMode) == 0 &&
     181           6 :                          aPair.Second.compareTo(sExternal) == 0)
     182           6 :                     bExternalTarget = true;
     183             : 
     184        7767 :             }
     185             : 
     186        2587 :             if (bFound)
     187             :             {
     188         450 :                 if (bExternalTarget)
     189           1 :                     rDocumentTarget = sMyTarget;
     190             :                 else
     191             :                 {
     192             :                     // 'Target' is a relative Uri, so a 'Target=/path'
     193             :                     // with a base Uri of file://base/foo will resolve to
     194             :                     // file://base/word. We need something more than some
     195             :                     // simple string concatination here to handle that.
     196         449 :                     uno::Reference< com::sun::star::uri::XUriReference > xPart = xFac->parse(  sMyTarget );
     197         449 :                     uno::Reference< com::sun::star::uri::XUriReference > xAbs = xFac->makeAbsolute(  xBase, xPart, sal_True,  com::sun::star::uri::RelativeUriExcessParentSegments_RETAIN );
     198         449 :                     rDocumentTarget = xAbs->getPath();
     199             :                     // path will start with the fragment separator. need to
     200             :                     // remove that
     201         449 :                     rDocumentTarget = rDocumentTarget.copy( 1 );
     202             :                 }
     203             : 
     204             :                 break;
     205             :             }
     206        3409 :         }
     207             :     }
     208             : 
     209         822 :     return bFound;
     210             : }
     211             : 
     212           1 : OUString OOXMLStreamImpl::getTargetForId(const OUString & rId)
     213             : {
     214           1 :     OUString sTarget;
     215             : 
     216             :     uno::Reference<embed::XRelationshipAccess> xRelationshipAccess
     217           1 :         (mxDocumentStream, uno::UNO_QUERY_THROW);
     218             : 
     219           1 :     if (lcl_getTarget(xRelationshipAccess, UNKNOWN, rId, sTarget))
     220           1 :         return sTarget;
     221             : 
     222           0 :     return OUString();
     223             : }
     224             : 
     225         821 : void OOXMLStreamImpl::init()
     226             : {
     227             :     bool bFound = lcl_getTarget(mxRelationshipAccess,
     228         821 :                                 mnStreamType, msId, msTarget);
     229             : #ifdef DEBUG_STREAM
     230             :     debug_logger->startElement("stream");
     231             :     debug_logger->attribute("target", msTarget);
     232             : #endif
     233             : 
     234         821 :     if (bFound)
     235             :     {
     236         449 :         sal_Int32 nLastIndex = msTarget.lastIndexOf('/');
     237         449 :         if (nLastIndex >= 0)
     238         449 :             msPath = msTarget.copy(0, nLastIndex + 1);
     239             : 
     240             :         uno::Reference<embed::XHierarchicalStorageAccess>
     241         449 :             xHierarchicalStorageAccess(mxStorage, uno::UNO_QUERY);
     242             : 
     243         449 :         if (xHierarchicalStorageAccess.is())
     244             :         {
     245         449 :             uno::Any aAny(xHierarchicalStorageAccess->
     246             :                           openStreamElementByHierarchicalName
     247         449 :                           (msTarget, embed::ElementModes::SEEKABLEREAD));
     248         449 :             aAny >>= mxDocumentStream;
     249         449 :         }
     250             :     }
     251         821 : }
     252             : 
     253         821 : uno::Reference<io::XInputStream> OOXMLStreamImpl::getDocumentStream()
     254             : {
     255         821 :     uno::Reference<io::XInputStream> xResult;
     256             : 
     257         821 :     if (mxDocumentStream.is())
     258         449 :         xResult = mxDocumentStream->getInputStream();
     259             : 
     260         821 :     return xResult;
     261             : }
     262             : 
     263          36 : uno::Reference<io::XInputStream> OOXMLStreamImpl::getStorageStream()
     264             : {
     265          36 :     return mxStorageStream;
     266             : }
     267             : 
     268           0 : uno::Reference<xml::sax::XParser> OOXMLStreamImpl::getParser()
     269             : {
     270           0 :     uno::Reference<xml::sax::XParser> xParser = xml::sax::Parser::create(mxContext);
     271           0 :     return xParser;
     272             : }
     273             : 
     274         726 : uno::Reference<uno::XComponentContext> OOXMLStreamImpl::getContext()
     275             : {
     276         726 :     return mxContext;
     277             : }
     278             : 
     279             : uno::Reference <xml::sax::XFastTokenHandler>
     280         726 : OOXMLStreamImpl::getFastTokenHandler
     281             : (uno::Reference<uno::XComponentContext> xContext)
     282             : {
     283         726 :     if (! mxFastTokenHandler.is())
     284         726 :         mxFastTokenHandler.set(new OOXMLFastTokenHandler(xContext));
     285             : 
     286         726 :     return mxFastTokenHandler;
     287             : }
     288             : 
     289             : OOXMLStream::Pointer_t
     290          94 : OOXMLDocumentFactory::createStream
     291             : (uno::Reference<uno::XComponentContext> xContext,
     292             :  uno::Reference<io::XInputStream> rStream,
     293             :  bool bRepairStorage,
     294             :  OOXMLStream::StreamType_t nStreamType)
     295             : {
     296             :     OOXMLStreamImpl * pStream = new OOXMLStreamImpl(xContext, rStream,
     297          94 :                                                     nStreamType, bRepairStorage);
     298          94 :     return OOXMLStream::Pointer_t(pStream);
     299             : }
     300             : 
     301             : OOXMLStream::Pointer_t
     302         701 : OOXMLDocumentFactory::createStream
     303             : (OOXMLStream::Pointer_t pStream,  OOXMLStream::StreamType_t nStreamType)
     304             : {
     305             :     return OOXMLStream::Pointer_t
     306         701 :         (new OOXMLStreamImpl(*dynamic_cast<OOXMLStreamImpl *>(pStream.get()),
     307         701 :                              nStreamType));
     308             : }
     309             : 
     310             : OOXMLStream::Pointer_t
     311          26 : OOXMLDocumentFactory::createStream
     312             : (OOXMLStream::Pointer_t pStream, const OUString & rId)
     313             : {
     314             :     return OOXMLStream::Pointer_t
     315          26 :         (new OOXMLStreamImpl(*dynamic_cast<OOXMLStreamImpl *>(pStream.get()),
     316          26 :                              rId));
     317             : }
     318             : 
     319          15 : }}
     320             : 
     321             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10