| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| #include <stdio.h> |
| #include "Dff.hxx" |
| #include <doctok/resourceids.hxx> |
| #include <resourcemodel/WW8ResourceModel.hxx> |
| #include "resources.hxx" |
| |
| namespace writerfilter { |
| namespace doctok { |
| |
| typedef boost::shared_ptr<WW8Value> 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<DffRecord> 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<DffFSP*>((*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<DffFSP*>((*aRecords.begin()).get()); |
| nResult = pDffFSP->get_shpid(); |
| } |
| |
| return nResult; |
| } |
| |
| class DffOPTHandler : public Properties |
| { |
| map<int, WW8ValueSharedPointer_t> 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<WW8Value &>(val); |
| WW8ValueSharedPointer_t |
| pVal(dynamic_cast<WW8Value *>(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<DffOPT*>((*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<BinaryObj>::Pointer_t DffRecord::getBinary() |
| { |
| return writerfilter::Reference<BinaryObj>::Pointer_t(); |
| } |
| |
| writerfilter::Reference<Stream>::Pointer_t DffRecord::getStream() |
| { |
| return writerfilter::Reference<Stream>::Pointer_t(); |
| } |
| |
| writerfilter::Reference<Properties>::Pointer_t DffRecord::getProps() |
| { |
| return writerfilter::Reference<Properties>::Pointer_t(this->clone()); |
| } |
| |
| string DffRecord::toString() const |
| { |
| char sBuffer[1024]; |
| |
| snprintf(sBuffer, sizeof(sBuffer), |
| "<dffrecord type=\"%" SAL_PRIuUINT32 "\" instance=\"%" SAL_PRIuUINT32 "\" version=\"%" SAL_PRIuUINT32 "\">\n", |
| getRecordType(), getInstance(), getVersion()); |
| string aResult = sBuffer; |
| |
| |
| if (!isContainer()) |
| aResult += mSequence.toString(); |
| else |
| { |
| WW8StructBase::Sequence aSeq(mSequence, 0, 8); |
| aResult += aSeq.toString(); |
| } |
| |
| aResult += "</dffrecord>"; |
| |
| 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<Properties>(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<DffFSP *>((*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"; |
| } |
| |
| }} |