AAPT2: Fix windows unicode path issues

Mingw64 was being difficult, so instead of defining a wmain entrypoint,
the command line parameters are parsed manually using built-in Windows
methods that support Unicode. The results are converted to UTF8 and
handled just like the rest of the linux/mac version of the code.

This also removes dependencies on std::istream in favour of a
FileInputStream which calls the appropriate unicode version of
open to read a file.

No speed regressions found on Linux or MacOS.

Bug: 62336414
Bug: 63830502
Bug: 65645766
Test: manual
Change-Id: I597da51e33729ed1b98bf246e7e773337fd3fee8
Merged-In: I597da51e33729ed1b98bf246e7e773337fd3fee8
diff --git a/tools/aapt2/xml/XmlDom.cpp b/tools/aapt2/xml/XmlDom.cpp
index 885ab3e..d6df715 100644
--- a/tools/aapt2/xml/XmlDom.cpp
+++ b/tools/aapt2/xml/XmlDom.cpp
@@ -29,8 +29,9 @@
 #include "XmlPullParser.h"
 #include "util/Util.h"
 
-using android::StringPiece;
-using android::StringPiece16;
+using ::aapt::io::InputStream;
+using ::android::StringPiece;
+using ::android::StringPiece16;
 
 namespace aapt {
 namespace xml {
@@ -189,40 +190,41 @@
   stack->pending_comment += comment;
 }
 
-std::unique_ptr<XmlResource> Inflate(std::istream* in, IDiagnostics* diag, const Source& source) {
+std::unique_ptr<XmlResource> Inflate(InputStream* in, IDiagnostics* diag, const Source& source) {
   Stack stack;
 
-  XML_Parser parser = XML_ParserCreateNS(nullptr, kXmlNamespaceSep);
-  XML_SetUserData(parser, &stack);
-  XML_UseParserAsHandlerArg(parser);
-  XML_SetElementHandler(parser, StartElementHandler, EndElementHandler);
-  XML_SetNamespaceDeclHandler(parser, StartNamespaceHandler, EndNamespaceHandler);
-  XML_SetCharacterDataHandler(parser, CharacterDataHandler);
-  XML_SetCommentHandler(parser, CommentDataHandler);
+  std::unique_ptr<std::remove_pointer<XML_Parser>::type, decltype(XML_ParserFree)*> parser = {
+      XML_ParserCreateNS(nullptr, kXmlNamespaceSep), XML_ParserFree};
+  XML_SetUserData(parser.get(), &stack);
+  XML_UseParserAsHandlerArg(parser.get());
+  XML_SetElementHandler(parser.get(), StartElementHandler, EndElementHandler);
+  XML_SetNamespaceDeclHandler(parser.get(), StartNamespaceHandler, EndNamespaceHandler);
+  XML_SetCharacterDataHandler(parser.get(), CharacterDataHandler);
+  XML_SetCommentHandler(parser.get(), CommentDataHandler);
 
-  char buffer[1024];
-  while (!in->eof()) {
-    in->read(buffer, sizeof(buffer) / sizeof(buffer[0]));
-    if (in->bad() && !in->eof()) {
-      stack.root = {};
-      diag->Error(DiagMessage(source) << strerror(errno));
-      break;
-    }
-
-    if (XML_Parse(parser, buffer, in->gcount(), in->eof()) == XML_STATUS_ERROR) {
-      stack.root = {};
-      diag->Error(DiagMessage(source.WithLine(XML_GetCurrentLineNumber(parser)))
-                  << XML_ErrorString(XML_GetErrorCode(parser)));
-      break;
+  const char* buffer = nullptr;
+  size_t buffer_size = 0;
+  while (in->Next(reinterpret_cast<const void**>(&buffer), &buffer_size)) {
+    if (XML_Parse(parser.get(), buffer, buffer_size, false) == XML_STATUS_ERROR) {
+      diag->Error(DiagMessage(source.WithLine(XML_GetCurrentLineNumber(parser.get())))
+                  << XML_ErrorString(XML_GetErrorCode(parser.get())));
+      return {};
     }
   }
 
-  XML_ParserFree(parser);
-  if (stack.root) {
-    return util::make_unique<XmlResource>(ResourceFile{{}, {}, source}, StringPool{},
-                                          std::move(stack.root));
+  if (in->HadError()) {
+    diag->Error(DiagMessage(source) << in->GetError());
+    return {};
+  } else {
+    // Finish off the parsing.
+    if (XML_Parse(parser.get(), nullptr, 0u, true) == XML_STATUS_ERROR) {
+      diag->Error(DiagMessage(source.WithLine(XML_GetCurrentLineNumber(parser.get())))
+                  << XML_ErrorString(XML_GetErrorCode(parser.get())));
+      return {};
+    }
   }
-  return {};
+  return util::make_unique<XmlResource>(ResourceFile{{}, {}, source}, StringPool{},
+                                        std::move(stack.root));
 }
 
 static void CopyAttributes(Element* el, android::ResXMLParser* parser, StringPool* out_pool) {