aboutsummaryrefslogtreecommitdiffstats
path: root/apps/dav
diff options
context:
space:
mode:
authorMorris Jobke <hey@morrisjobke.de>2019-03-15 12:25:28 +0100
committerGitHub <noreply@github.com>2019-03-15 12:25:28 +0100
commit8ff536f4f70f9444061da63cfbde92d3112d2e4a (patch)
tree95bb3bcc14243fe0d86546602d45594dd2341c54 /apps/dav
parent6bc1c885b209563b12148858daf22e17d3005c58 (diff)
parent6a47f924fca8c262129abba04772a8859871c9ba (diff)
downloadnextcloud-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.php40
-rw-r--r--apps/dav/tests/unit/Upload/AssemblyStreamTest.php15
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);