revamp plugin_common to use utf-8 instead of wchar_t as the internal comment format
authorJosh Coalson <jcoalson@users.sourceforce.net>
Thu, 30 Dec 2004 03:38:37 +0000 (03:38 +0000)
committerJosh Coalson <jcoalson@users.sourceforce.net>
Thu, 30 Dec 2004 03:38:37 +0000 (03:38 +0000)
src/plugin_common/canonical_tag.c [deleted file]
src/plugin_common/canonical_tag.h [deleted file]
src/plugin_common/tags.c [new file with mode: 0644]
src/plugin_common/tags.h [new file with mode: 0644]
src/plugin_common/vorbiscomment.c [deleted file]
src/plugin_common/vorbiscomment.h [deleted file]

diff --git a/src/plugin_common/canonical_tag.c b/src/plugin_common/canonical_tag.c
deleted file mode 100644 (file)
index c8b1154..0000000
+++ /dev/null
@@ -1,582 +0,0 @@
-/* plugin_common - Routines common to several plugins\r
- * Copyright (C) 2002,2003,2004  Josh Coalson\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.\r
- */\r
-\r
-#ifdef HAVE_CONFIG_H\r
-#include <config.h>\r
-#endif\r
-\r
-#include <stdlib.h>\r
-#include <stdio.h>\r
-#include <string.h> /* for strlen() and memcpy() */\r
-\r
-#include "canonical_tag.h"\r
-#include "vorbiscomment.h"\r
-#include "FLAC/assert.h"\r
-#include "FLAC/metadata.h"\r
-\r
-#include <wchar.h>\r
-\r
-/*\r
- * Here lies hackage to get any missing wide character string functions we\r
- * need.  The fallback implementations here are from glibc.\r
- */\r
-\r
-#if !defined(_MSC_VER) && !defined(HAVE_WCSDUP)\r
-/* Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.\r
-   This file is part of the GNU C Library.\r
-   Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.\r
-\r
-   The GNU C Library is free software; you can redistribute it and/or\r
-   modify it under the terms of the GNU Lesser General Public\r
-   License as published by the Free Software Foundation; either\r
-   version 2.1 of the License, or (at your option) any later version.\r
-\r
-   The GNU C Library is distributed in the hope that it will be useful,\r
-   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
-   Lesser General Public License for more details.\r
-\r
-   You should have received a copy of the GNU Lesser General Public\r
-   License along with the GNU C Library; if not, write to the Free\r
-   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA\r
-   02111-1307 USA.  */\r
-\r
-#include <wchar.h>\r
-#include <string.h>\r
-#include <stdlib.h>\r
-\r
-\r
-/* Duplicate S, returning an identical malloc'd string.         */\r
-wchar_t *\r
-wcsdup (s)\r
-     const wchar_t *s;\r
-{\r
-  size_t len = (__wcslen (s) + 1) * sizeof (wchar_t);\r
-  void *new = malloc (len);\r
-\r
-  if (new == NULL)\r
-    return NULL;\r
-\r
-  return (wchar_t *) memcpy (new, (void *) s, len);\r
-}\r
-#endif\r
-\r
-#if !defined(_MSC_VER) && !defined(HAVE_WCSCASECMP)\r
-/* Copyright (C) 1991, 1992, 1995, 1996, 1997 Free Software Foundation, Inc.\r
-   This file is part of the GNU C Library.\r
-\r
-   The GNU C Library is free software; you can redistribute it and/or\r
-   modify it under the terms of the GNU Lesser General Public\r
-   License as published by the Free Software Foundation; either\r
-   version 2.1 of the License, or (at your option) any later version.\r
-\r
-   The GNU C Library is distributed in the hope that it will be useful,\r
-   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
-   Lesser General Public License for more details.\r
-\r
-   You should have received a copy of the GNU Lesser General Public\r
-   License along with the GNU C Library; if not, write to the Free\r
-   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA\r
-   02111-1307 USA.  */\r
-\r
-#include <wctype.h>\r
-#include <wchar.h>\r
-\r
-#ifndef weak_alias\r
-# define __wcscasecmp wcscasecmp\r
-# define TOLOWER(Ch) towlower (Ch)\r
-#else\r
-# ifdef USE_IN_EXTENDED_LOCALE_MODEL\r
-#  define __wcscasecmp __wcscasecmp_l\r
-#  define TOLOWER(Ch) __towlower_l ((Ch), loc)\r
-# else\r
-#  define TOLOWER(Ch) towlower (Ch)\r
-# endif\r
-#endif\r
-\r
-#ifdef USE_IN_EXTENDED_LOCALE_MODEL\r
-# define LOCALE_PARAM , loc\r
-# define LOCALE_PARAM_DECL __locale_t loc;\r
-#else\r
-# define LOCALE_PARAM\r
-# define LOCALE_PARAM_DECL\r
-#endif\r
-\r
-/* Compare S1 and S2, ignoring case, returning less than, equal to or\r
-   greater than zero if S1 is lexicographically less than,\r
-   equal to or greater than S2.  */\r
-int\r
-__wcscasecmp (s1, s2 LOCALE_PARAM)\r
-     const wchar_t *s1;\r
-     const wchar_t *s2;\r
-     LOCALE_PARAM_DECL\r
-{\r
-  wint_t c1, c2;\r
-\r
-  if (s1 == s2)\r
-    return 0;\r
-\r
-  do\r
-    {\r
-      c1 = TOLOWER (*s1++);\r
-      c2 = TOLOWER (*s2++);\r
-      if (c1 == L'\0')\r
-       break;\r
-    }\r
-  while (c1 == c2);\r
-\r
-  return c1 - c2;\r
-}\r
-#ifndef __wcscasecmp\r
-weak_alias (__wcscasecmp, wcscasecmp)\r
-#endif\r
-#endif\r
-\r
-/*\r
- *  helpers\r
- */\r
-\r
-/* TODO: should be moved out somewhere? @@@ */\r
-\r
-wchar_t *FLAC_plugin__convert_ansi_to_wide(const char *src)\r
-{\r
-       int len;\r
-       wchar_t *dest;\r
-\r
-       FLAC__ASSERT(0 != src);\r
-\r
-       len = strlen(src) + 1;\r
-       /* copy */\r
-       dest = malloc(len*sizeof(wchar_t));\r
-       if (dest) mbstowcs(dest, src, len);\r
-       return dest;\r
-}\r
-\r
-/* TODO: more validation? @@@ */\r
-static __inline int utf8len(const FLAC__byte *utf8)\r
-{\r
-       FLAC__ASSERT(0 != utf8);\r
-       if ((*utf8 & 0x80) == 0)\r
-               return 1;\r
-       else if ((*utf8 & 0xE0) == 0xC0)\r
-               return 2;\r
-       else if ((*utf8 & 0xF0) == 0xE0)\r
-               return 3;\r
-       else return 0;\r
-}\r
-\r
-/* TODO: validation? @@@ */\r
-static __inline int utf8_to_ucs2(const FLAC__byte *utf8, wchar_t *ucs2)\r
-{\r
-       int len;\r
-       FLAC__ASSERT(utf8!=0 && *utf8!=0 && ucs2!=0);\r
-\r
-       if (!(len = utf8len(utf8))) return 0;\r
-\r
-       if (len == 1)\r
-               *ucs2 = *utf8;\r
-       else if (len == 2)\r
-               *ucs2 = (*utf8 & 0x3F)<<6 | (*(utf8+1) & 0x3F);\r
-       else if (len == 3)\r
-               *ucs2 = (*utf8 & 0x1F)<<12 | (*(utf8+1) & 0x3F)<<6 | (*(utf8+2) & 0x3F);\r
-       else {\r
-               FLAC__ASSERT(len == 0);\r
-       }\r
-\r
-       return len;\r
-}\r
-\r
-wchar_t *FLAC_plugin__convert_utf8_to_ucs2(const char *src, unsigned length)\r
-{\r
-       wchar_t *out, *p;\r
-       const char *s;\r
-       int len = 0;\r
-       /* calculate length */\r
-       for (s=src; length && *s; len++)\r
-       {\r
-               int l = utf8len(s);\r
-               if (!l) break;\r
-               s += l;\r
-               length -= l;\r
-       }\r
-       /* allocate */\r
-       len++;\r
-       p = out = (wchar_t*)malloc(len * sizeof(wchar_t));\r
-       if (!out) return NULL;\r
-       /* convert */\r
-       for (s=src; --len; p++)\r
-       {\r
-               int l = utf8_to_ucs2(s, p);\r
-               /* l==0 is possible, because real conversion */\r
-               /* might do more careful validation */\r
-               if (!l) break;\r
-               s += l;\r
-       }\r
-       *p = 0;\r
-\r
-       return out;\r
-}\r
-\r
-static __inline int ucs2len(wchar_t ucs2)\r
-{\r
-       if (ucs2 < 0x0080)\r
-               return 1;\r
-       else if (ucs2 < 0x0800)\r
-               return 2;\r
-       else return 3;\r
-}\r
-\r
-static __inline int ucs2_to_utf8(wchar_t ucs2, FLAC__byte *utf8)\r
-{\r
-       if (ucs2 < 0x080)\r
-       {\r
-               utf8[0] = (FLAC__byte)ucs2;\r
-               return 1;\r
-       }\r
-       else if (ucs2 < 0x800)\r
-       {\r
-               utf8[0] = 0xc0 | (ucs2 >> 6);\r
-               utf8[1] = 0x80 | (ucs2 & 0x3f);\r
-               return 2;\r
-       }\r
-       else\r
-       {\r
-               utf8[0] = 0xe0 | (ucs2 >> 12);\r
-               utf8[1] = 0x80 | ((ucs2 >> 6) & 0x3f);\r
-               utf8[2] = 0x80 | (ucs2 & 0x3f);\r
-               return 3;\r
-       }\r
-}\r
-\r
-char *FLAC_plugin__convert_ucs2_to_utf8(const wchar_t *src)\r
-{\r
-       const wchar_t *s;\r
-       char *out, *p;\r
-       int len = 0;\r
-       FLAC__ASSERT(0 != src);\r
-       /* calculate length */\r
-       for (s=src; *s; s++)\r
-               len += ucs2len(*s);\r
-       /* allocate */\r
-       len++;\r
-       p = out = malloc(len);\r
-       if (!out) return NULL;\r
-       /* convert */\r
-       for (s=src; *s; s++)\r
-       {\r
-               int l = ucs2_to_utf8(*s, p);\r
-               p += l;\r
-       }\r
-       *p = 0;\r
-\r
-       return out;\r
-}\r
-\r
-/*\r
- *  init/clear/delete\r
- */\r
-\r
-FLAC_Plugin__CanonicalTag *FLAC_plugin__canonical_tag_new()\r
-{\r
-       FLAC_Plugin__CanonicalTag *object = (FLAC_Plugin__CanonicalTag*)malloc(sizeof(FLAC_Plugin__CanonicalTag));\r
-       if (object != 0)\r
-               FLAC_plugin__canonical_tag_init(object);\r
-       return object;\r
-}\r
-\r
-void FLAC_plugin__canonical_tag_delete(FLAC_Plugin__CanonicalTag *object)\r
-{\r
-       FLAC_plugin__canonical_tag_clear(object);\r
-       free(object);\r
-}\r
-\r
-void FLAC_plugin__canonical_tag_init(FLAC_Plugin__CanonicalTag *object)\r
-{\r
-       object->head = object->tail = 0;\r
-       object->count = 0;\r
-}\r
-\r
-static void FLAC_plugin__canonical_tag_clear_entry(FLAC__tag_entry *entry)\r
-{\r
-       free(entry->name);\r
-       free(entry->value);\r
-       free(entry);\r
-}\r
-\r
-void FLAC_plugin__canonical_tag_clear(FLAC_Plugin__CanonicalTag *object)\r
-{\r
-       FLAC__tag_entry *entry = object->head;\r
-\r
-       while (entry)\r
-       {\r
-               FLAC__tag_entry *next = entry->next;\r
-               FLAC_plugin__canonical_tag_clear_entry(entry);\r
-               entry = next;\r
-       }\r
-\r
-       FLAC_plugin__canonical_tag_init(object);\r
-}\r
-\r
-/*\r
- *  internal\r
- */\r
-\r
-static FLAC__tag_entry *FLAC_plugin__canonical_find(const FLAC_Plugin__CanonicalTag *tag, const wchar_t *name)\r
-{\r
-       FLAC__tag_entry *entry = tag->head;\r
-\r
-       while (entry)\r
-       {\r
-#if defined _MSC_VER || defined __MINGW32__\r
-#define FLAC__WCSCASECMP wcsicmp\r
-#else\r
-#define FLAC__WCSCASECMP wcscasecmp\r
-#endif\r
-               if (!FLAC__WCSCASECMP(name, entry->name))\r
-#undef FLAC__WCSCASECMP\r
-                       break;\r
-               entry = entry->next;\r
-       }\r
-\r
-       return entry;\r
-}\r
-\r
-/* NOTE: does NOT copy strings. takes ownership over passed strings. */\r
-static void FLAC_plugin__canonical_add_tail(FLAC_Plugin__CanonicalTag *tag, wchar_t *name, wchar_t *value)\r
-{\r
-       FLAC__tag_entry *entry = (FLAC__tag_entry*)malloc(sizeof(FLAC__tag_entry));\r
-       if (!entry)\r
-       {\r
-               free(name);\r
-               free(value);\r
-               return;\r
-       }\r
-       /* init */\r
-       entry->name = name;\r
-       entry->value = value;\r
-       /* add */\r
-       entry->prev = tag->tail;\r
-       if (tag->tail)\r
-               tag->tail->next = entry;\r
-       tag->tail = entry;\r
-       if (!tag->head)\r
-               tag->head = entry;\r
-       entry->next = 0;\r
-       tag->count++;\r
-}\r
-\r
-static void FLAC_plugin__canonical_add_new(FLAC_Plugin__CanonicalTag *tag, const wchar_t *name, const wchar_t *value)\r
-{\r
-       FLAC_plugin__canonical_add_tail(tag, wcsdup(name), wcsdup(value));\r
-}\r
-\r
-/* NOTE: does NOT copy value, but copies name */\r
-static void FLAC_plugin__canonical_set_nc(FLAC_Plugin__CanonicalTag *tag, const wchar_t *name, wchar_t *value)\r
-{\r
-       FLAC__tag_entry *entry = FLAC_plugin__canonical_find(tag, name);\r
-\r
-       if (entry)\r
-       {\r
-               free(entry->value);\r
-               entry->value = value;\r
-       }\r
-       else FLAC_plugin__canonical_add_tail(tag, wcsdup(name), value);\r
-}\r
-\r
-/* NOTE: does NOT copy strings. takes ownership over passed strings. (except sep!) */\r
-static void FLAC_plugin__canonical_add_nc(FLAC_Plugin__CanonicalTag *tag, wchar_t *name, wchar_t *value, const wchar_t *sep)\r
-{\r
-       FLAC__tag_entry *entry;\r
-\r
-       if (sep && (entry = FLAC_plugin__canonical_find(tag, name)))\r
-       {\r
-               unsigned newlen = wcslen(entry->value) + wcslen(value) + wcslen(sep) + 1;\r
-               wchar_t *newvalue = realloc(entry->value, newlen*sizeof(wchar_t));\r
-\r
-               if (newvalue)\r
-               {\r
-                       entry->value = newvalue;\r
-                       wcscat(entry->value, sep);\r
-                       wcscat(entry->value, value);\r
-               }\r
-\r
-               free(name);\r
-               free(value);\r
-       }\r
-       else FLAC_plugin__canonical_add_tail(tag, name, value);\r
-}\r
-\r
-/*\r
- *  manipulation\r
- */\r
-\r
-void FLAC_plugin__canonical_set(FLAC_Plugin__CanonicalTag *tag, const wchar_t *name, const wchar_t *value)\r
-{\r
-       FLAC_plugin__canonical_set_nc(tag, name, wcsdup(value));\r
-}\r
-\r
-void FLAC_plugin__canonical_set_new(FLAC_Plugin__CanonicalTag *tag, const wchar_t *name, const wchar_t *value)\r
-{\r
-       FLAC__tag_entry *entry = FLAC_plugin__canonical_find(tag, name);\r
-       if (!entry) FLAC_plugin__canonical_add_new(tag, name, value);\r
-}\r
-\r
-void FLAC_plugin__canonical_set_ansi(FLAC_Plugin__CanonicalTag *tag, const wchar_t *name, const char *value)\r
-{\r
-       wchar_t *val = FLAC_plugin__convert_ansi_to_wide(value);\r
-       if (val) FLAC_plugin__canonical_set_nc(tag, name, val);\r
-}\r
-\r
-void FLAC_plugin__canonical_add(FLAC_Plugin__CanonicalTag *tag, const wchar_t *name, const wchar_t *value, const wchar_t *sep)\r
-{\r
-       FLAC__tag_entry *entry;\r
-\r
-       if (sep && (entry = FLAC_plugin__canonical_find(tag, name)))\r
-       {\r
-               unsigned newlen = wcslen(entry->value) + wcslen(value) + wcslen(sep) + 1;\r
-               wchar_t *newvalue = realloc(entry->value, newlen*sizeof(wchar_t));\r
-\r
-               if (newvalue)\r
-               {\r
-                       entry->value = newvalue;\r
-                       wcscat(entry->value, sep);\r
-                       wcscat(entry->value, value);\r
-               }\r
-       }\r
-       else FLAC_plugin__canonical_add_new(tag, name, value);\r
-}\r
-\r
-void FLAC_plugin__canonical_add_utf8(FLAC_Plugin__CanonicalTag *tag, const char *name, const char *value, unsigned namelen, unsigned vallen, const char *sep)\r
-{\r
-       wchar_t *n = FLAC_plugin__convert_utf8_to_ucs2(name, namelen);\r
-       wchar_t *v = FLAC_plugin__convert_utf8_to_ucs2(value, vallen);\r
-       wchar_t *s = sep ? FLAC_plugin__convert_utf8_to_ucs2(sep, -1) : 0;\r
-\r
-       if (n && v)\r
-       {\r
-               FLAC_plugin__canonical_add_nc(tag, n, v, s);\r
-       }\r
-       else\r
-       {\r
-               if (n) free(n);\r
-               if (v) free(v);\r
-       }\r
-       if (s) free(s);\r
-}\r
-\r
-const wchar_t *FLAC_plugin__canonical_get(const FLAC_Plugin__CanonicalTag *tag, const wchar_t *name)\r
-{\r
-       FLAC__tag_entry *entry = FLAC_plugin__canonical_find(tag, name);\r
-       return entry ? entry->value : 0;\r
-}\r
-\r
-FLAC__bool FLAC_plugin__canonical_remove(FLAC_Plugin__CanonicalTag *tag, const wchar_t *name)\r
-{\r
-       FLAC__tag_entry *entry = FLAC_plugin__canonical_find(tag, name);\r
-\r
-       if (entry)\r
-       {\r
-               if (entry->prev)\r
-                       entry->prev->next = entry->next;\r
-               else tag->head = entry->next;\r
-\r
-               if (entry->next)\r
-                       entry->next->prev = entry->prev;\r
-               else tag->tail = entry->prev;\r
-\r
-               FLAC_plugin__canonical_tag_clear_entry(entry);\r
-               tag->count--;\r
-               return true;\r
-       }\r
-\r
-       return false;\r
-}\r
-\r
-void FLAC_plugin__canonical_remove_all(FLAC_Plugin__CanonicalTag *tag, const wchar_t *name)\r
-{\r
-       while (FLAC_plugin__canonical_remove(tag, name));\r
-}\r
-\r
-char *FLAC_plugin__canonical_get_formatted(FLAC__tag_iterator it)\r
-{\r
-       int len1 = wcslen(it->name);\r
-       int len2 = wcslen(it->value);\r
-       int len  = len1 + len2 + 1;\r
-       wchar_t *val = malloc((len+1) * sizeof(wchar_t));\r
-\r
-       if (val)\r
-       {\r
-               char *res;\r
-\r
-               memcpy(val, it->name, len1 * sizeof(wchar_t));\r
-               val[len1] = '=';\r
-               memcpy(val+len1+1, it->value, len2 * sizeof(wchar_t));\r
-               val[len] = 0;\r
-\r
-               res = FLAC_plugin__convert_ucs2_to_utf8(val);\r
-               free(val);\r
-               return res;\r
-       }\r
-\r
-       return NULL;\r
-}\r
-\r
-/*\r
- * enumeration\r
- */\r
-unsigned FLAC_plugin__canonical_get_count(FLAC_Plugin__CanonicalTag *tag)\r
-{\r
-       return tag->count;\r
-}\r
-FLAC__tag_iterator FLAC_plugin__canonical_first(FLAC_Plugin__CanonicalTag *tag)\r
-{\r
-       return tag->head;\r
-}\r
-FLAC__tag_iterator FLAC_plugin__canonical_next(FLAC__tag_iterator it)\r
-{\r
-       return it->next;\r
-}\r
-wchar_t *FLAC_plugin__canonical_get_name(FLAC__tag_iterator it)\r
-{\r
-       return it->name;\r
-}\r
-wchar_t *FLAC_plugin__canonical_get_value(FLAC__tag_iterator it)\r
-{\r
-       return it->value;\r
-}\r
-\r
-/*\r
- *  merging\r
- */\r
-\r
-void FLAC_plugin__canonical_tag_merge(FLAC_Plugin__CanonicalTag *dest, const FLAC_Plugin__CanonicalTag *src)\r
-{\r
-       FLAC__tag_entry *entry = src->head;\r
-\r
-       while (entry)\r
-       {\r
-               FLAC_plugin__canonical_set_new(dest, entry->name, entry->value);\r
-               entry = entry->next;\r
-       }\r
-}\r
-\r
-void FLAC_plugin__canonical_tag_get_combined(const char *filename, FLAC_Plugin__CanonicalTag *tag, const char *sep)\r
-{\r
-       FLAC_plugin__vorbiscomment_get(filename, tag, sep);\r
-}\r
diff --git a/src/plugin_common/canonical_tag.h b/src/plugin_common/canonical_tag.h
deleted file mode 100644 (file)
index f792537..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-/* plugin_common - Routines common to several plugins\r
- * Copyright (C) 2002,2003,2004  Josh Coalson\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.\r
- */\r
-\r
-#ifndef FLAC__PLUGIN_COMMON__CANONICAL_TAG_H\r
-#define FLAC__PLUGIN_COMMON__CANONICAL_TAG_H\r
-\r
-#include "FLAC/ordinals.h"\r
-\r
-/* TODO: splay tree? */\r
-typedef struct tagFLAC__tag_entry FLAC__tag_entry;\r
-struct tagFLAC__tag_entry\r
-{\r
-       FLAC__tag_entry *next, *prev;\r
-       /* TODO: name in ascii? */\r
-       wchar_t *name;\r
-       wchar_t *value;\r
-};\r
-\r
-typedef struct {\r
-       FLAC__tag_entry *head, *tail;\r
-       unsigned count;\r
-} FLAC_Plugin__CanonicalTag;\r
-\r
-\r
-typedef FLAC__tag_entry *FLAC__tag_iterator;\r
-\r
-FLAC_Plugin__CanonicalTag *FLAC_plugin__canonical_tag_new();\r
-void FLAC_plugin__canonical_tag_init(FLAC_Plugin__CanonicalTag *);\r
-void FLAC_plugin__canonical_tag_clear(FLAC_Plugin__CanonicalTag *);\r
-void FLAC_plugin__canonical_tag_delete(FLAC_Plugin__CanonicalTag *);\r
-\r
-/* note that multiple fields with the same name are allowed.\r
- * set - adds field if it's not present yet, or replaces\r
- * existing field if it's present.\r
- */\r
-void FLAC_plugin__canonical_set(FLAC_Plugin__CanonicalTag *tag, const wchar_t *name, const wchar_t *value);\r
-void FLAC_plugin__canonical_set_ansi(FLAC_Plugin__CanonicalTag *tag, const wchar_t *name, const char *value);\r
-/* set_new - only adds field if it's not present yet. */\r
-void FLAC_plugin__canonical_set_new(FLAC_Plugin__CanonicalTag *tag, const wchar_t *name, const wchar_t *value);\r
-/* add - adds field if it's not present yet, or merges value with existing\r
- * field, if it's present. (sep - separator string to use when merging;\r
- * if sep==NULL no merging occurs - always adds new field)\r
- */\r
-void FLAC_plugin__canonical_add(FLAC_Plugin__CanonicalTag *tag, const wchar_t *name, const wchar_t *value, const wchar_t *sep);\r
-void FLAC_plugin__canonical_add_utf8(FLAC_Plugin__CanonicalTag *tag, const char *name, const char *value, unsigned namelen, unsigned vallen, const char *sep); /* 'namelen'/'vallen' may be (unsigned)(-1) if 'name'/'value' is NUL-terminated */\r
-\r
-/* gets value of the first field with the given name (NULL if field not found) */\r
-const wchar_t *FLAC_plugin__canonical_get(const FLAC_Plugin__CanonicalTag *tag, const wchar_t *name);\r
-/* removes first field with the given name.\r
- * (returns 'true' if deleted, 'false' if not found)\r
- */\r
-FLAC__bool FLAC_plugin__canonical_remove(FLAC_Plugin__CanonicalTag *tag, const wchar_t *name);\r
-/* removes all fields with the given name. */\r
-void FLAC_plugin__canonical_remove_all(FLAC_Plugin__CanonicalTag *tag, const wchar_t *name);\r
-\r
-/* enumeration */\r
-unsigned FLAC_plugin__canonical_get_count(FLAC_Plugin__CanonicalTag *tag);\r
-FLAC__tag_iterator FLAC_plugin__canonical_first(FLAC_Plugin__CanonicalTag *tag);\r
-FLAC__tag_iterator FLAC_plugin__canonical_next(FLAC__tag_iterator it);\r
-wchar_t *FLAC_plugin__canonical_get_name(FLAC__tag_iterator it);\r
-wchar_t *FLAC_plugin__canonical_get_value(FLAC__tag_iterator it);\r
-\r
-/* returns a new string containing the current entry in UTF-8 in "NAME=VALUE" form */\r
-char *FLAC_plugin__canonical_get_formatted(FLAC__tag_iterator it);\r
-\r
-void FLAC_plugin__canonical_tag_merge(FLAC_Plugin__CanonicalTag *dest, const FLAC_Plugin__CanonicalTag *src);\r
-\r
-/* helpers */\r
-wchar_t *FLAC_plugin__convert_ansi_to_wide(const char *src);\r
-wchar_t *FLAC_plugin__convert_utf8_to_ucs2(const char *src, unsigned length); /* 'length' may be (unsigned)(-1) if 'src' is NUL-terminated */\r
-char    *FLAC_plugin__convert_ucs2_to_utf8(const wchar_t *src);\r
-\r
-#endif\r
diff --git a/src/plugin_common/tags.c b/src/plugin_common/tags.c
new file mode 100644 (file)
index 0000000..1de2a8a
--- /dev/null
@@ -0,0 +1,307 @@
+/* plugin_common - Routines common to several plugins
+ * Copyright (C) 2002,2003,2004  Josh Coalson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "tags.h"
+#include "FLAC/assert.h"
+#include "FLAC/metadata.h"
+
+
+static __inline unsigned local__wide_strlen(const FLAC__uint16 *s)
+{
+       unsigned n = 0;
+       while(*s++)
+               n++;
+       return n;
+}
+
+static __inline unsigned local__utf8len(const FLAC__byte *utf8)
+{
+       FLAC__ASSERT(0 != utf8);
+       if ((utf8[0] & 0x80) == 0)
+               return 1;
+       else if ((utf8[0] & 0xE0) == 0xC0 && (utf8[1] & 0xC0) == 0x80)
+               return 2;
+       else if ((utf8[0] & 0xF0) == 0xE0 && (utf8[1] & 0xC0) == 0x80 && (utf8[2] & 0xC0) == 0x80)
+               return 3;
+       else
+               return 0;
+}
+
+static __inline unsigned local__utf8_to_ucs2(const FLAC__byte *utf8, FLAC__uint16 *ucs2)
+{
+       const unsigned len = local__utf8len(utf8);
+
+       FLAC__ASSERT(0 != ucs2);
+
+       if (len == 1)
+               *ucs2 = *utf8;
+       else if (len == 2)
+               *ucs2 = (*utf8 & 0x3F)<<6 | (*(utf8+1) & 0x3F);
+       else if (len == 3)
+               *ucs2 = (*utf8 & 0x1F)<<12 | (*(utf8+1) & 0x3F)<<6 | (*(utf8+2) & 0x3F);
+
+       return len;
+}
+
+static FLAC__uint16 *local__convert_utf8_to_ucs2(const char *src, unsigned length)
+{
+       FLAC__uint16 *out;
+       unsigned chars = 0;
+
+       FLAC__ASSERT(0 != src);
+
+       /* calculate length */
+       {
+               const char *s, *end;
+               for (s=src, end=src+length; s<end; chars++) {
+                       const unsigned n = local__utf8len(s);
+                       if (n == 0)
+                               return 0;
+                       s += n;
+               }
+               FLAC__ASSERT(s == end);
+       }
+
+       /* allocate */
+       out = (FLAC__uint16*)malloc(chars * sizeof(FLAC__uint16));
+       if (0 == out) {
+               FLAC__ASSERT(0);
+               return 0;
+       }
+
+       /* convert */
+       {
+               FLAC__uint16 *u = out;
+               for ( ; chars; chars--)
+                       src += local__utf8_to_ucs2(src, u++);
+       }
+
+       return out;
+}
+
+static __inline unsigned local__ucs2len(FLAC__uint16 ucs2)
+{
+       if (ucs2 < 0x0080)
+               return 1;
+       else if (ucs2 < 0x0800)
+               return 2;
+       else
+               return 3;
+}
+
+static __inline unsigned local__ucs2_to_utf8(FLAC__uint16 ucs2, FLAC__byte *utf8)
+{
+       if (ucs2 < 0x080) {
+               utf8[0] = (FLAC__byte)ucs2;
+               return 1;
+       }
+       else if (ucs2 < 0x800) {
+               utf8[0] = 0xc0 | (ucs2 >> 6);
+               utf8[1] = 0x80 | (ucs2 & 0x3f);
+               return 2;
+       }
+       else {
+               utf8[0] = 0xe0 | (ucs2 >> 12);
+               utf8[1] = 0x80 | ((ucs2 >> 6) & 0x3f);
+               utf8[2] = 0x80 | (ucs2 & 0x3f);
+               return 3;
+       }
+}
+
+static char *local__convert_ucs2_to_utf8(const FLAC__uint16 *src, unsigned length)
+{
+       char *out;
+       unsigned len = 0;
+
+       FLAC__ASSERT(0 != src);
+
+       /* calculate length */
+       {
+               unsigned i;
+               for (i = 0; i < length; i++)
+                       len += local__ucs2len(src[i]);
+       }
+
+       /* allocate */
+       out = (char*)malloc(len * sizeof(char));
+       if (0 == out)
+               return 0;
+
+       /* convert */
+       {
+               char *u = out;
+               for ( ; *src; src++)
+                       u += local__ucs2_to_utf8(*src, u);
+               local__ucs2_to_utf8(*src, u);
+       }
+
+       return out;
+}
+
+
+FLAC__bool FLAC_plugin__tags_get(const char *filename, FLAC__StreamMetadata **tags)
+{
+       if(!FLAC__metadata_get_tags(filename, tags))
+               if(0 == (*tags = FLAC__metadata_object_new(FLAC__METADATA_TYPE_VORBIS_COMMENT)))
+                       return false;
+       return true;
+}
+
+FLAC__bool FLAC_plugin__tags_set(const char *filename, const FLAC__StreamMetadata *tags)
+{
+       FLAC__Metadata_Chain *chain;
+       FLAC__Metadata_Iterator *iterator;
+       FLAC__StreamMetadata *block;
+       FLAC__bool got_vorbis_comments = false;
+       FLAC__bool ok;
+
+       if(0 == (chain = FLAC__metadata_chain_new()))
+               return false;
+
+       if(!FLAC__metadata_chain_read(chain, filename)) {
+               FLAC__metadata_chain_delete(chain);
+               return false;
+       }
+
+       if(0 == (iterator = FLAC__metadata_iterator_new())) {
+               FLAC__metadata_chain_delete(chain);
+               return false;
+       }
+
+       FLAC__metadata_iterator_init(iterator, chain);
+
+       do {
+               if(FLAC__metadata_iterator_get_block_type(iterator) == FLAC__METADATA_TYPE_VORBIS_COMMENT)
+                       got_vorbis_comments = true;
+       } while(!got_vorbis_comments && FLAC__metadata_iterator_next(iterator));
+
+       if(0 == (block = FLAC__metadata_object_clone(tags))) {
+               FLAC__metadata_chain_delete(chain);
+               FLAC__metadata_iterator_delete(iterator);
+               return false;
+       }
+
+       if(got_vorbis_comments)
+               ok = FLAC__metadata_iterator_set_block(iterator, block);
+       else
+               ok = FLAC__metadata_iterator_insert_block_after(iterator, block);
+
+       FLAC__metadata_iterator_delete(iterator);
+
+       if(ok) {
+               FLAC__metadata_chain_sort_padding(chain);
+               ok = FLAC__metadata_chain_write(chain, /*use_padding=*/true, /*preserve_file_stats=*/true);
+       }
+
+       FLAC__metadata_chain_delete(chain);
+
+       return ok;
+}
+
+void FLAC_plugin__tags_destroy(FLAC__StreamMetadata **tags)
+{
+       FLAC__metadata_object_delete(*tags);
+       *tags = 0;
+}
+
+const char *FLAC_plugin__tags_get_tag_utf8(const FLAC__StreamMetadata *tags, const char *name)
+{
+       const int i = FLAC__metadata_object_vorbiscomment_find_entry_from(tags, /*offset=*/0, name);
+       return (i < 0? 0 : tags->data.vorbis_comment.comments[i].entry);
+}
+
+FLAC__uint16 *FLAC_plugin__tags_get_tag_ucs2(const FLAC__StreamMetadata *tags, const char *name)
+{
+       const char *utf8 = FLAC_plugin__tags_get_tag_utf8(tags, name);
+       if(0 == utf8)
+               return 0;
+       return local__convert_utf8_to_ucs2(utf8, strlen(utf8)+1); /* +1 for terminating null */
+}
+
+int FLAC_plugin__tags_delete_tag(FLAC__StreamMetadata *tags, const char *name)
+{
+       return FLAC__metadata_object_vorbiscomment_remove_entries_matching(tags, name);
+}
+
+int FLAC_plugin__tags_delete_all(FLAC__StreamMetadata *tags)
+{
+       int n = (int)tags->data.vorbis_comment.num_comments;
+       if(n > 0) {
+               if(!FLAC__metadata_object_vorbiscomment_resize_comments(tags, 0))
+                       n = -1;
+       }
+       return n;
+}
+
+FLAC__bool FLAC_plugin__tags_add_tag_utf8(FLAC__StreamMetadata *tags, const char *name, const char *value, const char *separator)
+{
+       int i;
+
+       FLAC__ASSERT(0 != tags);
+       FLAC__ASSERT(0 != name);
+       FLAC__ASSERT(0 != value);
+
+       if(separator && (i = FLAC__metadata_object_vorbiscomment_find_entry_from(tags, /*offset=*/0, name)) >= 0) {
+               FLAC__StreamMetadata_VorbisComment_Entry *entry = tags->data.vorbis_comment.comments+i;
+               const size_t value_len = strlen(value);
+               const size_t separator_len = strlen(separator);
+               FLAC__byte *new_entry;
+               if(0 == (new_entry = realloc(entry->entry, entry->length + value_len + separator_len + 1)))
+                       return false;
+               memcpy(new_entry+entry->length, separator, separator_len);
+               entry->length += separator_len;
+               memcpy(new_entry+entry->length, value, value_len);
+               entry->length += value_len;
+               new_entry[entry->length] = '\0';
+               entry->entry = new_entry;
+       }
+       else {
+               FLAC__StreamMetadata_VorbisComment_Entry entry;
+               if(!FLAC__metadata_object_vorbiscomment_entry_from_name_value_pair(&entry, name, value))
+                       return false;
+               FLAC__metadata_object_vorbiscomment_append_comment(tags, entry, /*copy=*/false);
+       }
+       return true;
+}
+
+FLAC__bool FLAC_plugin__tags_set_tag_ucs2(FLAC__StreamMetadata *tags, const char *name, const FLAC__uint16 *value, FLAC__bool replace_all)
+{
+       FLAC__StreamMetadata_VorbisComment_Entry entry;
+
+       FLAC__ASSERT(0 != tags);
+       FLAC__ASSERT(0 != name);
+       FLAC__ASSERT(0 != value);
+
+       {
+               char *utf8 = local__convert_ucs2_to_utf8(value, local__wide_strlen(value)+1); /* +1 for the terminating null */
+               if(0 == utf8)
+                       return false;
+               if(!FLAC__metadata_object_vorbiscomment_entry_from_name_value_pair(&entry, name, utf8)) {
+                       free(utf8);
+                       return false;
+               }
+               free(utf8);
+       }
+       if(!FLAC__metadata_object_vorbiscomment_replace_comment(tags, entry, replace_all, /*copy=*/false))
+               return false;
+       return true;
+}
diff --git a/src/plugin_common/tags.h b/src/plugin_common/tags.h
new file mode 100644 (file)
index 0000000..379d244
--- /dev/null
@@ -0,0 +1,74 @@
+/* plugin_common - Routines common to several plugins
+ * Copyright (C) 2002,2003,2004  Josh Coalson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#ifndef FLAC__PLUGIN_COMMON__TAGS_H
+#define FLAC__PLUGIN_COMMON__TAGS_H
+
+#include "FLAC/format.h"
+
+FLAC__bool FLAC_plugin__tags_get(const char *filename, FLAC__StreamMetadata **tags);
+FLAC__bool FLAC_plugin__tags_set(const char *filename, const FLAC__StreamMetadata *tags);
+
+/*
+ * Deletes the tags object and sets '*tags' to NULL.
+ */
+void FLAC_plugin__tags_destroy(FLAC__StreamMetadata **tags);
+
+/*
+ * Gets the value (in UTF-8) of the first tag with the given name (NULL if no
+ * such tag exists).
+ */
+const char *FLAC_plugin__tags_get_tag_utf8(const FLAC__StreamMetadata *tags, const char *name);
+
+/*
+ * Gets the value (in UCS-2) of the first tag with the given name (NULL if no
+ * such tag exists).
+ *
+ * NOTE: the returned string is malloc()ed and must be free()d by the caller.
+ */
+FLAC__uint16 *FLAC_plugin__tags_get_tag_ucs2(const FLAC__StreamMetadata *tags, const char *name);
+
+/*
+ * Removes all tags with the given 'name'.  Returns the number of tags removed,
+ * or -1 on memory allocation error.
+ */
+int FLAC_plugin__tags_delete_tag(FLAC__StreamMetadata *tags, const char *name);
+
+/*
+ * Removes all tags.  Returns the number of tags removed, or -1 on memory
+ * allocation error.
+ */
+int FLAC_plugin__tags_delete_all(FLAC__StreamMetadata *tags);
+
+/*
+ * Adds a "name=value" tag to the tags.  'value' must be in UTF-8.  If
+ * 'separator' is non-NULL and 'tags' already contains a tag for 'name', the
+ * first such tag's value is appended with separator, then value.
+ */
+FLAC__bool FLAC_plugin__tags_add_tag_utf8(FLAC__StreamMetadata *tags, const char *name, const char *value, const char *separator);
+
+/*
+ * Adds a "name=value" tag to the tags.  'value' must be in UCS-2.  If 'tags'
+ * already contains a tag or tags for 'name', then they will be replaced
+ * according to 'replace_all': if 'replace_all' is false, only the first such
+ * tag will be replaced; if true, all matching tags will be replaced by the one
+ * new tag. 
+ */
+FLAC__bool FLAC_plugin__tags_set_tag_ucs2(FLAC__StreamMetadata *tags, const char *name, const FLAC__uint16 *value, FLAC__bool replace_all);
+
+#endif
diff --git a/src/plugin_common/vorbiscomment.c b/src/plugin_common/vorbiscomment.c
deleted file mode 100644 (file)
index 934b4f8..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-/* plugin_common - Routines common to several plugins\r
- * Copyright (C) 2002,2003,2004  Josh Coalson\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.\r
- */\r
-\r
-#include <stdio.h>\r
-#include <string.h>\r
-#include <stdlib.h>\r
-\r
-#include "vorbiscomment.h"\r
-#include "FLAC/metadata.h"\r
-\r
-\r
-static void local__add_vcentry(FLAC_Plugin__CanonicalTag *tag, FLAC__StreamMetadata_VorbisComment_Entry *entry, const char *sep)\r
-{\r
-       FLAC__byte *value = memchr(entry->entry, '=', entry->length);\r
-       int len;\r
-       if (!value) return;\r
-       len = value - entry->entry;\r
-       value++;\r
-       FLAC_plugin__canonical_add_utf8(tag, entry->entry, value, len, entry->length-len-1, sep);\r
-}\r
-\r
-void FLAC_plugin__vorbiscomment_get(const char *filename, FLAC_Plugin__CanonicalTag *tag, const char *sep)\r
-{\r
-       FLAC__Metadata_SimpleIterator *iterator = FLAC__metadata_simple_iterator_new();\r
-       if(0 != iterator) {\r
-               if(FLAC__metadata_simple_iterator_init(iterator, filename, /*read_only=*/true, /*preserve_file_stats=*/true)) {\r
-                       FLAC__bool got_vorbis_comments = false;\r
-                       do {\r
-                               if(FLAC__metadata_simple_iterator_get_block_type(iterator) == FLAC__METADATA_TYPE_VORBIS_COMMENT) {\r
-                                       FLAC__StreamMetadata *block = FLAC__metadata_simple_iterator_get_block(iterator);\r
-                                       if(0 != block) {\r
-                                               unsigned i;\r
-                                               const FLAC__StreamMetadata_VorbisComment *vc = &block->data.vorbis_comment;\r
-\r
-                                               for(i = 0; i < vc->num_comments; i++)\r
-                                                       local__add_vcentry(tag, vc->comments+i, sep);\r
-\r
-                                               FLAC__metadata_object_delete(block);\r
-                                               got_vorbis_comments = true;\r
-                                       }\r
-                               }\r
-                       } while (!got_vorbis_comments && FLAC__metadata_simple_iterator_next(iterator));\r
-               }\r
-               FLAC__metadata_simple_iterator_delete(iterator);\r
-       }\r
-}\r
-\r
-FLAC__bool FLAC_plugin__vorbiscomment_set(const char *filename, FLAC_Plugin__CanonicalTag *tag)\r
-{\r
-       FLAC__bool got_vorbis_comments = false, result;\r
-       FLAC__Metadata_SimpleIterator *iterator = FLAC__metadata_simple_iterator_new();\r
-       FLAC__StreamMetadata *block;\r
-       FLAC__tag_iterator it;\r
-       unsigned position = 0;\r
-               \r
-       if (!iterator || !FLAC__metadata_simple_iterator_init(iterator, filename, /*read_only=*/false, /*preserve_file_stats=*/true))\r
-               return false;\r
-\r
-       do {\r
-               if(FLAC__metadata_simple_iterator_get_block_type(iterator) == FLAC__METADATA_TYPE_VORBIS_COMMENT)\r
-                       got_vorbis_comments = true;\r
-       } while (!got_vorbis_comments && FLAC__metadata_simple_iterator_next(iterator));\r
-\r
-       if(!got_vorbis_comments) {\r
-               /* create a new block */\r
-               block = FLAC__metadata_object_new(FLAC__METADATA_TYPE_VORBIS_COMMENT);\r
-\r
-               if(!block) {\r
-                       FLAC__metadata_simple_iterator_delete(iterator);\r
-                       return false;\r
-               }\r
-       }\r
-       else\r
-               block = FLAC__metadata_simple_iterator_get_block(iterator);\r
-\r
-       FLAC__metadata_object_vorbiscomment_resize_comments(block, FLAC_plugin__canonical_get_count(tag));\r
-\r
-       for (it=FLAC_plugin__canonical_first(tag); it; it=FLAC_plugin__canonical_next(it))\r
-       {\r
-               FLAC__StreamMetadata_VorbisComment_Entry entry;\r
-               /* replace entry */\r
-               entry.entry = FLAC_plugin__canonical_get_formatted(it);\r
-               entry.length = strlen(entry.entry);\r
-               FLAC__metadata_object_vorbiscomment_set_comment(block, position++, entry, /*copy=*/false);\r
-       }\r
-\r
-       if (!got_vorbis_comments)\r
-               result = FLAC__metadata_simple_iterator_insert_block_after(iterator, block, /*use_padding=*/true);\r
-       else\r
-               result = FLAC__metadata_simple_iterator_set_block(iterator, block, /*use_padding=*/true);\r
-\r
-       FLAC__metadata_object_delete(block);\r
-       FLAC__metadata_simple_iterator_delete(iterator);\r
-       return result;\r
-}\r
diff --git a/src/plugin_common/vorbiscomment.h b/src/plugin_common/vorbiscomment.h
deleted file mode 100644 (file)
index f02b5ca..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/* plugin_common - Routines common to several plugins
- * Copyright (C) 2002,2003,2004  Josh Coalson
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- */
-
-#ifndef FLAC__PLUGIN_COMMON__VORBISCOMMENT_H
-#define FLAC__PLUGIN_COMMON__VORBISCOMMENT_H
-
-#include "canonical_tag.h"
-#include "FLAC/ordinals.h"
-
-void FLAC_plugin__vorbiscomment_get(const char *filename, FLAC_Plugin__CanonicalTag *tag, const char *sep);
-FLAC__bool FLAC_plugin__vorbiscomment_set(const char *filename, FLAC_Plugin__CanonicalTag *tag);
-
-#endif