Bump version to 4.1-6
[LibreOffice.git] / writerfilter / source / doctok / Dff.cxx
blobf39505e7723542a7175b3c317eb9784c2d3de1d4
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <stdio.h>
21 #include "Dff.hxx"
22 #include <doctok/resourceids.hxx>
23 #include <resourcemodel/WW8ResourceModel.hxx>
24 #include "doctok/resources.hxx"
26 namespace writerfilter {
27 namespace doctok {
29 typedef boost::shared_ptr<WW8Value> WW8ValueSharedPointer_t;
31 DffRecord::DffRecord(WW8Stream & rStream, sal_uInt32 nOffset,
32 sal_uInt32 nCount)
33 : WW8StructBase(rStream, nOffset, nCount), bInitialized(false)
37 DffRecord::DffRecord(WW8StructBase * pParent, sal_uInt32 nOffset,
38 sal_uInt32 nCount)
39 : WW8StructBase(pParent, nOffset, nCount), bInitialized(false)
43 Records_t::iterator DffRecord::begin()
45 if (! bInitialized)
46 initChildren();
48 return mRecords.begin();
51 Records_t::iterator DffRecord::end()
53 if (! bInitialized)
54 initChildren();
56 return mRecords.end();
59 bool DffRecord::isContainer() const
61 return getVersion() == 0xf;
64 sal_uInt32 DffRecord::calcSize() const
66 sal_uInt32 nResult = 0;
68 switch (getRecordType())
70 case 0xf000:
71 case 0xf001:
72 case 0xf002:
73 case 0xf003:
74 case 0xf004:
75 nResult = getU32(0x4) + 8;
77 break;
78 case 0xf700:
79 nResult = 8;
81 break;
82 default:
83 nResult = getU32(0x4);
85 if (! isContainer())
86 nResult += 8;
87 break;
90 return nResult;
93 sal_uInt32 DffRecord::getVersion() const
95 return getU8(0x0) & 0xf;
98 sal_uInt32 DffRecord::getInstance() const
100 return (getU16(0x0) & 0xfff0) >> 4;
103 sal_uInt32 DffRecord::getRecordType() const
105 return getU16(0x2);
108 void DffRecord::initChildren()
110 if (isContainer())
112 sal_uInt32 nOffset = 8;
113 sal_uInt32 nCount = calcSize();
115 while (nCount - nOffset >= 8)
117 sal_uInt32 nSize = 0;
118 boost::shared_ptr<DffRecord> pRec
119 (createDffRecord(this, nOffset, &nSize));
121 if (nSize == 0)
122 break;
124 mRecords.push_back(pRec);
126 nOffset += nSize;
130 bInitialized = true;
133 Records_t DffRecord::findRecords(sal_uInt32 nType, bool bRecursive, bool bAny)
135 Records_t aResult;
137 findRecords(nType, aResult, bRecursive, bAny);
139 return aResult;
142 void DffRecord::findRecords
143 (sal_uInt32 nType, Records_t & rRecords, bool bRecursive, bool bAny)
145 Records_t::iterator aIt = begin();
147 while (aIt != end())
149 Pointer_t pPointer = *aIt;
150 if (bAny || pPointer->getRecordType() == nType)
151 rRecords.push_back(pPointer);
153 if (bRecursive)
154 pPointer->findRecords(nType, rRecords, bRecursive,
155 bAny);
157 ++aIt;
161 void DffRecord::resolveChildren(Properties & rHandler)
163 Records_t::iterator aIt;
164 for (aIt = begin(); aIt != end(); ++aIt)
166 rHandler.sprm(**aIt);
170 void DffRecord::resolveLocal(Properties &)
174 void DffRecord::resolve(Properties & rHandler)
176 WW8Value::Pointer_t pVal = createValue(getRecordType());
177 rHandler.attribute(NS_rtf::LN_dfftype, *pVal);
179 pVal = createValue(getInstance());
180 rHandler.attribute(NS_rtf::LN_dffinstance, *pVal);
182 pVal = createValue(getVersion());
183 rHandler.attribute(NS_rtf::LN_dffversion, *pVal);
185 pVal = createValue(getU32(0x0));
186 rHandler.attribute(NS_rtf::LN_dffheader, *pVal);
188 if (isContainer())
190 resolveChildren(rHandler);
193 resolveLocal(rHandler);
195 WW8BinaryObjReference::Pointer_t pBinObjRef
196 (new WW8BinaryObjReference(this, 0, getCount()));
197 WW8Sprm aSprm(pBinObjRef);
199 rHandler.sprm(aSprm);
202 sal_uInt32 DffRecord::getShapeType()
204 sal_uInt32 nResult = 0;
206 Records_t aRecords = findRecords(0xf00a);
208 if (!aRecords.empty())
210 DffFSP * pDffFSP = dynamic_cast<DffFSP*>((*aRecords.begin()).get());
211 nResult = pDffFSP->get_shptype();
214 return nResult;
217 sal_uInt32 DffRecord::getShapeId()
219 sal_uInt32 nResult = 0;
221 Records_t aRecords = findRecords(0xf00a);
223 if (!aRecords.empty())
225 DffFSP * pDffFSP = dynamic_cast<DffFSP*>((*aRecords.begin()).get());
226 nResult = pDffFSP->get_shpid();
229 return nResult;
232 class DffOPTHandler : public Properties
234 map<int, WW8ValueSharedPointer_t> mMap;
235 int nId;
237 public:
238 DffOPTHandler() : nId(0) {}
239 virtual ~DffOPTHandler() {}
241 virtual void attribute(Id name, Value & val)
243 switch (name)
245 case NS_rtf::LN_shppid:
246 nId = val.getInt();
247 break;
248 case NS_rtf::LN_shpvalue:
250 WW8Value & rTmpVal = dynamic_cast<WW8Value &>(val);
251 WW8ValueSharedPointer_t
252 pVal(dynamic_cast<WW8Value *>(rTmpVal.clone()));
253 mMap[nId] = pVal;
258 virtual void sprm(Sprm & /*sprm_*/)
262 WW8ValueSharedPointer_t & getValue(int nId_)
264 return mMap[nId_];
269 sal_uInt32 DffRecord::getShapeBid()
271 sal_uInt32 nResult = 0;
273 if (getShapeType() == 75)
275 Records_t aRecords = findRecords(0xf00b);
277 if (!aRecords.empty())
279 DffOPTHandler aHandler;
280 DffOPT * pOpts = dynamic_cast<DffOPT*>((*aRecords.begin()).get());
282 sal_uInt32 nCount = pOpts->get_property_count();
284 for (sal_uInt32 n = 0; n < nCount; ++n)
286 pOpts->get_property(n)->resolve(aHandler);
289 WW8ValueSharedPointer_t pVal = aHandler.getValue(260);
291 if (pVal.get() != NULL)
292 nResult = pVal->getInt();
296 return nResult;
299 string DffRecord::getType() const
301 return "DffRecord";
304 Value::Pointer_t DffRecord::getValue()
306 return Value::Pointer_t();
309 writerfilter::Reference<BinaryObj>::Pointer_t DffRecord::getBinary()
311 return writerfilter::Reference<BinaryObj>::Pointer_t();
314 writerfilter::Reference<Stream>::Pointer_t DffRecord::getStream()
316 return writerfilter::Reference<Stream>::Pointer_t();
319 writerfilter::Reference<Properties>::Pointer_t DffRecord::getProps()
321 return writerfilter::Reference<Properties>::Pointer_t(this->clone());
324 string DffRecord::toString() const
326 char sBuffer[1024];
328 snprintf(sBuffer, sizeof(sBuffer),
329 "<dffrecord type=\"%" SAL_PRIuUINT32 "\" instance=\"%" SAL_PRIuUINT32 "\" version=\"%" SAL_PRIuUINT32 "\">\n",
330 getRecordType(), getInstance(), getVersion());
331 string aResult = sBuffer;
334 if (!isContainer())
335 aResult += mSequence.toString();
336 else
338 WW8StructBase::Sequence aSeq(mSequence, 0, 8);
339 aResult += aSeq.toString();
342 aResult += "</dffrecord>";
344 return aResult;
347 string DffRecord::getName() const
349 return "";
352 Sprm::Kind DffRecord::getKind()
354 return Sprm::UNKNOWN;
357 DffBlock::DffBlock(WW8Stream & rStream, sal_uInt32 nOffset,
358 sal_uInt32 nCount, sal_uInt32 nPadding)
359 : WW8StructBase(rStream, nOffset, nCount), bInitialized(false),
360 mnPadding(nPadding)
364 DffBlock::DffBlock(WW8StructBase * pParent, sal_uInt32 nOffset,
365 sal_uInt32 nCount, sal_uInt32 nPadding)
366 : WW8StructBase(pParent, nOffset, nCount), bInitialized(false),
367 mnPadding(nPadding)
371 DffBlock::DffBlock(const DffBlock & rSrc)
372 : WW8StructBase(rSrc), writerfilter::Reference<Properties>(rSrc),
373 bInitialized(false), mnPadding(rSrc.mnPadding)
377 void DffBlock::initChildren()
379 sal_uInt32 nOffset = 0;
380 sal_uInt32 nCount = getCount();
382 while (nOffset < nCount)
384 sal_uInt32 nSize = 0;
385 DffRecord::Pointer_t pDffRecord
386 (createDffRecord(this, nOffset, &nSize));
388 if (nSize == 0)
389 break;
391 mRecords.push_back(pDffRecord);
393 nOffset += nSize + mnPadding;
396 bInitialized = true;
399 Records_t DffBlock::findRecords(sal_uInt32 nType, bool bRecursive, bool bAny)
401 Records_t aResult;
403 findRecords(nType, aResult, bRecursive, bAny);
405 return aResult;
408 void DffBlock::findRecords
409 (sal_uInt32 nType, Records_t & rRecords, bool bRecursive, bool bAny)
411 Records_t::iterator aIt = begin();
413 while (aIt != end())
415 DffRecord::Pointer_t pPointer(*aIt);
417 if (bAny || pPointer->getRecordType() == nType)
418 rRecords.push_back(pPointer);
420 if (bRecursive)
421 pPointer->findRecords(nType, rRecords, bRecursive,
422 bAny);
424 ++aIt;
428 void DffBlock::resolve(Properties & rHandler)
430 Records_t::iterator aIt;
432 for (aIt = begin(); aIt != end(); ++aIt)
434 DffRecord * pDff = aIt->get();
435 rHandler.sprm(*pDff);
439 DffRecord::Pointer_t DffBlock::getShape(sal_uInt32 nSpid)
441 DffRecord::Pointer_t pResult;
443 Records_t aRecords = findRecords(0xf004);
444 Records_t::iterator aIt;
445 for (aIt = aRecords.begin(); aIt != aRecords.end(); ++aIt)
447 DffRecord::Pointer_t pPointer = *aIt;
449 Records_t aFSPs = pPointer->findRecords(0xf00a);
450 Records_t::iterator aItFSP = aFSPs.begin();
452 if (aItFSP != aFSPs.end())
454 DffFSP * pFSP = dynamic_cast<DffFSP *>((*aItFSP).get());
456 if (pFSP->get_shpid() == nSpid)
458 pResult = pPointer;
460 break;
465 return pResult;
468 DffRecord::Pointer_t DffBlock::getBlip(sal_uInt32 nBlip)
470 DffRecord::Pointer_t pResult;
472 if (nBlip > 0)
474 nBlip--;
476 Records_t aRecords = findRecords(0xf007);
478 if (nBlip < aRecords.size())
480 pResult = aRecords[nBlip];
484 return pResult;
487 Records_t::iterator DffBlock::begin()
489 if (! bInitialized)
490 initChildren();
492 return mRecords.begin();
495 Records_t::iterator DffBlock::end()
497 if (! bInitialized)
498 initChildren();
500 return mRecords.end();
503 string DffBlock::getType() const
505 return "DffBlock";
510 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */