diff options
author | Max Kellermann <max@duempel.org> | 2014-01-24 00:09:37 +0100 |
---|---|---|
committer | Max Kellermann <max@duempel.org> | 2014-01-24 00:09:37 +0100 |
commit | 4aa6d39fd8dfbb822db2f156ba371c1a5000f35c (patch) | |
tree | 4075b83e9da4a196e0f84d8fdcbaed8177f2dce1 /src/archive | |
parent | 51adaf2c47761e3f2095a52a7037cd8458b77990 (diff) |
archive/*: move to archive/plugins/
Diffstat (limited to 'src/archive')
16 files changed, 529 insertions, 9 deletions
diff --git a/src/archive/ArchiveDomain.cxx b/src/archive/ArchiveDomain.cxx new file mode 100644 index 000000000..4adf4a886 --- /dev/null +++ b/src/archive/ArchiveDomain.cxx @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2003-2014 The Music Player Daemon Project + * http://www.musicpd.org + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "ArchiveDomain.hxx" +#include "util/Domain.hxx" + +const Domain archive_domain("archive"); diff --git a/src/archive/ArchiveDomain.hxx b/src/archive/ArchiveDomain.hxx new file mode 100644 index 000000000..817ae5835 --- /dev/null +++ b/src/archive/ArchiveDomain.hxx @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2003-2014 The Music Player Daemon Project + * http://www.musicpd.org + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef MPD_ARCHIVE_DOMAIN_HXX +#define MPD_ARCHIVE_DOMAIN_HXX + +extern const class Domain archive_domain; + +#endif diff --git a/src/archive/ArchiveFile.hxx b/src/archive/ArchiveFile.hxx new file mode 100644 index 000000000..b95edcc8d --- /dev/null +++ b/src/archive/ArchiveFile.hxx @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2003-2014 The Music Player Daemon Project + * http://www.musicpd.org + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef MPD_ARCHIVE_FILE_HXX +#define MPD_ARCHIVE_FILE_HXX + +class Mutex; +class Cond; +class Error; +class ArchiveVisitor; +struct InputStream; + +class ArchiveFile { +public: + const struct archive_plugin &plugin; + + ArchiveFile(const struct archive_plugin &_plugin) + :plugin(_plugin) {} + +protected: + /** + * Use Close() instead of delete. + */ + ~ArchiveFile() {} + +public: + virtual void Close() = 0; + + /** + * Visit all entries inside this archive. + */ + virtual void Visit(ArchiveVisitor &visitor) = 0; + + /** + * Opens an InputStream of a file within the archive. + * + * @param path the path within the archive + */ + virtual InputStream *OpenStream(const char *path, + Mutex &mutex, Cond &cond, + Error &error) = 0; +}; + +#endif diff --git a/src/archive/ArchiveList.cxx b/src/archive/ArchiveList.cxx new file mode 100644 index 000000000..bf6493588 --- /dev/null +++ b/src/archive/ArchiveList.cxx @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2003-2014 The Music Player Daemon Project + * http://www.musicpd.org + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "config.h" +#include "ArchiveList.hxx" +#include "ArchivePlugin.hxx" +#include "util/StringUtil.hxx" +#include "plugins/Bzip2ArchivePlugin.hxx" +#include "plugins/Iso9660ArchivePlugin.hxx" +#include "plugins/ZzipArchivePlugin.hxx" +#include "util/Macros.hxx" + +#include <string.h> + +const struct archive_plugin *const archive_plugins[] = { +#ifdef HAVE_BZ2 + &bz2_archive_plugin, +#endif +#ifdef HAVE_ZZIP + &zzip_archive_plugin, +#endif +#ifdef HAVE_ISO9660 + &iso9660_archive_plugin, +#endif + nullptr +}; + +/** which plugins have been initialized successfully? */ +static bool archive_plugins_enabled[ARRAY_SIZE(archive_plugins) - 1]; + +#define archive_plugins_for_each_enabled(plugin) \ + archive_plugins_for_each(plugin) \ + if (archive_plugins_enabled[archive_plugin_iterator - archive_plugins]) + +const struct archive_plugin * +archive_plugin_from_suffix(const char *suffix) +{ + if (suffix == nullptr) + return nullptr; + + archive_plugins_for_each_enabled(plugin) + if (plugin->suffixes != nullptr && + string_array_contains(plugin->suffixes, suffix)) + return plugin; + + return nullptr; +} + +const struct archive_plugin * +archive_plugin_from_name(const char *name) +{ + archive_plugins_for_each_enabled(plugin) + if (strcmp(plugin->name, name) == 0) + return plugin; + + return nullptr; +} + +void archive_plugin_init_all(void) +{ + for (unsigned i = 0; archive_plugins[i] != nullptr; ++i) { + const struct archive_plugin *plugin = archive_plugins[i]; + if (plugin->init == nullptr || archive_plugins[i]->init()) + archive_plugins_enabled[i] = true; + } +} + +void archive_plugin_deinit_all(void) +{ + archive_plugins_for_each_enabled(plugin) + if (plugin->finish != nullptr) + plugin->finish(); +} + diff --git a/src/archive/ArchiveList.hxx b/src/archive/ArchiveList.hxx new file mode 100644 index 000000000..49798a93e --- /dev/null +++ b/src/archive/ArchiveList.hxx @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2003-2014 The Music Player Daemon Project + * http://www.musicpd.org + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef MPD_ARCHIVE_LIST_HXX +#define MPD_ARCHIVE_LIST_HXX + +struct archive_plugin; + +extern const struct archive_plugin *const archive_plugins[]; + +#define archive_plugins_for_each(plugin) \ + for (const struct archive_plugin *plugin, \ + *const*archive_plugin_iterator = &archive_plugins[0]; \ + (plugin = *archive_plugin_iterator) != nullptr; \ + ++archive_plugin_iterator) + +/* interface for using plugins */ + +const struct archive_plugin * +archive_plugin_from_suffix(const char *suffix); + +const struct archive_plugin * +archive_plugin_from_name(const char *name); + +/* this is where we "load" all the "plugins" ;-) */ +void archive_plugin_init_all(void); + +/* this is where we "unload" all the "plugins" */ +void archive_plugin_deinit_all(void); + +#endif diff --git a/src/archive/ArchiveLookup.cxx b/src/archive/ArchiveLookup.cxx new file mode 100644 index 000000000..53730c504 --- /dev/null +++ b/src/archive/ArchiveLookup.cxx @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2003-2014 The Music Player Daemon Project + * http://www.musicpd.org + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "config.h" /* must be first for large file support */ +#include "ArchiveLookup.hxx" +#include "ArchiveDomain.hxx" +#include "Log.hxx" + +#include <string.h> +#include <sys/stat.h> +#include <errno.h> + +gcc_pure +static char * +FindSlash(char *p, size_t i) +{ + for (; i > 0; --i) + if (p[i] == '/') + return p + i; + + return nullptr; +} + +gcc_pure +static const char * +FindSuffix(const char *p, const char *i) +{ + for (; i > p; --i) { + if (*i == '.') + return i + 1; + } + + return nullptr; +} + +bool +archive_lookup(char *pathname, const char **archive, + const char **inpath, const char **suffix) +{ + size_t idx = strlen(pathname); + + char *slash = nullptr; + + while (true) { + //try to stat if its real directory + struct stat st_info; + if (stat(pathname, &st_info) == -1) { + if (errno != ENOTDIR) { + FormatErrno(archive_domain, + "Failed to stat %s", pathname); + return false; + } + } else { + //is something found ins original path (is not an archive) + if (slash == nullptr) + return false; + + //its a file ? + if (S_ISREG(st_info.st_mode)) { + //so the upper should be file + *archive = pathname; + *inpath = slash + 1; + + //try to get suffix + *suffix = FindSuffix(pathname, slash - 1); + return true; + } else { + FormatError(archive_domain, + "Not a regular file: %s", + pathname); + return false; + } + } + + //find one dir up + if (slash != nullptr) + *slash = '/'; + + slash = FindSlash(pathname, idx - 1); + if (slash == nullptr) + return false; + + *slash = 0; + idx = slash - pathname; + } +} + diff --git a/src/archive/ArchiveLookup.hxx b/src/archive/ArchiveLookup.hxx new file mode 100644 index 000000000..0c08951a9 --- /dev/null +++ b/src/archive/ArchiveLookup.hxx @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2003-2014 The Music Player Daemon Project + * http://www.musicpd.org + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef MPD_ARCHIVE_LOOKUP_HXX +#define MPD_ARCHIVE_LOOKUP_HXX + +/** + * + * archive_lookup is used to determine if part of pathname refers to an regular + * file (archive). If so then its also used to split pathname into archive file + * and path used to locate file in archive. It also returns suffix of the file. + * How it works: + * We do stat of the parent of input pathname as long as we find an regular file + * Normally this should never happen. When routine returns true pathname modified + * and split into archive, inpath and suffix. Otherwise nothing happens + * + * For example: + * + * /music/path/Talco.zip/Talco - Combat Circus/12 - A la pachenka.mp3 + * is split into archive: /music/path/Talco.zip + * inarchive pathname: Talco - Combat Circus/12 - A la pachenka.mp3 + * and suffix: zip + */ +bool +archive_lookup(char *pathname, const char **archive, + const char **inpath, const char **suffix); + +#endif + diff --git a/src/archive/ArchivePlugin.cxx b/src/archive/ArchivePlugin.cxx new file mode 100644 index 000000000..f8025a121 --- /dev/null +++ b/src/archive/ArchivePlugin.cxx @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2003-2014 The Music Player Daemon Project + * http://www.musicpd.org + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "config.h" +#include "ArchivePlugin.hxx" +#include "ArchiveFile.hxx" +#include "util/Error.hxx" + +#include <assert.h> + +ArchiveFile * +archive_file_open(const struct archive_plugin *plugin, const char *path, + Error &error) +{ + assert(plugin != nullptr); + assert(plugin->open != nullptr); + assert(path != nullptr); + + ArchiveFile *file = plugin->open(path, error); + assert((file == nullptr) == error.IsDefined()); + + return file; +} diff --git a/src/archive/ArchivePlugin.hxx b/src/archive/ArchivePlugin.hxx new file mode 100644 index 000000000..602de240a --- /dev/null +++ b/src/archive/ArchivePlugin.hxx @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2003-2014 The Music Player Daemon Project + * http://www.musicpd.org + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef MPD_ARCHIVE_PLUGIN_HXX +#define MPD_ARCHIVE_PLUGIN_HXX + +class ArchiveFile; +class Error; + +struct archive_plugin { + const char *name; + + /** + * optional, set this to nullptr if the archive plugin doesn't + * have/need one this must false if there is an error and + * true otherwise + */ + bool (*init)(void); + + /** + * optional, set this to nullptr if the archive plugin doesn't + * have/need one + */ + void (*finish)(void); + + /** + * tryes to open archive file and associates handle with archive + * returns pointer to handle used is all operations with this archive + * or nullptr when opening fails + */ + ArchiveFile *(*open)(const char *path_fs, Error &error); + + /** + * suffixes handled by this plugin. + * last element in these arrays must always be a nullptr + */ + const char *const*suffixes; +}; + +ArchiveFile * +archive_file_open(const struct archive_plugin *plugin, const char *path, + Error &error); + +#endif diff --git a/src/archive/ArchiveVisitor.hxx b/src/archive/ArchiveVisitor.hxx new file mode 100644 index 000000000..6759695ca --- /dev/null +++ b/src/archive/ArchiveVisitor.hxx @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2003-2014 The Music Player Daemon Project + * http://www.musicpd.org + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef MPD_ARCHIVE_VISITOR_HXX +#define MPD_ARCHIVE_VISITOR_HXX + +class ArchiveVisitor { +public: + virtual void VisitArchiveEntry(const char *path_utf8) = 0; +}; + +#endif diff --git a/src/archive/Bzip2ArchivePlugin.cxx b/src/archive/plugins/Bzip2ArchivePlugin.cxx index 643892917..0e75dd77f 100644 --- a/src/archive/Bzip2ArchivePlugin.cxx +++ b/src/archive/plugins/Bzip2ArchivePlugin.cxx @@ -23,9 +23,9 @@ #include "config.h" #include "Bzip2ArchivePlugin.hxx" -#include "ArchivePlugin.hxx" -#include "ArchiveFile.hxx" -#include "ArchiveVisitor.hxx" +#include "../ArchivePlugin.hxx" +#include "../ArchiveFile.hxx" +#include "../ArchiveVisitor.hxx" #include "InputStream.hxx" #include "InputPlugin.hxx" #include "util/RefCount.hxx" diff --git a/src/archive/Bzip2ArchivePlugin.hxx b/src/archive/plugins/Bzip2ArchivePlugin.hxx index 060780633..060780633 100644 --- a/src/archive/Bzip2ArchivePlugin.hxx +++ b/src/archive/plugins/Bzip2ArchivePlugin.hxx diff --git a/src/archive/Iso9660ArchivePlugin.cxx b/src/archive/plugins/Iso9660ArchivePlugin.cxx index 120070cc1..8f3300b3e 100644 --- a/src/archive/Iso9660ArchivePlugin.cxx +++ b/src/archive/plugins/Iso9660ArchivePlugin.cxx @@ -23,9 +23,9 @@ #include "config.h" #include "Iso9660ArchivePlugin.hxx" -#include "ArchivePlugin.hxx" -#include "ArchiveFile.hxx" -#include "ArchiveVisitor.hxx" +#include "../ArchivePlugin.hxx" +#include "../ArchiveFile.hxx" +#include "../ArchiveVisitor.hxx" #include "InputStream.hxx" #include "InputPlugin.hxx" #include "util/RefCount.hxx" diff --git a/src/archive/Iso9660ArchivePlugin.hxx b/src/archive/plugins/Iso9660ArchivePlugin.hxx index e92d5962b..e92d5962b 100644 --- a/src/archive/Iso9660ArchivePlugin.hxx +++ b/src/archive/plugins/Iso9660ArchivePlugin.hxx diff --git a/src/archive/ZzipArchivePlugin.cxx b/src/archive/plugins/ZzipArchivePlugin.cxx index 6b21d6ed4..c1446da74 100644 --- a/src/archive/ZzipArchivePlugin.cxx +++ b/src/archive/plugins/ZzipArchivePlugin.cxx @@ -23,9 +23,9 @@ #include "config.h" #include "ZzipArchivePlugin.hxx" -#include "ArchivePlugin.hxx" -#include "ArchiveFile.hxx" -#include "ArchiveVisitor.hxx" +#include "../ArchivePlugin.hxx" +#include "../ArchiveFile.hxx" +#include "../ArchiveVisitor.hxx" #include "InputStream.hxx" #include "InputPlugin.hxx" #include "util/RefCount.hxx" diff --git a/src/archive/ZzipArchivePlugin.hxx b/src/archive/plugins/ZzipArchivePlugin.hxx index f82f62eb6..f82f62eb6 100644 --- a/src/archive/ZzipArchivePlugin.hxx +++ b/src/archive/plugins/ZzipArchivePlugin.hxx |