owncloud/core

View on GitHub
lib/private/Files/Stream/StaticStream.php

Summary

Maintainability
A
3 hrs
Test Coverage
<?php
/**
 * @author Morris Jobke <hey@morrisjobke.de>
 * @author Robin Appelman <icewind@owncloud.com>
 * @author Thomas Müller <thomas.mueller@tmit.eu>
 *
 * @copyright Copyright (c) 2018, ownCloud GmbH
 * @license AGPL-3.0
 *
 * This code is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License, version 3,
 * as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License, version 3,
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
 *
 */

namespace OC\Files\Stream;

class StaticStream {
    public const MODE_FILE = 0100000;

    public $context;
    protected static $data = [];

    protected $path = '';
    protected $pointer = 0;
    protected $writable = false;

    public function stream_close() {
    }

    public function stream_eof() {
        return $this->pointer >= \strlen(self::$data[$this->path]);
    }

    public function stream_flush() {
    }

    public static function clear() {
        self::$data = [];
    }

    public function stream_open($path, $mode, $options, &$opened_path) {
        switch ($mode[0]) {
            case 'r':
                if (!isset(self::$data[$path])) {
                    return false;
                }
                $this->path = $path;
                $this->writable = isset($mode[1]) && $mode[1] == '+';
                break;
            case 'w':
                self::$data[$path] = '';
                $this->path = $path;
                $this->writable = true;
                break;
            case 'a':
                if (!isset(self::$data[$path])) {
                    self::$data[$path] = '';
                }
                $this->path = $path;
                $this->writable = true;
                $this->pointer = \strlen(self::$data[$path]);
                break;
            case 'x':
                if (isset(self::$data[$path])) {
                    return false;
                }
                $this->path = $path;
                $this->writable = true;
                break;
            case 'c':
                if (!isset(self::$data[$path])) {
                    self::$data[$path] = '';
                }
                $this->path = $path;
                $this->writable = true;
                break;
            default:
                return false;
        }
        $opened_path = $this->path;
        return true;
    }

    public function stream_read($count) {
        $bytes = \min(\strlen(self::$data[$this->path]) - $this->pointer, $count);
        $data = \substr(self::$data[$this->path], $this->pointer, $bytes);
        $this->pointer += $bytes;
        return $data;
    }

    public function stream_seek($offset, $whence = SEEK_SET) {
        $len = \strlen(self::$data[$this->path]);
        switch ($whence) {
            case SEEK_SET:
                if ($offset <= $len) {
                    $this->pointer = $offset;
                    return true;
                }
                break;
            case SEEK_CUR:
                if ($this->pointer + $offset <= $len) {
                    $this->pointer += $offset;
                    return true;
                }
                break;
            case SEEK_END:
                if ($len + $offset <= $len) {
                    $this->pointer = $len + $offset;
                    return true;
                }
                break;
        }
        return false;
    }

    public function stream_stat() {
        return $this->url_stat($this->path);
    }

    public function stream_tell() {
        return $this->pointer;
    }

    public function stream_write($data) {
        if (!$this->writable) {
            return 0;
        }
        $size = \strlen($data);
        if ($this->stream_eof()) {
            self::$data[$this->path] .= $data;
        } else {
            self::$data[$this->path] = \substr_replace(
                self::$data[$this->path],
                $data,
                $this->pointer
            );
        }
        $this->pointer += $size;
        return $size;
    }

    public function unlink($path) {
        if (isset(self::$data[$path])) {
            unset(self::$data[$path]);
        }
        return true;
    }

    public function url_stat($path) {
        if (isset(self::$data[$path])) {
            $size = \strlen(self::$data[$path]);
            $time = \time();
            $data = [
                'dev' => 0,
                'ino' => 0,
                'mode' => self::MODE_FILE | 0777,
                'nlink' => 1,
                'uid' => 0,
                'gid' => 0,
                'rdev' => '',
                'size' => $size,
                'atime' => $time,
                'mtime' => $time,
                'ctime' => $time,
                'blksize' => -1,
                'blocks' => -1,
            ];
            return \array_values($data) + $data;
        }
        return false;
    }
}