Skip to content

Commit

Permalink
Add xml::Document constructor accepting a std::istream.
Browse files Browse the repository at this point in the history
  • Loading branch information
codereader committed Jan 20, 2020
1 parent 577c725 commit d7f010b
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 0 deletions.
34 changes: 34 additions & 0 deletions libs/xmlutil/Document.cpp
Expand Up @@ -4,6 +4,7 @@
#include "itextstream.h"
#include <libxml/parser.h>
#include <libxml/xpath.h>
#include <vector>

namespace xml
{
Expand All @@ -17,6 +18,39 @@ Document::Document(const std::string& filename) :
_xmlDoc(xmlParseFile(filename.c_str()))
{}

Document::Document(std::istream& stream) :
_xmlDoc(nullptr)
{
const std::size_t bufferSize = 4096;
static_assert(bufferSize < std::numeric_limits<int>::max());

std::vector<char> buffer(bufferSize);

// Read 1 byte to construct the parser context
stream.read(buffer.data(), 1);

if (stream.gcount() != 1)
{
rError() << "[xml::Document] Could not read a single byte from the given stream." << std::endl;
return;
}

xmlParserCtxtPtr ctxt = xmlCreatePushParserCtxt(nullptr, nullptr, buffer.data(), 1, "stream");

while (!stream.eof())
{
stream.read(buffer.data(), buffer.size());
xmlParseChunk(ctxt, buffer.data(), static_cast<int>(stream.gcount()), 0);
}

// Terminate the parser
xmlParseChunk(ctxt, buffer.data(), 0, 1);

_xmlDoc = ctxt->myDoc;

xmlFreeParserCtxt(ctxt);
}

Document::Document(const Document& other) :
_xmlDoc(other._xmlDoc)
{}
Expand Down
4 changes: 4 additions & 0 deletions libs/xmlutil/Document.h
Expand Up @@ -37,6 +37,10 @@ class Document
// Use the isValid() method to check if the load was successful.
Document(const std::string& filename);

// Create a document from the given stream. This will read the whole
// stream data into memory, and parse it chunk by chunk.
Document(std::istream& stream);

// Copy constructor (note: does not create an actual copy of the internal xmlDoc)
Document(const Document& other);

Expand Down

0 comments on commit d7f010b

Please sign in to comment.