[Top][All Lists]
[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