[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Gnash-commit] gnash/server/vm ASHandlers.cpp ASHandlers.h
From: |
zou lunkai |
Subject: |
Re: [Gnash-commit] gnash/server/vm ASHandlers.cpp ASHandlers.h |
Date: |
Mon, 20 Aug 2007 15:28:00 +0800 |
> Adding the multibyte string operators. This behavior currently has
> no testcases.
Any free compiler support these operators?
On 8/20/07, Chad Musick <address@hidden> wrote:
> CVSROOT: /sources/gnash
> Module name: gnash
> Changes by: Chad Musick <cmusick> 07/08/20 03:25:10
>
> Modified files:
> server/vm : ASHandlers.cpp ASHandlers.h
>
> Log message:
> Adding the multibyte string operators. This behavior currently has
> no testcases. There may be a more efficient way to know rather than
> discover encoding, but I have not found it. These operators are
> deprected since SWF 5.
>
> CVSWeb URLs:
> http://cvs.savannah.gnu.org/viewcvs/gnash/server/vm/ASHandlers.cpp?cvsroot=gnash&r1=1.122&r2=1.123
> http://cvs.savannah.gnu.org/viewcvs/gnash/server/vm/ASHandlers.h?cvsroot=gnash&r1=1.8&r2=1.9
>
> Patches:
> Index: ASHandlers.cpp
> ===================================================================
> RCS file: /sources/gnash/gnash/server/vm/ASHandlers.cpp,v
> retrieving revision 1.122
> retrieving revision 1.123
> diff -u -b -r1.122 -r1.123
> --- ASHandlers.cpp 19 Aug 2007 22:50:16 -0000 1.122
> +++ ASHandlers.cpp 20 Aug 2007 03:25:09 -0000 1.123
> @@ -17,7 +17,7 @@
> // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
> //
>
> -/* $Id: ASHandlers.cpp,v 1.122 2007/08/19 22:50:16 strk Exp $ */
> +/* $Id: ASHandlers.cpp,v 1.123 2007/08/20 03:25:09 cmusick Exp $ */
>
> #ifdef HAVE_CONFIG_H
> #include "config.h"
> @@ -55,6 +55,7 @@
> #include <set>
> #include <vector>
> #include <utility> // for std::pair
> +#include <locale.h>
>
> using namespace std;
>
> @@ -1376,12 +1377,115 @@
> env.top(0).set_int(tu_random::next_random() % max);
> }
>
> +as_encoding_guess_t
> +SWFHandlers::GuessEncoding(std::string &str, int &length, int *offsets)
> +{
> + const char *cstr = str.c_str();
> + const char *i = cstr;
> + int width = 0; // The remaining width, not the total.
> + bool is_sought = true;
> + int j;
> + int index = 0;
> +
> + length = 0;
> + // First, assume it's UTF8 and try to be wrong.
> + for (index = 0; is_sought && *i != '\0'; ++i, ++index)
> + {
> + j = static_cast<int> (*i);
> +
> + if (width)
> + {
> + --width;
> + if ((j & 0xB0) != 0x80)
> + is_sought = false;
> + continue;
> + }
> + ++length;
> + *(offsets + length - 1) = index;
> +
> + if ((j & 0xC0) == 0x80)
> + continue; // A 1 byte character.
> + else if ((j & 0xE0) == 0xC0)
> + width = 1;
> + else if ((j & 0xF0) == 0xE0)
> + width = 2;
> + else if ((j & 0xF8) == 0xF0)
> + width = 3;
> + else if (j & 0x80)
> + is_sought = false;
> + }
> + *(offsets + length - 1) = index;
> + if (!width && is_sought) // No width left, so it's almost certainly UTF8.
> + return ENCGUESS_UNICODE;
> +
> + is_sought = true;
> + width = 0;
> + length = 0;
> + bool was_odd = true;
> + bool was_even = true;
> + // Now, assume it's SHIFT_JIS and try to be wrong.
> + for (index = 0, i = cstr; is_sought && (*i != '\0'); ++i, ++index)
> + {
> + j = static_cast<int> (*i);
> +
> + if (width)
> + {
> + --width;
> + if ((j < 0x40) || ((j < 0x9F) && was_even) ||
> + ((j > 0x9E) && was_odd) || (j == 0x7F))
> + {
> + is_sought = false;
> + }
> + continue;
> + }
> +
> + ++length;
> + *(offsets + length - 1) = index;
> +
> + if ((j == 0x80) || (j == 0xA0) || (j >= 0xF0))
> + {
> + is_sought = false;
> + break;
> + }
> +
> + if (((j >= 0x81) && (j <= 0x9F)) || ((j >= 0xE0) && (j <= 0xEF)))
> + {
> + width = 1;
> + was_odd = j & 0x01;
> + was_even = !was_odd;
> + }
> +
> + }
> + *(offsets + length - 1) = index;
> + if (!width && is_sought) // No width left, so it's probably SHIFT_JIS.
> + return ENCGUESS_JIS;
> +
> + // It's something else.
> + length = mbstowcs(NULL, cstr, 0);
> + if (length == -1)
> + length = strlen(cstr);
> + return ENCGUESS_OTHER;
> +}
> +
> void
> -SWFHandlers::ActionMbLength(ActionExec& /*thread*/)
> +SWFHandlers::ActionMbLength(ActionExec& thread)
> {
> // GNASH_REPORT_FUNCTION;
> -// as_environment& env = thread.env;
> - log_unimpl (__PRETTY_FUNCTION__);
> + as_environment& env = thread.env;
> +
> + thread.ensureStack(1);
> + string str = env.top(0).to_string(&env);
> +
> + if (str.empty())
> + {
> + env.top(0).set_int(0);
> + }
> + else
> + {
> + int length;
> + (void) GuessEncoding(str, length, NULL);
> + env.top(0).set_int(length);
> + }
> }
>
> void
> @@ -1423,11 +1527,76 @@
> }
>
> void
> -SWFHandlers::ActionMbSubString(ActionExec& /*thread*/)
> +SWFHandlers::ActionMbSubString(ActionExec& thread)
> {
> // GNASH_REPORT_FUNCTION;
> -// as_environment& env = thread.env;
> - log_unimpl (__PRETTY_FUNCTION__);
> + as_environment& env = thread.env;
> +
> + thread.ensureStack(3);
> +
> + int size = env.top(0).to_int(env);
> + int start = env.top(1).to_int(env);
> + as_value& string_val = env.top(2);
> +
> + env.drop(2);
> +
> + if (string_val.is_undefined() || string_val.is_null())
> + {
> + log_error(_("Undefined or null string passed to ActionMBSubString, "
> + "returning undefined"));
> + env.top(0).set_undefined();
> + return;
> + }
> +
> + if (size < 1)
> + {
> + if (size < 0)
> + {
> + IF_VERBOSE_ASCODING_ERRORS(
> + log_aserror(_("Length is less than 1 in ActionMbSubString, "
> + "returning empty string."));
> + );
> + }
> + env.top(0).set_string("");
> + return;
> + }
> +
> + string str = string_val.to_string(&env);
> + int length = 0;
> + int offsets[str.length() + 1];
> +
> + as_encoding_guess_t encoding = GuessEncoding(str, length, offsets);
> +
> + if (start < 1)
> + {
> + IF_VERBOSE_ASCODING_ERRORS(
> + log_aserror(_("Base is less then 1 in ActionMbSubString, "
> + "setting to 1."));
> + );
> + start = 1;
> + }
> +
> + // Adjust the start for our own use.
> + --start;
> +
> + if (size + start - 1 > length)
> + {
> + IF_VERBOSE_ASCODING_ERRORS(
> + log_aserror(_("base+size goes beyond input string in
> ActionMbSubString, "
> + "adjusting size"));
> + );
> + size = length - start;
> + }
> +
> + if (encoding == ENCGUESS_OTHER)
> + {
> + env.top(0).set_string(str.substr(start, size));
> + }
> + else
> + {
> + env.top(0).set_string(str.substr(offsets[start], offsets[size] -
> offsets[start] + 1));
> + }
> + return;
> }
>
> void
> @@ -1439,11 +1608,26 @@
> }
>
> void
> -SWFHandlers::ActionMbChr(ActionExec& /*thread*/)
> +SWFHandlers::ActionMbChr(ActionExec& thread)
> {
> // GNASH_REPORT_FUNCTION;
> -// as_environment& env = thread.env;
> - log_unimpl (__PRETTY_FUNCTION__);
> +// The correctness of this depends on the locale being correct,
> +// which it should be far more often than not, by choosing UTF8.
> + as_environment& env = thread.env;
> +
> + thread.ensureStack(1);
> +
> + wchar_t i = static_cast<wchar_t> (env.top(0).to_int(env));
> + char str[MB_CUR_MAX + 1];
> + memset(str, '\0', MB_CUR_MAX + 1);
> + if (wctomb(str, i) == -1)
> + {
> + env.top(0).set_undefined();
> + }
> + else
> + {
> + env.top(0).set_string(str);
> + }
> }
>
> // also known as WaitForFrame2
>
> Index: ASHandlers.h
> ===================================================================
> RCS file: /sources/gnash/gnash/server/vm/ASHandlers.h,v
> retrieving revision 1.8
> retrieving revision 1.9
> diff -u -b -r1.8 -r1.9
> --- ASHandlers.h 1 Jul 2007 10:54:36 -0000 1.8
> +++ ASHandlers.h 20 Aug 2007 03:25:09 -0000 1.9
> @@ -49,6 +49,12 @@
> ARG_FUNCTION2
> } as_arg_t;
>
> +typedef enum {
> + ENCGUESS_UNICODE = 0,
> + ENCGUESS_JIS = 1,
> + ENCGUESS_OTHER = 2
> +} as_encoding_guess_t;
> +
> // @@strk@@ should we move this to .cpp file ? it's only
> // use is within SWFHandlers, anyway...
> typedef void (*action_callback_t)(ActionExec& thread);
> @@ -154,6 +160,13 @@
> static void CommonSetTarget(as_environment& env,
> const std::string& target_name);
>
> + /// Common code for guessing at the encoding of random text, between
> + // Shift-Jis, UTF8, and other. Puts the character count in length,
> + // and the offsets to the characters in offsets, if offsets is not
> NULL.
> + // If not NULL, offsets should be at least s.length().
> + // offsets are not accurate if the return value is GUESSENC_OTHER
> + static as_encoding_guess_t GuessEncoding(std::string& s, int&
> length, int *offsets);
> +
> static void ActionEnd(ActionExec& thread);
> static void ActionNextFrame(ActionExec& thread);
> static void ActionPrevFrame(ActionExec& thread);
>
>
> _______________________________________________
> Gnash-commit mailing list
> address@hidden
> http://lists.gnu.org/mailman/listinfo/gnash-commit
>