[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

Search

title

Body

[close]

/wp-includes/SimplePie/src/XML/Declaration/ -> Parser.php (source)

   1  <?php
   2  
   3  // SPDX-FileCopyrightText: 2004-2023 Ryan Parman, Sam Sneddon, Ryan McCue
   4  // SPDX-License-Identifier: BSD-3-Clause
   5  
   6  declare(strict_types=1);
   7  
   8  namespace SimplePie\XML\Declaration;
   9  
  10  /**
  11   * Parses the XML Declaration
  12   */
  13  class Parser
  14  {
  15      /**
  16       * XML Version
  17       *
  18       * @access public
  19       * @var string
  20       */
  21      public $version = '1.0';
  22  
  23      /**
  24       * Encoding
  25       *
  26       * @access public
  27       * @var string
  28       */
  29      public $encoding = 'UTF-8';
  30  
  31      /**
  32       * Standalone
  33       *
  34       * @access public
  35       * @var bool
  36       */
  37      public $standalone = false;
  38  
  39      private const STATE_BEFORE_VERSION_NAME = 'before_version_name';
  40  
  41      private const STATE_VERSION_NAME = 'version_name';
  42  
  43      private const STATE_VERSION_EQUALS = 'version_equals';
  44  
  45      private const STATE_VERSION_VALUE = 'version_value';
  46  
  47      private const STATE_ENCODING_NAME = 'encoding_name';
  48  
  49      private const STATE_EMIT = 'emit';
  50  
  51      private const STATE_ENCODING_EQUALS = 'encoding_equals';
  52  
  53      private const STATE_STANDALONE_NAME = 'standalone_name';
  54  
  55      private const STATE_ENCODING_VALUE = 'encoding_value';
  56  
  57      private const STATE_STANDALONE_EQUALS = 'standalone_equals';
  58  
  59      private const STATE_STANDALONE_VALUE = 'standalone_value';
  60  
  61      private const STATE_ERROR = false;
  62  
  63      /**
  64       * Current state of the state machine
  65       *
  66       * @access private
  67       * @var self::STATE_*
  68       */
  69      public $state = self::STATE_BEFORE_VERSION_NAME;
  70  
  71      /**
  72       * Input data
  73       *
  74       * @access private
  75       * @var string
  76       */
  77      public $data = '';
  78  
  79      /**
  80       * Input data length (to avoid calling strlen() everytime this is needed)
  81       *
  82       * @access private
  83       * @var int
  84       */
  85      public $data_length = 0;
  86  
  87      /**
  88       * Current position of the pointer
  89       *
  90       * @var int
  91       * @access private
  92       */
  93      public $position = 0;
  94  
  95      /**
  96       * Create an instance of the class with the input data
  97       *
  98       * @access public
  99       * @param string $data Input data
 100       */
 101      public function __construct(string $data)
 102      {
 103          $this->data = $data;
 104          $this->data_length = strlen($this->data);
 105      }
 106  
 107      /**
 108       * Parse the input data
 109       *
 110       * @access public
 111       * @return bool true on success, false on failure
 112       */
 113      public function parse(): bool
 114      {
 115          while ($this->state && $this->state !== self::STATE_EMIT && $this->has_data()) {
 116              $state = $this->state;
 117              $this->$state();
 118          }
 119          $this->data = '';
 120          if ($this->state === self::STATE_EMIT) {
 121              return true;
 122          }
 123  
 124          // Reset the parser state.
 125          $this->version = '1.0';
 126          $this->encoding = 'UTF-8';
 127          $this->standalone = false;
 128          return false;
 129      }
 130  
 131      /**
 132       * Check whether there is data beyond the pointer
 133       *
 134       * @access private
 135       * @return bool true if there is further data, false if not
 136       */
 137      public function has_data(): bool
 138      {
 139          return (bool) ($this->position < $this->data_length);
 140      }
 141  
 142      /**
 143       * Advance past any whitespace
 144       *
 145       * @return int Number of whitespace characters passed
 146       */
 147      public function skip_whitespace()
 148      {
 149          $whitespace = strspn($this->data, "\x09\x0A\x0D\x20", $this->position);
 150          $this->position += $whitespace;
 151          return $whitespace;
 152      }
 153  
 154      /**
 155       * Read value
 156       *
 157       * @return string|false
 158       */
 159      public function get_value()
 160      {
 161          $quote = substr($this->data, $this->position, 1);
 162          if ($quote === '"' || $quote === "'") {
 163              $this->position++;
 164              $len = strcspn($this->data, $quote, $this->position);
 165              if ($this->has_data()) {
 166                  $value = substr($this->data, $this->position, $len);
 167                  $this->position += $len + 1;
 168                  return $value;
 169              }
 170          }
 171          return false;
 172      }
 173  
 174      public function before_version_name(): void
 175      {
 176          if ($this->skip_whitespace()) {
 177              $this->state = self::STATE_VERSION_NAME;
 178          } else {
 179              $this->state = self::STATE_ERROR;
 180          }
 181      }
 182  
 183      public function version_name(): void
 184      {
 185          if (substr($this->data, $this->position, 7) === 'version') {
 186              $this->position += 7;
 187              $this->skip_whitespace();
 188              $this->state = self::STATE_VERSION_EQUALS;
 189          } else {
 190              $this->state = self::STATE_ERROR;
 191          }
 192      }
 193  
 194      public function version_equals(): void
 195      {
 196          if (substr($this->data, $this->position, 1) === '=') {
 197              $this->position++;
 198              $this->skip_whitespace();
 199              $this->state = self::STATE_VERSION_VALUE;
 200          } else {
 201              $this->state = self::STATE_ERROR;
 202          }
 203      }
 204  
 205      public function version_value(): void
 206      {
 207          if ($version = $this->get_value()) {
 208              $this->version = $version;
 209              $this->skip_whitespace();
 210              if ($this->has_data()) {
 211                  $this->state = self::STATE_ENCODING_NAME;
 212              } else {
 213                  $this->state = self::STATE_EMIT;
 214              }
 215          } else {
 216              $this->state = self::STATE_ERROR;
 217          }
 218      }
 219  
 220      public function encoding_name(): void
 221      {
 222          if (substr($this->data, $this->position, 8) === 'encoding') {
 223              $this->position += 8;
 224              $this->skip_whitespace();
 225              $this->state = self::STATE_ENCODING_EQUALS;
 226          } else {
 227              $this->state = self::STATE_STANDALONE_NAME;
 228          }
 229      }
 230  
 231      public function encoding_equals(): void
 232      {
 233          if (substr($this->data, $this->position, 1) === '=') {
 234              $this->position++;
 235              $this->skip_whitespace();
 236              $this->state = self::STATE_ENCODING_VALUE;
 237          } else {
 238              $this->state = self::STATE_ERROR;
 239          }
 240      }
 241  
 242      public function encoding_value(): void
 243      {
 244          if ($encoding = $this->get_value()) {
 245              $this->encoding = $encoding;
 246              $this->skip_whitespace();
 247              if ($this->has_data()) {
 248                  $this->state = self::STATE_STANDALONE_NAME;
 249              } else {
 250                  $this->state = self::STATE_EMIT;
 251              }
 252          } else {
 253              $this->state = self::STATE_ERROR;
 254          }
 255      }
 256  
 257      public function standalone_name(): void
 258      {
 259          if (substr($this->data, $this->position, 10) === 'standalone') {
 260              $this->position += 10;
 261              $this->skip_whitespace();
 262              $this->state = self::STATE_STANDALONE_EQUALS;
 263          } else {
 264              $this->state = self::STATE_ERROR;
 265          }
 266      }
 267  
 268      public function standalone_equals(): void
 269      {
 270          if (substr($this->data, $this->position, 1) === '=') {
 271              $this->position++;
 272              $this->skip_whitespace();
 273              $this->state = self::STATE_STANDALONE_VALUE;
 274          } else {
 275              $this->state = self::STATE_ERROR;
 276          }
 277      }
 278  
 279      public function standalone_value(): void
 280      {
 281          if ($standalone = $this->get_value()) {
 282              switch ($standalone) {
 283                  case 'yes':
 284                      $this->standalone = true;
 285                      break;
 286  
 287                  case 'no':
 288                      $this->standalone = false;
 289                      break;
 290  
 291                  default:
 292                      $this->state = self::STATE_ERROR;
 293                      return;
 294              }
 295  
 296              $this->skip_whitespace();
 297              if ($this->has_data()) {
 298                  $this->state = self::STATE_ERROR;
 299              } else {
 300                  $this->state = self::STATE_EMIT;
 301              }
 302          } else {
 303              $this->state = self::STATE_ERROR;
 304          }
 305      }
 306  }
 307  
 308  class_alias('SimplePie\XML\Declaration\Parser', 'SimplePie_XML_Declaration_Parser');


Generated : Fri Oct 17 08:20:04 2025 Cross-referenced by PHPXref