aboutsummaryrefslogtreecommitdiff
path: root/Src/replicant/metadata
diff options
context:
space:
mode:
Diffstat (limited to 'Src/replicant/metadata')
-rw-r--r--Src/replicant/metadata/MetadataKeys.h50
-rw-r--r--Src/replicant/metadata/api_artwork.h35
-rw-r--r--Src/replicant/metadata/api_metadata.h48
-rw-r--r--Src/replicant/metadata/genres.h41
-rw-r--r--Src/replicant/metadata/ifc_metadata.h65
-rw-r--r--Src/replicant/metadata/ifc_metadata_editor.h43
-rw-r--r--Src/replicant/metadata/metadata.h7
-rw-r--r--Src/replicant/metadata/metadata.xcodeproj/project.pbxproj268
-rw-r--r--Src/replicant/metadata/metadata.xcodeproj/xcshareddata/xcschemes/metadata.xcscheme59
-rw-r--r--Src/replicant/metadata/svc_metadata.h65
-rw-r--r--Src/replicant/metadata/types.h34
11 files changed, 715 insertions, 0 deletions
diff --git a/Src/replicant/metadata/MetadataKeys.h b/Src/replicant/metadata/MetadataKeys.h
new file mode 100644
index 00000000..c6113528
--- /dev/null
+++ b/Src/replicant/metadata/MetadataKeys.h
@@ -0,0 +1,50 @@
+#pragma once
+
+namespace MetadataKeys
+{
+ const int EXTENDED_KEYS_OFFSET = 1000; // The offset to where the extended id's start
+
+ enum
+ {
+ UNKNOWN=-1,
+ ARTIST=0,
+ ALBUM_ARTIST=1,
+ ALBUM=2,
+ TITLE=3,
+ URI=4,
+ GENRE=5,
+ YEAR=6,
+ TRACK=7, // in ifc_metadata::GetField, this might return something like "2/12" for track 2 out of 12. in ifc_metadata::GetInteger, you will just get the track number (use TRACKS for total)
+ DISC=8, // in ifc_metadata::GetField, this might return something like "1/2" for disc 1 out of 2. in ifc_metadata::GetInteger, you will just get the disc number (use DISCS for total)
+ BITRATE=9,
+ COMPOSER=10,
+ PUBLISHER=11,
+ BPM=12,
+ COMMENT=13,
+ DISCS=14, // only valid for use in ifc_metadata::GetInteger
+ FILE_SIZE=15,
+ FILE_TIME=16,
+ LENGTH=17,
+ PLAY_COUNT=18,
+ RATING=19,
+ SERVER=20,
+ MIME_TYPE=21,
+ TRACK_GAIN=22,
+ TRACK_PEAK=23,
+ ALBUM_GAIN=24,
+ ALBUM_PEAK=25,
+ TRACKS=26, // only valid for use in ifc_metadata::GetInteger
+ PREGAP=27,
+ POSTGAP=28,
+ STAT=29,
+ CATEGORY=30,
+ DIRECTOR=31,
+ PRODUCER=32,
+ LAST_PLAY=33,
+ LAST_UPDATE=34,
+ ADDED=35, // date added
+ CLOUD=36, // used by pmp_cloud for the 'all sources' view
+ METAHASH=37, // used by pmp_cloud for the 'all sources' view
+ NUM_OF_METADATA_KEYS,
+ };
+}
diff --git a/Src/replicant/metadata/api_artwork.h b/Src/replicant/metadata/api_artwork.h
new file mode 100644
index 00000000..b4ee6be5
--- /dev/null
+++ b/Src/replicant/metadata/api_artwork.h
@@ -0,0 +1,35 @@
+#pragma once
+#include "service/types.h"
+#include "nx/nx.h"
+#include "foundation/foundation.h"
+#include "metadata/types.h"
+
+// {60DB7F78-0238-4DA7-9260-87E60D30FAC4}
+static const GUID artwork_api_guid =
+{ 0x60db7f78, 0x238, 0x4da7, { 0x92, 0x60, 0x87, 0xe6, 0xd, 0x30, 0xfa, 0xc4 } };
+
+// ----------------------------------------------------------------------------
+class NOVTABLE api_artwork : public Wasabi2::Dispatchable
+{
+protected:
+ api_artwork() : Dispatchable(DISPATCHABLE_VERSION) {}
+ ~api_artwork() {}
+public:
+ static GUID GetServiceType() { return SVC_TYPE_UNIQUE; }
+ static GUID GetServiceGUID() { return artwork_api_guid; }
+
+ /* returns the data for the first piece of artwork found
+ pass NULL for any of the values that you don't care about */
+ int GetArtwork(nx_uri_t filename, unsigned int field, artwork_t *artwork, data_flags_t flags=DATA_FLAG_ALL, nx_time_unix_64_t *file_modified=0)
+ {
+ return Artwork_GetArtwork(filename, field, artwork, flags, file_modified);
+ }
+ enum
+ {
+ DISPATCHABLE_VERSION,
+ };
+
+protected:
+ virtual int WASABICALL Artwork_GetArtwork(nx_uri_t filename, unsigned int field, artwork_t *artwork, data_flags_t flags, nx_time_unix_64_t *file_modified)=0;
+};
+
diff --git a/Src/replicant/metadata/api_metadata.h b/Src/replicant/metadata/api_metadata.h
new file mode 100644
index 00000000..18a9de85
--- /dev/null
+++ b/Src/replicant/metadata/api_metadata.h
@@ -0,0 +1,48 @@
+#pragma once
+#include "foundation/dispatch.h"
+#include "foundation/error.h"
+#include "service/types.h"
+
+#include "nx/nxuri.h"
+#include "metadata/ifc_metadata.h"
+#include "metadata/ifc_metadata_editor.h"
+#include "metadata/MetadataKeys.h"
+
+// {63149C84-08DC-4EA0-9351-2B0CB263FE55}
+static const GUID metadataApiServiceGuid =
+{ 0x63149c84, 0x8dc, 0x4ea0, { 0x93, 0x51, 0x2b, 0xc, 0xb2, 0x63, 0xfe, 0x55 } };
+
+
+// ----------------------------------------------------------------------------
+class NOVTABLE api_metadata: public Wasabi2::Dispatchable
+{
+protected:
+ api_metadata() : Dispatchable(DISPATCHABLE_VERSION) {}
+ ~api_metadata() {}
+public:
+ static GUID GetServiceType() { return SVC_TYPE_UNIQUE; }
+ static GUID GetServiceGUID() { return metadataApiServiceGuid; }
+
+ ns_error_t RegisterField(nx_string_t field_name, int *field) { return Metadata_RegisterField(field_name, field); } // Register for a non standard metadata field name
+ ns_error_t GetFieldKey(nx_string_t field_name, int *field) { return Metadata_GetFieldKey(field_name, field); } // Return the integer key of the current field
+ ns_error_t GetFieldName(int field_key, nx_string_t *name) { return Metadata_GetFieldName(field_key, name); } // Return the field name when provided with the key
+ ns_error_t GetGenre(uint8_t genre_id, nx_string_t *genre) { return Metadata_GetGenre(genre_id, genre); }
+ ns_error_t GetGenreID(nx_string_t genre, uint8_t *genre_id) { return Metadata_GetGenreID(genre, genre_id); }
+ ns_error_t SupportedFilename(nx_uri_t filename) { return Metadata_SupportedFilename(filename); }
+ ns_error_t CreateMetadata(ifc_metadata **out_metadata, nx_uri_t filename) { return Metadata_CreateMetadata(out_metadata, filename); }
+ ns_error_t CreateMetadataEditor(ifc_metadata_editor **out_metadata, nx_uri_t filename) { return Metadata_CreateMetadataEditor(out_metadata, filename); }
+ enum
+ {
+ DISPATCHABLE_VERSION, // ToDo: Does this need to be set here?
+ };
+protected:
+ virtual ns_error_t WASABICALL Metadata_RegisterField(nx_string_t field_name, int *field)=0;
+ virtual ns_error_t WASABICALL Metadata_GetFieldKey(nx_string_t field_name, int *field)=0;
+ virtual ns_error_t WASABICALL Metadata_GetFieldName(int field_key, nx_string_t *name)=0;
+ virtual ns_error_t WASABICALL Metadata_GetGenre(uint8_t genre_id, nx_string_t *genre)=0;
+ virtual ns_error_t WASABICALL Metadata_GetGenreID(nx_string_t genre, uint8_t *genre_id)=0;
+ virtual ns_error_t WASABICALL Metadata_SupportedFilename(nx_uri_t filename)=0;
+ virtual ns_error_t WASABICALL Metadata_CreateMetadata(ifc_metadata **out_metadata, nx_uri_t filename)=0;
+ virtual ns_error_t WASABICALL Metadata_CreateMetadataEditor(ifc_metadata_editor **out_metadata, nx_uri_t filename)=0;
+};
+
diff --git a/Src/replicant/metadata/genres.h b/Src/replicant/metadata/genres.h
new file mode 100644
index 00000000..7609a1c9
--- /dev/null
+++ b/Src/replicant/metadata/genres.h
@@ -0,0 +1,41 @@
+#pragma once
+
+static const char* metadata_genre_list[] = {
+ "Blues", "Classic Rock", "Country", "Dance", "Disco", "Funk",
+ "Grunge", "Hip-Hop", "Jazz", "Metal", "New Age", "Oldies",
+ "Other", "Pop", "R&B", "Rap", "Reggae", "Rock",
+ "Techno", "Industrial", "Alternative", "Ska", "Death Metal", "Pranks",
+ "Soundtrack", "Euro-Techno", "Ambient", "Trip-Hop", "Vocal", "Jazz+Funk",
+ "Fusion", "Trance", "Classical", "Instrumental", "Acid", "House",
+ "Game", "Sound Clip", "Gospel", "Noise", "Alt Rock", "Bass",
+ "Soul", "Punk", "Space", "Meditative", "Instrumental Pop", "Instrumental Rock",
+ "Ethnic", "Gothic", "Darkwave", "Techno-Industrial", "Electronic", "Pop-Folk",
+ "Eurodance", "Dream", "Southern Rock", "Comedy", "Cult", "Gangsta",
+ "Top 40", "Christian Rap", "Pop/Funk", "Jungle", "Native American", "Cabaret",
+ "New Wave", "Psychedelic", "Rave", "Showtunes", "Trailer", "Lo-Fi",
+ "Tribal", "Acid Punk", "Acid Jazz", "Polka", "Retro", "Musical",
+ "Rock & Roll", "Hard Rock", "Folk", "Folk-Rock", "National Folk", "Swing",
+ "Fast-Fusion", "Bebop", "Latin", "Revival", "Celtic", "Bluegrass", "Avantgarde",
+ "Gothic Rock", "Progressive Rock", "Psychedelic Rock", "Symphonic Rock", "Slow Rock", "Big Band",
+ "Chorus", "Easy Listening", "Acoustic", "Humour", "Speech", "Chanson",
+ "Opera", "Chamber Music", "Sonata", "Symphony", "Booty Bass", "Primus",
+ "Porn Groove", "Satire", "Slow Jam", "Club", "Tango", "Samba",
+ "Folklore", "Ballad", "Power Ballad", "Rhythmic Soul", "Freestyle", "Duet",
+ "Punk Rock", "Drum Solo", "A capella", "Euro-House", "Dance Hall",
+ "Goa", "Drum & Bass", "Club House", "Hardcore", "Terror",
+ "Indie", "BritPop", "Afro-Punk", "Polsk Punk", "Beat",
+ "Christian Gangsta", "Heavy Metal", "Black Metal", "Crossover", "Contemporary Christian",
+ "Christian Rock", "Merengue", "Salsa", "Thrash Metal", "Anime", "JPop",
+ "SynthPop", "Abstract", "Art Rock", "Baroque", "Bhangra", "Big Beat", "Breakbeat", "Chillout", "Downtempo", "Dub", "EBM", "Eclectic", "Electro",
+ "Electroclash", "Emo", "Experimental", "Garage", "Global", "IDM", "Illbient", "Industro-Goth", "Jam Band", "Krautrock", "Leftfield", "Lounge",
+ "Math Rock", "New Romantic", "Nu-Breakz", "Post-Punk", "Post-Rock", "Psytrance", "Shoegaze", "Space Rock", "Trop Rock", "World Music", "Neoclassical",
+ "Audiobook", "Audio Theatre", "Neue Deutsche Welle", "Podcast", "Indie Rock", "G-Funk", "Dubstep", "Garage Rock", "Psybient", "Glam Rock", "Dream Pop",
+ "Merseybeat", "K-Pop", "Chiptune", "Grime", "Grindcore", "Indietronic", "Indietronica", "Jazz Rock", "Jazz Fusion", "Post-Punk Revival", "Electronica",
+ "Psychill", "Ethnotronic", "Americana", "Ambient Dub", "Digital Dub", "Chillwave", "Stoner Rock", "Slowcore", "Softcore", "Flamenco", "Hi-NRG", "Ethereal",
+ "Drone", "Doom Metal", "Doom Jazz", "Mainstream", "Glitch", "Balearic", "Modern Classical", "Mod", "Contemporary Classical", "Psybreaks", "Psystep",
+ "Psydub", "Chillstep", "Berlin School", "Future Jazz", "Djent", "Musique Concrète", "Electroacoustic", "Folktronica", "Texas Country", "Red Dirt",
+ "Arabic", "Asian", "Bachata", "Bollywood", "Cajun", "Calypso", "Creole", "Darkstep", "Jewish", "Reggaeton", "Smooth Jazz", "Soca", "Spiritual",
+ "Turntablism", "Zouk","Neofolk", "Nu Jazz", "Psychobilly", "Rockabilly", "Schlager & Volksmusik",
+};
+
+static const size_t metadata_genre_list_size = sizeof(metadata_genre_list)/sizeof(*metadata_genre_list);
diff --git a/Src/replicant/metadata/ifc_metadata.h b/Src/replicant/metadata/ifc_metadata.h
new file mode 100644
index 00000000..039d69b6
--- /dev/null
+++ b/Src/replicant/metadata/ifc_metadata.h
@@ -0,0 +1,65 @@
+#pragma once
+#include "foundation/dispatch.h"
+#include "nx/nxstring.h"
+#include "nx/nxdata.h"
+#include "foundation/error.h"
+#include "metadata/MetadataKeys.h"
+#include "metadata/types.h"
+
+class NOVTABLE ifc_metadata : public Wasabi2::Dispatchable
+{
+protected:
+ ifc_metadata() : Dispatchable(DISPATCHABLE_VERSION) {}
+public:
+ virtual ~ifc_metadata() {}
+
+ enum
+ {
+ INDEX_DEFAULT = -1,
+ };
+
+ /* Fields */
+ ns_error_t GetField(int field, unsigned int index, nx_string_t *value) { return Metadata_GetField(field, index, value); }
+ ns_error_t GetInteger(int field, unsigned int index, int64_t *value) { return Metadata_GetInteger(field, index, value); }
+ ns_error_t GetReal(int field, unsigned int index, double *value) { return Metadata_GetReal(field, index, value); }
+
+ ns_error_t SetField(int field, unsigned int index, nx_string_t value) { return Metadata_SetField(field, index, value); }
+ ns_error_t SetInteger(int field, unsigned int index, int64_t value) { return Metadata_SetInteger(field, index, value); }
+ ns_error_t SetReal(int field, unsigned int index, double value) { return Metadata_SetReal(field, index, value); }
+
+ /* Art */
+ ns_error_t GetArtwork(int field, unsigned int index, artwork_t *artwork, data_flags_t flags=DATA_FLAG_ALL) { return Metadata_GetArtwork(field, index, artwork, flags); }
+
+ /* Binary Data */
+ ns_error_t GetBinary(int field, unsigned int index, nx_data_t *data) { return Metadata_GetBinary(field, index, data); }
+
+ /* sub-tracks */
+ ns_error_t GetMetadata(int field, unsigned int index, ifc_metadata **metadata) { return Metadata_GetMetadata(field, index, metadata); }
+
+ ns_error_t Serialize(nx_data_t *data) { return Metadata_Serialize(data); }
+
+ enum
+ {
+ DISPATCHABLE_VERSION,
+ };
+protected:
+ virtual ns_error_t WASABICALL Metadata_GetField(int field, unsigned int index, nx_string_t *value)=0;
+ virtual ns_error_t WASABICALL Metadata_GetInteger(int field, unsigned int index, int64_t *value)=0;
+ virtual ns_error_t WASABICALL Metadata_GetReal(int field, unsigned int index, double *value)=0;
+
+ virtual ns_error_t WASABICALL Metadata_SetField(int field, unsigned int index, nx_string_t value){ return NErr_NotImplemented; };
+ virtual ns_error_t WASABICALL Metadata_SetInteger(int field, unsigned int index, int64_t value){ return NErr_NotImplemented; };
+ virtual ns_error_t WASABICALL Metadata_SetReal(int field, unsigned int index, double value){ return NErr_NotImplemented; };
+
+ /* notes:
+ passing NULL for any of the pointers (most notably, data) indicates that it's not needed
+ width and height aren't guaranteed to be actually accurate. they will be set only if it was marked in the file, otherwise they will be set to 0
+ mime_type might also come back as 0 if it wasn't stored in the metadata. and again, mime_type isn't guaranteed to be accurate
+ for type, MetadataKeys::ALBUM is for album art. use Metadata::UNKNOWN for unknown types, such as id3v2 tags with Picture types marked as "other" ($00)
+ index should be as stored in the file, do not re-arrange. */
+ virtual ns_error_t WASABICALL Metadata_GetArtwork(int field, unsigned int index, artwork_t *artwork, data_flags_t flags)=0;
+ virtual ns_error_t WASABICALL Metadata_GetBinary(int field, unsigned int index, nx_data_t *data)=0;
+ virtual ns_error_t WASABICALL Metadata_GetMetadata(int field, unsigned int index, ifc_metadata **metadata) { return NErr_NotImplemented; }
+
+ virtual ns_error_t WASABICALL Metadata_Serialize(nx_data_t *data) { return NErr_NotImplemented; }
+};
diff --git a/Src/replicant/metadata/ifc_metadata_editor.h b/Src/replicant/metadata/ifc_metadata_editor.h
new file mode 100644
index 00000000..311e0ed3
--- /dev/null
+++ b/Src/replicant/metadata/ifc_metadata_editor.h
@@ -0,0 +1,43 @@
+#pragma once
+#include "foundation/dispatch.h"
+#include "nx/nxstring.h"
+#include "foundation/error.h"
+#include "metadata/MetadataKeys.h"
+#include "nx/nxdata.h"
+#include "metadata/types.h"
+class NOVTABLE ifc_metadata_editor : public Wasabi2::Dispatchable
+{
+protected:
+ ifc_metadata_editor() : Dispatchable(DISPATCHABLE_VERSION) {}
+ ~ifc_metadata_editor() {}
+public:
+ enum
+ {
+ INDEX_DEFAULT = -1,
+ };
+
+ int Save() { return MetadataEditor_Save(); }
+
+ /* Fields */
+ int SetField(int field, unsigned int index, nx_string_t value) { return MetadataEditor_SetField(field, index, value); }
+ int SetInteger(int field, unsigned int index, int64_t value) { return MetadataEditor_SetInteger(field, index, value); }
+ int SetReal(int field, unsigned int index, double value) { return MetadataEditor_SetReal(field, index, value); }
+
+ /* Art */
+ int SetArtwork(int field, unsigned int index, artwork_t *data, data_flags_t flags=DATA_FLAG_ALL) { return MetadataEditor_SetArtwork(field, index, data, flags); }
+
+ /* Binary Data */
+
+ enum
+ {
+ DISPATCHABLE_VERSION,
+ };
+protected:
+ virtual int WASABICALL MetadataEditor_Save()=0;
+
+ virtual int WASABICALL MetadataEditor_SetField(int field, unsigned int index, nx_string_t value)=0;
+ virtual int WASABICALL MetadataEditor_SetInteger(int field, unsigned int index, int64_t value)=0;
+ virtual int WASABICALL MetadataEditor_SetReal(int field, unsigned int index, double value)=0;
+
+ virtual int WASABICALL MetadataEditor_SetArtwork(int field, unsigned int index, artwork_t *data, data_flags_t flags)=0;
+};
diff --git a/Src/replicant/metadata/metadata.h b/Src/replicant/metadata/metadata.h
new file mode 100644
index 00000000..dc137c55
--- /dev/null
+++ b/Src/replicant/metadata/metadata.h
@@ -0,0 +1,7 @@
+#pragma once
+/* convenience header that includes everything */
+#include "api_metadata.h"
+#include "ifc_metadata.h"
+#include "ifc_metadata_editor.h"
+#include "MetadataKeys.h"
+#include "svc_metadata.h"
diff --git a/Src/replicant/metadata/metadata.xcodeproj/project.pbxproj b/Src/replicant/metadata/metadata.xcodeproj/project.pbxproj
new file mode 100644
index 00000000..91b1f081
--- /dev/null
+++ b/Src/replicant/metadata/metadata.xcodeproj/project.pbxproj
@@ -0,0 +1,268 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 46;
+ objects = {
+
+/* Begin PBXAggregateTarget section */
+ 00DC1311150722D0007F9D73 /* metadata */ = {
+ isa = PBXAggregateTarget;
+ buildConfigurationList = 00DC1312150722D0007F9D73 /* Build configuration list for PBXAggregateTarget "metadata" */;
+ buildPhases = (
+ 00DC1315150722F0007F9D73 /* CopyFiles */,
+ 00B73372151B65EF00A8251C /* Install Public Headers */,
+ );
+ dependencies = (
+ 00B73378151B665900A8251C /* PBXTargetDependency */,
+ );
+ name = metadata;
+ productName = metadata;
+ };
+/* End PBXAggregateTarget section */
+
+/* Begin PBXBuildFile section */
+ 00B7336E151B645C00A8251C /* metadata.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 00B7336D151B645C00A8251C /* metadata.h */; };
+ 00B73371151B65AA00A8251C /* genres.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 00B73370151B65AA00A8251C /* genres.h */; };
+ 00D69B1A15BDD5AC0026710F /* types.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 00D69B1915BDD5AC0026710F /* types.h */; };
+ 00DC131615072301007F9D73 /* api_metadata.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 0088402315054AF300625F51 /* api_metadata.h */; };
+ 00DC131715072301007F9D73 /* ifc_metadata_editor.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 0088402415054AF300625F51 /* ifc_metadata_editor.h */; };
+ 00DC131815072301007F9D73 /* ifc_metadata.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 0088402515054AF300625F51 /* ifc_metadata.h */; };
+ 00DC131915072301007F9D73 /* MetadataKeys.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 0088402615054AF300625F51 /* MetadataKeys.h */; };
+ 00DC131A15072301007F9D73 /* svc_metadata.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 0088402715054AF300625F51 /* svc_metadata.h */; };
+ 00F535871553671D0069AC35 /* api_artwork.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 00F535861553671D0069AC35 /* api_artwork.h */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXContainerItemProxy section */
+ 00B73377151B665900A8251C /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 0088401015054ABD00625F51 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 00B73373151B662700A8251C;
+ remoteInfo = "metadata-cleanup";
+ };
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXCopyFilesBuildPhase section */
+ 00DC1315150722F0007F9D73 /* CopyFiles */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 2147483647;
+ dstPath = "$(PUBLIC_HEADERS_FOLDER_PATH)";
+ dstSubfolderSpec = 16;
+ files = (
+ 00DC131615072301007F9D73 /* api_metadata.h in CopyFiles */,
+ 00DC131715072301007F9D73 /* ifc_metadata_editor.h in CopyFiles */,
+ 00DC131815072301007F9D73 /* ifc_metadata.h in CopyFiles */,
+ 00DC131915072301007F9D73 /* MetadataKeys.h in CopyFiles */,
+ 00DC131A15072301007F9D73 /* svc_metadata.h in CopyFiles */,
+ 00B7336E151B645C00A8251C /* metadata.h in CopyFiles */,
+ 00B73371151B65AA00A8251C /* genres.h in CopyFiles */,
+ 00F535871553671D0069AC35 /* api_artwork.h in CopyFiles */,
+ 00D69B1A15BDD5AC0026710F /* types.h in CopyFiles */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXCopyFilesBuildPhase section */
+
+/* Begin PBXFileReference section */
+ 0088402315054AF300625F51 /* api_metadata.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = api_metadata.h; sourceTree = "<group>"; };
+ 0088402415054AF300625F51 /* ifc_metadata_editor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ifc_metadata_editor.h; sourceTree = "<group>"; };
+ 0088402515054AF300625F51 /* ifc_metadata.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ifc_metadata.h; sourceTree = "<group>"; };
+ 0088402615054AF300625F51 /* MetadataKeys.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MetadataKeys.h; sourceTree = "<group>"; };
+ 0088402715054AF300625F51 /* svc_metadata.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = svc_metadata.h; sourceTree = "<group>"; };
+ 00B7336D151B645C00A8251C /* metadata.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = metadata.h; sourceTree = "<group>"; };
+ 00B73370151B65AA00A8251C /* genres.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = genres.h; sourceTree = "<group>"; };
+ 00D69B1915BDD5AC0026710F /* types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = types.h; sourceTree = "<group>"; };
+ 00F535861553671D0069AC35 /* api_artwork.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = api_artwork.h; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXGroup section */
+ 0088400E15054ABD00625F51 = {
+ isa = PBXGroup;
+ children = (
+ 00F535861553671D0069AC35 /* api_artwork.h */,
+ 0088402315054AF300625F51 /* api_metadata.h */,
+ 0088402415054AF300625F51 /* ifc_metadata_editor.h */,
+ 0088402515054AF300625F51 /* ifc_metadata.h */,
+ 0088402615054AF300625F51 /* MetadataKeys.h */,
+ 0088402715054AF300625F51 /* svc_metadata.h */,
+ 00B7336D151B645C00A8251C /* metadata.h */,
+ 00B73370151B65AA00A8251C /* genres.h */,
+ 00D69B1915BDD5AC0026710F /* types.h */,
+ );
+ sourceTree = "<group>";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXLegacyTarget section */
+ 00B73373151B662700A8251C /* metadata-cleanup */ = {
+ isa = PBXLegacyTarget;
+ buildArgumentsString = "$(NSBUILD_TOOLS_BIN_DIR)/cleanbuild --xcode-mode \"$(PUBLIC_HEADERS_DIR)\"";
+ buildConfigurationList = 00B73374151B662700A8251C /* Build configuration list for PBXLegacyTarget "metadata-cleanup" */;
+ buildPhases = (
+ );
+ buildToolPath = /bin/sh;
+ buildWorkingDirectory = "";
+ dependencies = (
+ );
+ name = "metadata-cleanup";
+ passBuildSettingsInEnvironment = 1;
+ productName = "metadata-cleanup";
+ };
+/* End PBXLegacyTarget section */
+
+/* Begin PBXProject section */
+ 0088401015054ABD00625F51 /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ LastUpgradeCheck = 0430;
+ ORGANIZATIONNAME = "Nullsoft, Inc.";
+ };
+ buildConfigurationList = 0088401315054ABD00625F51 /* Build configuration list for PBXProject "metadata" */;
+ compatibilityVersion = "Xcode 3.2";
+ developmentRegion = English;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ en,
+ );
+ mainGroup = 0088400E15054ABD00625F51;
+ productRefGroup = 0088400E15054ABD00625F51;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ 00DC1311150722D0007F9D73 /* metadata */,
+ 00B73373151B662700A8251C /* metadata-cleanup */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXShellScriptBuildPhase section */
+ 00B73372151B65EF00A8251C /* Install Public Headers */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 8;
+ files = (
+ );
+ inputPaths = (
+ "$(BUILT_PRODUCTS_DIR)$(PUBLIC_HEADERS_FOLDER_PATH)",
+ );
+ name = "Install Public Headers";
+ outputPaths = (
+ "$(DSTROOT)$(PUBLIC_HEADERS_FOLDER_PATH)",
+ );
+ runOnlyForDeploymentPostprocessing = 1;
+ shellPath = /bin/sh;
+ shellScript = "INSTALLTOOL=\"$NSBUILD_TOOLS_BIN_DIR/installtool\"\n$INSTALLTOOL --headers-only \\\n \"$SCRIPT_INPUT_FILE_0/\" \\\n \"$SCRIPT_OUTPUT_FILE_0\"";
+ showEnvVarsInLog = 0;
+ };
+/* End PBXShellScriptBuildPhase section */
+
+/* Begin PBXTargetDependency section */
+ 00B73378151B665900A8251C /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 00B73373151B662700A8251C /* metadata-cleanup */;
+ targetProxy = 00B73377151B665900A8251C /* PBXContainerItemProxy */;
+ };
+/* End PBXTargetDependency section */
+
+/* Begin XCBuildConfiguration section */
+ 0088401B15054ABD00625F51 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
+ INSTALL_PATH_PREFIX = /usr/local;
+ MACOSX_DEPLOYMENT_TARGET = 10.6;
+ NSBUILD_TOOLS_BIN_DIR = "$(NSBUILD_TOOLS_DIR)/bin";
+ NSBUILD_TOOLS_DIR = "$(SRCROOT)/../../build-tools";
+ NSBUILD_TOOLS_SHARE_DIR = "$(NSBUILD_TOOLS_DIR)/share";
+ PRODUCT_NAME = "$(PROJECT_NAME)";
+ PUBLIC_HEADERS_FOLDER_PATH = "$(INSTALL_PATH_PREFIX)/include/$(PRODUCT_NAME)";
+ PUBLIC_HEADERS_FOLDER_PATH_AMD64 = "$(PUBLIC_HEADERS_FOLDER_PATH)/osx-amd64";
+ PUBLIC_HEADERS_FOLDER_PATH_X86 = "$(PUBLIC_HEADERS_FOLDER_PATH)/osx-x86";
+ SDKROOT = macosx;
+ SHARE_FOLDER_PATH = "$(INSTALL_PATH_PREFIX)/include/$(PRODUCT_NAME)";
+ USER_HEADER_SEARCH_PATHS = ".. $(BUILT_PRODUCTS_DIR)$(INSTALL_PATH_PREFIX)/include";
+ };
+ name = Debug;
+ };
+ 0088401C15054ABD00625F51 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
+ INSTALL_PATH_PREFIX = /usr/local;
+ MACOSX_DEPLOYMENT_TARGET = 10.6;
+ NSBUILD_TOOLS_BIN_DIR = "$(NSBUILD_TOOLS_DIR)/bin";
+ NSBUILD_TOOLS_DIR = "$(SRCROOT)/../../build-tools";
+ NSBUILD_TOOLS_SHARE_DIR = "$(NSBUILD_TOOLS_DIR)/share";
+ PRODUCT_NAME = "$(PROJECT_NAME)";
+ PUBLIC_HEADERS_FOLDER_PATH = "$(INSTALL_PATH_PREFIX)/include/$(PRODUCT_NAME)";
+ PUBLIC_HEADERS_FOLDER_PATH_AMD64 = "$(PUBLIC_HEADERS_FOLDER_PATH)/osx-amd64";
+ PUBLIC_HEADERS_FOLDER_PATH_X86 = "$(PUBLIC_HEADERS_FOLDER_PATH)/osx-x86";
+ SDKROOT = macosx;
+ SHARE_FOLDER_PATH = "$(INSTALL_PATH_PREFIX)/include/$(PRODUCT_NAME)";
+ USER_HEADER_SEARCH_PATHS = ".. $(BUILT_PRODUCTS_DIR)$(INSTALL_PATH_PREFIX)/include";
+ };
+ name = Release;
+ };
+ 00B73375151B662700A8251C /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ PUBLIC_HEADERS_DIR = "$(BUILT_PRODUCTS_DIR)$(PUBLIC_HEADERS_FOLDER_PATH)";
+ };
+ name = Debug;
+ };
+ 00B73376151B662700A8251C /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ PUBLIC_HEADERS_DIR = "$(BUILT_PRODUCTS_DIR)$(PUBLIC_HEADERS_FOLDER_PATH)";
+ };
+ name = Release;
+ };
+ 00DC1313150722D0007F9D73 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ };
+ name = Debug;
+ };
+ 00DC1314150722D0007F9D73 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 0088401315054ABD00625F51 /* Build configuration list for PBXProject "metadata" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 0088401B15054ABD00625F51 /* Debug */,
+ 0088401C15054ABD00625F51 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 00B73374151B662700A8251C /* Build configuration list for PBXLegacyTarget "metadata-cleanup" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 00B73375151B662700A8251C /* Debug */,
+ 00B73376151B662700A8251C /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 00DC1312150722D0007F9D73 /* Build configuration list for PBXAggregateTarget "metadata" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 00DC1313150722D0007F9D73 /* Debug */,
+ 00DC1314150722D0007F9D73 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 0088401015054ABD00625F51 /* Project object */;
+}
diff --git a/Src/replicant/metadata/metadata.xcodeproj/xcshareddata/xcschemes/metadata.xcscheme b/Src/replicant/metadata/metadata.xcodeproj/xcshareddata/xcschemes/metadata.xcscheme
new file mode 100644
index 00000000..94865816
--- /dev/null
+++ b/Src/replicant/metadata/metadata.xcodeproj/xcshareddata/xcschemes/metadata.xcscheme
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Scheme
+ LastUpgradeVersion = "0460"
+ version = "1.3">
+ <BuildAction
+ parallelizeBuildables = "YES"
+ buildImplicitDependencies = "YES">
+ <BuildActionEntries>
+ <BuildActionEntry
+ buildForTesting = "YES"
+ buildForRunning = "YES"
+ buildForProfiling = "YES"
+ buildForArchiving = "YES"
+ buildForAnalyzing = "YES">
+ <BuildableReference
+ BuildableIdentifier = "primary"
+ BlueprintIdentifier = "00DC1311150722D0007F9D73"
+ BuildableName = "metadata"
+ BlueprintName = "metadata"
+ ReferencedContainer = "container:metadata.xcodeproj">
+ </BuildableReference>
+ </BuildActionEntry>
+ </BuildActionEntries>
+ </BuildAction>
+ <TestAction
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+ shouldUseLaunchSchemeArgsEnv = "YES"
+ buildConfiguration = "Debug">
+ <Testables>
+ </Testables>
+ </TestAction>
+ <LaunchAction
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+ launchStyle = "0"
+ useCustomWorkingDirectory = "NO"
+ buildConfiguration = "Debug"
+ ignoresPersistentStateOnLaunch = "NO"
+ debugDocumentVersioning = "YES"
+ allowLocationSimulation = "YES">
+ <AdditionalOptions>
+ </AdditionalOptions>
+ </LaunchAction>
+ <ProfileAction
+ shouldUseLaunchSchemeArgsEnv = "YES"
+ savedToolIdentifier = ""
+ useCustomWorkingDirectory = "NO"
+ buildConfiguration = "Release"
+ debugDocumentVersioning = "YES">
+ </ProfileAction>
+ <AnalyzeAction
+ buildConfiguration = "Debug">
+ </AnalyzeAction>
+ <ArchiveAction
+ buildConfiguration = "Release"
+ revealArchiveInOrganizer = "YES">
+ </ArchiveAction>
+</Scheme>
diff --git a/Src/replicant/metadata/svc_metadata.h b/Src/replicant/metadata/svc_metadata.h
new file mode 100644
index 00000000..d3a0dace
--- /dev/null
+++ b/Src/replicant/metadata/svc_metadata.h
@@ -0,0 +1,65 @@
+#pragma once
+#include "foundation/foundation.h"
+#include "ifc_metadata.h"
+#include "ifc_metadata_editor.h"
+#include "nx/nxuri.h"
+
+// {7DBF780E-78B6-436C-A188-864AF6859D87}
+static const GUID metadata_service_type_guid =
+{ 0x7dbf780e, 0x78b6, 0x436c, { 0xa1, 0x88, 0x86, 0x4a, 0xf6, 0x85, 0x9d, 0x87 } };
+
+class svc_metadata : public Wasabi2::Dispatchable
+{
+protected:
+ svc_metadata() : Dispatchable(DISPATCHABLE_VERSION) {}
+ ~svc_metadata() {}
+public:
+ static GUID GetServiceType() { return metadata_service_type_guid; }
+ // to make the implementation more flexible, you need to NXStringRelease on the extension you get (i.e. this function follows Apple's "Create" rule)
+ int EnumerateExtensions(unsigned int index, nx_string_t *extension) { return MetadataService_EnumerateExtensions(index, extension); }
+
+ int CreateMetadata(nx_uri_t filename, ifc_metadata **metadata) {return MetadataService_CreateMetadata(filename, metadata); }
+ int CreateMetadataEditor(nx_uri_t filename, ifc_metadata_editor **metadata) { return MetadataService_CreateMetadataEditor(filename, metadata); }
+
+ int DeserializeMetadata(nx_data_t data, ifc_metadata **metadata) { return MetadataService_DeserializeMetadata(data, metadata); }
+
+ int CreateMetadata(unsigned int pass, nx_uri_t filename, ifc_metadata **metadata)
+ {
+ if (dispatchable_version == 0)
+ {
+ if (pass == 0)
+ return MetadataService_CreateMetadata(filename, metadata);
+ else
+ return NErr_False;
+ }
+ else
+ return MetadataService_CreateMetadata(pass, filename, metadata);
+ }
+ int CreateMetadataEditor(unsigned int pass, nx_uri_t filename, ifc_metadata_editor **metadata)
+ {
+ if (dispatchable_version == 0)
+ {
+ if (pass == 0)
+ return MetadataService_CreateMetadataEditor(filename, metadata);
+ else
+ return NErr_False;
+ }
+ else
+ return MetadataService_CreateMetadataEditor(pass, filename, metadata);
+ }
+ enum
+ {
+ DISPATCHABLE_VERSION=1,
+ };
+private:
+ // implementation note: to make the implementation more flexible, you need to NXStringRetain on the extension you pass back (i.e. follow Apple's "Create" rule)
+ virtual int WASABICALL MetadataService_EnumerateExtensions(unsigned int index, nx_string_t *extension)=0;
+
+ /* these two no longer have to be implemented */
+ virtual int WASABICALL MetadataService_CreateMetadata(nx_uri_t filename, ifc_metadata **metadata) { return MetadataService_CreateMetadata(0, filename, metadata); }
+ virtual int WASABICALL MetadataService_CreateMetadataEditor(nx_uri_t filename, ifc_metadata_editor **metadata) { return MetadataService_CreateMetadataEditor(0, filename, metadata); }
+
+ virtual int WASABICALL MetadataService_DeserializeMetadata(nx_data_t data, ifc_metadata **metadata) { return NErr_NotImplemented; }
+ virtual int WASABICALL MetadataService_CreateMetadata(unsigned int pass, nx_uri_t filename, ifc_metadata **metadata)=0;
+ virtual int WASABICALL MetadataService_CreateMetadataEditor(unsigned int pass, nx_uri_t filename, ifc_metadata_editor **metadata)=0;
+};
diff --git a/Src/replicant/metadata/types.h b/Src/replicant/metadata/types.h
new file mode 100644
index 00000000..fe26eb71
--- /dev/null
+++ b/Src/replicant/metadata/types.h
@@ -0,0 +1,34 @@
+#pragma once
+#include "foundation/types.h"
+#include "nx/nxdata.h"
+
+typedef int data_flags_t;
+enum
+{
+ DATA_FLAG_NONE=0,
+ DATA_FLAG_DATA=(1<<0),
+ DATA_FLAG_SOURCE_INFORMATION=(1<<1),
+ DATA_FLAG_MIME=(1<<2),
+ DATA_FLAG_DESCRIPTION=(1<<3),
+ DATA_FLAG_ALL=DATA_FLAG_DATA|DATA_FLAG_SOURCE_INFORMATION|DATA_FLAG_MIME|DATA_FLAG_DESCRIPTION,
+};
+
+class artwork_t
+{
+public:
+ artwork_t()
+ {
+ data=0;
+ width=0;
+ height=0;
+ }
+
+ ~artwork_t()
+ {
+ NXDataRelease(data);
+ }
+
+ nx_data_t data;
+ uint32_t width;
+ uint32_t height;
+};