fix brain malfunction
[LibreOffice.git] / xmloff / source / style / xmlprmap.cxx
blobd8503eebb3f9103faa62c1055cdc4c8bb5075407
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 <o3tl/safeint.hxx>
21 #include <rtl/ref.hxx>
23 #include <xmloff/xmlprmap.hxx>
24 #include <xmloff/xmlprhdl.hxx>
25 #include <xmloff/xmltypes.hxx>
26 #include <xmloff/xmltoken.hxx>
27 #include <xmloff/maptype.hxx>
28 #include <xmloff/prhdlfac.hxx>
29 #include <xmloff/xmlimp.hxx>
31 #include <com/sun/star/beans/XPropertySet.hpp>
33 #include <vector>
35 using namespace ::com::sun::star::uno;
36 using namespace ::com::sun::star::beans;
37 using ::xmloff::token::GetXMLToken;
39 namespace {
41 /** Helper-class for XML-im/export:
42 - Holds a pointer to a given array of XMLPropertyMapEntry
43 - Provides several methods to access data from this array
44 - Holds a Sequence of XML-names (for properties)
45 - The filter takes all properties of the XPropertySet which are also
46 in the XMLPropertyMapEntry and which are have not a default value
47 and put them into a vector of XMLPropertyStae
48 - this class knows how to compare, im/export properties
50 Attention: At all methods, which get an index as parameter, there is no
51 range validation to save runtime !!
53 struct XMLPropertySetMapperEntry_Impl
55 OUString sXMLAttributeName;
56 OUString sAPIPropertyName;
57 sal_Int32 nType;
58 sal_uInt16 nXMLNameSpace;
59 sal_Int16 nContextId;
60 SvtSaveOptions::ODFSaneDefaultVersion nEarliestODFVersionForExport;
61 bool bImportOnly;
62 const XMLPropertyHandler *pHdl;
64 XMLPropertySetMapperEntry_Impl(
65 const XMLPropertyMapEntry& rMapEntry,
66 const rtl::Reference< XMLPropertyHandlerFactory >& rFactory );
68 sal_uInt32 GetPropType() const { return nType & XML_TYPE_PROP_MASK; }
73 XMLPropertySetMapperEntry_Impl::XMLPropertySetMapperEntry_Impl(
74 const XMLPropertyMapEntry& rMapEntry,
75 const rtl::Reference< XMLPropertyHandlerFactory >& rFactory ) :
76 sXMLAttributeName( GetXMLToken(rMapEntry.meXMLName) ),
77 sAPIPropertyName( rMapEntry.getApiName() ),
78 nType( rMapEntry.mnType ),
79 nXMLNameSpace( rMapEntry.mnNameSpace ),
80 nContextId( rMapEntry.mnContextId ),
81 nEarliestODFVersionForExport( rMapEntry.mnEarliestODFVersionForExport ),
82 bImportOnly( rMapEntry.mbImportOnly),
83 pHdl( rFactory->GetPropertyHandler( rMapEntry.mnType & MID_FLAG_MASK ) )
85 assert(pHdl);
88 struct XMLPropertySetMapper::Impl
90 std::vector<XMLPropertySetMapperEntry_Impl> maMapEntries;
91 std::vector<rtl::Reference <XMLPropertyHandlerFactory> > maHdlFactories;
93 bool mbOnlyExportMappings;
95 explicit Impl( bool bForExport ) : mbOnlyExportMappings(bForExport) {}
98 // Ctor
99 XMLPropertySetMapper::XMLPropertySetMapper(
100 const XMLPropertyMapEntry* pEntries, const rtl::Reference<XMLPropertyHandlerFactory>& rFactory,
101 bool bForExport ) :
102 mpImpl(new Impl(bForExport))
104 mpImpl->maHdlFactories.push_back(rFactory);
105 if( !pEntries )
106 return;
108 const XMLPropertyMapEntry* pIter = pEntries;
110 if (mpImpl->mbOnlyExportMappings)
112 while( !pIter->IsEnd() )
114 if (!pIter->mbImportOnly)
116 XMLPropertySetMapperEntry_Impl aEntry( *pIter, rFactory );
117 mpImpl->maMapEntries.push_back( aEntry );
119 ++pIter;
122 else
124 while( !pIter->IsEnd() )
126 XMLPropertySetMapperEntry_Impl aEntry( *pIter, rFactory );
127 mpImpl->maMapEntries.push_back( aEntry );
128 ++pIter;
133 XMLPropertySetMapper::~XMLPropertySetMapper()
137 void XMLPropertySetMapper::AddMapperEntry(
138 const rtl::Reference < XMLPropertySetMapper >& rMapper )
140 for( const auto& rHdlFactory : rMapper->mpImpl->maHdlFactories )
142 mpImpl->maHdlFactories.push_back(rHdlFactory);
145 for( const auto& rMapEntry : rMapper->mpImpl->maMapEntries )
147 if (!mpImpl->mbOnlyExportMappings || !rMapEntry.bImportOnly)
148 mpImpl->maMapEntries.push_back( rMapEntry );
152 sal_Int32 XMLPropertySetMapper::GetEntryCount() const
154 return mpImpl->maMapEntries.size();
157 sal_uInt32 XMLPropertySetMapper::GetEntryFlags( sal_Int32 nIndex ) const
159 assert((0 <= nIndex) && (o3tl::make_unsigned(nIndex) < mpImpl->maMapEntries.size()));
160 return mpImpl->maMapEntries[nIndex].nType & ~MID_FLAG_MASK;
163 sal_uInt32 XMLPropertySetMapper::GetEntryType( sal_Int32 nIndex ) const
165 assert((0 <= nIndex) && (o3tl::make_unsigned(nIndex) < mpImpl->maMapEntries.size()));
166 sal_uInt32 nType = mpImpl->maMapEntries[nIndex].nType;
167 return nType;
170 sal_uInt16 XMLPropertySetMapper::GetEntryNameSpace( sal_Int32 nIndex ) const
172 assert((0 <= nIndex) && (o3tl::make_unsigned(nIndex) < mpImpl->maMapEntries.size()));
173 return mpImpl->maMapEntries[nIndex].nXMLNameSpace;
176 const OUString& XMLPropertySetMapper::GetEntryXMLName( sal_Int32 nIndex ) const
178 assert((0 <= nIndex) && (o3tl::make_unsigned(nIndex) < mpImpl->maMapEntries.size()));
179 return mpImpl->maMapEntries[nIndex].sXMLAttributeName;
182 const OUString& XMLPropertySetMapper::GetEntryAPIName( sal_Int32 nIndex ) const
184 assert((0 <= nIndex) && (o3tl::make_unsigned(nIndex) < mpImpl->maMapEntries.size()));
185 return mpImpl->maMapEntries[nIndex].sAPIPropertyName;
188 sal_Int16 XMLPropertySetMapper::GetEntryContextId( sal_Int32 nIndex ) const
190 assert((-1 <= nIndex) && (nIndex < static_cast<sal_Int32>(mpImpl->maMapEntries.size())));
191 return nIndex == -1 ? 0 : mpImpl->maMapEntries[nIndex].nContextId;
194 SvtSaveOptions::ODFSaneDefaultVersion
195 XMLPropertySetMapper::GetEarliestODFVersionForExport(sal_Int32 const nIndex) const
197 assert((0 <= nIndex) && (o3tl::make_unsigned(nIndex) < mpImpl->maMapEntries.size()));
198 return mpImpl->maMapEntries[nIndex].nEarliestODFVersionForExport;
201 const XMLPropertyHandler* XMLPropertySetMapper::GetPropertyHandler( sal_Int32 nIndex ) const
203 assert((0 <= nIndex) && (o3tl::make_unsigned(nIndex) < mpImpl->maMapEntries.size()));
204 return mpImpl->maMapEntries[nIndex].pHdl;
207 // Export a Property
208 bool XMLPropertySetMapper::exportXML(
209 OUString& rStrExpValue,
210 const XMLPropertyState& rProperty,
211 const SvXMLUnitConverter& rUnitConverter ) const
213 bool bRet = false;
215 const XMLPropertyHandler* pHdl = GetPropertyHandler( rProperty.mnIndex );
217 assert(pHdl);
218 if( pHdl )
219 bRet = pHdl->exportXML( rStrExpValue, rProperty.maValue,
220 rUnitConverter );
222 return bRet;
225 // Import a Property
226 bool XMLPropertySetMapper::importXML(
227 const OUString& rStrImpValue,
228 XMLPropertyState& rProperty,
229 const SvXMLUnitConverter& rUnitConverter ) const
231 bool bRet = false;
233 const XMLPropertyHandler* pHdl = GetPropertyHandler( rProperty.mnIndex );
235 if( pHdl )
236 bRet = pHdl->importXML( rStrImpValue, rProperty.maValue,
237 rUnitConverter );
239 return bRet;
242 // Search for the given name and the namespace in the list and return
243 // the index of the entry
244 // If there is no matching entry the method returns -1
245 sal_Int32 XMLPropertySetMapper::GetEntryIndex(
246 sal_uInt16 nNamespace,
247 std::u16string_view rStrName,
248 sal_uInt32 nPropType,
249 sal_Int32 nStartAt /* = -1 */ ) const
251 sal_Int32 nEntries = GetEntryCount();
252 sal_Int32 nIndex= nStartAt == - 1? 0 : nStartAt+1;
254 if ( nEntries && nIndex < nEntries )
258 const XMLPropertySetMapperEntry_Impl& rEntry = mpImpl->maMapEntries[nIndex];
259 if( (!nPropType || nPropType == rEntry.GetPropType()) &&
260 rEntry.nXMLNameSpace == nNamespace &&
261 rStrName == rEntry.sXMLAttributeName )
262 return nIndex;
263 else
264 nIndex++;
266 } while( nIndex<nEntries );
269 return -1;
272 // Search for the given name and the namespace in the list and return
273 // the index of the entry
274 // If there is no matching entry the method returns -1
275 sal_Int32 XMLPropertySetMapper::GetEntryIndex(
276 sal_Int32 nElement,
277 sal_uInt32 nPropType,
278 sal_Int32 nStartAt /* = -1 */ ) const
280 sal_Int32 nEntries = GetEntryCount();
281 sal_Int32 nIndex= nStartAt == - 1? 0 : nStartAt+1;
283 if ( nEntries && nIndex < nEntries )
285 sal_uInt16 nNamespace = (nElement >> NMSP_SHIFT) - 1;
286 const OUString& rStrName = SvXMLImport::getNameFromToken(nElement);
289 const XMLPropertySetMapperEntry_Impl& rEntry = mpImpl->maMapEntries[nIndex];
290 if( (!nPropType || nPropType == rEntry.GetPropType()) &&
291 rEntry.nXMLNameSpace == nNamespace &&
292 rStrName == rEntry.sXMLAttributeName )
293 return nIndex;
294 else
295 nIndex++;
297 } while( nIndex<nEntries );
300 return -1;
303 /** searches for an entry that matches the given api name, namespace and local name or -1 if nothing found */
304 sal_Int32 XMLPropertySetMapper::FindEntryIndex(
305 const char* sApiName,
306 sal_uInt16 nNameSpace,
307 std::u16string_view sXMLName ) const
309 sal_Int32 nIndex = 0;
310 sal_Int32 nEntries = GetEntryCount();
314 const XMLPropertySetMapperEntry_Impl& rEntry = mpImpl->maMapEntries[nIndex];
315 if( rEntry.nXMLNameSpace == nNameSpace &&
316 rEntry.sXMLAttributeName == sXMLName &&
317 rEntry.sAPIPropertyName.equalsAscii( sApiName ) )
318 return nIndex;
319 else
320 nIndex++;
322 } while( nIndex < nEntries );
324 return -1;
327 sal_Int32 XMLPropertySetMapper::FindEntryIndex( const sal_Int16 nContextId ) const
329 const sal_Int32 nEntries = GetEntryCount();
331 if ( nEntries )
333 sal_Int32 nIndex = 0;
336 const XMLPropertySetMapperEntry_Impl& rEntry = mpImpl->maMapEntries[nIndex];
337 if( rEntry.nContextId == nContextId )
338 return nIndex;
339 else
340 nIndex++;
342 } while( nIndex < nEntries );
345 return -1;
348 void XMLPropertySetMapper::RemoveEntry( sal_Int32 nIndex )
350 const sal_Int32 nEntries = GetEntryCount();
351 if( nIndex>=nEntries || nIndex<0 )
352 return;
353 std::vector < XMLPropertySetMapperEntry_Impl >::iterator aEIter = mpImpl->maMapEntries.begin();
354 std::advance(aEIter, nIndex);
355 mpImpl->maMapEntries.erase( aEIter );
358 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */