diff options
author | Max Kellermann <max@duempel.org> | 2016-02-22 13:31:03 +0100 |
---|---|---|
committer | Max Kellermann <max@duempel.org> | 2016-02-22 17:30:36 +0100 |
commit | cc5443c38eddbbd2894436b1e2107f8dda7262b8 (patch) | |
tree | 0a13f447f2b1440b73a1f30ea3405093705b62cd /src | |
parent | 8a86460b8f054a42130a4b59e082b66d921d2a1b (diff) |
tag/ApeLoader: use class InputStream instead of FILE*
Prepare for APE tag support on userspace NFS/SMB/CIFS mounts.
Diffstat (limited to 'src')
-rw-r--r-- | src/tag/ApeLoader.cxx | 37 | ||||
-rw-r--r-- | src/tag/ApeLoader.hxx | 10 | ||||
-rw-r--r-- | src/tag/ApeTag.cxx | 17 | ||||
-rw-r--r-- | src/tag/ApeTag.hxx | 10 |
4 files changed, 61 insertions, 13 deletions
diff --git a/src/tag/ApeLoader.cxx b/src/tag/ApeLoader.cxx index b1759a730..26d42c48b 100644 --- a/src/tag/ApeLoader.cxx +++ b/src/tag/ApeLoader.cxx @@ -20,12 +20,16 @@ #include "config.h" #include "ApeLoader.hxx" #include "system/ByteOrder.hxx" -#include "fs/FileSystem.hxx" +#include "fs/Path.hxx" +#include "thread/Mutex.hxx" +#include "thread/Cond.hxx" +#include "input/InputStream.hxx" +#include "input/LocalOpen.hxx" #include "util/StringView.hxx" +#include "util/Error.hxx" #include <stdint.h> #include <assert.h> -#include <stdio.h> #include <string.h> struct ape_footer { @@ -37,13 +41,18 @@ struct ape_footer { unsigned char reserved[8]; }; -static bool -ape_scan_internal(FILE *fp, ApeTagCallback callback) +bool +tag_ape_scan(InputStream &is, ApeTagCallback callback) { + const ScopeLock protect(is.mutex); + + if (!is.KnownSize() || !is.CheapSeeking()) + return false; + /* determine if file has an apeV2 tag */ struct ape_footer footer; - if (fseek(fp, -(long)sizeof(footer), SEEK_END) || - fread(&footer, 1, sizeof(footer), fp) != sizeof(footer) || + if (!is.Seek(is.GetSize() - sizeof(footer), IgnoreError()) || + !is.ReadFull(&footer, sizeof(footer), IgnoreError()) || memcmp(footer.id, "APETAGEX", sizeof(footer.id)) != 0 || FromLE32(footer.version) != 2000) return false; @@ -53,7 +62,7 @@ ape_scan_internal(FILE *fp, ApeTagCallback callback) if (remaining <= sizeof(footer) + 10 || /* refuse to load more than one megabyte of tag data */ remaining > 1024 * 1024 || - fseek(fp, -(long)remaining, SEEK_END)) + !is.Seek(is.GetSize() - remaining, IgnoreError())) return false; /* read tag into buffer */ @@ -61,7 +70,7 @@ ape_scan_internal(FILE *fp, ApeTagCallback callback) assert(remaining > 10); char *buffer = new char[remaining]; - if (fread(buffer, 1, remaining, fp) != remaining) { + if (!is.ReadFull(buffer, remaining, IgnoreError())) { delete[] buffer; return false; } @@ -104,11 +113,13 @@ ape_scan_internal(FILE *fp, ApeTagCallback callback) bool tag_ape_scan(Path path_fs, ApeTagCallback callback) { - FILE *fp = FOpen(path_fs, PATH_LITERAL("rb")); - if (fp == nullptr) + Mutex mutex; + Cond cond; + + std::unique_ptr<InputStream> is(OpenLocalInputStream(path_fs, mutex, + cond, IgnoreError())); + if (!is) return false; - bool success = ape_scan_internal(fp, callback); - fclose(fp); - return success; + return tag_ape_scan(*is, callback); } diff --git a/src/tag/ApeLoader.hxx b/src/tag/ApeLoader.hxx index 4587ff063..0e2eadff1 100644 --- a/src/tag/ApeLoader.hxx +++ b/src/tag/ApeLoader.hxx @@ -28,6 +28,7 @@ struct StringView; class Path; +class InputStream; typedef std::function<bool(unsigned long flags, const char *key, StringView value)> ApeTagCallback; @@ -35,6 +36,15 @@ typedef std::function<bool(unsigned long flags, const char *key, /** * Scans the APE tag values from a file. * + * @return false if the file could not be opened or if no APE tag is + * present + */ +bool +tag_ape_scan(InputStream &is, ApeTagCallback callback); + +/** + * Scans the APE tag values from a file. + * * @param path_fs the path of the file in filesystem encoding * @return false if the file could not be opened or if no APE tag is * present diff --git a/src/tag/ApeTag.cxx b/src/tag/ApeTag.cxx index 81318a771..edf30dd4d 100644 --- a/src/tag/ApeTag.cxx +++ b/src/tag/ApeTag.cxx @@ -106,6 +106,23 @@ tag_ape_import_item(unsigned long flags, } bool +tag_ape_scan2(InputStream &is, + const struct tag_handler *handler, void *handler_ctx) +{ + bool recognized = false; + + auto callback = [handler, handler_ctx, &recognized] + (unsigned long flags, const char *key, + StringView value) { + recognized |= tag_ape_import_item(flags, key, value, + handler, handler_ctx); + return true; + }; + + return tag_ape_scan(is, callback) && recognized; +} + +bool tag_ape_scan2(Path path_fs, const struct tag_handler *handler, void *handler_ctx) { diff --git a/src/tag/ApeTag.hxx b/src/tag/ApeTag.hxx index 20d1d7b81..003f9404c 100644 --- a/src/tag/ApeTag.hxx +++ b/src/tag/ApeTag.hxx @@ -23,11 +23,21 @@ #include "TagTable.hxx" class Path; +class InputStream; struct tag_handler; extern const struct tag_table ape_tags[]; /** + * Scan the APE tags of a stream. + * + * @param path_fs the path of the file in filesystem encoding + */ +bool +tag_ape_scan2(InputStream &is, + const tag_handler *handler, void *handler_ctx); + +/** * Scan the APE tags of a file. * * @param path_fs the path of the file in filesystem encoding |