- Merge another bug-fix from 1.6rc1 (this adds 3 symbols) and really add

tstring bug-fix:
171957)
:operator[] and in String::operator+=. (BUG:169389)
This commit is contained in:
Michael Schwendt 2009-09-04 10:21:32 +00:00
parent 3c15b4b36b
commit d017c73508
3 changed files with 334 additions and 1 deletions

View File

@ -44,3 +44,287 @@ diff -Nur taglib-1.5/taglib/ogg/xiphcomment.cpp taglib/taglib/ogg/xiphcomment.cp
if(i == 0)
removeField("TRACKNUMBER");
else
diff -Nur taglib-1.5-orig/taglib/ogg/oggfile.cpp taglib-1.5/taglib/ogg/oggfile.cpp
--- taglib-1.5-orig/taglib/ogg/oggfile.cpp 2008-02-04 16:14:46.000000000 +0100
+++ taglib-1.5/taglib/ogg/oggfile.cpp 2009-09-04 11:46:54.859122796 +0200
@@ -270,11 +270,28 @@
return true;
}
-void Ogg::File::writePageGroup(const List<int> &pageGroup)
+void Ogg::File::writePageGroup(const List<int> &thePageGroup)
{
- if(pageGroup.isEmpty())
+ if(thePageGroup.isEmpty())
return;
+
+ // pages in the pageGroup and packets must be equivalent
+ // (originalSize and size of packets would not work together),
+ // therefore we sometimes have to add pages to the group
+ List<int> pageGroup(thePageGroup);
+ while (!d->pages[pageGroup.back()]->header()->lastPacketCompleted()) {
+ if (d->currentPage->header()->pageSequenceNumber() == pageGroup.back()) {
+ if (nextPage() == false) {
+ debug("broken ogg file");
+ return;
+ }
+ pageGroup.append(d->currentPage->header()->pageSequenceNumber());
+ } else {
+ pageGroup.append(pageGroup.back() + 1);
+ }
+ }
+
ByteVectorList packets;
// If the first page of the group isn't dirty, append its partial content here.
@@ -313,6 +330,52 @@
d->streamSerialNumber, pageGroup.front(),
continued, completed);
+ List<Page *> renumberedPages;
+
+ // Correct the page numbering of following pages
+
+ if (pages.back()->header()->pageSequenceNumber() != pageGroup.back()) {
+
+ // TODO: change the internal data structure so that we don't need to hold the
+ // complete file in memory (is unavoidable at the moment)
+
+ // read the complete stream
+ while(!d->currentPage->header()->lastPageOfStream()) {
+ if(nextPage() == false) {
+ debug("broken ogg file");
+ break;
+ }
+ }
+
+ // create a gap for the new pages
+ int numberOfNewPages = pages.back()->header()->pageSequenceNumber() - pageGroup.back();
+ List<Page *>::Iterator pageIter = d->pages.begin();
+ for(int i = 0; i < pageGroup.back(); i++) {
+ if(pageIter != d->pages.end()) {
+ ++pageIter;
+ }
+ else {
+ debug("Ogg::File::writePageGroup() -- Page sequence is broken in original file.");
+ break;
+ }
+ }
+
+ ++pageIter;
+ for(; pageIter != d->pages.end(); ++pageIter) {
+ Ogg::Page *newPage =
+ (*pageIter)->getCopyWithNewPageSequenceNumber(
+ (*pageIter)->header()->pageSequenceNumber() + numberOfNewPages);
+
+ ByteVector data;
+ data.append(newPage->render());
+ insert(data, newPage->fileOffset(), data.size());
+
+ renumberedPages.append(newPage);
+ }
+ }
+
+ // insert the new data
+
ByteVector data;
for(List<Page *>::ConstIterator it = pages.begin(); it != pages.end(); ++it)
data.append((*it)->render());
@@ -328,9 +391,37 @@
// Update the page index to include the pages we just created and to delete the
// old pages.
+ // First step: Pages that contain the comment data
+
for(List<Page *>::ConstIterator it = pages.begin(); it != pages.end(); ++it) {
const int index = (*it)->header()->pageSequenceNumber();
- delete d->pages[index];
- d->pages[index] = *it;
+ if(index < static_cast<int>(d->pages.size())) {
+ delete d->pages[index];
+ d->pages[index] = *it;
+ }
+ else if(index == d->pages.size()) {
+ d->pages.append(*it);
+ }
+ else {
+ // oops - there's a hole in the sequence
+ debug("Ogg::File::writePageGroup() -- Page sequence is broken.");
+ }
+ }
+
+ // Second step: the renumbered pages
+
+ for(List<Page *>::ConstIterator it = renumberedPages.begin(); it != renumberedPages.end(); ++it) {
+ const int index = (*it)->header()->pageSequenceNumber();
+ if(index < static_cast<int>(d->pages.size())) {
+ delete d->pages[index];
+ d->pages[index] = *it;
+ }
+ else if(index == d->pages.size()) {
+ d->pages.append(*it);
+ }
+ else {
+ // oops - there's a hole in the sequence
+ debug("Ogg::File::writePageGroup() -- Page sequence is broken.");
+ }
}
}
diff -Nur taglib-1.5-orig/taglib/ogg/oggpage.cpp taglib-1.5/taglib/ogg/oggpage.cpp
--- taglib-1.5-orig/taglib/ogg/oggpage.cpp 2008-02-04 16:14:46.000000000 +0100
+++ taglib-1.5/taglib/ogg/oggpage.cpp 2009-09-04 11:47:00.527115729 +0200
@@ -116,12 +116,14 @@
flags = ContainsPacketFlags(flags | CompletePacket);
}
- // Or if the page is (a) the first page and it's complete or (b) the last page
- // and it's complete or (c) a page in the middle.
-
- else if((flags & BeginsWithPacket && !d->header.firstPacketContinued()) ||
- (flags & EndsWithPacket && d->header.lastPacketCompleted()) ||
- (!(flags & BeginsWithPacket) && !(flags & EndsWithPacket)))
+ // Or if there is more than one page and the page is
+ // (a) the first page and it's complete or
+ // (b) the last page and it's complete or
+ // (c) a page in the middle.
+ else if(packetCount() > 1 &&
+ ((flags & BeginsWithPacket && !d->header.firstPacketContinued()) ||
+ (flags & EndsWithPacket && d->header.lastPacketCompleted()) ||
+ (!(flags & BeginsWithPacket) && !(flags & EndsWithPacket))))
{
flags = ContainsPacketFlags(flags | CompletePacket);
}
@@ -208,20 +210,101 @@
for(ByteVectorList::ConstIterator it = packets.begin(); it != packets.end(); ++it)
totalSize += (*it).size();
- if(strategy == Repaginate || totalSize + packets.size() > 255 * 256) {
- debug("Ogg::Page::paginate() -- Sorry! Repagination is not yet implemented.");
- return l;
- }
+ // Handle creation of multiple pages with appropriate pagination.
+ if(strategy == Repaginate || totalSize + packets.size() > 255 * 255) {
- // TODO: Handle creation of multiple pages here with appropriate pagination.
+ // SPLITSIZE must be a multiple of 255 in order to get the lacing values right
+ // create pages of about 8KB each
+#define SPLITSIZE (32*255)
+
+ int pageIndex = 0;
+
+ for(ByteVectorList::ConstIterator it = packets.begin(); it != packets.end(); ++it) {
+ bool continued = false;
+
+ // mark very first packet?
+ if(firstPacketContinued && it==packets.begin()) {
+ continued = true;
+ }
+
+ // append to buf
+ ByteVector packetBuf;
+ packetBuf.append(*it);
+
+ while(packetBuf.size() > SPLITSIZE) {
+ // output a Page
+ ByteVector packetForOnePage;
+ packetForOnePage.resize(SPLITSIZE);
+ std::copy(packetBuf.begin(), packetBuf.begin() + SPLITSIZE, packetForOnePage.begin());
+
+ ByteVectorList packetList;
+ packetList.append(packetForOnePage);
+ Page *p = new Page(packetList, streamSerialNumber, firstPage+pageIndex, continued, false, false);
+ l.append(p);
+
+ pageIndex++;
+ continued = true;
+ packetBuf = packetBuf.mid(SPLITSIZE);
+ }
+
+ ByteVectorList::ConstIterator jt = it;
+ ++jt;
+ bool lastPacketInList = (jt == packets.end());
+
+ // output a page for the rest (we output one packet per page, so this one should be completed)
+ ByteVectorList packetList;
+ packetList.append(packetBuf);
+
+ bool isVeryLastPacket = false;
+ if(containsLastPacket) {
+ // mark the very last output page as last of stream
+ ByteVectorList::ConstIterator jt = it;
+ ++jt;
+ if(jt == packets.end()) {
+ isVeryLastPacket = true;
+ }
+ }
+
+ Page *p = new Page(packetList, streamSerialNumber, firstPage+pageIndex, continued,
+ lastPacketInList ? lastPacketCompleted : true,
+ isVeryLastPacket);
+ pageIndex++;
- Page *p = new Page(packets, streamSerialNumber, firstPage, firstPacketContinued,
- lastPacketCompleted, containsLastPacket);
- l.append(p);
+ l.append(p);
+ }
+ }
+ else {
+ Page *p = new Page(packets, streamSerialNumber, firstPage, firstPacketContinued,
+ lastPacketCompleted, containsLastPacket);
+ l.append(p);
+ }
return l;
}
+Ogg::Page* Ogg::Page::getCopyWithNewPageSequenceNumber(int sequenceNumber)
+{
+ Page *pResultPage = NULL;
+
+ // TODO: a copy constructor would be helpful
+
+ if(d->file == 0) {
+ pResultPage = new Page(
+ d->packets,
+ d->header.streamSerialNumber(),
+ sequenceNumber,
+ d->header.firstPacketContinued(),
+ d->header.lastPacketCompleted(),
+ d->header.lastPageOfStream());
+ }
+ else
+ {
+ pResultPage = new Page(d->file, d->fileOffset);
+ pResultPage->d->header.setPageSequenceNumber(sequenceNumber);
+ }
+ return pResultPage;
+}
+
////////////////////////////////////////////////////////////////////////////////
// protected members
////////////////////////////////////////////////////////////////////////////////
@@ -254,3 +337,4 @@
d->packets = packets;
d->header.setPacketSizes(packetSizes);
}
+
diff -Nur taglib-1.5-orig/taglib/ogg/oggpage.h taglib-1.5/taglib/ogg/oggpage.h
--- taglib-1.5-orig/taglib/ogg/oggpage.h 2008-02-04 16:14:46.000000000 +0100
+++ taglib-1.5/taglib/ogg/oggpage.h 2009-09-04 11:47:06.387120297 +0200
@@ -70,6 +70,14 @@
*/
const PageHeader *header() const;
+ /*!
+ * Returns a copy of the page with \a sequenceNumber set as sequence number.
+ *
+ * \see header()
+ * \see PageHeader::setPageSequenceNumber()
+ */
+ Page* getCopyWithNewPageSequenceNumber(int sequenceNumber);
+
/*!
* Returns the index of the first packet wholly or partially contained in
* this page.

View File

@ -40,3 +40,45 @@ diff -Nur taglib-1.5/taglib/toolkit/tbytevectorlist.cpp taglib/taglib/toolkit/tb
l.append(v.mid(previousOffset, offset - previousOffset));
else
l.append(ByteVector::null);
diff -Nur taglib-1.5-orig/taglib/toolkit/tstring.cpp taglib-1.5/taglib/toolkit/tstring.cpp
--- taglib-1.5-orig/taglib/toolkit/tstring.cpp 2008-02-04 16:14:45.000000000 +0100
+++ taglib-1.5/taglib/toolkit/tstring.cpp 2009-09-04 12:07:00.506121756 +0200
@@ -35,7 +35,7 @@
inline unsigned short byteSwap(unsigned short x)
{
- return ((x) >> 8) & 0xff | ((x) & 0xff) << 8;
+ return (((x) >> 8) & 0xff) | (((x) & 0xff) << 8);
}
inline unsigned short combine(unsigned char c1, unsigned char c2)
@@ -510,6 +510,8 @@
TagLib::wchar &String::operator[](int i)
{
+ detach();
+
return d->data[i];
}
@@ -558,6 +560,8 @@
String &String::operator+=(char c)
{
+ detach();
+
d->data += uchar(c);
return *this;
}
diff -Nur taglib-1.5-orig/taglib/toolkit/tstring.h taglib-1.5/taglib/toolkit/tstring.h
--- taglib-1.5-orig/taglib/toolkit/tstring.h 2008-02-04 16:14:45.000000000 +0100
+++ taglib-1.5/taglib/toolkit/tstring.h 2009-09-04 12:07:03.465121011 +0200
@@ -31,7 +31,7 @@
#include "tbytevector.h"
#include <string>
-#include <ostream>
+#include <iostream>
/*!
* \relates TagLib::String

View File

@ -12,7 +12,7 @@
Name: taglib
Version: 1.5
Release: 7%{?dist}
Release: 8%{?dist}
Summary: Audio Meta-Data Library
Group: System Environment/Libraries
@ -171,6 +171,13 @@ rm -rf %{buildroot}
%changelog
* Fri Sep 4 2009 Michael Schwendt <mschwendt@fedoraproject.org> - 1.5-8
- Merge another bug-fix from 1.6rc1 (this adds 3 symbols) and
really add tstring bug-fix:
* Split Ogg packets larger than 64k into multiple pages. (BUG:171957)
* Fixed a possible crash in the non-const version of String::operator[]
and in String::operator+=. (BUG:169389)
* Sun Aug 23 2009 Michael Schwendt <mschwendt@fedoraproject.org> - 1.5-7
- Build API documentation into -doc package.