diff options
Diffstat (limited to 'Src/Agave/Metadata')
-rw-r--r-- | Src/Agave/Metadata/api_metadata.cpp | 1 | ||||
-rw-r--r-- | Src/Agave/Metadata/api_metadata.h | 102 | ||||
-rw-r--r-- | Src/Agave/Metadata/ifc_metadataReader.h | 107 | ||||
-rw-r--r-- | Src/Agave/Metadata/svc_metatag.h | 152 |
4 files changed, 362 insertions, 0 deletions
diff --git a/Src/Agave/Metadata/api_metadata.cpp b/Src/Agave/Metadata/api_metadata.cpp new file mode 100644 index 00000000..1eedadb9 --- /dev/null +++ b/Src/Agave/Metadata/api_metadata.cpp @@ -0,0 +1 @@ +#include "api_metadata.h"
\ No newline at end of file diff --git a/Src/Agave/Metadata/api_metadata.h b/Src/Agave/Metadata/api_metadata.h new file mode 100644 index 00000000..da3c2145 --- /dev/null +++ b/Src/Agave/Metadata/api_metadata.h @@ -0,0 +1,102 @@ +#ifndef NULLSOFT_AGAVE_METADATA_API_METADATA_H +#define NULLSOFT_AGAVE_METADATA_API_METADATA_H + +/** + ** Author: Ben Allison + ** original date: April 10, 2006 + */ +#include <bfc/dispatch.h> +#include "svc_metatag.h" + + +class api_metadata : public Dispatchable +{ +protected: + api_metadata() {} + ~api_metadata() {} + +public: + // replacement for IPC_GET_EXTENDED_FILE_INFO, it's slow, so only use for converting old code, or one-off metadata grabbing + int GetExtendedFileInfo(const wchar_t *filename, const wchar_t *tag, wchar_t *data, size_t dataLength); + + // replacement for IPC_SET_EXTENDED_FILE_INFO + int SetExtendedFileInfo(const wchar_t *filename, const wchar_t *tag, const wchar_t *data); + int WriteExtendedFileInfo(const wchar_t *filename); + + /** faster methods below. these return you an object that you can keep re-using (for a single file) + ** it's still your job to call svc_metaTag::metaTag_open() - see note [2] + ** call svc_metaTag::close() when you're done - see note [3] + */ + svc_metaTag *GetMetaTagObject(const wchar_t *filename, int flags=METATAG_ALL, GUID *exclude=0, int numExcludes=0); // see note [1] + svc_metaTag *GetMetaTagObject(const GUID metaTagGuid); // gets a specific svc_metaTag object by GUID + + /** + ** Retrieves a unique key for a given field name + ** if one already exists, that index is returned + ** returns -1 on failure/not implemented + **/ + uint32_t GenerateKey(const wchar_t *field); + + + DISPATCH_CODES + { + API_METADATA_GETEXTENDEDFILEINFO = 10, + API_METADATA_SETEXTENDEDFILEINFO = 11, + API_METADATA_WRITEEXTENDEDFILEINFO = 12, + API_METADATA_GETMETATAGOBJECT = 20, + API_METADATA_GETMETATAGOBJECTBYGUID = 30, + API_METADATA_GENERATEKEY = 40, + }; +}; + +/** + ** [1] flags can be set to only use certain metadata providers, file info, database, online lookup (CDDB, etc), guessing + ** exclude list can be use to exclude certain metatag GUIDs. This is useful for metadata services that need to look up metadata themselves + ** e.g. CDDB might need to get a Disc ID, media library wants to ask for info to fill itself in. Neither services wants to have themselves + ** be asked, and might not want a "guessing" metatag provider to be used, either. + ** [2] these methods could technically open the file also, but we've left that out to allow for some flexibility + ** e.g. someone might just be looking for the metaTag service name or GUID. + ** [3] you need to close it even if you never opened it. This allows the object to "self-destruct". + ** If we didn't do this, we would also have to pass back the service factory + ** + */ + +inline int api_metadata::GetExtendedFileInfo(const wchar_t *filename, const wchar_t *tag, wchar_t *data, size_t dataLength) +{ + return _call(API_METADATA_GETEXTENDEDFILEINFO, (int)0, filename, tag, data, dataLength); +} + +inline int api_metadata::SetExtendedFileInfo(const wchar_t *filename, const wchar_t *tag, const wchar_t *data) +{ + return _call(API_METADATA_SETEXTENDEDFILEINFO, (int)0, filename, tag, data); +} + +inline int api_metadata::WriteExtendedFileInfo(const wchar_t *filename) +{ + return _call(API_METADATA_WRITEEXTENDEDFILEINFO, (int)0, filename); +} + + +inline svc_metaTag *api_metadata::GetMetaTagObject(const wchar_t *filename, int flags, GUID *exclude, int numExcludes) +{ + return _call(API_METADATA_GETMETATAGOBJECT, (svc_metaTag *)NULL, filename, flags, exclude, numExcludes); +} + +inline svc_metaTag *api_metadata::GetMetaTagObject(const GUID metaTagGuid) +{ + return _call(API_METADATA_GETMETATAGOBJECTBYGUID, (svc_metaTag *)NULL, metaTagGuid); +} + +#pragma warning(push) +#pragma warning(disable : 4267) +inline uint32_t api_metadata::GenerateKey(const wchar_t *field) +{ + return _call(API_METADATA_GENERATEKEY, (uint32_t)-1); +} +#pragma warning(pop) + +// {DFA89F63-995A-407b-8BC8-827900440727} +static const GUID api_metadataGUID = +{ 0xdfa89f63, 0x995a, 0x407b, { 0x8b, 0xc8, 0x82, 0x79, 0x0, 0x44, 0x7, 0x27 } }; + +#endif diff --git a/Src/Agave/Metadata/ifc_metadataReader.h b/Src/Agave/Metadata/ifc_metadataReader.h new file mode 100644 index 00000000..16749795 --- /dev/null +++ b/Src/Agave/Metadata/ifc_metadataReader.h @@ -0,0 +1,107 @@ +#ifndef NULLSOFT_AGAVE_METADATA_IFC_METADATAREADER_H +#define NULLSOFT_AGAVE_METADATA_IFC_METADATAREADER_H + +#include <bfc/dispatch.h> + +class ifc_metadataReader : public Dispatchable +{ +protected: + ifc_metadataReader() + {} + ~ifc_metadataReader() + {} +public: + /* If there are multiple values for the same field, these functions will concatenate the values in some + manner as defined by the language pack */ + int GetField( const wchar_t *field, wchar_t *destination, size_t destinationCch ); + int GetFieldByKey( uint32_t field_key, wchar_t *destination, size_t destinationCch ); + + int GetIndexedField( const wchar_t *field, uint32_t index, wchar_t *destination, size_t destinationCch ); + int GetIndexedFieldByKey( uint32_t field_key, uint32_t index, wchar_t *destination, size_t destinationCch ); + + class ifc_fieldEnumerator : public Dispatchable + { + protected: + ifc_fieldEnumerator(); + ~ifc_fieldEnumerator(); + + public: + const wchar_t *GetField(); + uint32_t GetKey(); + int Next(); + + DISPATCH_CODES + { + DISP_GETFIELD = 0, + DISP_GETKEY = 1, + DISP_NEXT = 2, + }; + + }; + + enum + { + ENUMERATORFLAG_MULTIPLE_FIELDS = 0, // if multiple values of the same field are present, return each one + ENUMERATORFLAG_REMOVE_DUPLICATE_FIELDS = 1, // don't enumerate duplicate fields (with differing values) + }; + + ifc_fieldEnumerator *GetFieldEnumerator( int flags = ENUMERATORFLAG_MULTIPLE_FIELDS ); // Enumerate fields present in this file + + DISPATCH_CODES + { + DISP_GETFIELD = 0, + DISP_GETFIELDKEY = 1, + DISP_GETINDEXEDFIELD = 2, + DISP_GETINDEXEDFIELDBYKEY = 3, + DISP_GETFIELDENUMERATOR = 4, + }; + + enum + { + NOT_IMPLEMENTED = -1, + SUCCESS = 0, + FAILURE = 1, + END_OF_ITERATOR = 2, + }; +}; + +inline int ifc_metadataReader::GetField(const wchar_t *field, wchar_t *destination, size_t destinationCch) +{ + return _call(DISP_GETFIELD, (int)ifc_metadataReader::NOT_IMPLEMENTED, field, destination, destinationCch); +} + +inline int ifc_metadataReader::GetFieldByKey(uint32_t field_key, wchar_t *destination, size_t destinationCch) +{ + return _call(DISP_GETFIELDKEY, (int)ifc_metadataReader::NOT_IMPLEMENTED, field_key, destination, destinationCch); +} + +inline int ifc_metadataReader::GetIndexedField(const wchar_t *field, uint32_t index, wchar_t *destination, size_t destinationCch) +{ + return _call(DISP_GETINDEXEDFIELD, (int)ifc_metadataReader::NOT_IMPLEMENTED, field, index, destination, destinationCch); +} + +inline int ifc_metadataReader::GetIndexedFieldByKey(uint32_t field_key, uint32_t index, wchar_t *destination, size_t destinationCch) +{ + return _call(DISP_GETINDEXEDFIELDBYKEY, (int)ifc_metadataReader::NOT_IMPLEMENTED, field_key, index, destination, destinationCch); +} + +inline ifc_metadataReader::ifc_fieldEnumerator *ifc_metadataReader::GetFieldEnumerator(int flags) +{ + return _call(DISP_GETFIELDENUMERATOR, (ifc_metadataReader::ifc_fieldEnumerator *)0, flags); +} + +inline const wchar_t *ifc_metadataReader::ifc_fieldEnumerator::GetField() +{ + return _call(DISP_NEXT, (const wchar_t *)0); +} + +inline uint32_t ifc_metadataReader::ifc_fieldEnumerator::GetKey() +{ + return _call(DISP_NEXT, (int)ifc_metadataReader::NOT_IMPLEMENTED); +} + +inline int ifc_metadataReader::ifc_fieldEnumerator::Next() +{ + return _call(DISP_NEXT, (int)END_OF_ITERATOR); +} +#endif
\ No newline at end of file diff --git a/Src/Agave/Metadata/svc_metatag.h b/Src/Agave/Metadata/svc_metatag.h new file mode 100644 index 00000000..0f633926 --- /dev/null +++ b/Src/Agave/Metadata/svc_metatag.h @@ -0,0 +1,152 @@ +#ifndef NULLSOFT_AGAVE_SVC_METATAG_H +#define NULLSOFT_AGAVE_SVC_METATAG_H + +/** + ** Author: Ben Allison + ** original date: April 10, 2006 + */ +#include <bfc/dispatch.h> +#include <api/service/services.h> +#include <bfc/platform/types.h> +#include <bfc/std_mkncc.h> // for MKnCC() + +/* these two GUIDs are to allow you to QueryInterface between readers and writers */ +// {9FD00FBE-B707-4743-B630-CC14071EA443} +static const GUID AgaveMetadataReaderIID = +{ 0x9fd00fbe, 0xb707, 0x4743, { 0xb6, 0x30, 0xcc, 0x14, 0x7, 0x1e, 0xa4, 0x43 } }; + +// {3444E4AD-D6B3-4ac4-A08D-C3F935DC7B98} +static const GUID AgaveMetadataWriterIID = +{ 0x3444e4ad, 0xd6b3, 0x4ac4, { 0xa0, 0x8d, 0xc3, 0xf9, 0x35, 0xdc, 0x7b, 0x98 } }; + +enum +{ + METATAG_SUCCESS = 0, + METATAG_FAILED = 1, + + METATAG_UNKNOWN_TAG = 2, // the tag name isn't understood + METATAG_NO_METADATA = 3, // returned if the file has no metadata at all + METATAG_NOT_APPLICABLE = 4, + +}; + +enum +{ + METATYPE_STRING = 0, // always unicode! and always null terminated + METATYPE_FILENAME = 0, + METATYPE_INTEGER = 1, + METATYPE_UNSIGNED = 2, + METATYPE_SIZE = 2, + METATYPE_GUID = 3, + METATYPE_BINARY = 4, +}; + +// flags +enum +{ + METATAG_FILE_INFO = 0x1, + METATAG_ONLINE_LOOKUP = 0x2, + METATAG_CACHE_DB = 0x4, + METATAG_GUESS = 0x8, + METATAG_ALL = 0xFFFFFFFF +}; + +class svc_metaTag : public Dispatchable +{ +protected: + svc_metaTag() {} + ~svc_metaTag() {} + +public: + /* These methods are to be used by api_metadata */ + static FOURCC getServiceType() { return svc_metaTag::SERVICETYPE; } + const wchar_t *getName(); // i.e. "ID3v2" or something + GUID getGUID(); // this needs to be the same GUID that you use when registering your service factory + int getFlags(); // how this service gets its info + int isOurFile(const wchar_t *filename); + int metaTag_open(const wchar_t *filename); + void metaTag_close(); // self-destructs when this is called (you don't need to call serviceFactory->releaseInterface) + + /* user API starts here */ + const wchar_t *enumSupportedTag(int n, int *datatype = NULL); // returns a list of understood tags. might not be complete (see note [1]) + int getTagSize(const wchar_t *tag, size_t *sizeBytes); // always gives you BYTES, not characters (be careful with your strings) + int getMetaData(const wchar_t *tag, uint8_t *buf, int buflenBytes, int datatype = METATYPE_STRING); // buflen is BYTES, not characters (be careful with your strings) + int setMetaData(const wchar_t *tag, const uint8_t *buf, int buflenBytes, int datatype = METATYPE_STRING); +public: + DISPATCH_CODES + { + SVC_METATAG_GETNAME = 10, + SVC_METATAG_GETGUID = 20, + SVC_METATAG_GETFLAGS = 30, + SVC_METATAG_ISOURFILE = 40, + SVC_METATAG_OPEN = 50, + SVC_METATAG_CLOSE = 60, + SVC_METATAG_ENUMTAGS = 100, + SVC_METATAG_GETTAGSIZE = 110, + SVC_METATAG_GETMETADATA = 120, + SVC_METATAG_SETMETADATA = 130, + + }; + enum + { + SERVICETYPE = MK4CC('m','t','t','g') + }; +}; + +/** Notes: + ** [1] Many metadata getters rely on an underlying library, and some metadata systems (e.g. Vorbis) are open-ended. As a result, there might be no way of + ** generating a complete list +*/ + +inline const wchar_t *svc_metaTag::getName() +{ + return _call(SVC_METATAG_GETNAME, (const wchar_t*)NULL); +} + +inline GUID svc_metaTag::getGUID() +{ + return _call(SVC_METATAG_GETGUID, GUID_NULL); +} + +inline int svc_metaTag::getFlags() +{ + return _call(SVC_METATAG_GETFLAGS, 0); +} + +inline int svc_metaTag::isOurFile(const wchar_t *filename) +{ + return _call(SVC_METATAG_ISOURFILE, (int)0, filename); +} + +inline int svc_metaTag::metaTag_open(const wchar_t *filename) +{ + return _call(SVC_METATAG_OPEN, (int)METATAG_FAILED, filename); +} + +inline void svc_metaTag::metaTag_close() +{ + _voidcall(SVC_METATAG_CLOSE); +} + +inline const wchar_t *svc_metaTag::enumSupportedTag(int n, int *datatype) +{ + return _call(SVC_METATAG_ENUMTAGS, (const wchar_t *)NULL, n, datatype); +} + +inline int svc_metaTag::getTagSize(const wchar_t *tag, size_t *sizeBytes) +{ + return _call(SVC_METATAG_GETTAGSIZE, (int)0, tag, sizeBytes); +} + +inline int svc_metaTag::getMetaData(const wchar_t *tag, uint8_t *buf, int buflenBytes, int datatype) +{ + return _call(SVC_METATAG_GETMETADATA, (int)METATAG_FAILED, tag, buf, buflenBytes, datatype); +} + +inline int svc_metaTag::setMetaData(const wchar_t *tag, const uint8_t *buf, int buflenBytes, int datatype) +{ + return _call(SVC_METATAG_SETMETADATA, (int)METATAG_FAILED, tag, buf, buflenBytes, datatype); +} + + +#endif |