123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254 |
- <?php
- namespace PHPHtmlParser;
- /**
- * Class Content
- *
- * @package PHPHtmlParser
- */
- class Content
- {
- /**
- * The content string.
- *
- * @var string
- */
- protected $content;
- /**
- * The size of the content.
- *
- * @var integer
- */
- protected $size;
- /**
- * The current position we are in the content.
- *
- * @var integer
- */
- protected $pos;
- /**
- * The following 4 strings are tags that are important to us.
- *
- * @var string
- */
- protected $blank = " \t\r\n";
- protected $equal = ' =/>';
- protected $slash = " />\r\n\t";
- protected $attr = ' >';
- /**
- * Content constructor.
- *
- * @param string $content
- */
- public function __construct(string $content = '')
- {
- $this->content = $content;
- $this->size = strlen($content);
- $this->pos = 0;
- }
- /**
- * Returns the current position of the content.
- *
- * @return int
- */
- public function getPosition(): int
- {
- return $this->pos;
- }
- /**
- * Gets the current character we are at.
- *
- * @param int $char
- * @return string
- */
- public function char(int $char = null): string
- {
- $pos = $this->pos;
- if ( ! is_null($char)) {
- $pos = $char;
- }
- if ( ! isset($this->content[$pos])) {
- return '';
- }
- return $this->content[$pos];
- }
- /**
- * Moves the current position forward.
- *
- * @param int $count
- * @return Content
- * @chainable
- */
- public function fastForward(int $count): Content
- {
- $this->pos += $count;
- return $this;
- }
- /**
- * Moves the current position backward.
- *
- * @param int $count
- * @return Content
- * @chainable
- */
- public function rewind(int $count): Content
- {
- $this->pos -= $count;
- if ($this->pos < 0) {
- $this->pos = 0;
- }
- return $this;
- }
- /**
- * Copy the content until we find the given string.
- *
- * @param string $string
- * @param bool $char
- * @param bool $escape
- * @return string
- */
- public function copyUntil(string $string, bool $char = false, bool $escape = false): string
- {
- if ($this->pos >= $this->size) {
- // nothing left
- return '';
- }
- if ($escape) {
- $position = $this->pos;
- $found = false;
- while ( ! $found) {
- $position = strpos($this->content, $string, $position);
- if ($position === false) {
- // reached the end
- $found = true;
- continue;
- }
- if ($this->char($position - 1) == '\\') {
- // this character is escaped
- ++$position;
- continue;
- }
- $found = true;
- }
- } elseif ($char) {
- $position = strcspn($this->content, $string, $this->pos);
- $position += $this->pos;
- } else {
- $position = strpos($this->content, $string, $this->pos);
- }
- if ($position === false) {
- // could not find character, just return the remaining of the content
- $return = substr($this->content, $this->pos, $this->size - $this->pos);
- $this->pos = $this->size;
- return $return;
- }
- if ($position == $this->pos) {
- // we are at the right place
- return '';
- }
- $return = substr($this->content, $this->pos, $position - $this->pos);
- // set the new position
- $this->pos = $position;
- return $return;
- }
- /**
- * Copies the content until the string is found and return it
- * unless the 'unless' is found in the substring.
- *
- * @param string $string
- * @param string $unless
- * @return string
- */
- public function copyUntilUnless(string $string, string $unless)
- {
- $lastPos = $this->pos;
- $this->fastForward(1);
- $foundString = $this->copyUntil($string, true, true);
- $position = strcspn($foundString, $unless);
- if ($position == strlen($foundString)) {
- return $string.$foundString;
- }
- // rewind changes and return nothing
- $this->pos = $lastPos;
- return '';
- }
- /**
- * Copies the content until it reaches the token string.,
- *
- * @param string $token
- * @param bool $char
- * @param bool $escape
- * @return string
- * @uses $this->copyUntil()
- */
- public function copyByToken(string $token, bool $char = false, bool $escape = false)
- {
- $string = $this->$token;
- return $this->copyUntil($string, $char, $escape);
- }
- /**
- * Skip a given set of characters.
- *
- * @param string $string
- * @param bool $copy
- * @return Content|string
- */
- public function skip(string $string, bool $copy = false)
- {
- $len = strspn($this->content, $string, $this->pos);
- // make it chainable if they don't want a copy
- $return = $this;
- if ($copy) {
- $return = substr($this->content, $this->pos, $len);
- }
- // update the position
- $this->pos += $len;
- return $return;
- }
- /**
- * Skip a given token of pre-defined characters.
- *
- * @param string $token
- * @param bool $copy
- * @return Content|string
- * @uses $this->skip()
- */
- public function skipByToken(string $token, bool $copy = false)
- {
- $string = $this->$token;
- return $this->skip($string, $copy);
- }
- }
|