--- a/src/XMLDocumentConstructor.h Sat Mar 13 19:28:13 2021 +0100
+++ b/src/XMLDocumentConstructor.h Sun Mar 14 19:58:35 2021 +0100
@@ -42,6 +42,7 @@
relpipe::in::asn1::lib::BasicASN1Reader reader;
reader.write(nullptr, 0); // FIXME: transfer data from input to reader + use DOMBuildingSAXContentHandler
+ reader.close();
parser->parse_stream(*input);
}
--- a/src/lib/AbstractParser.cpp Sat Mar 13 19:28:13 2021 +0100
+++ b/src/lib/AbstractParser.cpp Sun Mar 14 19:58:35 2021 +0100
@@ -55,6 +55,9 @@
}
}
+void AbstractParser::close() {
+}
+
void AbstractParser::rollback() {
// FIXME: store content of the current buffer + update pointers and positions
// TODO: notify rollback listeners? (they can monitor the performance / frequency of rollbacks)
--- a/src/lib/AbstractParser.h Sat Mar 13 19:28:13 2021 +0100
+++ b/src/lib/AbstractParser.h Sun Mar 14 19:58:35 2021 +0100
@@ -25,14 +25,41 @@
class AbstractParserImpl;
+/**
+ * Event-driven parser that consumes sequence of byte buffers (chunked stream)
+ * and produces some output (implementation specific).
+ *
+ * The flow is controlled from outside: incomming data pieces are passed to the parser through the write() method as they come.
+ *
+ * From the child class perspective (implementation of particular parser)
+ * data pieces are obtained through the read() method from the internal buffer maintained by AbstractParser.
+ */
class AbstractParser {
private:
friend AbstractParserImpl;
AbstractParserImpl* implementation;
+ void rollback();
public:
virtual ~AbstractParser();
+
+ /**
+ * Submit a part of incomming data to the parser.
+ * When possible, such data are usually processed synchronously during this method call.
+ * If not (incomplete TLV/AVP/PDU/token/etc.) this part is appended to the internal buffer maintained by AbstractParser
+ * and processed in some next cycle or – in worst case – during the close() call.
+ *
+ * @param buffer readable memory
+ * @param length size of the buffer
+ */
void write(const char* buffer, const size_t length);
- void rollback();
+
+ /**
+ * Finalize the parsing process.
+ * After calling this method, all data from AbstractParser buffers should be consumed, parsed and results published.
+ * No write() call is expected after close() and would fail.
+ * However the parser object remains valid and may be used to get some auxiliary information (if supperted by given implementation).
+ */
+ void close();
protected:
AbstractParser();
@@ -66,21 +93,31 @@
void commit();
/**
+ * Fill the buffer with incomming data of given length (exactly).
*
- * @param buffer
- * @param length
+ * If there are not enough data available, ReadBufferUnderflowException is thrown.
+ * This exception should not be caught in the child class – it should propagate back to the AbstractParser
+ * where it causes rollback(). In such case, the same data will be available during next update() cycle.
+ *
+ * @param buffer writable memory
+ * @param length size of the buffer
*/
void read(char* buffer, const size_t length);
/**
+ * Like read(), but does not update the marks (buffer positions), so it can be called again and again with same result.
*
- * @param buffer
- * @param length
+ * @param buffer writable memory
+ * @param length size of the buffer
*/
void peek(char* buffer, const size_t length);
/**
- *
+ * Reads input from buffers using read(), parses data and usually emits the result (e.g. to a handler/listener).
+ * Is specific for particular format/parser.
+ *
+ * This method is called at least once at the end of the stream (with whole stream content in read buffers).
+ * Usually it is called more often, by default: after each write (with just already received data part in read buffers).
*/
virtual void update() = 0;
};