Mercurial > hg > isophonics-drupal-site
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 } |