Tag Parser 12.3.1
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
27void 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) {
34 } else {
35 maxSize -= 27;
36 }
37 // read header values
38 if (reader.readUInt32LE() != 0x5367674f) {
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) {
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) {
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
116void 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
The exception that is thrown when the data to be parsed or to be made seems invalid and therefore can...
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
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
std::uint64_t startOffset() const
Returns the start offset of the page.
Definition oggpage.h:86
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
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
std::uint8_t segmentTableSize() const
Returns the size of the segment table.
Definition oggpage.h:210
The exception that is thrown when the data to be parsed is truncated and therefore can not be parsed ...
Contains all classes and functions of the TagInfo library.
Definition aaccodebook.h:10