Completed
Push — id3-metadata-objects ( e55453...161f4c )
by Daniel
11:12
created

HeaderReader::readVersion()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 14
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 14
rs 9.2
cc 4
eloc 10
nc 4
nop 0
1
<?php
2
/**
3
 * This file is part of the Metadata package.
4
 *
5
 * @author Daniel Schröder <[email protected]>
6
 */
7
8
namespace GravityMedia\Metadata\ID3v2\Reader;
9
10
use GravityMedia\Metadata\Exception\RuntimeException;
11
use GravityMedia\Metadata\ID3v2\Enum\HeaderFlag;
12
use GravityMedia\Metadata\ID3v2\Enum\Version;
13
use GravityMedia\Metadata\ID3v2\Header;
14
use GravityMedia\Metadata\ID3v2\Stream\SynchsafeInteger32Reader;
15
use GravityMedia\Metadata\Metadata\HeaderInterface;
16
use GravityMedia\Stream\Enum\ByteOrder;
17
use GravityMedia\Stream\Reader\Integer8Reader;
18
use GravityMedia\Stream\StreamInterface;
19
20
/**
21
 * ID3v2 header reader
22
 *
23
 * @package GravityMedia\Metadata\ID3v2\Reader
24
 */
25
class HeaderReader
26
{
27
    /**
28
     * @var StreamInterface
29
     */
30
    protected $stream;
31
32
    /**
33
     * @var Integer8Reader
34
     */
35
    protected $integer8Reader;
36
37
    /**
38
     * @var SynchsafeInteger32Reader
39
     */
40
    protected $synchsafeInteger32Reader;
41
42
    /**
43
     * Create ID3v2 header reader.
44
     *
45
     * @param StreamInterface $stream
46
     */
47
    public function __construct(StreamInterface $stream)
48
    {
49
        $this->stream = $stream;
50
    }
51
52
    /**
53
     * Get 8-bit integer reader.
54
     *
55
     * @return Integer8Reader
56
     */
57
    public function getInteger8Reader()
58
    {
59
        if (null === $this->integer8Reader) {
60
            $this->integer8Reader = new Integer8Reader($this->stream);
61
        }
62
63
        return $this->integer8Reader;
64
    }
65
66
    /**
67
     * Get synchsafe 32-bit integer reader
68
     *
69
     * @return SynchsafeInteger32Reader
70
     */
71 View Code Duplication
    public function getSynchsafeInteger32Reader()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
72
    {
73
        if (null === $this->synchsafeInteger32Reader) {
74
            $this->synchsafeInteger32Reader = new SynchsafeInteger32Reader($this->stream);
75
            $this->synchsafeInteger32Reader->setByteOrder(ByteOrder::BIG_ENDIAN);
76
        }
77
78
        return $this->synchsafeInteger32Reader;
79
    }
80
81
    /**
82
     * Read ID3v2 header version.
83
     *
84
     * @throws RuntimeException An exception is thrown on invalid versions.
85
     *
86
     * @return int
87
     */
88
    protected function readVersion()
89
    {
90
        $this->stream->seek(3);
91
        switch ($this->getInteger8Reader()->read()) {
92
            case 2:
93
                return Version::VERSION_22;
94
            case 3:
95
                return Version::VERSION_23;
96
            case 4:
97
                return Version::VERSION_24;
98
        }
99
100
        throw new RuntimeException('Invalid version.');
101
    }
102
103
    /**
104
     * Read ID3v2 header revision.
105
     *
106
     * @return int
107
     */
108
    protected function readRevision()
109
    {
110
        $this->stream->seek(4);
111
112
        return $this->getInteger8Reader()->read();
113
    }
114
115
    /**
116
     * Read ID3v2 header flags.
117
     *
118
     * @param int $version
119
     *
120
     * @return array
121
     */
122
    protected function readFlags($version)
123
    {
124
        $this->stream->seek(5);
125
        $flags = $this->getInteger8Reader()->read();
126
127 View Code Duplication
        if ($version === Version::VERSION_22) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
128
            return [
129
                HeaderFlag::FLAG_UNSYNCHRONISATION => (bool)($flags & 0x80),
130
                HeaderFlag::FLAG_COMPRESSION => (bool)($flags & 0x40)
131
            ];
132
        }
133
134 View Code Duplication
        if ($version === Version::VERSION_23) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
135
            return [
136
                HeaderFlag::FLAG_UNSYNCHRONISATION => (bool)($flags & 0x80),
137
                HeaderFlag::FLAG_EXTENDED_HEADER => (bool)($flags & 0x40),
138
                HeaderFlag::FLAG_EXPERIMENTAL_INDICATOR => (bool)($flags & 0x20)
139
            ];
140
        }
141
142
        return [
143
            HeaderFlag::FLAG_UNSYNCHRONISATION => (bool)($flags & 0x80),
144
            HeaderFlag::FLAG_EXTENDED_HEADER => (bool)($flags & 0x40),
145
            HeaderFlag::FLAG_EXPERIMENTAL_INDICATOR => (bool)($flags & 0x20),
146
            HeaderFlag::FLAG_FOOTER_PRESENT => (bool)($flags & 0x10)
147
        ];
148
    }
149
150
    /**
151
     * Read ID3v2 header size.
152
     *
153
     * @return int
154
     */
155
    public function readSize()
156
    {
157
        $this->stream->seek(6);
158
159
        return $this->getSynchsafeInteger32Reader()->read();
160
    }
161
162
    /**
163
     * Read ID3v2 header.
164
     *
165
     * @return HeaderInterface
166
     */
167
    public function read()
168
    {
169
        $version = $this->readVersion();
170
171
        $header = new Header($version);
172
        return $header
173
            ->setRevision($this->readRevision())
174
            ->setFlags($this->readFlags($version))
175
            ->setSize($this->readSize());
176
    }
177
}
178