diff options
Diffstat (limited to 'libs/taglib/taglib/ape/apefooter.cpp')
-rw-r--r-- | libs/taglib/taglib/ape/apefooter.cpp | 236 |
1 files changed, 236 insertions, 0 deletions
diff --git a/libs/taglib/taglib/ape/apefooter.cpp b/libs/taglib/taglib/ape/apefooter.cpp new file mode 100644 index 0000000000..da6494b0b0 --- /dev/null +++ b/libs/taglib/taglib/ape/apefooter.cpp @@ -0,0 +1,236 @@ +/*************************************************************************** + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * + * 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 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; +} |