]> granicus.if.org Git - taglib/commitdiff
Update interface. Just needs more documentation now.
authorAllan Sandfeld Jensen <kde@carewolf.com>
Mon, 23 Aug 2004 20:38:47 +0000 (20:38 +0000)
committerAllan Sandfeld Jensen <kde@carewolf.com>
Mon, 23 Aug 2004 20:38:47 +0000 (20:38 +0000)
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@340209 283d02a7-25f6-0310-bc7c-ecb5cbfe19da

ape/Makefile.am
ape/apefooter.cpp
ape/apeitem.cpp [new file with mode: 0644]
ape/apeitem.h [new file with mode: 0644]
ape/apetag.cpp
ape/apetag.h

index 25637340f7be6047a17069b8beaff867c262def3..e28770d865867f5dcbbbbd016909d1758aeba636 100644 (file)
@@ -5,7 +5,7 @@ INCLUDES = \
 
 noinst_LTLIBRARIES = libape.la
 
-libape_la_SOURCES = apetag.cpp apefooter.cpp
+libape_la_SOURCES = apetag.cpp apefooter.cpp apeitem.cpp
 
 taglib_include_HEADERS = apetag.h apefooter.h
 taglib_includedir = $(includedir)/taglib
index 7d709dec515a1c169a3fc0ca53300087b7aac473..bde69782c9d0f3856b4d76dfcbec66eaafe4d925 100644 (file)
@@ -181,7 +181,7 @@ void Footer::parse(const ByteVector &data)
   d->itemCount = data.mid(16, 4).toUInt(false);
 
   // Read the flags
-  std::bitset<32> flags(data.mid(8, 4).toUInt(false));
+  std::bitset<32> flags(data.mid(20, 4).toUInt(false));
 
   d->headerPresent         = flags[31];
   d->footerPresent         = !flags[30];
