Tag Parser
12.5.3
C++ library for reading and writing MP4 (iTunes), ID3, Vorbis, Opus, FLAC and Matroska tags
Toggle main menu visibility
Loading...
Searching...
No Matches
ogg
oggpage.cpp
Go to the documentation of this file.
1
#include "
./oggpage.h
"
2
3
#include "
../exceptions.h
"
4
5
#include <c++utilities/conversion/binaryconversion.h>
6
#include <c++utilities/io/binaryreader.h>
7
8
#include <limits>
9
10
using namespace
std;
11
using namespace
CppUtilities
;
12
13
namespace
TagParser
{
14
21
27
void
OggPage::parseHeader
(istream &stream, std::uint64_t
startOffset
, std::int32_t maxSize)
28
{
29
// prepare reading
30
stream.seekg(
static_cast<
streamoff
>
(
startOffset
));
31
BinaryReader reader(&stream);
32
if
(maxSize < 27) {
33
throw
TruncatedDataException
();
34
}
else
{
35
maxSize -= 27;
36
}
37
// read header values
38
if
(reader.readUInt32LE() != 0x5367674f) {
39
throw
InvalidDataException
();
40
}
41
m_startOffset =
startOffset
;
42
m_streamStructureVersion = reader.readByte();
43
m_headerTypeFlag = reader.readByte();
44
m_absoluteGranulePosition = reader.readUInt64LE();
45
m_streamSerialNumber = reader.readUInt32LE();
46
m_sequenceNumber = reader.readUInt32LE();
47
m_checksum = reader.readUInt32LE();
48
m_segmentCount = reader.readByte();
49
m_segmentSizes.clear();
50
if
(m_segmentCount > 0) {
51
if
(maxSize < m_segmentCount) {
52
throw
TruncatedDataException
();
53
}
else
{
54
maxSize -= m_segmentCount;
55
}
56
// read segment size table
57
m_segmentSizes.emplace_back(0);
58
for
(std::uint8_t i = 0; i < m_segmentCount;) {
59
std::uint8_t entry = reader.readByte();
60
maxSize -= entry;
61
m_segmentSizes.back() += entry;
62
if
(++i < m_segmentCount && entry < 0xFF) {
63
m_segmentSizes.emplace_back(0);
64
}
else
if
(i == m_segmentCount && entry == 0xFF) {
65
m_lastSegmentUnconcluded =
true
;
66
}
67
}
68
// check whether the maximum size is exceeded
69
if
(maxSize < 0) {
70
throw
TruncatedDataException
();
71
}
72
}
73
}
74
79
std::uint32_t
OggPage::computeChecksum
(istream &stream, std::uint64_t
startOffset
)
80
{
81
stream.seekg(
static_cast<
streamoff
>
(
startOffset
));
82
std::uint32_t crc = 0x0;
83
std::uint8_t value,
segmentTableSize
= 0, segmentTableIndex = 0;
84
for
(std::uint32_t i = 0, segmentLength = 27; i != segmentLength; ++i) {
85
switch
(i) {
86
case
22:
87
// bytes 22, 23, 24, 25 hold denoted checksum and must be set to zero
88
stream.seekg(4, ios_base::cur);
89
[[fallthrough]];
90
case
23:
91
case
24:
92
case
25:
93
value = 0;
94
break
;
95
case
26:
96
// byte 26 holds the number of segment sizes
97
segmentLength += (
segmentTableSize
= (value =
static_cast<
std::uint8_t
>
(stream.get())));
98
break
;
99
default
:
100
value =
static_cast<
std::uint8_t
>
(stream.get());
101
if
(i > 26 && segmentTableIndex <
segmentTableSize
) {
102
// bytes 27 to (27 + segment size count) hold page size
103
segmentLength += value;
104
++segmentTableIndex;
105
}
106
}
107
crc = (crc << 8) ^ BinaryReader::crc32Table[((crc >> 24) & 0xFF) ^ value];
108
}
109
return
crc;
110
}
111
116
void
OggPage::updateChecksum
(iostream &stream, std::uint64_t
startOffset
)
117
{
118
char
buff[4];
119
LE::getBytes(
computeChecksum
(stream,
startOffset
), buff);
120
stream.seekp(
static_cast<
streamoff
>
(
startOffset
+ 22));
121
stream.write(buff,
sizeof
(buff));
122
}
123
129
std::uint32_t
OggPage::makeSegmentSizeDenotation
(ostream &stream, std::uint32_t size)
130
{
131
std::uint32_t bytesWritten = 1;
132
while
(size >= 0xff) {
133
stream.put(
static_cast<
char
>
(0xff));
134
size -= 0xff;
135
++bytesWritten;
136
}
137
stream.put(
static_cast<
char
>
(size));
138
return
bytesWritten;
139
}
140
141
}
// namespace TagParser
TagParser::InvalidDataException::InvalidDataException
InvalidDataException() noexcept
Constructs a new exception.
Definition
exceptions.cpp:73
TagParser::OggPage::parseHeader
void parseHeader(std::istream &stream, std::uint64_t startOffset, std::int32_t maxSize)
Parses the header read from the specified stream at the specified startOffset.
Definition
oggpage.cpp:27
TagParser::OggPage::makeSegmentSizeDenotation
static std::uint32_t makeSegmentSizeDenotation(std::ostream &stream, std::uint32_t size)
Writes the segment size denotation for the specified segment size to the specified stream.
Definition
oggpage.cpp:129
TagParser::OggPage::startOffset
std::uint64_t startOffset() const
Returns the start offset of the page.
Definition
oggpage.h:86
TagParser::OggPage::computeChecksum
static std::uint32_t computeChecksum(std::istream &stream, std::uint64_t startOffset)
Computes the actual checksum of the page read from the specified stream at the specified startOffset.
Definition
oggpage.cpp:79
TagParser::OggPage::updateChecksum
static void updateChecksum(std::iostream &stream, std::uint64_t startOffset)
Updates the checksum of the page read from the specified stream at the specified startOffset.
Definition
oggpage.cpp:116
TagParser::OggPage::segmentTableSize
std::uint8_t segmentTableSize() const
Returns the size of the segment table.
Definition
oggpage.h:210
TagParser::TruncatedDataException::TruncatedDataException
TruncatedDataException() noexcept
Constructs a new exception.
Definition
exceptions.cpp:129
exceptions.h
CppUtilities
Definition
abstractcontainer.h:16
TagParser
Contains all classes and functions of the TagInfo library.
Definition
aaccodebook.h:10
oggpage.h
Generated on
for Tag Parser by
1.18.0