B4SLoader.cpp 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. #include "main.h"
  2. #include "B4SLoader.h"
  3. #include "../nu/AutoChar.h"
  4. #include "..\Components\wac_network\wac_network_http_receiver_api.h"
  5. #include <strsafe.h>
  6. B4SLoader::B4SLoader() : parser(0), parserFactory(0)
  7. {
  8. parserFactory = WASABI_API_SVC->service_getServiceByGuid(obj_xmlGUID);
  9. if (parserFactory)
  10. parser = (obj_xml *)parserFactory->getInterface();
  11. if (parser)
  12. {
  13. parser->xmlreader_registerCallback(L"WasabiXML\fplaylist\fentry\fname", &b4sXml.title);
  14. parser->xmlreader_registerCallback(L"WinampXML\fplaylist\fentry\fname", &b4sXml.title);
  15. parser->xmlreader_registerCallback(L"WasabiXML\fplaylist\fentry\flength", &b4sXml.length);
  16. parser->xmlreader_registerCallback(L"WinampXML\fplaylist\fentry\flength", &b4sXml.length);
  17. //parser->xmlreader_registerCallback(L"WasabiXML\fplaylist", this);
  18. //parser->xmlreader_registerCallback(L"WinampXML\fplaylist", this);
  19. parser->xmlreader_registerCallback(L"WasabiXML\fplaylist\fentry", &b4sXml);
  20. parser->xmlreader_registerCallback(L"WinampXML\fplaylist\fentry", &b4sXml);
  21. parser->xmlreader_open();
  22. //parser->xmlreader_setEncoding(L"UTF-8");
  23. }
  24. }
  25. B4SXML::B4SXML()
  26. {
  27. filename[0]=0;
  28. playlist = 0;
  29. }
  30. B4SLoader::~B4SLoader()
  31. {
  32. if (parser)
  33. {
  34. parser->xmlreader_unregisterCallback(&b4sXml);
  35. parser->xmlreader_unregisterCallback(&b4sXml.length);
  36. parser->xmlreader_unregisterCallback(&b4sXml.title);
  37. parser->xmlreader_close();
  38. }
  39. if (parserFactory && parser)
  40. parserFactory->releaseInterface(parser);
  41. parserFactory = 0;
  42. parser = 0;
  43. }
  44. #define HTTP_BUFFER_SIZE 1024
  45. static int FeedXMLHTTP(api_httpreceiver *http, obj_xml *parser, bool *noData)
  46. {
  47. char downloadedData[HTTP_BUFFER_SIZE] = {0};
  48. int xmlResult = API_XML_SUCCESS;
  49. int downloadSize = http->get_bytes(downloadedData, HTTP_BUFFER_SIZE);
  50. if (downloadSize)
  51. {
  52. xmlResult = parser->xmlreader_feed((void *)downloadedData, downloadSize);
  53. *noData=false;
  54. }
  55. else
  56. *noData = true;
  57. return xmlResult;
  58. }
  59. static void RunXMLDownload(api_httpreceiver *http, obj_xml *parser)
  60. {
  61. int ret;
  62. bool noData;
  63. do
  64. {
  65. Sleep(50);
  66. ret = http->run();
  67. if (FeedXMLHTTP(http, parser, &noData) != API_XML_SUCCESS)
  68. return ;
  69. }
  70. while (ret == HTTPRECEIVER_RUN_OK);
  71. // finish off the data
  72. do
  73. {
  74. if (FeedXMLHTTP(http, parser, &noData) != API_XML_SUCCESS)
  75. return ;
  76. } while (!noData);
  77. parser->xmlreader_feed(0, 0);
  78. }
  79. void B4SXML::StartTag(const wchar_t *xmlpath, const wchar_t *xmltag, ifc_xmlreaderparams *params)
  80. {
  81. if (!_wcsicmp(xmltag, L"entry"))
  82. {
  83. const wchar_t *track = params->getItemValue(L"playstring");
  84. if (!_wcsnicmp(track, L"file://", 7))
  85. track+=7;
  86. else if (!_wcsnicmp(track, L"file:", 5))
  87. track+=5;
  88. StringCchCopyW(filename, FILENAME_SIZE, track);
  89. }
  90. }
  91. void B4SXML::EndTag(const wchar_t *xmlpath, const wchar_t *xmltag)
  92. {
  93. if (!_wcsicmp(xmltag, L"entry") && filename[0])
  94. {
  95. int lengthSeconds=-1;
  96. const wchar_t *trackLength = length.GetString();
  97. if (trackLength && *trackLength)
  98. lengthSeconds = _wtoi(trackLength) / 1000;
  99. const wchar_t *trackTitle = title.GetString();
  100. // TODO: deal with relative pathnames
  101. if (trackTitle && *trackTitle)
  102. playlist->OnFile(filename, trackTitle, lengthSeconds, 0); // TODO: extended info
  103. else
  104. playlist->OnFile(filename, 0, lengthSeconds, 0);// TODO: extended info
  105. filename[0]=0;
  106. length.Reset();
  107. title.Reset();
  108. }
  109. }
  110. #if 0 // TOOD: reimplement
  111. void B4SLoader::LoadURL(const char *url)
  112. {
  113. if (!parser)
  114. return ; // no sense in continuing if there's no parser available
  115. api_httpreceiver *http = 0;
  116. waServiceFactory *sf = WASABI_API_SVC->service_getServiceByGuid(httpreceiverGUID);
  117. if (sf)
  118. http = (api_httpreceiver *)sf->getInterface();
  119. if (!http)
  120. return ;
  121. http->AllowCompression();
  122. http->open(API_DNS_AUTODNS, HTTP_BUFFER_SIZE, GetProxy());
  123. SetUserAgent(http);
  124. http->connect(url);
  125. int ret;
  126. bool first = true;
  127. do
  128. {
  129. Sleep(50);
  130. ret = http->run();
  131. if (ret == -1) // connection failed
  132. break;
  133. // ---- check our reply code ----
  134. int replycode = http->GetReplyCode();
  135. switch (replycode)
  136. {
  137. case 0:
  138. case 100:
  139. break;
  140. case 200:
  141. {
  142. RunXMLDownload(http, parser);
  143. sf->releaseInterface(http);
  144. return ;
  145. }
  146. break;
  147. default:
  148. sf->releaseInterface(http);
  149. return ;
  150. }
  151. }
  152. while (ret == HTTPRECEIVER_RUN_OK);
  153. const char *er = http->geterrorstr();
  154. sf->releaseInterface(http);
  155. return ;
  156. }
  157. void B4SLoader::LoadFile(const char *filename)
  158. {
  159. if (!parser)
  160. return ; // no sense in continuing if there's no parser available
  161. HANDLE file = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL, NULL);
  162. if (file == INVALID_HANDLE_VALUE)
  163. return ;
  164. char data[1024] = {0};
  165. while (true)
  166. {
  167. DWORD bytesRead = 0;
  168. if (ReadFile(file, data, 1024, &bytesRead, NULL) && bytesRead)
  169. {
  170. parser->xmlreader_feed(data, bytesRead);
  171. }
  172. else
  173. break;
  174. }
  175. CloseHandle(file);
  176. parser->xmlreader_feed(0, 0);
  177. }
  178. #endif
  179. int B4SLoader::Load(const wchar_t *filename, ifc_playlistloadercallback *playlist)
  180. {
  181. if (!parser)
  182. return IFC_PLAYLISTLOADER_FAILED; // no sense in continuing if there's no parser available
  183. b4sXml.playlist=playlist;
  184. HANDLE file = CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL, NULL);
  185. if (file == INVALID_HANDLE_VALUE)
  186. return IFC_PLAYLISTLOADER_FAILED;
  187. while (true)
  188. {
  189. char data[1024] = {0};
  190. DWORD bytesRead = 0;
  191. if (ReadFile(file, data, 1024, &bytesRead, NULL) && bytesRead)
  192. {
  193. parser->xmlreader_feed(data, bytesRead);
  194. }
  195. else
  196. break;
  197. }
  198. CloseHandle(file);
  199. parser->xmlreader_feed(0, 0);
  200. return IFC_PLAYLISTLOADER_SUCCESS;
  201. }
  202. #ifdef CBCLASS
  203. #undef CBCLASS
  204. #endif
  205. #define CBCLASS B4SXML
  206. START_DISPATCH;
  207. VCB(ONSTARTELEMENT, StartTag)
  208. VCB(ONENDELEMENT, EndTag)
  209. END_DISPATCH;
  210. #ifdef CBCLASS
  211. #undef CBCLASS
  212. #endif
  213. #define CBCLASS B4SLoader
  214. START_DISPATCH;
  215. CB(IFC_PLAYLISTLOADER_LOAD, Load)
  216. END_DISPATCH;