initial version

This commit is contained in:
Robin Appelman 2014-07-23 23:02:10 +02:00
commit d54615fd3a
11 changed files with 494 additions and 0 deletions

76
src/CallbackWrapper.php Normal file
View file

@ -0,0 +1,76 @@
<?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 before the operation is executed on the source stream
*/
class CallBackWrapper extends Wrapper {
/**
* @var callable
*/
protected $readCallback;
/**
* @var callable
*/
protected $writeCallback;
/**
* @var callable
*/
protected $closeCallback;
public function stream_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'];
}
return true;
}
public function stream_read($count) {
if ($this->readCallback) {
call_user_func($this->readCallback, $count);
}
return parent::stream_read($count);
}
public function stream_write($data) {
if ($this->writeCallback) {
call_user_func($this->writeCallback, $data);
}
return parent::stream_write($data);
}
public function stream_close() {
if ($this->closeCallback) {
call_user_func($this->closeCallback);
}
return parent::stream_close();
}
}

15
src/NullWrapper.php Normal file
View file

@ -0,0 +1,15 @@
<?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;
class NullWrapper extends Wrapper {
public function stream_open() {
$this->loadContext('null');
return true;
}
}

105
src/Wrapper.php Normal file
View file

@ -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;
/**
* 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 {
/**
* 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);
}
}