1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 #include <stdio.h>
25 #include "Dff.hxx"
26 #include <doctok/resourceids.hxx>
27 #include <resourcemodel/WW8ResourceModel.hxx>
28 #include "resources.hxx"
29
30 namespace writerfilter {
31 namespace doctok {
32
33 typedef boost::shared_ptr<WW8Value> WW8ValueSharedPointer_t;
34
DffRecord(WW8Stream & rStream,sal_uInt32 nOffset,sal_uInt32 nCount)35 DffRecord::DffRecord(WW8Stream & rStream, sal_uInt32 nOffset,
36 sal_uInt32 nCount)
37 : WW8StructBase(rStream, nOffset, nCount), bInitialized(false)
38 {
39 }
40
DffRecord(WW8StructBase * pParent,sal_uInt32 nOffset,sal_uInt32 nCount)41 DffRecord::DffRecord(WW8StructBase * pParent, sal_uInt32 nOffset,
42 sal_uInt32 nCount)
43 : WW8StructBase(pParent, nOffset, nCount), bInitialized(false)
44 {
45 }
46
begin()47 Records_t::iterator DffRecord::begin()
48 {
49 if (! bInitialized)
50 initChildren();
51
52 return mRecords.begin();
53 }
54
end()55 Records_t::iterator DffRecord::end()
56 {
57 if (! bInitialized)
58 initChildren();
59
60 return mRecords.end();
61 }
62
isContainer() const63 bool DffRecord::isContainer() const
64 {
65 return getVersion() == 0xf;
66 }
67
calcSize() const68 sal_uInt32 DffRecord::calcSize() const
69 {
70 sal_uInt32 nResult = 0;
71
72 switch (getRecordType())
73 {
74 case 0xf000:
75 case 0xf001:
76 case 0xf002:
77 case 0xf003:
78 case 0xf004:
79 nResult = getU32(0x4) + 8;
80
81 break;
82 case 0xf700:
83 nResult = 8;
84
85 break;
86 default:
87 nResult = getU32(0x4);
88
89 if (! isContainer())
90 nResult += 8;
91 break;
92 }
93
94 return nResult;
95 }
96
getVersion() const97 sal_uInt32 DffRecord::getVersion() const
98 {
99 return getU8(0x0) & 0xf;
100 }
101
getInstance() const102 sal_uInt32 DffRecord::getInstance() const
103 {
104 return (getU16(0x0) & 0xfff0) >> 4;
105 }
106
getRecordType() const107 sal_uInt32 DffRecord::getRecordType() const
108 {
109 return getU16(0x2);
110 }
111
initChildren()112 void DffRecord::initChildren()
113 {
114 if (isContainer())
115 {
116 sal_uInt32 nOffset = 8;
117 sal_uInt32 nCount = calcSize();
118
119 while (nCount - nOffset >= 8)
120 {
121 sal_uInt32 nSize = 0;
122 boost::shared_ptr<DffRecord> pRec
123 (createDffRecord(this, nOffset, &nSize));
124
125 if (nSize == 0)
126 break;
127
128 mRecords.push_back(pRec);
129
130 nOffset += nSize;
131 }
132 }
133
134 bInitialized = true;
135 }
136
findRecords(sal_uInt32 nType,bool bRecursive,bool bAny)137 Records_t DffRecord::findRecords(sal_uInt32 nType, bool bRecursive, bool bAny)
138 {
139 Records_t aResult;
140
141 findRecords(nType, aResult, bRecursive, bAny);
142
143 return aResult;
144 }
145
findRecords(sal_uInt32 nType,Records_t & rRecords,bool bRecursive,bool bAny)146 void DffRecord::findRecords
147 (sal_uInt32 nType, Records_t & rRecords, bool bRecursive, bool bAny)
148 {
149 Records_t::iterator aIt = begin();
150
151 while (aIt != end())
152 {
153 Pointer_t pPointer = *aIt;
154 if (bAny || pPointer->getRecordType() == nType)
155 rRecords.push_back(pPointer);
156
157 if (bRecursive)
158 pPointer->findRecords(nType, rRecords, bRecursive,
159 bAny);
160
161 ++aIt;
162 }
163 }
164
resolveChildren(Properties & rHandler)165 void DffRecord::resolveChildren(Properties & rHandler)
166 {
167 Records_t::iterator aIt;
168 for (aIt = begin(); aIt != end(); ++aIt)
169 {
170 rHandler.sprm(**aIt);
171 }
172 }
173
resolveLocal(Properties &)174 void DffRecord::resolveLocal(Properties &)
175 {
176 }
177
resolve(Properties & rHandler)178 void DffRecord::resolve(Properties & rHandler)
179 {
180 WW8Value::Pointer_t pVal = createValue(getRecordType());
181 rHandler.attribute(NS_rtf::LN_dfftype, *pVal);
182
183 pVal = createValue(getInstance());
184 rHandler.attribute(NS_rtf::LN_dffinstance, *pVal);
185
186 pVal = createValue(getVersion());
187 rHandler.attribute(NS_rtf::LN_dffversion, *pVal);
188
189 pVal = createValue(getU32(0x0));
190 rHandler.attribute(NS_rtf::LN_dffheader, *pVal);
191
192 if (isContainer())
193 {
194 resolveChildren(rHandler);
195 }
196
197 resolveLocal(rHandler);
198
199 #if 1
200 WW8BinaryObjReference::Pointer_t pBinObjRef
201 (new WW8BinaryObjReference(this, 0, getCount()));
202 WW8Sprm aSprm(pBinObjRef);
203
204 rHandler.sprm(aSprm);
205 #endif
206 }
207
getShapeType()208 sal_uInt32 DffRecord::getShapeType()
209 {
210 sal_uInt32 nResult = 0;
211
212 Records_t aRecords = findRecords(0xf00a);
213
214 if (aRecords.size() > 0)
215 {
216 DffFSP * pDffFSP = dynamic_cast<DffFSP*>((*aRecords.begin()).get());
217 nResult = pDffFSP->get_shptype();
218 }
219
220 return nResult;
221 }
222
getShapeId()223 sal_uInt32 DffRecord::getShapeId()
224 {
225 sal_uInt32 nResult = 0;
226
227 Records_t aRecords = findRecords(0xf00a);
228
229 if (aRecords.size() > 0)
230 {
231 DffFSP * pDffFSP = dynamic_cast<DffFSP*>((*aRecords.begin()).get());
232 nResult = pDffFSP->get_shpid();
233 }
234
235 return nResult;
236 }
237
238 class DffOPTHandler : public Properties
239 {
240 map<int, WW8ValueSharedPointer_t> mMap;
241 int nId;
242
243 public:
DffOPTHandler()244 DffOPTHandler() : nId(0) {}
~DffOPTHandler()245 virtual ~DffOPTHandler() {}
246
attribute(Id name,Value & val)247 virtual void attribute(Id name, Value & val)
248 {
249 switch (name)
250 {
251 case NS_rtf::LN_shppid:
252 nId = val.getInt();
253 break;
254 case NS_rtf::LN_shpvalue:
255 {
256 WW8Value & rTmpVal = dynamic_cast<WW8Value &>(val);
257 WW8ValueSharedPointer_t
258 pVal(dynamic_cast<WW8Value *>(rTmpVal.clone()));
259 mMap[nId] = pVal;
260 }
261 }
262 }
263
sprm(Sprm &)264 virtual void sprm(Sprm & /*sprm_*/)
265 {
266 }
267
getValue(int nId_)268 WW8ValueSharedPointer_t & getValue(int nId_)
269 {
270 return mMap[nId_];
271 }
272
273 };
274
getShapeBid()275 sal_uInt32 DffRecord::getShapeBid()
276 {
277 sal_uInt32 nResult = 0;
278
279 if (getShapeType() == 75)
280 {
281 Records_t aRecords = findRecords(0xf00b);
282
283 if (aRecords.size() > 0)
284 {
285 DffOPTHandler aHandler;
286 DffOPT * pOpts = dynamic_cast<DffOPT*>((*aRecords.begin()).get());
287
288 sal_uInt32 nCount = pOpts->get_property_count();
289
290 for (sal_uInt32 n = 0; n < nCount; ++n)
291 {
292 pOpts->get_property(n)->resolve(aHandler);
293 }
294
295 WW8ValueSharedPointer_t pVal = aHandler.getValue(260);
296
297 if (pVal.get() != NULL)
298 nResult = pVal->getInt();
299 }
300 }
301
302 return nResult;
303 }
304
getType() const305 string DffRecord::getType() const
306 {
307 return "DffRecord";
308 }
309
getValue()310 Value::Pointer_t DffRecord::getValue()
311 {
312 return Value::Pointer_t();
313 }
314
getBinary()315 writerfilter::Reference<BinaryObj>::Pointer_t DffRecord::getBinary()
316 {
317 return writerfilter::Reference<BinaryObj>::Pointer_t();
318 }
319
getStream()320 writerfilter::Reference<Stream>::Pointer_t DffRecord::getStream()
321 {
322 return writerfilter::Reference<Stream>::Pointer_t();
323 }
324
getProps()325 writerfilter::Reference<Properties>::Pointer_t DffRecord::getProps()
326 {
327 return writerfilter::Reference<Properties>::Pointer_t(this->clone());
328 }
329
toString() const330 string DffRecord::toString() const
331 {
332 char sBuffer[1024];
333
334 snprintf(sBuffer, sizeof(sBuffer),
335 "<dffrecord type=\"%" SAL_PRIuUINT32 "\" instance=\"%" SAL_PRIuUINT32 "\" version=\"%" SAL_PRIuUINT32 "\">\n",
336 getRecordType(), getInstance(), getVersion());
337 string aResult = sBuffer;
338
339
340 if (!isContainer())
341 aResult += mSequence.toString();
342 else
343 {
344 WW8StructBase::Sequence aSeq(mSequence, 0, 8);
345 aResult += aSeq.toString();
346 }
347
348 aResult += "</dffrecord>";
349
350 return aResult;
351 }
352
getName() const353 string DffRecord::getName() const
354 {
355 return "";
356 }
357
getKind()358 Sprm::Kind DffRecord::getKind()
359 {
360 return Sprm::UNKNOWN;
361 }
362
DffBlock(WW8Stream & rStream,sal_uInt32 nOffset,sal_uInt32 nCount,sal_uInt32 nPadding)363 DffBlock::DffBlock(WW8Stream & rStream, sal_uInt32 nOffset,
364 sal_uInt32 nCount, sal_uInt32 nPadding)
365 : WW8StructBase(rStream, nOffset, nCount), bInitialized(false),
366 mnPadding(nPadding)
367 {
368 }
369
DffBlock(WW8StructBase * pParent,sal_uInt32 nOffset,sal_uInt32 nCount,sal_uInt32 nPadding)370 DffBlock::DffBlock(WW8StructBase * pParent, sal_uInt32 nOffset,
371 sal_uInt32 nCount, sal_uInt32 nPadding)
372 : WW8StructBase(pParent, nOffset, nCount), bInitialized(false),
373 mnPadding(nPadding)
374 {
375 }
376
DffBlock(const DffBlock & rSrc)377 DffBlock::DffBlock(const DffBlock & rSrc)
378 : WW8StructBase(rSrc), writerfilter::Reference<Properties>(rSrc),
379 bInitialized(false), mnPadding(rSrc.mnPadding)
380 {
381 }
382
initChildren()383 void DffBlock::initChildren()
384 {
385 sal_uInt32 nOffset = 0;
386 sal_uInt32 nCount = getCount();
387
388 while (nOffset < nCount)
389 {
390 sal_uInt32 nSize = 0;
391 DffRecord::Pointer_t pDffRecord
392 (createDffRecord(this, nOffset, &nSize));
393
394 if (nSize == 0)
395 break;
396
397 mRecords.push_back(pDffRecord);
398
399 nOffset += nSize + mnPadding;
400 }
401
402 bInitialized = true;
403 }
404
findRecords(sal_uInt32 nType,bool bRecursive,bool bAny)405 Records_t DffBlock::findRecords(sal_uInt32 nType, bool bRecursive, bool bAny)
406 {
407 Records_t aResult;
408
409 findRecords(nType, aResult, bRecursive, bAny);
410
411 return aResult;
412 }
413
findRecords(sal_uInt32 nType,Records_t & rRecords,bool bRecursive,bool bAny)414 void DffBlock::findRecords
415 (sal_uInt32 nType, Records_t & rRecords, bool bRecursive, bool bAny)
416 {
417 Records_t::iterator aIt = begin();
418
419 while (aIt != end())
420 {
421 DffRecord::Pointer_t pPointer(*aIt);
422
423 if (bAny || pPointer->getRecordType() == nType)
424 rRecords.push_back(pPointer);
425
426 if (bRecursive)
427 pPointer->findRecords(nType, rRecords, bRecursive,
428 bAny);
429
430 ++aIt;
431 }
432 }
433
resolve(Properties & rHandler)434 void DffBlock::resolve(Properties & rHandler)
435 {
436 Records_t::iterator aIt;
437
438 for (aIt = begin(); aIt != end(); ++aIt)
439 {
440 DffRecord * pDff = aIt->get();
441 rHandler.sprm(*pDff);
442 }
443 }
444
getShape(sal_uInt32 nSpid)445 DffRecord::Pointer_t DffBlock::getShape(sal_uInt32 nSpid)
446 {
447 DffRecord::Pointer_t pResult;
448
449 Records_t aRecords = findRecords(0xf004);
450 Records_t::iterator aIt;
451 for (aIt = aRecords.begin(); aIt != aRecords.end(); ++aIt)
452 {
453 DffRecord::Pointer_t pPointer = *aIt;
454
455 Records_t aFSPs = pPointer->findRecords(0xf00a);
456 Records_t::iterator aItFSP = aFSPs.begin();
457
458 if (aItFSP != aFSPs.end())
459 {
460 DffFSP * pFSP = dynamic_cast<DffFSP *>((*aItFSP).get());
461
462 if (pFSP->get_shpid() == nSpid)
463 {
464 pResult = pPointer;
465
466 break;
467 }
468 }
469 }
470
471 return pResult;
472 }
473
getBlip(sal_uInt32 nBlip)474 DffRecord::Pointer_t DffBlock::getBlip(sal_uInt32 nBlip)
475 {
476 DffRecord::Pointer_t pResult;
477
478 if (nBlip > 0)
479 {
480 nBlip--;
481
482 Records_t aRecords = findRecords(0xf007);
483
484 if (nBlip < aRecords.size())
485 {
486 pResult = aRecords[nBlip];
487 }
488 }
489
490 return pResult;
491 }
492
begin()493 Records_t::iterator DffBlock::begin()
494 {
495 if (! bInitialized)
496 initChildren();
497
498 return mRecords.begin();
499 }
500
end()501 Records_t::iterator DffBlock::end()
502 {
503 if (! bInitialized)
504 initChildren();
505
506 return mRecords.end();
507 }
508
getType() const509 string DffBlock::getType() const
510 {
511 return "DffBlock";
512 }
513
514 }}
515