[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Gnash-commit] gnash ChangeLog server/as_object.cpp server/as_...
From: |
Bastiaan Jacques |
Subject: |
[Gnash-commit] gnash ChangeLog server/as_object.cpp server/as_... |
Date: |
Wed, 28 Mar 2007 15:22:24 +0000 |
CVSROOT: /sources/gnash
Module name: gnash
Changes by: Bastiaan Jacques <bjacques> 07/03/28 15:22:24
Modified files:
. : ChangeLog
server : as_object.cpp as_object.h
button_character_instance.cpp
sprite_instance.cpp
server/asobj : string.cpp
testsuite/actionscript.all: String.as
Log message:
* server/as_object{.h, .cpp}: Rename init_property(name, getter)
to init_readonly_property(name, getter).
* server/{button_character_instance.cpp, sprite_instance.cpp):
Update callers to use init_readonly_property.
* server/asobj/string.cpp: Reimplement the ActionScript String
class using std::string. Also change the style to Rob's
preffered one.
* testsuite/actionscript.all/String.as: Add a few more
testcases.
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.2700&r2=1.2701
http://cvs.savannah.gnu.org/viewcvs/gnash/server/as_object.cpp?cvsroot=gnash&r1=1.44&r2=1.45
http://cvs.savannah.gnu.org/viewcvs/gnash/server/as_object.h?cvsroot=gnash&r1=1.51&r2=1.52
http://cvs.savannah.gnu.org/viewcvs/gnash/server/button_character_instance.cpp?cvsroot=gnash&r1=1.36&r2=1.37
http://cvs.savannah.gnu.org/viewcvs/gnash/server/sprite_instance.cpp?cvsroot=gnash&r1=1.205&r2=1.206
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/string.cpp?cvsroot=gnash&r1=1.23&r2=1.24
http://cvs.savannah.gnu.org/viewcvs/gnash/testsuite/actionscript.all/String.as?cvsroot=gnash&r1=1.15&r2=1.16
Patches:
Index: ChangeLog
===================================================================
RCS file: /sources/gnash/gnash/ChangeLog,v
retrieving revision 1.2700
retrieving revision 1.2701
diff -u -b -r1.2700 -r1.2701
--- ChangeLog 28 Mar 2007 14:58:29 -0000 1.2700
+++ ChangeLog 28 Mar 2007 15:22:24 -0000 1.2701
@@ -15,6 +15,15 @@
* server/as_value.h: Add as_value::to_number<type>(), which will
cast the result of to_number() to the requested number type.
+ * server/as_object{.h, .cpp}: Rename init_property(name, getter)
+ to init_readonly_property(name, getter).
+ * server/{button_character_instance.cpp, sprite_instance.cpp):
+ Update callers to use init_readonly_property.
+ * server/asobj/string.cpp: Reimplement the ActionScript String
+ class using std::string. Also change the style to Rob's
+ preffered one.
+ * testsuite/actionscript.all/String.as: Add a few more
+ testcases.
2007-03-28 Sandro Santilli <address@hidden>
Index: server/as_object.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/as_object.cpp,v
retrieving revision 1.44
retrieving revision 1.45
diff -u -b -r1.44 -r1.45
--- server/as_object.cpp 22 Mar 2007 16:56:36 -0000 1.44
+++ server/as_object.cpp 28 Mar 2007 15:22:24 -0000 1.45
@@ -298,7 +298,7 @@
}
void
-as_object::init_property(const std::string& key, as_function& getter)
+as_object::init_readonly_property(const std::string& key, as_function& getter)
{
init_property(key, getter, getter);
Index: server/as_object.h
===================================================================
RCS file: /sources/gnash/gnash/server/as_object.h,v
retrieving revision 1.51
retrieving revision 1.52
diff -u -b -r1.51 -r1.52
--- server/as_object.h 27 Mar 2007 10:04:45 -0000 1.51
+++ server/as_object.h 28 Mar 2007 15:22:24 -0000 1.52
@@ -223,7 +223,7 @@
///
/// The arguments are the same as the above init_property arguments,
/// although the setter argument is omitted.
- void init_property(const std::string& key, as_function& getter);
+ void init_readonly_property(const std::string& key, as_function&
getter);
/// Get a member as_value by name
//
Index: server/button_character_instance.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/button_character_instance.cpp,v
retrieving revision 1.36
retrieving revision 1.37
diff -u -b -r1.36 -r1.37
--- server/button_character_instance.cpp 22 Mar 2007 16:56:36 -0000
1.36
+++ server/button_character_instance.cpp 28 Mar 2007 15:22:24 -0000
1.37
@@ -180,10 +180,10 @@
o.init_property("_yscale", *gettersetter, *gettersetter);
gettersetter = new builtin_function(&character::xmouse_get, NULL);
- o.init_property("_xmouse", *gettersetter);
+ o.init_readonly_property("_xmouse", *gettersetter);
gettersetter = new builtin_function(&character::ymouse_get, NULL);
- o.init_property("_ymouse", *gettersetter);
+ o.init_readonly_property("_ymouse", *gettersetter);
gettersetter = new builtin_function(&character::alpha_getset, NULL);
o.init_property("_alpha", *gettersetter, *gettersetter);
Index: server/sprite_instance.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/sprite_instance.cpp,v
retrieving revision 1.205
retrieving revision 1.206
diff -u -b -r1.205 -r1.206
--- server/sprite_instance.cpp 28 Mar 2007 08:59:14 -0000 1.205
+++ server/sprite_instance.cpp 28 Mar 2007 15:22:24 -0000 1.206
@@ -1312,10 +1312,10 @@
o.init_property("_yscale", *gettersetter, *gettersetter);
gettersetter = new builtin_function(&character::xmouse_get, NULL);
- o.init_property("_xmouse", *gettersetter);
+ o.init_readonly_property("_xmouse", *gettersetter);
gettersetter = new builtin_function(&character::ymouse_get, NULL);
- o.init_property("_ymouse", *gettersetter);
+ o.init_readonly_property("_ymouse", *gettersetter);
gettersetter = new builtin_function(&character::alpha_getset, NULL);
o.init_property("_alpha", *gettersetter, *gettersetter);
Index: server/asobj/string.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/string.cpp,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -b -r1.23 -r1.24
--- server/asobj/string.cpp 20 Mar 2007 16:41:00 -0000 1.23
+++ server/asobj/string.cpp 28 Mar 2007 15:22:24 -0000 1.24
@@ -14,7 +14,7 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-/* $Id: string.cpp,v 1.23 2007/03/20 16:41:00 strk Exp $ */
+/* $Id: string.cpp,v 1.24 2007/03/28 15:22:24 bjacques Exp $ */
// Implementation of ActionScript String class.
@@ -23,7 +23,6 @@
#endif
#include "tu_config.h"
-#include "gstring.h"
#include "smart_ptr.h"
#include "fn_call.h"
#include "as_object.h"
@@ -32,12 +31,29 @@
#include "array.h"
#include "as_value.h"
#include "GnashException.h"
+#include <boost/algorithm/string/case_conv.hpp>
+#include "VM.h"
-namespace gnash {
+#define ENSURE_FN_ARGS(min, max, rv) \
+ if (fn.nargs < min) { \
+ IF_VERBOSE_ASCODING_ERRORS( \
+ log_aserror("%s needs one argument", __FUNCTION__); \
+ ) \
+ return as_value(rv); \
+ } \
+ IF_VERBOSE_ASCODING_ERRORS( \
+ if (fn.nargs > max) \
+ log_aserror("%s has more than one argument", __FUNCTION__); \
+ )
+
+
+
+namespace gnash
+{
// Forward declarations
+
static as_value string_get_length(const fn_call& fn);
-static as_value string_set_length(const fn_call& fn);
static as_value string_concat(const fn_call& fn);
static as_value string_slice(const fn_call& fn);
static as_value string_split(const fn_call& fn);
@@ -72,8 +88,7 @@
o.init_member("toLowerCase", new
builtin_function(string_to_lower_case));
boost::intrusive_ptr<builtin_function> length_getter(new
builtin_function(string_get_length));
- boost::intrusive_ptr<builtin_function> length_setter(new
builtin_function(string_set_length));
- o.init_property("length", *length_getter, *length_setter);
+ o.init_readonly_property("length", *length_getter);
}
@@ -81,315 +96,307 @@
getStringInterface()
{
static boost::intrusive_ptr<as_object> o;
- if ( o == NULL )
- {
+
+ if ( o == NULL ) {
o = new as_object();
attachStringInterface(*o);
}
+
return o.get();
}
-class tu_string_as_object : public as_object
+class string_as_object : public as_object
{
-public:
- // TODO: make private
- tu_string m_string;
- tu_string_as_object()
+public:
+ string_as_object()
:
as_object(getStringInterface())
- {
- }
+ {}
const char* get_text_value() const
{
- return m_string.c_str();
+ return _string.c_str();
}
as_value get_primitive_value() const
+
+ {
+ return as_value(_string.c_str());
+ }
+
+ std::string& str()
+
{
- return as_value(m_string.c_str());
+ return _string;
}
+private:
+ std::string _string;
};
static as_value
string_get_length(const fn_call& fn)
{
- boost::intrusive_ptr<tu_string_as_object> str =
ensureType<tu_string_as_object>(fn.this_ptr);
-
- return as_value(str->m_string.utf8_length());
+ boost::intrusive_ptr<string_as_object> obj =
ensureType<string_as_object>(fn.this_ptr);
+ return as_value(obj->str().size());
}
+// all the arguments will be converted to string and concatenated
static as_value
-string_set_length(const fn_call& /*fn*/)
+string_concat(const fn_call& fn)
{
- IF_VERBOSE_ASCODING_ERRORS(
- log_aserror("String: length property is read-only");
- );
- return as_value();
+ boost::intrusive_ptr<string_as_object> obj =
ensureType<string_as_object>(fn.this_ptr);
+
+ // Make a copy of our string.
+ std::string str = obj->str();
+
+ for (unsigned int i = 0; i < fn.nargs; i++) {
+ str += fn.arg(i).to_std_string();
+ }
+
+ return as_value(str);
}
-// all the arguments will be converted to string and concatenated
-static as_value
-string_concat(const fn_call& fn)
+
+static size_t
+valid_index(std::string subject, int index)
{
- boost::intrusive_ptr<tu_string_as_object> str =
ensureType<tu_string_as_object>(fn.this_ptr);
- tu_string this_string = str->m_string;
+ int myIndex = index;
- int len = strlen(this_string.c_str());
- int pos = len;
- for (unsigned int i = 0; i < fn.nargs; i++) len +=
strlen(fn.arg(i).to_string());
-
- char *newstr = new char[len + 1];
- memcpy(newstr, this_string.c_str(),pos); // because pos at the moments
holds the strlen of this_string!
- for (unsigned int i = 0; i < fn.nargs; i++)
- {
- int len = strlen(fn.arg(i).to_string());
- memcpy((newstr + pos),fn.arg(i).to_string(),len);
- pos += len;
- }
- newstr[len] = '\0';
-
- tu_string returnstring(newstr);
- delete[] newstr; // because tu_string copies newstr
- return as_value(returnstring);
+ if (myIndex < 0) {
+ myIndex = subject.size() + myIndex;
+ }
+
+ myIndex = iclamp(myIndex, 0, subject.size());
+
+ return myIndex;
}
// 1st param: start_index, 2nd param: end_index
static as_value
string_slice(const fn_call& fn)
{
- boost::intrusive_ptr<tu_string_as_object> str =
ensureType<tu_string_as_object>(fn.this_ptr);
- tu_string this_string = str->m_string;
- // Pull a slice out of this_string.
- int start = 0;
- int utf8_len = this_string.utf8_length();
- int end = utf8_len;
- if (fn.nargs >= 1)
- {
- start = static_cast<int>(fn.arg(0).to_number());
- if (start < 0) start = utf8_len + start;
- start = iclamp(start, 0, utf8_len);
- }
- if (fn.nargs >= 2)
- {
- end = static_cast<int>(fn.arg(1).to_number());
- if (end < 0) end = utf8_len + end;
- end = iclamp(end, 0, utf8_len);
- }
+ boost::intrusive_ptr<string_as_object> obj =
ensureType<string_as_object>(fn.this_ptr);
+
+ // Make a copy.
+ std::string str = obj->str();
+
+ ENSURE_FN_ARGS(1, 2, str);
+
+ int start = fn.arg(0).to_number<int>();
+
+ int end = str.size();
+
+ if (fn.nargs >= 2) {
+ end = fn.arg(1).to_number<int>();
if (end < start) {
- IF_VERBOSE_ASCODING_ERRORS(
- log_aserror("string.slice() called with end < start");
- )
- // Swap start and end, cos that's what substr does
+ // Swap start and end like substring
swap(&start, &end);
}
- return as_value(this_string.utf8_substring(start, end));
+ start = valid_index(str, start);
+
+ end = valid_index(str, end) - start ;
+ } else {
+ start = valid_index(str, start);
+ }
+
+ return as_value(str.substr(start, end));
}
static as_value
string_split(const fn_call& fn)
{
- boost::intrusive_ptr<tu_string_as_object> str =
ensureType<tu_string_as_object>(fn.this_ptr);
+ boost::intrusive_ptr<string_as_object> obj =
+ ensureType<string_as_object>(fn.this_ptr);
- boost::intrusive_ptr<tu_string_as_object> this_string_ptr(str); // why
??
+ std::string str = obj->str();
as_value val;
boost::intrusive_ptr<as_array_object> array(new as_array_object());
- if (fn.nargs == 0)
- {
- val.set_tu_string(this_string_ptr->m_string);
+ if (fn.nargs == 0) {
+ val.set_std_string(str);
array->push(val);
return as_value(array.get());
- } else
- {
- tu_string this_string = this_string_ptr->m_string;
+ }
- int utf8_len = this_string.utf8_length();
+ std::string delim = fn.arg(0).to_std_string();
- if (strcmp("",fn.arg(0).to_string()) == 0)
- {
- for (int i = 0; i < utf8_len; i++) {
-
val.set_tu_string(this_string.utf8_substring(i,i+1));
+ if (delim == "") {
+ for (unsigned i=0; i < str.size(); i++) {
+ val.set_std_string(str.substr(i, i+1));
array->push(val);
}
+
return as_value(array.get());
}
- else
- {
- const char *str = this_string.c_str();
- const char *delimeter = fn.arg(0).to_string();
-
- tu_string str_tu(str);
- tu_string delimeter_tu(str);
- int start = 0;
- int end;
- //int utf8_str_len = str_tu.utf8_length();
- //int utf8_delimeter_len = delimeter_tu.utf8_length();
- int delimeter_len = strlen(delimeter);
-
- const char *pstart = str;
- const char *pend = strstr(pstart,delimeter);
- while (pend != NULL)
- {
- //tu_string fromstart(pstart);
- //tu_string fromend(pend);
- start =
tu_string::utf8_char_count(str,int(pstart-str));
- end = start +
tu_string::utf8_char_count(pstart,int(pend-pstart));
+ size_t max = -1;
-
val.set_tu_string(this_string.utf8_substring(start,end));
- array->push(val);
- pstart = pend + delimeter_len;
- if (!(*pstart))
- {
- return as_value(array.get());
+ if (fn.nargs >= 2) {
+ max = fn.arg(1).to_number<size_t>();
}
- pend = strstr(pstart,delimeter);
- }
- val.set_tu_string(tu_string(pstart));
+ size_t pos = 0, prevpos = 0;
+ size_t num = 0;
+
+ while (num < max) {
+ pos = str.find(delim, pos);
+
+ if (pos != std::string::npos) {
+ val.set_std_string(str.substr(prevpos, pos - prevpos));
array->push(val);
- return as_value(array.get());
+ num++;
+ prevpos = pos + delim.size();
+ pos++;
+ } else {
+ val.set_std_string(str.substr(prevpos));
+ array->push(val);
+ break;
}
}
+ return as_value(array.get());
}
static as_value
string_last_index_of(const fn_call& fn)
{
- boost::intrusive_ptr<tu_string_as_object> this_string_ptr =
ensureType<tu_string_as_object>(fn.this_ptr);
+ boost::intrusive_ptr<string_as_object> obj =
ensureType<string_as_object>(fn.this_ptr);
- if (fn.nargs < 1)
- {
- return as_value(-1);
- }
- else
- {
- int start_index = 0;
- if (fn.nargs > 1)
- {
- start_index = static_cast<int>(fn.arg(1).to_number());
- }
- const char* str = this_string_ptr->m_string.c_str();
- const char* p = strstr(
- str + start_index, // FIXME: not UTF-8 correct!
- fn.arg(0).to_string());
- if (p == NULL)
- {
- return as_value(-1);
- }
+ const std::string& str = obj->str();
- const char* lastocc = p;
- while (p != NULL)
- {
- if (!(*p)) break;
- p = strstr((p+1),fn.arg(0).to_string()); // FIXME: also
not UTF-8 correct!
- if (p) lastocc = p;
+ ENSURE_FN_ARGS(1, 2, -1);
+
+ std::string toFind = fn.arg(0).to_std_string();
+
+ size_t start = str.size();
+
+ if (fn.nargs >= 2) {
+ start = fn.arg(1).to_number<size_t>();
}
- return as_value(tu_string::utf8_char_count(str, int(lastocc -
str)));
+ size_t found = str.find_last_of(toFind, start);
+
+ if (found == std::string::npos) {
+ return as_value(-1);
}
+
+ return as_value(found-toFind.size()+1);
}
// 1st param: start_index, 2nd param: length (NOT end_index)
static as_value
string_sub_str(const fn_call& fn)
{
- boost::intrusive_ptr<tu_string_as_object> this_string_ptr =
ensureType<tu_string_as_object>(fn.this_ptr);
- tu_string this_string = this_string_ptr->m_string;
+ boost::intrusive_ptr<string_as_object> obj =
ensureType<string_as_object>(fn.this_ptr);
- // Pull a slice out of this_string.
- int start = 0;
- int utf8_len = this_string.utf8_length();
- int end = utf8_len;
- if (fn.nargs >= 1)
- {
- start = static_cast<int>(fn.arg(0).to_number());
- if (start < 0) start = utf8_len + start;
- start = iclamp(start, 0, utf8_len);
- }
- if (fn.nargs >= 2)
- {
- end = static_cast<int>(fn.arg(1).to_number()) + start;
- end = iclamp(end, start, utf8_len);
+ // Make a copy.
+ std::string str = obj->str();
+
+ ENSURE_FN_ARGS(1, 2, str);
+
+ int start = valid_index(str, fn.arg(0).to_number<int>());
+
+ int num = str.size();
+
+ if (fn.nargs >= 2) {
+ num = fn.arg(1).to_number<int>();
}
- return as_value(this_string.utf8_substring(start, end));
+ return as_value(str.substr(start, num));
}
// 1st param: start_index, 2nd param: end_index
+// end_index is 1-based.
static as_value
string_sub_string(const fn_call& fn)
{
- boost::intrusive_ptr<tu_string_as_object> this_string_ptr =
ensureType<tu_string_as_object>(fn.this_ptr);
- tu_string this_string = this_string_ptr->m_string;
- // Pull a slice out of this_string.
- int start = 0;
- int utf8_len = this_string.utf8_length();
- int end = utf8_len;
- if (fn.nargs >= 1)
- {
- start = static_cast<int>(fn.arg(0).to_number());
- start = iclamp(start, 0, utf8_len);
+ boost::intrusive_ptr<string_as_object> obj =
ensureType<string_as_object>(fn.this_ptr);
+
+ const std::string& str = obj->str();
+
+ ENSURE_FN_ARGS(1, 2, str);
+
+ int start = fn.arg(0).to_number<int>();
+
+ if (start < 0) {
+ start = 0;
}
- if (fn.nargs >= 2)
- {
- end = static_cast<int>(fn.arg(1).to_number());
- end = iclamp(end, 0, utf8_len);
+
+ if (static_cast<unsigned>(start) > str.size()) {
+ return as_value("");
}
- if (end < start) swap(&start, &end); // dumb, but that's what the
docs say
+ int end = str.size();
- return as_value(this_string.utf8_substring(start, end));
+ if (fn.nargs >= 2) {
+ int num = fn.arg(1).to_number<int>();
+
+ if (num < 0) {
+ return as_value("");
+ }
+
+ if (num > 1 && static_cast<unsigned>(num) < str.size()) {
+ end = num;
+
+ if (end < start) {
+ IF_VERBOSE_ASCODING_ERRORS(
+ log_aserror("string.slice() called with end < start");
+ )
+ swap(&end, &start);
+ }
+
+ end -= start;
+ }
+
+ }
+
+ return as_value(str.substr(start, end));
}
static as_value
string_index_of(const fn_call& fn)
{
- boost::intrusive_ptr<tu_string_as_object> this_string_ptr =
ensureType<tu_string_as_object>(fn.this_ptr);
+ boost::intrusive_ptr<string_as_object> obj =
ensureType<string_as_object>(fn.this_ptr);
- if (fn.nargs < 1)
- {
- return as_value(-1);
- }
- else
- {
- int start_index = 0;
- if (fn.nargs > 1)
- {
- start_index = static_cast<int>(fn.arg(1).to_number());
+ const std::string& str = obj->str();
+
+ ENSURE_FN_ARGS(1, 2, -1);
+
+ std::string toFind = fn.arg(0).to_std_string();
+
+ size_t start = 0;
+
+ if (fn.nargs >= 2) {
+ start = fn.arg(1).to_number<size_t>();
}
- const char* str = this_string_ptr->m_string.c_str();
- const char* p = strstr(
- str + start_index, // FIXME: not UTF-8 correct!
- fn.arg(0).to_string());
- if (p == NULL)
- {
+
+ size_t pos = str.find(toFind, start);
+
+ if (pos == std::string::npos) {
return as_value(-1);
}
- return as_value(tu_string::utf8_char_count(str, p - str));
- }
+ return as_value(pos);
}
static as_value
string_from_char_code(const fn_call& fn)
{
- tu_string result;
+ std::string result;
- for (unsigned int i = 0; i < fn.nargs; i++)
- {
- uint32 c = (uint32) fn.arg(i).to_number();
- result.append_wide_char(c);
+ // isn't this function supposed to take one argument?
+
+ for (unsigned int i = 0; i < fn.nargs; i++) {
+ uint32_t c = fn.arg(i).to_number<uint32_t>();
+ result += c;
}
return as_value(result);
@@ -398,10 +405,11 @@
static as_value
string_char_code_at(const fn_call& fn)
{
- boost::intrusive_ptr<tu_string_as_object> this_string_ptr =
ensureType<tu_string_as_object>(fn.this_ptr);
+ boost::intrusive_ptr<string_as_object> obj =
ensureType<string_as_object>(fn.this_ptr);
- // assert(fn.nargs == 1);
- if (fn.nargs < 1) {
+ const std::string& str = obj->str();
+
+ if (fn.nargs == 0) {
IF_VERBOSE_ASCODING_ERRORS(
log_aserror("string.charCodeAt needs one argument");
)
@@ -409,98 +417,106 @@
rv.set_nan();
return rv; // Same as for out-of-range arg
}
+
IF_VERBOSE_ASCODING_ERRORS(
- if (fn.nargs > 1)
+ if (fn.nargs > 1) {
log_aserror("string.charCodeAt has more than one argument");
+ }
)
- int index = static_cast<int>(fn.arg(0).to_number());
- if (index >= 0 && index < this_string_ptr->m_string.utf8_length())
- {
- return as_value(this_string_ptr->m_string.utf8_char_at(index));
+ size_t index = fn.arg(0).to_number<size_t>();
+
+ if (index > str.size()) {
+ as_value rv;
+ rv.set_nan();
+ return rv;
}
- double temp = 0.0; // This variable will let us divide by zero
without a compiler warning
- return as_value(temp/temp); // this division by zero creates a NaN
value
+ return as_value(str[index]);
}
static as_value
string_char_at(const fn_call& fn)
{
- boost::intrusive_ptr<tu_string_as_object> this_string_ptr =
ensureType<tu_string_as_object>(fn.this_ptr);
+ boost::intrusive_ptr<string_as_object> obj =
ensureType<string_as_object>(fn.this_ptr);
+ std::string& str = obj->str();
- // assert(fn.nargs == 1);
- if (fn.nargs < 1) {
- IF_VERBOSE_ASCODING_ERRORS(
- log_aserror("%s needs one argument", __FUNCTION__);
- )
- return as_value(""); // Same as for out-of-range arg
- }
- IF_VERBOSE_ASCODING_ERRORS(
- if (fn.nargs > 1)
- log_aserror("%s has more than one argument", __FUNCTION__);
- )
+ ENSURE_FN_ARGS(1, 1, "");
- int index = static_cast<int>(fn.arg(0).to_number());
- if (index >= 0 && index < this_string_ptr->m_string.utf8_length())
- {
- tu_string result;
- result += this_string_ptr->m_string.utf8_char_at(index);
- return as_value(result);
+ size_t index = fn.arg(0).to_number<size_t>();
+
+ if (index > str.size()) {
+ as_value rv;
+ rv.set_nan();
+ return rv;
}
- double temp = 0.0; // This variable will let us divide by zero
without a compiler warning
- return as_value(temp/temp); // this division by zero creates a NaN
value
+ std::string rv;
+
+ rv.push_back(str[index]);
+
+ return as_value(rv);
}
static as_value
string_to_upper_case(const fn_call& fn)
{
- boost::intrusive_ptr<tu_string_as_object> this_string_ptr =
ensureType<tu_string_as_object>(fn.this_ptr);
+ boost::intrusive_ptr<string_as_object> obj =
ensureType<string_as_object>(fn.this_ptr);
+ std::string subject = obj->str();
- return as_value(this_string_ptr->m_string.utf8_to_upper());
+ VM& vm = VM::get();
+
+ boost::to_upper(subject, vm.getLocale());
+
+ return as_value(subject);
}
static as_value
string_to_lower_case(const fn_call& fn)
{
- boost::intrusive_ptr<tu_string_as_object> this_string_ptr =
ensureType<tu_string_as_object>(fn.this_ptr);
+ boost::intrusive_ptr<string_as_object> obj =
ensureType<string_as_object>(fn.this_ptr);
+ std::string subject = obj->str();
+
+ VM& vm = VM::get();
- return as_value(this_string_ptr->m_string.utf8_to_lower());
+ boost::to_lower(subject, vm.getLocale());
+
+ return as_value(subject);
}
static as_value
string_to_string(const fn_call& fn)
{
- boost::intrusive_ptr<tu_string_as_object> this_string_ptr =
ensureType<tu_string_as_object>(fn.this_ptr);
- return as_value(this_string_ptr->m_string);
+ boost::intrusive_ptr<string_as_object> obj =
ensureType<string_as_object>(fn.this_ptr);
+ return as_value(obj->str());
}
static as_value
string_ctor(const fn_call& fn)
{
- boost::intrusive_ptr<tu_string_as_object> str = new tu_string_as_object;
+ boost::intrusive_ptr<string_as_object> obj = new string_as_object;
- if (fn.nargs > 0)
- {
- str->m_string = fn.arg(0).to_tu_string();
+ std::string& str = obj->str();
+
+ if (fn.nargs > 0) {
+ str = fn.arg(0).to_std_string();
}
// this shouldn't be needed
//attachStringInterface(*str);
- return as_value(str.get());
+ return as_value(obj.get());
}
static boost::intrusive_ptr<builtin_function>
getStringConstructor()
{
// This is going to be the global String "class"/"function"
+
static boost::intrusive_ptr<builtin_function> cl;
- if ( cl == NULL )
- {
+ if ( cl == NULL ) {
cl=new builtin_function(&string_ctor, getStringInterface());
// replicate all interface to class, to be able to access
// all methods as static functions
@@ -523,6 +539,7 @@
}
boost::intrusive_ptr<as_object>
+
init_string_instance(const char* val)
{
boost::intrusive_ptr<builtin_function> cl = getStringConstructor();
Index: testsuite/actionscript.all/String.as
===================================================================
RCS file: /sources/gnash/gnash/testsuite/actionscript.all/String.as,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -b -r1.15 -r1.16
--- testsuite/actionscript.all/String.as 21 Mar 2007 16:20:57 -0000
1.15
+++ testsuite/actionscript.all/String.as 28 Mar 2007 15:22:24 -0000
1.16
@@ -16,7 +16,7 @@
// Original author: Mike Carlson - June 19th, 2006
-rcsid="$Id: String.as,v 1.15 2007/03/21 16:20:57 strk Exp $";
+rcsid="$Id: String.as,v 1.16 2007/03/28 15:22:24 bjacques Exp $";
#include "check.as"
@@ -32,6 +32,8 @@
check_equals ( a.charAt(2), "l" );
check_equals ( a.charAt(3), "l" );
check_equals ( a.charAt(4), "a" );
+isNaN ( a.charAt(-1) );
+isNaN (a.charAt(21) );
check_equals ( a.indexOf("lawa"), 3 );
check_equals ( a.lastIndexOf("lawa"), 8);
check_equals ( a.indexOf("lawas"), 8 );
@@ -82,6 +84,7 @@
check_equals ( a.slice(-4), "wxyz" );
check_equals ( a.substring(5,2), "cde" );
check_equals ( a.substring(5,7), "fg" );
+check_equals ( a.substring(3,3), "" );
check_equals ( a.length, 26 );
check_equals ( a.concat("sir ","william",15), "abcdefghijklmnopqrstuvwxyzsir
william15");
var b = new String("1234");