3 #include "../exceptions.h"
5 #include <c++utilities/io/binaryreader.h>
32 void OggIterator::clear(istream &stream, std::uint64_t startOffset, std::uint64_t streamSize)
35 m_startOffset = startOffset;
36 m_streamSize = streamSize;
46 void OggIterator::reset()
48 for (m_page = m_segment = m_offset = 0; m_page < m_pages.size() || fetchNextPage(); ++m_page) {
49 const OggPage &page = m_pages[m_page];
50 if (!page.
segmentSizes().empty() && matchesFilter(page)) {
63 void OggIterator::nextPage()
65 while (++m_page < m_pages.size() || fetchNextPage()) {
66 const OggPage &page = m_pages[m_page];
67 if (!page.
segmentSizes().empty() && matchesFilter(page)) {
69 m_segment = m_bytesRead = 0;
81 void OggIterator::nextSegment()
83 const OggPage &page = m_pages[m_page];
84 if (matchesFilter(page) && ++m_segment < page.
segmentSizes().size()) {
98 void OggIterator::previousPage()
101 const OggPage &page = m_pages[--m_page];
102 if (matchesFilter(page)) {
113 void OggIterator::previousSegment()
115 const OggPage &page = m_pages[m_page];
116 if (m_segment && matchesFilter(page)) {
134 void OggIterator::read(
char *buffer, std::size_t count)
136 std::size_t bytesRead = 0;
137 while (*
this && count) {
138 const auto available = currentSegmentSize() - m_bytesRead;
139 stream().seekg(
static_cast<std::streamoff
>(currentCharacterOffset()));
140 if (count <= available) {
141 stream().read(buffer + bytesRead,
static_cast<std::streamsize
>(count));
142 m_bytesRead += count;
145 stream().read(buffer + bytesRead,
static_cast<std::streamsize
>(available));
147 bytesRead += available;
168 std::size_t OggIterator::readAll(
char *buffer, std::size_t max)
170 auto bytesRead = std::size_t(0);
171 while (*
this && max) {
172 const auto available = currentSegmentSize() - m_bytesRead;
173 stream().seekg(
static_cast<std::streamoff
>(currentCharacterOffset()), std::ios_base::beg);
174 if (max <= available) {
175 stream().read(buffer + bytesRead,
static_cast<std::streamsize
>(max));
177 return bytesRead + max;
179 stream().read(buffer + bytesRead,
static_cast<std::streamsize
>(available));
181 bytesRead += available;
198 void OggIterator::ignore(std::size_t count)
200 auto available = currentSegmentSize() - m_bytesRead;
202 available = currentSegmentSize() - m_bytesRead;
203 if (count <= available) {
204 m_bytesRead += count;
237 bool OggIterator::resyncAt(std::uint64_t offset)
240 if (offset >= streamSize() || offset < (m_pages.empty() ? m_startOffset : m_pages.back().startOffset() + m_pages.back().totalSize())) {
245 stream().seekg(
static_cast<streamoff
>(offset));
246 std::uint8_t lettersFound = 0;
247 for (std::uint64_t bytesAvailable = max<std::uint64_t>(streamSize() - offset, 65307ul); bytesAvailable >= 27; --bytesAvailable) {
248 switch (
static_cast<char>(stream().get())) {
253 lettersFound = lettersFound == 1 || lettersFound == 2 ? lettersFound + 1 : 0;
256 if (lettersFound == 3) {
258 const auto currentOffset = stream().tellg();
261 m_pages.emplace_back(stream(),
static_cast<std::uint64_t
>(stream().tellg()) - 4,
262 bytesAvailable > numeric_limits<std::int32_t>::max() ? numeric_limits<std::int32_t>::max()
263 :
static_cast<std::int32_t
>(bytesAvailable));
264 setPageIndex(m_pages.size() - 1);
267 stream().seekg(currentOffset);
288 bool OggIterator::fetchNextPage()
290 if (m_page == m_pages.size()) {
291 m_offset = m_pages.empty() ? m_startOffset : m_pages.back().startOffset() + m_pages.back().totalSize();
292 if (m_offset < m_streamSize) {
293 const std::uint64_t bytesAvailable = m_streamSize - m_offset;
294 m_pages.emplace_back(*m_stream, m_offset,
295 bytesAvailable > numeric_limits<std::int32_t>::max() ? numeric_limits<std::int32_t>::max()
296 :
static_cast<std::int32_t
>(bytesAvailable));
The class inherits from std::exception and serves as base class for exceptions thrown by the elements...
The OggPage class is used to parse OGG pages.
std::uint64_t dataOffset(std::vector< std::uint32_t >::size_type segmentIndex=0) const
Returns the data offset of the segment with the specified segmentIndex.
const std::vector< std::uint32_t > & segmentSizes() const
Returns the sizes of the segments of the page in byte.
std::uint64_t startOffset() const
Returns the start offset of the page.
std::uint32_t headerSize() const
Returns the header size in byte.
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.