diff --git a/ape/apeitem.cpp b/ape/apeitem.cpp
new file mode 100644 (file)
index 0000000..1cc7950
--- /dev/null
@@ -0,0 +1,167 @@
+/***************************************************************************
+    copyright            : (C) 2004 by Allan Sandfeld Jensen
+    email                : kde@carewolf.com
+ ***************************************************************************/
+
+/***************************************************************************
+ *   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 "apeitem.h"
+#include "tbytevectorlist.h"
+#include "tstringlist.h"
+#include <iostream>
+
+using std::cout;
+
+using namespace TagLib;
+using namespace APE;
+
+
+class APE::Item::ItemPrivate
+{
+public:
+  ItemPrivate() : type(Text), readOnly(false) {}
+
+  Item::ItemTypes type;
+  String key;
+  ByteVector value;
+  StringList text;
+  bool readOnly;
+};
+
+APE::Item::Item()
+{
+  d = new ItemPrivate;
+}
+
+APE::Item::Item(const String& key, const String& str)
+{
+  d = new ItemPrivate;
+  d->key = key;
+  d->text.append(str);
+}
+
+APE::Item::Item(const Item& item)
+{
+  d = new ItemPrivate(*item.d);
+}
+
+Item& APE::Item::operator=(const Item& item)
+{
+  delete d;
+  d = new ItemPrivate(*item.d);
+  return *this;
+}
+
+void APE::Item::setReadOnly(bool val) {
+  d->readOnly = val;
+}
+
+bool APE::Item::isReadOnly() const {
+  return d->readOnly;
+}
+
+void APE::Item::setType(APE::Item::ItemTypes val) {
+  d->type = val;
+}
+
+APE::Item::ItemTypes APE::Item::type() const {
+  return d->type;
+}
+
+String APE::Item::key() const {
+  return d->key;
+}
+
+ByteVector APE::Item::value() const {
+  return d->value;
+}
+
+int APE::Item::size() const {
+  return  8 + d->key.size() + 1 + d->value.size();
+}
+
+StringList APE::Item::toStringList() const {
+  return d->text;
+}
+
+String APE::Item::toString() const {
+  return d->text.front();
+}
+
+bool APE::Item::isEmpty() const {
+  switch(d->type) {
+    case 0:
+    case 1:
+      if(d->text.isEmpty()) return true;
+      if(d->text.size() == 1 && d->text.front() == "") return true;
+      return false;
+    case 2:
+      return d->value.isEmpty();
+    default:
+      return false;
+  }
+}
+
+void APE::Item::parse(const ByteVector& data) {
+  uint valueLength  = data.mid(0, 4).toUInt(false);
+  uint flags        = data.mid(4, 4).toUInt(false);
+
+  d->key = String(data.mid(8), String::UTF8);
+
+  d->value = data.mid(8 + d->key.size() + 1, valueLength);
+
+  setReadOnly(flags & 1);
+  setType(ItemTypes((flags >> 1) & 3));
+
+  if ((int)(d->type) < 2) {
+    ByteVectorList bl = ByteVectorList::split(d->value, '\0');
+    d->text = StringList(bl, String::UTF8);
+    cout << d->text.toString(",") << "\n";
+  }
+
+}
+
+ByteVector APE::Item::render()
+{
+  ByteVector data;
+  TagLib::uint flags = ((d->readOnly) ? 1 : 0) | (d->type << 1);
+  ByteVector value;
+
+  if(isEmpty())
+    return data;
+
+  if(d->type != Item::Binary) {
+    StringList::ConstIterator it = d->text.begin();
+    value.append(it->data(String::UTF8));
+    it++;
+    while(it != d->text.end()) {
+      value.append('\0');
+      value.append(it->data(String::UTF8));
+      it++;
+    }
+    d->value = value;
+  } else
+    value.append(d->value);
+
+  data.append(ByteVector::fromUInt(value.size(), false));
+  data.append(ByteVector::fromUInt(flags, false));
+  data.append(d->key.data(String::UTF8));
+  data.append(ByteVector('\0'));
+  data.append(value);
+
+  return data;
+}
diff --git a/ape/apeitem.h b/ape/apeitem.h
new file mode 100644 (file)
index 0000000..a450f01
--- /dev/null
@@ -0,0 +1,90 @@
+/***************************************************************************
+    copyright            : (C) 2004 by Allan Sandfeld Jensen
+    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                                                                   *
+ ***************************************************************************/
+
+#ifndef TAGLIB_APEITEM_H
+#define TAGLIB_APEITEM_H
+
+#include <tbytevector.h>
+#include <tstring.h>
+#include <tstringlist.h>
+
+namespace TagLib {
+
+  namespace APE {
+
+    //! An implementation of APE-items
+
+    /*!
+     * This class provides the features of items in the APEv2 standard.
+     */
+    struct Item
+    {
+      enum ItemTypes {
+        //! Item contains text information coded in UTF-8
+        Text = 0,
+        //! Item contains binary information
+        Binary = 1,
+        //! Item is a locator of external stored information
+        Locator = 2
+      };
+      Item();
+      explicit Item(ByteVector& bin);
+      explicit Item(const String&, const String&);
+      explicit Item(const String&, const StringList &);
+      Item(const Item&);
+      Item& operator=(const Item&);
+
+      String key() const;
+      ByteVector value() const;
+
+      int size() const;
+
+      String toString() const;
+      StringList toStringList() const;
+
+      ByteVector render();
+      void parse(const ByteVector&);
+
+      void setReadOnly(bool);
+
+      bool isReadOnly() const;
+
+      void setType(ItemTypes type);
+
+      ItemTypes type() const;
+/*
+      void setValue(ByteVector);
+      void setValue(const String&);
+      void setValue(const StringList&);
+ */
+      bool isEmpty() const;
+
+    private:
+      class ItemPrivate;
+      ItemPrivate *d;
+    };
+  }
+
+}
+
+#endif
+
+
index db936e2fc60a91539cfd0fa2f7cc064242b1bbfb..0d69a9f5decb437e325e576f45def4e287b9a8fd 100644 (file)
 
 #include "apetag.h"
 #include "apefooter.h"
