taglib/ape/apefooter.cpp
Scott Wheeler a51d1cb117 Scott's silly nitpicks...
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@345141 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2004-09-09 00:28:57 +00:00

233 lines
5.1 KiB
C++

/***************************************************************************
copyright : (C) 2004 by Allan Sandfeld Jensen
(C) 2002, 2003 by Scott Wheeler (id3v2header.cpp)
email : kde@carewolf.org
***************************************************************************/
/***************************************************************************
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License version *
* 2.1 as published by the Free Software Foundation. *
* *
* This library is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
* USA *
***************************************************************************/
#include <iostream>
#include <bitset>
#include <tstring.h>
#include <tdebug.h>
#include "apefooter.h"
using namespace TagLib;
using namespace APE;
class Footer::FooterPrivate
{
public:
FooterPrivate() : version(0),
footerPresent(true),
headerPresent(false),
isHeader(false),
itemCount(0),
tagSize(0) {}
~FooterPrivate() {}
uint version;
bool footerPresent;
bool headerPresent;
bool isHeader;
uint itemCount;
uint tagSize;
static const uint size = 32;
};
////////////////////////////////////////////////////////////////////////////////
// static members
////////////////////////////////////////////////////////////////////////////////
TagLib::uint Footer::size()
{
return FooterPrivate::size;
}
ByteVector Footer::fileIdentifier()
{
return ByteVector::fromCString("APETAGEX");
}
////////////////////////////////////////////////////////////////////////////////
// public members
////////////////////////////////////////////////////////////////////////////////
Footer::Footer()
{
d = new FooterPrivate;
}
Footer::Footer(const ByteVector &data)
{
d = new FooterPrivate;
parse(data);
}
Footer::~Footer()
{
delete d;
}
TagLib::uint Footer::version() const
{
return d->version;
}
bool Footer::headerPresent() const
{
return d->headerPresent;
}
bool Footer::footerPresent() const
{
return d->footerPresent;
}
bool Footer::isHeader() const
{
return d->isHeader;
}
void Footer::setHeaderPresent(bool b) const
{
d->headerPresent = b;
}
TagLib::uint Footer::itemCount() const
{
return d->itemCount;
}
void Footer::setItemCount(uint s)
{
d->itemCount = s;
}
TagLib::uint Footer::tagSize() const
{
return d->tagSize;
}
TagLib::uint Footer::completeTagSize() const
{
if(d->headerPresent)
return d->tagSize + d->size;
else
return d->tagSize;
}
void Footer::setTagSize(uint s)
{
d->tagSize = s;
}
void Footer::setData(const ByteVector &data)
{
parse(data);
}
ByteVector Footer::renderFooter() const
{
return render(false);
}
ByteVector Footer::renderHeader() const
{
if (!d->headerPresent) return ByteVector();
return render(true);
}
////////////////////////////////////////////////////////////////////////////////
// protected members
////////////////////////////////////////////////////////////////////////////////
void Footer::parse(const ByteVector &data)
{
if(data.size() < size())
return;
// The first eight bytes, data[0..7], are the File Identifier, "APETAGEX".
// Read the version number
d->version = data.mid(8, 4).toUInt(false);
// Read the tag size
d->tagSize = data.mid(12, 4).toUInt(false);
// Read the item count
d->itemCount = data.mid(16, 4).toUInt(false);
// Read the flags
std::bitset<32> flags(data.mid(20, 4).toUInt(false));
d->headerPresent = flags[31];
d->footerPresent = !flags[30];
d->isHeader = flags[29];
}
ByteVector Footer::render(bool isHeader) const
{
ByteVector v;
// add the file identifier -- "APETAGEX"
v.append(fileIdentifier());
// add the version number -- we always render a 2.000 tag regardless of what
// the tag originally was.
v.append(ByteVector::fromUInt(2000, false));
// add the tag size
v.append(ByteVector::fromUInt(d->tagSize, false));
// add the item count
v.append(ByteVector::fromUInt(d->itemCount, false));
// render and add the flags
std::bitset<32> flags;
flags[31] = d->headerPresent;
flags[30] = false; // footer is always present
flags[29] = isHeader;
v.append(ByteVector::fromUInt(flags.to_ulong(), false));
// add the reserved 64bit
v.append(ByteVector::fromLongLong(0));
return v;
}