~ubuntu-branches/ubuntu/saucy/gnash/saucy-proposed

« back to all changes in this revision

Viewing changes to libcore/array.h

  • Committer: Bazaar Package Importer
  • Author(s): Alexander Sack
  • Date: 2008-10-13 14:29:49 UTC
  • mfrom: (1.1.9 upstream)
  • Revision ID: james.westby@ubuntu.com-20081013142949-f6qdvnu4mn05ltdc
Tags: 0.8.4~~bzr9980-0ubuntu1
* new upstream release 0.8.4 (LP: #240325)
* ship new lib usr/lib/gnash/libmozsdk.so.* in mozilla-plugin-gnash
  - update debian/mozilla-plugin-gnash.install
* ship new lib usr/lib/gnash/libgnashnet.so.* in gnash-common
  - update debian/gnash-common.install
* add basic debian/build_head script to build latest CVS head packages.
  - add debian/build_head
* new sound architecture requires build depend on libsdl1.2-dev
  - update debian/control
* head build script now has been completely migrated to bzr (upstream +
  ubuntu)
  - update debian/build_head
* disable kde gui until klash/qt4 has been fixed; keep kde packages as empty
  packages for now.
  - update debian/rules
  - debian/klash.install
  - debian/klash.links
  - debian/klash.manpages
  - debian/konqueror-plugin-gnash.install
* drop libkonq5-dev build dependency accordingly
  - update debian/control
* don't install headers manually anymore. gnash doesnt provide a -dev
  package after all
  - update debian/rules
* update libs installed in gnash-common; libgnashserver-*.so is not available
  anymore (removed); in turn we add the new libgnashcore-*.so
  - update debian/gnash-common.install
* use -Os for optimization and properly pass CXXFLAGS=$(CFLAGS) to configure
  - update debian/rules
* touch firefox .autoreg in postinst of mozilla plugin
  - update debian/mozilla-plugin-gnash.postinst
* link gnash in ubufox plugins directory for the plugin alternative switcher
  - add debian/mozilla-plugin-gnash.links
* suggest ubufox accordingly
  - update debian/control
* add new required build-depends on libgif-dev
  - update debian/control
* add Xb-Npp-Description and Xb-Npp-File as new plugin database meta data
  - update debian/control

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// 
 
2
//   Copyright (C) 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
 
3
// 
 
4
// This program is free software; you can redistribute it and/or modify
 
5
// it under the terms of the GNU General Public License as published by
 
6
// the Free Software Foundation; either version 3 of the License, or
 
7
// (at your option) any later version.
 
8
// 
 
9
// This program is distributed in the hope that it will be useful,
 
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
// GNU General Public License for more details.
 
13
// 
 
14
// You should have received a copy of the GNU General Public License
 
15
// along with this program; if not, write to the Free Software
 
16
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
17
 
 
18
#ifndef GNASH_ARRAY_H
 
19
#define GNASH_ARRAY_H
 
20
 
 
21
#include "as_object.h" // for inheritance
 
22
#include "smart_ptr.h" // GNASH_USE_GC
 
23
 
 
24
#include <deque>
 
25
#include <vector>
 
26
#include <memory> // for auto_ptr
 
27
#include <boost/numeric/ublas/vector_sparse.hpp>
 
28
 
 
29
#include <string>
 
30
 
 
31
// Forward declarations
 
32
namespace gnash {
 
33
        class fn_call;
 
34
        class as_value;
 
35
}
 
36
 
 
37
namespace gnash {
 
38
 
 
39
struct indexed_as_value : public as_value
 
40
{
 
41
        int vec_index;
 
42
 
 
43
        indexed_as_value(const as_value& val, int index)
 
44
        : as_value(val)
 
45
        {
 
46
                vec_index = index;
 
47
        }
 
48
};
 
49
 
 
50
template <class T>
 
51
struct ContainerFiller {
 
52
        T& cont;
 
53
        ContainerFiller(T& c): cont(c) {}
 
54
        void visit(as_value& v) { cont.push_back(v); }
 
55
};
 
56
 
 
57
struct blank {};
 
58
 
 
59
/// The Array ActionScript object
 
60
class Array_as : public as_object
 
61
{
 
62
 
 
63
    /// Other classes shouldn't care about this, but should rather use
 
64
    /// the public iterator / const_iterator members.
 
65
        typedef boost::numeric::ublas::mapped_vector<as_value> ArrayContainer;
 
66
 
 
67
public:
 
68
 
 
69
        typedef ArrayContainer::const_iterator const_iterator;
 
70
        typedef ArrayContainer::iterator iterator;
 
71
 
 
72
        typedef std::list<as_value> ValueList;
 
73
 
 
74
 
 
75
        enum { itemBlank, itemValue };
 
76
 
 
77
        /// Visit all elements 
 
78
        //
 
79
        /// The visitor class will have to expose a visit(as_value&) method
 
80
        ///
 
81
        template<class V> void visitAll(V& v)
 
82
        {
 
83
                // NOTE: we copy the elements as the visitor might call arbitrary code
 
84
                //       possibly modifying the container itself.
 
85
                ArrayContainer copy = elements;
 
86
 
 
87
                // iterating this way will skip holes
 
88
                for (Array_as::iterator i=copy.begin(), ie=copy.end(); i!=ie; ++i)
 
89
                        v.visit(*i);
 
90
        }
 
91
 
 
92
    // see dox in as_object.h
 
93
        virtual void visitPropertyValues(AbstractPropertyVisitor& visitor) const;
 
94
 
 
95
    // see dox in as_object.h
 
96
        virtual void visitNonHiddenPropertyValues(AbstractPropertyVisitor& visitor) const;
 
97
 
 
98
        /// Sort flags
 
99
        enum SortFlags {
 
100
 
 
101
                /// Case-insensitive (z precedes A)
 
102
                fCaseInsensitive        = (1<<0), // 1
 
103
 
 
104
                /// Descending order (b precedes a)
 
105
                fDescending             = (1<<1), // 2
 
106
 
 
107
                /// If two or more elements in the array
 
108
                /// have identical sort fields, return 0
 
109
                /// and don't modify the array.
 
110
                /// Otherwise proceed to sort the array.
 
111
                fUniqueSort             = (1<<2), // 4
 
112
 
 
113
                /// Don't modify the array, rather return
 
114
                /// a new array containing indexes into it
 
115
                /// in sorted order.
 
116
                fReturnIndexedArray     = (1<<3), // 8
 
117
 
 
118
                /// Numerical sort (9 preceeds 10)
 
119
                fNumeric                = (1<<4) // 16
 
120
        };
 
121
 
 
122
        Array_as();
 
123
 
 
124
        Array_as(const Array_as& other);
 
125
 
 
126
        ~Array_as();
 
127
 
 
128
        std::deque<indexed_as_value> get_indexed_elements();
 
129
 
 
130
        Array_as::const_iterator begin();
 
131
 
 
132
        Array_as::const_iterator end();
 
133
 
 
134
        /// Push an element to the end of the array
 
135
        //
 
136
        /// @param val
 
137
        ///     The element to add 
 
138
        ///
 
139
        void push(const as_value& val);
 
140
 
 
141
        void unshift(const as_value& val);
 
142
 
 
143
        as_value shift();
 
144
 
 
145
        as_value pop();
 
146
 
 
147
        as_value at(unsigned int index) const;
 
148
 
 
149
        Array_as* get_indices(std::deque<indexed_as_value> origElems);
 
150
 
 
151
        void reverse();
 
152
 
 
153
        void set_indexed(unsigned int index, const as_value &v);
 
154
 
 
155
        /// @param env
 
156
        ///     If not-null will be used to properl invoke the toString()
 
157
        ///     method against member values.
 
158
        ///
 
159
        std::string join(const std::string& separator, as_environment* env) const;
 
160
 
 
161
        /// @param env
 
162
        ///     If not-null will be used to properly invoke the toString()
 
163
        ///     method against member values.
 
164
        ///
 
165
        std::string toString(as_environment* env=NULL) const;
 
166
 
 
167
        // override from as_object
 
168
        std::string get_text_value() const
 
169
        {
 
170
                return toString();
 
171
        }
 
172
 
 
173
        unsigned int size() const;
 
174
 
 
175
        void resize(unsigned int);
 
176
 
 
177
        void concat(const Array_as& other);
 
178
 
 
179
        /// \brief
 
180
        /// Return a newly created array containing elements
 
181
        /// from 'start' up to but not including 'end'.
 
182
        //
 
183
        ///
 
184
        /// NOTE: assertions are:
 
185
        ///
 
186
        ///     assert(one_past_end >= start);
 
187
        ///     assert(one_past_end <= size());
 
188
        ///     assert(start <= size());
 
189
        ///
 
190
        /// @param start
 
191
        ///     index to first element to include in result
 
192
        ///     0-based index.
 
193
        ///
 
194
        /// @param one_past_end
 
195
        ///     index to one-past element to include in result
 
196
        ///     0-based index.
 
197
        ///
 
198
        boost::intrusive_ptr<Array_as> slice(
 
199
                unsigned int start, unsigned int one_past_end);
 
200
 
 
201
        /// Remove first element matching the given value
 
202
        //
 
203
        /// Return true if any element was removed, false otherwise
 
204
        ///
 
205
        /// NOTE: if an element is removed, holes in the array will be
 
206
        ///       filled.
 
207
        ///
 
208
        /// @param v
 
209
        ///     The value to compare elements against
 
210
        ///
 
211
        /// @param env
 
212
        ///     The environment to use when comparing (needed by as_value::equals)
 
213
        ///
 
214
        bool removeFirst(const as_value& v);
 
215
 
 
216
        /// \brief
 
217
        /// Replace count elements from start with given values, optionally
 
218
        /// returning the erased ones.
 
219
        //
 
220
        /// @param start
 
221
        ///     First element to remove. Will abort if invalid.
 
222
        ///
 
223
        /// @param count
 
224
        ///     Number of elements to remove. Will abort if > then available.
 
225
        ///
 
226
        /// @param replace
 
227
        ///     If not null, use as a replacement for the cutted values
 
228
        ///
 
229
        /// @param copy
 
230
        ///     If not null, an array to push cutted values to.
 
231
        ///
 
232
        void splice(unsigned int start, unsigned int count, 
 
233
                        const std::vector<as_value>* replace=NULL,
 
234
                        Array_as* copy=NULL);
 
235
 
 
236
        /// \brief
 
237
        /// Sort the array, using given values comparator
 
238
        ///
 
239
        /// @param avc
 
240
        ///     boolean functor or function comparing two as_value& objects
 
241
        ///
 
242
        template <class AVCMP>
 
243
        void sort(AVCMP avc)
 
244
        {
 
245
                // IMPORTANT NOTE
 
246
                //
 
247
                // As for ISO/IEC 14882:2003 - 23.2.2.4.29 
 
248
                // the sort algorithm relies on the assumption
 
249
                // that the comparator function implements
 
250
                // a Strict Weak Ordering operator:
 
251
                // http://www.sgi.com/tech/stl/StrictWeakOrdering.html
 
252
                //
 
253
                // Invalid comparator can lead to undefined behaviour,
 
254
                // including invalid memory access and infinite loops.
 
255
                //
 
256
                // Pragmatically, it seems that std::list::sort is
 
257
                // more robust in this reguard, so we'll sort a list
 
258
                // instead of the queue. We want to sort a copy anyway
 
259
                // to avoid the comparator changing the original container.
 
260
                //
 
261
                ValueList nelem;
 
262
                ContainerFiller<ValueList> filler(nelem);
 
263
                visitAll(filler);
 
264
 
 
265
                size_t oldSize = elements.size(); // custom comparator might change input size
 
266
                nelem.sort(avc);
 
267
                elements.resize(oldSize, false);
 
268
                size_t idx=0;
 
269
                for (ValueList::iterator i=nelem.begin(), e=nelem.end(); i!=e; ++i)
 
270
                {
 
271
                        elements[idx++] = *i;
 
272
                };
 
273
        }
 
274
 
 
275
        /// \brief
 
276
        /// Attempt to sort the array using given values comparator, avc.
 
277
        /// If two or more elements in the array are equal, as determined
 
278
        /// by the equality comparator ave, then the array is not sorted
 
279
        /// and 0 is returned. Otherwise the array is sorted and returned.
 
280
        ///
 
281
        /// @param avc
 
282
        ///     boolean functor or function comparing two as_value& objects
 
283
        ///     used to determine sort-order
 
284
        ///
 
285
        /// @param ave
 
286
        ///     boolean functor or function comparing two as_value& objects
 
287
        ///     used to determine equality
 
288
        ///
 
289
        template <class AVCMP, class AVEQ>
 
290
        as_value sort(AVCMP avc, AVEQ ave)
 
291
        {
 
292
                // IMPORTANT NOTE
 
293
                //
 
294
                // As for ISO/IEC 14882:2003 - 23.2.2.4.29 
 
295
                // the sort algorithm relies on the assumption
 
296
                // that the comparator function implements
 
297
                // a Strict Weak Ordering operator:
 
298
                // http://www.sgi.com/tech/stl/StrictWeakOrdering.html
 
299
                //
 
300
                // Invalid comparator can lead to undefined behaviour,
 
301
                // including invalid memory access and infinite loops.
 
302
                //
 
303
                // Pragmatically, it seems that std::list::sort is
 
304
                // more robust in this reguard, so we'll sort a list
 
305
                // instead of the queue. We want to sort a copy anyway
 
306
                // to avoid the comparator changing the original container.
 
307
                //
 
308
 
 
309
                typedef std::list<as_value> ValueList;
 
310
                ValueList nelem;
 
311
                ContainerFiller<ValueList> filler(nelem);
 
312
                visitAll(filler);
 
313
 
 
314
                size_t oldSize = elements.size(); // custom comparator might change input size
 
315
 
 
316
                nelem.sort(avc);
 
317
 
 
318
                if (std::adjacent_find(nelem.begin(), nelem.end(), ave) != nelem.end() )
 
319
                        return as_value(0);
 
320
 
 
321
                elements.resize(oldSize, false);
 
322
                size_t idx=0;
 
323
                for (ValueList::iterator i=nelem.begin(), e=nelem.end(); i!=e; ++i)
 
324
                {
 
325
                        elements[idx++] = *i;
 
326
                };
 
327
 
 
328
                return as_value(this);
 
329
        }
 
330
 
 
331
        /// \brief
 
332
        /// Return a new array containing sorted index of this array
 
333
        ///
 
334
        /// @param avc
 
335
        ///     boolean functor or function comparing two as_value& objects
 
336
        ///
 
337
        template <class AVCMP>
 
338
        Array_as* sort_indexed(AVCMP avc)
 
339
        {
 
340
                std::deque<indexed_as_value> ielem = get_indexed_elements();
 
341
                std::sort(ielem.begin(), ielem.end(), avc);
 
342
                return get_indices(ielem);
 
343
        }
 
344
 
 
345
        /// \brief
 
346
        /// Return a new array containing sorted index of this array.
 
347
        /// If two or more elements in the array are equal, as determined
 
348
        /// by the equality comparator ave, then 0 is returned instead.
 
349
        ///
 
350
        /// @param avc
 
351
        ///     boolean functor or function comparing two as_value& objects
 
352
        ///     used to determine sort-order
 
353
        ///
 
354
        /// @param ave
 
355
        ///     boolean functor or function comparing two as_value& objects
 
356
        ///     used to determine equality
 
357
        ///
 
358
        template <class AVCMP, class AVEQ>
 
359
        as_value sort_indexed(AVCMP avc, AVEQ ave)
 
360
        {
 
361
                std::deque<indexed_as_value> ielem = get_indexed_elements();
 
362
 
 
363
                std::sort(ielem.begin(), ielem.end(), avc);
 
364
 
 
365
                if (std::adjacent_find(ielem.begin(), ielem.end(), ave) != ielem.end() )
 
366
                        return as_value(0);
 
367
 
 
368
                return get_indices(ielem);
 
369
        }
 
370
 
 
371
    /// Why is this overridden?
 
372
        virtual bool get_member(string_table::key name, as_value* val,
 
373
                string_table::key nsname = 0);
 
374
 
 
375
        /// Overridden to provide array[#]=x semantic
 
376
        virtual bool set_member(string_table::key name,
 
377
                const as_value& val, string_table::key nsname=0, bool ifFound=false);
 
378
 
 
379
        /// Overridden to deal with indexed elements
 
380
        virtual std::pair<bool,bool> delProperty(string_table::key name, string_table::key nsname = 0);
 
381
 
 
382
        /// Overridden to expose indexed elements
 
383
        virtual bool hasOwnProperty(string_table::key name, string_table::key nsname = 0);
 
384
 
 
385
        /// Enumerate elements
 
386
        //
 
387
        /// See as_object::enumerateNonProperties(as_environment&) for more info.
 
388
        ///
 
389
        virtual void enumerateNonProperties(as_environment&) const;
 
390
 
 
391
protected:
 
392
 
 
393
#ifdef GNASH_USE_GC
 
394
        /// Mark array-specific reachable resources and invoke
 
395
        /// the parent's class version (markAsObjectReachable)
 
396
        //
 
397
        /// array-specific reachable resources are:
 
398
        ///     - The elements values (elements)
 
399
        ///
 
400
        virtual void markReachableResources() const;
 
401
#endif // GNASH_USE_GC
 
402
 
 
403
private:
 
404
 
 
405
        ArrayContainer elements;
 
406
 
 
407
        // this function is used internally by set_member and get_member
 
408
        // it takes a string that is the member name of the array and returns -1
 
409
        // if the string does not refer to an index, or an appropriate int if the string does refer to an index
 
410
        int index_requested(string_table::key name);
 
411
 
 
412
        /// Shift all elements to the left by count positions
 
413
        //
 
414
        /// Pre-condition: size of the array must be >= count
 
415
        /// Post-condition: size of the array will reduce by 'count'
 
416
        ///
 
417
        void shiftElementsLeft(unsigned int count);
 
418
 
 
419
        /// Shift all elements to the right by count positions
 
420
        //
 
421
        /// Pre-condition: none
 
422
        /// Post-condition: size of the array will incremented by 'count'
 
423
        ///
 
424
        void shiftElementsRight(unsigned int count);
 
425
};
 
426
 
 
427
 
 
428
/// Initialize the global.Array object
 
429
// needed by SWFHandlers::ActionInitArray
 
430
void array_class_init(as_object& global);
 
431
 
 
432
/// Constructor for ActionScript class Array.
 
433
// needed by SWFHandlers::ActionInitArray
 
434
as_value        array_new(const fn_call& fn);
 
435
 
 
436
}
 
437
 
 
438
#endif