3 #include "../exceptions.h" 5 #include <c++utilities/io/binaryreader.h> 32 void OggIterator::clear(istream &stream, uint64 startOffset, uint64 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,
size_t count)
136 size_t bytesRead = 0;
137 while(*
this && count) {
138 const uint32 available = currentSegmentSize() - m_bytesRead;
139 stream().seekg(currentCharacterOffset());
140 if(count <= available) {
141 stream().read(buffer + bytesRead, count);
142 m_bytesRead += count;
145 stream().read(buffer + bytesRead, available);
147 bytesRead += available;
169 size_t OggIterator::readAll(
char *buffer,
size_t max)
171 size_t bytesRead = 0;
172 while(*
this && max) {
173 const uint32 available = currentSegmentSize() - m_bytesRead;
174 stream().seekg(currentCharacterOffset());
175 if(max <= available) {
176 stream().read(buffer + bytesRead, max);
178 return bytesRead + max;
180 stream().read(buffer + bytesRead, available);
182 bytesRead += available;
199 void OggIterator::ignore(
size_t count)
201 uint32 available = currentSegmentSize() - m_bytesRead;
203 available = currentSegmentSize() - m_bytesRead;
204 if(count <= available) {
205 m_bytesRead += count;
238 bool OggIterator::resyncAt(uint64 offset)
241 if(offset >= streamSize() || offset < (m_pages.empty() ? m_startOffset : m_pages.back().startOffset() + m_pages.back().totalSize())) {
246 stream().seekg(offset);
247 byte lettersFound = 0;
248 for(uint64 bytesAvailable = max<uint64>(streamSize() - offset, 65307ul); bytesAvailable >= 27; --bytesAvailable) {
249 switch(static_cast<char>(stream().
get())) {
254 lettersFound = lettersFound == 1 || lettersFound == 2 ? lettersFound + 1 : 0;
257 if(lettersFound == 3) {
259 const auto currentOffset = stream().tellg();
262 m_pages.emplace_back(stream(), static_cast<uint64>(stream().tellg()) - 4, bytesAvailable > numeric_limits<int32>::max() ? numeric_limits<int32>::max() : static_cast<int32>(bytesAvailable));
263 setPageIndex(m_pages.size() - 1);
266 stream().seekg(currentOffset);
287 bool OggIterator::fetchNextPage()
289 if(m_page == m_pages.size()) {
290 m_offset = m_pages.empty() ? m_startOffset : m_pages.back().startOffset() + m_pages.back().totalSize();
291 if(m_offset < m_streamSize) {
292 const uint64 bytesAvailable = m_streamSize - m_offset;
293 m_pages.emplace_back(*m_stream, m_offset, bytesAvailable > numeric_limits<int32>::max() ? numeric_limits<int32>::max() : static_cast<int32>(bytesAvailable));
uint64 dataOffset(byte segmentIndex=0) const
Returns the data offset of the segment with the specified segmentIndex.
uint32 headerSize() const
Returns the header size in byte.
The OggPage class is used to parse OGG pages.
Contains utility classes helping to read and write streams.
uint64 startOffset() const
Returns the start offset of the page.
const std::vector< uint32 > & segmentSizes() const
Returns the sizes of the segments of the page in byte.