#ifndef __StreamReader_h__ #define __StreamReader_h__ #include "MString.h" namespace coreutils { /// /// StreamReader accumulates data delivered in arbitrary-sized chunks (e.g. from /// core::Socket::onDataReceived) into one continuous, growable buffer, and exposes /// it to a chain of Parser objects so they can build higher-level protocol objects /// (a header, a line, a MIME part, etc.) without needing to worry about where one /// network packet ended and the next began - a "complete" unit may span any number /// of feed() calls. /// /// Parsers consume data through the ZString-style cursor on getBuffer(). Once a /// Parser has fully consumed a unit (advanced the cursor past it), call compact() /// to drop the already-parsed prefix so the buffer doesn't grow unboundedly for the /// life of a long-running connection. /// class StreamReader { public: StreamReader(); /// /// Append newly-arrived data to the end of the buffer. Does not affect the /// cursor - existing parse position is preserved across a feed(). /// void feed(ZString &data); /// /// The accumulated buffer Parsers read from and advance the cursor over. /// MString &getBuffer(); /// /// Drop the already-parsed prefix (everything before the cursor) and reset /// the cursor to the new start of the buffer. Call this once a Parser has /// completed a unit and before waiting for more data, so the buffer only /// ever grows by the amount of not-yet-parsed data. /// void compact(); /// /// True if there is unparsed data currently sitting in the buffer that a /// Parser hasn't consumed yet (i.e. more progress may be possible without /// waiting for the next feed()). /// bool hasUnparsedData(); private: MString buffer; }; } #endif