array.h

Go to the documentation of this file.
00001 // 
00002 //   Copyright (C) 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
00003 // 
00004 // This program is free software; you can redistribute it and/or modify
00005 // it under the terms of the GNU General Public License as published by
00006 // the Free Software Foundation; either version 3 of the License, or
00007 // (at your option) any later version.
00008 // 
00009 // This program is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 // GNU General Public License for more details.
00013 // 
00014 // You should have received a copy of the GNU General Public License
00015 // along with this program; if not, write to the Free Software
00016 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00017 
00018 #ifndef GNASH_ARRAY_H
00019 #define GNASH_ARRAY_H
00020 
00021 #include "as_object.h" // for inheritance
00022 
00023 #include <deque>
00024 #include <vector>
00025 #include <memory> // for auto_ptr
00026 
00027 #include <string>
00028 
00029 // Forward declarations
00030 namespace gnash {
00031         class fn_call;
00032         class as_value;
00033 }
00034 
00035 namespace gnash {
00036 
00037 struct indexed_as_value : public as_value
00038 {
00039         int vec_index;
00040 
00041         indexed_as_value(const as_value& val, int index)
00042         : as_value(val)
00043         {
00044                 vec_index = index;
00045         }
00046 };
00047 
00049 class as_array_object : public as_object
00050 {
00051 
00052 public:
00053 
00054         typedef std::deque<as_value> container;
00055 
00056         typedef container::const_iterator const_iterator;
00057         typedef container::iterator iterator;
00058 
00060         //
00063         template<class V> void visitAll(V& v)
00064         {
00065                 // NOTE: we copy the elements as the visitor might call arbitrary code
00066                 //       possibly modifying the container itself.
00067                 container copy = elements;
00068                 for (iterator i=copy.begin(), ie=copy.end(); i!=ie; ++i)
00069                 {
00070                         v.visit(*i);
00071                 }
00072         }
00073 
00075         enum SortFlags {
00076 
00078                 fCaseInsensitive        = (1<<0), // 1
00079 
00081                 fDescending             = (1<<1), // 2
00082 
00087                 fUniqueSort             = (1<<2), // 4
00088 
00092                 fReturnIndexedArray     = (1<<3), // 8
00093 
00095                 fNumeric                = (1<<4) // 16
00096         };
00097 
00098         as_array_object();
00099 
00100         as_array_object(const as_array_object& other);
00101 
00102         ~as_array_object();
00103 
00104         std::deque<indexed_as_value> get_indexed_elements();
00105 
00106         const_iterator begin();
00107 
00108         const_iterator end();
00109 
00111         //
00115         void push(const as_value& val);
00116 
00117         void unshift(const as_value& val);
00118 
00119         as_value shift();
00120 
00121         as_value pop();
00122 
00123         as_value at(unsigned int index);
00124 
00125         as_array_object* get_indices(std::deque<indexed_as_value> origElems);
00126 
00127         void reverse();
00128 
00129         void set_indexed(unsigned int index, const as_value &v);
00130 
00135         std::string join(const std::string& separator, as_environment* env) const;
00136 
00141         std::string toString(as_environment* env=NULL) const;
00142 
00143         // override from as_object
00144         std::string get_text_value() const
00145         {
00146                 return toString();
00147         }
00148 
00149         unsigned int size() const;
00150 
00151         void resize(unsigned int);
00152 
00153         void concat(const as_array_object& other);
00154 
00158         //
00174         std::auto_ptr<as_array_object> slice(
00175                 unsigned int start, unsigned int one_past_end);
00176 
00178         //
00187         bool removeFirst(const as_value& v);
00188 
00192         //
00209         std::auto_ptr<as_array_object> splice(unsigned start, unsigned len,
00210                         const std::vector<as_value>& replacement);
00211 
00218         template <class AVCMP>
00219         void sort(AVCMP avc)
00220         {
00221                 // IMPORTANT NOTE
00222                 //
00223                 // As for ISO/IEC 14882:2003 - 23.2.2.4.29 
00224                 // the sort algorithm relies on the assumption
00225                 // that the comparator function implements
00226                 // a Strict Weak Ordering operator:
00227                 // http://www.sgi.com/tech/stl/StrictWeakOrdering.html
00228                 //
00229                 // Invalid comparator can lead to undefined behaviour,
00230                 // including invalid memory access and infinite loops.
00231                 //
00232                 // Pragmatically, it seems that std::list::sort is
00233                 // more robust in this reguard, so we'll sort a list
00234                 // instead of the queue. We want to sort a copy anyway
00235                 // to avoid the comparator changing the original container.
00236                 //
00237 
00238                 std::list<as_value> nelem(elements.begin(), elements.end());
00239 
00240                 nelem.sort(avc);
00241 
00242                 elements.assign(nelem.begin(), nelem.end());
00243         }
00244 
00259         template <class AVCMP, class AVEQ>
00260         as_value sort(AVCMP avc, AVEQ ave)
00261         {
00262                 // IMPORTANT NOTE
00263                 //
00264                 // As for ISO/IEC 14882:2003 - 23.2.2.4.29 
00265                 // the sort algorithm relies on the assumption
00266                 // that the comparator function implements
00267                 // a Strict Weak Ordering operator:
00268                 // http://www.sgi.com/tech/stl/StrictWeakOrdering.html
00269                 //
00270                 // Invalid comparator can lead to undefined behaviour,
00271                 // including invalid memory access and infinite loops.
00272                 //
00273                 // Pragmatically, it seems that std::list::sort is
00274                 // more robust in this reguard, so we'll sort a list
00275                 // instead of the queue. We want to sort a copy anyway
00276                 // to avoid the comparator changing the original container.
00277                 //
00278 
00279                 std::list<as_value> nelem(elements.begin(), elements.end());
00280 
00281                 nelem.sort(avc);
00282 
00283                 if (adjacent_find(nelem.begin(), nelem.end(), ave) != nelem.end() )
00284                         return as_value(0);
00285 
00286                 elements.assign(nelem.begin(), nelem.end());
00287 
00288                 return as_value(this);
00289         }
00290 
00297         template <class AVCMP>
00298         as_array_object* sort_indexed(AVCMP avc)
00299         {
00300                 std::deque<indexed_as_value> ielem = get_indexed_elements();
00301                 std::sort(ielem.begin(), ielem.end(), avc);
00302                 return get_indices(ielem);
00303         }
00304 
00318         template <class AVCMP, class AVEQ>
00319         as_value sort_indexed(AVCMP avc, AVEQ ave)
00320         {
00321                 std::deque<indexed_as_value> ielem = get_indexed_elements();
00322 
00323                 std::sort(ielem.begin(), ielem.end(), avc);
00324 
00325                 if (adjacent_find(ielem.begin(), ielem.end(), ave) != ielem.end() )
00326                         return as_value(0);
00327 
00328                 return get_indices(ielem);
00329         }
00330 
00332         //
00334         virtual bool get_member(string_table::key name, as_value* val,
00335                 string_table::key nsname = 0);
00336 
00338         virtual void set_member(string_table::key name,
00339                 const as_value& val, string_table::key nsname = 0);
00340 
00342         //
00345         virtual void enumerateNonProperties(as_environment&) const;
00346 
00347 protected:
00348 
00349 #ifdef GNASH_USE_GC
00352         //
00356         virtual void markReachableResources() const;
00357 #endif // GNASH_USE_GC
00358 
00359 private:
00360 
00361         container elements;
00362 
00363         // this function is used internally by set_member and get_member
00364         // it takes a string that is the member name of the array and returns -1
00365         // if the string does not refer to an index, or an appropriate int if the string does refer to an index
00366         int index_requested(string_table::key name);
00367 
00368 };
00369 
00370 
00372 // needed by SWFHandlers::ActionInitArray
00373 void array_class_init(as_object& global);
00374 
00376 // needed by SWFHandlers::ActionInitArray
00377 as_value        array_new(const fn_call& fn);
00378 
00379 }
00380 
00381 #endif

Generated on Thu Mar 6 18:25:06 2008 for Gnash by  doxygen 1.5.4