diff options
Diffstat (limited to 'src/archive')
16 files changed, 619 insertions, 74 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..7d6c9e17c --- /dev/null +++ b/src/archive/ArchiveFile.hxx @@ -0,0 +1,61 @@ +/* + * 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; +struct ArchivePlugin; +class ArchiveVisitor; +struct InputStream; + +class ArchiveFile { +public: + const ArchivePlugin &plugin; + + ArchiveFile(const ArchivePlugin &_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..79c3a16fe --- /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 ArchivePlugin *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 ArchivePlugin * +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 ArchivePlugin * +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 ArchivePlugin *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..1f1b0ae96 --- /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 ArchivePlugin; + +extern const ArchivePlugin *const archive_plugins[]; + +#define archive_plugins_for_each(plugin) \ + for (const ArchivePlugin *plugin, \ + *const*archive_plugin_iterator = &archive_plugins[0]; \ + (plugin = *archive_plugin_iterator) != nullptr; \ + ++archive_plugin_iterator) + +/* interface for using plugins */ + +const ArchivePlugin * +archive_plugin_from_suffix(const char *suffix); + +const ArchivePlugin * +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..67f469e08 --- /dev/null +++ b/src/archive/ArchivePlugin.cxx @@ -0,0 +1,40 @@ +/* + * 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 "fs/Path.hxx" +#include "util/Error.hxx" + +#include <assert.h> + +ArchiveFile * +archive_file_open(const ArchivePlugin *plugin, Path path, + Error &error) +{ + assert(plugin != nullptr); + assert(plugin->open != nullptr); + assert(!path.IsNull()); + + 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..eb24bbdf9 --- /dev/null +++ b/src/archive/ArchivePlugin.hxx @@ -0,0 +1,61 @@ +/* + * 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 Path; +class Error; + +struct ArchivePlugin { + 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)(Path 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 ArchivePlugin *plugin, Path 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 d1e6b51af..8cb9af122 100644 --- a/src/archive/Bzip2ArchivePlugin.cxx +++ b/src/archive/plugins/Bzip2ArchivePlugin.cxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2013 The Music Player Daemon Project + * 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 @@ -23,21 +23,20 @@ #include "config.h" #include "Bzip2ArchivePlugin.hxx" -#include "ArchivePlugin.hxx" -#include "ArchiveFile.hxx" -#include "ArchiveVisitor.hxx" -#include "InputStream.hxx" -#include "InputPlugin.hxx" +#include "../ArchivePlugin.hxx" +#include "../ArchiveFile.hxx" +#include "../ArchiveVisitor.hxx" +#include "input/InputStream.hxx" +#include "input/InputPlugin.hxx" #include "util/RefCount.hxx" #include "util/Error.hxx" #include "util/Domain.hxx" #include "fs/Traits.hxx" +#include "fs/Path.hxx" #include <bzlib.h> -#include <stdint.h> #include <stddef.h> -#include <string.h> #ifdef HAVE_OLDER_BZIP2 #define BZ2_bzDecompressInit bzDecompressInit @@ -51,9 +50,9 @@ public: std::string name; InputStream *const istream; - Bzip2ArchiveFile(const char *path, InputStream *_is) + Bzip2ArchiveFile(Path path, InputStream *_is) :ArchiveFile(bz2_archive_plugin), - name(PathTraits::GetBaseUTF8(path)), + name(PathTraitsFS::GetBase(path.c_str())), istream(_is) { // remove .bz2 suffix const size_t len = name.length(); @@ -144,11 +143,12 @@ Bzip2InputStream::Close() /* archive open && listing routine */ static ArchiveFile * -bz2_open(const char *pathname, Error &error) +bz2_open(Path pathname, Error &error) { static Mutex mutex; static Cond cond; - InputStream *is = InputStream::Open(pathname, mutex, cond, error); + InputStream *is = InputStream::OpenReady(pathname.c_str(), mutex, cond, + error); if (is == nullptr) return nullptr; @@ -284,7 +284,7 @@ const InputPlugin bz2_inputplugin = { nullptr, }; -const struct archive_plugin bz2_archive_plugin = { +const ArchivePlugin bz2_archive_plugin = { "bz2", nullptr, nullptr, diff --git a/src/archive/Bzip2ArchivePlugin.hxx b/src/archive/plugins/Bzip2ArchivePlugin.hxx index a7933a7a7..1a0a578d1 100644 --- a/src/archive/Bzip2ArchivePlugin.hxx +++ b/src/archive/plugins/Bzip2ArchivePlugin.hxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2013 The Music Player Daemon Project + * 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 @@ -20,6 +20,8 @@ #ifndef MPD_ARCHIVE_BZ2_HXX #define MPD_ARCHIVE_BZ2_HXX -extern const struct archive_plugin bz2_archive_plugin; +struct ArchivePlugin; + +extern const ArchivePlugin bz2_archive_plugin; #endif diff --git a/src/archive/Iso9660ArchivePlugin.cxx b/src/archive/plugins/Iso9660ArchivePlugin.cxx index ad21d4a3d..f2f91e9f6 100644 --- a/src/archive/Iso9660ArchivePlugin.cxx +++ b/src/archive/plugins/Iso9660ArchivePlugin.cxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2013 The Music Player Daemon Project + * 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 @@ -23,16 +23,16 @@ #include "config.h" #include "Iso9660ArchivePlugin.hxx" -#include "ArchivePlugin.hxx" -#include "ArchiveFile.hxx" -#include "ArchiveVisitor.hxx" -#include "InputStream.hxx" -#include "InputPlugin.hxx" +#include "../ArchivePlugin.hxx" +#include "../ArchiveFile.hxx" +#include "../ArchiveVisitor.hxx" +#include "input/InputStream.hxx" +#include "input/InputPlugin.hxx" +#include "fs/Path.hxx" #include "util/RefCount.hxx" #include "util/Error.hxx" #include "util/Domain.hxx" -#include <cdio/cdio.h> #include <cdio/iso9660.h> #include <stdlib.h> @@ -41,11 +41,11 @@ #define CEILING(x, y) ((x+(y-1))/y) class Iso9660ArchiveFile final : public ArchiveFile { -public: RefCount ref; iso9660_t *iso; +public: Iso9660ArchiveFile(iso9660_t *_iso) :ArchiveFile(iso9660_archive_plugin), iso(_iso) {} @@ -53,11 +53,19 @@ public: iso9660_close(iso); } + void Ref() { + ref.Increment(); + } + void Unref() { if (ref.Decrement()) delete this; } + long SeekRead(void *ptr, lsn_t start, long int i_size) const { + return iso9660_iso_seek_read(iso, ptr, start, i_size); + } + void Visit(const char *path, ArchiveVisitor &visitor); virtual void Close() override { @@ -110,13 +118,14 @@ Iso9660ArchiveFile::Visit(const char *psz_path, ArchiveVisitor &visitor) } static ArchiveFile * -iso9660_archive_open(const char *pathname, Error &error) +iso9660_archive_open(Path pathname, Error &error) { /* open archive */ - auto iso = iso9660_open(pathname); + auto iso = iso9660_open(pathname.c_str()); if (iso == nullptr) { error.Format(iso9660_domain, - "Failed to open ISO9660 file %s", pathname); + "Failed to open ISO9660 file %s", + pathname.c_str()); return nullptr; } @@ -131,31 +140,35 @@ Iso9660ArchiveFile::Visit(ArchiveVisitor &visitor) /* single archive handling */ -struct Iso9660InputStream { +class Iso9660InputStream { InputStream base; - Iso9660ArchiveFile *archive; + Iso9660ArchiveFile &archive; iso9660_stat_t *statbuf; - size_t max_blocks; +public: Iso9660InputStream(Iso9660ArchiveFile &_archive, const char *uri, Mutex &mutex, Cond &cond, iso9660_stat_t *_statbuf) :base(iso9660_input_plugin, uri, mutex, cond), - archive(&_archive), statbuf(_statbuf), - max_blocks(CEILING(statbuf->size, ISO_BLOCKSIZE)) { - + archive(_archive), statbuf(_statbuf) { base.ready = true; base.size = statbuf->size; - archive->ref.Increment(); + archive.Ref(); } ~Iso9660InputStream() { free(statbuf); - archive->Unref(); + archive.Unref(); } + + InputStream *Get() { + return &base; + } + + size_t Read(void *ptr, size_t size, Error &error); }; InputStream * @@ -173,7 +186,7 @@ Iso9660ArchiveFile::OpenStream(const char *pathname, Iso9660InputStream *iis = new Iso9660InputStream(*this, pathname, mutex, cond, statbuf); - return &iis->base; + return iis->Get(); } static void @@ -184,45 +197,49 @@ iso9660_input_close(InputStream *is) delete iis; } - -static size_t -iso9660_input_read(InputStream *is, void *ptr, size_t size, - Error &error) +inline size_t +Iso9660InputStream::Read(void *ptr, size_t size, Error &error) { - Iso9660InputStream *iis = (Iso9660InputStream *)is; int readed = 0; int no_blocks, cur_block; - size_t left_bytes = iis->statbuf->size - is->offset; - - size = (size * ISO_BLOCKSIZE) / ISO_BLOCKSIZE; + size_t left_bytes = statbuf->size - base.offset; if (left_bytes < size) { no_blocks = CEILING(left_bytes,ISO_BLOCKSIZE); } else { no_blocks = size / ISO_BLOCKSIZE; } - if (no_blocks > 0) { - cur_block = is->offset / ISO_BLOCKSIZE; + if (no_blocks == 0) + return 0; - readed = iso9660_iso_seek_read (iis->archive->iso, ptr, - iis->statbuf->lsn + cur_block, no_blocks); + cur_block = base.offset / ISO_BLOCKSIZE; - if (readed != no_blocks * ISO_BLOCKSIZE) { - error.Format(iso9660_domain, - "error reading ISO file at lsn %lu", - (unsigned long)cur_block); - return 0; - } - if (left_bytes < size) { - readed = left_bytes; - } + readed = archive.SeekRead(ptr, statbuf->lsn + cur_block, + no_blocks); - is->offset += readed; + if (readed != no_blocks * ISO_BLOCKSIZE) { + error.Format(iso9660_domain, + "error reading ISO file at lsn %lu", + (unsigned long)cur_block); + return 0; + } + if (left_bytes < size) { + readed = left_bytes; } + + base.offset += readed; return readed; } +static size_t +iso9660_input_read(InputStream *is, void *ptr, size_t size, + Error &error) +{ + Iso9660InputStream *iis = (Iso9660InputStream *)is; + return iis->Read(ptr, size, error); +} + static bool iso9660_input_eof(InputStream *is) { @@ -251,7 +268,7 @@ const InputPlugin iso9660_input_plugin = { nullptr, }; -const struct archive_plugin iso9660_archive_plugin = { +const ArchivePlugin iso9660_archive_plugin = { "iso", nullptr, nullptr, diff --git a/src/archive/Iso9660ArchivePlugin.hxx b/src/archive/plugins/Iso9660ArchivePlugin.hxx index 6fbab6159..9335e83b3 100644 --- a/src/archive/Iso9660ArchivePlugin.hxx +++ b/src/archive/plugins/Iso9660ArchivePlugin.hxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2013 The Music Player Daemon Project + * 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 @@ -20,6 +20,8 @@ #ifndef MPD_ARCHIVE_ISO9660_HXX #define MPD_ARCHIVE_ISO9660_HXX -extern const struct archive_plugin iso9660_archive_plugin; +struct ArchivePlugin; + +extern const ArchivePlugin iso9660_archive_plugin; #endif diff --git a/src/archive/ZzipArchivePlugin.cxx b/src/archive/plugins/ZzipArchivePlugin.cxx index 973fe91dc..716b56160 100644 --- a/src/archive/ZzipArchivePlugin.cxx +++ b/src/archive/plugins/ZzipArchivePlugin.cxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2013 The Music Player Daemon Project + * 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 @@ -23,19 +23,18 @@ #include "config.h" #include "ZzipArchivePlugin.hxx" -#include "ArchivePlugin.hxx" -#include "ArchiveFile.hxx" -#include "ArchiveVisitor.hxx" -#include "InputStream.hxx" -#include "InputPlugin.hxx" +#include "../ArchivePlugin.hxx" +#include "../ArchiveFile.hxx" +#include "../ArchiveVisitor.hxx" +#include "input/InputStream.hxx" +#include "input/InputPlugin.hxx" +#include "fs/Path.hxx" #include "util/RefCount.hxx" #include "util/Error.hxx" #include "util/Domain.hxx" #include <zzip/zzip.h> -#include <string.h> - class ZzipArchiveFile final : public ArchiveFile { public: RefCount ref; @@ -72,12 +71,12 @@ static constexpr Domain zzip_domain("zzip"); /* archive open && listing routine */ static ArchiveFile * -zzip_archive_open(const char *pathname, Error &error) +zzip_archive_open(Path pathname, Error &error) { - ZZIP_DIR *dir = zzip_dir_open(pathname, nullptr); + ZZIP_DIR *dir = zzip_dir_open(pathname.c_str(), nullptr); if (dir == nullptr) { error.Format(zzip_domain, "Failed to open ZIP file %s", - pathname); + pathname.c_str()); return nullptr; } @@ -216,7 +215,7 @@ const InputPlugin zzip_input_plugin = { zzip_input_seek, }; -const struct archive_plugin zzip_archive_plugin = { +const ArchivePlugin zzip_archive_plugin = { "zzip", nullptr, nullptr, diff --git a/src/archive/ZzipArchivePlugin.hxx b/src/archive/plugins/ZzipArchivePlugin.hxx index 4ba16849b..cc92b7c52 100644 --- a/src/archive/ZzipArchivePlugin.hxx +++ b/src/archive/plugins/ZzipArchivePlugin.hxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2013 The Music Player Daemon Project + * 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 @@ -20,6 +20,8 @@ #ifndef MPD_ARCHIVE_ZZIP_HXX #define MPD_ARCHIVE_ZZIP_HXX -extern const struct archive_plugin zzip_archive_plugin; +struct ArchivePlugin; + +extern const ArchivePlugin zzip_archive_plugin; #endif |