2 // Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Free Software
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
25 #include <string> // for use within map
26 #include <cassert> // for inlines
27 #include <utility> // for std::pair
28 #include <boost/cstdint.hpp>
29 #include <boost/multi_index_container.hpp>
30 #include <boost/multi_index/ordered_index.hpp>
31 #include <boost/multi_index/sequenced_index.hpp>
32 #include <boost/multi_index/key_extractors.hpp>
33 #include <boost/noncopyable.hpp>
34 #include <boost/bind.hpp>
37 #include "Property.h" // for templated functions
39 // Forward declaration
50 /// An abstract property visitor
51 class PropertyVisitor
{
54 /// This function should return false if no further visits are needed.
55 virtual bool accept(const ObjectURI
& uri
, const as_value
& val
) = 0;
56 virtual ~PropertyVisitor() {}
59 /// An abstract key visitor
63 /// This function should return false if no further visits are needed.
64 virtual void operator()(const ObjectURI
& uri
) = 0;
65 virtual ~KeyVisitor() {}
69 /// Set of properties associated with an ActionScript object.
71 /// The PropertyList container is the sole owner of the Property
72 /// elements in it contained and has full responsibility of their
73 /// construction and destruction.
75 /// A PropertyList holds a reference to the as_object whose properties it
76 /// contains. This reference will always be valid if the PropertyList
77 /// is a member of as_object.
79 /// It is theoretically possible for a PropertyList to be used with any
80 /// as_object, not just original as_object it was use with. Currently (as
81 /// there is no use for this scenario) it is not possible to change the
83 class PropertyList
: boost::noncopyable
87 typedef std::set
<ObjectURI
, ObjectURI::LessThan
> PropertyTracker
;
88 typedef Property value_type
;
90 /// Identifier for the sequenced index
91 struct CreationOrder
{};
93 /// The sequenced index in creation order.
94 typedef boost::multi_index::sequenced
<
95 boost::multi_index::tag
<CreationOrder
> > SequencedIndex
;
99 typedef const ObjectURI
& result_type
;
100 result_type
operator()(const Property
& p
) const {
105 /// Identifier for the case-sensitive index
108 /// The case-sensitive index
109 typedef boost::multi_index::ordered_unique
<
110 boost::multi_index::tag
<Case
>,
112 ObjectURI::LessThan
> CaseIndex
;
114 /// Identifier for the case-insensitive index
117 /// The case-insensitive index
118 typedef boost::multi_index::ordered_non_unique
<
119 boost::multi_index::tag
<NoCase
>,
121 ObjectURI::CaseLessThan
> NoCaseIndex
;
123 /// The container of the Properties.
124 typedef boost::multi_index_container
<
126 boost::multi_index::indexed_by
<SequencedIndex
, CaseIndex
, NoCaseIndex
>
129 typedef container::iterator iterator
;
130 typedef container::const_iterator const_iterator
;
132 /// Construct the PropertyList
134 /// @param obj The as_object to which this PropertyList belongs.
135 PropertyList(as_object
& obj
);
139 /// The method will invoke the given visitor method
140 /// passing it two arguments: name of the property and
143 /// @tparam V The type of the visitor.
144 /// @tparam U An object that may check property values. The object's
145 /// operator() should return false if the property is not
148 /// @param visitor The visitor function. It must implement the function:
149 /// bool accept(const ObjectURI&, const as_value&);
150 /// Scan is by enumeration order and stops when accept()
152 template <class U
, class V
>
153 void visitValues(V
& visitor
, U cmp
= U()) const {
155 for (const_iterator it
= _props
.begin(), ie
= _props
.end();
158 if (!cmp(*it
)) continue;
159 as_value val
= it
->getValue(_owner
);
160 if (!visitor
.accept(it
->uri(), val
)) return;
164 /// Enumerate all non-hidden properties to the given as_environment.
166 /// Follows enumeration order. Note that this enumeration does not
167 /// access the values. Accessing the values can result in changes to
168 /// the object if the value is a getter-setter, and key enumeration must
171 /// @param donelist Don't enumerate properties in donelist.
172 /// Enumerated properties are added to donelist.
173 void visitKeys(KeyVisitor
& v
, PropertyTracker
& donelist
) const;
175 /// Set the value of a property, creating a new one if it doesn't exist.
177 /// If the named property is a getter/setter one it's setter
178 /// will be invoked using the given as_object as 'this' pointer.
179 /// If the property is not found a SimpleProperty will be created.
182 /// Name of the property.
184 /// a const reference to the as_value to use for setting
185 /// or creating the property.
186 /// @param flagsIfMissing
187 /// Flags to associate to the property if a new one is created.
188 /// @return true if the value was successfully set, false
189 /// otherwise (found a read-only property, most likely).
190 bool setValue(const ObjectURI
& uri
, const as_value
& value
,
191 const PropFlags
& flagsIfMissing
= 0);
193 /// Get a property if it exists.
195 /// @param uri Name of the property.
196 /// @return A Property or 0, if no such property exists.
197 /// All Property objects are owned by this PropertyList. Do
199 Property
* getProperty(const ObjectURI
& uri
) const;
201 /// Delete a Property, if existing and not protected from deletion.
204 /// @param uri Name of the property.
205 /// @return a pair of boolean values expressing whether the property
206 /// was found (first) and whether it was deleted (second).
207 /// Of course a pair(false, true) would be invalid (deleted
208 /// a non-found property!?). Valid returns are:
209 /// - (false, false) : property not found
210 /// - (true, false) : property protected from deletion
211 /// - (true, true) : property successfully deleted
212 std::pair
<bool,bool> delProperty(const ObjectURI
& uri
);
214 /// Add a getter/setter property, if not already existing
216 /// TODO: this function has far too many arguments.
218 /// @param uri Name of the property.
219 /// @param getter A function to invoke when this property value is
221 /// @param setter A function to invoke when setting this property's value.
222 /// @param cacheVal The value to use as a cache. If null uses any cache
223 /// from pre-existing property with same name.
224 /// @param flagsIfMissing Flags to associate to the property if a new one
226 /// @return true if the property was successfully added, false
228 bool addGetterSetter(const ObjectURI
& uri
, as_function
& getter
,
229 as_function
* setter
, const as_value
& cacheVal
,
230 const PropFlags
& flagsIfMissing
= 0);
232 /// Add a getter/setter property, if not already existing
234 /// @param uri Name of the property.
235 /// @param getter A function to invoke when this property value is
237 /// @param setter A function to invoke when setting this property's value.
238 /// @return true if the property was successfully added, false
240 bool addGetterSetter(const ObjectURI
& uri
, as_c_function_ptr getter
,
241 as_c_function_ptr setter
, const PropFlags
& flagsIfMissing
);
243 /// Add a destructive getter property, if not already existant.
245 /// @param uri Name of the property.
246 /// @param getter A function to invoke when this property value is
248 /// @param flagsIfMissing Flags to associate to the property if a new
250 /// @return true if the property was successfully added.
251 bool addDestructiveGetter(const ObjectURI
& uri
, as_function
& getter
,
252 const PropFlags
& flagsIfMissing
= 0);
254 /// Add a destructive getter property, if not already existant.
256 /// @param uri Name of the property.
257 /// @param getter A function to invoke when this property value is
260 /// @param flagsIfMissing Flags to associate to the property if a new
262 /// @return true if the property was successfully added, false
264 bool addDestructiveGetter(const ObjectURI
& uri
, as_c_function_ptr getter
,
265 const PropFlags
& flagsIfMissing
= 0);
267 /// Set the flags of a property.
269 /// @param uri Name of the property.
270 /// @param setTrue The set of flags to set
271 /// @param setFalse The set of flags to clear
272 void setFlags(const ObjectURI
& uri
, int setTrue
, int setFalse
);
274 /// Set the flags of all properties.
276 /// @param setTrue The set of flags to set
277 /// @param setFalse The set of flags to clear
278 void setFlagsAll(int setTrue
, int setFalse
);
280 /// Remove all entries in the container
283 /// Return number of properties in this list
284 size_t size() const {
285 return _props
.size();
288 /// Dump all members (using log_debug)
290 /// This does not reflect the normal enumeration order. It is sorted
291 /// lexicographically by property.
294 /// Mark all properties reachable
296 /// This can be called very frequently, so is inlined to allow the
297 /// compiler to optimize it.
298 void setReachable() const {
299 std::for_each(_props
.begin(), _props
.end(),
300 boost::mem_fn(&Property::setReachable
));
314 #endif // GNASH_PROPERTYLIST_H