14 * You should have received a copy of the GNU General Public License |
14 * You should have received a copy of the GNU General Public License |
15 * along with this program. If not, see <http://www.gnu.org/licenses/>. |
15 * along with this program. If not, see <http://www.gnu.org/licenses/>. |
16 */ |
16 */ |
17 |
17 |
18 #include "AbstractParser.h" |
18 #include "AbstractParser.h" |
|
19 #include "TransactionalBuffer.h" |
19 |
20 |
20 namespace relpipe { |
21 namespace relpipe { |
21 namespace in { |
22 namespace in { |
22 namespace asn1 { |
23 namespace asn1 { |
23 namespace lib { |
24 namespace lib { |
24 |
25 |
25 class AbstractParserImpl { |
26 class AbstractParserImpl { |
26 private: |
27 private: |
|
28 friend AbstractParser; |
27 AbstractParser* interface; |
29 AbstractParser* interface; |
|
30 TransactionalBuffer buffer; |
28 public: |
31 public: |
29 |
32 |
30 AbstractParserImpl(AbstractParser* interface) : interface(interface) { |
33 AbstractParserImpl(AbstractParser* interface) : interface(interface) { |
31 } |
34 } |
32 |
35 |
41 AbstractParser::~AbstractParser() { |
44 AbstractParser::~AbstractParser() { |
42 delete implementation; |
45 delete implementation; |
43 } |
46 } |
44 |
47 |
45 void AbstractParser::write(const char* buffer, const size_t length) { |
48 void AbstractParser::write(const char* buffer, const size_t length) { |
46 // TODO: update pointers and positions |
|
47 try { |
49 try { |
|
50 // TODO: do not write to the buffer, just append in read()/peek() and write just the part that was not read during this cycle |
|
51 implementation->buffer.write(buffer, length); |
|
52 |
48 // TODO: call an overridable method to get preferred minimum block size and run cycle only if we have enough data or EOF |
53 // TODO: call an overridable method to get preferred minimum block size and run cycle only if we have enough data or EOF |
|
54 // and/or remember the length of last failed (rollbacked) read() call |
49 update(); |
55 update(); |
50 commit(); |
56 commit(); |
51 } catch (const AbstractParser::ReadBufferUnderflowException& e) { |
57 } catch (const TransactionalBuffer::ReadBufferUnderflowException& e) { |
52 rollback(); |
58 rollback(); |
53 } catch (const AbstractParser::ExplicitRollbackException& e) { |
59 } catch (const AbstractParser::ExplicitRollbackException& e) { |
54 rollback(); |
60 rollback(); |
55 } |
61 } |
56 } |
62 } |
57 |
63 |
58 void AbstractParser::close() { |
64 void AbstractParser::close() { |
|
65 // TODO: check remaining data + call update() or just let parsers override this method? |
59 } |
66 } |
60 |
67 |
61 void AbstractParser::rollback() { |
68 void AbstractParser::rollback() { |
62 // FIXME: store content of the current buffer + update pointers and positions |
|
63 // TODO: notify rollback listeners? (they can monitor the performance / frequency of rollbacks) |
69 // TODO: notify rollback listeners? (they can monitor the performance / frequency of rollbacks) |
|
70 implementation->buffer.rollbackRead(); |
64 } |
71 } |
65 |
72 |
66 void AbstractParser::commit() { |
73 void AbstractParser::commit() { |
|
74 implementation->buffer.commitRead(); |
67 } |
75 } |
68 |
76 |
69 void AbstractParser::read(char* buffer, const size_t length) { |
77 void AbstractParser::read(char* buffer, const size_t length) { |
|
78 implementation->buffer.read(buffer, length); |
70 } |
79 } |
71 |
80 |
72 void AbstractParser::peek(char* buffer, const size_t length) { |
81 void AbstractParser::peek(char* buffer, const size_t length) { |
|
82 implementation->buffer.read(buffer, length); |
73 } |
83 } |
74 |
84 |
75 } |
85 } |
76 } |
86 } |
77 } |
87 } |