aboutsummaryrefslogtreecommitdiff
path: root/Src/playlist/B4SLoader.cpp
diff options
context:
space:
mode:
authorJean-Francois Mauguit <jfmauguit@mac.com>2024-09-24 09:03:25 -0400
committerGitHub <noreply@github.com>2024-09-24 09:03:25 -0400
commitbab614c421ed7ae329d26bf028c4a3b1d2450f5a (patch)
tree12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/playlist/B4SLoader.cpp
parent4bde6044fddf053f31795b9eaccdd2a5a527d21f (diff)
parent20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (diff)
downloadwinamp-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.cpp253
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