123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343 |
- /** (c) Nullsoft, Inc. C O N F I D E N T I A L
- ** Filename:
- ** Project:
- ** Description:
- ** Author: Ben Allison [email protected]
- ** Created:
- **/
- #include "main.h"
- #include "tagz.h"
- #include "../tagz/ifc_tagprovider.h"
- #include "../tagz/ifc_tagparams.h"
- #include "api.h"
- #include "TagProvider.h"
- #include "../nu/AutoWide.h"
- #include "../nu/AutoChar.h"
- #include "../nu/ns_wc.h"
- extern "C"
- {
- typedef char * (*GetTagFunc)(const char * tag, void * p);
- typedef void (*FreeTagFunc)(char * tag,void * p);
- typedef wchar_t * (*GetTagFuncW)(const wchar_t * tag, void * p);
- typedef void (*FreeTagFuncW)(wchar_t * tag,void * p);
- }
- class TagParameters : public ifc_tagparams
- {
- public:
- TagParameters(const wchar_t *_filename) :filename(_filename){}
- void *GetParameter(const GUID *parameterID)
- {
- if (*parameterID == filenameParameterID)
- return (void *)filename;
- return 0;
- }
- protected:
- RECVS_DISPATCH;
- private:
- const wchar_t *filename;
- };
- class ExternalTagProvider : public ifc_tagprovider
- {
- public:
- ExternalTagProvider(GetTagFunc getter, FreeTagFunc freer, void *context);
- wchar_t *GetTag(const wchar_t *name, ifc_tagparams *parameters);
- void FreeTag(wchar_t *Tag);
- protected:
- RECVS_DISPATCH;
- private:
- GetTagFunc externalGetTag;
- FreeTagFunc externalFreeTag;
- void *externalContext;
- };
- class ExtendedTagProvider : public ifc_tagprovider
- {
- public:
- ExtendedTagProvider(const wchar_t *_filename, GetTagFuncW getter, FreeTagFuncW freer, void *context, bool _useExtendedInfo);
- wchar_t *GetTag(const wchar_t *name, ifc_tagparams *parameters);
- void FreeTag(char *Tag);
- protected:
- RECVS_DISPATCH;
- private:
- GetTagFuncW externalGetTag;
- FreeTagFuncW externalFreeTag;
- void *externalContext;
- const wchar_t *filename;
- bool useExtendedInfo;
- };
- static void CleanupTitle(char *title)
- {
- while (title && *title)
- {
- if (*title == '\n' || *title == '\r')
- *title = ' ';
- title = CharNextA(title);
- }
- }
- static void CleanupTitleW(wchar_t *title)
- {
- while (title && *title)
- {
- if (*title == L'\n' || *title == L'\r')
- *title = L' ';
- title = CharNextW(title);
- }
- }
- void FormatTitle(waFormatTitle *format)
- {
- AutoWide wideSpec(format->spec);
- wchar_t *spec = (format->spec ? wideSpec : config_titlefmt);
- if (format->out && format->out_len)
- {
- memset(format->out, 0, format->out_len);
- if (WINAMP5_API_TAGZ)
- {
- if (format->TAGFUNC)
- {
- ExternalTagProvider provider(format->TAGFUNC, format->TAGFREEFUNC, format->p);
- wchar_t *tempOut = (wchar_t *)calloc(format->out_len, sizeof(wchar_t));
- if (tempOut)
- {
- WINAMP5_API_TAGZ->format(spec, tempOut, format->out_len, &provider, 0 /*¶meters*/);
- WideCharToMultiByteSZ(CP_ACP, 0, tempOut, -1, format->out, format->out_len, 0, 0);
- free(tempOut);
- }
- }
- else
- {
- AutoWide wideFn((char *)format->p); // we'd better hope it's the filename!
- TagParameters parameters(wideFn);
- wchar_t *tempOut = (wchar_t *)calloc(format->out_len, sizeof(wchar_t));
- if (tempOut)
- {
- WINAMP5_API_TAGZ->format(spec, tempOut, format->out_len, tagProvider, ¶meters);
- WideCharToMultiByteSZ(CP_ACP, 0, tempOut, -1, format->out, format->out_len, 0, 0);
- free(tempOut);
- }
- }
- CleanupTitle(format->out);
- }
- }
- }
- void FormatTitleExtended(waFormatTitleExtended *format)
- {
- if (!format->filename || format->filename && !*format->filename) return;
- const wchar_t *spec = (format->spec ? format->spec : config_titlefmt);
- if (format->out && format->out_len)
- {
- if (WINAMP5_API_TAGZ)
- {
- ExtendedTagProvider provider(format->filename, format->TAGFUNC, format->TAGFREEFUNC, format->p, !!format->useExtendedInfo);
- WINAMP5_API_TAGZ->format(spec, format->out, format->out_len, &provider, 0 /*¶meters*/);
- CleanupTitleW(format->out);
- }
- else
- {
- lstrcpynW(format->out, format->filename, format->out_len);
- PathStripPathW(format->out);
- }
- }
- }
- int FormatTitle(waHookTitleStructW *hts)
- {
- if (hts && hts->title &&
- ((hts->force_useformatting&1) || !(PathIsURLW(hts->filename) && StrCmpNIW(hts->filename, L"cda://", 6))))
- {
- wchar_t buf[32] = {0};
- wchar_t buf2[32] = {0};
- hts->length = -1;
- hts->title[0] = 0;
- if (in_get_extended_fileinfoW(hts->filename, L"length", buf, 32) ||
- in_get_extended_fileinfoW(hts->filename, L"type", buf2, 32))
- {
- hts->length = StrToIntW(buf);
- if (hts->length <= 0)
- hts->length = -1;
- else
- hts->length /= 1000;
- if (WINAMP5_API_TAGZ)
- {
- TagParameters parameters(hts->filename);
- WINAMP5_API_TAGZ->format(config_titlefmt, hts->title, 2048, tagProvider, ¶meters);
- }
- CleanupTitleW(hts->title);
- if (hts->title[0]) return 1;
- }
- }
- return 0;
- }
- namespace Winamp
- {
- /* our tag getting functions */
- wchar_t *GetTag(const wchar_t *tag, const wchar_t *filename) // for simple tags
- {
- if (!_wcsicmp(tag, L"filename"))
- return _wcsdup(filename);
- else if (!_wcsicmp(tag, L"folder"))
- {
- wchar_t *folder = (wchar_t *)calloc(MAX_PATH, sizeof(wchar_t));
- if (folder)
- {
- lstrcpynW(folder, filename, MAX_PATH);
- PathRemoveFileSpecW(folder);
- PathRemoveBackslashW(folder);
- PathStripPathW(folder);
- return folder;
- }
- }
- return 0;
- }
- wchar_t *GetExtendedTag(const wchar_t *tag, const wchar_t *filename) //return 0 if not found
- {
- wchar_t buf[1024] = {0};
- if (!_wcsicmp(tag, L"tracknumber"))
- tag = L"track";
- #if 0
- if (in_get_extended_fileinfo(filename, tag, buf, sizeof(buf)) && buf[0])
- return _strdup(buf);
- #else
- extendedFileInfoStructW s = {filename, tag, buf, 1024};
- if (SendMessageW(hMainWindow, WM_WA_IPC, (WPARAM)&s, IPC_GET_EXTENDED_FILE_INFOW_HOOKABLE) && buf[0])
- return _wcsdup(buf);
- #endif
- return 0;
- }
- } // namespace Winamp
- /* --- ExternalTagProvider ---
- maybe we'll move this to a separate file once it's done
- */
- ExternalTagProvider::ExternalTagProvider(GetTagFunc getter, FreeTagFunc freer, void *context)
- : externalGetTag(getter), externalFreeTag(freer), externalContext(context)
- {
- }
- wchar_t *ExternalTagProvider::GetTag(const wchar_t *name, ifc_tagparams *parameters)
- {
- if (externalGetTag)
- {
- char *tag = externalGetTag(AutoChar(name), externalContext);
- if (tag == reinterpret_cast<char *>(-1))
- return 0;
- int size = MultiByteToWideChar(CP_ACP, 0, tag, -1, 0, 0);
- if (!size)
- {
- if (externalFreeTag)
- externalFreeTag(tag, externalContext);
- return 0;
- }
- wchar_t *wide = (wchar_t *)calloc(size, sizeof(wchar_t));
- if (!MultiByteToWideChar(CP_ACP, 0, tag, -1, wide, size))
- {
- if (wide) free(wide);
- if (externalFreeTag)
- externalFreeTag(tag, externalContext);
- return 0;
- }
- if (externalFreeTag)
- externalFreeTag(tag, externalContext);
- return wide;
- }
- return 0;
- }
- void ExternalTagProvider::FreeTag(wchar_t *tag)
- {
- if (tag) free(tag);
- }
- #ifdef CBCLASS
- #undef CBCLASS
- #endif
- #define CBCLASS ExternalTagProvider
- START_DISPATCH;
- CB(IFC_TAGPROVIDER_GET_TAG, GetTag);
- VCB(IFC_TAGPROVIDER_FREE_TAG, FreeTag);
- END_DISPATCH;
- #undef CBCLASS
- /* --- ExtendedTagProvider ---
- maybe we'll move this to a separate file once it's done
- */
- ExtendedTagProvider::ExtendedTagProvider(const wchar_t *_filename, GetTagFuncW getter, FreeTagFuncW freer, void *context, bool _useExtendedInfo)
- : externalGetTag(getter), externalFreeTag(freer), externalContext(context), filename(_filename), useExtendedInfo(_useExtendedInfo)
- {
- }
- wchar_t *ExtendedTagProvider::GetTag(const wchar_t *name, ifc_tagparams *parameters)
- {
- wchar_t *tag=0;
- if (externalGetTag)
- tag=externalGetTag(name, externalContext);
- if (tag) // if we got a tag, we'll need to make a copy, because we won't be able to tell where it came from when it's time to free it
- {
- if (tag == reinterpret_cast<wchar_t *>(-1))
- return 0;
- wchar_t *temp = *tag?_wcsdup(tag):0;
- if (externalFreeTag)
- externalFreeTag(tag, externalContext);
- return temp;
- }
- else
- {
- tag = Winamp::GetTag(name, filename);
- if (tag == reinterpret_cast<wchar_t *>(-1))
- return 0;
- if (!tag && useExtendedInfo)
- tag = Winamp::GetExtendedTag(name, filename);
- if (tag == reinterpret_cast<wchar_t *>(-1))
- return 0;
- return tag;
- }
- }
- void ExtendedTagProvider::FreeTag(char *tag)
- {
- if (tag) free(tag);
- }
- #ifdef CBCLASS
- #undef CBCLASS
- #endif
- #define CBCLASS ExtendedTagProvider
- START_DISPATCH;
- CB(IFC_TAGPROVIDER_GET_TAG, GetTag);
- VCB(IFC_TAGPROVIDER_FREE_TAG, FreeTag);
- END_DISPATCH;
- #undef CBCLASS
- #ifdef CBCLASS
- #undef CBCLASS
- #endif
- #define CBCLASS TagParameters
- START_DISPATCH;
- CB(IFC_TAGPARAMS_GETPARAMETER, GetParameter);
- END_DISPATCH;
- #undef CBCLASS
|