/** * Return the message headers. * * @return Horde_Mime_Headers The header object. */ public function getHeaders() { if (!empty($this->_header_text)) { $hdr_text = $this->_header_text; } else { $this->_stream->rewind(); $hdr_text = $this->_stream->substring(0, $this->_hdr_pos); } return Horde_Mime_Headers::parseHeaders($hdr_text); }
/** * Find the location of the end of the header text. * * @return array 1st element: Header position, 2nd element: Length of * trailing EOL. */ protected function _findHeader() { $i = 0; while (!$this->_stream->eof()) { $data = $this->_stream->substring(0, 8192); $hdr_pos = strpos($data, "\r\n\r\n"); if ($hdr_pos !== false) { return array($hdr_pos + $i * 8192, 4); } $hdr_pos = strpos($data, "\n\n"); if ($hdr_pos !== false) { return array($hdr_pos + $i * 8192, 2); } $i++; } $this->_stream->end(); return array($this->_stream->pos(), 0); }
/** * @return mixed Either a string, boolean (true for open paren, false for * close paren/EOS), Horde_Stream object, or null. */ public function next() { $level = isset($this->_nextModify['level']) ? $this->_nextModify['level'] : null; /* Directly access stream here to drastically reduce the number of * getChar() calls we would have to make. */ $stream = $this->_stream->stream; do { $check_len = true; $in_quote = $text = $binary = false; while (($c = fgetc($stream)) !== false) { switch ($c) { case '\\': $text .= $in_quote ? fgetc($stream) : $c; break; case '"': if ($in_quote) { $check_len = false; break 2; } $in_quote = true; /* Set $text to non-false (could be empty string). */ $text = ''; break; default: if ($in_quote) { $text .= $c; break; } switch ($c) { case '(': ++$this->_level; $check_len = false; $text = true; break 3; case ')': if ($text === false) { --$this->_level; $check_len = $text = false; } else { $this->_stream->seek(-1); } break 3; case '~': // Ignore binary string identifier. PHP strings are // binary-safe. But keep it if it is not used as string // identifier. $binary = true; $text .= $c; continue; case '{': if ($binary) { $text = substr($text, 0, -1); } $literal_len = intval($this->_stream->getToChar('}')); $pos = $this->_stream->pos(); if (isset($this->_literals[$pos])) { $text = $this->_literals[$pos]; if (!$this->_literalStream) { $text = strval($text); } } elseif ($this->_literalStream) { $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 = $this->_stream->substring(0, $literal_len); } $check_len = false; break 3; case ' ': if ($text !== false) { break 3; } break; default: $text .= $c; break; } break; } $binary = false; } if ($check_len) { switch (strlen($text)) { case 0: $text = false; break; case 3: if (strcasecmp($text, 'NIL') === 0) { $text = null; } break; } } if ($text === false && feof($stream)) { $this->_key = $this->_level = false; break; } ++$this->_key; if (is_null($level) || $level > $this->_level) { break; } if ($level === $this->_level && !is_bool($text)) { $this->_nextModify['out'][] = $text; } } while (true); $this->_current = $text; return $text; }
/** * @return mixed Either a string, boolean (true for open paren, false for * close paren/EOS), or null. */ public function next() { $level = isset($this->_nextModify['level']) ? $this->_nextModify['level'] : null; /* Directly access stream here to drastically reduce the number of * getChar() calls we would have to make. */ $stream = $this->_stream->stream; do { $check_len = true; $in_quote = $text = false; while (($c = fgetc($stream)) !== false) { switch ($c) { case '\\': $text .= $in_quote ? fgetc($stream) : $c; break; case '"': if ($in_quote) { $check_len = false; break 2; } $in_quote = true; /* Set $text to non-false (could be empty string). */ $text = ''; break; default: if ($in_quote) { $text .= $c; break; } switch ($c) { case '(': ++$this->_level; $check_len = false; $text = true; break 3; case ')': if ($text === false) { --$this->_level; $check_len = $text = false; } else { $this->_stream->seek(-1); } break 3; case '~': // Ignore binary string identifier. PHP strings are // binary-safe. break; case '{': $text = $this->_stream->substring(0, intval($this->_stream->getToChar('}'))); $check_len = false; break 3; case ' ': if ($text !== false) { break 3; } break; default: $text .= $c; break; } break; } } if ($check_len) { switch (strlen($text)) { case 0: $text = false; break; case 3: if ($text === 'NIL' || strcasecmp($text, 'NIL') === 0) { $text = null; } break; } } if ($text === false && feof($stream)) { $this->_key = $this->_level = false; break; } ++$this->_key; if (is_null($level) || $level > $this->_level) { break; } if ($level === $this->_level && !is_bool($text)) { $this->_nextModify['out'][] = $text; } } while (true); $this->_current = $text; return $text; }