summaryrefslogtreecommitdiff
path: root/examples/cxx/tree/streaming/grammar-input-stream.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'examples/cxx/tree/streaming/grammar-input-stream.cxx')
-rw-r--r--examples/cxx/tree/streaming/grammar-input-stream.cxx96
1 files changed, 96 insertions, 0 deletions
diff --git a/examples/cxx/tree/streaming/grammar-input-stream.cxx b/examples/cxx/tree/streaming/grammar-input-stream.cxx
new file mode 100644
index 0000000..ffdb5b4
--- /dev/null
+++ b/examples/cxx/tree/streaming/grammar-input-stream.cxx
@@ -0,0 +1,96 @@
+// file : examples/cxx/tree/streaming/grammar-input-stream.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+#include <cassert>
+#include "grammar-input-stream.hxx"
+
+grammar_input_stream::
+grammar_input_stream (const XMLByte* data, std::size_t size)
+ : data_ (data),
+ size_ (size),
+ pos_ (0),
+ vpos_ (0),
+ cseq_ (0),
+ add_zero_ (false)
+{
+}
+
+XMLFilePos grammar_input_stream::
+curPos () const
+{
+ return static_cast<XMLFilePos> (vpos_);
+}
+
+XMLSize_t grammar_input_stream::
+readBytes (XMLByte* const buf, const XMLSize_t size)
+{
+ std::size_t i (0);
+
+ // Add a zero from the alternating sequence if it didn't
+ // fit on the previous read.
+ //
+ if (add_zero_)
+ {
+ buf[i++] = 0;
+ add_zero_ = false;
+ }
+
+ // If have an unfinished sequential sequence, output it now.
+ //
+ if (cseq_ != 0 && !alt_)
+ {
+ for (; cseq_ != 0 && i < size; --cseq_)
+ buf[i++] = 0;
+ }
+
+ for (; i < size && pos_ < size_;)
+ {
+ XMLByte b = buf[i++] = data_[pos_++];
+
+ // See if we are in a compression sequence.
+ //
+ if (cseq_ != 0)
+ {
+ if (i < size)
+ buf[i++] = 0;
+ else
+ add_zero_ = true; // Add it on the next read.
+
+ cseq_--;
+ continue;
+ }
+
+ // If we are not in a compression sequence and this byte is
+ // not zero then we are done.
+ //
+ if (b != 0)
+ continue;
+
+ // We have a zero.
+ //
+ assert (pos_ < size_); // There has to be another byte.
+ unsigned char v (static_cast<unsigned char> (data_[pos_++]));
+ alt_ = (v & 128) != 0;
+ cseq_ = v & 127;
+
+ // If it is a sequential sequence, output as many zeros as
+ // we can.
+ //
+ if (!alt_)
+ {
+ for (; cseq_ != 0 && i < size; --cseq_)
+ buf[i++] = 0;
+ }
+ }
+
+ vpos_ += i;
+
+ return static_cast<XMLSize_t> (i);
+}
+
+const XMLCh* grammar_input_stream::
+getContentType () const
+{
+ return 0;
+}