+#include "apeitem.h"
 
 using namespace TagLib;
 using namespace APE;
-
-static ByteVector renderAPEItem(const String &key, const Item &item)
-{
-  ByteVector data;
-  TagLib::uint flags = ((item.readOnly) ? 1 : 0) | ((item.locator) ? 2 : 0);
-  ByteVector value;
-
-  if(item.value.isEmpty())
-    return data;
-
-  StringList::ConstIterator it = item.value.begin();
-  value.append(it->data(String::UTF8));
-  it++;
-  while(it != item.value.end()) {
-    value.append('\0');
-    value.append(it->data(String::UTF8));
-    it++;
-  }
-
-  data.append(ByteVector::fromUInt(value.size(), false));
-  data.append(ByteVector::fromUInt(flags, false));
-  data.append(key.data(String::UTF8));
-  data.append(ByteVector('\0'));
-  data.append(value);
-
-  return data;
-}
-
+/*
 static StringList parseAPEString(const ByteVector &data)
 {
   StringList value;
@@ -71,7 +45,7 @@ static StringList parseAPEString(const ByteVector &data)
   value.append(String(data.mid(pOld), String::UTF8));
 
   return value;
-}
+}*/
 
 class APE::Tag::TagPrivate
 {
@@ -85,24 +59,8 @@ public:
   Footer footer;
 
   ItemListMap itemListMap;
-  Map<const String, ByteVector> binaries;
 };
 
-APE::Item::Item(const String& str) : readOnly(false), locator(false)
-{
-  value.append(str);
-}
-
-APE::Item::Item(const StringList& values) : readOnly(false), locator(false)
-{
-  value.append(values);
-}
-
-bool APE::Item::isEmpty() const
-{
-  return value.isEmpty();
-}
-
 ////////////////////////////////////////////////////////////////////////////////
 // public methods
 ////////////////////////////////////////////////////////////////////////////////
@@ -126,40 +84,6 @@ APE::Tag::~Tag()
   delete d;
 }
 
-ByteVector APE::Tag::render() const
-{
-  ByteVector data;
-  uint itemCount = 0;
-
-  {
-    Map<const String,Item>::Iterator i = d->itemListMap.begin();
-    while(i != d->itemListMap.end()) {
-      if(!i->second.value.isEmpty()) {
-        data.append(renderAPEItem(i->first, i->second));
-        itemCount++;
-      }
-      i++;
-    }
-  }
-
-  {
-    Map<String,ByteVector>::Iterator i = d->binaries.begin();
-    while(i != d->binaries.end()) {
-      if(!i->second.isEmpty()) {
-        data.append(i->second);
-        itemCount++;
-      }
-      i++;
-    }
-  }
-
-  d->footer.setItemCount(itemCount);
-  d->footer.setTagSize(data.size()+Footer::size());
-  d->footer.setHeaderPresent(true);
-
-  return d->footer.renderHeader() + data + d->footer.renderFooter();
-}
-
 ByteVector APE::Tag::fileIdentifier()
 {
   return ByteVector::fromCString("APETAGEX");
@@ -169,49 +93,49 @@ String APE::Tag::title() const
 {
   if(d->itemListMap["TITLE"].isEmpty())
     return String::null;
-  return d->itemListMap["TITLE"].value.front();
+  return d->itemListMap["TITLE"].toString();
 }
 
 String APE::Tag::artist() const
 {
   if(d->itemListMap["ARTIST"].isEmpty())
     return String::null;
-  return d->itemListMap["ARTIST"].value.front();
+  return d->itemListMap["ARTIST"].toString();
 }
 
 String APE::Tag::album() const
 {
   if(d->itemListMap["ALBUM"].isEmpty())
     return String::null;
-  return d->itemListMap["ALBUM"].value.front();
+  return d->itemListMap["ALBUM"].toString();
 }
 
 String APE::Tag::comment() const
 {
   if(d->itemListMap["COMMENT"].isEmpty())
     return String::null;
-  return d->itemListMap["COMMENT"].value.front();
+  return d->itemListMap["COMMENT"].toString();
 }
 
 String APE::Tag::genre() const
 {
   if(d->itemListMap["GENRE"].isEmpty())
     return String::null;
-  return d->itemListMap["GENRE"].value.front();
+  return d->itemListMap["GENRE"].toString();
 }
 
 TagLib::uint APE::Tag::year() const
 {
   if(d->itemListMap["YEAR"].isEmpty())
     return 0;
-  return d->itemListMap["YEAR"].value.front().toInt();
+  return d->itemListMap["YEAR"].toString().toInt();
 }
 
 TagLib::uint APE::Tag::track() const
 {
   if(d->itemListMap["TRACK"].isEmpty())
     return 0;
-  return d->itemListMap["TRACK"].value.front().toInt();
+  return d->itemListMap["TRACK"].toString().toInt();
 }
 
 void APE::Tag::setTitle(const String &s)
@@ -278,9 +202,9 @@ void APE::Tag::addValue(const String &key, const String &value, bool replace)
     removeItem(key);
   if(!value.isEmpty()) {
     if(d->itemListMap.contains(key) || !replace)
-      d->itemListMap[key.upper()].value.append(value);
+      d->itemListMap[key.upper()].toStringList().append(value);
     else
-      setItem(key, Item(value));
+      setItem(key, Item(key, value));
   }
 }
 
