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
22 #include "Property.h" // for templated functions
26 #include <string> // for use within map
27 #include <cassert> // for inlines
28 #include <utility> // for std::pair
29 #include <boost/cstdint.hpp>
30 #include <boost/multi_index_container.hpp>
31 #include <boost/multi_index/ordered_index.hpp>
32 #include <boost/multi_index/sequenced_index.hpp>
33 #include <boost/multi_index/key_extractors.hpp>
34 #include <boost/noncopyable.hpp>
36 // Forward declaration
47 /// Set of properties associated with an ActionScript object.
49 /// The PropertyList container is the sole owner of the Property
50 /// elements in it contained and has full responsibility of their
51 /// construction and destruction.
53 /// A PropertyList holds a reference to the as_object whose properties it
54 /// contains. This reference will always be valid if the PropertyList
55 /// is a member of as_object.
57 /// It is theoretically possible for a PropertyList to be used with any
58 /// as_object, not just original as_object it was use with. Currently (as
59 /// there is no use for this scenario) it is not possible to change the
61 class PropertyList
: boost::noncopyable
66 typedef std::set
<ObjectURI
> PropertyTracker
;
67 typedef std::pair
<Property
, string_table::key
> value_type
;
71 typedef ObjectURI result_type
;
72 const result_type
& operator()(const value_type
& r
) const {
75 const result_type
& operator()(value_type
& r
) {
80 typedef boost::multi_index::member
<value_type
, value_type::second_type
,
81 &value_type::second
> KeyExtractor
;
83 typedef boost::multi_index_container
<
85 boost::multi_index::indexed_by
<
86 boost::multi_index::sequenced
<>,
87 boost::multi_index::ordered_unique
<NameExtractor
>,
88 boost::multi_index::ordered_non_unique
<KeyExtractor
>
91 typedef container::iterator iterator
;
92 typedef container::const_iterator const_iterator
;
94 /// Construct the PropertyList
96 /// @param obj The as_object to which this PropertyList belongs.
97 /// This object is not fully constructed at this stage,
98 /// so this constructor should not do anything with it!
99 PropertyList(as_object
& obj
)
108 /// The method will invoke the given visitor method
109 /// passing it two arguments: name of the property and
112 /// @tparam V The type of the visitor.
113 /// @tparam U An object that may check property values. The object's
114 /// operator() should return false if the property is not
117 /// @param visitor The visitor function. It must implement the function:
118 /// bool accept(const ObjectURI&, const as_value&);
119 /// Scan is by enumeration order and stops when accept()
121 template <class U
, class V
>
122 void visitValues(V
& visitor
, U cmp
= U()) const
124 // The template keyword is not required by the Standard here, but the
125 // OpenBSD compiler needs it. Use of the template keyword where it is
126 // not necessary is not an error.
127 for (const_iterator it
= _props
.begin(), ie
= _props
.end();
130 if (!cmp(it
->first
)) continue;
131 as_value val
= it
->first
.getValue(_owner
);
132 if (!visitor
.accept(it
->first
.uri(), val
)) return;
136 /// Enumerate all non-hidden properties to the given as_environment.
138 /// Follows enumeration order. Note that this enumeration does not
139 /// access the values. Accessing the values can result in changes to
140 /// the object if the value is a getter-setter, and key enumeration must
143 /// @param donelist Don't enumerate properties in donelist.
144 /// Enumerated properties are added to donelist.
145 void enumerateKeys(as_environment
& env
, PropertyTracker
& donelist
) const;
147 /// Set the value of a property, creating a new one if it doesn't exist.
149 /// If the named property is a getter/setter one it's setter
150 /// will be invoked using the given as_object as 'this' pointer.
151 /// If the property is not found a SimpleProperty will be created.
154 /// Name of the property.
156 /// a const reference to the as_value to use for setting
157 /// or creating the property.
158 /// @param flagsIfMissing
159 /// Flags to associate to the property if a new one is created.
160 /// @return true if the value was successfully set, false
161 /// otherwise (found a read-only property, most likely).
162 bool setValue(const ObjectURI
& uri
, const as_value
& value
,
163 const PropFlags
& flagsIfMissing
= 0);
165 /// Get a property if it exists.
167 /// @param uri Name of the property.
168 /// @return A Property or 0, if no such property exists.
169 /// All Property objects are owned by this PropertyList. Do
171 Property
* getProperty(const ObjectURI
& uri
) const;
173 /// Delete a Property, if existing and not protected from deletion.
176 /// @param uri Name of the property.
177 /// @return a pair of boolean values expressing whether the property
178 /// was found (first) and whether it was deleted (second).
179 /// Of course a pair(false, true) would be invalid (deleted
180 /// a non-found property!?). Valid returns are:
181 /// - (false, false) : property not found
182 /// - (true, false) : property protected from deletion
183 /// - (true, true) : property successfully deleted
184 std::pair
<bool,bool> delProperty(const ObjectURI
& uri
);
186 /// Add a getter/setter property, if not already existing
188 /// TODO: this function has far too many arguments.
190 /// @param uri Name of the property.
191 /// @param getter A function to invoke when this property value is
193 /// @param setter A function to invoke when setting this property's value.
194 /// @param cacheVal The value to use as a cache. If null uses any cache
195 /// from pre-existing property with same name.
196 /// @param flagsIfMissing Flags to associate to the property if a new one
198 /// @return true if the property was successfully added, false
200 bool addGetterSetter(const ObjectURI
& uri
, as_function
& getter
,
201 as_function
* setter
, const as_value
& cacheVal
,
202 const PropFlags
& flagsIfMissing
= 0);
204 /// Add a getter/setter property, if not already existing
206 /// @param uri Name of the property.
207 /// @param getter A function to invoke when this property value is
209 /// @param setter A function to invoke when setting this property's value.
210 /// @return true if the property was successfully added, false
212 bool addGetterSetter(const ObjectURI
& uri
, as_c_function_ptr getter
,
213 as_c_function_ptr setter
, const PropFlags
& flagsIfMissing
);
215 /// Add a destructive getter property, if not already existant.
217 /// @param uri Name of the property.
218 /// @param getter A function to invoke when this property value is
220 /// @param flagsIfMissing Flags to associate to the property if a new
222 /// @return true if the property was successfully added.
223 bool addDestructiveGetter(const ObjectURI
& uri
, as_function
& getter
,
224 const PropFlags
& flagsIfMissing
= 0);
226 /// Add a destructive getter property, if not already existant.
228 /// @param uri Name of the property.
229 /// @param getter A function to invoke when this property value is
232 /// @param flagsIfMissing Flags to associate to the property if a new
234 /// @return true if the property was successfully added, false
236 bool addDestructiveGetter(const ObjectURI
& uri
, as_c_function_ptr getter
,
237 const PropFlags
& flagsIfMissing
= 0);
239 /// Set the flags of a property.
241 /// @param uri Name of the property.
242 /// @param setTrue The set of flags to set
243 /// @param setFalse The set of flags to clear
244 void setFlags(const ObjectURI
& uri
, int setTrue
, int setFalse
);
246 /// Set the flags of all properties.
248 /// @param setTrue The set of flags to set
249 /// @param setFalse The set of flags to clear
250 void setFlagsAll(int setTrue
, int setFalse
);
252 /// Remove all entries in the container
255 /// Return number of properties in this list
256 size_t size() const {
257 return _props
.size();
260 /// Dump all members (using log_debug)
262 /// This does not reflect the normal enumeration order. It is sorted
263 /// lexicographically by property.
266 /// Dump all members into the given map
268 /// This does not reflect the normal enumeration order. It is sorted
269 /// lexicographically by property.
271 void dump(std::map
<std::string
, as_value
>& to
);
273 /// Mark all simple properties, getters and setters
274 /// as being reachable (for the GC)
275 void setReachable() const;
288 #endif // GNASH_PROPERTYLIST_H