gnash-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Gnash-commit] gnash ChangeLog server/array.cpp server/array.h...


From: Sandro Santilli
Subject: [Gnash-commit] gnash ChangeLog server/array.cpp server/array.h...
Date: Wed, 28 Mar 2007 14:58:30 +0000

CVSROOT:        /sources/gnash
Module name:    gnash
Changes by:     Sandro Santilli <strk>  07/03/28 14:58:30

Modified files:
        .              : ChangeLog 
        server         : array.cpp array.h 
        testsuite/actionscript.all: array.as 

Log message:
                * server/array.{cpp,h}: implement Array.splice(),
                  improve toString to actually call the user-provided
                  toString on all elements.
                * testsuite/actionscript.all/array.as: added testcases
                  for Array.splice().

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.2699&r2=1.2700
http://cvs.savannah.gnu.org/viewcvs/gnash/server/array.cpp?cvsroot=gnash&r1=1.54&r2=1.55
http://cvs.savannah.gnu.org/viewcvs/gnash/server/array.h?cvsroot=gnash&r1=1.22&r2=1.23
http://cvs.savannah.gnu.org/viewcvs/gnash/testsuite/actionscript.all/array.as?cvsroot=gnash&r1=1.14&r2=1.15

Patches:
Index: ChangeLog
===================================================================
RCS file: /sources/gnash/gnash/ChangeLog,v
retrieving revision 1.2699
retrieving revision 1.2700
diff -u -b -r1.2699 -r1.2700
--- ChangeLog   28 Mar 2007 12:55:41 -0000      1.2699
+++ ChangeLog   28 Mar 2007 14:58:29 -0000      1.2700
@@ -1,5 +1,10 @@
 2007-03-28 Sandro Santilli <address@hidden>
 
+       * server/array.{cpp,h}: implement Array.splice(),
+         improve toString to actually call the user-provided
+         toString on all elements.
+       * testsuite/actionscript.all/array.as: added testcases
+         for Array.splice().
        * testsuite/misc-ming.all/Dejagnu.c: use a larger window for traces.
        * testsuite/misc-ming.all/: FlashVarsTest.as, FlashVarsTest.html,
          Makefile.am: added a test for querystring and flashparams parsing.

Index: server/array.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/array.cpp,v
retrieving revision 1.54
retrieving revision 1.55
diff -u -b -r1.54 -r1.55
--- server/array.cpp    20 Mar 2007 15:01:20 -0000      1.54
+++ server/array.cpp    28 Mar 2007 14:58:30 -0000      1.55
@@ -41,6 +41,9 @@
 #include <algorithm>
 #include <memory> // for auto_ptr
 
+//#define GNASH_DEBUG 
+
+
 namespace gnash {
 
 static as_object* getArrayInterface();
@@ -221,7 +224,7 @@
 }
 
 std::string
-as_array_object::join(const std::string& separator) const
+as_array_object::join(const std::string& separator, as_environment* env) const
 {
        // TODO - confirm this is the right format!
        // Reportedly, flash version 7 on linux, and Flash 8 on IE look like
@@ -240,12 +243,12 @@
                        itEnd=elements.end();
 
                // print first element w/out separator prefix
-               temp += (*it++).to_string();
+               temp += (*it++).to_string(env);
 
                // print subsequent elements with separator prefix
                while ( it != itEnd )
                {
-                       temp += separator + (*it++).to_string();
+                       temp += separator + (*it++).to_string(env);
                }
        }
 
@@ -263,9 +266,9 @@
 }
 
 std::string
-as_array_object::toString() const
+as_array_object::toString(as_environment* env) const
 {
-       return join(",");
+       return join(",", env);
 }
 
 unsigned int
@@ -296,7 +299,9 @@
 
        std::auto_ptr<as_array_object> newarray(new as_array_object);
 
+#ifdef GNASH_DEBUG
        log_msg("Array.slice(%u, %u) called", start, one_past_end);
+#endif
 
        size_t newsize = one_past_end - start;
        newarray->elements.resize(newsize);
@@ -311,6 +316,48 @@
 
 }
 
