annotate vendor/nikic/php-parser/lib/PhpParser/Unserializer/XML.php @ 0:4c8ae668cc8c

Initial import (non-working)
author Chris Cannam
date Wed, 29 Nov 2017 16:09:58 +0000
parents
children
rev   line source
Chris@0 1 <?php
Chris@0 2
Chris@0 3 namespace PhpParser\Unserializer;
Chris@0 4
Chris@0 5 use DomainException;
Chris@0 6 use PhpParser\Unserializer;
Chris@0 7 use XMLReader;
Chris@0 8
Chris@0 9 /**
Chris@0 10 * @deprecated
Chris@0 11 */
Chris@0 12 class XML implements Unserializer
Chris@0 13 {
Chris@0 14 protected $reader;
Chris@0 15
Chris@0 16 public function __construct() {
Chris@0 17 $this->reader = new XMLReader;
Chris@0 18 }
Chris@0 19
Chris@0 20 public function unserialize($string) {
Chris@0 21 $this->reader->XML($string);
Chris@0 22
Chris@0 23 $this->reader->read();
Chris@0 24 if ('AST' !== $this->reader->name) {
Chris@0 25 throw new DomainException('AST root element not found');
Chris@0 26 }
Chris@0 27
Chris@0 28 return $this->read($this->reader->depth);
Chris@0 29 }
Chris@0 30
Chris@0 31 protected function read($depthLimit, $throw = true, &$nodeFound = null) {
Chris@0 32 $nodeFound = true;
Chris@0 33 while ($this->reader->read() && $depthLimit < $this->reader->depth) {
Chris@0 34 if (XMLReader::ELEMENT !== $this->reader->nodeType) {
Chris@0 35 continue;
Chris@0 36 }
Chris@0 37
Chris@0 38 if ('node' === $this->reader->prefix) {
Chris@0 39 return $this->readNode();
Chris@0 40 } elseif ('scalar' === $this->reader->prefix) {
Chris@0 41 return $this->readScalar();
Chris@0 42 } elseif ('comment' === $this->reader->name) {
Chris@0 43 return $this->readComment();
Chris@0 44 } else {
Chris@0 45 throw new DomainException(sprintf('Unexpected node of type "%s"', $this->reader->name));
Chris@0 46 }
Chris@0 47 }
Chris@0 48
Chris@0 49 $nodeFound = false;
Chris@0 50 if ($throw) {
Chris@0 51 throw new DomainException('Expected node or scalar');
Chris@0 52 }
Chris@0 53 }
Chris@0 54
Chris@0 55 protected function readNode() {
Chris@0 56 $className = $this->getClassNameFromType($this->reader->localName);
Chris@0 57
Chris@0 58 // create the node without calling it's constructor
Chris@0 59 $node = unserialize(
Chris@0 60 sprintf(
Chris@0 61 "O:%d:\"%s\":1:{s:13:\"\0*\0attributes\";a:0:{}}",
Chris@0 62 strlen($className), $className
Chris@0 63 )
Chris@0 64 );
Chris@0 65
Chris@0 66 $depthLimit = $this->reader->depth;
Chris@0 67 while ($this->reader->read() && $depthLimit < $this->reader->depth) {
Chris@0 68 if (XMLReader::ELEMENT !== $this->reader->nodeType) {
Chris@0 69 continue;
Chris@0 70 }
Chris@0 71
Chris@0 72 $type = $this->reader->prefix;
Chris@0 73 if ('subNode' !== $type && 'attribute' !== $type) {
Chris@0 74 throw new DomainException(
Chris@0 75 sprintf('Expected sub node or attribute, got node of type "%s"', $this->reader->name)
Chris@0 76 );
Chris@0 77 }
Chris@0 78
Chris@0 79 $name = $this->reader->localName;
Chris@0 80 $value = $this->read($this->reader->depth);
Chris@0 81
Chris@0 82 if ('subNode' === $type) {
Chris@0 83 $node->$name = $value;
Chris@0 84 } else {
Chris@0 85 $node->setAttribute($name, $value);
Chris@0 86 }
Chris@0 87 }
Chris@0 88
Chris@0 89 return $node;
Chris@0 90 }
Chris@0 91
Chris@0 92 protected function readScalar() {
Chris@0 93 switch ($name = $this->reader->localName) {
Chris@0 94 case 'array':
Chris@0 95 $depth = $this->reader->depth;
Chris@0 96 $array = array();
Chris@0 97 while (true) {
Chris@0 98 $node = $this->read($depth, false, $nodeFound);
Chris@0 99 if (!$nodeFound) {
Chris@0 100 break;
Chris@0 101 }
Chris@0 102 $array[] = $node;
Chris@0 103 }
Chris@0 104 return $array;
Chris@0 105 case 'string':
Chris@0 106 return $this->reader->readString();
Chris@0 107 case 'int':
Chris@0 108 return $this->parseInt($this->reader->readString());
Chris@0 109 case 'float':
Chris@0 110 $text = $this->reader->readString();
Chris@0 111 if (false === $float = filter_var($text, FILTER_VALIDATE_FLOAT)) {
Chris@0 112 throw new DomainException(sprintf('"%s" is not a valid float', $text));
Chris@0 113 }
Chris@0 114 return $float;
Chris@0 115 case 'true':
Chris@0 116 case 'false':
Chris@0 117 case 'null':
Chris@0 118 if (!$this->reader->isEmptyElement) {
Chris@0 119 throw new DomainException(sprintf('"%s" scalar must be empty', $name));
Chris@0 120 }
Chris@0 121 return constant($name);
Chris@0 122 default:
Chris@0 123 throw new DomainException(sprintf('Unknown scalar type "%s"', $name));
Chris@0 124 }
Chris@0 125 }
Chris@0 126
Chris@0 127 private function parseInt($text) {
Chris@0 128 if (false === $int = filter_var($text, FILTER_VALIDATE_INT)) {
Chris@0 129 throw new DomainException(sprintf('"%s" is not a valid integer', $text));
Chris@0 130 }
Chris@0 131 return $int;
Chris@0 132 }
Chris@0 133
Chris@0 134 protected function readComment() {
Chris@0 135 $className = $this->reader->getAttribute('isDocComment') === 'true'
Chris@0 136 ? 'PhpParser\Comment\Doc'
Chris@0 137 : 'PhpParser\Comment'
Chris@0 138 ;
Chris@0 139 return new $className(
Chris@0 140 $this->reader->readString(),
Chris@0 141 $this->parseInt($this->reader->getAttribute('line'))
Chris@0 142 );
Chris@0 143 }
Chris@0 144
Chris@0 145 protected function getClassNameFromType($type) {
Chris@0 146 $className = 'PhpParser\\Node\\' . strtr($type, '_', '\\');
Chris@0 147 if (!class_exists($className)) {
Chris@0 148 $className .= '_';
Chris@0 149 }
Chris@0 150 if (!class_exists($className)) {
Chris@0 151 throw new DomainException(sprintf('Unknown node type "%s"', $type));
Chris@0 152 }
Chris@0 153 return $className;
Chris@0 154 }
Chris@0 155 }