class APE::Tag::TagPrivate
{
public:
+ TagPrivate() :
+ file(0),
+ footerLocation(0) {}
+
+ File *file;
+ long footerLocation;
+
Footer footer;
ItemListMap itemListMap;
};
TagLib::Tag(),
d(new TagPrivate())
{
- read(file, footerLocation);
+ d->file = file;
+ d->footerLocation = footerLocation;
+
+ read();
}
APE::Tag::~Tag()
// protected methods
////////////////////////////////////////////////////////////////////////////////
-void APE::Tag::read(TagLib::File *file, long footerLocation)
+void APE::Tag::read()
{
- if(file && file->isValid()) {
+ if(d->file && d->file->isValid()) {
- file->seek(footerLocation);
- d->footer.setData(file->readBlock(Footer::size()));
+ d->file->seek(d->footerLocation);
+ d->footer.setData(d->file->readBlock(Footer::size()));
if(d->footer.tagSize() <= Footer::size() ||
- d->footer.tagSize() > static_cast<unsigned long>(file->length()))
+ d->footer.tagSize() > static_cast<unsigned long>(d->file->length()))
return;
- file->seek(footerLocation + Footer::size() - d->footer.tagSize());
- parse(file->readBlock(d->footer.tagSize() - Footer::size()));
+ d->file->seek(d->footerLocation + Footer::size() - d->footer.tagSize());
+ parse(d->file->readBlock(d->footer.tagSize() - Footer::size()));
}
}
/*!
* Reads from the file specified in the constructor.
*/
- void read(TagLib::File *file, long footerLocation);
+ void read();
/*!
* Parses the body of the tag in \a data.
{
public:
TagPrivate() :
+ file(0),
+ tagOffset(0),
track(0),
genre(255) {}
+ File *file;
+ long tagOffset;
+
String title;
String artist;
String album;
TagLib::Tag(),
d(new TagPrivate())
{
- read(file, tagOffset);
+ d->file = file;
+ d->tagOffset = tagOffset;
+
+ read();
}
ID3v1::Tag::~Tag()
// protected methods
////////////////////////////////////////////////////////////////////////////////
-void ID3v1::Tag::read(File *file, long tagOffset)
+void ID3v1::Tag::read()
{
- if(file && file->isValid()) {
- file->seek(tagOffset);
+ if(d->file && d->file->isValid()) {
+ d->file->seek(d->tagOffset);
// read the tag -- always 128 bytes
- const ByteVector data = file->readBlock(128);
+ const ByteVector data = d->file->readBlock(128);
// some initial sanity checking
if(data.size() == 128 && data.startsWith("TAG"))
/*!
* Reads from the file specified in the constructor.
*/
- void read(File *file, long tagOffset);
+ void read();
/*!
* Pareses the body of the tag in \a data.
*/
{
public:
TagPrivate() :
- fileLength(0),
+ file(0),
+ tagOffset(0),
extendedHeader(0),
footer(0)
{
delete footer;
}
- long fileLength;
const FrameFactory *factory;
+ File *file;
+ long tagOffset;
+
Header header;
ExtendedHeader *extendedHeader;
Footer *footer;
d(new TagPrivate())
{
d->factory = factory;
+ d->file = file;
+ d->tagOffset = tagOffset;
- read(file, tagOffset);
+ read();
}
ID3v2::Tag::~Tag()
else {
// Padding won't increase beyond 1% of the file size or 1MB.
- long threshold = d->fileLength / 100;
+ long threshold = d->file ? d->file->length() / 100 : 0;
threshold = std::max(threshold, MinPaddingSize);
threshold = std::min(threshold, MaxPaddingSize);
d->header.setMajorVersion(version);
d->header.setTagSize(tagData.size() - Header::size());
- if(d->fileLength > 0)
- d->fileLength += (d->header.tagSize() - originalSize);
-
// TODO: This should eventually include d->footer->render().
const ByteVector headerData = d->header.render();
std::copy(headerData.begin(), headerData.end(), tagData.begin());
// protected members
////////////////////////////////////////////////////////////////////////////////
-void ID3v2::Tag::read(TagLib::File *file, long offset)
+void ID3v2::Tag::read()
{
- if(!file)
+ if(!d->file)
return;
- if(!file->isOpen())
+ if(!d->file->isOpen())
return;
- d->fileLength = file->length();
-
- file->seek(offset);
- d->header.setData(file->readBlock(Header::size()));
+ d->file->seek(d->tagOffset);
+ d->header.setData(d->file->readBlock(Header::size()));
// If the tag size is 0, then this is an invalid tag (tags must contain at
// least one frame)
if(d->header.tagSize() != 0)
- parse(file->readBlock(d->header.tagSize()));
+ parse(d->file->readBlock(d->header.tagSize()));
// Look for duplicate ID3v2 tags and treat them as an extra blank of this one.
// It leads to overwriting them with zero when saving the tag.
while(true) {
- file->seek(offset + d->header.completeTagSize() + extraSize);
+ d->file->seek(d->tagOffset + d->header.completeTagSize() + extraSize);
- const ByteVector data = file->readBlock(Header::size());
+ const ByteVector data = d->file->readBlock(Header::size());
if(data.size() < Header::size() || !data.startsWith(Header::fileIdentifier()))
break;
* the Header, the body of the tag (which contains the ExtendedHeader and
* frames) and Footer.
*/
- void read(TagLib::File *file, long offset);
+ void read();
/*!
* This is called by read to parse the body of the tag. It determines if an