@@ -309,24 +233,38 @@ void APE::Tag::read()
   }
 }
 
+ByteVector APE::Tag::render() const
+{
+  ByteVector data;
+  uint itemCount = 0;
+
+  {
+    Map<const String,Item>::Iterator i = d->itemListMap.begin();
+    while(i != d->itemListMap.end()) {
+      data.append(i->second.render());
+      itemCount++;
+      i++;
+    }
+  }
+
+  d->footer.setItemCount(itemCount);
+  d->footer.setTagSize(data.size()+Footer::size());
+  d->footer.setHeaderPresent(true);
+
+  return d->footer.renderHeader() + data + d->footer.renderFooter();
+}
+
 void APE::Tag::parse(const ByteVector &data, uint count)
 {
   uint pos = 0;
 
   while(count > 0) {
-    uint valueLength = data.mid(pos + 0, 4).toUInt(false);
-    uint flags = data.mid(pos + 4, 4).toUInt(false);
-    String key = String(data.mid(pos + 8), String::UTF8);
     APE::Item item;
+    item.parse(data.mid(pos));
 
-    if(flags < 4 ) {
-      ByteVector val = data.mid(pos + 8 + key.size() + 1, valueLength);
-      d->itemListMap.insert(key.upper(), Item(parseAPEString(val)));
-    }
-    else
-      d->binaries.insert(key.upper(), data.mid(pos, 8 + key.size() + 1 + valueLength));
+    d->itemListMap.insert(item.key().upper(), item);
 
-    pos += 8 + key.size() + 1 + valueLength;
+    pos += item.size();
     count--;
   }
 }
index 9646d0858f73bab546991629e88a741da928a247..7c6438bdc3fe2887768c001a07638b528bdefc3c 100644 (file)
@@ -28,6 +28,8 @@
 #include "tstring.h"
 #include "tstringlist.h"
 
+#include "apeitem.h"
+
 namespace TagLib {
 
   class File;
@@ -36,22 +38,6 @@ namespace TagLib {
 
     class Footer;
 
-    /*!
-     * A non-binary APE-item.
-     */
-    struct Item
-    {
-      Item() {};
-      explicit Item(const String &);
-      explicit Item(const StringList &);
-      bool readOnly;
-      /*!
-       * The value is a URL to external data
-       */
-      bool locator;
-      StringList value;
-      bool isEmpty() const;
-    };
 
     /*!
      * A mapping between a list of item names, or keys, and the associated item.
@@ -120,7 +106,7 @@ namespace TagLib {
       const ItemListMap &itemListMap() const;
 
       /*!
-       * Removes the \a key comment from the tag
+       * Removes the \a key item from the tag
        */
       void removeItem(const String &key);