summaryrefslogtreecommitdiff
path: root/zend/streambuf.cpp
diff options
context:
space:
mode:
authorEmiel Bruijntjes <emiel.bruijntjes@copernica.com>2014-04-06 21:53:24 +0200
committerEmiel Bruijntjes <emiel.bruijntjes@copernica.com>2014-04-06 21:53:24 +0200
commit35fd3ccbeb4def71b4d8a59dfbb5c31201b099b9 (patch)
tree915223360aed4743aa6127fde4836aa413a260e5 /zend/streambuf.cpp
parentda4710512865e6816585ac4ab8edab2fa125e2d8 (diff)
renamed src directory to zend directory, disabled TSRM debug code
Diffstat (limited to 'zend/streambuf.cpp')
-rw-r--r--zend/streambuf.cpp93
1 files changed, 93 insertions, 0 deletions
diff --git a/zend/streambuf.cpp b/zend/streambuf.cpp
new file mode 100644
index 0000000..e258b4e
--- /dev/null
+++ b/zend/streambuf.cpp
@@ -0,0 +1,93 @@
+/**
+ * StreamBuf.cpp
+ *
+ * Implementation file for the StreamBuf class
+ *
+ * @see http://www.mr-edd.co.uk/blog/beginners_guide_streambuf
+ *
+ * @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
+ * @copyright 2014 Copernica BV
+ */
+#include "includes.h"
+
+/**
+ * Set up namespace
+ */
+namespace Php {
+
+/**
+ * Constructor
+ * @param error
+ */
+StreamBuf::StreamBuf(int error) : _error(error)
+{
+ // we reserve one byte, so that when overflow is called, we still have one
+ // byte extra in the buffer to put the overflowed byte int
+ setp(_buffer, _buffer+1024-1);
+}
+
+
+/**
+ * Method that is called when the internal buffer overflows
+ * @param c
+ * @return int
+ */
+int StreamBuf::overflow(int c)
+{
+ // for error buffers, overflow is simply discarded
+ if (_error) return c;
+
+ // end-of-file has not output, we call EOF directly, and by using the
+ // comma operator we ensure that EOF is returned
+ if (c == EOF) return sync(), EOF;
+
+ // because we lied the underlying buffer about the size of the buffer
+ // by one byte, there is no real overflow, and we can still add the byte
+ // to the end of the buffer
+ *pptr() = c;
+
+ // increment buffer size
+ pbump(1);
+
+ // and now we're going to syn the buffer
+ return sync() == -1 ? EOF : c;
+}
+
+/**
+ * Called when the internal buffer should be synchronized
+ * @return int
+ */
+int StreamBuf::sync()
+{
+ // current buffer size
+ size_t size = pptr() - pbase();
+
+ // is this the error stream or the regular output stream?
+ if (_error)
+ {
+ // write to error (the zend_error() method is a varargs function,
+ // which means that we have to include a printf() like format as first
+ // parameter. We can not specify pbase() directly, because (1) it is
+ // not null terminated and (2) it could contain % signs and allow all
+ // sorts of buffer overflows.
+ zend_error(_error, "%.*s", (int)size, pbase());
+
+ }
+ else
+ {
+ // write to zend
+ zend_write(pbase(), size);
+ }
+
+ // reset the buffer
+ pbump(-size);
+
+ // done
+ return 0;
+}
+
+/**
+ * End namespace
+ */
+}
+ \ No newline at end of file