[ Index ] |
PHP Cross Reference of WordPress Trunk (Updated Daily) |
[Summary view] [Print] [Text view]
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');
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated : Fri Oct 17 08:20:04 2025 | Cross-referenced by PHPXref |