Merge pull request #14641 from nextcloud/assemblystream-seek
make assemblystream seekable
This commit is contained in:
commit
8ff536f4f7
|
@ -83,12 +83,46 @@ class AssemblyStream implements \Icewind\Streams\File {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $offset
|
* @param int $offset
|
||||||
* @param int $whence
|
* @param int $whence
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function stream_seek($offset, $whence = SEEK_SET) {
|
public function stream_seek($offset, $whence = SEEK_SET) {
|
||||||
return false;
|
if ($whence === SEEK_CUR) {
|
||||||
|
$offset = $this->stream_tell() + $offset;
|
||||||
|
} else if ($whence === SEEK_END) {
|
||||||
|
$offset = $this->size + $offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($offset > $this->size) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$nodeIndex = 0;
|
||||||
|
$nodeStart = 0;
|
||||||
|
while (true) {
|
||||||
|
if (!isset($this->nodes[$nodeIndex + 1])) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
$node = $this->nodes[$nodeIndex];
|
||||||
|
if ($nodeStart + $node->getSize() > $offset) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
$nodeIndex++;
|
||||||
|
$nodeStart += $node->getSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
$stream = $this->getStream($this->nodes[$nodeIndex]);
|
||||||
|
$nodeOffset = $offset - $nodeStart;
|
||||||
|
if(fseek($stream, $nodeOffset) === -1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$this->currentNode = $nodeIndex;
|
||||||
|
$this->currentNodeRead = $nodeOffset;
|
||||||
|
$this->currentStream = $stream;
|
||||||
|
$this->pos = $offset;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -210,7 +244,7 @@ class AssemblyStream implements \Icewind\Streams\File {
|
||||||
*
|
*
|
||||||
* @param string $name
|
* @param string $name
|
||||||
* @return array
|
* @return array
|
||||||
* @throws \Exception
|
* @throws \BadMethodCallException
|
||||||
*/
|
*/
|
||||||
protected function loadContext($name) {
|
protected function loadContext($name) {
|
||||||
$context = stream_context_get_options($this->context);
|
$context = stream_context_get_options($this->context);
|
||||||
|
|
|
@ -54,6 +54,21 @@ class AssemblyStreamTest extends \Test\TestCase {
|
||||||
$this->assertEquals($expected, $content);
|
$this->assertEquals($expected, $content);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider providesNodes()
|
||||||
|
*/
|
||||||
|
public function testSeek($expected, $nodes) {
|
||||||
|
$stream = \OCA\DAV\Upload\AssemblyStream::wrap($nodes);
|
||||||
|
|
||||||
|
$offset = floor(strlen($expected) * 0.6);
|
||||||
|
if(fseek($stream, $offset) === -1) {
|
||||||
|
$this->fail('fseek failed');
|
||||||
|
}
|
||||||
|
|
||||||
|
$content = stream_get_contents($stream);
|
||||||
|
$this->assertEquals(substr($expected, $offset), $content);
|
||||||
|
}
|
||||||
|
|
||||||
function providesNodes() {
|
function providesNodes() {
|
||||||
$data8k = $this->makeData(8192);
|
$data8k = $this->makeData(8192);
|
||||||
$dataLess8k = $this->makeData(8191);
|
$dataLess8k = $this->makeData(8191);
|
||||||
|
|
Loading…
Reference in New Issue