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 <resourcemodel/WW8ResourceModel.hxx>
26 #include <resourcemodel/TableManager.hxx>
27 #include <resourcemodel/QNameToString.hxx>
28 #include <resourcemodel/exceptions.hxx>
29 #include <resourcemodel/SubSequence.hxx>
30 #include <resourcemodel/util.hxx>
31 #include <resourcemodel.hxx>
32 
33 namespace writerfilter {
34 
35 class ResourceModelOutputWithDepth : public OutputWithDepth<string>
36 {
37 public:
ResourceModelOutputWithDepth()38     ResourceModelOutputWithDepth()
39     : OutputWithDepth<string>("<tablegroup>", "</tablegroup>") {}
40 
~ResourceModelOutputWithDepth()41     ~ResourceModelOutputWithDepth() {outputGroup();}
42 
output(const string & str) const43     void output(const string & str) const { cout << str << endl; }
44 };
45 
46 ResourceModelOutputWithDepth output;
47 
createStreamHandler()48 Stream::Pointer_t createStreamHandler()
49 {
50     return Stream::Pointer_t(new WW8StreamHandler());
51 }
52 
dump(OutputWithDepth<string> &,const char *,writerfilter::Reference<Properties>::Pointer_t)53 void dump(OutputWithDepth<string> & /*o*/, const char * /*name*/,
54           writerfilter::Reference<Properties>::Pointer_t /*props*/)
55 {
56 }
57 
dump(OutputWithDepth<string> & o,const char * name,sal_uInt32 n)58 void dump(OutputWithDepth<string> & o, const char * name, sal_uInt32 n)
59 {
60     char sBuffer[256];
61     snprintf(sBuffer, sizeof(sBuffer), "%" SAL_PRIuUINT32, n);
62     string tmpStr = name;
63     tmpStr += "=";
64     tmpStr += sBuffer;
65 
66     o.addItem(tmpStr);
67 }
68 
dump(OutputWithDepth<string> &,const char *,const rtl::OUString &)69 void dump(OutputWithDepth<string> & /*o*/, const char * /*name*/,
70           const rtl::OUString & /*str*/)
71 {
72 }
73 
dump(OutputWithDepth<string> &,const char *,writerfilter::Reference<BinaryObj>::Pointer_t)74 void dump(OutputWithDepth<string> & /*o*/, const char * /*name*/,
75           writerfilter::Reference<BinaryObj>::Pointer_t /*binary*/)
76 {
77 }
78 
79 string gInfo = "";
80 // ------- WW8TableDataHandler ---------
81 
82 class TablePropsRef : public writerfilter::Reference<Properties>
83 {
84 public:
85     typedef boost::shared_ptr<TablePropsRef> Pointer_t;
86 
TablePropsRef()87     TablePropsRef() {}
~TablePropsRef()88     virtual ~TablePropsRef() {}
89 
resolve(Properties &)90     virtual void resolve(Properties & /*rHandler*/) {}
91 
getType() const92     virtual string getType() const { return "TableProps"; }
reset()93     void reset() {}
insert(Pointer_t)94     void insert(Pointer_t /* pTablePropsRef */) {}
95 };
96 
97 typedef TablePropsRef::Pointer_t TablePropsRef_t;
98 
99 class WW8TableDataHandler : public TableDataHandler<string,
100                             TablePropsRef_t>
101 {
102 public:
103     typedef boost::shared_ptr<WW8TableDataHandler> Pointer_t;
104     virtual void startTable(unsigned int nRows, unsigned int nDepth,
105                             TablePropsRef_t pProps);
106     virtual void endTable(
107         const unsigned int nDepth );
108     virtual void startRow(unsigned int nCols,
109                           TablePropsRef_t pProps);
110     virtual void endRow();
111     virtual void startCell(const string & start, TablePropsRef_t pProps);
112     virtual void endCell(const string & end);
113 };
114 
startTable(unsigned int nRows,unsigned int nDepth,TablePropsRef_t)115 void WW8TableDataHandler::startTable(unsigned int nRows, unsigned int nDepth,
116                                      TablePropsRef_t /*pProps*/)
117 {
118     char sBuffer[256];
119 
120     string tmpStr = "<tabledata.table rows=\"";
121     snprintf(sBuffer, sizeof(sBuffer), "%d", nRows);
122     tmpStr += sBuffer;
123     tmpStr += "\" depth=\"";
124     snprintf(sBuffer, sizeof(sBuffer), "%d", nDepth);
125     tmpStr += sBuffer;
126     tmpStr += "\">";
127 
128     output.addItem(tmpStr);
129 }
130 
endTable(const unsigned int)131 void WW8TableDataHandler::endTable(
132     const unsigned int /*nDepth*/ )
133 {
134     output.addItem("</tabledata.table>");
135 }
136 
startRow(unsigned int nCols,TablePropsRef_t)137 void WW8TableDataHandler::startRow
138 (unsigned int nCols, TablePropsRef_t /*pProps*/)
139 {
140     char sBuffer[256];
141 
142     snprintf(sBuffer, sizeof(sBuffer), "%d", nCols);
143     string tmpStr = "<tabledata.row cells=\"";
144     tmpStr += sBuffer;
145     tmpStr += "\">";
146     output.addItem(tmpStr);
147 }
148 
endRow()149 void WW8TableDataHandler::endRow()
150 {
151     output.addItem("</tabledata.row>");
152 }
153 
startCell(const string & start,TablePropsRef_t)154 void WW8TableDataHandler::startCell(const string & start,
155                                     TablePropsRef_t /*pProps*/)
156 {
157     output.addItem("<tabledata.cell>");
158     output.addItem(start);
159     output.addItem(", ");
160 }
161 
endCell(const string & end)162 void WW8TableDataHandler::endCell(const string & end)
163 {
164     output.addItem(end);
165     output.addItem("</tabledata.cell>");
166 }
167 
168 // ----- WW8TableDataManager -------------------------------
169 
170 class WW8TableManager :
171     public TableManager<string, TablePropsRef_t>
172 {
173     typedef TableDataHandler<string, TablePropsRef_t>
174     TableDataHandlerPointer_t;
175 
176 public:
177     WW8TableManager();
~WW8TableManager()178     virtual ~WW8TableManager() {}
179     virtual void endParagraphGroup();
180     virtual bool sprm(Sprm & rSprm);
181 };
182 
WW8TableManager()183 WW8TableManager::WW8TableManager()
184 {
185     TableDataHandler<string, TablePropsRef_t>::Pointer_t pHandler(new WW8TableDataHandler());
186     setHandler(pHandler);
187 }
188 
sprm(Sprm & rSprm)189 bool WW8TableManager::sprm(Sprm & rSprm)
190 {
191     TableManager<string, TablePropsRef_t>::sprm(rSprm);
192     output.setDepth(getTableDepthNew());
193     return true;
194 }
195 
endParagraphGroup()196 void WW8TableManager::endParagraphGroup()
197 {
198     string tmpStr = "<tabledepth depth=\"";
199     char sBuffer[256];
200     snprintf(sBuffer, sizeof(sBuffer), "%" SAL_PRIuUINT32, getTableDepthNew());
201     tmpStr += sBuffer;
202     tmpStr += "\"/>";
203     output.addItem(tmpStr);
204     TableManager<string, TablePropsRef_t>::endParagraphGroup();
205 }
206 
207 WW8TableManager gTableManager;
208 
209 /* WW8StreamHandler */
210 
WW8StreamHandler()211 WW8StreamHandler::WW8StreamHandler()
212 : mnUTextCount(0)
213 {
214     output.closeGroup();
215     output.addItem("<stream>");
216     gTableManager.startLevel();
217 }
218 
~WW8StreamHandler()219 WW8StreamHandler::~WW8StreamHandler()
220 {
221     gTableManager.endLevel();
222 
223     output.closeGroup();
224     output.addItem("</stream>");
225 }
226 
startSectionGroup()227 void WW8StreamHandler::startSectionGroup()
228 {
229     output.addItem("<section-group>");
230 }
231 
endSectionGroup()232 void WW8StreamHandler::endSectionGroup()
233 {
234     output.addItem("</section-group>");
235 }
236 
startParagraphGroup()237 void WW8StreamHandler::startParagraphGroup()
238 {
239     output.openGroup();
240     output.addItem("<paragraph-group>");
241 
242     gTableManager.startParagraphGroup();
243     gTableManager.handle(gInfo);
244 }
245 
endParagraphGroup()246 void WW8StreamHandler::endParagraphGroup()
247 {
248     gTableManager.endParagraphGroup();
249 
250     output.addItem("</paragraph-group>");
251     output.closeGroup();
252 
253 }
254 
startCharacterGroup()255 void WW8StreamHandler::startCharacterGroup()
256 {
257     output.addItem("<character-group>");
258 }
259 
endCharacterGroup()260 void WW8StreamHandler::endCharacterGroup()
261 {
262     output.addItem("</character-group>");
263 }
264 
startShape(::com::sun::star::uno::Reference<::com::sun::star::drawing::XShape>)265 void WW8StreamHandler::startShape( ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > /*xShape*/ )
266 {
267     output.addItem("<shape>");
268 }
269 
endShape()270 void WW8StreamHandler::endShape( )
271 {
272     output.addItem( "</shape>" );
273 }
274 
text(const sal_uInt8 * data,size_t len)275 void WW8StreamHandler::text(const sal_uInt8 * data, size_t len)
276 {
277     string tmpStr = "<text>";
278 
279     for (unsigned int n = 0; n < len; ++n)
280     {
281         switch (static_cast<unsigned char>(data[n]))
282         {
283         case '<':
284             tmpStr += "&lt;";
285 
286             break;
287         case '>':
288             tmpStr += "&gt;";
289 
290             break;
291 
292         case '&':
293             tmpStr += "&amp;";
294 
295             break;
296         default:
297             if (isprint(data[n]))
298                 tmpStr += static_cast<char>(data[n]);
299             else
300             {
301                 char sBuffer[256];
302 
303                 snprintf(sBuffer, sizeof(sBuffer), "\\0x%02x", data[n]);
304 
305                 tmpStr += sBuffer;
306             }
307         }
308     }
309 
310     tmpStr += "</text>";
311 
312     output.addItem(tmpStr);
313 
314     gTableManager.text(data, len);
315 }
316 
utext(const sal_uInt8 * data,size_t len)317 void WW8StreamHandler::utext(const sal_uInt8 * data, size_t len)
318 {
319 	static char sBuffer[256];
320 	snprintf(sBuffer, sizeof(sBuffer), "<utext count=\"%d\">", mnUTextCount);
321     string tmpStr(sBuffer);
322 
323     for (unsigned int n = 0; n < len; ++n)
324     {
325         sal_Unicode nChar = data[n * 2] + (data[n * 2 + 1] << 8);
326         if (nChar < 0xff && isprint(nChar))
327         {
328             switch (nChar)
329             {
330             case '&':
331                 tmpStr += "&amp;";
332                 break;
333             case '<':
334                 tmpStr += "&lt;";
335                 break;
336             case '>':
337                 tmpStr += "&gt;";
338                 break;
339             default:
340                 tmpStr += static_cast<char>(nChar);
341             }
342         }
343         else
344         {
345             snprintf(sBuffer, sizeof(sBuffer), "\\0x%04x", nChar);
346 
347             tmpStr += sBuffer;
348         }
349     }
350 
351     tmpStr += "</utext>";
352 
353     output.addItem(tmpStr);
354 
355     gTableManager.utext(data, len);
356 
357 	mnUTextCount++;
358 }
359 
props(writerfilter::Reference<Properties>::Pointer_t ref)360 void WW8StreamHandler::props(writerfilter::Reference<Properties>::Pointer_t ref)
361 {
362     WW8PropertiesHandler aHandler;
363 
364     output.addItem("<properties type=\"" + ref->getType() + "\">");
365     ref->resolve(aHandler);
366 
367     //gTableManager.props(ref);
368 
369     output.addItem("</properties>");
370 }
371 
table(Id name,writerfilter::Reference<Table>::Pointer_t ref)372 void WW8StreamHandler::table(Id name, writerfilter::Reference<Table>::Pointer_t ref)
373 {
374     WW8TableHandler aHandler;
375 
376     output.addItem("<table id=\"" + (*QNameToString::Instance())(name)
377                    + "\">");
378 
379     try
380     {
381         ref->resolve(aHandler);
382     }
383     catch (Exception e)
384     {
385         output.addItem("<exception>" + e.getText() + "</exception>");
386     }
387 
388     output.addItem("</table>");
389 }
390 
substream(Id name,writerfilter::Reference<Stream>::Pointer_t ref)391 void WW8StreamHandler::substream(Id name,
392                                  writerfilter::Reference<Stream>::Pointer_t ref)
393 {
394     output.addItem("<substream name=\"" + (*QNameToString::Instance())(name)
395                    + "\">");
396 
397     gTableManager.startLevel();
398 
399     ref->resolve(*this);
400 
401     gTableManager.endLevel();
402 
403     output.addItem("</substream>");
404 }
405 
info(const string & info_)406 void WW8StreamHandler::info(const string & info_)
407 {
408     gInfo = info_;
409     output.addItem("<info>" + info_ + "</info>");
410 }
411 
attribute(Id name,Value & val)412 void WW8PropertiesHandler::attribute(Id name, Value & val)
413 {
414     boost::shared_ptr<rtl::OString> pStr(new ::rtl::OString());
415     ::rtl::OUString aStr = val.getString();
416     aStr.convertToString(pStr.get(), RTL_TEXTENCODING_ASCII_US,
417                          OUSTRING_TO_OSTRING_CVTFLAGS);
418     string sXMLValue = xmlify(pStr->getStr());
419 
420     char sBuffer[256];
421     snprintf(sBuffer, sizeof(sBuffer), "0x%x", val.getInt());
422 
423     output.addItem("<attribute name=\"" +
424                    (*QNameToString::Instance())(name) +
425                    "\" value=\"" +
426                    sXMLValue +
427                    + "\" hexvalue=\""
428                    + sBuffer + "\">");
429 
430     writerfilter::Reference<Properties>::Pointer_t pProps = val.getProperties();
431 
432     if (pProps.get() != NULL)
433     {
434         output.addItem("<properties name=\"" +
435                        (*QNameToString::Instance())(name)
436                        + "\" type=\"" + pProps->getType() + "\">");
437 
438         try
439         {
440             pProps->resolve(*this);
441         }
442         catch (ExceptionOutOfBounds e)
443         {
444             output.addItem("<exception/>");
445         }
446 
447         output.addItem("</properties>");
448     }
449 
450     writerfilter::Reference<Stream>::Pointer_t pStream = val.getStream();
451 
452     if (pStream.get() != NULL)
453     {
454         try
455         {
456             WW8StreamHandler aHandler;
457 
458             pStream->resolve(aHandler);
459         }
460         catch (ExceptionOutOfBounds e)
461         {
462             output.addItem("<exception>Out Of Bounds</exception>");
463         }
464     }
465 
466     writerfilter::Reference<BinaryObj>::Pointer_t pBinObj = val.getBinary();
467 
468     if (pBinObj.get() != NULL)
469     {
470         try
471         {
472             WW8BinaryObjHandler aHandler;
473 
474             pBinObj->resolve(aHandler);
475         }
476         catch (ExceptionOutOfBounds e)
477         {
478             output.addItem("<exception>Out Of Bounds</exception>");
479         }
480     }
481 
482     output.addItem("</attribute>");
483 }
484 
sprm(Sprm & sprm_)485 void WW8PropertiesHandler::sprm(Sprm & sprm_)
486 {
487     string tmpStr = "<sprm id=\"";
488     char buffer[256];
489     snprintf(buffer, sizeof(buffer), "0x%" SAL_PRIxUINT32, sprm_.getId());
490     tmpStr += buffer;
491     tmpStr += "\" name=\"";
492     tmpStr += sprm_.getName();
493     tmpStr += "\">";
494     output.addItem(tmpStr);
495     output.addItem(sprm_.toString());
496 
497     writerfilter::Reference<Properties>::Pointer_t pProps = sprm_.getProps();
498 
499     if (pProps.get() != NULL)
500     {
501         output.addItem("<properties type=\"" + pProps->getType() + "\">");
502         pProps->resolve(*this);
503         output.addItem("</properties>");
504     }
505 
506     writerfilter::Reference<BinaryObj>::Pointer_t pBinObj = sprm_.getBinary();
507 
508     if (pBinObj.get() != NULL)
509     {
510         output.addItem("<binary>");
511         WW8BinaryObjHandler aHandler;
512         pBinObj->resolve(aHandler);
513         output.addItem("</binary>");
514     }
515 
516     writerfilter::Reference<Stream>::Pointer_t pStream = sprm_.getStream();
517 
518     if (pStream.get() != NULL)
519     {
520         output.addItem("<stream>");
521         WW8StreamHandler aHandler;
522         pStream->resolve(aHandler);
523         output.addItem("</stream>");
524     }
525 
526     gTableManager.sprm(sprm_);
527 
528     output.addItem("</sprm>");
529 }
530 
entry(int,writerfilter::Reference<Properties>::Pointer_t ref)531 void WW8TableHandler::entry(int /*pos*/,
532                             writerfilter::Reference<Properties>::Pointer_t ref)
533 {
534     output.addItem("<tableentry>");
535 
536     WW8PropertiesHandler aHandler;
537 
538     try
539     {
540         ref->resolve(aHandler);
541     }
542     catch (Exception e)
543     {
544         output.addItem("<exception>" + e.getText() + "</exception>");
545         output.addItem("</tableentry>");
546 
547         throw e;
548     }
549 
550     output.addItem("</tableentry>");
551 }
552 
data(const sal_uInt8 * buf,size_t length,writerfilter::Reference<Properties>::Pointer_t)553 void WW8BinaryObjHandler::data
554 (const sal_uInt8 * buf, size_t length,
555  writerfilter::Reference<Properties>::Pointer_t /*pRef*/)
556 {
557 #if 1
558     SubSequence<sal_uInt8> aSeq(buf, length);
559 
560     aSeq.dump(output);
561 #endif
562 }
563 
564 }
565