summaryrefslogtreecommitdiffstats
path: root/vendor/gipfl/protocol-netstring/src/StreamWrapper.php
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/gipfl/protocol-netstring/src/StreamWrapper.php')
-rw-r--r--vendor/gipfl/protocol-netstring/src/StreamWrapper.php113
1 files changed, 113 insertions, 0 deletions
diff --git a/vendor/gipfl/protocol-netstring/src/StreamWrapper.php b/vendor/gipfl/protocol-netstring/src/StreamWrapper.php
new file mode 100644
index 0000000..b23b909
--- /dev/null
+++ b/vendor/gipfl/protocol-netstring/src/StreamWrapper.php
@@ -0,0 +1,113 @@
+<?php
+
+namespace gipfl\Protocol\NetString;
+
+use gipfl\Protocol\Exception\ProtocolError;
+use gipfl\Protocol\Generic\AbstractStreamWrapper;
+
+class StreamWrapper extends AbstractStreamWrapper
+{
+ protected $buffer = '';
+ protected $bufferLength = 0;
+ protected $bufferOffset = 0;
+ protected $expectedLength;
+
+ public function close()
+ {
+ // We might want to complain when buffer is not empty
+ $this->buffer = '';
+ $this->bufferLength = 0;
+ $this->bufferOffset = 0;
+ $this->expectedLength = null;
+ parent::close();
+ }
+
+ /**
+ * @param $data
+ */
+ public function handleData($data)
+ {
+ $this->buffer .= $data;
+ $this->bufferLength += \strlen($data);
+ while ($this->bufferHasPacket()) {
+ $this->processNextPacket();
+
+ if ($this->bufferOffset !== 0) {
+ $this->buffer = \substr($this->buffer, $this->bufferOffset);
+ $this->bufferOffset = 0;
+ $this->bufferLength = \strlen($this->buffer);
+ }
+ }
+ }
+
+ public function write($data)
+ {
+ return $this->output->write(strlen($data) . ':' . $data . ',');
+ }
+
+ public function end($data = null)
+ {
+ if ($data !== null) {
+ $this->write($data);
+ }
+
+ $this->output->end();
+ }
+
+ /**
+ * @return bool
+ */
+ protected function bufferHasPacket()
+ {
+ if ($this->expectedLength === null) {
+ if (false !== ($pos = \strpos(\substr($this->buffer, $this->bufferOffset, 10), ':'))) {
+ $lengthString = \ltrim(\substr($this->buffer, $this->bufferOffset, $pos), ',');
+ if (! \ctype_digit($lengthString)) {
+ $this->emit('error', [
+ new ProtocolError("Invalid length $lengthString")
+ ]);
+ $this->close();
+
+ return false;
+ }
+ $this->expectedLength = (int) $lengthString;
+ $this->bufferOffset = $pos + 1;
+ } elseif ($this->bufferLength > ($this->bufferOffset + 10)) {
+ $this->throwInvalidBuffer();
+ $this->close();
+
+ return false;
+ } else {
+ return false;
+ }
+ }
+
+ return $this->bufferLength > ($this->bufferOffset + $this->expectedLength);
+ }
+
+ protected function processNextPacket()
+ {
+ $packet = \substr($this->buffer, $this->bufferOffset, $this->expectedLength);
+
+ $this->bufferOffset = $this->bufferOffset + $this->expectedLength;
+ $this->expectedLength = null;
+
+ $this->emit('data', [$packet]);
+ }
+
+ protected function throwInvalidBuffer()
+ {
+ $len = \strlen($this->buffer);
+ if ($len < 200) {
+ $debug = $this->buffer;
+ } else {
+ $debug = \substr($this->buffer, 0, 100)
+ . \sprintf('[..] truncated %d bytes [..] ', $len)
+ . \substr($this->buffer, -100);
+ }
+
+ $this->emit('error', [
+ new ProtocolError("Got invalid NetString data: $debug")
+ ]);
+ }
+}