- }
-
- private function countMessages($from = 0)
- {
- $this->messages =& $this->readMessages(array($from), true, true);
- return count($this->messages);
- }
-
- /** Read the current message (identified by current_id)
- * @param needFrom_ BOOLEAN is true if the first line *must* be a From_ line
- * @param alignNext BOOLEAN is true if the buffer must be aligned at the beginning of the next From_ line
- * @return message sources (without storage data)
- */
- private function &readCurrentMessage($stripBody = false, $needFrom_ = true, $alignNext = true)
- {
- $file_cache =& $this->file_cache;
- if ($file_cache && $file_cache != ftell($this->file)) {
- $file_cache = null;
- }
- $msg = array();
- $canFrom_ = false;
- $inBody = false;
- while(!feof($this->file)) {
- // Process file cache
- if ($file_cache) { // this is a From_ line
- $needFrom_ = false;
- $this->at_beginning = false;
- $file_cache = null;
- continue;
- }
-
- // Read a line
- $line = rtrim(fgets($this->file), "\r\n");
-
- // Process From_ line
- if ($needFrom_ || !$msg || $canFrom_) {
- if (substr($line, 0, 5) == 'From ') { // this is a From_ line
- if ($needFrom_) {
- $needFrom = false;
- } elseif (!$msg) {
- continue;
- } else {
- $this->current_id++; // we are finally in the next message
- if ($alignNext) { // align the file pointer at the beginning of the new message
- $this->at_beginning = true;
- $file_cache = ftell($this->file);
- }
- break;
- }
- } elseif ($needFrom_) {
- return $msg;
- }
- }
-
- // Process non-From_ lines
- if (substr($line, 0, 6) == '>From ') { // remove inline From_ quotation
- $line = substr($line, 1);
- }
- if (!$stripBody || !$inBody) {
- $msg[] = $line; // add the line to the message source
- }
- $canFrom_ = empty($line); // check if next line can be a From_ line
- if ($canFrom_ && !$inBody && $stripBody) {
- $inBody = true;
- }
- $this->at_beginning = false;
- }
- if (!feof($this->file) && !$canFrom_) {
- $msg = array();
- }
- return $msg;
- }
-
- /** Read message with the given ids
- * @param ids ARRAY of ids to look for
- * @param strip BOOLEAN if true, only headers are retrieved
- * @param from BOOLEAN if true, process all messages from max(ids) to the end of the mbox
- * @return Array(Array('message' => message sources (or parsed message headers if $strip is true),
- * 'beginning' => offset of message beginning,
- * 'end' => offset of message end))
- */
- private function &readMessages(array $ids, $strip = false, $from = false)
- {
- if (!is_null($this->messages)) {
- return $this->messages;
- }
- sort($ids);
- $messages = array();
- while ((count($ids) || $from) && !feof($this->file)) {
- if (count($ids)) {
- $id = array_shift($ids);
- } else {
- $id++;
- }
- if ($id != $this->current_id || !$this->at_beginning) {
- if (!$this->goTo($id)) {
- continue;
- }
- }
- $beginning = ftell($this->file);
- $message =& $this->readCurrentMessage($strip, false);
- if ($strip) {
- $message =& BananaMimePart::parseHeaders($message);
- }
- $end = ftell($this->file);
- $messages[$id] = array('message' => $message, 'beginning' => $beginning, 'end' => $end);