Author: [EMAIL PROTECTED]
Date: Mon Sep 29 21:38:22 2008
New Revision: 3693
Modified:
changes/jat/oophm-branch/plugins/xpcom/FFSessionHandler.cpp
changes/jat/oophm-branch/plugins/xpcom/Makefile
changes/jat/oophm-branch/user/src/com/google/gwt/dom/client/Element.java
Log:
Fix DOMTest, UTF8 string handling, fix Makefile install targets.
Modified: changes/jat/oophm-branch/plugins/xpcom/FFSessionHandler.cpp
==============================================================================
--- changes/jat/oophm-branch/plugins/xpcom/FFSessionHandler.cpp (original)
+++ changes/jat/oophm-branch/plugins/xpcom/FFSessionHandler.cpp Mon Sep 29
21:38:22 2008
@@ -49,9 +49,6 @@
FFSessionHandler::FFSessionHandler(HostChannel* channel)
: SessionData(channel, this, getJSContext()), jsObjectId(0),
jsObjectsById(NULL), stringObjectClass(NULL) {
- if (!JS_CStringsAreUTF8()) {
- Debug::log(Debug::Error) << "UTF8 is not in use" << Debug::flush;
- }
FFSessionHandler::registerHandler(ctx, this);
jsObjectsById = JS_NewArrayObject(ctx, 0, NULL);
if (!(jsObjectsById && JS_AddNamedRoot(ctx,
&jsObjectsById, "jsObjectsById"))) {
@@ -252,6 +249,122 @@
return false;
}
+/**
+ * Convert UTF16 string to UTF8-encoded std::string.
+ *
+ * @return UTF8-encoded string.
+ */
+static std::string utf8String(const jschar* str, unsigned len) {
+ std::string utf8str;
+ while (len-- > 0) {
+ unsigned ch = *str++;
+ // check for paired surrogates first, leave unpaired surrogates as-is
+ if (ch >= 0xD800 && ch < 0xDC00 && len > 0 && *str >= 0xDC00 && *str <
0xE000) {
+ ch = ((ch & 1023) << 10) + (*str++ & 1023) + 0x10000;
+ len--;
+ }
+ if (ch < 0x80) { // U+0000 - U+007F as 0xxxxxxx
+ utf8str.append(1, ch);
+ } else if (ch < 0x800) { // U+0080 - U+07FF as 110xxxxx 10xxxxxx
+ utf8str.append(1, 0xC0 + ((ch >> 6) & 31));
+ utf8str.append(1, 0x80 + (ch & 63));
+ } else if (ch < 0x10000) { // U+0800 - U+FFFF as 1110xxxx 10xxxxxx
10xxxxxx
+ utf8str.append(1, 0xE0 + ((ch >> 12) & 15));
+ utf8str.append(1, 0x80 + ((ch >> 6) & 63));
+ utf8str.append(1, 0x80 + (ch & 63));
+ } else { // rest as 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
+ utf8str.append(1, 0xF0 + ((ch >> 18) & 7));
+ utf8str.append(1, 0x80 + ((ch >> 12) & 63));
+ utf8str.append(1, 0x80 + ((ch >> 6) & 63));
+ utf8str.append(1, 0x80 + (ch & 63));
+ }
+ }
+ return utf8str;
+}
+
+/**
+ * Creates a JSString from a UTF8-encoded std::string.
+ *
+ * @return the JSString object, which owns its memory buffer.
+ */
+static JSString* stringUtf8(JSContext* ctx, const std::string& utf8str) {
+ unsigned len = 0;
+ for (int i = 0; i < utf8str.length(); ++i) {
+ char ch = utf8str[i];
+ switch (ch & 0xF8) {
+ // continuation & invalid chars
+ default:
+ // ASCII characters
+ case 0x00: case 0x08: case 0x10: case 0x18:
+ case 0x20: case 0x28: case 0x30: case 0x38:
+ case 0x40: case 0x48: case 0x50: case 0x58:
+ case 0x60: case 0x68: case 0x70: case 0x78:
+ // 2-byte UTF8 characters
+ case 0xC0: case 0xC8: case 0xD0: case 0xD8:
+ // 3-byte UTF8 characters
+ case 0xE0: case 0xE8:
+ ++len;
+ break;
+ case 0xF0:
+ len += 2;
+ break;
+ }
+ }
+ jschar* buf = static_cast<jschar*>(JS_malloc(ctx, len * sizeof(jschar)));
+ if (!buf) {
+ return NULL;
+ }
+ jschar* p = buf;
+ unsigned codePoint;
+ int charsLeft = -1;
+ for (int i = 0; i < utf8str.length(); ++i) {
+ char ch = utf8str[i];
+ if (charsLeft >= 0) {
+ if ((ch & 0xC0) != 0x80) {
+ // invalid, missing continuation character
+ *p++ = static_cast<jschar>(0xFFFD);
+ charsLeft = -1;
+ } else {
+ codePoint = (codePoint << 6) | (ch & 63);
+ if (!--charsLeft) {
+ if (codePoint >= 0x10000) {
+ codePoint -= 0x10000;
+ *p++ = static_cast<jschar>(0xD800 + ((codePoint >> 10) &
1023));
+ *p++ = static_cast<jschar>(0xDC00 + (codePoint & 1023));
+ } else {
+ *p++ = static_cast<jschar>(codePoint);
+ }
+ charsLeft = -1;
+ }
+ }
+ continue;
+ }
+ switch (ch & 0xF8) {
+ default: // skip invalid and continuation chars
+ break;
+ case 0x00: case 0x08: case 0x10: case 0x18:
+ case 0x20: case 0x28: case 0x30: case 0x38:
+ case 0x40: case 0x48: case 0x50: case 0x58:
+ case 0x60: case 0x68: case 0x70: case 0x78:
+ *p++ = static_cast<jschar>(ch);
+ break;
+ case 0xC0: case 0xC8: case 0xD0: case 0xD8:
+ charsLeft = 1;
+ codePoint = ch & 31;
+ break;
+ case 0xE0: case 0xE8:
+ charsLeft = 2;
+ codePoint = ch & 15;
+ break;
+ case 0xF0:
+ charsLeft = 3;
+ codePoint = ch & 7;
+ break;
+ }
+ }
+ return JS_NewUCString(ctx, buf, p - buf);
+}
+
void FFSessionHandler::makeValue(Value& retVal, JSContext* ctx, const
jsval& value) {
if (JSVAL_IS_VOID(value)) {
retVal.setUndefined();
@@ -263,8 +376,8 @@
retVal.setBoolean(JSVAL_TO_BOOLEAN(value));
} else if (JSVAL_IS_STRING(value)) {
JSString* str = JSVAL_TO_STRING(value);
- // TODO(jat): is this Unicode safe?
- retVal.setString(JS_GetStringBytes(str), JS_GetStringLength(str));
+ retVal.setString(utf8String(JS_GetStringChars(str),
+ JS_GetStringLength(str)));
} else if (JSVAL_IS_DOUBLE(value)) {
retVal.setDouble(*JSVAL_TO_DOUBLE(value));
} else if (JSVAL_IS_OBJECT(value)) {
@@ -274,8 +387,9 @@
} else if (JS_GET_CLASS(ctx, obj) == stringObjectClass) {
// JS String wrapper object, treat as a string primitive
JSString* str = JS_ValueToString(ctx, value);
- // TODO(jat): is this Unicode safe?
- retVal.setString(JS_GetStringBytes(str), JS_GetStringLength(str));
+ retVal.setString(utf8String(JS_GetStringChars(str),
+ JS_GetStringLength(str)));
+ // str will be garbage-collected, does not need to be freed
} else {
// It's a plain-old JavaScript Object
std::map<JSObject*, int>::iterator it = jsIdsByObject.find(obj);
@@ -332,8 +446,7 @@
break;
case Value::STRING:
{
- std::string strVal = value.getString();
- JSString* str = JS_NewStringCopyN(ctx, strVal.c_str(),
strVal.length());
+ JSString* str = stringUtf8(ctx, value.getString());
retVal = STRING_TO_JSVAL(str);
}
break;
Modified: changes/jat/oophm-branch/plugins/xpcom/Makefile
==============================================================================
--- changes/jat/oophm-branch/plugins/xpcom/Makefile (original)
+++ changes/jat/oophm-branch/plugins/xpcom/Makefile Mon Sep 29 21:38:22 2008
@@ -17,7 +17,7 @@
COMMON= ../common/libcommon$(FLAG32BIT).a
-ALL: oophm-xpcom.xpi
+all:: oophm-xpcom.xpi
OBJS= ExternalWrapper.o ModuleOOPHM.o FFSessionHandler.o JavaObject.o
JSRunner.o XpcomDebug.o
@@ -69,20 +69,20 @@
$(OBJS): arch IOOPHM.h
-.PHONY: clean depend common install install-platform
+.PHONY: all clean realclean depend common install install-platform
-install: oophm-xpcom.xpi
- -cp $< prebuilt
+install:: oophm-xpcom.xpi
+ -cp --preserve=mode $< prebuilt
-install-platform: liboophm.so liboophm.rsrc
+install-platform:: liboophm.so
-mkdir -p $(subst extension,prebuilt/extension,$(INSTDIR))
- -mkdir -p $(subst extension,prebuilt/extension,$(RESDIR))
- -cp liboophm.so $(subst extension,prebuilt/extension,$(INSTDIR))
- -cp liboophm.rsrc $(subst extension,prebuilt/extension,$(RESDIR))
-
-clean:
- -rm -f arch $(OBJS) liboophm.so liboophm.rsrc IOOPHM.h IOOPHM.xpt
oophm-xpcom.xpi
+ -cp --preserve=mode $< $(subst extension,prebuilt/extension,$(INSTDIR))
+clean::
+ -rm -f $(OBJS) liboophm.so liboophm.rsrc IOOPHM.h IOOPHM.xpt
oophm-xpcom.xpi
-rm -rf extension
+
+realclean:: clean
+ -rm -f arch
depend:
g++ -MM $(CFLAGS) $(SRCS) >>Makefile
Modified:
changes/jat/oophm-branch/user/src/com/google/gwt/dom/client/Element.java
==============================================================================
---
changes/jat/oophm-branch/user/src/com/google/gwt/dom/client/Element.java
(original)
+++
changes/jat/oophm-branch/user/src/com/google/gwt/dom/client/Element.java
Mon Sep 29 21:38:22 2008
@@ -56,10 +56,7 @@
* does not have a specified or default value
*/
public final native String getAttribute(String name) /*-{
- var result = this.getAttribute(name);
- // BUILD FIX HACK: must coerce to String for IE.
- // ON MERGE: use a jgw fix from trunk instead of this!
- return (result == null) ? null : String(result);
+ return this.getAttribute(name) || "";
}-*/;
/**
--~--~---------~--~----~------------~-------~--~----~
http://groups.google.com/group/Google-Web-Toolkit-Contributors
-~----------~----~----~----~------~----~------~--~---