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 
21 #include <comphelper/propertysetinfo.hxx>
22 #include <comphelper/sequence.hxx>
23 #include <vector>
24 
25 
26 using namespace ::comphelper;
27 using namespace ::com::sun::star;
28 using namespace ::com::sun::star::uno;
29 using namespace ::com::sun::star::beans;
30 using namespace ::com::sun::star::lang;
31 
32 namespace comphelper
33 {
34 class PropertyMapImpl final
35 {
36 public:
37     PropertyMapImpl() throw();
38 
39     void add(PropertyMapEntry const * pMap) throw();
40     void remove( const OUString& aName ) throw();
41 
42     std::vector< Property > const & getProperties() throw();
43 
getPropertyMap() const44     const PropertyMap& getPropertyMap() const throw() { return maPropertyMap;}
45 
46         /// @throws UnknownPropertyException
47     Property getPropertyByName( const OUString& aName );
48     bool hasPropertyByName( const OUString& aName ) throw();
49 
50 private:
51     PropertyMap maPropertyMap;
52     std::vector< Property > maProperties;
53 };
54 }
55 
PropertyMapImpl()56 PropertyMapImpl::PropertyMapImpl() throw()
57 {
58 }
59 
add(PropertyMapEntry const * pMap)60 void PropertyMapImpl::add(PropertyMapEntry const * pMap) throw()
61 {
62     while (!pMap->maName.isEmpty())
63     {
64         // check for duplicates
65         assert(maPropertyMap.find(pMap->maName) == maPropertyMap.end());
66 
67         maPropertyMap[pMap->maName] = pMap;
68 
69         maProperties.clear();
70 
71         pMap = &pMap[1];
72     }
73 }
74 
remove(const OUString & aName)75 void PropertyMapImpl::remove( const OUString& aName ) throw()
76 {
77     maPropertyMap.erase( aName );
78 
79     maProperties.clear();
80 }
81 
getProperties()82 std::vector< Property > const & PropertyMapImpl::getProperties() throw()
83 {
84     // maybe we have to generate the properties after
85     // a change in the property map or at first call
86     // to getProperties
87     if( maProperties.size() != maPropertyMap.size() )
88     {
89         maProperties.resize( maPropertyMap.size() );
90         auto propIter = maProperties.begin();
91 
92         for( const auto& rProperty : maPropertyMap )
93         {
94             PropertyMapEntry const * pEntry = rProperty.second;
95 
96             propIter->Name = pEntry->maName;
97             propIter->Handle = pEntry->mnHandle;
98             propIter->Type = pEntry->maType;
99             propIter->Attributes = pEntry->mnAttributes;
100 
101             ++propIter;
102         }
103     }
104 
105     return maProperties;
106 }
107 
108 
getPropertyByName(const OUString & aName)109 Property PropertyMapImpl::getPropertyByName( const OUString& aName )
110 {
111     PropertyMap::iterator aIter = maPropertyMap.find( aName );
112 
113     if( maPropertyMap.end() == aIter )
114         throw UnknownPropertyException( aName );
115 
116     PropertyMapEntry const * pEntry = (*aIter).second;
117 
118     return Property( aName, pEntry->mnHandle, pEntry->maType, pEntry->mnAttributes );
119 }
120 
hasPropertyByName(const OUString & aName)121 bool PropertyMapImpl::hasPropertyByName( const OUString& aName ) throw()
122 {
123     return maPropertyMap.find( aName ) != maPropertyMap.end();
124 }
125 
126 
PropertySetInfo()127 PropertySetInfo::PropertySetInfo() throw()
128     : mpImpl(new PropertyMapImpl)
129 {
130 }
131 
PropertySetInfo(PropertyMapEntry const * pMap)132 PropertySetInfo::PropertySetInfo( PropertyMapEntry const * pMap ) throw()
133     : mpImpl(new PropertyMapImpl)
134 {
135     mpImpl->add( pMap );
136 }
137 
PropertySetInfo(uno::Sequence<beans::Property> const & rProps)138 PropertySetInfo::PropertySetInfo(uno::Sequence<beans::Property> const& rProps) throw()
139     : mpImpl(new PropertyMapImpl)
140 {
141     PropertyMapEntry * pEntries(new PropertyMapEntry[rProps.getLength() + 1]);
142     PropertyMapEntry * pEntry(&pEntries[0]);
143     for (auto const& it : rProps)
144     {
145         pEntry->maName = it.Name;
146         pEntry->mnHandle = it.Handle;
147         pEntry->maType = it.Type;
148         pEntry->mnAttributes = it.Attributes;
149         pEntry->mnMemberId = 0;
150         ++pEntry;
151     }
152     pEntry->maName = OUString();
153     mpImpl->add(pEntries);
154 }
155 
~PropertySetInfo()156 PropertySetInfo::~PropertySetInfo() throw()
157 {
158 }
159 
add(PropertyMapEntry const * pMap)160 void PropertySetInfo::add( PropertyMapEntry const * pMap ) throw()
161 {
162     mpImpl->add( pMap );
163 }
164 
remove(const OUString & aName)165 void PropertySetInfo::remove( const OUString& aName ) throw()
166 {
167     mpImpl->remove( aName );
168 }
169 
getProperties()170 Sequence< css::beans::Property > SAL_CALL PropertySetInfo::getProperties()
171 {
172     return comphelper::containerToSequence(mpImpl->getProperties());
173 }
174 
getPropertyByName(const OUString & aName)175 Property SAL_CALL PropertySetInfo::getPropertyByName( const OUString& aName )
176 {
177     return mpImpl->getPropertyByName( aName );
178 }
179 
hasPropertyByName(const OUString & Name)180 sal_Bool SAL_CALL PropertySetInfo::hasPropertyByName( const OUString& Name )
181 {
182     return mpImpl->hasPropertyByName( Name );
183 }
184 
getPropertyMap() const185 const PropertyMap& PropertySetInfo::getPropertyMap() const throw()
186 {
187     return mpImpl->getPropertyMap();
188 }
189 
190 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
191