4 #include "../exceptions.h" 6 #include <c++utilities/conversion/binaryconversion.h> 23 void MatroskaSeekInfo::shift(uint64 start, int64 amount)
25 for(
auto &info : m_info) {
26 if(get<1>(info) >= start) {
27 get<1>(info) += amount;
40 static const string context(
"parsing \"SeekHead\"-element");
41 m_seekHeadElement = seekHeadElement;
44 EbmlElement *seekElementChild, *seekIdElement, *seekPositionElement;
47 switch(seekElement->
id()) {
50 seekIdElement = seekPositionElement =
nullptr;
51 while(seekElementChild) {
52 seekElementChild->
parse();
53 switch(seekElementChild->
id()) {
56 addNotification(NotificationType::Warning,
"The \"Seek\"-element contains multiple \"SeekID\"-elements. Surplus elements will be ignored.", context);
58 seekIdElement = seekElementChild;
61 if(seekPositionElement) {
62 addNotification(NotificationType::Warning,
"The \"Seek\"-element contains multiple \"SeekPosition\"-elements. Surplus elements will be ignored.", context);
64 seekPositionElement = seekElementChild;
70 addNotification(NotificationType::Warning,
"The element \"" 72 +
"\" within the \"Seek\" element is not a \"SeekID\"-element nor a \"SeekPosition\"-element and will be ignored.", context);
76 if(seekIdElement && seekPositionElement) {
79 addNotification(NotificationType::Warning,
"The \"Seek\"-element does not contain a \"SeekID\"- and a \"SeekPosition\"-element.", context);
86 addNotification(NotificationType::Warning,
"The element " + seekElement->
idToString() +
" is not a seek element and will be ignored.", context);
91 addNotification(NotificationType::Warning,
"No seek information found.", context);
101 void MatroskaSeekInfo::make(ostream &stream)
103 uint64 totalSize = 0;
107 byte sizeLength0, sizeLength1;
109 for(
const auto &info : m_info) {
111 totalSize += 2 + 1 + (2 + 1 + EbmlElement::calculateIdLength(get<0>(info))) + (2 + 1 + EbmlElement::calculateUIntegerLength(get<1>(info)));
115 stream.write(buff0, 4);
116 sizeLength0 = EbmlElement::makeSizeDenotation(totalSize, buff0);
117 stream.write(buff0, sizeLength0);
119 for(
const auto &info : m_info) {
121 sizeLength0 = EbmlElement::makeId(get<0>(info), buff0);
122 sizeLength1 = EbmlElement::makeUInteger(get<1>(info), buff1);
125 stream.write(buff2, 2);
126 stream.put(0x80 | (2 + 1 + sizeLength0 + 2 + 1 + sizeLength1));
129 stream.write(buff2, 2);
130 stream.put(0x80 | sizeLength0);
131 stream.write(buff0, sizeLength0);
134 stream.write(buff2, 2);
135 stream.put(0x80 | sizeLength1);
136 stream.write(buff1, sizeLength1);
144 uint64 MatroskaSeekInfo::minSize()
const 146 uint64 maxTotalSize = m_info.size() * (2 + 1 + 2 + 1 + 1 + 2 + 1 + 1);
147 return 4 + EbmlElement::calculateSizeDenotationLength(maxTotalSize) + maxTotalSize;
154 uint64 MatroskaSeekInfo::maxSize()
const 156 uint64 maxTotalSize = m_info.size() * (2 + 1 + 2 + 1 + 4 + 2 + 1 + 8);
157 return 4 + EbmlElement::calculateSizeDenotationLength(maxTotalSize) + maxTotalSize;
164 uint64 MatroskaSeekInfo::actualSize()
const 166 uint64 totalSize = 0;
167 for(
const auto &info : m_info) {
169 totalSize += 2 + 1 + (2 + 1 + EbmlElement::calculateIdLength(get<0>(info))) + (2 + 1 + EbmlElement::calculateUIntegerLength(get<1>(info)));
171 return totalSize += 4 + EbmlElement::calculateSizeDenotationLength(totalSize);
182 bool MatroskaSeekInfo::push(
unsigned int index, EbmlElement::identifierType
id, uint64 offset)
184 unsigned int currentIndex = 0;
185 for(
auto &entry : info()) {
186 if(get<0>(entry) ==
id) {
187 if(index == currentIndex) {
188 bool sizeUpdated = EbmlElement::calculateUIntegerLength(get<1>(entry)) != EbmlElement::calculateUIntegerLength(offset);
189 get<1>(entry) = offset;
195 info().emplace_back(
id, offset);
202 void MatroskaSeekInfo::clear()
204 m_seekHeadElement =
nullptr;
211 std::pair<EbmlElement::identifierType, uint64> *MatroskaSeekInfo::findSeekInfo(std::vector<MatroskaSeekInfo> &seekInfos, uint64 offset)
213 for(
auto &seekInfo : seekInfos) {
214 for(
auto &entry : seekInfo.info()) {
215 if(get<1>(entry) == offset) {
227 bool MatroskaSeekInfo::updateSeekInfo(
const std::vector<MatroskaSeekInfo> &oldSeekInfos, std::vector<MatroskaSeekInfo> &newSeekInfos, uint64 oldOffset, uint64 newOffset)
229 bool updated =
false;
230 auto oldIterator0 = oldSeekInfos.cbegin(), oldEnd0 = oldSeekInfos.cend();
231 auto newIterator0 = newSeekInfos.begin(), newEnd0 = newSeekInfos.end();
232 for(; oldIterator0 != oldEnd0 && newIterator0 != newEnd0; ++oldIterator0, ++newIterator0) {
233 auto oldIterator1 = oldIterator0->info().cbegin(), oldEnd1 = oldIterator0->info().cend();
234 auto newIterator1 = newIterator0->info().begin(), newEnd1 = newIterator0->info().end();
235 for(; oldIterator1 != oldEnd1 && newIterator1 != newEnd1; ++oldIterator1, ++newIterator1) {
236 if(get<1>(*oldIterator1) == oldOffset) {
237 if(get<1>(*newIterator1) != newOffset) {
238 updated = updated || (EbmlElement::calculateUIntegerLength(newOffset) != EbmlElement::calculateUIntegerLength(get<1>(*newIterator1)));
239 get<1>(*newIterator1) = newOffset;
251 bool MatroskaSeekInfo::updateSeekInfo(std::vector<MatroskaSeekInfo> &newSeekInfos, uint64 oldOffset, uint64 newOffset)
253 if(oldOffset == newOffset) {
256 bool updated =
false;
257 for(
auto &seekInfo : newSeekInfos) {
258 for(
auto &info : seekInfo.info()) {
259 if(get<1>(info) == oldOffset) {
260 get<1>(info) = newOffset;