Completed
Push — id3-metadata-objects ( 3a53b8...e55453 )
by Daniel
14:15
created

HeaderReader::read()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 10
rs 9.4285
cc 1
eloc 7
nc 1
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\Metadata;
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\StreamReader
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 View Code Duplication
    public function getInteger8Reader()
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...
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
        switch ($this->getInteger8Reader()->read()) {
91
            case 2:
92
                return Version::VERSION_22;
93
            case 3:
94
                return Version::VERSION_23;
95
            case 4:
96
                return Version::VERSION_24;
97
        }
98
99
        throw new RuntimeException('Invalid version.');
100
    }
101
102
    /**
103
     * Read ID3v2 header revision.
104
     *
105
     * @return int
106
     */
107
    protected function readRevision()
108
    {
109
        return $this->getInteger8Reader()->read();
110
    }
111
112
    /**
113
     * Read ID3v2 header flags.
114
     *
115
     * @param int $version
116
     *
117
     * @return array
118
     */
119
    protected function readFlags($version)
120
    {
121
        $flags = $this->getInteger8Reader()->read();
122
123 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...
124
            return [
125
                HeaderFlag::FLAG_UNSYNCHRONISATION => (bool)($flags & 0x80),
126
                HeaderFlag::FLAG_COMPRESSION => (bool)($flags & 0x40)
127
            ];
128
        }
129
130 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...
131
            return [
132
                HeaderFlag::FLAG_UNSYNCHRONISATION => (bool)($flags & 0x80),
133
                HeaderFlag::FLAG_EXTENDED_HEADER => (bool)($flags & 0x40),
134
                HeaderFlag::FLAG_EXPERIMENTAL_INDICATOR => (bool)($flags & 0x20)
135
            ];
136
        }
137
138
        return [
139
            HeaderFlag::FLAG_UNSYNCHRONISATION => (bool)($flags & 0x80),
140
            HeaderFlag::FLAG_EXTENDED_HEADER => (bool)($flags & 0x40),
141
            HeaderFlag::FLAG_EXPERIMENTAL_INDICATOR => (bool)($flags & 0x20),
142
            HeaderFlag::FLAG_FOOTER_PRESENT => (bool)($flags & 0x10)
143
        ];
144
    }
145
146
    /**
147
     * Read ID3v2 header size.
148
     *
149
     * @return int
150
     */
151
    public function readSize()
152
    {
153
        return $this->getSynchsafeInteger32Reader()->read();
154
    }
155
156
    /**
157
     * Read ID3v2 header.
158
     *
159
     * @return HeaderInterface
160
     */
161
    public function read()
162
    {
163
        $version = $this->readVersion();
164
165
        $header = new Header($version);
166
        return $header
167
            ->setRevision($this->readRevision())
168
            ->setFlags($this->readFlags($version))
169
            ->setSize($this->readSize());
170
    }
171
}
172