Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.11.x will end 14 Nov 2022 (12 months plus 6 months extension).
  • Bug fixes for security issues in 3.11.x will end 13 Nov 2023 (18 months plus 12 months extension).
  • PHP version: minimum PHP 7.3.0 Note: minimum PHP version has increased since Moodle 3.10. PHP 7.4.x is supported too.

Differences Between: [Versions 311 and 401]

   1  <?php
   2  /*
   3   * Copyright 2018 MongoDB, Inc.
   4   *
   5   * Licensed under the Apache License, Version 2.0 (the "License");
   6   * you may not use this file except in compliance with the License.
   7   * You may obtain a copy of the License at
   8   *
   9   *   http://www.apache.org/licenses/LICENSE-2.0
  10   *
  11   * Unless required by applicable law or agreed to in writing, software
  12   * distributed under the License is distributed on an "AS IS" BASIS,
  13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14   * See the License for the specific language governing permissions and
  15   * limitations under the License.
  16   */
  17  
  18  namespace MongoDB\Model;
  19  
  20  use Iterator;
  21  use MongoDB\Exception\InvalidArgumentException;
  22  use MongoDB\Exception\UnexpectedValueException;
  23  use function is_array;
  24  use function MongoDB\BSON\toPHP;
  25  use function sprintf;
  26  use function strlen;
  27  use function substr;
  28  use function unpack;
  29  
  30  /**
  31   * Iterator for BSON documents.
  32   */
  33  class BSONIterator implements Iterator
  34  {
  35      /** @var integer */
  36      private static $bsonSize = 4;
  37  
  38      /** @var string */
  39      private $buffer;
  40  
  41      /** @var integer */
  42      private $bufferLength;
  43  
  44      /** @var mixed */
  45      private $current;
  46  
  47      /** @var integer */
  48      private $key = 0;
  49  
  50      /** @var integer */
  51      private $position = 0;
  52  
  53      /** @var array */
  54      private $options;
  55  
  56      /**
  57       * Constructs a BSON Iterator.
  58       *
  59       * Supported options:
  60       *
  61       *  * typeMap (array): Type map for BSON deserialization.
  62       *
  63       * @internal
  64       * @see http://php.net/manual/en/function.mongodb.bson-tophp.php
  65       * @param string $data    Concatenated, valid, BSON-encoded documents
  66       * @param array  $options Iterator options
  67       * @throws InvalidArgumentException for parameter/option parsing errors
  68       */
  69      public function __construct($data, array $options = [])
  70      {
  71          if (isset($options['typeMap']) && ! is_array($options['typeMap'])) {
  72              throw InvalidArgumentException::invalidType('"typeMap" option', $options['typeMap'], 'array');
  73          }
  74  
  75          if (! isset($options['typeMap'])) {
  76              $options['typeMap'] = [];
  77          }
  78  
  79          $this->buffer = $data;
  80          $this->bufferLength = strlen($data);
  81          $this->options = $options;
  82      }
  83  
  84      /**
  85       * @see http://php.net/iterator.current
  86       * @return mixed
  87       */
  88      public function current()
  89      {
  90          return $this->current;
  91      }
  92  
  93      /**
  94       * @see http://php.net/iterator.key
  95       * @return mixed
  96       */
  97      public function key()
  98      {
  99          return $this->key;
 100      }
 101  
 102      /**
 103       * @see http://php.net/iterator.next
 104       * @return void
 105       */
 106      public function next()
 107      {
 108          $this->key++;
 109          $this->current = null;
 110          $this->advance();
 111      }
 112  
 113      /**
 114       * @see http://php.net/iterator.rewind
 115       * @return void
 116       */
 117      public function rewind()
 118      {
 119          $this->key = 0;
 120          $this->position = 0;
 121          $this->current = null;
 122          $this->advance();
 123      }
 124  
 125      /**
 126       * @see http://php.net/iterator.valid
 127       * @return boolean
 128       */
 129      public function valid()
 130      {
 131          return $this->current !== null;
 132      }
 133  
 134      private function advance()
 135      {
 136          if ($this->position === $this->bufferLength) {
 137              return;
 138          }
 139  
 140          if (($this->bufferLength - $this->position) < self::$bsonSize) {
 141              throw new UnexpectedValueException(sprintf('Expected at least %d bytes; %d remaining', self::$bsonSize, $this->bufferLength - $this->position));
 142          }
 143  
 144          list(,$documentLength) = unpack('V', substr($this->buffer, $this->position, self::$bsonSize));
 145  
 146          if (($this->bufferLength - $this->position) < $documentLength) {
 147              throw new UnexpectedValueException(sprintf('Expected %d bytes; %d remaining', $documentLength, $this->bufferLength - $this->position));
 148          }
 149  
 150          $this->current = toPHP(substr($this->buffer, $this->position, $documentLength), $this->options['typeMap']);
 151          $this->position += $documentLength;
 152      }
 153  }