Beispiel #1
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;
 }
Beispiel #2
0
 /**
  * @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;
 }