Merge "Migrate UnicodeString usage to equivalent C API"
am: 401a214792

Change-Id: I03f265f52da8c2871ee51c1355cb43f1fca63883
diff --git a/luni/src/main/native/org_apache_harmony_xml_ExpatParser.cpp b/luni/src/main/native/org_apache_harmony_xml_ExpatParser.cpp
index 9d23837..6df5bdd 100644
--- a/luni/src/main/native/org_apache_harmony_xml_ExpatParser.cpp
+++ b/luni/src/main/native/org_apache_harmony_xml_ExpatParser.cpp
@@ -33,7 +33,8 @@
 
 #include "JniConstants.h"
 #include "JniException.h"
-#include "unicode/unistr.h"
+#include "unicode/char16ptr.h"
+#include "unicode/ustring.h"
 
 #define BUCKET_COUNT 128
 
@@ -428,11 +429,11 @@
  *
  * @returns number of UTF-16 characters which were copied
  */
-static size_t fillBuffer(ParsingContext* parsingContext, const char* utf8, int byteCount) {
+static size_t fillBuffer(ParsingContext* parsingContext, const char* utf8, int byteLength) {
     JNIEnv* env = parsingContext->env;
 
     // Grow buffer if necessary (the length in bytes is always >= the length in chars).
-    jcharArray javaChars = parsingContext->ensureCapacity(byteCount);
+    jcharArray javaChars = parsingContext->ensureCapacity(byteLength);
     if (javaChars == NULL) {
         return -1;
     }
@@ -443,8 +444,19 @@
         return -1;
     }
     UErrorCode status = U_ZERO_ERROR;
-    icu::UnicodeString utf16(icu::UnicodeString::fromUTF8(icu::StringPiece(utf8, byteCount)));
-    return utf16.extract(chars.get(), byteCount, status);
+    int32_t length16;
+    // Use inline C++ class provided by ICU
+    icu::Char16Ptr dest(chars.get()); // Convert jchar (aka uint16_t*) to char16_t*
+    // Avoid icu::UnicodeString due to unstable C++ ABI.
+    u_strFromUTF8WithSub(dest.get(), // dest
+      byteLength, // destCapacity
+      &length16, // pDestLength
+      utf8, // src
+      byteLength, // srcLength
+      0xfffd,  // 0xfffd is the standard substitution character for malformed input sequence.
+      NULL,    // Don't care about number of substitutions.
+      &status);
+    return length16;
 }
 
 /**