Less string copies of text in XML parsing.

Change-Id: I5bf80de3da7ae4bd91dd7675a9af16d377c014aa
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/366409
Reviewed-by: Florin Malita <fmalita@google.com>
Commit-Queue: Ben Wagner <bungeman@google.com>
diff --git a/src/xml/SkDOM.cpp b/src/xml/SkDOM.cpp
index 3300090..49d4db2 100644
--- a/src/xml/SkDOM.cpp
+++ b/src/xml/SkDOM.cpp
@@ -179,11 +179,11 @@
 #include "include/private/SkTDArray.h"
 #include "src/xml/SkXMLParser.h"
 
-static char* dupstr(SkArenaAlloc* chunk, const char src[]) {
+static char* dupstr(SkArenaAlloc* chunk, const char src[], size_t srcLen) {
     SkASSERT(chunk && src);
-    size_t  len = strlen(src);
-    char*   dst = chunk->makeArrayDefault<char>(len + 1);
-    memcpy(dst, src, len + 1);
+    char* dst = chunk->makeArrayDefault<char>(srcLen + 1);
+    memcpy(dst, src, srcLen);
+    dst[srcLen] = '\0';
     return dst;
 }
 
@@ -230,14 +230,14 @@
     }
 
     bool onStartElement(const char elem[]) override {
-        this->startCommon(elem, SkDOM::kElement_Type);
+        this->startCommon(elem, strlen(elem), SkDOM::kElement_Type);
         return false;
     }
 
     bool onAddAttribute(const char name[], const char value[]) override {
         SkDOM::Attr* attr = fAttrs.append();
-        attr->fName = dupstr(fAlloc, name);
-        attr->fValue = dupstr(fAlloc, value);
+        attr->fName = dupstr(fAlloc, name, strlen(name));
+        attr->fValue = dupstr(fAlloc, value, strlen(value));
         return false;
     }
 
@@ -264,20 +264,19 @@
     }
 
     bool onText(const char text[], int len) override {
-        SkString str(text, len);
-        this->startCommon(str.c_str(), SkDOM::kText_Type);
-        this->SkDOMParser::onEndElement(str.c_str());
+        this->startCommon(text, len, SkDOM::kText_Type);
+        this->SkDOMParser::onEndElement(fElemName);
 
         return false;
     }
 
 private:
-    void startCommon(const char elem[], SkDOM::Type type) {
+    void startCommon(const char elem[], size_t elemSize, SkDOM::Type type) {
         if (fLevel > 0 && fNeedToFlush) {
             this->flushAttributes();
         }
         fNeedToFlush = true;
-        fElemName = dupstr(fAlloc, elem);
+        fElemName = dupstr(fAlloc, elem, elemSize);
         fElemType = type;
         ++fLevel;
     }
diff --git a/src/xml/SkXMLParser.cpp b/src/xml/SkXMLParser.cpp
index fb31e06..7432ae8 100644
--- a/src/xml/SkXMLParser.cpp
+++ b/src/xml/SkXMLParser.cpp
@@ -5,15 +5,16 @@
  * found in the LICENSE file.
  */
 
-#include "src/xml/SkXMLParser.h"
-
-#include "expat.h"
-
 #include "include/core/SkStream.h"
 #include "include/core/SkString.h"
 #include "include/core/SkTypes.h"
 #include "include/private/SkTemplates.h"
 #include "include/private/SkTo.h"
+#include "src/xml/SkXMLParser.h"
+
+#include <expat.h>
+
+#include <vector>
 
 static char const* const gErrorStrings[] = {
     "empty or missing file ",
@@ -70,21 +71,21 @@
         , fXMLParser(XML_ParserCreate_MM(nullptr, &sk_XML_alloc, nullptr)) { }
 
     void flushText() {
-        if (!fBufferedText.isEmpty()) {
-            fParser->text(fBufferedText.c_str(), SkTo<int>(fBufferedText.size()));
-            fBufferedText.reset();
+        if (!fBufferedText.empty()) {
+            fParser->text(fBufferedText.data(), SkTo<int>(fBufferedText.size()));
+            fBufferedText.clear();
         }
     }
 
     void appendText(const char* txt, size_t len) {
-        fBufferedText.append(txt, len);
+        fBufferedText.insert(fBufferedText.end(), txt, &txt[len]);
     }
 
     SkXMLParser* fParser;
     SkAutoTCallVProc<std::remove_pointer_t<XML_Parser>, XML_ParserFree> fXMLParser;
 
 private:
-    SkString fBufferedText;
+    std::vector<char> fBufferedText;
 };
 
 #define HANDLER_CONTEXT(arg, name) ParsingContext* name = static_cast<ParsingContext*>(arg)