2 // Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010,
3 // 2011 Free Software Foundation, Inc
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 3 of the License, or
8 // (at your option) any later version.
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 #ifndef GNASH_PROPERTYLIST_H
20 #define GNASH_PROPERTYLIST_H
23 #include <string> // for use within map
24 #include <cassert> // for inlines
25 #include <utility> // for std::pair
26 #include <boost/cstdint.hpp>
27 #include <boost/multi_index_container.hpp>
28 #include <boost/multi_index/ordered_index.hpp>
29 #include <boost/multi_index/sequenced_index.hpp>
30 #include <boost/multi_index/key_extractors.hpp>
31 #include <boost/noncopyable.hpp>
32 #include <boost/bind.hpp>
35 #include "Property.h" // for templated functions
37 // Forward declaration
47 /// An abstract property visitor
48 class PropertyVisitor
{
51 /// This function should return false if no further visits are needed.
52 virtual bool accept(const ObjectURI
& uri
, const as_value
& val
) = 0;
53 virtual ~PropertyVisitor() {}
56 /// An abstract key visitor
60 /// This function should return false if no further visits are needed.
61 virtual void operator()(const ObjectURI
& uri
) = 0;
62 virtual ~KeyVisitor() {}
66 /// Set of properties associated with an ActionScript object.
68 /// The PropertyList container is the sole owner of the Property
69 /// elements in it contained and has full responsibility of their
70 /// construction and destruction.
72 /// A PropertyList holds a reference to the as_object whose properties it
73 /// contains. This reference will always be valid if the PropertyList
74 /// is a member of as_object.
76 /// It is theoretically possible for a PropertyList to be used with any
77 /// as_object, not just original as_object it was use with. Currently (as
78 /// there is no use for this scenario) it is not possible to change the
80 class PropertyList
: boost::noncopyable
84 typedef std::set
<ObjectURI
, ObjectURI::LessThan
> PropertyTracker
;
85 typedef Property value_type
;
87 /// Identifier for the sequenced index
88 struct CreationOrder
{};
90 /// The sequenced index in creation order.
91 typedef boost::multi_index::sequenced
<
92 boost::multi_index::tag
<CreationOrder
> > SequencedIndex
;
96 typedef const ObjectURI
& result_type
;
97 result_type
operator()(const Property
& p
) const {
102 /// Identifier for the case-sensitive index
105 /// The case-sensitive index
106 typedef boost::multi_index::ordered_unique
<
107 boost::multi_index::tag
<Case
>,
109 ObjectURI::LessThan
> CaseIndex
;
111 /// Identifier for the case-insensitive index
114 /// The case-insensitive index
115 typedef boost::multi_index::ordered_non_unique
<
116 boost::multi_index::tag
<NoCase
>,
118 ObjectURI::CaseLessThan
> NoCaseIndex
;
120 /// The container of the Properties.
121 typedef boost::multi_index_container
<
123 boost::multi_index::indexed_by
<SequencedIndex
, CaseIndex
, NoCaseIndex
>
126 typedef container::iterator iterator
;
127 typedef container::const_iterator const_iterator
;
129 /// Construct the PropertyList
131 /// @param obj The as_object to which this PropertyList belongs.
132 PropertyList(as_object
& obj
);
136 /// The method will invoke the given visitor method
137 /// passing it two arguments: name of the property and
140 /// @tparam V The type of the visitor.
141 /// @tparam U An object that may check property values. The object's
142 /// operator() should return false if the property is not
145 /// @param visitor The visitor function. It must implement the function:
146 /// bool accept(const ObjectURI&, const as_value&);
147 /// Scan is by enumeration order and stops when accept()
149 template <class U
, class V
>
150 void visitValues(V
& visitor
, U cmp
= U()) const {
152 for (const_iterator it
= _props
.begin(), ie
= _props
.end();
155 if (!cmp(*it
)) continue;
156 as_value val
= it
->getValue(_owner
);
157 if (!visitor
.accept(it
->uri(), val
)) return;
161 /// Enumerate all non-hidden properties to the given container.
163 /// Follows enumeration order. Note that this enumeration does not
164 /// access the values. Accessing the values can result in changes to
165 /// the object if the value is a getter-setter, and key enumeration must
168 /// @param donelist Don't enumerate properties in donelist.
169 /// Enumerated properties are added to donelist.
170 void visitKeys(KeyVisitor
& v
, PropertyTracker
& donelist
) const;
172 /// Set the value of a property, creating a new one if it doesn't exist.
174 /// If the named property is a getter/setter one it's setter
175 /// will be invoked using the given as_object as 'this' pointer.
176 /// If the property is not found a SimpleProperty will be created.
179 /// Name of the property.
181 /// a const reference to the as_value to use for setting
182 /// or creating the property.
183 /// @param flagsIfMissing
184 /// Flags to associate to the property if a new one is created.
185 /// @return true if the value was successfully set, false
186 /// otherwise (found a read-only property, most likely).
187 bool setValue(const ObjectURI
& uri
, const as_value
& value
,
188 const PropFlags
& flagsIfMissing
= 0);
190 /// Get a property if it exists.
192 /// @param uri Name of the property.
193 /// @return A Property or 0, if no such property exists.
194 /// All Property objects are owned by this PropertyList. Do
196 Property
* getProperty(const ObjectURI
& uri
) const;
198 /// Delete a Property, if existing and not protected from deletion.
201 /// @param uri Name of the property.
202 /// @return a pair of boolean values expressing whether the property
203 /// was found (first) and whether it was deleted (second).
204 /// Of course a pair(false, true) would be invalid (deleted
205 /// a non-found property!?). Valid returns are:
206 /// - (false, false) : property not found
207 /// - (true, false) : property protected from deletion
208 /// - (true, true) : property successfully deleted
209 std::pair
<bool,bool> delProperty(const ObjectURI
& uri
);
211 /// Add a getter/setter property, if not already existing
213 /// TODO: this function has far too many arguments.
215 /// @param uri Name of the property.
216 /// @param getter A function to invoke when this property value is
218 /// @param setter A function to invoke when setting this property's value.
219 /// @param cacheVal The value to use as a cache. If null uses any cache
220 /// from pre-existing property with same name.
221 /// @param flagsIfMissing Flags to associate to the property if a new one
223 /// @return true if the property was successfully added, false
225 bool addGetterSetter(const ObjectURI
& uri
, as_function
& getter
,
226 as_function
* setter
, const as_value
& cacheVal
,
227 const PropFlags
& flagsIfMissing
= 0);
229 /// Add a getter/setter property, if not already existing
231 /// @param uri Name of the property.
232 /// @param getter A function to invoke when this property value is
234 /// @param setter A function to invoke when setting this property's value.
235 /// @return true if the property was successfully added, false
237 bool addGetterSetter(const ObjectURI
& uri
, as_c_function_ptr getter
,
238 as_c_function_ptr setter
, const PropFlags
& flagsIfMissing
);
240 /// Add a destructive getter property, if not already existant.
242 /// @param uri Name of the property.
243 /// @param getter A function to invoke when this property value is
245 /// @param flagsIfMissing Flags to associate to the property if a new
247 /// @return true if the property was successfully added.
248 bool addDestructiveGetter(const ObjectURI
& uri
, as_function
& getter
,
249 const PropFlags
& flagsIfMissing
= 0);
251 /// Add a destructive getter property, if not already existant.
253 /// @param uri Name of the property.
254 /// @param getter A function to invoke when this property value is
257 /// @param flagsIfMissing Flags to associate to the property if a new
259 /// @return true if the property was successfully added, false
261 bool addDestructiveGetter(const ObjectURI
& uri
, as_c_function_ptr getter
,
262 const PropFlags
& flagsIfMissing
= 0);
264 /// Set the flags of a property.
266 /// @param uri Name of the property.
267 /// @param setTrue The set of flags to set
268 /// @param setFalse The set of flags to clear
269 void setFlags(const ObjectURI
& uri
, int setTrue
, int setFalse
);
271 /// Set the flags of all properties.
273 /// @param setTrue The set of flags to set
274 /// @param setFalse The set of flags to clear
275 void setFlagsAll(int setTrue
, int setFalse
);
277 /// Remove all entries in the container
280 /// Return number of properties in this list
281 size_t size() const {
282 return _props
.size();
285 /// Dump all members (using log_debug)
287 /// This does not reflect the normal enumeration order. It is sorted
288 /// lexicographically by property.
291 /// Mark all properties reachable
293 /// This can be called very frequently, so is inlined to allow the
294 /// compiler to optimize it.
295 void setReachable() const {
296 std::for_each(_props
.begin(), _props
.end(),
297 boost::mem_fn(&Property::setReachable
));
311 #endif // GNASH_PROPERTYLIST_H