mirror of
https://github.com/WinampDesktop/winamp.git
synced 2024-09-24 15:54:12 +00:00
253 lines
5.7 KiB
C++
253 lines
5.7 KiB
C++
|
#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;
|