Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/3rdparty.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoeland Jago Douma <rullzer@owncloud.com>2015-11-18 11:38:19 +0300
committerRoeland Jago Douma <rullzer@owncloud.com>2015-11-18 11:38:19 +0300
commitda0cd71e5b38087101baf116ed2e3373d67664cb (patch)
treeaa1acf5e16202a3f0ba58a75fcd945d58e68cdde /icewind
parentbe700d4918627e06eb3e8c5f3b025911061badff (diff)
Bump 3rdparty for icewind/streams-0.3.0
Diffstat (limited to 'icewind')
-rw-r--r--icewind/streams/README.md52
-rw-r--r--icewind/streams/composer.json23
-rw-r--r--icewind/streams/src/CallbackWrapper.php67
-rw-r--r--icewind/streams/src/File.php2
-rw-r--r--icewind/streams/src/IteratorDirectory.php4
-rw-r--r--icewind/streams/src/NullWrapper.php15
-rw-r--r--icewind/streams/src/Path.php104
-rw-r--r--icewind/streams/src/Url.php64
-rw-r--r--icewind/streams/src/UrlCallBack.php121
-rw-r--r--icewind/streams/src/Wrapper.php31
10 files changed, 367 insertions, 116 deletions
diff --git a/icewind/streams/README.md b/icewind/streams/README.md
deleted file mode 100644
index 54f6d19a..00000000
--- a/icewind/streams/README.md
+++ /dev/null
@@ -1,52 +0,0 @@
-#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/icewind/streams/composer.json b/icewind/streams/composer.json
deleted file mode 100644
index 86d3c834..00000000
--- a/icewind/streams/composer.json
+++ /dev/null
@@ -1,23 +0,0 @@
-{
- "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/icewind/streams/src/CallbackWrapper.php b/icewind/streams/src/CallbackWrapper.php
index fd99aa6e..c5847b95 100644
--- a/icewind/streams/src/CallbackWrapper.php
+++ b/icewind/streams/src/CallbackWrapper.php
@@ -13,10 +13,11 @@ namespace Icewind\Streams;
* 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)
+ * 'source' => resource
+ * 'read' => function($count){} (optional)
+ * 'write' => function($data){} (optional)
+ * 'close' => function(){} (optional)
+ * 'readdir' => function(){} (optional)
* ]
* ]
*
@@ -39,54 +40,56 @@ class CallbackWrapper extends Wrapper {
protected $closeCallback;
/**
+ * @var callable
+ */
+ protected $readDirCallBack;
+
+ /**
* Wraps a stream with the provided callbacks
*
* @param resource $source
* @param callable $read (optional)
* @param callable $write (optional)
* @param callable $close (optional)
+ * @param callable $readDir (optional)
* @return resource
*
* @throws \BadMethodCallException
*/
- public static function wrap($source, $read = null, $write = null, $close = null) {
+ public static function wrap($source, $read = null, $write = null, $close = null, $readDir = null) {
$context = stream_context_create(array(
'callback' => array(
'source' => $source,
'read' => $read,
'write' => $write,
- 'close' => $close
+ 'close' => $close,
+ 'readDir' => $readDir
)
));
- 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;
+ return Wrapper::wrapSource($source, $context, 'callback', '\Icewind\Streams\CallbackWrapper');
}
- public function stream_open($path, $mode, $options, &$opened_path) {
+ protected function open() {
$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'];
- }
+ $this->readCallback = $context['read'];
+ $this->writeCallback = $context['write'];
+ $this->closeCallback = $context['close'];
+ $this->readDirCallBack = $context['readDir'];
return true;
}
+ public function dir_opendir($path, $options) {
+ return $this->open();
+ }
+
+ public function stream_open($path, $mode, $options, &$opened_path) {
+ return $this->open();
+ }
+
public function stream_read($count) {
$result = parent::stream_read($count);
- if ($this->readCallback) {
+ if (is_callable($this->readCallback)) {
call_user_func($this->readCallback, $count);
}
return $result;
@@ -94,7 +97,7 @@ class CallbackWrapper extends Wrapper {
public function stream_write($data) {
$result = parent::stream_write($data);
- if ($this->writeCallback) {
+ if (is_callable($this->writeCallback)) {
call_user_func($this->writeCallback, $data);
}
return $result;
@@ -102,9 +105,17 @@ class CallbackWrapper extends Wrapper {
public function stream_close() {
$result = parent::stream_close();
- if ($this->closeCallback) {
+ if (is_callable($this->closeCallback)) {
call_user_func($this->closeCallback);
}
return $result;
}
+
+ public function dir_readdir() {
+ $result = parent::dir_readdir();
+ if (is_callable($this->readDirCallBack)) {
+ call_user_func($this->readDirCallBack);
+ }
+ return $result;
+ }
}
diff --git a/icewind/streams/src/File.php b/icewind/streams/src/File.php
index 6202ef4a..252b7b89 100644
--- a/icewind/streams/src/File.php
+++ b/icewind/streams/src/File.php
@@ -21,7 +21,7 @@ interface File {
public function stream_open($path, $mode, $options, &$opened_path);
/**
- * @param string $offset
+ * @param int $offset
* @param int $whence
* @return bool
*/
diff --git a/icewind/streams/src/IteratorDirectory.php b/icewind/streams/src/IteratorDirectory.php
index c4eac5d4..6dfa42a8 100644
--- a/icewind/streams/src/IteratorDirectory.php
+++ b/icewind/streams/src/IteratorDirectory.php
@@ -45,9 +45,9 @@ class IteratorDirectory implements Directory {
} else {
throw new \BadMethodCallException('Invalid context, "' . $name . '" options not set');
}
- if (isset($context['iterator']) and $context['iterator'] instanceof \Iterator) {
+ if (isset($context['iterator'])) {
$this->iterator = $context['iterator'];
- } else if (isset($context['array']) and is_array($context['array'])) {
+ } else if (isset($context['array'])) {
$this->iterator = new \ArrayIterator($context['array']);
} else {
throw new \BadMethodCallException('Invalid context, iterator or array not set');
diff --git a/icewind/streams/src/NullWrapper.php b/icewind/streams/src/NullWrapper.php
index 8cbaaa75..b6c71d98 100644
--- a/icewind/streams/src/NullWrapper.php
+++ b/icewind/streams/src/NullWrapper.php
@@ -24,19 +24,16 @@ class NullWrapper extends Wrapper {
'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;
+ return Wrapper::wrapSource($source, $context, 'null', '\Icewind\Streams\NullWrapper');
}
public function stream_open($path, $mode, $options, &$opened_path) {
$this->loadContext('null');
return true;
}
+
+ public function dir_opendir($path, $options) {
+ $this->loadContext('null');
+ return true;
+ }
}
diff --git a/icewind/streams/src/Path.php b/icewind/streams/src/Path.php
new file mode 100644
index 00000000..46d2156b
--- /dev/null
+++ b/icewind/streams/src/Path.php
@@ -0,0 +1,104 @@
+<?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;
+
+/**
+ * A string-like object that automatically registers a stream wrapper when used and removes the stream wrapper when no longer used
+ *
+ * Can optionally pass context options to the stream wrapper
+ */
+class Path {
+
+ /**
+ * @var bool
+ */
+ protected $registered = false;
+
+ /**
+ * @var string
+ */
+ protected $protocol;
+
+ /**
+ * @var string
+ */
+ protected $class;
+
+ /**
+ * @var array
+ */
+ protected $contextOptions;
+
+ /**
+ * @param string $class
+ * @param array $contextOptions
+ */
+ public function __construct($class, $contextOptions = array()) {
+ $this->class = $class;
+ $this->contextOptions = $contextOptions;
+ }
+
+ public function getProtocol() {
+ if (!$this->protocol) {
+ $this->protocol = 'auto' . uniqid();
+ }
+ return $this->protocol;
+ }
+
+ public function wrapPath($path) {
+ return $this->getProtocol() . '://' . $path;
+ }
+
+ protected function register() {
+ if (!$this->registered) {
+ $this->appendDefaultContent($this->getProtocol(), $this->contextOptions);
+ stream_wrapper_register($this->getProtocol(), $this->class);
+ $this->registered = true;
+ }
+ }
+
+ protected function unregister() {
+ stream_wrapper_unregister($this->getProtocol());
+ $this->unsetDefaultContent($this->getProtocol());
+ $this->registered = false;
+ }
+
+ /**
+ * Add values to the default stream context
+ *
+ * @param string $key
+ * @param array $values
+ */
+ protected function appendDefaultContent($key, $values) {
+ $context = stream_context_get_default();
+ $defaults = stream_context_get_options($context);
+ $defaults[$key] = $values;
+ stream_context_set_default($defaults);
+ }
+
+ /**
+ * Remove values from the default stream context
+ *
+ * @param string $key
+ */
+ protected function unsetDefaultContent($key) {
+ $context = stream_context_get_default();
+ $defaults = stream_context_get_options($context);
+ unset($defaults[$key]);
+ stream_context_set_default($defaults);
+ }
+
+ public function __toString() {
+ $this->register();
+ return $this->protocol . '://';
+ }
+
+ public function __destruct() {
+ $this->unregister();
+ }
+}
diff --git a/icewind/streams/src/Url.php b/icewind/streams/src/Url.php
new file mode 100644
index 00000000..d6822608
--- /dev/null
+++ b/icewind/streams/src/Url.php
@@ -0,0 +1,64 @@
+<?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 implement url functions such as unlink, stat
+ */
+interface Url {
+ /**
+ * @param string $path
+ * @param array $options
+ * @return bool
+ */
+ public function dir_opendir($path, $options);
+
+ /**
+ * @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 $path
+ * @param int $mode
+ * @param int $options
+ * @return bool
+ */
+ public function mkdir($path, $mode, $options);
+
+ /**
+ * @param string $source
+ * @param string $target
+ * @return bool
+ */
+ public function rename($source, $target);
+
+ /**
+ * @param string $path
+ * @param int $options
+ * @return bool
+ */
+ public function rmdir($path, $options);
+
+ /**
+ * @param string
+ * @return bool
+ */
+ public function unlink($path);
+
+ /**
+ * @param string $path
+ * @param int $flags
+ * @return array
+ */
+ public function url_stat($path, $flags);
+}
diff --git a/icewind/streams/src/UrlCallBack.php b/icewind/streams/src/UrlCallBack.php
new file mode 100644
index 00000000..580bfc6b
--- /dev/null
+++ b/icewind/streams/src/UrlCallBack.php
@@ -0,0 +1,121 @@
+<?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 url actions such as fopen, unlink, rename
+ *
+ * Usage:
+ *
+ * $path = UrlCallBack('/path/so/source', function(){
+ * echo 'fopen';
+ * }, function(){
+ * echo 'opendir';
+ * }, function(){
+ * echo 'mkdir';
+ * }, function(){
+ * echo 'rename';
+ * }, function(){
+ * echo 'rmdir';
+ * }, function(){
+ * echo 'unlink';
+ * }, function(){
+ * echo 'stat';
+ * });
+ *
+ * mkdir($path);
+ * ...
+ *
+ * All callbacks are called after the operation is executed on the source stream
+ */
+class UrlCallback extends Wrapper implements Url {
+
+ /**
+ * @param string $source
+ * @param callable $fopen
+ * @param callable $opendir
+ * @param callable $mkdir
+ * @param callable $rename
+ * @param callable $rmdir
+ * @param callable $unlink
+ * @param callable $stat
+ * @return \Icewind\Streams\Path
+ *
+ * @throws \BadMethodCallException
+ * @throws \Exception
+ */
+ public static function wrap($source, $fopen = null, $opendir = null, $mkdir = null, $rename = null, $rmdir = null,
+ $unlink = null, $stat = null) {
+ $options = array(
+ 'source' => $source,
+ 'fopen' => $fopen,
+ 'opendir' => $opendir,
+ 'mkdir' => $mkdir,
+ 'rename' => $rename,
+ 'rmdir' => $rmdir,
+ 'unlink' => $unlink,
+ 'stat' => $stat
+ );
+ return new Path('\Icewind\Streams\UrlCallBack', $options);
+ }
+
+ protected function loadContext($url) {
+ list($protocol) = explode('://', $url);
+ $options = stream_context_get_options($this->context);
+ return $options[$protocol];
+ }
+
+ protected function callCallBack($context, $callback) {
+ if (is_callable($context[$callback])) {
+ call_user_func($context[$callback]);
+ }
+ }
+
+ public function stream_open($path, $mode, $options, &$opened_path) {
+ $context = $this->loadContext($path);
+ $this->callCallBack($context, 'fopen');
+ $this->setSourceStream(fopen($context['source'], $mode));
+ return true;
+ }
+
+ public function dir_opendir($path, $options) {
+ $context = $this->loadContext($path);
+ $this->callCallBack($context, 'opendir');
+ $this->setSourceStream(opendir($context['source']));
+ return true;
+ }
+
+ public function mkdir($path, $mode, $options) {
+ $context = $this->loadContext($path);
+ $this->callCallBack($context, 'mkdir');
+ return mkdir($context['source'], $mode, $options & STREAM_MKDIR_RECURSIVE);
+ }
+
+ public function rmdir($path, $options) {
+ $context = $this->loadContext($path);
+ $this->callCallBack($context, 'rmdir');
+ return rmdir($context['source']);
+ }
+
+ public function rename($source, $target) {
+ $context = $this->loadContext($source);
+ $this->callCallBack($context, 'rename');
+ list(, $target) = explode('://', $target);
+ return rename($context['source'], $target);
+ }
+
+ public function unlink($path) {
+ $context = $this->loadContext($path);
+ $this->callCallBack($context, 'unlink');
+ return unlink($context['source']);
+ }
+
+ public function url_stat($path, $flags) {
+ throw new \Exception('stat is not supported due to php bug 50526');
+ }
+}
diff --git a/icewind/streams/src/Wrapper.php b/icewind/streams/src/Wrapper.php
index 2e3a6e6c..53de2942 100644
--- a/icewind/streams/src/Wrapper.php
+++ b/icewind/streams/src/Wrapper.php
@@ -12,7 +12,7 @@ namespace Icewind\Streams;
*
* This wrapper itself doesn't implement any functionality but is just a base class for other wrappers to extend
*/
-abstract class Wrapper implements File {
+abstract class Wrapper implements File, Directory {
/**
* @var resource
*/
@@ -25,6 +25,22 @@ abstract class Wrapper implements File {
*/
protected $source;
+ protected static function wrapSource($source, $context, $protocol, $class) {
+ try {
+ stream_wrapper_register($protocol, $class);
+ if (@rewinddir($source) === false) {
+ $wrapped = fopen($protocol . '://', 'r+', false, $context);
+ } else {
+ $wrapped = opendir($protocol . '://', $context);
+ }
+ } catch (\BadMethodCallException $e) {
+ stream_wrapper_unregister($protocol);
+ throw $e;
+ }
+ stream_wrapper_unregister($protocol);
+ return $wrapped;
+ }
+
/**
* Load the source from the stream context and return the context options
*
@@ -107,4 +123,17 @@ abstract class Wrapper implements File {
public function stream_close() {
return fclose($this->source);
}
+
+ public function dir_readdir() {
+ return readdir($this->source);
+ }
+
+ public function dir_closedir() {
+ closedir($this->source);
+ return true;
+ }
+
+ public function dir_rewinddir() {
+ return rewind($this->source);
+ }
}