diff options
author | Jean-Francois Mauguit <jfmauguit@mac.com> | 2024-09-24 09:03:25 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-09-24 09:03:25 -0400 |
commit | bab614c421ed7ae329d26bf028c4a3b1d2450f5a (patch) | |
tree | 12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/playlist/B4SLoader.cpp | |
parent | 4bde6044fddf053f31795b9eaccdd2a5a527d21f (diff) | |
parent | 20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (diff) | |
download | winamp-bab614c421ed7ae329d26bf028c4a3b1d2450f5a.tar.gz |
Merge pull request #5 from WinampDesktop/community
Merge to main
Diffstat (limited to 'Src/playlist/B4SLoader.cpp')
-rw-r--r-- | Src/playlist/B4SLoader.cpp | 253 |
1 files changed, 253 insertions, 0 deletions
diff --git a/Src/playlist/B4SLoader.cpp b/Src/playlist/B4SLoader.cpp new file mode 100644 index 00000000..735cdfe8 --- /dev/null +++ b/Src/playlist/B4SLoader.cpp @@ -0,0 +1,253 @@ +#include "main.h" +#include "B4SLoader.h" +#include "../nu/AutoChar.h" +#include "..\Components\wac_network\wac_network_http_receiver_api.h" +#include <strsafe.h> + +B4SLoader::B4SLoader() : parser(0), parserFactory(0) +{ + parserFactory = WASABI_API_SVC->service_getServiceByGuid(obj_xmlGUID); + if (parserFactory) + parser = (obj_xml *)parserFactory->getInterface(); + + if (parser) + { + parser->xmlreader_registerCallback(L"WasabiXML\fplaylist\fentry\fname", &b4sXml.title); + parser->xmlreader_registerCallback(L"WinampXML\fplaylist\fentry\fname", &b4sXml.title); + + parser->xmlreader_registerCallback(L"WasabiXML\fplaylist\fentry\flength", &b4sXml.length); + parser->xmlreader_registerCallback(L"WinampXML\fplaylist\fentry\flength", &b4sXml.length); + + //parser->xmlreader_registerCallback(L"WasabiXML\fplaylist", this); + //parser->xmlreader_registerCallback(L"WinampXML\fplaylist", this); + parser->xmlreader_registerCallback(L"WasabiXML\fplaylist\fentry", &b4sXml); + parser->xmlreader_registerCallback(L"WinampXML\fplaylist\fentry", &b4sXml); + parser->xmlreader_open(); + //parser->xmlreader_setEncoding(L"UTF-8"); + } +} + +B4SXML::B4SXML() +{ + filename[0]=0; + playlist = 0; +} + +B4SLoader::~B4SLoader() +{ + if (parser) + { + parser->xmlreader_unregisterCallback(&b4sXml); + parser->xmlreader_unregisterCallback(&b4sXml.length); + parser->xmlreader_unregisterCallback(&b4sXml.title); + parser->xmlreader_close(); + } + + if (parserFactory && parser) + parserFactory->releaseInterface(parser); + + parserFactory = 0; + parser = 0; +} + +#define HTTP_BUFFER_SIZE 1024 +static int FeedXMLHTTP(api_httpreceiver *http, obj_xml *parser, bool *noData) +{ + char downloadedData[HTTP_BUFFER_SIZE] = {0}; + int xmlResult = API_XML_SUCCESS; + int downloadSize = http->get_bytes(downloadedData, HTTP_BUFFER_SIZE); + if (downloadSize) + { + xmlResult = parser->xmlreader_feed((void *)downloadedData, downloadSize); + *noData=false; + } + else + *noData = true; + + return xmlResult; +} + +static void RunXMLDownload(api_httpreceiver *http, obj_xml *parser) +{ + int ret; + bool noData; + do + { + Sleep(50); + ret = http->run(); + if (FeedXMLHTTP(http, parser, &noData) != API_XML_SUCCESS) + return ; + } + while (ret == HTTPRECEIVER_RUN_OK); + + // finish off the data + do + { + if (FeedXMLHTTP(http, parser, &noData) != API_XML_SUCCESS) + return ; + } while (!noData); + + parser->xmlreader_feed(0, 0); +} + +void B4SXML::StartTag(const wchar_t *xmlpath, const wchar_t *xmltag, ifc_xmlreaderparams *params) +{ + if (!_wcsicmp(xmltag, L"entry")) + { + const wchar_t *track = params->getItemValue(L"playstring"); + if (!_wcsnicmp(track, L"file://", 7)) + track+=7; + else if (!_wcsnicmp(track, L"file:", 5)) + track+=5; + StringCchCopyW(filename, FILENAME_SIZE, track); + } +} + +void B4SXML::EndTag(const wchar_t *xmlpath, const wchar_t *xmltag) +{ + if (!_wcsicmp(xmltag, L"entry") && filename[0]) + { + int lengthSeconds=-1; + const wchar_t *trackLength = length.GetString(); + if (trackLength && *trackLength) + lengthSeconds = _wtoi(trackLength) / 1000; + + const wchar_t *trackTitle = title.GetString(); + // TODO: deal with relative pathnames + if (trackTitle && *trackTitle) + playlist->OnFile(filename, trackTitle, lengthSeconds, 0); // TODO: extended info + else + playlist->OnFile(filename, 0, lengthSeconds, 0);// TODO: extended info + + filename[0]=0; + length.Reset(); + title.Reset(); + } +} +#if 0 // TOOD: reimplement +void B4SLoader::LoadURL(const char *url) +{ + if (!parser) + return ; // no sense in continuing if there's no parser available + + api_httpreceiver *http = 0; + waServiceFactory *sf = WASABI_API_SVC->service_getServiceByGuid(httpreceiverGUID); + if (sf) + http = (api_httpreceiver *)sf->getInterface(); + + if (!http) + return ; + http->AllowCompression(); + http->open(API_DNS_AUTODNS, HTTP_BUFFER_SIZE, GetProxy()); + SetUserAgent(http); + http->connect(url); + int ret; + bool first = true; + + do + { + Sleep(50); + ret = http->run(); + if (ret == -1) // connection failed + break; + + // ---- check our reply code ---- + int replycode = http->GetReplyCode(); + switch (replycode) + { + case 0: + case 100: + break; + case 200: + { + RunXMLDownload(http, parser); + sf->releaseInterface(http); + return ; + } + break; + default: + sf->releaseInterface(http); + return ; + } + } + while (ret == HTTPRECEIVER_RUN_OK); + const char *er = http->geterrorstr(); + sf->releaseInterface(http); + return ; +} + +void B4SLoader::LoadFile(const char *filename) +{ + if (!parser) + return ; // no sense in continuing if there's no parser available + + HANDLE file = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL, NULL); + + if (file == INVALID_HANDLE_VALUE) + return ; + + char data[1024] = {0}; + + while (true) + { + DWORD bytesRead = 0; + if (ReadFile(file, data, 1024, &bytesRead, NULL) && bytesRead) + { + parser->xmlreader_feed(data, bytesRead); + } + else + break; + } + + CloseHandle(file); + parser->xmlreader_feed(0, 0); +} +#endif +int B4SLoader::Load(const wchar_t *filename, ifc_playlistloadercallback *playlist) +{ + if (!parser) + return IFC_PLAYLISTLOADER_FAILED; // no sense in continuing if there's no parser available + + b4sXml.playlist=playlist; + + HANDLE file = CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL, NULL); + + if (file == INVALID_HANDLE_VALUE) + return IFC_PLAYLISTLOADER_FAILED; + + while (true) + { + char data[1024] = {0}; + DWORD bytesRead = 0; + if (ReadFile(file, data, 1024, &bytesRead, NULL) && bytesRead) + { + parser->xmlreader_feed(data, bytesRead); + } + else + break; + } + + CloseHandle(file); + parser->xmlreader_feed(0, 0); + return IFC_PLAYLISTLOADER_SUCCESS; +} + +#ifdef CBCLASS +#undef CBCLASS +#endif + +#define CBCLASS B4SXML +START_DISPATCH; +VCB(ONSTARTELEMENT, StartTag) +VCB(ONENDELEMENT, EndTag) +END_DISPATCH; + +#ifdef CBCLASS +#undef CBCLASS +#endif + +#define CBCLASS B4SLoader +START_DISPATCH; +CB(IFC_PLAYLISTLOADER_LOAD, Load) + +END_DISPATCH;
\ No newline at end of file |