GzDumpReader::initReader()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 3

Importance

Changes 0
Metric Value
dl 0
loc 11
rs 9.9
c 0
b 0
f 0
cc 3
nc 3
nop 0
ccs 7
cts 7
cp 1
crap 3
1
<?php
2
3
declare( strict_types = 1 );
4
5
namespace Wikibase\JsonDumpReader\Reader;
6
7
use Wikibase\JsonDumpReader\SeekableDumpReader;
8
use Wikibase\JsonDumpReader\DumpReadingException;
9
10
/**
11
 * Package private
12
 *
13
 * @licence GNU GPL v2+
14
 * @author Jeroen De Dauw < [email protected] >
15
 */
16
class GzDumpReader implements SeekableDumpReader {
17
18
	/**
19
	 * @var string
20
	 */
21
	private $dumpFile;
22
23
	/**
24
	 * @var int
25
	 */
26
	private $initialPosition;
27
28
	/**
29
	 * @var resource|null
30
	 */
31
	private $handle = null;
32
33
	/**
34
	 * @param string $dumpFilePath
35
	 * @param int $initialPosition
36
	 */
37 5
	public function __construct( $dumpFilePath, $initialPosition = 0 ) {
38 5
		$this->dumpFile = $dumpFilePath;
39 5
		$this->initialPosition = $initialPosition;
40 5
	}
41
42 5
	public function __destruct() {
43 5
		$this->closeReader();
44 5
	}
45
46 5
	private function closeReader() {
47 5
		if ( is_resource( $this->handle ) ) {
48 4
			gzclose( $this->handle );
49 4
			$this->handle = null;
50
		}
51 5
	}
52
53 1
	public function rewind(): void {
54 1
		$this->closeReader();
55 1
		$this->initReader();
56 1
	}
57
58 5
	private function initReader() {
59 5
		if ( $this->handle === null ) {
60 5
			$this->handle = @gzopen( $this->dumpFile, 'r' );
61
62 5
			if ( $this->handle === false ) {
63 1
				throw new DumpReadingException( 'Could not open file: ' . $this->dumpFile );
64
			}
65
66 4
			$this->seekToPosition( $this->initialPosition );
67
		}
68 4
	}
69
70
	/**
71
	 * @return string|null
72
	 * @throws DumpReadingException
73
	 */
74 5
	public function nextJsonLine(): ?string {
75 5
		$this->initReader();
76
77
		do {
78 4
			if ( gzeof( $this->handle ) ) {
79 2
				return null;
80
			}
81
82 4
			$line = @gzgets( $this->handle );
83
84 4
			if ( $line === false ) {
85
				return null;
86
			}
87
		}
88 4
		while ( $line === '' || $line{0} !== '{' );
89
90 3
		return rtrim( $line, ",\n\r" );
91
	}
92
93
	/**
94
	 * @return int
95
	 * @throws DumpReadingException
96
	 */
97 1
	public function getPosition(): int {
98 1
		if ( PHP_INT_SIZE < 8 ) {
99
			throw new DumpReadingException( 'Cannot reliably get the file position on 32bit PHP' );
100
		}
101
102 1
		$this->initReader();
103 1
		$position = @gztell( $this->handle );
104
105 1
		if ( !is_int( $position ) ) {
106
			throw new DumpReadingException( 'Could not tell the position of the file handle' );
107
		}
108
109 1
		return $position;
110
	}
111
112
	/**
113
	 * @param int $position
114
	 * @throws DumpReadingException
115
	 */
116 4
	public function seekToPosition( int $position ): void {
117 4
		$this->initReader();
118 4
		$seekResult = @gzseek( $this->handle, $position );
119
120 4
		if ( $seekResult !== 0 ) {
121
			throw new DumpReadingException( 'Seeking to position failed' );
122
		}
123 4
	}
124
125
}
126