strawberry-audio-player-win.../3rdparty/taglib/ape/apefooter.cpp

216 lines
5.5 KiB
C++

/***************************************************************************
copyright : (C) 2004 by Allan Sandfeld Jensen
(C) 2002 - 2008 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., 51 Franklin Street, Fifth Floor, Boston, MA *
* 02110-1301 USA *
* *
* Alternatively, this file is available under the Mozilla Public *
* License Version 1.1. You may obtain a copy of the License at *
* http://www.mozilla.org/MPL/ *
***************************************************************************/
#include <iostream>
#include <bitset>
#include "tstring.h"
#include "tdebug.h"
#include "apefooter.h"
using namespace Strawberry_TagLib::TagLib;
using namespace APE;
class APE::Footer::FooterPrivate {
public:
FooterPrivate() : version(0),
footerPresent(true),
headerPresent(false),
isHeader(false),
itemCount(0),
tagSize(0) {}
unsigned int version;
bool footerPresent;
bool headerPresent;
bool isHeader;
unsigned int itemCount;
unsigned int tagSize;
};
////////////////////////////////////////////////////////////////////////////////
// static members
////////////////////////////////////////////////////////////////////////////////
unsigned int APE::Footer::size() {
return 32;
}
ByteVector APE::Footer::fileIdentifier() {
return ByteVector("APETAGEX");
}
////////////////////////////////////////////////////////////////////////////////
// public members
////////////////////////////////////////////////////////////////////////////////
APE::Footer::Footer() : d(new FooterPrivate()) {
}
APE::Footer::Footer(const ByteVector &data) : d(new FooterPrivate()) {
parse(data);
}
APE::Footer::~Footer() {
delete d;
}
unsigned int APE::Footer::version() const {
return d->version;
}
bool APE::Footer::headerPresent() const {
return d->headerPresent;
}
bool APE::Footer::footerPresent() const {
return d->footerPresent;
}
bool APE::Footer::isHeader() const {
return d->isHeader;
}
void APE::Footer::setHeaderPresent(bool b) const {
d->headerPresent = b;
}
unsigned int APE::Footer::itemCount() const {
return d->itemCount;
}
void APE::Footer::setItemCount(unsigned int s) {
d->itemCount = s;
}
unsigned int APE::Footer::tagSize() const {
return d->tagSize;
}
unsigned int APE::Footer::completeTagSize() const {
if (d->headerPresent)
return d->tagSize + size();
else
return d->tagSize;
}
void APE::Footer::setTagSize(unsigned int s) {
d->tagSize = s;
}
void APE::Footer::setData(const ByteVector &data) {
parse(data);
}
ByteVector APE::Footer::renderFooter() const {
return render(false);
}
ByteVector APE::Footer::renderHeader() const {
if (!d->headerPresent)
return ByteVector();
else
return render(true);
}
////////////////////////////////////////////////////////////////////////////////
// protected members
////////////////////////////////////////////////////////////////////////////////
void APE::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.toUInt32LE(8);
// Read the tag size
d->tagSize = data.toUInt32LE(12);
// Read the item count
d->itemCount = data.toUInt32LE(16);
// Read the flags
std::bitset<32> flags(TAGLIB_CONSTRUCT_BITSET(data.toUInt32LE(20)));
d->headerPresent = flags[31];
d->footerPresent = !flags[30];
d->isHeader = flags[29];
}
ByteVector APE::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::fromUInt32LE(2000));
// add the tag size
v.append(ByteVector::fromUInt32LE(d->tagSize));
// add the item count
v.append(ByteVector::fromUInt32LE(d->itemCount));
// 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::fromUInt32LE(flags.to_ulong()));
// add the reserved 64bit
v.append(ByteVector::fromUInt64BE(0));
return v;
}