update copyright date
[gnash.git] / libcore / PropertyList.h
blob99c45528e0a80d87868d4e406afa41c291006c50
1 //
2 // Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010,
3 // 2011 Free Software 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 <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>
33 #include <algorithm>
35 #include "Property.h" // for templated functions
37 // Forward declaration
38 namespace gnash {
39 class as_object;
40 class as_function;
41 struct ObjectURI;
42 class as_value;
45 namespace gnash {
47 /// An abstract property visitor
48 class PropertyVisitor {
49 public:
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
57 class KeyVisitor {
58 public:
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
79 /// owner.
80 class PropertyList : boost::noncopyable
82 public:
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;
94 struct KeyExtractor
96 typedef const ObjectURI& result_type;
97 result_type operator()(const Property& p) const {
98 return p.uri();
102 /// Identifier for the case-sensitive index
103 struct Case {};
105 /// The case-sensitive index
106 typedef boost::multi_index::ordered_unique<
107 boost::multi_index::tag<Case>,
108 KeyExtractor,
109 ObjectURI::LessThan> CaseIndex;
111 /// Identifier for the case-insensitive index
112 struct NoCase {};
114 /// The case-insensitive index
115 typedef boost::multi_index::ordered_non_unique<
116 boost::multi_index::tag<NoCase>,
117 KeyExtractor,
118 ObjectURI::CaseLessThan> NoCaseIndex;
120 /// The container of the Properties.
121 typedef boost::multi_index_container<
122 value_type,
123 boost::multi_index::indexed_by<SequencedIndex, CaseIndex, NoCaseIndex>
124 > container;
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);
134 /// Visit properties
136 /// The method will invoke the given visitor method
137 /// passing it two arguments: name of the property and
138 /// value of it.
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
143 /// acceptable.
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()
148 /// returns false.
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();
153 it != ie; ++it) {
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
166 /// avoid this.
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.
178 /// @param uri
179 /// Name of the property.
180 /// @param value
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
195 /// not delete them.
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
217 /// requested.
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
222 /// is created.
223 /// @return true if the property was successfully added, false
224 /// otherwise.
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
233 /// requested.
234 /// @param setter A function to invoke when setting this property's value.
235 /// @return true if the property was successfully added, false
236 /// otherwise.
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
244 /// requested.
245 /// @param flagsIfMissing Flags to associate to the property if a new
246 /// one is created.
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
255 /// requested.
257 /// @param flagsIfMissing Flags to associate to the property if a new
258 // one is created.
259 /// @return true if the property was successfully added, false
260 /// otherwise.
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
278 void clear();
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.
289 void dump();
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));
300 private:
302 container _props;
304 as_object& _owner;
309 } // namespace gnash
311 #endif // GNASH_PROPERTYLIST_H