+std::auto_ptr<as_array_object>
+as_array_object::splice(unsigned start, unsigned len,
+               const std::vector<as_value>& replace)
+{
+       assert(len <= size()-start);
+       assert(start <= size());
+
+#ifdef GNASH_DEBUG
+       std::stringstream ss;
+       ss << "Array.splice(" << start << ", " << len << ", ";
+       std::ostream_iterator<as_value> ostrIter(ss, "," ) ;
+       std::copy(replace.begin(), replace.end(), ostrIter);
+        ss << ") called";
+       log_msg("%s", ss.str().c_str());
+       log_msg("Current array is %s", toString().c_str());
+#endif
+
+       container::iterator itStart = elements.begin()+start;
+       container::iterator itEnd = itStart+len;
+
+       // This will be returned...
+       std::auto_ptr<as_array_object> ret(new as_array_object);
+       
+       // If something has to be removed do it and assign
+       // to the returned object
+       if ( itStart != itEnd )
+       {
+               ret->elements.assign(itStart, itEnd);
+
+               elements.erase(itStart, itEnd);
+       }
+
+       // Now insert the new stuff, if needed
+       if ( replace.size() )
+       {
+               container::iterator itStart = elements.begin()+start;
+               elements.insert(itStart, replace.begin(), replace.end());
+       }
+
+       return ret;
+}
+
 /* virtual public, overriding as_object::get_member */
 bool
 as_array_object::get_member(const std::string& name, as_value *val)
@@ -461,10 +508,66 @@
 array_splice(const fn_call& fn)
 {
        boost::intrusive_ptr<as_array_object> array = 
ensureType<as_array_object>(fn.this_ptr);
-       UNUSED(array);
 
-       log_error("FIXME: Array.splice() method not implemented yet!\n");
+#ifdef GNASH_DEBUG
+       std::stringstream ss;
+       fn.dump_args(ss);
+       log_msg("Array(%s).splice(%s) called", array->toString().c_str(), 
ss.str().c_str());
+#endif
+
+       if (fn.nargs < 1)
+       {
+               IF_VERBOSE_ASCODING_ERRORS(
+               log_aserror("Array.splice() needs at least 1 argument, call 
ignored");
+               );
+               return as_value();
+       }
+
+       unsigned origlen = array->size();
+
+       //----------------
+       // Get start offset
+       //----------------
+       unsigned startoffset;
+       int start = fn.arg(0).to_number<int>(&(fn.env()));
+       if ( start < 0 ) start = array->size()+start; // start is negative, so 
+ means -abs()
+       startoffset = iclamp(start, 0, origlen);
+#ifdef GNASH_DEBUG
+       if ( startoffset != start ) log_msg("Array.splice: start:%d became %u", 
start, startoffset);
+#endif
+
+       //----------------
+       // Get length
+       //----------------
+       unsigned len = 0;
+       if (fn.nargs > 1)
+       {
+               int lenval = fn.arg(1).to_number<int>(&(fn.env()));
+               if ( lenval < 0 )
+               {
+                       IF_VERBOSE_ASCODING_ERRORS(
+                       log_aserror("Array.splice(%d,%d): negative length 
given, call ignored",
+                               start, lenval);
+                       );
        return as_value();
+               }
+               len = iclamp(lenval, 0, origlen-startoffset);
+       }
+
+       //----------------
+       // Get replacement
+       //----------------
+       std::vector<as_value> replace;
+       for (unsigned i=2; i<fn.nargs; ++i)
+       {
+               replace.push_back(fn.arg(i));
+       }
+
+       std::auto_ptr<as_array_object> spliced ( array->splice(startoffset, 
len, replace) );
+
+       boost::intrusive_ptr<as_object> ret = spliced.release();
+
+       return as_value(ret);
 }
 
 static as_value
@@ -595,7 +698,7 @@
        if (fn.nargs > 0)
                separator = fn.arg(0).to_string();
 
-       std::string ret = array->join(separator);
+       std::string ret = array->join(separator, &(fn.env()));
 
        return as_value(ret.c_str());
 }
