/** * Constructor... * * @param Integer $offset The offset at which to start iteration * @param \Traversable $inner The iterator being wrapped */ public function __construct($offset, \Traversable $inner) { $this->inner = $inner; $offset = (int) $offset; // If we can, be intelligent about the offset if ($inner instanceof \Countable) { try { $offset = \r8\num\offsetWrap($inner->count(), $offset, \r8\num\OFFSET_NONE); } catch (\r8\Exception\Index $err) { $offset = NULL; } } else { if ($offset < 0) { $err = new \r8\Exception\Index($offset, "Iterator Offset", "Negative offsets are only supported if Iterator implements the Countable interface"); $err->addData("Iterator", \r8\getDump($inner)); throw $err; } } $this->offset = $offset; }
/** * calculates the offset based on the wrap flag * * This is generally used by array functions to wrap offsets * * @param array $array The array to use as a base for calculating the offset * @param Integer $offset The offset being wrapped * @param Integer $wrapFlag How to handle offsets that fall outside of the * length of the list. Allowed values are: * - \r8\ary::OFFSET_NONE * - \r8\ary::OFFSET_WRAP * - \r8\ary::OFFSET_RESTRICT * - \r8\ary::OFFSET_LIMIT * @return Integer Returns the wrapped offset */ function calcOffset(array $array, $offset, $wrapFlag) { return \r8\num\offsetWrap(count($array), $offset, $wrapFlag); }
function testOffsetWrap() { try { \r8\num\offsetWrap(5, 2, "invalid offset value"); $this->fail('An expected exception has not been raised.'); } catch (\r8\Exception\Argument $err) { $this->assertSame("Invalid offset wrap flag", $err->getMessage()); } try { \r8\num\offsetWrap(0, 2, "invalid offset value"); $this->fail('An expected exception has not been raised.'); } catch (\r8\Exception\Index $err) { $this->assertSame("List is empty", $err->getMessage()); } $this->assertEquals(0, \r8\num\offsetWrap(5, -5, \r8\num\OFFSET_NONE)); $this->assertEquals(3, \r8\num\offsetWrap(5, -2, \r8\num\OFFSET_NONE)); $this->assertEquals(4, \r8\num\offsetWrap(5, -1, \r8\num\OFFSET_NONE)); $this->assertEquals(0, \r8\num\offsetWrap(5, 0, \r8\num\OFFSET_NONE)); $this->assertEquals(3, \r8\num\offsetWrap(5, 3, \r8\num\OFFSET_NONE)); $this->assertEquals(4, \r8\num\offsetWrap(5, 4, \r8\num\OFFSET_NONE)); try { \r8\num\offsetWrap(1, 2, \r8\num\OFFSET_NONE); $this->fail('An expected exception has not been raised.'); } catch (\r8\Exception\Index $err) { $this->assertSame("Offset is out of bounds", $err->getMessage()); } try { \r8\num\offsetWrap(5, 5, \r8\num\OFFSET_NONE); $this->fail('An expected exception has not been raised.'); } catch (\r8\Exception\Index $err) { $this->assertSame("Offset is out of bounds", $err->getMessage()); } try { \r8\num\offsetWrap(5, -6, \r8\num\OFFSET_NONE); $this->fail('An expected exception has not been raised.'); } catch (\r8\Exception\Index $err) { $this->assertSame("Offset is out of bounds", $err->getMessage()); } $this->assertEquals(1, \r8\num\offsetWrap(5, -14, \r8\num\OFFSET_WRAP)); $this->assertEquals(2, \r8\num\offsetWrap(5, -8, \r8\num\OFFSET_WRAP)); $this->assertEquals(0, \r8\num\offsetWrap(5, -5, \r8\num\OFFSET_WRAP)); $this->assertEquals(3, \r8\num\offsetWrap(5, -2, \r8\num\OFFSET_WRAP)); $this->assertEquals(4, \r8\num\offsetWrap(5, -1, \r8\num\OFFSET_WRAP)); $this->assertEquals(0, \r8\num\offsetWrap(5, 0, \r8\num\OFFSET_WRAP)); $this->assertEquals(3, \r8\num\offsetWrap(5, 3, \r8\num\OFFSET_WRAP)); $this->assertEquals(4, \r8\num\offsetWrap(5, 4, \r8\num\OFFSET_WRAP)); $this->assertEquals(3, \r8\num\offsetWrap(5, 8, \r8\num\OFFSET_WRAP)); $this->assertEquals(0, \r8\num\offsetWrap(5, 15, \r8\num\OFFSET_WRAP)); $this->assertEquals(0, \r8\num\offsetWrap(5, -14, \r8\num\OFFSET_RESTRICT)); $this->assertEquals(0, \r8\num\offsetWrap(5, -8, \r8\num\OFFSET_RESTRICT)); $this->assertEquals(0, \r8\num\offsetWrap(5, -5, \r8\num\OFFSET_RESTRICT)); $this->assertEquals(3, \r8\num\offsetWrap(5, -2, \r8\num\OFFSET_RESTRICT)); $this->assertEquals(4, \r8\num\offsetWrap(5, -1, \r8\num\OFFSET_RESTRICT)); $this->assertEquals(0, \r8\num\offsetWrap(5, 0, \r8\num\OFFSET_RESTRICT)); $this->assertEquals(3, \r8\num\offsetWrap(5, 3, \r8\num\OFFSET_RESTRICT)); $this->assertEquals(4, \r8\num\offsetWrap(5, 4, \r8\num\OFFSET_RESTRICT)); $this->assertEquals(4, \r8\num\offsetWrap(5, 8, \r8\num\OFFSET_RESTRICT)); $this->assertEquals(4, \r8\num\offsetWrap(5, 15, \r8\num\OFFSET_RESTRICT)); $this->assertEquals(0, \r8\num\offsetWrap(5, -2, \r8\num\OFFSET_LIMIT)); $this->assertEquals(0, \r8\num\offsetWrap(5, -1, \r8\num\OFFSET_LIMIT)); $this->assertEquals(0, \r8\num\offsetWrap(5, 0, \r8\num\OFFSET_LIMIT)); $this->assertEquals(3, \r8\num\offsetWrap(5, 3, \r8\num\OFFSET_LIMIT)); $this->assertEquals(4, \r8\num\offsetWrap(5, 4, \r8\num\OFFSET_LIMIT)); $this->assertEquals(4, \r8\num\offsetWrap(5, 8, \r8\num\OFFSET_LIMIT)); $this->assertEquals(4, \r8\num\offsetWrap(5, 15, \r8\num\OFFSET_LIMIT)); }
/** * Sets the internal result pointer to a given offset * * SeekableIterator interface function * * @param Integer $offset The offset to seek to * @param Integer $wrapFlag How to handle offsets that fall outside of the length of the list. * @return \r8\DB\Result\Read Returns a self reference */ public function seek($offset, $wrapFlag = \r8\num\OFFSET_RESTRICT) { if (!isset($this->adapter)) { return $this; } $offset = \r8\num\offsetWrap($this->count(), $offset, $wrapFlag); if ($offset !== FALSE && $this->pointer !== $offset) { $this->pointer = $offset; $this->adapter->seek($offset); $this->row = (array) $this->adapter->fetch(); } return $this; }