Passed
Push — master ( b21215...d63abe )
by Roeland
13:25 queued 17s
created

HashWrapper::stream_close()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 4
c 1
b 0
f 0
nc 2
nop 0
dl 0
loc 7
rs 10
1
<?php declare(strict_types=1);
2
/**
3
 * @copyright Copyright (c) 2020 Robin Appelman <[email protected]>
4
 *
5
 * @license GNU AGPL version 3 or any later version
6
 *
7
 * This program is free software: you can redistribute it and/or modify
8
 * it under the terms of the GNU Affero General Public License as
9
 * published by the Free Software Foundation, either version 3 of the
10
 * License, or (at your option) any later version.
11
 *
12
 * This program is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU Affero General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Affero General Public License
18
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
 *
20
 */
21
22
namespace OC\Files\Stream;
23
24
use Icewind\Streams\Wrapper;
25
26
class HashWrapper extends Wrapper {
27
	protected $callback;
28
	protected $hash;
29
30
	public static function wrap($source, string $algo, callable $callback) {
31
		$hash = hash_init($algo);
32
		$context = stream_context_create([
33
			'hash' => [
34
				'source' => $source,
35
				'callback' => $callback,
36
				'hash' => $hash,
37
			],
38
		]);
39
		return Wrapper::wrapSource($source, $context, 'hash', self::class);
40
	}
41
42
	protected function open() {
43
		$context = $this->loadContext('hash');
44
45
		$this->callback = $context['callback'];
46
		$this->hash = $context['hash'];
47
		return true;
48
	}
49
50
	public function dir_opendir($path, $options) {
51
		return $this->open();
52
	}
53
54
	public function stream_open($path, $mode, $options, &$opened_path) {
55
		return $this->open();
56
	}
57
58
	public function stream_read($count) {
59
		$result = parent::stream_read($count);
60
		hash_update($this->hash, $result);
61
		return $result;
62
	}
63
64
	public function stream_close() {
65
		if (is_callable($this->callback)) {
66
			call_user_func($this->callback, hash_final($this->hash));
67
			// prevent further calls by potential PHP 7 GC ghosts
68
			$this->callback = null;
69
		}
70
		return parent::stream_close();
71
	}
72
}
73