Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/CarnetApp/CarnetNextcloud.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/sebastian/recursion-context/src/Context.php')
-rw-r--r--vendor/sebastian/recursion-context/src/Context.php167
1 files changed, 167 insertions, 0 deletions
diff --git a/vendor/sebastian/recursion-context/src/Context.php b/vendor/sebastian/recursion-context/src/Context.php
new file mode 100644
index 0000000..0b4b8a0
--- /dev/null
+++ b/vendor/sebastian/recursion-context/src/Context.php
@@ -0,0 +1,167 @@
+<?php
+/*
+ * This file is part of the Recursion Context package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\RecursionContext;
+
+/**
+ * A context containing previously processed arrays and objects
+ * when recursively processing a value.
+ */
+final class Context
+{
+ /**
+ * @var array[]
+ */
+ private $arrays;
+
+ /**
+ * @var \SplObjectStorage
+ */
+ private $objects;
+
+ /**
+ * Initialises the context
+ */
+ public function __construct()
+ {
+ $this->arrays = array();
+ $this->objects = new \SplObjectStorage;
+ }
+
+ /**
+ * Adds a value to the context.
+ *
+ * @param array|object $value The value to add.
+ *
+ * @return int|string The ID of the stored value, either as a string or integer.
+ *
+ * @throws InvalidArgumentException Thrown if $value is not an array or object
+ */
+ public function add(&$value)
+ {
+ if (is_array($value)) {
+ return $this->addArray($value);
+ } elseif (is_object($value)) {
+ return $this->addObject($value);
+ }
+
+ throw new InvalidArgumentException(
+ 'Only arrays and objects are supported'
+ );
+ }
+
+ /**
+ * Checks if the given value exists within the context.
+ *
+ * @param array|object $value The value to check.
+ *
+ * @return int|string|false The string or integer ID of the stored value if it has already been seen, or false if the value is not stored.
+ *
+ * @throws InvalidArgumentException Thrown if $value is not an array or object
+ */
+ public function contains(&$value)
+ {
+ if (is_array($value)) {
+ return $this->containsArray($value);
+ } elseif (is_object($value)) {
+ return $this->containsObject($value);
+ }
+
+ throw new InvalidArgumentException(
+ 'Only arrays and objects are supported'
+ );
+ }
+
+ /**
+ * @param array $array
+ *
+ * @return bool|int
+ */
+ private function addArray(array &$array)
+ {
+ $key = $this->containsArray($array);
+
+ if ($key !== false) {
+ return $key;
+ }
+
+ $key = count($this->arrays);
+ $this->arrays[] = &$array;
+
+ if (!isset($array[PHP_INT_MAX]) && !isset($array[PHP_INT_MAX - 1])) {
+ $array[] = $key;
+ $array[] = $this->objects;
+ } else { /* cover the improbable case too */
+ do {
+ $key = random_int(PHP_INT_MIN, PHP_INT_MAX);
+ } while (isset($array[$key]));
+
+ $array[$key] = $key;
+
+ do {
+ $key = random_int(PHP_INT_MIN, PHP_INT_MAX);
+ } while (isset($array[$key]));
+
+ $array[$key] = $this->objects;
+ }
+
+ return $key;
+ }
+
+ /**
+ * @param object $object
+ *
+ * @return string
+ */
+ private function addObject($object)
+ {
+ if (!$this->objects->contains($object)) {
+ $this->objects->attach($object);
+ }
+
+ return spl_object_hash($object);
+ }
+
+ /**
+ * @param array $array
+ *
+ * @return int|false
+ */
+ private function containsArray(array &$array)
+ {
+ $end = array_slice($array, -2);
+
+ return isset($end[1]) && $end[1] === $this->objects ? $end[0] : false;
+ }
+
+ /**
+ * @param object $value
+ *
+ * @return string|false
+ */
+ private function containsObject($value)
+ {
+ if ($this->objects->contains($value)) {
+ return spl_object_hash($value);
+ }
+
+ return false;
+ }
+
+ public function __destruct()
+ {
+ foreach ($this->arrays as &$array) {
+ if (is_array($array)) {
+ array_pop($array);
+ array_pop($array);
+ }
+ }
+ }
+}