4 #include "../exceptions.h" 6 #include <c++utilities/conversion/stringbuilder.h> 7 #include <c++utilities/conversion/binaryconversion.h> 24 void MatroskaSeekInfo::shift(uint64 start, int64 amount)
26 for(
auto &info : m_info) {
27 if(get<1>(info) >= start) {
28 get<1>(info) += amount;
41 static const string context(
"parsing \"SeekHead\"-element");
42 m_seekHeadElement = seekHeadElement;
45 EbmlElement *seekElementChild, *seekIdElement, *seekPositionElement;
48 switch(seekElement->
id()) {
51 seekIdElement = seekPositionElement =
nullptr;
52 while(seekElementChild) {
53 seekElementChild->
parse();
54 switch(seekElementChild->
id()) {
57 addNotification(NotificationType::Warning,
"The \"Seek\"-element contains multiple \"SeekID\"-elements. Surplus elements will be ignored.", context);
59 seekIdElement = seekElementChild;
62 if(seekPositionElement) {
63 addNotification(NotificationType::Warning,
"The \"Seek\"-element contains multiple \"SeekPosition\"-elements. Surplus elements will be ignored.", context);
65 seekPositionElement = seekElementChild;
71 addNotification(NotificationType::Warning,
"The element \"" 73 +
"\" within the \"Seek\" element is not a \"SeekID\"-element nor a \"SeekPosition\"-element and will be ignored.", context);
77 if(seekIdElement && seekPositionElement) {
80 addNotification(NotificationType::Warning,
"The \"Seek\"-element does not contain a \"SeekID\"- and a \"SeekPosition\"-element.", context);
87 addNotification(NotificationType::Warning,
"The element " % seekElement->
idToString() +
" is not a seek element and will be ignored.", context);
92 addNotification(NotificationType::Warning,
"No seek information found.", context);
102 void MatroskaSeekInfo::make(ostream &stream)
104 uint64 totalSize = 0;
108 byte sizeLength0, sizeLength1;
110 for(
const auto &info : m_info) {
112 totalSize += 2 + 1 + (2 + 1 + EbmlElement::calculateIdLength(get<0>(info))) + (2 + 1 + EbmlElement::calculateUIntegerLength(get<1>(info)));
116 stream.write(buff0, 4);
117 sizeLength0 = EbmlElement::makeSizeDenotation(totalSize, buff0);
118 stream.write(buff0, sizeLength0);
120 for(
const auto &info : m_info) {
122 sizeLength0 = EbmlElement::makeId(get<0>(info), buff0);
123 sizeLength1 = EbmlElement::makeUInteger(get<1>(info), buff1);
126 stream.write(buff2, 2);
127 stream.put(0x80 | (2 + 1 + sizeLength0 + 2 + 1 + sizeLength1));
130 stream.write(buff2, 2);
131 stream.put(0x80 | sizeLength0);
132 stream.write(buff0, sizeLength0);
135 stream.write(buff2, 2);
136 stream.put(0x80 | sizeLength1);
137 stream.write(buff1, sizeLength1);
145 uint64 MatroskaSeekInfo::minSize()
const 147 uint64 maxTotalSize = m_info.size() * (2 + 1 + 2 + 1 + 1 + 2 + 1 + 1);
148 return 4 + EbmlElement::calculateSizeDenotationLength(maxTotalSize) + maxTotalSize;
155 uint64 MatroskaSeekInfo::maxSize()
const 157 uint64 maxTotalSize = m_info.size() * (2 + 1 + 2 + 1 + 4 + 2 + 1 + 8);
158 return 4 + EbmlElement::calculateSizeDenotationLength(maxTotalSize) + maxTotalSize;
165 uint64 MatroskaSeekInfo::actualSize()
const 167 uint64 totalSize = 0;
168 for(
const auto &info : m_info) {
170 totalSize += 2 + 1 + (2 + 1 + EbmlElement::calculateIdLength(get<0>(info))) + (2 + 1 + EbmlElement::calculateUIntegerLength(get<1>(info)));
172 return totalSize += 4 + EbmlElement::calculateSizeDenotationLength(totalSize);
183 bool MatroskaSeekInfo::push(
unsigned int index, EbmlElement::identifierType
id, uint64 offset)
185 unsigned int currentIndex = 0;
186 for(
auto &entry : info()) {
187 if(get<0>(entry) ==
id) {
188 if(index == currentIndex) {
189 bool sizeUpdated = EbmlElement::calculateUIntegerLength(get<1>(entry)) != EbmlElement::calculateUIntegerLength(offset);
190 get<1>(entry) = offset;
196 info().emplace_back(
id, offset);
203 void MatroskaSeekInfo::clear()
205 m_seekHeadElement =
nullptr;
212 std::pair<EbmlElement::identifierType, uint64> *MatroskaSeekInfo::findSeekInfo(std::vector<MatroskaSeekInfo> &seekInfos, uint64 offset)
214 for(
auto &seekInfo : seekInfos) {
215 for(
auto &entry : seekInfo.info()) {
216 if(get<1>(entry) == offset) {
228 bool MatroskaSeekInfo::updateSeekInfo(
const std::vector<MatroskaSeekInfo> &oldSeekInfos, std::vector<MatroskaSeekInfo> &newSeekInfos, uint64 oldOffset, uint64 newOffset)
230 bool updated =
false;
231 auto oldIterator0 = oldSeekInfos.cbegin(), oldEnd0 = oldSeekInfos.cend();
232 auto newIterator0 = newSeekInfos.begin(), newEnd0 = newSeekInfos.end();
233 for(; oldIterator0 != oldEnd0 && newIterator0 != newEnd0; ++oldIterator0, ++newIterator0) {
234 auto oldIterator1 = oldIterator0->info().cbegin(), oldEnd1 = oldIterator0->info().cend();
235 auto newIterator1 = newIterator0->info().begin(), newEnd1 = newIterator0->info().end();
236 for(; oldIterator1 != oldEnd1 && newIterator1 != newEnd1; ++oldIterator1, ++newIterator1) {
237 if(get<1>(*oldIterator1) == oldOffset) {
238 if(get<1>(*newIterator1) != newOffset) {
239 updated = updated || (EbmlElement::calculateUIntegerLength(newOffset) != EbmlElement::calculateUIntegerLength(get<1>(*newIterator1)));
240 get<1>(*newIterator1) = newOffset;
252 bool MatroskaSeekInfo::updateSeekInfo(std::vector<MatroskaSeekInfo> &newSeekInfos, uint64 oldOffset, uint64 newOffset)
254 if(oldOffset == newOffset) {
257 bool updated =
false;
258 for(
auto &seekInfo : newSeekInfos) {
259 for(
auto &info : seekInfo.info()) {
260 if(get<1>(info) == oldOffset) {
261 get<1>(info) = newOffset;