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>
This commit is contained in:
parent
c7d6e0ba0b
commit
81bc8fe0c5
@ -179,11 +179,11 @@ const char* SkDOM::AttrIter::next(const char** value) {
|
||||
#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 @@ protected:
|
||||
}
|
||||
|
||||
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 @@ protected:
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -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 @@ struct ParsingContext {
|
||||
, 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)
|
||||
|
Loading…
Reference in New Issue
Block a user