src/share/vm/utilities/utf8.cpp

Print this page
rev 6283 : redundant memcpy

@@ -327,27 +327,23 @@
   return result;
 }
 
 char* UNICODE::as_utf8(jchar* base, int length) {
   int utf8_len = utf8_length(base, length);
-  u_char* result = NEW_RESOURCE_ARRAY(u_char, utf8_len + 1);
-  u_char* p = result;
-  for (int index = 0; index < length; index++) {
-    p = utf8_write(p, base[index]);
-  }
-  *p = '\0';
-  assert(p == &result[utf8_len], "length prediction must be correct");
-  return (char*) result;
+  u_char* buf = NEW_RESOURCE_ARRAY(u_char, utf8_len + 1);
+  char* result = as_utf8(base, length, (char*) buf, utf8_len + 1);
+  assert((int) strlen(result) == utf8_len, "length prediction must be correct");
+  return result;
 }
 
 char* UNICODE::as_utf8(jchar* base, int length, char* buf, int buflen) {
   u_char* p = (u_char*)buf;
-  u_char* end = (u_char*)buf + buflen;
   for (int index = 0; index < length; index++) {
     jchar c = base[index];
-    if (p + utf8_size(c) >= end) break;      // string is truncated
-    p = utf8_write(p, base[index]);
+    buflen -= utf8_size(c);
+    if (buflen <= 0) break; // string is truncated
+    p = utf8_write(p, c);
   }
   *p = '\0';
   return buf;
 }
 

@@ -387,5 +383,31 @@
       p += 6;
     }
   }
   *p = '\0';
 }
+
+#ifndef PRODUCT
+void TestAsUtf8() {
+  char res[60];
+  jchar str[20];
+
+  for (int i = 0; i < 20; i++) {
+    str[i] = 0x0800; // char that is 2B in UTF-16 but 3B in UTF-8
+  }
+  str[19] = (jchar)'\0';
+
+  // The resulting string in UTF-8 is 3*19 bytes long, but should be truncated
+  UNICODE::as_utf8(str, 19, res, 10);
+  assert(strlen(res) == 9, "string should be truncated here");
+
+  UNICODE::as_utf8(str, 19, res, 18);
+  assert(strlen(res) == 15, "string should be truncated here");
+
+  UNICODE::as_utf8(str, 19, res, 20);
+  assert(strlen(res) == 18, "string should be truncated here");
+
+  // Test with an "unbounded" buffer
+  UNICODE::as_utf8(str, 19, res, INT_MAX);
+  assert(strlen(res) == 3*19, "string should end here");
+}
+#endif
\ No newline at end of file