Tag Parser: ogg/oggpage.cpp Source File

Tag Parser 12.5.3 C++ library for reading and writing MP4 (iTunes), ID3, Vorbis, Opus, FLAC and Matroska tags

Loading...
Searching...
No Matches
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
10using namespace std;
11using namespace CppUtilities;
12
13namespace 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
79std::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
129std::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
The exception that is thrown when the data to be parsed or to be made seems invalid and therefore can...
Definition exceptions.h:25
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
The exception that is thrown when the data to be parsed is truncated and therefore can not be parsed ...
Definition exceptions.h:39
exceptions.h
CppUtilities
Definition abstractcontainer.h:16
TagParser
Contains all classes and functions of the TagInfo library.
Definition aaccodebook.h:10
oggpage.h