Bug 538324 - Move ctypes into js/src. Part 4: Use js string conversion functions. r=benjamn
authorDan Witte <dwitte@mozilla.com>
Fri, 02 Apr 2010 13:06:15 -0700
changeset 40445 7b252bd84c794a16ec75d8d361b1d6b3fcaadf04
parent 40444 508e1575dd040e915685b22c46f6fdcdeba33e51
child 40446 d052f11b495bfc278deed384c40dcc17f95f0398
push id12610
push userrsayre@mozilla.com
push dateMon, 05 Apr 2010 17:26:41 +0000
treeherdermozilla-central@1942c0b4e101 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbenjamn
bugs538324
milestone1.9.3a4pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
Bug 538324 - Move ctypes into js/src. Part 4: Use js string conversion functions. r=benjamn
js/src/ctypes/CTypes.cpp
--- a/js/src/ctypes/CTypes.cpp
+++ b/js/src/ctypes/CTypes.cpp
@@ -1368,31 +1368,16 @@ StringToInteger(JSContext* cx, JSString*
     if (i / base != ii) // overflow
       return false;
   }
 
   *result = i;
   return true;
 }
 
-static bool
-IsUTF16(const jschar* string, size_t length)
-{
-  PRBool error;
-  const PRUnichar* buffer = reinterpret_cast<const PRUnichar*>(string);
-  const PRUnichar* end = buffer + length;
-  while (buffer != end) {
-    UTF16CharEnumerator::NextChar(&buffer, end, &error);
-    if (error)
-      return false;
-  }
-
-  return true;
-}
-
 template<class CharType>
 static size_t
 strnlen(const CharType* begin, size_t max)
 {
   for (const CharType* s = begin; s != begin + max; ++s)
     if (*s == 0)
       return s - begin;
 
@@ -1638,31 +1623,32 @@ ImplicitConvert(JSContext* cx,
       const jschar* sourceChars = JS_GetStringChars(sourceString);
       size_t sourceLength = JS_GetStringLength(sourceString);
 
       switch (CType::GetTypeCode(cx, baseType)) {
       case TYPE_char:
       case TYPE_signed_char:
       case TYPE_unsigned_char: {
         // Convert from UTF-16 to UTF-8.
-        if (!IsUTF16(sourceChars, sourceLength))
-          return TypeError(cx, "UTF-16 string", val);
-
-        NS_ConvertUTF16toUTF8 converted(
-          reinterpret_cast<const PRUnichar*>(sourceChars), sourceLength);
+        size_t nbytes =
+          js_GetDeflatedUTF8StringLength(cx, sourceChars, sourceLength);
+        if (nbytes == (size_t) -1)
+          return false;
 
         char** charBuffer = static_cast<char**>(buffer);
-        *charBuffer = new char[converted.Length() + 1];
+        *charBuffer = new char[nbytes + 1];
         if (!*charBuffer) {
           JS_ReportAllocationOverflow(cx);
           return false;
         }
 
+        ASSERT_OK(js_DeflateStringToUTF8Buffer(cx, sourceChars, sourceLength,
+                    *charBuffer, &nbytes));
+        (*charBuffer)[nbytes] = 0;
         *freePointer = true;
-        memcpy(*charBuffer, converted.get(), converted.Length() + 1);
         break;
       }
       case TYPE_jschar: {
         // Copy the jschar string data. (We could provide direct access to the
         // JSString's buffer, but this approach is safer if the caller happens
         // to modify the string.)
         jschar** jscharBuffer = static_cast<jschar**>(buffer);
         *jscharBuffer = new jschar[sourceLength + 1];
@@ -1700,30 +1686,32 @@ ImplicitConvert(JSContext* cx,
       const jschar* sourceChars = JS_GetStringChars(sourceString);
       size_t sourceLength = JS_GetStringLength(sourceString);
 
       switch (CType::GetTypeCode(cx, baseType)) {
       case TYPE_char:
       case TYPE_signed_char:
       case TYPE_unsigned_char: {
         // Convert from UTF-16 to UTF-8.
-        if (!IsUTF16(sourceChars, sourceLength))
-          return TypeError(cx, "UTF-16 string", val);
-
-        NS_ConvertUTF16toUTF8 converted(
-          reinterpret_cast<const PRUnichar*>(sourceChars), sourceLength);
-
-        if (targetLength < converted.Length()) {
+        size_t nbytes =
+          js_GetDeflatedUTF8StringLength(cx, sourceChars, sourceLength);
+        if (nbytes == (size_t) -1)
+            return false;
+
+        if (targetLength < nbytes) {
           JS_ReportError(cx, "ArrayType has insufficient length");
           return false;
         }
 
-        memcpy(buffer, converted.get(), converted.Length());
-        if (targetLength > converted.Length())
-          static_cast<char*>(buffer)[converted.Length()] = 0;
+        char* charBuffer = static_cast<char*>(buffer);
+        ASSERT_OK(js_DeflateStringToUTF8Buffer(cx, sourceChars, sourceLength,
+                    charBuffer, &nbytes));
+
+        if (targetLength > nbytes)
+          charBuffer[nbytes] = 0;
 
         break;
       }
       case TYPE_jschar: {
         // Copy the string data, jschar for jschar, including the terminator
         // if there's space.
         if (targetLength < sourceLength) {
           JS_ReportError(cx, "ArrayType has insufficient length");
@@ -3418,24 +3406,22 @@ ArrayType::ConstructData(JSContext* cx,
       JSString* sourceString = JSVAL_TO_STRING(argv[0]);
       const jschar* sourceChars = JS_GetStringChars(sourceString);
       size_t sourceLength = JS_GetStringLength(sourceString);
 
       switch (CType::GetTypeCode(cx, baseType)) {
       case TYPE_char:
       case TYPE_signed_char:
       case TYPE_unsigned_char: {
-        // Convert from UTF-16 to UTF-8 to determine the length. :(
-        if (!IsUTF16(sourceChars, sourceLength))
-          return TypeError(cx, "UTF-16 string", argv[0]);
-
-        NS_ConvertUTF16toUTF8 converted(
-          reinterpret_cast<const PRUnichar*>(sourceChars), sourceLength);
-
-        length = converted.Length() + 1;
+        // Determine the UTF-8 length.
+        length = js_GetDeflatedUTF8StringLength(cx, sourceChars, sourceLength);
+        if (length == (size_t) -1)
+          return false;
+
+        ++length;
         break;
       }
       case TYPE_jschar:
         length = sourceLength + 1;
         break;
       default:
         return TypeError(cx, "array", argv[0]);
       }
@@ -5307,23 +5293,30 @@ CData::ReadString(JSContext* cx, uintN a
   switch (CType::GetTypeCode(cx, baseType)) {
   case TYPE_int8_t:
   case TYPE_uint8_t:
   case TYPE_char:
   case TYPE_signed_char:
   case TYPE_unsigned_char: {
     char* bytes = static_cast<char*>(data);
     size_t length = strnlen(bytes, maxLength);
-    nsDependentCSubstring string(bytes, bytes + length);
-    if (!IsUTF8(string)) {
-      JS_ReportError(cx, "not a UTF-8 string");
+
+    // Determine the length.
+    size_t dstlen;
+    if (!js_InflateUTF8StringToBuffer(cx, bytes, length, NULL, &dstlen))
       return JS_FALSE;
-    }
-
-    result = NewUCString(cx, NS_ConvertUTF8toUTF16(string));
+
+    jschar* dst =
+      static_cast<jschar*>(JS_malloc(cx, (dstlen + 1) * sizeof(jschar)));
+    if (!dst)
+      return JS_FALSE;
+
+    ASSERT_OK(js_InflateUTF8StringToBuffer(cx, bytes, length, dst, &dstlen));
+
+    result = JS_NewUCString(cx, dst, dstlen);
     break;
   }
   case TYPE_int16_t:
   case TYPE_uint16_t:
   case TYPE_short:
   case TYPE_unsigned_short:
   case TYPE_jschar: {
     jschar* chars = static_cast<jschar*>(data);