/************************************************************************* * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * Copyright 2000, 2010 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * only, as published by the Free Software Foundation. * * OpenOffice.org is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License version 3 for more details * (a copy is included in the LICENSE file that accompanied this code). * * You should have received a copy of the GNU Lesser General Public License * version 3 along with OpenOffice.org. If not, see * * for a copy of the LGPLv3 License. * ************************************************************************/ #include #include "Dff.hxx" #include #include #include "resources.hxx" namespace writerfilter { namespace doctok { typedef boost::shared_ptr WW8ValueSharedPointer_t; DffRecord::DffRecord(WW8Stream & rStream, sal_uInt32 nOffset, sal_uInt32 nCount) : WW8StructBase(rStream, nOffset, nCount), bInitialized(false) { } DffRecord::DffRecord(WW8StructBase * pParent, sal_uInt32 nOffset, sal_uInt32 nCount) : WW8StructBase(pParent, nOffset, nCount), bInitialized(false) { } Records_t::iterator DffRecord::begin() { if (! bInitialized) initChildren(); return mRecords.begin(); } Records_t::iterator DffRecord::end() { if (! bInitialized) initChildren(); return mRecords.end(); } bool DffRecord::isContainer() const { return getVersion() == 0xf; } sal_uInt32 DffRecord::calcSize() const { sal_uInt32 nResult = 0; switch (getRecordType()) { case 0xf000: case 0xf001: case 0xf002: case 0xf003: case 0xf004: nResult = getU32(0x4) + 8; break; case 0xf700: nResult = 8; break; default: nResult = getU32(0x4); if (! isContainer()) nResult += 8; break; } return nResult; } sal_uInt32 DffRecord::getVersion() const { return getU8(0x0) & 0xf; } sal_uInt32 DffRecord::getInstance() const { return (getU16(0x0) & 0xfff0) >> 4; } sal_uInt32 DffRecord::getRecordType() const { return getU16(0x2); } void DffRecord::initChildren() { if (isContainer()) { sal_uInt32 nOffset = 8; sal_uInt32 nCount = calcSize(); while (nCount - nOffset >= 8) { sal_uInt32 nSize = 0; boost::shared_ptr pRec (createDffRecord(this, nOffset, &nSize)); if (nSize == 0) break; mRecords.push_back(pRec); nOffset += nSize; } } bInitialized = true; } Records_t DffRecord::findRecords(sal_uInt32 nType, bool bRecursive, bool bAny) { Records_t aResult; findRecords(nType, aResult, bRecursive, bAny); return aResult; } void DffRecord::findRecords (sal_uInt32 nType, Records_t & rRecords, bool bRecursive, bool bAny) { Records_t::iterator aIt = begin(); while (aIt != end()) { Pointer_t pPointer = *aIt; if (bAny || pPointer->getRecordType() == nType) rRecords.push_back(pPointer); if (bRecursive) pPointer->findRecords(nType, rRecords, bRecursive, bAny); ++aIt; } } void DffRecord::resolveChildren(Properties & rHandler) { Records_t::iterator aIt; for (aIt = begin(); aIt != end(); ++aIt) { rHandler.sprm(**aIt); } } void DffRecord::resolveLocal(Properties &) { } void DffRecord::resolve(Properties & rHandler) { WW8Value::Pointer_t pVal = createValue(getRecordType()); rHandler.attribute(NS_rtf::LN_dfftype, *pVal); pVal = createValue(getInstance()); rHandler.attribute(NS_rtf::LN_dffinstance, *pVal); pVal = createValue(getVersion()); rHandler.attribute(NS_rtf::LN_dffversion, *pVal); pVal = createValue(getU32(0x0)); rHandler.attribute(NS_rtf::LN_dffheader, *pVal); if (isContainer()) { resolveChildren(rHandler); } resolveLocal(rHandler); #if 1 WW8BinaryObjReference::Pointer_t pBinObjRef (new WW8BinaryObjReference(this, 0, getCount())); WW8Sprm aSprm(pBinObjRef); rHandler.sprm(aSprm); #endif } sal_uInt32 DffRecord::getShapeType() { sal_uInt32 nResult = 0; Records_t aRecords = findRecords(0xf00a); if (aRecords.size() > 0) { DffFSP * pDffFSP = dynamic_cast((*aRecords.begin()).get()); nResult = pDffFSP->get_shptype(); } return nResult; } sal_uInt32 DffRecord::getShapeId() { sal_uInt32 nResult = 0; Records_t aRecords = findRecords(0xf00a); if (aRecords.size() > 0) { DffFSP * pDffFSP = dynamic_cast((*aRecords.begin()).get()); nResult = pDffFSP->get_shpid(); } return nResult; } class DffOPTHandler : public Properties { map mMap; int nId; public: DffOPTHandler() : nId(0) {} virtual ~DffOPTHandler() {} virtual void attribute(Id name, Value & val) { switch (name) { case NS_rtf::LN_shppid: nId = val.getInt(); break; case NS_rtf::LN_shpvalue: { WW8Value & rTmpVal = dynamic_cast(val); WW8ValueSharedPointer_t pVal(dynamic_cast(rTmpVal.clone())); mMap[nId] = pVal; } } } virtual void sprm(Sprm & /*sprm_*/) { } WW8ValueSharedPointer_t & getValue(int nId_) { return mMap[nId_]; } }; sal_uInt32 DffRecord::getShapeBid() { sal_uInt32 nResult = 0; if (getShapeType() == 75) { Records_t aRecords = findRecords(0xf00b); if (aRecords.size() > 0) { DffOPTHandler aHandler; DffOPT * pOpts = dynamic_cast((*aRecords.begin()).get()); sal_uInt32 nCount = pOpts->get_property_count(); for (sal_uInt32 n = 0; n < nCount; ++n) { pOpts->get_property(n)->resolve(aHandler); } WW8ValueSharedPointer_t pVal = aHandler.getValue(260); if (pVal.get() != NULL) nResult = pVal->getInt(); } } return nResult; } string DffRecord::getType() const { return "DffRecord"; } Value::Pointer_t DffRecord::getValue() { return Value::Pointer_t(); } writerfilter::Reference::Pointer_t DffRecord::getBinary() { return writerfilter::Reference::Pointer_t(); } writerfilter::Reference::Pointer_t DffRecord::getStream() { return writerfilter::Reference::Pointer_t(); } writerfilter::Reference::Pointer_t DffRecord::getProps() { return writerfilter::Reference::Pointer_t(this->clone()); } string DffRecord::toString() const { char sBuffer[1024]; snprintf(sBuffer, sizeof(sBuffer), "\n", getRecordType(), getInstance(), getVersion()); string aResult = sBuffer; if (!isContainer()) aResult += mSequence.toString(); else { WW8StructBase::Sequence aSeq(mSequence, 0, 8); aResult += aSeq.toString(); } aResult += ""; return aResult; } string DffRecord::getName() const { return ""; } Sprm::Kind DffRecord::getKind() { return Sprm::UNKNOWN; } DffBlock::DffBlock(WW8Stream & rStream, sal_uInt32 nOffset, sal_uInt32 nCount, sal_uInt32 nPadding) : WW8StructBase(rStream, nOffset, nCount), bInitialized(false), mnPadding(nPadding) { } DffBlock::DffBlock(WW8StructBase * pParent, sal_uInt32 nOffset, sal_uInt32 nCount, sal_uInt32 nPadding) : WW8StructBase(pParent, nOffset, nCount), bInitialized(false), mnPadding(nPadding) { } DffBlock::DffBlock(const DffBlock & rSrc) : WW8StructBase(rSrc), writerfilter::Reference(rSrc), bInitialized(false), mnPadding(rSrc.mnPadding) { } void DffBlock::initChildren() { sal_uInt32 nOffset = 0; sal_uInt32 nCount = getCount(); while (nOffset < nCount) { sal_uInt32 nSize = 0; DffRecord::Pointer_t pDffRecord (createDffRecord(this, nOffset, &nSize)); if (nSize == 0) break; mRecords.push_back(pDffRecord); nOffset += nSize + mnPadding; } bInitialized = true; } Records_t DffBlock::findRecords(sal_uInt32 nType, bool bRecursive, bool bAny) { Records_t aResult; findRecords(nType, aResult, bRecursive, bAny); return aResult; } void DffBlock::findRecords (sal_uInt32 nType, Records_t & rRecords, bool bRecursive, bool bAny) { Records_t::iterator aIt = begin(); while (aIt != end()) { DffRecord::Pointer_t pPointer(*aIt); if (bAny || pPointer->getRecordType() == nType) rRecords.push_back(pPointer); if (bRecursive) pPointer->findRecords(nType, rRecords, bRecursive, bAny); ++aIt; } } void DffBlock::resolve(Properties & rHandler) { Records_t::iterator aIt; for (aIt = begin(); aIt != end(); ++aIt) { DffRecord * pDff = aIt->get(); rHandler.sprm(*pDff); } } DffRecord::Pointer_t DffBlock::getShape(sal_uInt32 nSpid) { DffRecord::Pointer_t pResult; Records_t aRecords = findRecords(0xf004); Records_t::iterator aIt; for (aIt = aRecords.begin(); aIt != aRecords.end(); ++aIt) { DffRecord::Pointer_t pPointer = *aIt; Records_t aFSPs = pPointer->findRecords(0xf00a); Records_t::iterator aItFSP = aFSPs.begin(); if (aItFSP != aFSPs.end()) { DffFSP * pFSP = dynamic_cast((*aItFSP).get()); if (pFSP->get_shpid() == nSpid) { pResult = pPointer; break; } } } return pResult; } DffRecord::Pointer_t DffBlock::getBlip(sal_uInt32 nBlip) { DffRecord::Pointer_t pResult; if (nBlip > 0) { nBlip--; Records_t aRecords = findRecords(0xf007); if (nBlip < aRecords.size()) { pResult = aRecords[nBlip]; } } return pResult; } Records_t::iterator DffBlock::begin() { if (! bInitialized) initChildren(); return mRecords.begin(); } Records_t::iterator DffBlock::end() { if (! bInitialized) initChildren(); return mRecords.end(); } string DffBlock::getType() const { return "DffBlock"; } }}