tag/ApeLoader: use class InputStream instead of FILE*
Prepare for APE tag support on userspace NFS/SMB/CIFS mounts.
This commit is contained in:
parent
8a86460b8f
commit
cc5443c38e
@ -1882,10 +1882,15 @@ test_read_tags_SOURCES = test/read_tags.cxx \
|
|||||||
|
|
||||||
test_ReadApeTags_LDADD = \
|
test_ReadApeTags_LDADD = \
|
||||||
$(TAG_LIBS) \
|
$(TAG_LIBS) \
|
||||||
|
$(INPUT_LIBS) \
|
||||||
|
$(ARCHIVE_LIBS) \
|
||||||
$(FS_LIBS) \
|
$(FS_LIBS) \
|
||||||
$(ICU_LDADD) \
|
$(ICU_LDADD) \
|
||||||
|
libsystem.a \
|
||||||
libutil.a
|
libutil.a
|
||||||
test_ReadApeTags_SOURCES = test/ReadApeTags.cxx
|
test_ReadApeTags_SOURCES = \
|
||||||
|
src/Log.cxx src/LogBackend.cxx \
|
||||||
|
test/ReadApeTags.cxx
|
||||||
|
|
||||||
if ENABLE_ID3TAG
|
if ENABLE_ID3TAG
|
||||||
test_dump_rva2_LDADD = \
|
test_dump_rva2_LDADD = \
|
||||||
|
@ -20,12 +20,16 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "ApeLoader.hxx"
|
#include "ApeLoader.hxx"
|
||||||
#include "system/ByteOrder.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/StringView.hxx"
|
||||||
|
#include "util/Error.hxx"
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
struct ape_footer {
|
struct ape_footer {
|
||||||
@ -37,13 +41,18 @@ struct ape_footer {
|
|||||||
unsigned char reserved[8];
|
unsigned char reserved[8];
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool
|
bool
|
||||||
ape_scan_internal(FILE *fp, ApeTagCallback callback)
|
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 */
|
/* determine if file has an apeV2 tag */
|
||||||
struct ape_footer footer;
|
struct ape_footer footer;
|
||||||
if (fseek(fp, -(long)sizeof(footer), SEEK_END) ||
|
if (!is.Seek(is.GetSize() - sizeof(footer), IgnoreError()) ||
|
||||||
fread(&footer, 1, sizeof(footer), fp) != sizeof(footer) ||
|
!is.ReadFull(&footer, sizeof(footer), IgnoreError()) ||
|
||||||
memcmp(footer.id, "APETAGEX", sizeof(footer.id)) != 0 ||
|
memcmp(footer.id, "APETAGEX", sizeof(footer.id)) != 0 ||
|
||||||
FromLE32(footer.version) != 2000)
|
FromLE32(footer.version) != 2000)
|
||||||
return false;
|
return false;
|
||||||
@ -53,7 +62,7 @@ ape_scan_internal(FILE *fp, ApeTagCallback callback)
|
|||||||
if (remaining <= sizeof(footer) + 10 ||
|
if (remaining <= sizeof(footer) + 10 ||
|
||||||
/* refuse to load more than one megabyte of tag data */
|
/* refuse to load more than one megabyte of tag data */
|
||||||
remaining > 1024 * 1024 ||
|
remaining > 1024 * 1024 ||
|
||||||
fseek(fp, -(long)remaining, SEEK_END))
|
!is.Seek(is.GetSize() - remaining, IgnoreError()))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* read tag into buffer */
|
/* read tag into buffer */
|
||||||
@ -61,7 +70,7 @@ ape_scan_internal(FILE *fp, ApeTagCallback callback)
|
|||||||
assert(remaining > 10);
|
assert(remaining > 10);
|
||||||
|
|
||||||
char *buffer = new char[remaining];
|
char *buffer = new char[remaining];
|
||||||
if (fread(buffer, 1, remaining, fp) != remaining) {
|
if (!is.ReadFull(buffer, remaining, IgnoreError())) {
|
||||||
delete[] buffer;
|
delete[] buffer;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -104,11 +113,13 @@ ape_scan_internal(FILE *fp, ApeTagCallback callback)
|
|||||||
bool
|
bool
|
||||||
tag_ape_scan(Path path_fs, ApeTagCallback callback)
|
tag_ape_scan(Path path_fs, ApeTagCallback callback)
|
||||||
{
|
{
|
||||||
FILE *fp = FOpen(path_fs, PATH_LITERAL("rb"));
|
Mutex mutex;
|
||||||
if (fp == nullptr)
|
Cond cond;
|
||||||
|
|
||||||
|
std::unique_ptr<InputStream> is(OpenLocalInputStream(path_fs, mutex,
|
||||||
|
cond, IgnoreError()));
|
||||||
|
if (!is)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
bool success = ape_scan_internal(fp, callback);
|
return tag_ape_scan(*is, callback);
|
||||||
fclose(fp);
|
|
||||||
return success;
|
|
||||||
}
|
}
|
||||||
|
@ -28,10 +28,20 @@
|
|||||||
|
|
||||||
struct StringView;
|
struct StringView;
|
||||||
class Path;
|
class Path;
|
||||||
|
class InputStream;
|
||||||
|
|
||||||
typedef std::function<bool(unsigned long flags, const char *key,
|
typedef std::function<bool(unsigned long flags, const char *key,
|
||||||
StringView value)> ApeTagCallback;
|
StringView value)> ApeTagCallback;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
* Scans the APE tag values from a file.
|
||||||
*
|
*
|
||||||
|
@ -105,6 +105,23 @@ tag_ape_import_item(unsigned long flags,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
bool
|
||||||
tag_ape_scan2(Path path_fs,
|
tag_ape_scan2(Path path_fs,
|
||||||
const struct tag_handler *handler, void *handler_ctx)
|
const struct tag_handler *handler, void *handler_ctx)
|
||||||
|
@ -23,10 +23,20 @@
|
|||||||
#include "TagTable.hxx"
|
#include "TagTable.hxx"
|
||||||
|
|
||||||
class Path;
|
class Path;
|
||||||
|
class InputStream;
|
||||||
struct tag_handler;
|
struct tag_handler;
|
||||||
|
|
||||||
extern const struct tag_table ape_tags[];
|
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.
|
* Scan the APE tags of a file.
|
||||||
*
|
*
|
||||||
|
Loading…
Reference in New Issue
Block a user