diff options
author | Morris Jobke <hey@morrisjobke.de> | 2019-03-15 12:25:28 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-03-15 12:25:28 +0100 |
commit | 8ff536f4f70f9444061da63cfbde92d3112d2e4a (patch) | |
tree | 95bb3bcc14243fe0d86546602d45594dd2341c54 /apps/dav | |
parent | 6bc1c885b209563b12148858daf22e17d3005c58 (diff) | |
parent | 6a47f924fca8c262129abba04772a8859871c9ba (diff) | |
download | nextcloud-server-8ff536f4f70f9444061da63cfbde92d3112d2e4a.tar.gz nextcloud-server-8ff536f4f70f9444061da63cfbde92d3112d2e4a.zip |
Merge pull request #14641 from nextcloud/assemblystream-seek
make assemblystream seekable
Diffstat (limited to 'apps/dav')
-rw-r--r-- | apps/dav/lib/Upload/AssemblyStream.php | 40 | ||||
-rw-r--r-- | apps/dav/tests/unit/Upload/AssemblyStreamTest.php | 15 |
2 files changed, 52 insertions, 3 deletions
diff --git a/apps/dav/lib/Upload/AssemblyStream.php b/apps/dav/lib/Upload/AssemblyStream.php index eaf24f8741a..c8a1be82f6b 100644 --- a/apps/dav/lib/Upload/AssemblyStream.php +++ b/apps/dav/lib/Upload/AssemblyStream.php @@ -83,12 +83,46 @@ class AssemblyStream implements \Icewind\Streams\File { } /** - * @param string $offset + * @param int $offset * @param int $whence * @return bool */ 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 * @return array - * @throws \Exception + * @throws \BadMethodCallException */ protected function loadContext($name) { $context = stream_context_get_options($this->context); diff --git a/apps/dav/tests/unit/Upload/AssemblyStreamTest.php b/apps/dav/tests/unit/Upload/AssemblyStreamTest.php index de60b94168e..0ac9cbb234e 100644 --- a/apps/dav/tests/unit/Upload/AssemblyStreamTest.php +++ b/apps/dav/tests/unit/Upload/AssemblyStreamTest.php @@ -54,6 +54,21 @@ class AssemblyStreamTest extends \Test\TestCase { $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() { $data8k = $this->makeData(8192); $dataLess8k = $this->makeData(8191); |