PageRenderTime 26ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/vendor/nikic/php-parser/lib/PhpParser/Unserializer/XML.php

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