Passed
Push — master ( 8a2626...808886 )
by Daniel
01:53
created

RarFileReader   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 116
Duplicated Lines 0 %

Test Coverage

Coverage 97.83%

Importance

Changes 3
Bugs 0 Features 0
Metric Value
wmc 10
eloc 43
c 3
b 0
f 0
dl 0
loc 116
ccs 45
cts 46
cp 0.9783
rs 10

5 Methods

Rating   Name   Duplication   Size   Complexity  
A openFile() 0 5 1
A createRarArchive() 0 24 2
A __construct() 0 4 1
A readSignature() 0 24 3
A createRarArchiveStruct() 0 15 3
1
<?php
2
3
namespace Selective\Rar;
4
5
use Selective\Rar\Struct\RarArchiveStruct;
6
use SplFileObject;
7
use UnexpectedValueException;
8
9
/**
10
 * RAR file reader.
11
 */
12
final class RarFileReader
13
{
14
    /**
15
     * @var Rar4FileReader
16
     */
17
    private $rar4;
18
19
    /**
20
     * @var Rar5FileReader
21
     */
22
    private $rar5;
23
24
    /**
25
     * The constructor.
26
     */
27 3
    public function __construct()
28
    {
29 3
        $this->rar4 = new Rar4FileReader();
30 3
        $this->rar5 = new Rar5FileReader();
31
    }
32
33
    /**
34
     * Open RAR file.
35
     *
36
     * @param SplFileObject $file The rar file
37
     *
38
     * @return RarArchive The RAR archive
39
     */
40 3
    public function openFile(SplFileObject $file): RarArchive
41
    {
42 3
        $file->rewind();
43
44 3
        return $this->createRarArchive($this->createRarArchiveStruct($file));
45
    }
46
47
    /**
48
     * Create RarArchive instance.
49
     *
50
     * @param RarArchiveStruct $rarArchiveStruct The archive struct
51
     *
52
     * @return RarArchive The RAR archive
53
     */
54 3
    private function createRarArchive(RarArchiveStruct $rarArchiveStruct): RarArchive
55
    {
56 3
        $rarArchive = new RarArchive();
57
58 3
        foreach ($rarArchiveStruct->files as $file) {
59 3
            $entry = new RarEntry();
60
61 3
            $rarArchive = $rarArchive->addEntry(
62 3
                $entry
63 3
                    ->withAttr($file->fileAttr)
64 3
                    ->withCrc($file->fileCRC)
65 3
                    ->withFileTime($file->fileTime)
66 3
                    ->withHostOs($file->hostOS)
67 3
                    ->withMethod($file->method)
68 3
                    ->withName($file->fileName)
69 3
                    ->withPackedSize($file->packSize)
70 3
                    ->withUnpackedSize($file->unpackSize)
71 3
                    ->withVersion($file->unpVer)
72 3
                    ->withIsDirectory(false)
73 3
                    ->withIsEncrypted(false)
74 3
            );
75
        }
76
77 3
        return $rarArchive;
78
    }
79
80
    /**
81
     * Create struct instance.
82
     *
83
     * @param SplFileObject $file The rar file
84
     *
85
     * @return RarArchiveStruct The result
86
     */
87 3
    private function createRarArchiveStruct(SplFileObject $file): RarArchiveStruct
88
    {
89 3
        $rarFile = new RarArchiveStruct();
90
91 3
        $this->readSignature($file, $rarFile);
92
93 3
        if ($rarFile->version === 4) {
94 1
            $this->rar4->readRarFile($file, $rarFile);
95
        }
96
97 3
        if ($rarFile->version === 5) {
98 2
            $this->rar5->readRarFile($file, $rarFile);
99
        }
100
101 3
        return $rarFile;
102
    }
103
104 3
    private function readSignature(SplFileObject $file, RarArchiveStruct $rarFile): void
105
    {
106 3
        $signature = bin2hex((string)$file->fread(7));
107
108 3
        if ($signature === '526172211a0700') {
109
            // Rar 4 signature
110 1
            $rarFile->version = 4;
111 1
            $rarFile->signature = $signature;
112
113 1
            return;
114
        }
115
116 2
        $file->fseek(0);
117 2
        $signature = bin2hex((string)$file->fread(8));
118
119 2
        if ($signature === '526172211a070100') {
120
            // Rar 5 signature
121 2
            $rarFile->version = 5;
122 2
            $rarFile->signature = $signature;
123
124 2
            return;
125
        }
126
127
        throw new UnexpectedValueException('This is not a valid RAR file');
128
    }
129
}
130