YAML emitter/parser ownership refinement

This commit is contained in:
Jack Andersen 2016-01-04 14:00:12 -10:00
parent 9c880813ac
commit cf3739fced
2 changed files with 98 additions and 105 deletions

View File

@ -498,14 +498,34 @@ class YAMLDocReader
std::unique_ptr<YAMLNode> m_rootNode; std::unique_ptr<YAMLNode> m_rootNode;
std::vector<YAMLNode*> m_subStack; std::vector<YAMLNode*> m_subStack;
std::vector<int> m_seqTrackerStack; std::vector<int> m_seqTrackerStack;
static std::unique_ptr<YAMLNode> ParseEvents(yaml_parser_t* doc); yaml_parser_t m_parser;
std::unique_ptr<YAMLNode> ParseEvents();
public: public:
static bool ValidateClassType(yaml_parser_t* doc, const char* expectedType); YAMLDocReader()
inline const YAMLNode* getRootNode() const {return m_rootNode.get();}
std::unique_ptr<YAMLNode> releaseRootNode() {return std::move(m_rootNode);}
bool read(yaml_parser_t* doc)
{ {
std::unique_ptr<YAMLNode> newRoot = ParseEvents(doc); if (!yaml_parser_initialize(&m_parser))
{
HandleYAMLParserError(&m_parser);
return;
}
}
~YAMLDocReader()
{
yaml_parser_delete(&m_parser);
}
void reset()
{
yaml_parser_delete(&m_parser);
if (!yaml_parser_initialize(&m_parser))
HandleYAMLParserError(&m_parser);
}
yaml_parser_t* getParser() {return &m_parser;}
bool parse()
{
std::unique_ptr<YAMLNode> newRoot = ParseEvents();
if (!newRoot) if (!newRoot)
return false; return false;
m_rootNode = std::move(newRoot); m_rootNode = std::move(newRoot);
@ -515,6 +535,10 @@ public:
return true; return true;
} }
static bool ValidateClassType(yaml_parser_t* doc, const char* expectedType);
inline const YAMLNode* getRootNode() const {return m_rootNode.get();}
std::unique_ptr<YAMLNode> releaseRootNode() {return std::move(m_rootNode);}
void enterSubRecord(const char* name) void enterSubRecord(const char* name)
{ {
YAMLNode* curSub = m_subStack.back(); YAMLNode* curSub = m_subStack.back();
@ -759,10 +783,19 @@ class YAMLDocWriter
{ {
YAMLNode m_rootNode; YAMLNode m_rootNode;
std::vector<YAMLNode*> m_subStack; std::vector<YAMLNode*> m_subStack;
yaml_emitter_t m_emitter;
static bool RecursiveFinish(yaml_emitter_t* doc, const YAMLNode& node); static bool RecursiveFinish(yaml_emitter_t* doc, const YAMLNode& node);
public: public:
YAMLDocWriter(const char* classType) : m_rootNode(YAML_MAPPING_NODE) YAMLDocWriter(const char* classType) : m_rootNode(YAML_MAPPING_NODE)
{ {
if (!yaml_emitter_initialize(&m_emitter))
{
HandleYAMLEmitterError(&m_emitter);
return;
}
yaml_emitter_set_unicode(&m_emitter, true);
yaml_emitter_set_width(&m_emitter, -1);
m_subStack.emplace_back(&m_rootNode); m_subStack.emplace_back(&m_rootNode);
if (classType) if (classType)
{ {
@ -772,6 +805,34 @@ public:
} }
} }
~YAMLDocWriter()
{
yaml_emitter_delete(&m_emitter);
}
yaml_emitter_t* getEmitter() {return &m_emitter;}
bool open()
{
if (!yaml_emitter_open(&m_emitter))
{
HandleYAMLEmitterError(&m_emitter);
return false;
}
return true;
}
bool close()
{
if (!yaml_emitter_close(&m_emitter) ||
!yaml_emitter_flush(&m_emitter))
{
HandleYAMLEmitterError(&m_emitter);
return false;
}
return true;
}
void enterSubRecord(const char* name) void enterSubRecord(const char* name)
{ {
YAMLNode* curSub = m_subStack.back(); YAMLNode* curSub = m_subStack.back();
@ -885,21 +946,21 @@ public:
leaveSubVector(); leaveSubVector();
} }
bool finish(yaml_emitter_t* docOut) bool finish()
{ {
yaml_event_t event = {YAML_DOCUMENT_START_EVENT}; yaml_event_t event = {YAML_DOCUMENT_START_EVENT};
event.data.document_start.implicit = true; event.data.document_start.implicit = true;
if (!yaml_emitter_emit(docOut, &event)) if (!yaml_emitter_emit(&m_emitter, &event))
goto err; goto err;
if (!RecursiveFinish(docOut, m_rootNode)) if (!RecursiveFinish(&m_emitter, m_rootNode))
return false; return false;
event.type = YAML_DOCUMENT_END_EVENT; event.type = YAML_DOCUMENT_END_EVENT;
event.data.document_end.implicit = true; event.data.document_end.implicit = true;
if (!yaml_emitter_emit(docOut, &event)) if (!yaml_emitter_emit(&m_emitter, &event))
goto err; goto err;
return true; return true;
err: err:
HandleYAMLEmitterError(docOut); HandleYAMLEmitterError(&m_emitter);
return false; return false;
} }
@ -1074,65 +1135,31 @@ struct DNAYaml : DNA<DNAE>
std::string toYAMLString() const std::string toYAMLString() const
{ {
yaml_emitter_t emitter; YAMLDocWriter docWriter(DNATypeV());
if (!yaml_emitter_initialize(&emitter))
{
HandleYAMLEmitterError(&emitter);
return std::string();
}
std::string res; std::string res;
yaml_emitter_set_output(&emitter, (yaml_write_handler_t*)YAMLStdStringWriter, &res); yaml_emitter_set_output(docWriter.getEmitter(), (yaml_write_handler_t*)YAMLStdStringWriter, &res);
yaml_emitter_set_unicode(&emitter, true); yaml_emitter_set_unicode(docWriter.getEmitter(), true);
yaml_emitter_set_width(&emitter, -1); yaml_emitter_set_width(docWriter.getEmitter(), -1);
if (!yaml_emitter_open(&emitter)) if (!docWriter.open())
{
HandleYAMLEmitterError(&emitter);
yaml_emitter_delete(&emitter);
return std::string(); return std::string();
}
{
YAMLDocWriter docWriter(DNATypeV());
write(docWriter); write(docWriter);
if (!docWriter.finish(&emitter)) if (!docWriter.finish())
{
yaml_emitter_delete(&emitter);
return std::string(); return std::string();
} docWriter.close();
}
if (!yaml_emitter_close(&emitter) ||
!yaml_emitter_flush(&emitter))
{
HandleYAMLEmitterError(&emitter);
yaml_emitter_delete(&emitter);
return std::string();
}
yaml_emitter_delete(&emitter);
return res; return res;
} }
bool fromYAMLString(const std::string& str) bool fromYAMLString(const std::string& str)
{ {
yaml_parser_t parser;
if (!yaml_parser_initialize(&parser))
{
HandleYAMLParserError(&parser);
return false;
}
YAMLStdStringReaderState reader(str); YAMLStdStringReaderState reader(str);
yaml_parser_set_input(&parser, (yaml_read_handler_t*)YAMLStdStringReader, &reader);
YAMLDocReader docReader; YAMLDocReader docReader;
if (!docReader.read(&parser)) yaml_parser_set_input(docReader.getParser(), (yaml_read_handler_t*)YAMLStdStringReader, &reader);
{ if (!docReader.parse())
yaml_parser_delete(&parser);
return false; return false;
}
read(docReader); read(docReader);
yaml_parser_delete(&parser);
return true; return true;
} }
@ -1153,64 +1180,30 @@ struct DNAYaml : DNA<DNAE>
} }
bool toYAMLFile(FILE* fout) const bool toYAMLFile(FILE* fout) const
{
yaml_emitter_t emitter;
if (!yaml_emitter_initialize(&emitter))
{
HandleYAMLEmitterError(&emitter);
return false;
}
yaml_emitter_set_output_file(&emitter, fout);
yaml_emitter_set_unicode(&emitter, true);
yaml_emitter_set_width(&emitter, -1);
if (!yaml_emitter_open(&emitter))
{
HandleYAMLEmitterError(&emitter);
yaml_emitter_delete(&emitter);
return false;
}
{ {
YAMLDocWriter docWriter(DNATypeV()); YAMLDocWriter docWriter(DNATypeV());
yaml_emitter_set_output_file(docWriter.getEmitter(), fout);
yaml_emitter_set_unicode(docWriter.getEmitter(), true);
yaml_emitter_set_width(docWriter.getEmitter(), -1);
if (!docWriter.open())
return false;
write(docWriter); write(docWriter);
if (!docWriter.finish(&emitter)) if (!docWriter.finish())
{
yaml_emitter_delete(&emitter);
return false; return false;
} docWriter.close();
}
if (!yaml_emitter_close(&emitter) ||
!yaml_emitter_flush(&emitter))
{
HandleYAMLEmitterError(&emitter);
yaml_emitter_delete(&emitter);
return false;
}
yaml_emitter_delete(&emitter);
return true; return true;
} }
bool fromYAMLFile(FILE* fin) bool fromYAMLFile(FILE* fin)
{ {
yaml_parser_t parser;
if (!yaml_parser_initialize(&parser))
{
HandleYAMLParserError(&parser);
return false;
}
yaml_parser_set_input_file(&parser, fin);
YAMLDocReader docReader; YAMLDocReader docReader;
if (!docReader.read(&parser)) yaml_parser_set_input_file(docReader.getParser(), fin);
{ if (!docReader.parse())
yaml_parser_delete(&parser);
return false; return false;
}
read(docReader); read(docReader);
yaml_parser_delete(&parser);
return true; return true;
} }

View File

@ -93,12 +93,12 @@ static inline void InsertNode(std::vector<YAMLNode*>& nodeStack,
} }
} }
std::unique_ptr<YAMLNode> YAMLDocReader::ParseEvents(yaml_parser_t* doc) std::unique_ptr<YAMLNode> YAMLDocReader::ParseEvents()
{ {
yaml_event_t event; yaml_event_t event;
if (!yaml_parser_parse(doc, &event)) if (!yaml_parser_parse(&m_parser, &event))
{ {
HandleYAMLParserError(doc); HandleYAMLParserError(&m_parser);
return std::unique_ptr<YAMLNode>(); return std::unique_ptr<YAMLNode>();
} }
@ -106,13 +106,13 @@ std::unique_ptr<YAMLNode> YAMLDocReader::ParseEvents(yaml_parser_t* doc)
std::unique_ptr<YAMLNode> mapKey; std::unique_ptr<YAMLNode> mapKey;
std::unique_ptr<YAMLNode> retVal; std::unique_ptr<YAMLNode> retVal;
int result; int result;
for (result = yaml_parser_parse(doc, &event); for (result = yaml_parser_parse(&m_parser, &event);
event.type != YAML_STREAM_END_EVENT; event.type != YAML_STREAM_END_EVENT;
result = yaml_parser_parse(doc, &event)) result = yaml_parser_parse(&m_parser, &event))
{ {
if (!result) if (!result)
{ {
HandleYAMLParserError(doc); HandleYAMLParserError(&m_parser);
return std::unique_ptr<YAMLNode>(); return std::unique_ptr<YAMLNode>();
} }
switch (event.type) switch (event.type)