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