LibreOffice Module writerfilter (master) 1
OOXMLPropertySet.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#include "OOXMLPropertySet.hxx"
21#include <stdio.h>
22#include <iostream>
24#include <com/sun/star/drawing/XShape.hpp>
26#include <tools/color.hxx>
27#include <o3tl/string_view.hxx>
28#include <utility>
29
30namespace writerfilter::ooxml
31{
32using namespace com::sun::star;
33
36 : mId(id), mpValue(std::move(pValue)), meType(eType)
37{
38}
39
41{
42}
43
44sal_uInt32 OOXMLProperty::getId() const
45{
46 return mId;
47}
48
50{
51 Value::Pointer_t pResult;
52
53 if (mpValue)
54 pResult = Value::Pointer_t(mpValue->clone());
55 else
56 pResult = Value::Pointer_t(new OOXMLValue());
57
58 return pResult;
59}
60
62{
64
65 if (mpValue)
66 pResult = mpValue->getProperties();
67
68 return pResult;
69}
70
71#ifdef DBG_UTIL
72std::string OOXMLProperty::getName() const
73{
74 std::string sResult(QNameToString(mId));
75
76 if (sResult.length() == 0)
77 sResult = fastTokenToId(mId);
78
79 if (sResult.length() == 0)
80 {
81 static char sBuffer[256];
82
83 snprintf(sBuffer, sizeof(sBuffer), "%" SAL_PRIxUINT32, mId);
84 sResult = sBuffer;
85 }
86
87 return sResult;
88}
89#endif
90
91#ifdef DBG_UTIL
92std::string OOXMLProperty::toString() const
93{
94 std::string sResult = "(";
95
96 sResult += getName();
97 sResult += ", ";
98 if (mpValue)
99 sResult += mpValue->toString();
100 else
101 sResult +="(null)";
102 sResult +=")";
103
104 return sResult;
105}
106#endif
107
109{
110 switch (meType)
111 {
112 case SPRM:
113 if (mId != 0x0)
114 rProperties.sprm(*this);
115 break;
116 case ATTRIBUTE:
117 rProperties.attribute(mId, *getValue());
118 break;
119 }
120}
121
122/*
123 class OOXMLValue
124*/
125
127{
128}
129
131{
132}
133
135{
136 return 0;
137}
138
139OUString OOXMLValue::getString() const
140{
141 return OUString();
142}
143
145{
146 return uno::Any();
147}
148
150{
152}
153
155{
157}
158
159#ifdef DBG_UTIL
160std::string OOXMLValue::toString() const
161{
162 return "OOXMLValue";
163}
164#endif
165
167{
168 return new OOXMLValue(*this);
169}
170
171/*
172 class OOXMLBinaryValue
173 */
174
176: mpBinaryObj(std::move(pBinaryObj))
177{
178}
179
181{
182}
183
185{
186 return mpBinaryObj;
187}
188
189#ifdef DBG_UTIL
190std::string OOXMLBinaryValue::toString() const
191{
192 return "BinaryObj";
193}
194#endif
195
197{
198 return new OOXMLBinaryValue(mpBinaryObj);
199}
200
201/*
202 class OOXMLBooleanValue
203*/
204
205static bool GetBooleanValue(std::string_view pValue)
206{
207 return pValue == "true"
208 || pValue == "True"
209 || pValue == "1"
210 || pValue == "on"
211 || pValue == "On";
212}
213
215{
218
219 return bValue ? True : False;
220}
221
222OOXMLValue::Pointer_t const & OOXMLBooleanValue::Create(std::string_view pValue)
223{
224 return Create (GetBooleanValue(pValue));
225}
226
228: mbValue(bValue)
229{
230}
231
233{
234}
235
237{
238 return mbValue ? 1 : 0;
239}
240
242{
243 return uno::Any(mbValue);
244}
245
246#ifdef DBG_UTIL
248{
249 return mbValue ? "true" : "false";
250}
251#endif
252
254{
255 return new OOXMLBooleanValue(*this);
256}
257
258/*
259 class OOXMLStringValue
260*/
261
263: mStr(std::move(sStr))
264{
265}
266
268{
269}
270
272{
273 return uno::Any(mStr);
274}
275
277{
278 return mStr;
279}
280
281#ifdef DBG_UTIL
282std::string OOXMLStringValue::toString() const
283{
284 return std::string(OUStringToOString(mStr, RTL_TEXTENCODING_ASCII_US));
285}
286#endif
287
289{
290 return new OOXMLStringValue(*this);
291}
292
293/*
294 class OOXMLInputStreamValue
295 */
297: mxInputStream(std::move(xInputStream))
298{
299}
300
302{
303}
304
306{
307 return uno::Any(mxInputStream);
308}
309
310#ifdef DBG_UTIL
312{
313 return "InputStream";
314}
315#endif
316
318{
320}
321
327{
328}
329
331{
332}
333
335{
336 // The pProp->resolve(rHandler) call below can cause elements to
337 // be appended to mProperties. I don't think it can cause elements
338 // to be deleted. But let's check with < here just to be safe that
339 // the indexing below works.
340 for (size_t nIt = 0; nIt < mProperties.size(); ++nIt)
341 {
343
344 if (pProp)
345 pProp->resolve(rHandler);
346 }
347}
348
349OOXMLPropertySet::OOXMLProperties_t::iterator OOXMLPropertySet::begin()
350{
351 return mProperties.begin();
352}
353
354OOXMLPropertySet::OOXMLProperties_t::iterator OOXMLPropertySet::end()
355{
356 return mProperties.end();
357}
358
359OOXMLPropertySet::OOXMLProperties_t::const_iterator
361{
362 return mProperties.begin();
363}
364
365OOXMLPropertySet::OOXMLProperties_t::const_iterator
367{
368 return mProperties.end();
369}
370
372{
373 if (pProperty && pProperty->getId() != 0x0)
374 {
375 mProperties.push_back(pProperty);
376 }
377}
378
380{
381 OOXMLProperty::Pointer_t pProperty(new OOXMLProperty(id, pValue, eType));
382 add(pProperty);
383}
384
386{
387 const OOXMLPropertySet * pSet = pPropertySet.get();
388
389 if (pSet != nullptr)
390 {
391 mProperties.insert( mProperties.end(), pSet->mProperties.begin(), pSet->mProperties.end() );
392 }
393}
394
396{
397 return new OOXMLPropertySet(*this);
398}
399
400#ifdef DBG_UTIL
402{
403 std::string sResult = "[";
404 char sBuffer[256];
405 snprintf(sBuffer, sizeof(sBuffer), "%p", this);
406 sResult += sBuffer;
407 sResult += ":";
408
409 OOXMLProperties_t::iterator aItBegin = begin();
410 OOXMLProperties_t::iterator aItEnd = end();
411
412 for (OOXMLProperties_t::iterator aIt = aItBegin; aIt != aItEnd; ++aIt)
413 {
414 if (aIt != aItBegin)
415 sResult += ", ";
416
417 if (*aIt)
418 sResult += (*aIt)->toString();
419 else
420 sResult += "0x0";
421 }
422
423 sResult += "]";
424
425 return sResult;
426}
427#endif
428
429/*
430 class OOXMLPropertySetValue
431*/
432
434 : mpPropertySet(std::move(pPropertySet))
435{
436}
437
439{
440}
441
443{
445 (mpPropertySet->clone());
446}
447
448#ifdef DBG_UTIL
450{
451 char sBuffer[256];
452
453 snprintf(sBuffer, sizeof(sBuffer), "t:%p, m:%p", this, mpPropertySet.get());
454
455 return "OOXMLPropertySetValue(" + std::string(sBuffer) + ")";
456}
457#endif
458
460{
461 return new OOXMLPropertySetValue(*this);
462}
463
464/*
465 class OOXMLIntegerValue
466*/
467
469{
471 static OOXMLValue::Pointer_t One(new OOXMLIntegerValue (1));
472 static OOXMLValue::Pointer_t Two(new OOXMLIntegerValue (2));
473 static OOXMLValue::Pointer_t Three(new OOXMLIntegerValue (3));
474 static OOXMLValue::Pointer_t Four(new OOXMLIntegerValue (4));
475 static OOXMLValue::Pointer_t Five(new OOXMLIntegerValue (5));
476 static OOXMLValue::Pointer_t Six(new OOXMLIntegerValue (6));
477 static OOXMLValue::Pointer_t Seven(new OOXMLIntegerValue (7));
478 static OOXMLValue::Pointer_t Eight(new OOXMLIntegerValue (8));
479 static OOXMLValue::Pointer_t Nine(new OOXMLIntegerValue (9));
480
481 switch (nValue) {
482 case 0: return Zero;
483 case 1: return One;
484 case 2: return Two;
485 case 3: return Three;
486 case 4: return Four;
487 case 5: return Five;
488 case 6: return Six;
489 case 7: return Seven;
490 case 8: return Eight;
491 case 9: return Nine;
492 default: break;
493 }
494
496
497 return value;
498}
499
502{
503}
504
506{
507}
508
510{
511 return mnValue;
512}
513
515{
516 return uno::Any(mnValue);
517}
518
520{
521 return new OOXMLIntegerValue(*this);
522}
523
524#ifdef DBG_UTIL
526{
527 char buffer[256];
528 snprintf(buffer, sizeof(buffer), "%" SAL_PRIdINT32, mnValue);
529
530 return buffer;
531}
532#endif
533
534/*
535 class OOXMLHexValue
536*/
537
540{
541}
542
543OOXMLHexValue::OOXMLHexValue(std::string_view pValue)
544: mnValue(o3tl::toUInt32(pValue, 16))
545{
546}
547
549{
550}
551
553{
554 return mnValue;
555}
556
558{
559 return new OOXMLHexValue(*this);
560}
561
562#ifdef DBG_UTIL
563std::string OOXMLHexValue::toString() const
564{
565 char buffer[256];
566 snprintf(buffer, sizeof(buffer), "0x%" SAL_PRIxUINT32, mnValue);
567
568 return buffer;
569}
570#endif
571
572/*
573 class OOXMLHexColorValue
574*/
576 : OOXMLHexValue(sal_uInt32(COL_AUTO))
577{
578 if (pValue == "auto")
579 return;
580
581 mnValue = o3tl::toUInt32(pValue, 16);
582
583 // Convert hash-encoded values (like #FF0080)
584 const sal_Int32 nLen = pValue.size();
585 if ( !mnValue && nLen > 1 && pValue[0] == '#' )
586 {
587 sal_Int32 nColor(COL_AUTO);
588 // Word appears to require strict 6 digit length, else it ignores it
589 if ( nLen == 7 )
590 {
591 const OUString sHashColor(pValue.data(), nLen, RTL_TEXTENCODING_ASCII_US);
592 sax::Converter::convertColor( nColor, sHashColor );
593 }
594 mnValue = nColor;
595 }
596}
597
598// OOXMLUniversalMeasureValue
599// ECMA-376 5th ed. Part 1 , 22.9.2.15
600OOXMLUniversalMeasureValue::OOXMLUniversalMeasureValue(std::string_view pValue, sal_uInt32 npPt)
601{
602 double val = o3tl::toDouble(pValue); // will ignore the trailing unit
603
604 int nLen = pValue.size();
605 if (nLen > 2 &&
606 pValue[nLen-2] == 'p' &&
607 pValue[nLen-1] == 't')
608 {
609 mnValue = static_cast<int>(val * npPt);
610 }
611 else if (nLen > 2 &&
612 pValue[nLen - 2] == 'c' &&
613 pValue[nLen - 1] == 'm')
614 {
615 mnValue = static_cast<int>(val * npPt * 72 / 2.54);
616 }
617 else if (nLen > 2 &&
618 pValue[nLen - 2] == 'm' &&
619 pValue[nLen - 1] == 'm')
620 {
621 mnValue = static_cast<int>(val * npPt * 72 / 25.4);
622 }
623 else if (nLen > 2 &&
624 pValue[nLen - 2] == 'i' &&
625 pValue[nLen - 1] == 'n')
626 {
627 mnValue = static_cast<int>(val * npPt * 72);
628 }
629 else if (nLen > 2 &&
630 pValue[nLen - 2] == 'p' &&
631 ( pValue[nLen - 1] == 'c' || pValue[nLen - 1] == 'i' ))
632 {
633 mnValue = static_cast<int>(val * npPt * 12);
634 }
635 else
636 {
637 mnValue = static_cast<int>(val);
638 }
639}
640
642{
643}
644
646{
647 return mnValue;
648}
649
650#ifdef DBG_UTIL
652{
653 return std::string(OString::number(mnValue));
654}
655#endif
656
657// OOXMLMeasurementOrPercentValue
658// ECMA-376 5th ed. Part 1 , 17.18.107; 17.18.11
660{
661 double val = o3tl::toDouble(pValue); // will ignore the trailing unit
662
663 int nLen = pValue.size();
664 if (nLen > 1 &&
665 pValue[nLen - 1] == '%')
666 {
667 mnValue = static_cast<int>(val * 50);
668 }
669 else
670 {
671 mnValue = OOXMLTwipsMeasureValue(pValue).getInt();
672 }
673}
674
676{
677 return mnValue;
678}
679
680#ifdef DBG_UTIL
682{
683 return std::string(OString::number(mnValue));
684}
685#endif
686
687/*
688 class OOXMLShapeValue
689 */
690
691
693: mrShape(std::move(xShape))
694{
695}
696
698{
699}
700
702{
703 return uno::Any(mrShape);
704}
705
706#ifdef DBG_UTIL
707std::string OOXMLShapeValue::toString() const
708{
709 return "Shape";
710}
711#endif
712
714{
715 return new OOXMLShapeValue(mrShape);
716}
717
718/*
719 class OOXMLStarMathValue
720 */
721
722
724: m_component(std::move(c))
725{
726}
727
729{
730}
731
733{
734 return uno::Any(m_component);
735}
736
737#ifdef DBG_UTIL
739{
740 return "StarMath";
741}
742#endif
743
745{
746 return new OOXMLStarMathValue( m_component );
747}
748
749/*
750 class OOXMLTableImpl
751 */
752
754{
755}
756
758{
759}
760
761
763{
764 Table * pTable = &rTable;
765
766 int nPos = 0;
767
768 for (const auto& rPropSet : mPropertySets)
769 {
771 (rPropSet->getProperties());
772
773 if (pProperties)
774 pTable->entry(nPos, pProperties);
775
776 ++nPos;
777 }
778}
779
780void OOXMLTable::add(const ValuePointer_t& pPropertySet)
781{
782 if (pPropertySet)
783 mPropertySets.push_back(pPropertySet);
784}
785
787{
788 return new OOXMLTable(*this);
789}
790
791/*
792 class: OOXMLPropertySetEntryToString
793*/
794
796: mnId(nId)
797{
798}
799
801{
802}
803
805{
806}
807
809{
810 if (nId == mnId)
811 mStr = rValue.getString();
812}
813
814/*
815 class: OOXMLPropertySetEntryToInteger
816*/
817
819: mnId(nId), mnValue(0)
820{
821}
822
824{
825}
826
828{
829}
830
832{
833 if (nId == mnId)
834 mnValue = rValue.getInt();
835}
836
837/*
838 class: OOXMLPropertySetEntryToBool
839*/
840
842 : mnId(nId), mValue(false)
843{}
844
846
848
850{
851 if (nId == mnId)
852 mValue = (rValue.getInt() != 0);
853}
854
855}
856
857/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
static bool convertColor(sal_Int32 &rColor, std::u16string_view rValue)
T * get() const
Handler for properties.
virtual void attribute(Id name, Value &val)=0
Receives an attribute.
virtual void sprm(Sprm &sprm)=0
Receives a SPRM.
tools::SvRef< Reference< T > > Pointer_t
Pointer to reference.
An SPRM: Section, Paragraph and Run Modifier.
Handler for tables.
virtual void entry(int pos, writerfilter::Reference< Properties >::Pointer_t ref)=0
Receives an entry of the table.
virtual int getInt() const =0
Returns integer representation of the value.
virtual OUString getString() const =0
Returns string representation of the value.
tools::SvRef< Value > Pointer_t
Pointer to a value.
OOXMLBinaryValue(OOXMLBinaryObjectReference::Pointer_t pBinaryObj)
virtual writerfilter::Reference< BinaryObj >::Pointer_t getBinary() override
Returns binary object of this value.
virtual std::string toString() const override
Returns string representation of this value.
virtual OOXMLValue * clone() const override
OOXMLBinaryObjectReference::Pointer_t mpBinaryObj
virtual css::uno::Any getAny() const override
Returns representation of the value as uno::Any.
virtual int getInt() const override
Returns integer representation of the value.
virtual std::string toString() const override
Returns string representation of this value.
static OOXMLValue::Pointer_t const & Create(bool bValue)
virtual OOXMLValue * clone() const override
virtual int getInt() const override
Returns integer representation of the value.
virtual OOXMLValue * clone() const override
virtual std::string toString() const override
Returns string representation of this value.
virtual OOXMLValue * clone() const override
virtual std::string toString() const override
Returns string representation of this value.
css::uno::Reference< css::io::XInputStream > mxInputStream
OOXMLInputStreamValue(css::uno::Reference< css::io::XInputStream > xInputStream)
virtual css::uno::Any getAny() const override
Returns representation of the value as uno::Any.
static OOXMLValue::Pointer_t Create(sal_Int32 nValue)
virtual std::string toString() const override
Returns string representation of this value.
virtual css::uno::Any getAny() const override
Returns representation of the value as uno::Any.
virtual int getInt() const override
Returns integer representation of the value.
virtual OOXMLValue * clone() const override
virtual int getInt() const override
Returns integer representation of the value.
virtual std::string toString() const override
Returns string representation of this value.
virtual void attribute(Id nId, Value &rValue) override
Receives an attribute.
virtual void sprm(Sprm &rSprm) override
Receives a SPRM.
virtual void sprm(Sprm &rSprm) override
Receives a SPRM.
virtual void attribute(Id nId, Value &rValue) override
Receives an attribute.
virtual void sprm(Sprm &rSprm) override
Receives a SPRM.
virtual void attribute(Id nId, Value &rValue) override
Receives an attribute.
OOXMLPropertySetValue(OOXMLPropertySet::Pointer_t pPropertySet)
virtual OOXMLValue * clone() const override
virtual writerfilter::Reference< Properties >::Pointer_t getProperties() override
Returns properties of this value.
virtual std::string toString() const override
Returns string representation of this value.
void resolve(Properties &rHandler) override
Resolves the reference.
OOXMLProperties_t::iterator begin()
OOXMLProperties_t::iterator end()
void add(const OOXMLProperty::Pointer_t &pProperty)
sal_uInt32 getId() const override
Returns id of the SPRM.
std::string getName() const override
Returns name of sprm.
std::string toString() const override
Returns string representation of sprm.
void resolve(Properties &rProperties)
writerfilter::Reference< Properties >::Pointer_t getProps() override
Returns reference to properties contained in the SPRM.
Value::Pointer_t getValue() override
Returns value of the SPRM.
OOXMLProperty(Id id, OOXMLValue::Pointer_t pValue, Type_t eType)
css::uno::Reference< css::drawing::XShape > mrShape
virtual css::uno::Any getAny() const override
Returns representation of the value as uno::Any.
virtual std::string toString() const override
Returns string representation of this value.
virtual OOXMLValue * clone() const override
OOXMLShapeValue(css::uno::Reference< css::drawing::XShape > xShape)
virtual css::uno::Any getAny() const override
Returns representation of the value as uno::Any.
virtual OOXMLValue * clone() const override
css::uno::Reference< css::embed::XEmbeddedObject > m_component
virtual std::string toString() const override
Returns string representation of this value.
OOXMLStarMathValue(css::uno::Reference< css::embed::XEmbeddedObject > component)
virtual css::uno::Any getAny() const override
Returns representation of the value as uno::Any.
virtual OOXMLValue * clone() const override
virtual OUString getString() const override
Returns string representation of the value.
virtual std::string toString() const override
Returns string representation of this value.
void add(const ValuePointer_t &pPropertySet)
void resolve(Table &rTable) override
Resolves the reference.
OOXMLUniversalMeasureValue(std::string_view pValue, sal_uInt32 npPt)
virtual int getInt() const override
Returns integer representation of the value.
virtual std::string toString() const override
Returns string representation of this value.
virtual std::string toString() const override
Returns string representation of this value.
virtual writerfilter::Reference< BinaryObj >::Pointer_t getBinary() override
Returns binary object of this value.
virtual OOXMLValue * clone() const
virtual writerfilter::Reference< Properties >::Pointer_t getProperties() override
Returns properties of this value.
virtual css::uno::Any getAny() const override
Returns representation of the value as uno::Any.
virtual OUString getString() const override
Returns string representation of the value.
virtual int getInt() const override
Returns integer representation of the value.
constexpr ::Color COL_AUTO(ColorTransparency, 0xFF, 0xFF, 0xFF, 0xFF)
Any value
sal_uInt16 mnId
DocumentType eType
sal_Int16 nValue
sal_uInt16 nPos
double toDouble(std::u16string_view str)
sal_uInt32 toUInt32(std::u16string_view str, sal_Int16 radix=10)
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
std::string fastTokenToId(sal_uInt32 nToken)
static bool GetBooleanValue(std::string_view pValue)
OOXMLNthPtMeasureValue< 20 > OOXMLTwipsMeasureValue
Handles OOXML's ST_TwipsMeasure value.
std::string QNameToString(Id)
sal_Int16 nId
sal_uInt32 Id
const double mnValue
RedlineType meType