Added TagLib (with AUTORS and COPYING files)
[someplayer] / src / taglib / ape / apefooter.cpp
diff --git a/src/taglib/ape/apefooter.cpp b/src/taglib/ape/apefooter.cpp
new file mode 100644 (file)
index 0000000..da6494b
--- /dev/null
@@ -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;
+}