From 35e5ad4fe0650ffa7c679c7447eeb34a703133f4 Mon Sep 17 00:00:00 2001 From: Michael M Slusarz Date: Tue, 5 May 2015 18:33:11 -0600 Subject: [PATCH] [mms] Directly store literal data in a separate stream when parsing IMAP tokens, so we don't have to duplicate the stream later when processing it. --- .../Imap/Client/Socket/Connection/Socket.php | 2 +- .../lib/Horde/Imap/Client/Tokenize.php | 52 +++++++++++++++---- framework/Imap_Client/package.xml | 2 + 3 files changed, 44 insertions(+), 12 deletions(-) diff --git a/framework/Imap_Client/lib/Horde/Imap/Client/Socket/Connection/Socket.php b/framework/Imap_Client/lib/Horde/Imap/Client/Socket/Connection/Socket.php index a8f885772b6..b700fd2ffbf 100644 --- a/framework/Imap_Client/lib/Horde/Imap/Client/Socket/Connection/Socket.php +++ b/framework/Imap_Client/lib/Horde/Imap/Client/Socket/Connection/Socket.php @@ -185,7 +185,7 @@ public function read($size = null) while (($literal_len > 0) && !feof($this->_stream)) { $in = fread($this->_stream, min($literal_len, 8192)); - $token->add($in); + $token->addLiteralStream($in); if (!empty($this->_params['debugliteral'])) { $this->_params['debug']->raw($in); } diff --git a/framework/Imap_Client/lib/Horde/Imap/Client/Tokenize.php b/framework/Imap_Client/lib/Horde/Imap/Client/Tokenize.php index 8d07e420680..4600c36fc1f 100644 --- a/framework/Imap_Client/lib/Horde/Imap/Client/Tokenize.php +++ b/framework/Imap_Client/lib/Horde/Imap/Client/Tokenize.php @@ -62,6 +62,13 @@ class Horde_Imap_Client_Tokenize implements Iterator */ protected $_level = false; + /** + * Array of literal stream objects. + * + * @var array + */ + protected $_literals = array(); + /** * next() modifiers. * @@ -136,6 +143,21 @@ public function add($data) $this->_stream->add($data); } + /** + * Add data to literal stream at the current position. + * + * @param mixed $data Data to add (string, resource, or Horde_Stream + * object). + */ + public function addLiteralStream($data) + { + $pos = $this->_stream->pos(); + if (!isset($this->_literals[$pos])) { + $this->_literals[$pos] = new Horde_Stream_Temp(); + } + $this->_literals[$pos]->add($data); + } + /** * Flush the remaining entries left in the iterator. * @@ -279,18 +301,26 @@ public function next() case '{': $literal_len = intval($this->_stream->getToChar('}')); - if ($this->literalStream && - ($literal_len > self::MIN_LITERAL_STREAM)) { - $text = new Horde_Stream_Temp(); - while (($literal_len > 0) && !feof($stream)) { - $part = $this->_stream->substring( - 0, - min($literal_len, 8192) - ); - $text->add($part); - $literal_len -= strlen($part); + if ($this->literalStream) { + $pos = $this->_stream->pos(); + if (isset($this->_literals[$pos])) { + $text = $this->_literals[$pos]; + } elseif ($literal_len > self::MIN_LITERAL_STREAM) { + $text = new Horde_Stream_Temp(); + while (($literal_len > 0) && !feof($stream)) { + $part = $this->_stream->substring( + 0, + min($literal_len, 8192) + ); + $text->add($part); + $literal_len -= strlen($part); + } + } else { + $text = false; } - } else { + } + + if ($text === false) { $text = $this->_stream->substring(0, $literal_len); } $check_len = false; diff --git a/framework/Imap_Client/package.xml b/framework/Imap_Client/package.xml index 06f36f862a1..7fa0fc5b4e3 100644 --- a/framework/Imap_Client/package.xml +++ b/framework/Imap_Client/package.xml @@ -21,6 +21,7 @@ LGPL-2.1 +* [mms] Directly store literal data in a separate stream when parsing IMAP tokens, so we don't have to duplicate the stream later when processing it. * [mms] Don't load literal IMAP data into a string variable when tokenizing IMAP input. * [mms] Fix search queries where ID list given is explicitly empty, indicating that a match can never be successful (Bug #13971). * [mms] Fix expunging in certain cases when UIDPLUS is not available (Bug #13970; Robin McCorkell <rmccorkell@karoshi.org.uk>). @@ -2876,6 +2877,7 @@ 2015-04-27 LGPL-2.1 +* [mms] Directly store literal data in a separate stream when parsing IMAP tokens, so we don't have to duplicate the stream later when processing it. * [mms] Don't load literal IMAP data into a string variable when tokenizing IMAP input. * [mms] Fix search queries where ID list given is explicitly empty, indicating that a match can never be successful (Bug #13971). * [mms] Fix expunging in certain cases when UIDPLUS is not available (Bug #13970; Robin McCorkell <rmccorkell@karoshi.org.uk>).