summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2016-02-22 13:31:03 +0100
committerMax Kellermann <max@duempel.org>2016-02-22 17:30:36 +0100
commitcc5443c38eddbbd2894436b1e2107f8dda7262b8 (patch)
tree0a13f447f2b1440b73a1f30ea3405093705b62cd /src
parent8a86460b8f054a42130a4b59e082b66d921d2a1b (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.cxx37
-rw-r--r--src/tag/ApeLoader.hxx10
-rw-r--r--src/tag/ApeTag.cxx17
-rw-r--r--src/tag/ApeTag.hxx10
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