3 #include "../exceptions.h"
5 #include <c++utilities/conversion/binaryconversion.h>
6 #include <c++utilities/io/binaryreader.h>
24 void OggPage::parseHeader(istream &stream, std::uint64_t startOffset, std::int32_t maxSize)
27 stream.seekg(
static_cast<streamoff
>(startOffset));
28 BinaryReader reader(&stream);
35 if (reader.readUInt32LE() != 0x5367674f) {
38 m_startOffset = startOffset;
39 m_streamStructureVersion = reader.readByte();
40 m_headerTypeFlag = reader.readByte();
41 m_absoluteGranulePosition = reader.readUInt64LE();
42 m_streamSerialNumber = reader.readUInt32LE();
43 m_sequenceNumber = reader.readUInt32LE();
44 m_checksum = reader.readUInt32LE();
45 m_segmentCount = reader.readByte();
46 m_segmentSizes.clear();
47 if (m_segmentCount > 0) {
48 if (maxSize < m_segmentCount) {
51 maxSize -= m_segmentCount;
54 m_segmentSizes.push_back(0);
55 for (std::uint8_t i = 0; i < m_segmentCount;) {
56 std::uint8_t entry = reader.readByte();
58 m_segmentSizes.back() += entry;
59 if (++i < m_segmentCount && entry < 0xff) {
60 m_segmentSizes.push_back(0);
74 std::uint32_t OggPage::computeChecksum(istream &stream, std::uint64_t startOffset)
76 stream.seekg(
static_cast<streamoff
>(startOffset));
77 std::uint32_t crc = 0x0;
78 std::uint8_t value, segmentTableSize = 0, segmentTableIndex = 0;
79 for (std::uint32_t i = 0, segmentLength = 27; i != segmentLength; ++i) {
83 stream.seekg(4, ios_base::cur);
92 segmentLength += (segmentTableSize = (value =
static_cast<std::uint8_t
>(stream.get())));
95 value =
static_cast<std::uint8_t
>(stream.get());
96 if (i > 26 && segmentTableIndex < segmentTableSize) {
98 segmentLength += value;
102 crc = (crc << 8) ^ BinaryReader::crc32Table[((crc >> 24) & 0xFF) ^ value];
111 void OggPage::updateChecksum(iostream &stream, std::uint64_t startOffset)
114 LE::getBytes(computeChecksum(stream, startOffset), buff);
115 stream.seekp(
static_cast<streamoff
>(startOffset + 22));
116 stream.write(buff,
sizeof(buff));
123 std::uint32_t OggPage::makeSegmentSizeDenotation(ostream &stream, std::uint32_t size)
125 std::uint32_t bytesWritten = 1;
126 while (size >= 0xff) {
127 stream.put(
static_cast<char>(0xff));
131 stream.put(
static_cast<char>(size));