<!--#--------------------------------------------------------------------------
# This is the file where strStream class lives
# written by : Gyozo Papp @: hide@address.com, hide@address.com
# last modified : 2001.04.30
#--COPYRIGHT-------------------------------------------------------------------
# strStream is Copyright © by all of us (created by Gyozo Papp)
# Permission to use, copy, modify, and distribute this software and
# its documentation for any purpose, without fee, and without a written
# agreement is hereby granted, provided that the above copyright notice
# and this paragraph and the following two paragraphs appear in all copies.
#
# IN NO EVENT SHALL i BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL,
# INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS,
# ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION,
# EVEN IF i HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# i SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS-IS" BASIS,
# AND i HAS NO OBLIGATIONS TO PROVIDE MAINTAINANCE, SUPPORT, UPDATES,
# ENHANCEMENTS, OR MODIFICATIONS.
# BUT i LIKE TO VERY MUCH.
#--------------------------------------------------------------------------#-->
<?php
if (!defined("__strStream__")) {
define ("__strStream__", "1.0");
define ("S", "\n\t\v\r ");
define ("OPENBR", "<([{");
define ("CLOSEBR", ">)]}");
#--CONSTANTS for $mode----------
define ("FETCH", 0); # returning value(s) is NOT removed from the $buffer
define ("GET", 1); # returning value(s) IS removed from the $buffer
define ("TRUSTED", true);
#-----------------------------------------------------------------------------
#--CLASS strStream------------------------------------------------------------
class strStream
{
var $buffer = ''; # string buffer; $buffer (below) refer to it
var $normalised = false;# indicates whether the $buffer is normalised
var $delimited = ''; # indicates whether the the whitespaces are
# stripped around the characters product $delimited
#--STREAM initialization------------------------------------------------------
function strStream($str ='')
{
if (!empty($str)) $this->put($str);
return true;
}
# append new content (string $str) to the $buffer, indicators are cleared
function put($str)
{
if (empty($str)) return false;
$this->buffer .= $str;
$this->delimited = '';
$this->normalized = false;
return strlen($str);
}
# clears the $buffer and additional indicators
function done()
{
$this->buffer = '';
$this->normalised = false;
$this->delimited = '';
}
#--BUFFER status checking methods----------------------------------------------
# returns whether $internal count of character is in the $buffer or not
function enough($internal = 1)
{
return (strlen($this->buffer) >= $internal);
}
# returns true if $buffer is empty or no characters of $what is in $buffer
function eos($what, $whole = false )
{
if (!empty($what))
{ # find a word delimited by one of $dlmtrs
$what = $this->_quotemeta($what);
if (!$whole) $what = '['.$what.']';
if (!ereg($what, $this->buffer)) return true;
}# position of the opening bracket
return (empty($this->buffer));
}
#--DATA retrieving methods-----------------------------------------------------
# returns with $count pieces of characters from $buffer,
# or false if there's not enough characters
function getc($count = 1, $mode = GET)
{
if (!$this->enough($count)) return false;
if (FETCH == $mode)
return substr($this->buffer, 0, $count);
list($s1, $s2) = $this->_divide($count);
$this->buffer = $s2;
return $s1;
}
# returns with a 'word' enclosed by one of the $dlmtrs
# or false if no word found, this may signify the $buffer is empty
function getw($dlmtrs = S, $mode = GET, $skipquote = true)
{
if ($this->eos('')) return false;
# find a word delimited by one of $dlmtrs
$dlmtrs = $this->_quotemeta($dlmtrs);
$regexp = sprintf("([^%s]+)(.*)", $dlmtrs, $dlmtrs);
if (!ereg($regexp, $this->buffer, $regs)) return false;
if (GET == $mode) $this->buffer = $regs[2]; # content behind the word
return $regs[1]; # the word found
}
# returns with the largest subsequent 'block' from $buffer or false
# 'block' means charaters enclosed by a GIVEN pair of brackets, braces,
# parentheses, etc:<> () [] {}
function getp($op = "(", $mode = GET, $skipquote = true)
{
if ($this->eos($op)) return false;
$pos = strpos(OPENBR, $op);
if ($pos === false) return -1; # non-valid opening bracket
$cl = substr(CLOSEBR, $pos, 1); # the closing bracket
# position of the opening bracket
$pos = strpos($this->buffer, $op);
if ($pos === false) return false; # no opening tag found
for($i = $pos + 1, $level = 1; $level && $this->enough($i+1); $i++)
{
if ($skipquote && ("'" == $this->buffer[$i] || '"' == $this->buffer[$i]))
{# skips standalone quote too, no quote-balance checking
list( $d, $s) = $this->_divide($i+1);
$i += strpos($s, $this->buffer[$i]);
continue;
}
if ($op == $this->buffer[$i]) $level++; # opening bracket
else if ($cl == $this->buffer[$i]) $level--; # closing bracket
}
if ($level == 0) { # brackets balance OK
$skipped = ($pos ? $this->getc($pos, $mode): '');
# in GET $mode preceding string is popped above
if (GET == $mode) $i -= $pos;
$block = substr($this->getc($i, $mode), 1, $i-2);
return array($block, $skipped);
}
else return -2; # not balanced brackets, maybe false???
}
# returns with the first parenthesed 'block' from $buffer if possible
# otherwise false
# 'block' means charaters enclosed by ANY pair of brackets braces , etc
# (in default priority order) <> () [] {}, overridable by subset of OPENBR
function geta($ops = "<([{", $mode = GET, $skipquote = true)
{
for($i = 0; $i < strlen($ops); $i++)
{
$ret = $this->getp($ops[$i], $mode, $skipquote);
if (is_array($ret)) return array_push($ret, $ops[$i]) ;
if ($ret == -1) return -1;
}
}
function getb($op, $cl, $mode = GET)
{
if (empty($op) || empty($cl)) return -1; # not valid $tags specified
$regexp = sprintf("(.*)%s(.*)%s(.*)", $this->_quotemeta($op), $this->_quotemeta($cl));
if (ereg($regexp, $this->buffer, $regs))
{
if (GET == $mode) $this->buffer = $regs[3];
return array($regs[2], $regs[1]);
}
else return false;
}
# returns with the whole content of $buffer
function get($mode = GET)
{
if (FETCH == $mode) return $this->buffer;
$s = $this->buffer; $this->buffer = '';
return $s;
}
#--BUFFER manipulation methods-------------------------------------------------
# push $str at the beginnig of $buffer
# Setting $trusted indicates the $str is in the same state as $buffer
function unget($str, $trusted = false)
{
if (!$trusted)
{
$this->delimited = '';
$this->normalized = false;
}
$this->buffer = $str . $this->buffer;
return true;
}
# strips leading and trailing whitespace and
# replaces sequences of whitespace characters by a single space in $buffer
function normalize_space()
{
if (!$this->normalised)
{
$this->buffer = trim(ereg_replace(sprintf("[%s]+", S),' ',$this->buffer));
$this->normalised = true;
}
return $this->buffer;
}
# removes whitespaces around delimiters in $buffer
function strip_space($dlmtrs = "|,()?*+")
{
if ($this->delimited != $dlmtrs)
{
$dlmtrs = $this->_quotemeta($dlmtrs);
$regexp = sprintf("[%s]*([%s])[%s]*", S, $dlmtrs, S);
$this->buffer = trim(ereg_replace($regexp, "\\1", $this->buffer));
$this->delimited = $dlmtrs;
}
return $this->buffer;
}
#--PRIVATE funtions------------------------------------------------------------
# divides into 2 parts of buffer at the position $pos
function _divide($pos)
{
return array(substr($this->buffer, 0, $pos), substr($this->buffer, $pos));
}
# original quotemeta and add slash before '|', too
function _quotemeta($dlmtrs)
{
$dlmtrs = quotemeta($dlmtrs);
$dlmtrs = str_replace('|', '\\|', $dlmtrs);
return $dlmtrs;
}
}
#--INCLUDE ends----------------------------------------------------------------
}
?>