@@ -615,7 +718,7 @@
 {
        boost::intrusive_ptr<as_array_object> array = 
ensureType<as_array_object>(fn.this_ptr);
 
-       std::string ret = array->toString();
+       std::string ret = array->toString(&(fn.env()));
 
                IF_VERBOSE_ACTION
                (

Index: server/array.h
===================================================================
RCS file: /sources/gnash/gnash/server/array.h,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -b -r1.22 -r1.23
--- server/array.h      19 Mar 2007 17:11:14 -0000      1.22
+++ server/array.h      28 Mar 2007 14:58:30 -0000      1.23
@@ -24,6 +24,7 @@
 #include "as_object.h" // for inheritance
 
 #include <deque>
+#include <vector>
 #include <memory> // for auto_ptr
 
 #include <string>
@@ -79,9 +80,17 @@
 
        void reverse();
 
-       std::string join(const std::string& separator) const;
+       /// @param env
+       ///     If not-null will be used to properl invoke the toString()
+       ///     method against member values.
+       ///
+       std::string join(const std::string& separator, as_environment* env) 
const;
 
-       std::string toString() const;
+       /// @param env
+       ///     If not-null will be used to properly invoke the toString()
+       ///     method against member values.
+       ///
+       std::string toString(as_environment* env=NULL) const;
 
        // override from as_object
        const char* get_text_value() const
@@ -118,6 +127,29 @@
        std::auto_ptr<as_array_object> slice(
                unsigned int start, unsigned int one_past_end);
 
+       /// \brief
+       /// Substitute 'len' elements from 'start' with elements from
+       /// the given array.
+       //
+       /// NOTE: assertions are:
+       ///
+       ///     assert(len <= size()-start);
+       ///     assert(start <= size());
+       ///
+       /// @param start
+       ///     0-index based offset of first element to replace.
+       ///
+       /// @param len
+       ///     Number of elements to replace.
+       ///
+       /// @param replacement
+       ///     The element to use as replacement
+       ///
+       /// TODO: should we return by intrusive_ptr instead ?
+       ///
+       std::auto_ptr<as_array_object> splice(unsigned start, unsigned len,
+                       const std::vector<as_value>& replacement);
+
        /// Sort the array, using given values comparator
        void sort(as_function& comparator, uint8_t flags=0);
 
@@ -141,7 +173,9 @@
 
 private:
 
-       std::deque<as_value> elements;
+       typedef std::deque<as_value> container;
+
+       container elements;
 
        // this function is used internally by set_member and get_member
        // it takes a string that is the member name of the array and returns -1

Index: testsuite/actionscript.all/array.as
===================================================================
RCS file: /sources/gnash/gnash/testsuite/actionscript.all/array.as,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -b -r1.14 -r1.15
--- testsuite/actionscript.all/array.as 28 Feb 2007 23:58:26 -0000      1.14
+++ testsuite/actionscript.all/array.as 28 Mar 2007 14:58:30 -0000      1.15
@@ -5,7 +5,7 @@
 // Updated with sort functions, and to use check() macro
 // by Mike Carlson Feb. 14th, 2006
 
-rcsid="$Id: array.as,v 1.14 2007/02/28 23:58:26 strk Exp $";
+rcsid="$Id: array.as,v 1.15 2007/03/28 14:58:30 strk Exp $";
 
 #include "check.as"
 
@@ -139,7 +139,102 @@
 portion = concatted.slice(18);
 check_equals ( portion.toString(), "");
 
+//-------------------------------
+// Test splice
+//-------------------------------
+
+ary = [0,1,2,3,4,5];
+check_equals ( ary.toString(), "0,1,2,3,4,5" );
+
+// No args is invalid
+spliced = ary.splice();
+check_equals ( ary.toString(), "0,1,2,3,4,5" );
+check_equals ( typeof(spliced), "undefined" );
+
+// Zero and positive offset starts from the end (-1 is last)
+spliced = ary.splice(0, 1);
+check_equals ( ary.toString(), "1,2,3,4,5" );
+check_equals ( spliced.toString(), "0" );
+spliced = ary.splice(1, 1);
+check_equals ( ary.toString(), "1,3,4,5" );
+check_equals ( spliced.toString(), "2" );
+
+// Negative offset starts from the end (-1 is last)
+spliced = ary.splice(-1, 1);
+check_equals ( ary.toString(), "1,3,4" );
+check_equals ( spliced.toString(), "5" );
+spliced = ary.splice(-2, 1);
+check_equals ( ary.toString(), "1,4" );
+check_equals ( spliced.toString(), "3" );
+
+// Out-of bound zero or positive offset are taken as one-past the end
+spliced = ary.splice(2, 1);
+check_equals ( ary.toString(), "1,4" );
+check_equals ( spliced.toString(), "" );
+spliced = ary.splice(2, 10);
+check_equals ( ary.toString(), "1,4" );
+check_equals ( spliced.toString(), "" );
+
+// Out-of bound negative offset are taken as zero
+spliced = ary.splice(-20, 1);
+check_equals ( ary.toString(), "4" );
+check_equals ( spliced.toString(), "1" );
+
+// rebuild the array
+ary = [0,1,2,3,4,5,6,7,8];
+
+// Zero length doesn't change anything, and return an empty array
+spliced = ary.splice(2, 0);
+check_equals ( ary.toString(), "0,1,2,3,4,5,6,7,8" );
+check_equals ( spliced.toString(), "" );
+
+// Out of bound positive length consumes up to the end
+spliced = ary.splice(2, 100);
+check_equals ( ary.toString(), "0,1" );
+check_equals ( spliced.toString(), "2,3,4,5,6,7,8" );
+ary=spliced; // reset array
+spliced = ary.splice(-2, 100);
+check_equals ( ary.toString(), "2,3,4,5,6" );
+check_equals ( spliced.toString(), "7,8" );
+
+// Negative length are invalid
+spliced = ary.splice(0, -1);
+check_equals ( typeof(spliced), 'undefined' );
+check_equals ( ary.toString(), "2,3,4,5,6" );
+spliced = ary.splice(3, -1);
+check_equals ( typeof(spliced), 'undefined' );
+check_equals ( ary.toString(), "2,3,4,5,6" );
+spliced = ary.splice(-1, -1);
+check_equals ( typeof(spliced), 'undefined' );
+check_equals ( ary.toString(), "2,3,4,5,6" );
+spliced = ary.splice(-1, -1, "a", "b", "c");
+check_equals ( typeof(spliced), 'undefined' );
+check_equals ( ary.toString(), "2,3,4,5,6" );
+
+// Provide substitutions now
+spliced = ary.splice(1, 1, "a", "b", "c");
+check_equals ( ary.toString(), "2,a,b,c,4,5,6" );
+check_equals ( spliced.toString(), '3' );
+spliced = ary.splice(-4, 2, 8);
+check_equals ( ary.toString(), "2,a,b,8,5,6" );
+check_equals ( spliced.toString(), 'c,4' );
+
+// Insert w/out deleting anything
+spliced = ary.splice(3, 0, 10, 11, 12);
+check_equals ( ary.toString(), "2,a,b,10,11,12,8,5,6" );
+check_equals ( spliced.toString(), '' );
+
+// Use arrays as replacement
+spliced = ary.splice(0, 7, [1,2], [3,4]);
+check_equals ( ary.toString(), "1,2,3,4,5,6" );
+check_equals ( ary.length, 4 ); // don't be fooled by toString output !
+check_equals ( spliced.toString(), '2,a,b,10,11,12,8' );
+
+
+//-------------------------------
 // Test single parameter constructor, and implicitly expanding array
+//-------------------------------
+
 var c = new Array(10);
 check (a instanceOf Array);
 check_equals ( typeof(c), "object" );
@@ -159,6 +254,13 @@
 check_equals(c[8], undefined);
 
 // $Log: array.as,v $
+// Revision 1.15  2007/03/28 14:58:30  strk
+//         * server/array.{cpp,h}: implement Array.splice(),
+//           improve toString to actually call the user-provided
+//           toString on all elements.
+//         * testsuite/actionscript.all/array.as: added testcases
+//           for Array.splice().
+//
 // Revision 1.14  2007/02/28 23:58:26  strk
 //         * testsuite/actionscript.all/: array.as, Function.as
 //           Don't expect failures when checking for missing




reply via email to

[Prev in Thread] Current Thread [Next in Thread]