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

216 lines
5.5 KiB
C++
Raw Normal View History

2018-05-10 15:29:28 +02:00
/***************************************************************************
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>
2020-06-26 23:30:30 +02:00
#include "tstring.h"
#include "tdebug.h"
2018-05-10 15:29:28 +02:00
#include "apefooter.h"
using namespace Strawberry_TagLib::TagLib;
2018-05-10 15:29:28 +02:00
using namespace APE;
2020-06-13 19:02:42 +02:00
class APE::Footer::FooterPrivate {
public:
FooterPrivate() : version(0),
footerPresent(true),
headerPresent(false),
isHeader(false),
itemCount(0),
tagSize(0) {}
2018-05-10 15:29:28 +02:00
unsigned int version;
bool footerPresent;
bool headerPresent;
bool isHeader;
unsigned int itemCount;
unsigned int tagSize;
};
////////////////////////////////////////////////////////////////////////////////
// static members
////////////////////////////////////////////////////////////////////////////////
2020-06-13 19:02:42 +02:00
unsigned int APE::Footer::size() {
2018-05-10 15:29:28 +02:00
return 32;
}
2020-06-13 19:02:42 +02:00
ByteVector APE::Footer::fileIdentifier() {
2018-05-10 15:29:28 +02:00
return ByteVector("APETAGEX");
}
////////////////////////////////////////////////////////////////////////////////
// public members
////////////////////////////////////////////////////////////////////////////////
2020-06-13 19:02:42 +02:00
APE::Footer::Footer() : d(new FooterPrivate()) {
2018-05-10 15:29:28 +02:00
}
2020-06-13 19:02:42 +02:00
APE::Footer::Footer(const ByteVector &data) : d(new FooterPrivate()) {
2018-05-10 15:29:28 +02:00
parse(data);
}
2020-06-13 19:02:42 +02:00
APE::Footer::~Footer() {
2018-05-10 15:29:28 +02:00
delete d;
}
2020-06-13 19:02:42 +02:00
unsigned int APE::Footer::version() const {
2018-05-10 15:29:28 +02:00
return d->version;
}
2020-06-13 19:02:42 +02:00
bool APE::Footer::headerPresent() const {
2018-05-10 15:29:28 +02:00
return d->headerPresent;
}
2020-06-13 19:02:42 +02:00
bool APE::Footer::footerPresent() const {
2018-05-10 15:29:28 +02:00
return d->footerPresent;
}
2020-06-13 19:02:42 +02:00
bool APE::Footer::isHeader() const {
2018-05-10 15:29:28 +02:00
return d->isHeader;
}
2020-06-13 19:02:42 +02:00
void APE::Footer::setHeaderPresent(bool b) const {
2018-05-10 15:29:28 +02:00
d->headerPresent = b;
}
2020-06-13 19:02:42 +02:00
unsigned int APE::Footer::itemCount() const {
2018-05-10 15:29:28 +02:00
return d->itemCount;
}
2020-06-13 19:02:42 +02:00
void APE::Footer::setItemCount(unsigned int s) {
2018-05-10 15:29:28 +02:00
d->itemCount = s;
}
2020-06-13 19:02:42 +02:00
unsigned int APE::Footer::tagSize() const {
2018-05-10 15:29:28 +02:00
return d->tagSize;
}
2020-06-13 19:02:42 +02:00
unsigned int APE::Footer::completeTagSize() const {
if (d->headerPresent)
2018-05-10 15:29:28 +02:00
return d->tagSize + size();
else
return d->tagSize;
}
2020-06-13 19:02:42 +02:00
void APE::Footer::setTagSize(unsigned int s) {
2018-05-10 15:29:28 +02:00
d->tagSize = s;
}
2020-06-13 19:02:42 +02:00
void APE::Footer::setData(const ByteVector &data) {
2018-05-10 15:29:28 +02:00
parse(data);
}
2020-06-13 19:02:42 +02:00
ByteVector APE::Footer::renderFooter() const {
2018-05-10 15:29:28 +02:00
return render(false);
}
2020-06-13 19:02:42 +02:00
ByteVector APE::Footer::renderHeader() const {
2020-06-13 19:02:42 +02:00
if (!d->headerPresent)
2018-05-10 15:29:28 +02:00
return ByteVector();
else
return render(true);
2018-05-10 15:29:28 +02:00
}
////////////////////////////////////////////////////////////////////////////////
// protected members
////////////////////////////////////////////////////////////////////////////////
2020-06-13 19:02:42 +02:00
void APE::Footer::parse(const ByteVector &data) {
2020-06-13 19:02:42 +02:00
if (data.size() < size())
2018-05-10 15:29:28 +02:00
return;
// The first eight bytes, data[0..7], are the File Identifier, "APETAGEX".
// Read the version number
2020-06-26 23:30:30 +02:00
d->version = data.toUInt32LE(8);
2018-05-10 15:29:28 +02:00
// Read the tag size
2020-06-26 23:30:30 +02:00
d->tagSize = data.toUInt32LE(12);
2018-05-10 15:29:28 +02:00
// Read the item count
2020-06-26 23:30:30 +02:00
d->itemCount = data.toUInt32LE(16);
2018-05-10 15:29:28 +02:00
// Read the flags
2020-06-26 23:30:30 +02:00
std::bitset<32> flags(TAGLIB_CONSTRUCT_BITSET(data.toUInt32LE(20)));
2018-05-10 15:29:28 +02:00
d->headerPresent = flags[31];
d->footerPresent = !flags[30];
d->isHeader = flags[29];
2018-05-10 15:29:28 +02:00
}
2020-06-13 19:02:42 +02:00
ByteVector APE::Footer::render(bool isHeader) const {
2018-05-10 15:29:28 +02:00
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.
2020-06-26 23:30:30 +02:00
v.append(ByteVector::fromUInt32LE(2000));
2018-05-10 15:29:28 +02:00
// add the tag size
2020-06-26 23:30:30 +02:00
v.append(ByteVector::fromUInt32LE(d->tagSize));
2018-05-10 15:29:28 +02:00
// add the item count
2020-06-26 23:30:30 +02:00
v.append(ByteVector::fromUInt32LE(d->itemCount));
2018-05-10 15:29:28 +02:00
// render and add the flags
std::bitset<32> flags;
flags[31] = d->headerPresent;
2020-06-13 19:02:42 +02:00
flags[30] = false; // footer is always present
2018-05-10 15:29:28 +02:00
flags[29] = isHeader;
2020-06-26 23:30:30 +02:00
v.append(ByteVector::fromUInt32LE(flags.to_ulong()));
2018-05-10 15:29:28 +02:00
// add the reserved 64bit
2020-06-26 23:30:30 +02:00
v.append(ByteVector::fromUInt64BE(0));
2018-05-10 15:29:28 +02:00
return v;
2018-05-10 15:29:28 +02:00
}