gnash-commit
[Top][All Lists]
Advanced

[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");




reply via email to

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