summaryrefslogtreecommitdiffstats
path: root/apps/files_external/3rdparty/icewind/streams
diff options
context:
space:
mode:
authorMorris Jobke <hey@morrisjobke.de>2015-02-16 17:37:20 +0100
committerMorris Jobke <hey@morrisjobke.de>2015-02-16 17:37:20 +0100
commitfadf0a944345272cb2303283dafd4fa70ff688b0 (patch)
tree50df4907dfe27d1f2f49d48265f25cc179d98a4e /apps/files_external/3rdparty/icewind/streams
parent92710591955e4696c29628b438dbb7a173ee379c (diff)
parent6477e39be931e33864c64bfcea72391e51f44213 (diff)
downloadnextcloud-server-fadf0a944345272cb2303283dafd4fa70ff688b0.tar.gz
nextcloud-server-fadf0a944345272cb2303283dafd4fa70ff688b0.zip
Merge pull request #10673 from owncloud/smb-new
New SMB storage backend
Diffstat (limited to 'apps/files_external/3rdparty/icewind/streams')
-rw-r--r--apps/files_external/3rdparty/icewind/streams/.gitignore3
-rw-r--r--apps/files_external/3rdparty/icewind/streams/.travis.yml26
-rw-r--r--apps/files_external/3rdparty/icewind/streams/README.md52
-rw-r--r--apps/files_external/3rdparty/icewind/streams/composer.json23
-rw-r--r--apps/files_external/3rdparty/icewind/streams/src/CallbackWrapper.php110
-rw-r--r--apps/files_external/3rdparty/icewind/streams/src/Directory.php35
-rw-r--r--apps/files_external/3rdparty/icewind/streams/src/File.php86
-rw-r--r--apps/files_external/3rdparty/icewind/streams/src/IteratorDirectory.php123
-rw-r--r--apps/files_external/3rdparty/icewind/streams/src/NullWrapper.php42
-rw-r--r--apps/files_external/3rdparty/icewind/streams/src/Wrapper.php110
-rw-r--r--apps/files_external/3rdparty/icewind/streams/tests/CallbackWrapper.php72
-rw-r--r--apps/files_external/3rdparty/icewind/streams/tests/IteratorDirectory.php130
-rw-r--r--apps/files_external/3rdparty/icewind/streams/tests/NullWrapper.php59
-rw-r--r--apps/files_external/3rdparty/icewind/streams/tests/Wrapper.php105
-rw-r--r--apps/files_external/3rdparty/icewind/streams/tests/bootstrap.php9
-rw-r--r--apps/files_external/3rdparty/icewind/streams/tests/phpunit.xml6
16 files changed, 991 insertions, 0 deletions
diff --git a/apps/files_external/3rdparty/icewind/streams/.gitignore b/apps/files_external/3rdparty/icewind/streams/.gitignore
new file mode 100644
index 00000000000..4f389129e2d
--- /dev/null
+++ b/apps/files_external/3rdparty/icewind/streams/.gitignore
@@ -0,0 +1,3 @@
+.idea
+vendor
+composer.lock
diff --git a/apps/files_external/3rdparty/icewind/streams/.travis.yml b/apps/files_external/3rdparty/icewind/streams/.travis.yml
new file mode 100644
index 00000000000..dfa52767dda
--- /dev/null
+++ b/apps/files_external/3rdparty/icewind/streams/.travis.yml
@@ -0,0 +1,26 @@
+language: php
+php:
+ - 5.3
+ - 5.4
+ - 5.5
+ - hhvm
+
+matrix:
+ allow_failures:
+ - php: hhvm # due to facebook/hhvm#3321
+
+env:
+ global:
+ - CURRENT_DIR=`pwd`
+
+install:
+ - composer install --dev --no-interaction
+
+script:
+ - mkdir -p build/logs
+ - cd tests
+ - phpunit --coverage-clover ../build/logs/clover.xml --configuration phpunit.xml
+
+after_script:
+ - cd $CURRENT_DIR
+ - php vendor/bin/coveralls -v
diff --git a/apps/files_external/3rdparty/icewind/streams/README.md b/apps/files_external/3rdparty/icewind/streams/README.md
new file mode 100644
index 00000000000..54f6d19a560
--- /dev/null
+++ b/apps/files_external/3rdparty/icewind/streams/README.md
@@ -0,0 +1,52 @@
+#Streams#
+
+[![Build Status](https://travis-ci.org/icewind1991/Streams.svg?branch=master)](https://travis-ci.org/icewind1991/Streams)
+[![Coverage Status](https://img.shields.io/coveralls/icewind1991/Streams.svg)](https://coveralls.io/r/icewind1991/Streams?branch=master)
+
+Generic stream wrappers for php.
+
+##CallBackWrapper##
+
+A `CallBackWrapper` can be used to register callbacks on read, write and closing of the stream,
+it wraps an existing stream and can thus be used for any stream in php
+
+The callbacks are passed in the stream context along with the source stream
+and can be any valid [php callable](http://php.net/manual/en/language.types.callable.php)
+
+###Example###
+```php
+<?php
+
+use \Icewind\Streams\CallBackWrapper;
+
+require('vendor/autoload.php');
+
+// get an existing stream to wrap
+$source = fopen('php://temp', 'r+');
+
+// register the callbacks
+$stream = CallbackWrapper::wrap($source,
+ // read callback
+ function ($count) {
+ echo "read " . $count . "bytes\n";
+ },
+ // write callback
+ function ($data) {
+ echo "wrote '" . $data . "'\n";
+ },
+ // close callback
+ function () {
+ echo "stream closed\n";
+ });
+
+fwrite($stream, 'some dummy data');
+
+rewind($stream);
+fread($stream, 5);
+
+fclose($stream);
+```
+
+Note: due to php's internal stream buffering the `$count` passed to the read callback
+will be equal to php's internal buffer size (8192 on default) an not the number of bytes
+requested by `fopen()`
diff --git a/apps/files_external/3rdparty/icewind/streams/composer.json b/apps/files_external/3rdparty/icewind/streams/composer.json
new file mode 100644
index 00000000000..86d3c834258
--- /dev/null
+++ b/apps/files_external/3rdparty/icewind/streams/composer.json
@@ -0,0 +1,23 @@
+{
+ "name" : "icewind/streams",
+ "description" : "A set of generic stream wrappers",
+ "license" : "MIT",
+ "authors" : [
+ {
+ "name" : "Robin Appelman",
+ "email": "icewind@owncloud.com"
+ }
+ ],
+ "require" : {
+ "php": ">=5.3"
+ },
+ "require-dev" : {
+ "satooshi/php-coveralls": "dev-master"
+ },
+ "autoload" : {
+ "psr-4": {
+ "Icewind\\Streams\\Tests\\": "tests/",
+ "Icewind\\Streams\\": "src/"
+ }
+ }
+}
diff --git a/apps/files_external/3rdparty/icewind/streams/src/CallbackWrapper.php b/apps/files_external/3rdparty/icewind/streams/src/CallbackWrapper.php
new file mode 100644
index 00000000000..fd99aa6ebe8
--- /dev/null
+++ b/apps/files_external/3rdparty/icewind/streams/src/CallbackWrapper.php
@@ -0,0 +1,110 @@
+<?php
+/**
+ * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Licensed under the MIT license:
+ * http://opensource.org/licenses/MIT
+ */
+
+namespace Icewind\Streams;
+
+/**
+ * Wrapper that provides callbacks for write, read and close
+ *
+ * The following options should be passed in the context when opening the stream
+ * [
+ * 'callback' => [
+ * 'source' => resource
+ * 'read' => function($count){} (optional)
+ * 'write' => function($data){} (optional)
+ * 'close' => function(){} (optional)
+ * ]
+ * ]
+ *
+ * All callbacks are called after the operation is executed on the source stream
+ */
+class CallbackWrapper extends Wrapper {
+ /**
+ * @var callable
+ */
+ protected $readCallback;
+
+ /**
+ * @var callable
+ */
+ protected $writeCallback;
+
+ /**
+ * @var callable
+ */
+ protected $closeCallback;
+
+ /**
+ * Wraps a stream with the provided callbacks
+ *
+ * @param resource $source
+ * @param callable $read (optional)
+ * @param callable $write (optional)
+ * @param callable $close (optional)
+ * @return resource
+ *
+ * @throws \BadMethodCallException
+ */
+ public static function wrap($source, $read = null, $write = null, $close = null) {
+ $context = stream_context_create(array(
+ 'callback' => array(
+ 'source' => $source,
+ 'read' => $read,
+ 'write' => $write,
+ 'close' => $close
+ )
+ ));
+ stream_wrapper_register('callback', '\Icewind\Streams\CallbackWrapper');
+ try {
+ $wrapped = fopen('callback://', 'r+', false, $context);
+ } catch (\BadMethodCallException $e) {
+ stream_wrapper_unregister('callback');
+ throw $e;
+ }
+ stream_wrapper_unregister('callback');
+ return $wrapped;
+ }
+
+ public function stream_open($path, $mode, $options, &$opened_path) {
+ $context = $this->loadContext('callback');
+
+ if (isset($context['read']) and is_callable($context['read'])) {
+ $this->readCallback = $context['read'];
+ }
+ if (isset($context['write']) and is_callable($context['write'])) {
+ $this->writeCallback = $context['write'];
+ }
+ if (isset($context['close']) and is_callable($context['close'])) {
+ $this->closeCallback = $context['close'];
+ }
+ return true;
+ }
+
+ public function stream_read($count) {
+ $result = parent::stream_read($count);
+ if ($this->readCallback) {
+ call_user_func($this->readCallback, $count);
+ }
+ return $result;
+ }
+
+ public function stream_write($data) {
+ $result = parent::stream_write($data);
+ if ($this->writeCallback) {
+ call_user_func($this->writeCallback, $data);
+ }
+ return $result;
+ }
+
+ public function stream_close() {
+ $result = parent::stream_close();
+ if ($this->closeCallback) {
+ call_user_func($this->closeCallback);
+ }
+ return $result;
+ }
+}
diff --git a/apps/files_external/3rdparty/icewind/streams/src/Directory.php b/apps/files_external/3rdparty/icewind/streams/src/Directory.php
new file mode 100644
index 00000000000..c80a878386b
--- /dev/null
+++ b/apps/files_external/3rdparty/icewind/streams/src/Directory.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Licensed under the MIT license:
+ * http://opensource.org/licenses/MIT
+ */
+
+namespace Icewind\Streams;
+
+/**
+ * Interface for stream wrappers that implements a directory
+ */
+interface Directory {
+ /**
+ * @param string $path
+ * @param array $options
+ * @return bool
+ */
+ public function dir_opendir($path, $options);
+
+ /**
+ * @return string
+ */
+ public function dir_readdir();
+
+ /**
+ * @return bool
+ */
+ public function dir_closedir();
+
+ /**
+ * @return bool
+ */
+ public function dir_rewinddir();
+}
diff --git a/apps/files_external/3rdparty/icewind/streams/src/File.php b/apps/files_external/3rdparty/icewind/streams/src/File.php
new file mode 100644
index 00000000000..6202ef4a4b4
--- /dev/null
+++ b/apps/files_external/3rdparty/icewind/streams/src/File.php
@@ -0,0 +1,86 @@
+<?php
+/**
+ * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Licensed under the MIT license:
+ * http://opensource.org/licenses/MIT
+ */
+
+namespace Icewind\Streams;
+
+/**
+ * Interface for stream wrappers that implements a file
+ */
+interface File {
+ /**
+ * @param string $path
+ * @param string $mode
+ * @param int $options
+ * @param string &$opened_path
+ * @return bool
+ */
+ public function stream_open($path, $mode, $options, &$opened_path);
+
+ /**
+ * @param string $offset
+ * @param int $whence
+ * @return bool
+ */
+ public function stream_seek($offset, $whence = SEEK_SET);
+
+ /**
+ * @return int
+ */
+ public function stream_tell();
+
+ /**
+ * @param int $count
+ * @return string
+ */
+ public function stream_read($count);
+
+ /**
+ * @param string $data
+ * @return int
+ */
+ public function stream_write($data);
+
+ /**
+ * @param int $option
+ * @param int $arg1
+ * @param int $arg2
+ * @return bool
+ */
+ public function stream_set_option($option, $arg1, $arg2);
+
+ /**
+ * @param int $size
+ * @return bool
+ */
+ public function stream_truncate($size);
+
+ /**
+ * @return array
+ */
+ public function stream_stat();
+
+ /**
+ * @param int $operation
+ * @return bool
+ */
+ public function stream_lock($operation);
+
+ /**
+ * @return bool
+ */
+ public function stream_flush();
+
+ /**
+ * @return bool
+ */
+ public function stream_eof();
+
+ /**
+ * @return bool
+ */
+ public function stream_close();
+}
diff --git a/apps/files_external/3rdparty/icewind/streams/src/IteratorDirectory.php b/apps/files_external/3rdparty/icewind/streams/src/IteratorDirectory.php
new file mode 100644
index 00000000000..c4eac5d4ed3
--- /dev/null
+++ b/apps/files_external/3rdparty/icewind/streams/src/IteratorDirectory.php
@@ -0,0 +1,123 @@
+<?php
+/**
+ * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Licensed under the MIT license:
+ * http://opensource.org/licenses/MIT
+ */
+
+namespace Icewind\Streams;
+
+/**
+ * Create a directory handle from an iterator or array
+ *
+ * The following options should be passed in the context when opening the stream
+ * [
+ * 'dir' => [
+ * 'array' => string[]
+ * 'iterator' => \Iterator
+ * ]
+ * ]
+ *
+ * Either 'array' or 'iterator' need to be set, if both are set, 'iterator' takes preference
+ */
+class IteratorDirectory implements Directory {
+ /**
+ * @var resource
+ */
+ public $context;
+
+ /**
+ * @var \Iterator
+ */
+ protected $iterator;
+
+ /**
+ * Load the source from the stream context and return the context options
+ *
+ * @param string $name
+ * @return array
+ * @throws \Exception
+ */
+ protected function loadContext($name) {
+ $context = stream_context_get_options($this->context);
+ if (isset($context[$name])) {
+ $context = $context[$name];
+ } else {
+ throw new \BadMethodCallException('Invalid context, "' . $name . '" options not set');
+ }
+ if (isset($context['iterator']) and $context['iterator'] instanceof \Iterator) {
+ $this->iterator = $context['iterator'];
+ } else if (isset($context['array']) and is_array($context['array'])) {
+ $this->iterator = new \ArrayIterator($context['array']);
+ } else {
+ throw new \BadMethodCallException('Invalid context, iterator or array not set');
+ }
+ return $context;
+ }
+
+ /**
+ * @param string $path
+ * @param array $options
+ * @return bool
+ */
+ public function dir_opendir($path, $options) {
+ $this->loadContext('dir');
+ return true;
+ }
+
+ /**
+ * @return string
+ */
+ public function dir_readdir() {
+ if ($this->iterator->valid()) {
+ $result = $this->iterator->current();
+ $this->iterator->next();
+ return $result;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * @return bool
+ */
+ public function dir_closedir() {
+ return true;
+ }
+
+ /**
+ * @return bool
+ */
+ public function dir_rewinddir() {
+ $this->iterator->rewind();
+ return true;
+ }
+
+ /**
+ * Creates a directory handle from the provided array or iterator
+ *
+ * @param \Iterator | array $source
+ * @return resource
+ *
+ * @throws \BadMethodCallException
+ */
+ public static function wrap($source) {
+ if ($source instanceof \Iterator) {
+ $context = stream_context_create(array(
+ 'dir' => array(
+ 'iterator' => $source)
+ ));
+ } else if (is_array($source)) {
+ $context = stream_context_create(array(
+ 'dir' => array(
+ 'array' => $source)
+ ));
+ } else {
+ throw new \BadMethodCallException('$source should be an Iterator or array');
+ }
+ stream_wrapper_register('iterator', '\Icewind\Streams\IteratorDirectory');
+ $wrapped = opendir('iterator://', $context);
+ stream_wrapper_unregister('iterator');
+ return $wrapped;
+ }
+}
diff --git a/apps/files_external/3rdparty/icewind/streams/src/NullWrapper.php b/apps/files_external/3rdparty/icewind/streams/src/NullWrapper.php
new file mode 100644
index 00000000000..8cbaaa756d3
--- /dev/null
+++ b/apps/files_external/3rdparty/icewind/streams/src/NullWrapper.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Licensed under the MIT license:
+ * http://opensource.org/licenses/MIT
+ */
+
+namespace Icewind\Streams;
+
+/**
+ * Stream wrapper that does nothing, used for tests
+ */
+class NullWrapper extends Wrapper {
+ /**
+ * Wraps a stream with the provided callbacks
+ *
+ * @param resource $source
+ * @return resource
+ *
+ * @throws \BadMethodCallException
+ */
+ public static function wrap($source) {
+ $context = stream_context_create(array(
+ 'null' => array(
+ 'source' => $source)
+ ));
+ stream_wrapper_register('null', '\Icewind\Streams\NullWrapper');
+ try {
+ $wrapped = fopen('null://', 'r+', false, $context);
+ } catch (\BadMethodCallException $e) {
+ stream_wrapper_unregister('null');
+ throw $e;
+ }
+ stream_wrapper_unregister('null');
+ return $wrapped;
+ }
+
+ public function stream_open($path, $mode, $options, &$opened_path) {
+ $this->loadContext('null');
+ return true;
+ }
+}
diff --git a/apps/files_external/3rdparty/icewind/streams/src/Wrapper.php b/apps/files_external/3rdparty/icewind/streams/src/Wrapper.php
new file mode 100644
index 00000000000..2e3a6e6cd88
--- /dev/null
+++ b/apps/files_external/3rdparty/icewind/streams/src/Wrapper.php
@@ -0,0 +1,110 @@
+<?php
+/**
+ * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Licensed under the MIT license:
+ * http://opensource.org/licenses/MIT
+ */
+
+namespace Icewind\Streams;
+
+/**
+ * Base class for stream wrappers, wraps an existing stream
+ *
+ * This wrapper itself doesn't implement any functionality but is just a base class for other wrappers to extend
+ */
+abstract class Wrapper implements File {
+ /**
+ * @var resource
+ */
+ public $context;
+
+ /**
+ * The wrapped stream
+ *
+ * @var resource
+ */
+ protected $source;
+
+ /**
+ * Load the source from the stream context and return the context options
+ *
+ * @param string $name
+ * @return array
+ * @throws \Exception
+ */
+ protected function loadContext($name) {
+ $context = stream_context_get_options($this->context);
+ if (isset($context[$name])) {
+ $context = $context[$name];
+ } else {
+ throw new \BadMethodCallException('Invalid context, "callable" options not set');
+ }
+ if (isset($context['source']) and is_resource($context['source'])) {
+ $this->setSourceStream($context['source']);
+ } else {
+ throw new \BadMethodCallException('Invalid context, source not set');
+ }
+ return $context;
+ }
+
+ /**
+ * @param resource $source
+ */
+ protected function setSourceStream($source) {
+ $this->source = $source;
+ }
+
+ public function stream_seek($offset, $whence = SEEK_SET) {
+ $result = fseek($this->source, $offset, $whence);
+ return $result == 0 ? true : false;
+ }
+
+ public function stream_tell() {
+ return ftell($this->source);
+ }
+
+ public function stream_read($count) {
+ return fread($this->source, $count);
+ }
+
+ public function stream_write($data) {
+ return fwrite($this->source, $data);
+ }
+
+ public function stream_set_option($option, $arg1, $arg2) {
+ switch ($option) {
+ case STREAM_OPTION_BLOCKING:
+ stream_set_blocking($this->source, $arg1);
+ break;
+ case STREAM_OPTION_READ_TIMEOUT:
+ stream_set_timeout($this->source, $arg1, $arg2);
+ break;
+ case STREAM_OPTION_WRITE_BUFFER:
+ stream_set_write_buffer($this->source, $arg1);
+ }
+ }
+
+ public function stream_truncate($size) {
+ return ftruncate($this->source, $size);
+ }
+
+ public function stream_stat() {
+ return fstat($this->source);
+ }
+
+ public function stream_lock($mode) {
+ return flock($this->source, $mode);
+ }
+
+ public function stream_flush() {
+ return fflush($this->source);
+ }
+
+ public function stream_eof() {
+ return feof($this->source);
+ }
+
+ public function stream_close() {
+ return fclose($this->source);
+ }
+}
diff --git a/apps/files_external/3rdparty/icewind/streams/tests/CallbackWrapper.php b/apps/files_external/3rdparty/icewind/streams/tests/CallbackWrapper.php
new file mode 100644
index 00000000000..229b629dcd9
--- /dev/null
+++ b/apps/files_external/3rdparty/icewind/streams/tests/CallbackWrapper.php
@@ -0,0 +1,72 @@
+<?php
+/**
+ * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Licensed under the MIT license:
+ * http://opensource.org/licenses/MIT
+ */
+
+namespace Icewind\Streams\Tests;
+
+class CallbackWrapper extends Wrapper {
+
+ /**
+ * @param resource $source
+ * @param callable $read
+ * @param callable $write
+ * @param callable $close
+ * @return resource
+ */
+ protected function wrapSource($source, $read = null, $write = null, $close = null) {
+ return \Icewind\Streams\CallbackWrapper::wrap($source, $read, $write, $close);
+ }
+
+ /**
+ * @expectedException \BadMethodCallException
+ */
+ public function testWrapInvalidSource() {
+ $this->wrapSource('foo');
+ }
+
+ public function testReadCallback() {
+ $called = false;
+ $callBack = function () use (&$called) {
+ $called = true;
+ };
+
+ $source = fopen('php://temp', 'r+');
+ fwrite($source, 'foobar');
+ rewind($source);
+
+ $wrapped = $this->wrapSource($source, $callBack);
+ $this->assertEquals('foo', fread($wrapped, 3));
+ $this->assertTrue($called);
+ }
+
+ public function testWriteCallback() {
+ $lastData = '';
+ $callBack = function ($data) use (&$lastData) {
+ $lastData = $data;
+ };
+
+ $source = fopen('php://temp', 'r+');
+
+ $wrapped = $this->wrapSource($source, null, $callBack);
+ fwrite($wrapped, 'foobar');
+ $this->assertEquals('foobar', $lastData);
+ }
+
+ public function testCloseCallback() {
+ $called = false;
+ $callBack = function () use (&$called) {
+ $called = true;
+ };
+
+ $source = fopen('php://temp', 'r+');
+ fwrite($source, 'foobar');
+ rewind($source);
+
+ $wrapped = $this->wrapSource($source, null, null, $callBack);
+ fclose($wrapped);
+ $this->assertTrue($called);
+ }
+}
diff --git a/apps/files_external/3rdparty/icewind/streams/tests/IteratorDirectory.php b/apps/files_external/3rdparty/icewind/streams/tests/IteratorDirectory.php
new file mode 100644
index 00000000000..0d990468368
--- /dev/null
+++ b/apps/files_external/3rdparty/icewind/streams/tests/IteratorDirectory.php
@@ -0,0 +1,130 @@
+<?php
+/**
+ * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Licensed under the MIT license:
+ * http://opensource.org/licenses/MIT
+ */
+
+namespace Icewind\Streams\Tests;
+
+class IteratorDirectory extends \PHPUnit_Framework_TestCase {
+
+ /**
+ * @param \Iterator | array $source
+ * @return resource
+ */
+ protected function wrapSource($source) {
+ return \Icewind\Streams\IteratorDirectory::wrap($source);
+ }
+
+ /**
+ * @expectedException \BadMethodCallException
+ */
+ public function testNoContext() {
+ $context = stream_context_create(array());
+ stream_wrapper_register('iterator', '\Icewind\Streams\IteratorDirectory');
+ try {
+ opendir('iterator://', $context);
+ stream_wrapper_unregister('iterator');
+ } catch (\Exception $e) {
+ stream_wrapper_unregister('iterator');
+ throw $e;
+ }
+ }
+
+ /**
+ * @expectedException \BadMethodCallException
+ */
+ public function testInvalidSource() {
+ $context = stream_context_create(array(
+ 'dir' => array(
+ 'array' => 2
+ )
+ ));
+ stream_wrapper_register('iterator', '\Icewind\Streams\IteratorDirectory');
+ try {
+ opendir('iterator://', $context);
+ stream_wrapper_unregister('iterator');
+ } catch (\Exception $e) {
+ stream_wrapper_unregister('iterator');
+ throw $e;
+ }
+ }
+
+ /**
+ * @expectedException \BadMethodCallException
+ */
+ public function testWrapInvalidSource() {
+ $this->wrapSource(2);
+ }
+
+ public function fileListProvider() {
+ $longList = array_fill(0, 500, 'foo');
+ return array(
+ array(
+ array(
+ 'foo',
+ 'bar',
+ 'qwerty'
+ )
+ ),
+ array(
+ array(
+ 'with spaces',
+ 'under_scores',
+ '日本語',
+ 'character %$_',
+ '.',
+ '0',
+ 'double "quotes"',
+ "single 'quotes'"
+ )
+ ),
+ array(
+ array(
+ 'single item'
+ )
+ ),
+ array(
+ $longList
+ ),
+ array(
+ array()
+ )
+ );
+ }
+
+ protected function basicTest($fileList, $dh) {
+ $result = array();
+
+ while (($file = readdir($dh)) !== false) {
+ $result[] = $file;
+ }
+
+ $this->assertEquals($fileList, $result);
+
+ rewinddir($dh);
+ if (count($fileList)) {
+ $this->assertEquals($fileList[0], readdir($dh));
+ } else {
+ $this->assertFalse(readdir($dh));
+ }
+ }
+
+ /**
+ * @dataProvider fileListProvider
+ */
+ public function testBasicIterator($fileList) {
+ $iterator = new \ArrayIterator($fileList);
+ $dh = $this->wrapSource($iterator);
+ $this->basicTest($fileList, $dh);
+ }
+
+ /**
+ * @dataProvider fileListProvider
+ */
+ public function testBasicArray($fileList) {
+ $dh = $this->wrapSource($fileList);
+ $this->basicTest($fileList, $dh);
+ }
+}
diff --git a/apps/files_external/3rdparty/icewind/streams/tests/NullWrapper.php b/apps/files_external/3rdparty/icewind/streams/tests/NullWrapper.php
new file mode 100644
index 00000000000..ba42b4dfea1
--- /dev/null
+++ b/apps/files_external/3rdparty/icewind/streams/tests/NullWrapper.php
@@ -0,0 +1,59 @@
+<?php
+/**
+ * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Licensed under the MIT license:
+ * http://opensource.org/licenses/MIT
+ */
+
+namespace Icewind\Streams\Tests;
+
+class NullWrapper extends Wrapper {
+
+ /**
+ * @param resource $source
+ * @return resource
+ */
+ protected function wrapSource($source) {
+ return \Icewind\Streams\NullWrapper::wrap($source);
+ }
+
+ /**
+ * @expectedException \BadMethodCallException
+ */
+ public function testNoContext() {
+ stream_wrapper_register('null', '\Icewind\Streams\NullWrapper');
+ $context = stream_context_create(array());
+ try {
+ fopen('null://', 'r+', false, $context);
+ stream_wrapper_unregister('null');
+ } catch (\Exception $e) {
+ stream_wrapper_unregister('null');
+ throw $e;
+ }
+ }
+
+ /**
+ * @expectedException \BadMethodCallException
+ */
+ public function testNoSource() {
+ stream_wrapper_register('null', '\Icewind\Streams\NullWrapper');
+ $context = stream_context_create(array(
+ 'null' => array(
+ 'source' => 'bar'
+ )
+ ));
+ try {
+ fopen('null://', 'r+', false, $context);
+ } catch (\Exception $e) {
+ stream_wrapper_unregister('null');
+ throw $e;
+ }
+ }
+
+ /**
+ * @expectedException \BadMethodCallException
+ */
+ public function testWrapInvalidSource() {
+ $this->wrapSource('foo');
+ }
+}
diff --git a/apps/files_external/3rdparty/icewind/streams/tests/Wrapper.php b/apps/files_external/3rdparty/icewind/streams/tests/Wrapper.php
new file mode 100644
index 00000000000..6bb644dd611
--- /dev/null
+++ b/apps/files_external/3rdparty/icewind/streams/tests/Wrapper.php
@@ -0,0 +1,105 @@
+<?php
+/**
+ * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Licensed under the MIT license:
+ * http://opensource.org/licenses/MIT
+ */
+
+namespace Icewind\Streams\Tests;
+
+abstract class Wrapper extends \PHPUnit_Framework_TestCase {
+ /**
+ * @param resource $source
+ * @return resource
+ */
+ abstract protected function wrapSource($source);
+
+ public function testRead() {
+ $source = fopen('php://temp', 'r+');
+ fwrite($source, 'foobar');
+ rewind($source);
+
+ $wrapped = $this->wrapSource($source);
+ $this->assertEquals('foo', fread($wrapped, 3));
+ $this->assertEquals('bar', fread($wrapped, 3));
+ $this->assertEquals('', fread($wrapped, 3));
+ }
+
+ public function testWrite() {
+ $source = fopen('php://temp', 'r+');
+ rewind($source);
+
+ $wrapped = $this->wrapSource($source);
+
+ $this->assertEquals(6, fwrite($wrapped, 'foobar'));
+ rewind($source);
+ $this->assertEquals('foobar', stream_get_contents($source));
+ }
+
+ public function testClose() {
+ $source = fopen('php://temp', 'r+');
+ rewind($source);
+
+ $wrapped = $this->wrapSource($source);
+
+ fclose($wrapped);
+ $this->assertFalse(is_resource($source));
+ }
+
+ public function testSeekTell() {
+ $source = fopen('php://temp', 'r+');
+ fwrite($source, 'foobar');
+ rewind($source);
+
+ $wrapped = $this->wrapSource($source);
+
+ $this->assertEquals(0, ftell($wrapped));
+
+ fseek($wrapped, 2);
+ $this->assertEquals(2, ftell($source));
+ $this->assertEquals(2, ftell($wrapped));
+
+ fseek($wrapped, 2, SEEK_CUR);
+ $this->assertEquals(4, ftell($source));
+ $this->assertEquals(4, ftell($wrapped));
+
+ fseek($wrapped, -1, SEEK_END);
+ $this->assertEquals(5, ftell($source));
+ $this->assertEquals(5, ftell($wrapped));
+ }
+
+ public function testStat() {
+ $source = fopen(__FILE__, 'r+');
+ $wrapped = $this->wrapSource($source);
+ $this->assertEquals(stat(__FILE__), fstat($wrapped));
+ }
+
+ public function testTruncate() {
+ if (version_compare(phpversion(), '5.4.0', '<')) {
+ $this->markTestSkipped('php <5.4 doesn\'t support truncate for stream wrappers');
+ }
+ $source = fopen('php://temp', 'r+');
+ fwrite($source, 'foobar');
+ rewind($source);
+ $wrapped = $this->wrapSource($source);
+
+ ftruncate($wrapped, 2);
+ $this->assertEquals('fo', fread($wrapped, 10));
+ }
+
+ public function testLock() {
+ $source = tmpfile();
+ $wrapped = $this->wrapSource($source);
+ if (!flock($wrapped, LOCK_EX)) {
+ $this->fail('Unable to acquire lock');
+ }
+ }
+
+ public function testStreamOptions() {
+ $source = fopen('php://temp', 'r+');
+ $wrapped = $this->wrapSource($source);
+ stream_set_blocking($wrapped, 0);
+ stream_set_timeout($wrapped, 1, 0);
+ stream_set_write_buffer($wrapped, 0);
+ }
+}
diff --git a/apps/files_external/3rdparty/icewind/streams/tests/bootstrap.php b/apps/files_external/3rdparty/icewind/streams/tests/bootstrap.php
new file mode 100644
index 00000000000..2c17fd57feb
--- /dev/null
+++ b/apps/files_external/3rdparty/icewind/streams/tests/bootstrap.php
@@ -0,0 +1,9 @@
+<?php
+/**
+ * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Licensed under the MIT license:
+ * http://opensource.org/licenses/MIT
+ */
+
+date_default_timezone_set('UTC');
+require_once __DIR__ . '/../vendor/autoload.php';
diff --git a/apps/files_external/3rdparty/icewind/streams/tests/phpunit.xml b/apps/files_external/3rdparty/icewind/streams/tests/phpunit.xml
new file mode 100644
index 00000000000..e3d96352c43
--- /dev/null
+++ b/apps/files_external/3rdparty/icewind/streams/tests/phpunit.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<phpunit bootstrap="bootstrap.php">
+ <testsuite name='Stream'>
+ <directory suffix='.php'>./</directory>
+ </testsuite>
+</phpunit>