streamwrappers.php 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. <?php
  2. class OC_FakeDirStream{
  3. public static $dirs=array();
  4. private $name;
  5. private $index;
  6. public function dir_opendir($path,$options){
  7. $this->name=substr($path,strlen('fakedir://'));
  8. $this->index=0;
  9. if(!isset(self::$dirs[$this->name])){
  10. self::$dirs[$this->name]=array();
  11. }
  12. return true;
  13. }
  14. public function dir_readdir(){
  15. if($this->index>=count(self::$dirs[$this->name])){
  16. return false;
  17. }
  18. $filename=self::$dirs[$this->name][$this->index];
  19. $this->index++;
  20. return $filename;
  21. }
  22. public function dir_closedir() {
  23. $this->name='';
  24. return true;
  25. }
  26. public function dir_rewinddir() {
  27. $this->index=0;
  28. return true;
  29. }
  30. }
  31. class OC_StaticStreamWrapper {
  32. public $context;
  33. protected static $data = array();
  34. protected $path = '';
  35. protected $pointer = 0;
  36. protected $writable = false;
  37. public function stream_close() {}
  38. public function stream_eof() {
  39. return $this->pointer >= strlen(self::$data[$this->path]);
  40. }
  41. public function stream_flush() {}
  42. public function stream_open($path, $mode, $options, &$opened_path) {
  43. switch ($mode[0]) {
  44. case 'r':
  45. if (!isset(self::$data[$path])) return false;
  46. $this->path = $path;
  47. $this->writable = isset($mode[1]) && $mode[1] == '+';
  48. break;
  49. case 'w':
  50. self::$data[$path] = '';
  51. $this->path = $path;
  52. $this->writable = true;
  53. break;
  54. case 'a':
  55. if (!isset(self::$data[$path])) self::$data[$path] = '';
  56. $this->path = $path;
  57. $this->writable = true;
  58. $this->pointer = strlen(self::$data[$path]);
  59. break;
  60. case 'x':
  61. if (isset(self::$data[$path])) return false;
  62. $this->path = $path;
  63. $this->writable = true;
  64. break;
  65. case 'c':
  66. if (!isset(self::$data[$path])) self::$data[$path] = '';
  67. $this->path = $path;
  68. $this->writable = true;
  69. break;
  70. default:
  71. return false;
  72. }
  73. $opened_path = $this->path;
  74. return true;
  75. }
  76. public function stream_read($count) {
  77. $bytes = min(strlen(self::$data[$this->path]) - $this->pointer, $count);
  78. $data = substr(self::$data[$this->path], $this->pointer, $bytes);
  79. $this->pointer += $bytes;
  80. return $data;
  81. }
  82. public function stream_seek($offset, $whence = SEEK_SET) {
  83. $len = strlen(self::$data[$this->path]);
  84. switch ($whence) {
  85. case SEEK_SET:
  86. if ($offset <= $len) {
  87. $this->pointer = $offset;
  88. return true;
  89. }
  90. break;
  91. case SEEK_CUR:
  92. if ($this->pointer + $offset <= $len) {
  93. $this->pointer += $offset;
  94. return true;
  95. }
  96. break;
  97. case SEEK_END:
  98. if ($len + $offset <= $len) {
  99. $this->pointer = $len + $offset;
  100. return true;
  101. }
  102. break;
  103. }
  104. return false;
  105. }
  106. public function stream_stat() {
  107. $size = strlen(self::$data[$this->path]);
  108. $time = time();
  109. return array(
  110. 0 => 0,
  111. 'dev' => 0,
  112. 1 => 0,
  113. 'ino' => 0,
  114. 2 => 0777,
  115. 'mode' => 0777,
  116. 3 => 1,
  117. 'nlink' => 1,
  118. 4 => 0,
  119. 'uid' => 0,
  120. 5 => 0,
  121. 'gid' => 0,
  122. 6 => '',
  123. 'rdev' => '',
  124. 7 => $size,
  125. 'size' => $size,
  126. 8 => $time,
  127. 'atime' => $time,
  128. 9 => $time,
  129. 'mtime' => $time,
  130. 10 => $time,
  131. 'ctime' => $time,
  132. 11 => -1,
  133. 'blksize' => -1,
  134. 12 => -1,
  135. 'blocks' => -1,
  136. );
  137. }
  138. public function stream_tell() {
  139. return $this->pointer;
  140. }
  141. public function stream_write($data) {
  142. if (!$this->writable) return 0;
  143. $size = strlen($data);
  144. if ($this->stream_eof()) {
  145. self::$data[$this->path] .= $data;
  146. } else {
  147. self::$data[$this->path] = substr_replace(
  148. self::$data[$this->path],
  149. $data,
  150. $this->pointer
  151. );
  152. }
  153. $this->pointer += $size;
  154. return $size;
  155. }
  156. public function unlink($path) {
  157. if (isset(self::$data[$path])) {
  158. unset(self::$data[$path]);
  159. }
  160. return true;
  161. }
  162. public function url_stat($path) {
  163. if (isset(self::$data[$path])) {
  164. $size = strlen(self::$data[$path]);
  165. $time = time();
  166. return array(
  167. 0 => 0,
  168. 'dev' => 0,
  169. 1 => 0,
  170. 'ino' => 0,
  171. 2 => 0777,
  172. 'mode' => 0777,
  173. 3 => 1,
  174. 'nlink' => 1,
  175. 4 => 0,
  176. 'uid' => 0,
  177. 5 => 0,
  178. 'gid' => 0,
  179. 6 => '',
  180. 'rdev' => '',
  181. 7 => $size,
  182. 'size' => $size,
  183. 8 => $time,
  184. 'atime' => $time,
  185. 9 => $time,
  186. 'mtime' => $time,
  187. 10 => $time,
  188. 'ctime' => $time,
  189. 11 => -1,
  190. 'blksize' => -1,
  191. 12 => -1,
  192. 'blocks' => -1,
  193. );
  194. }
  195. return false;
  196. }
  197. }
  198. /**
  199. * stream wrapper that provides a callback on stream close
  200. */
  201. class OC_CloseStreamWrapper{
  202. public static $callBacks=array();
  203. private $path='';
  204. private $source;
  205. private static $open=array();
  206. public function stream_open($path, $mode, $options, &$opened_path){
  207. $path=substr($path,strlen('close://'));
  208. $this->path=$path;
  209. $this->source=fopen($path,$mode);
  210. if(is_resource($this->source)){
  211. $this->meta=stream_get_meta_data($this->source);
  212. }
  213. self::$open[]=$path;
  214. return is_resource($this->source);
  215. }
  216. public function stream_seek($offset, $whence=SEEK_SET){
  217. fseek($this->source,$offset,$whence);
  218. }
  219. public function stream_tell(){
  220. return ftell($this->source);
  221. }
  222. public function stream_read($count){
  223. return fread($this->source,$count);
  224. }
  225. public function stream_write($data){
  226. return fwrite($this->source,$data);
  227. }
  228. public function stream_set_option($option,$arg1,$arg2){
  229. switch($option){
  230. case STREAM_OPTION_BLOCKING:
  231. stream_set_blocking($this->source,$arg1);
  232. break;
  233. case STREAM_OPTION_READ_TIMEOUT:
  234. stream_set_timeout($this->source,$arg1,$arg2);
  235. break;
  236. case STREAM_OPTION_WRITE_BUFFER:
  237. stream_set_write_buffer($this->source,$arg1,$arg2);
  238. }
  239. }
  240. public function stream_stat(){
  241. return fstat($this->source);
  242. }
  243. public function stream_lock($mode){
  244. flock($this->source,$mode);
  245. }
  246. public function stream_flush(){
  247. return fflush($this->source);
  248. }
  249. public function stream_eof(){
  250. return feof($this->source);
  251. }
  252. public function url_stat($path) {
  253. $path=substr($path,strlen('close://'));
  254. if(file_exists($path)){
  255. return stat($path);
  256. }else{
  257. return false;
  258. }
  259. }
  260. public function stream_close(){
  261. fclose($this->source);
  262. if(isset(self::$callBacks[$this->path])){
  263. call_user_func(self::$callBacks[$this->path],$this->path);
  264. }
  265. }
  266. public function unlink($path){
  267. $path=substr($path,strlen('close://'));
  268. return unlink($path);
  269. }
  270. }