#ifndef __Parser_h__ #define __Parser_h__ #include "StreamReader.h" namespace coreutils { /// /// Parser is the base class for building a protocol/object parser that reads /// from a shared StreamReader's buffer. A subclass implements parse() as a /// resumable state machine (typically a switch on an internal state member) /// that consumes as much of the buffer as it currently can and reports how /// the parse should proceed via Status: /// /// - COMPLETE: the object this Parser builds is fully parsed and ready. /// - INCOMPLETE: not enough data is currently buffered to make more /// progress; the caller should wait for more data /// (StreamReader::feed()) before calling doParse() again. /// The subclass's state member must reflect exactly where /// parsing should resume - and must NOT have consumed any /// cursor position it can't yet commit to (see individual /// Parser subclasses for how they guarantee this). /// - DATA_AVAIL: this call made progress and there is more buffered data /// this Parser can still work through right now, without /// waiting for new data to arrive. /// /// Call doParse() (not parse() directly) to drive a Parser - it loops on /// DATA_AVAIL automatically and returns once the result is COMPLETE or /// INCOMPLETE. /// class Parser { public: Parser(StreamReader &reader); enum class Status { COMPLETE, INCOMPLETE, DATA_AVAIL }; virtual ~Parser(); /// /// doParse is the entry and re-entry point method to continue the /// parsing process. Safe to call repeatedly (e.g. once per /// StreamReader::feed()) - each call resumes exactly where the /// previous one left off. /// Status doParse(); /// /// Inside of parse() you can call another parser object with the /// checkParse method to attempt parsing with a candidate sub-parser /// sharing the same StreamReader. Returns true only once that /// sub-parser fully completes - retain the same sub-parser instance /// across re-entries into your own parse() (e.g. as a member) so it /// can resume, rather than constructing a new one on every call. /// bool checkParse(Parser &parser); protected: /// /// parse() performs one resumable step of parsing against reader's /// buffer. Must be implemented by every concrete Parser to build its /// specific object. /// virtual Status parse() = 0; StreamReader &reader; }; } #endif