summaryrefslogtreecommitdiff
path: root/zenXml/zenxml/xml.h
diff options
context:
space:
mode:
Diffstat (limited to 'zenXml/zenxml/xml.h')
-rw-r--r--zenXml/zenxml/xml.h46
1 files changed, 22 insertions, 24 deletions
diff --git a/zenXml/zenxml/xml.h b/zenXml/zenxml/xml.h
index 10f0ecd8..8b86a49f 100644
--- a/zenXml/zenxml/xml.h
+++ b/zenXml/zenxml/xml.h
@@ -34,39 +34,37 @@ namespace
{
XmlDoc loadXml(const Zstring& filePath) //throw FileError
{
- FileInputPlain fileIn(filePath); //throw FileError
- const size_t blockSize = fileIn.getBlockSize(); //throw FileError
- bool xmlPrefixChecked = false;
+ FileInputPlain fileIn(filePath); //throw FileError, ErrorFileLocked
+ std::string headBuf;
+ const size_t headSizeMin = BYTE_ORDER_MARK_UTF8.size() + strLength("<?xml?>");
- std::string buffer;
- for (;;)
+ const std::string buf = unbufferedLoad<std::string>([&](void* buffer, size_t bytesToRead)
{
- warn_static("don't need zero-initialization! => resize_and_overwrite")
- buffer.resize(buffer.size() + blockSize);
- const size_t bytesRead = fileIn.tryRead(&*(buffer.end() - blockSize), blockSize); //throw FileError; may return short, only 0 means EOF! CONTRACT: bytesToRead > 0!
- buffer.resize(buffer.size() - blockSize + bytesRead); //caveat: unsigned arithmetics
+ const size_t bytesRead = fileIn.tryRead(buffer, bytesToRead); //throw FileError; may return short, only 0 means EOF! => CONTRACT: bytesToRead > 0!
//quick test whether input is an XML: avoid loading large binary files up front!
- if (!xmlPrefixChecked && buffer.size() >= strLength(BYTE_ORDER_MARK_UTF8) + strLength("<?xml?>"))
+ if (headBuf.size() < headSizeMin)
{
- xmlPrefixChecked = true;
-
- std::string_view bufStart = buffer;
- if (startsWith(bufStart, BYTE_ORDER_MARK_UTF8))
- bufStart.remove_prefix(strLength(BYTE_ORDER_MARK_UTF8));
-
- if (!startsWith(bufStart, "<?xml ") &&
- !startsWith(bufStart, "<?xml?>"))
- throw FileError(replaceCpy(_("File %x does not contain a valid configuration."), L"%x", fmtPath(filePath)));
+ headBuf.append(static_cast<const char*>(buffer), std::min(headSizeMin - headBuf.size(), bytesRead));
+
+ if (headBuf.size() == headSizeMin)
+ {
+ std::string_view header = headBuf;
+ if (startsWith(header, BYTE_ORDER_MARK_UTF8))
+ header.remove_prefix(BYTE_ORDER_MARK_UTF8.size()); //keep headBuf.size()!
+
+ if (!startsWith(header, "<?xml ") &&
+ !startsWith(header, "<?xml?>"))
+ throw FileError(replaceCpy(_("File %x does not contain a valid configuration."), L"%x", fmtPath(filePath)));
+ }
}
-
- if (bytesRead == 0) //end of file
- break;
- }
+ return bytesRead;
+ },
+ fileIn.getBlockSize()); //throw FileError
try
{
- return parseXml(buffer); //throw XmlParsingError
+ return parseXml(buf); //throw XmlParsingError
}
catch (const XmlParsingError& e)
{
bgstack15