Plug more leaks (in the test, not the core)
[gnash.git] / libcore / PropertyList.h
blobd4afe52f3745d4d7d67e53746081bcd24133bf26
1 //
2 // Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Free Software
3 // Foundation, Inc
4 //
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.
9 //
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.
14 //
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 <set>
23 #include <map>
24 #include <vector>
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>
35 #include <algorithm>
37 #include "Property.h" // for templated functions
39 // Forward declaration
40 namespace gnash {
41 class as_object;
42 class as_environment;
43 class as_function;
44 struct ObjectURI;
45 class as_value;
48 namespace gnash {
50 /// An abstract property visitor
51 class PropertyVisitor {
52 public:
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
60 class KeyVisitor {
61 public:
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
82 /// owner.
83 class PropertyList : boost::noncopyable
85 public:
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;
97 struct KeyExtractor
99 typedef const ObjectURI& result_type;
100 result_type operator()(const Property& p) const {
101 return p.uri();
105 /// Identifier for the case-sensitive index
106 struct Case {};
108 /// The case-sensitive index
109 typedef boost::multi_index::ordered_unique<
110 boost::multi_index::tag<Case>,
111 KeyExtractor,
112 ObjectURI::LessThan> CaseIndex;
114 /// Identifier for the case-insensitive index
115 struct NoCase {};
117 /// The case-insensitive index
118 typedef boost::multi_index::ordered_non_unique<
119 boost::multi_index::tag<NoCase>,
120 KeyExtractor,
121 ObjectURI::CaseLessThan> NoCaseIndex;
123 /// The container of the Properties.
124 typedef boost::multi_index_container<
125 value_type,
126 boost::multi_index::indexed_by<SequencedIndex, CaseIndex, NoCaseIndex>
127 > container;
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);
137 /// Visit properties
139 /// The method will invoke the given visitor method
140 /// passing it two arguments: name of the property and
141 /// value of it.
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
146 /// acceptable.
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()
151 /// returns false.
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();
156 it != ie; ++it) {
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
169 /// avoid this.
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.
181 /// @param uri
182 /// Name of the property.
183 /// @param value
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
198 /// not delete them.
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
220 /// requested.
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
225 /// is created.
226 /// @return true if the property was successfully added, false
227 /// otherwise.
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
236 /// requested.
237 /// @param setter A function to invoke when setting this property's value.
238 /// @return true if the property was successfully added, false
239 /// otherwise.
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
247 /// requested.
248 /// @param flagsIfMissing Flags to associate to the property if a new
249 /// one is created.
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
258 /// requested.
260 /// @param flagsIfMissing Flags to associate to the property if a new
261 // one is created.
262 /// @return true if the property was successfully added, false
263 /// otherwise.
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
281 void clear();
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.
292 void dump();
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));
303 private:
305 container _props;
307 as_object& _owner;
312 } // namespace gnash
314 #endif // GNASH_PROPERTYLIST_H