aboutsummaryrefslogtreecommitdiff
path: root/Src/filereader
diff options
context:
space:
mode:
Diffstat (limited to 'Src/filereader')
-rw-r--r--Src/filereader/HTTPReader.cpp630
-rw-r--r--Src/filereader/HTTPReader.h50
-rw-r--r--Src/filereader/HTTPReaderFactory.cpp75
-rw-r--r--Src/filereader/HTTPReaderFactory.h26
-rw-r--r--Src/filereader/ProgressiveHTTPReader.cpp88
-rw-r--r--Src/filereader/ProgressiveHTTPReader.h27
-rw-r--r--Src/filereader/ResourceReader.cpp115
-rw-r--r--Src/filereader/ResourceReader.h34
-rw-r--r--Src/filereader/ResourceReaderFactory.cpp75
-rw-r--r--Src/filereader/ResourceReaderFactory.h26
-rw-r--r--Src/filereader/WA5_FileReader.h15
-rw-r--r--Src/filereader/api__filereader.h14
-rw-r--r--Src/filereader/filereader.rc76
-rw-r--r--Src/filereader/filereader.sln30
-rw-r--r--Src/filereader/filereader.vcxproj262
-rw-r--r--Src/filereader/filereader.vcxproj.filters68
-rw-r--r--Src/filereader/filereader.xcodeproj/project.pbxproj208
-rw-r--r--Src/filereader/main.cpp77
-rw-r--r--Src/filereader/resource.h14
-rw-r--r--Src/filereader/version.rc239
20 files changed, 1949 insertions, 0 deletions
diff --git a/Src/filereader/HTTPReader.cpp b/Src/filereader/HTTPReader.cpp
new file mode 100644
index 00000000..12e0db7d
--- /dev/null
+++ b/Src/filereader/HTTPReader.cpp
@@ -0,0 +1,630 @@
+#include "HTTPReader.h"
+#include "..\Components\wac_network\wac_network_http_receiver_api.h"
+#include "api__filereader.h"
+#include "../nu/AutoChar.h"
+#include <api/service/waservicefactory.h>
+#include <api/filereader/api_readercallback.h>
+#include <wchar.h>
+#include <bfc/platform/strcmp.h>
+#include <bfc/platform/minmax.h>
+#ifdef _WIN32
+#include <shlwapi.h>
+#endif
+
+#ifdef __APPLE__
+#include <unistd.h>
+#endif
+
+#include <stdexcept>
+
+// so we don't accidently call these CRT functions
+#ifdef close
+#undef close
+#endif
+#ifdef open
+#undef open
+#endif
+#ifdef read
+#undef read
+#endif
+
+#define config_guess_prebuffer true
+#define config_buffer_size 64
+#define config_prebuffer_size 24
+#define config_prebuffer_min 0
+#define config_allowseek true
+#define config_fullseek true
+#define config_seekprebuffer 1
+#define config_suppressstatus false
+
+// {C0A565DC-0CFE-405a-A27C-468B0C8A3A5C}
+static const GUID internetConfigGroupGUID =
+ {
+ 0xc0a565dc, 0xcfe, 0x405a, { 0xa2, 0x7c, 0x46, 0x8b, 0xc, 0x8a, 0x3a, 0x5c }
+ };
+
+class HttpReader
+{
+public:
+ HttpReader(const char *url, uint64_t start_offset = 0, uint64_t total_len = 0, int is_seek = 0);
+ ~HttpReader();
+
+ int connect();
+ int read(int8_t *buffer, int length);
+
+ void abort() { killswitch = 1; }
+
+ int bytesAvailable();
+
+ uint64_t getContentLength()
+ {
+ if (m_contentlength)
+ return m_contentlength;
+
+ return -1;
+ }
+
+ int canSeek()
+ {
+ return (m_contentlength &&
+ /* JF> this is correct but not as compatible: m_accept_ranges && */
+ !m_meta_interval);
+ }
+
+ uint64_t getPos() { return m_contentpos; }
+
+ const char *getHeader( const char *header ) { return httpGetter->getheader( (char *)header ); }
+
+ void setMetaCB( api_readercallback *cb ) { metacb = cb; }
+
+ //static BOOL CALLBACK httpDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
+
+private:
+ api_httpreceiver *httpGetter = NULL;
+ api_dns *dns = NULL;
+
+ char *m_AllHeaders;
+
+ int buffer_size;
+ int prebuffer_size, prebuffer_min;
+ int need_prebuffer;
+ uint64_t m_contentlength, m_contentpos;
+ int m_accept_ranges;
+
+ int proxy_enabled;
+ char *proxy;
+
+ int killswitch = -1;
+
+ int m_meta_init, m_meta_interval, m_meta_pos, m_meta_size, m_meta_buf_pos;
+ char m_meta_buf[4096];
+
+ api_readercallback *metacb;
+
+ int guessed_prebuffer_size;
+
+ char lpinfo[256];
+ char force_lpinfo[256];
+ char *dlg_realm;
+ char *m_url;
+};
+
+
+HttpReader::HttpReader( const char *url, uint64_t start_offset, uint64_t total_len, int is_seek )
+{
+ m_accept_ranges = 0;
+ buffer_size = (config_buffer_size * 1024);
+ prebuffer_size = (config_prebuffer_size * 1024);
+ prebuffer_min = (config_prebuffer_min * 1024);
+ guessed_prebuffer_size = !config_guess_prebuffer;
+
+ if (is_seek)
+ {
+ prebuffer_min = prebuffer_size = config_seekprebuffer;
+ guessed_prebuffer_size = 1;
+ }
+
+ proxy_enabled = 0;
+ killswitch = 0;
+ need_prebuffer = 0;
+ m_contentlength = total_len;
+ m_contentpos = start_offset;
+ m_meta_init = m_meta_interval = m_meta_pos = m_meta_size = m_meta_buf_pos = 0;
+ m_meta_buf[0] = 0;
+ metacb = NULL;
+ force_lpinfo[0] = 0;
+ lpinfo[0] = 0;
+
+ m_url = _strdup(url);
+
+ int use_proxy = 1;
+ bool proxy80 = AGAVE_API_CONFIG->GetBool(internetConfigGroupGUID, L"proxy80", false);
+ if (proxy80 && strstr(url, ":") && (!strstr(url, ":80/") && strstr(url, ":80") != (url + strlen(url) - 3)))
+ use_proxy = 0;
+
+ waServiceFactory *sf = WASABI_API_SVC->service_getServiceByGuid( httpreceiverGUID );
+ if (sf)
+ httpGetter = (api_httpreceiver *)sf->getInterface();
+
+ const wchar_t *proxy = AGAVE_API_CONFIG->GetString(internetConfigGroupGUID, L"proxy", 0);
+
+ httpGetter->open(API_DNS_AUTODNS, buffer_size, (use_proxy && proxy && proxy[0]) ? (char *)AutoChar(proxy) : NULL);
+ httpGetter->addheader("Accept:*/*");
+ if (!_strnicmp(url, "uvox://", 7))
+ {
+ httpGetter->addheader("User-Agent: ultravox/2.0");
+ }
+ else
+ {
+ httpGetter->AddHeaderValue("User-Agent", AutoChar(WASABI_API_APP->main_getVersionString()));
+ }
+
+ if (start_offset > 0)
+ {
+ char temp[128];
+ sprintf(temp, "Range: bytes=%d-", (int)start_offset);
+ httpGetter->addheader(temp);
+ }
+ else
+ httpGetter->addheader("Icy-Metadata:1");
+
+ httpGetter->connect((char *)m_url, start_offset > 0);
+ HttpReader::connect();
+ HttpReader::read(0, 0);
+
+ //if (!config_suppressstatus) api->core_setCustomMsg(0, StringPrintf("[Connecting] %s",url));
+}
+
+HttpReader::~HttpReader()
+{
+ waServiceFactory *sf = WASABI_API_SVC->service_getServiceByGuid( httpreceiverGUID );
+ if ( sf )
+ sf->releaseInterface( httpGetter );
+}
+
+// TODO: BOOL CALLBACK HttpReader::httpDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
+
+int HttpReader::connect()
+{
+ try
+ {
+ while ( killswitch >= 0 && httpGetter->run() == 0 && httpGetter->get_status() == 0 )
+ {
+#ifdef _WIN32
+ //Sleep( 50 );
+#else
+ usleep( 50000 );
+#endif
+ }
+ if ( killswitch )
+ return 0;
+
+ if ( httpGetter->get_status() == -1 )
+ {
+ int code = httpGetter->getreplycode();
+ if ( code == 401 )
+ {
+ /* TODO:
+ // authorization required
+ JNL_Connection *m_connection=httpGetter->get_con();
+ char str[4096];
+ while (m_connection->recv_lines_available() > 0) {
+ char *wwwa="WWW-Authenticate:";
+ m_connection->recv_line(str,4096);
+ if (!str[0]) break;
+ if (!_strnicmp(str,wwwa,strlen(wwwa))) {
+ char *s2="Basic realm=\"";
+ char *p=str+strlen(wwwa); while (p && *p== ' ') p++;
+ if (!_strnicmp(p,s2,strlen(s2))) {
+ p+=strlen(s2);
+ if (strstr(p,"\"")) {
+ strstr(p,"\"")[0]=0;
+ if (*p) {
+ if(force_lpinfo[0]) {
+ force_lpinfo[0]=0; // invalid l/p
+ } else WASABI_API_CONFIG->getStringPrivate(StringPrintf("HTTP-AUTH/%s",p),force_lpinfo,sizeof(force_lpinfo),"");
+ if (!force_lpinfo[0] || lpinfo[0]) {
+ dlg_realm = p;
+ api->pushModalWnd();
+ RootWnd *pr=api->main_getRootWnd();
+ while(pr->getParent()) pr=pr->getParent();
+ if (!DialogBoxParam(the->gethInstance(),MAKEINTRESOURCE(IDD_HTTPAUTH),pr->gethWnd(),httpDlgProc,(long)this)) {
+ force_lpinfo[0]=0;
+ } else {
+ WASABI_API_CONFIG->setStringPrivate(StringPrintf("HTTP-AUTH/%s",p),force_lpinfo);
+ }
+ api->popModalWnd();
+ }
+ if (force_lpinfo[0]) {
+ const char *p=STRSTR(m_url,"http://");
+ if(p) {
+ p+=7;
+ StringPrintf tmp("http://%s@%s",force_lpinfo,p);
+ httpGetter->connect((char *)tmp.getValue());
+ return connect(); // recursive city
+ }
+ }
+ }
+ }
+ }
+ break;
+ }
+ }*/
+ }
+ // TODO: api->core_setCustomMsg(0, StringPrintf("HTTP: can't connect (%i)",code));
+ return 0;
+ }
+
+ if ( httpGetter->getreplycode() < 200 || httpGetter->getreplycode() > 299 )
+ {
+ // TODO: api->core_setCustomMsg(0, StringPrintf("HTTP: returned %i",httpGetter->getreplycode()));
+ return 0;
+ }
+
+ need_prebuffer = 1;
+ }
+ catch ( const std::exception &e )
+ {
+ return 0;
+ }
+
+
+ return 1;
+}
+
+int HttpReader::bytesAvailable()
+{
+ int code = httpGetter->run();
+ int ba = httpGetter->bytes_available();
+
+ if ( !ba && code )
+ return -1;
+
+ return ba;
+}
+
+int HttpReader::read(int8_t *buffer, int length)
+{
+ if (!httpGetter->GetConnection())
+ return 0;
+
+ if ( httpGetter->GetConnection()->get_state() == CONNECTION_STATE_CONNECTED && httpGetter->bytes_available() < prebuffer_min )
+ need_prebuffer = 1;
+
+ if (need_prebuffer)
+ {
+ need_prebuffer = 0;
+ // TODO: if (!config_suppressstatus) api->core_setCustomMsg(0, "Prebuffering ...");
+
+ if (!guessed_prebuffer_size)
+ {
+ // wait for headers
+ int s;
+ do
+ {
+ s = httpGetter->run();
+ }
+ while (s == 0 && httpGetter->get_status() != 2);
+
+ // calculate the needed prebuffer size if it's a shoutcast stream
+ const char *icybr;
+ if (icybr = httpGetter->getheader("icy-br"))
+ {
+ prebuffer_size = (atoi(icybr) / 8) * 4096;
+ prebuffer_min = (atoi(icybr) / 8) * 1024;
+
+ if (prebuffer_size > buffer_size)
+ prebuffer_size = buffer_size;
+ }
+
+ guessed_prebuffer_size = 1;
+ }
+
+ int last_pre = -1;
+ while (httpGetter->bytes_available() < prebuffer_size && !killswitch)
+ {
+ int s = httpGetter->run();
+// JNL_Connection::state s = getter->get_state();
+ // if (s == JNL_Connection::STATE_ERROR || s == JNL_Connection::STATE_CLOSED) break;
+ if (s == -1 || s == 1) break;
+#ifdef _WIN32
+ Sleep(50);
+#else
+ usleep(50000);
+#endif
+ if (last_pre != httpGetter->bytes_available() && !killswitch)
+ {
+// TODO: if (!config_suppressstatus) api->core_setCustomMsg(0, StringPrintf(0, "Prebuffering : %i/%i bytes",httpGetter->bytes_available(),prebuffer_size));
+ }
+ }
+
+// if (!killswitch)
+// {
+//// TODO: if (!config_suppressstatus) api->core_setCustomMsg(0, "Prebuffering done.");
+// }
+ }
+
+ if (killswitch) return 0;
+
+ // metadata filtering
+ if ( !m_meta_init )
+ {
+ const char *v;
+ if ( v = httpGetter->getheader( "icy-metaint:" ) )
+ m_meta_interval = atoi( v );
+
+ if ( !m_contentlength )
+ {
+ if ( v = httpGetter->getheader( "content-length:" ) )
+ m_contentlength = _strtoui64( v, NULL, 10 );//atoi(v);
+ }
+
+ v = httpGetter->getheader( "accept-ranges:" );
+ if ( v && strcasestr( v, "bytes" ) )
+ m_accept_ranges = 1;
+
+ m_meta_init = 1;
+ }
+
+ int error = 0, recvBytes = 0;
+ while (length && !error && !killswitch)
+ {
+ int code = httpGetter->run();
+
+ if (code != 0)
+ error = 1;
+
+ // old metadata parsing
+ /*if (httpGetter->bytes_available()>0) {
+ int l=httpGetter->get_bytes(buffer,length);
+
+ // metadata stuff
+ if (m_meta_interval) {
+ int x=l;
+ unsigned char *buf=(unsigned char *)buffer;
+ if (m_meta_size)// already in meta block
+ {
+ int len=MIN(x,m_meta_size-m_meta_buf_pos);
+
+ MEMCPY(m_meta_buf+m_meta_buf_pos,buf,len);
+ m_meta_buf_pos+=len;
+
+ if (m_meta_buf_pos==m_meta_size)
+ {
+ if(metacb) metacb->metaDataReader_onData(m_meta_buf,m_meta_size);
+ m_meta_buf_pos=0;
+ m_meta_size=0;
+ m_meta_pos=0;
+ }
+
+ x-=len;
+ if (x) MEMCPY(buf,buf+len,x);
+ }
+ else if (m_meta_pos+x > m_meta_interval) // block contains meta data somewhere in it, and we're not alreayd reading a block
+ {
+ int start_offs=m_meta_interval-m_meta_pos;
+ int len;
+ m_meta_size=((unsigned char *)buf)[start_offs]*16;
+
+ len=MIN(x-start_offs-1,m_meta_size);
+
+ if (len) MEMCPY(m_meta_buf,buf+start_offs+1,len);
+ m_meta_buf_pos=len;
+
+ if (m_meta_buf_pos==m_meta_size) // full read of metadata successful
+ {
+ x-=m_meta_size+1;
+ if (x > start_offs) MEMCPY(buf+start_offs,buf+start_offs+1+m_meta_size,x-start_offs);
+ if(metacb) metacb->metaDataReader_onData(m_meta_buf,m_meta_size);
+ m_meta_buf_pos=0;
+ m_meta_pos=-start_offs;
+ m_meta_size=0;
+ }
+ else
+ {
+ x=start_offs; // otherwise, there's only the first block of data
+ }
+ }
+ if (x > 0)
+ {
+ m_meta_pos+=x;
+ }
+ l=x;
+ }
+
+ length-=l;
+ buffer+=l;
+ recvBytes+=l;
+ } else Sleep(50);*/
+
+ while (1)
+ {
+ int len = httpGetter->bytes_available();
+ if (m_meta_interval && m_meta_pos >= m_meta_interval)
+ {
+ unsigned char b;
+ if (len > 0 && httpGetter->peek_bytes((char*)&b, 1) && len > (b << 4))
+ {
+ char metabuf[4096];
+ httpGetter->get_bytes(metabuf, 1);
+ httpGetter->get_bytes(metabuf, b << 4);
+ if (metacb) metacb->metaDataReader_onData(metabuf, b << 4);
+ //stream_metabytes_read+=(b<<4)+1;
+ m_meta_pos = 0;
+ }
+ else
+ break;
+ }
+ else
+ {
+ len = MIN(length, len);
+ if (m_meta_interval)
+ len = MIN(m_meta_interval - m_meta_pos, len);
+
+ if (len > 0)
+ {
+ len = httpGetter->get_bytes((char*)buffer, len);
+ m_meta_pos += len;
+ //stream_bytes_read+=len;
+ length -= len;
+ buffer += len;
+ recvBytes += len;
+ }
+ else
+ {
+#ifdef _WIN32
+ Sleep(50);
+#else
+ usleep(50000);
+#endif
+ }
+ break;
+ }
+ }
+
+ /* int s=httpGetter->get_con()->get_state();
+ if(code==0) {*/
+ /* char tmp[512];
+ wsprintf(tmp,"[Connected] Retrieving list (%i bytes)", recvBytes);
+ api->status_setText(tmp);*/
+// } else error=1;
+ }
+
+ m_contentpos += recvBytes;
+
+ return recvBytes;
+}
+
+
+/* ---------------------------------------------------------------------- */
+int HTTPReader::isMine(const wchar_t *filename, int mode)
+{
+ if (!_wcsnicmp(filename, L"http://", 7) ||
+ !_wcsnicmp(filename, L"https://", 8) ||
+ !_wcsnicmp(filename, L"icy://", 6) ||
+ !_wcsnicmp(filename, L"sc://", 5) ||
+ !_wcsnicmp(filename, L"uvox://", 7)) return 1;
+ return 0;
+}
+
+int HTTPReader::open( const wchar_t *filename, int mode )
+{
+ if ( !isMine( filename, mode ) )
+ return 0;
+
+ m_filename = _strdup( AutoChar( filename ) );
+ reader = new HttpReader( m_filename );
+
+ return 1;
+}
+
+uint64_t HTTPReader::bytesAvailable( uint64_t requested )
+{
+ int v = reader ? reader->bytesAvailable() : 0;
+ if ( v > requested )
+ return requested;
+
+ return v;
+}
+
+size_t HTTPReader::read( int8_t *buffer, size_t length )
+{
+ if ( !reader )
+ return 0;
+
+ if ( !hasConnected )
+ {
+ int res = reader->connect();
+ if ( !res )
+ return 0;
+
+ hasConnected = 1;
+ }
+
+ return reader->read( buffer, (int)length );
+}
+
+void HTTPReader::close()
+{
+ delete reader;
+ reader = NULL;
+}
+
+void HTTPReader::abort()
+{
+ if ( reader )
+ reader->abort();
+}
+
+uint64_t HTTPReader::getLength()
+{
+ return reader ? reader->getContentLength() : -1;
+}
+
+uint64_t HTTPReader::getPos()
+{
+ return reader ? reader->getPos() : 0;
+}
+
+int HTTPReader::canSeek()
+{
+ return ( config_allowseek && reader && reader->canSeek() ) ? ( config_fullseek ? 1 : -1 ) : 0;
+}
+
+int HTTPReader::seek( uint64_t position )
+{
+ if ( reader && reader->canSeek() && config_allowseek )
+ {
+ if ( position == getPos() ) return 0;
+ hasConnected = 0;
+ uint64_t cl = reader->getContentLength();
+ delete( (HttpReader *)reader );
+ reader = new HttpReader( m_filename, position, cl, 1 );
+ return 0;
+ }
+
+ return -1;
+}
+
+int HTTPReader::hasHeaders()
+{
+ return 1;
+}
+
+const char *HTTPReader::getHeader( const char *header )
+{
+ return reader ? reader->getHeader( header ) : NULL;
+}
+
+void HTTPReader::setMetaDataCallback( api_readercallback *cb )
+{
+ if ( reader )
+ reader->setMetaCB( cb );
+}
+
+#define CBCLASS HTTPReader
+START_DISPATCH;
+CB(ISMINE, isMine);
+CB(OPEN, open);
+CB(READ, read);
+CB(WRITE, write);
+VCB(CLOSE, close);
+VCB(ABORT, abort);
+CB(GETLENGTH, getLength);
+CB(GETPOS, getPos);
+CB(CANSEEK, canSeek);
+CB(SEEK, seek);
+CB(HASHEADERS, hasHeaders);
+CB(GETHEADER, getHeader);
+CB(EXISTS, exists);
+// CB(REMOVE,remove);
+// CB(REMOVEUNDOABLE,removeUndoable);
+// CB(MOVE,move);
+CB(BYTESAVAILABLE, bytesAvailable);
+VCB(SETMETADATACALLBACK, setMetaDataCallback);
+CB(CANPREFETCH, canPrefetch);
+// CB(CANSETEOF, canSetEOF);
+// CB(SETEOF, setEOF);
+END_DISPATCH;
+#undef CBCLASS
+
diff --git a/Src/filereader/HTTPReader.h b/Src/filereader/HTTPReader.h
new file mode 100644
index 00000000..3afe02ee
--- /dev/null
+++ b/Src/filereader/HTTPReader.h
@@ -0,0 +1,50 @@
+#ifndef NULLSOFT_HTTPREADER_H
+#define NULLSOFT_HTTPREADER_H
+
+#include "api/service/svcs/svc_fileread.h"
+
+class HttpReader;
+
+class HTTPReader : public svc_fileReader
+{
+public:
+ HTTPReader() {}
+ virtual ~HTTPReader() { close(); }
+
+ int isMine( const wchar_t *filename, int mode = SvcFileReader::READ );
+ int open( const wchar_t *filename, int mode = SvcFileReader::READ );
+
+ size_t read( int8_t *buffer, size_t length );
+ size_t write( const int8_t *buffer, size_t length ) { return 0; }
+
+ uint64_t bytesAvailable( uint64_t requested );
+
+ void close();
+ void abort();
+
+ uint64_t getLength();
+ uint64_t getPos();
+
+ int canSeek();
+ int seek( uint64_t position );
+
+ int hasHeaders();
+ const char *getHeader( const char *header );
+
+ void setMetaDataCallback( api_readercallback *cb );
+
+ int canPrefetch() { return 0; } // no info fetch on HTTP files
+
+/*int remove(const char *filename) { return 0; }
+int move(const char *filename, const char *destfilename) { return 0; }*/
+
+protected:
+ RECVS_DISPATCH;
+
+private:
+ HttpReader *reader = NULL;
+ int hasConnected = 0;
+ char *m_filename = 0;
+};
+
+#endif \ No newline at end of file
diff --git a/Src/filereader/HTTPReaderFactory.cpp b/Src/filereader/HTTPReaderFactory.cpp
new file mode 100644
index 00000000..0abf3d6e
--- /dev/null
+++ b/Src/filereader/HTTPReaderFactory.cpp
@@ -0,0 +1,75 @@
+#include "api__filereader.h"
+#include "HTTPReaderFactory.h"
+#include "HTTPReader.h"
+
+static const char serviceName[] = "HTTP reader";
+
+// {bc10fa00-53F5-4032-BD29-032B87EC3404}
+static const GUID HTTPReaderGUID =
+ { 0xbc10fa00, 0x53f5, 0x4032, { 0xa0, 0x09, 0x2, 0x2b, 0x87, 0xec, 0x34, 0x04 } };
+
+
+FOURCC HTTPReaderFactory::GetServiceType()
+{
+ return WaSvc::FILEREADER;
+}
+
+const char *HTTPReaderFactory::GetServiceName()
+{
+ return serviceName;
+}
+
+GUID HTTPReaderFactory::GetGUID()
+{
+ return HTTPReaderGUID;
+}
+
+void *HTTPReaderFactory::GetInterface( int global_lock )
+{
+ HTTPReader *ifc = new HTTPReader;
+
+ if ( global_lock )
+ WASABI_API_SVC->service_lock( this, (void *)ifc );
+
+ return ifc;
+}
+
+int HTTPReaderFactory::SupportNonLockingInterface()
+{
+ return 1;
+}
+
+int HTTPReaderFactory::ReleaseInterface(void *ifc)
+{
+ //WASABI_API_SVC->service_unlock(ifc);
+ svc_fileReader *reader = static_cast<svc_fileReader *>(ifc);
+ HTTPReader *resourceReader = static_cast<HTTPReader *>(reader);
+ delete resourceReader;
+ return 1;
+}
+
+const char *HTTPReaderFactory::GetTestString()
+{
+ return 0;
+}
+
+int HTTPReaderFactory::ServiceNotify(int msg, int param1, int param2)
+{
+ return 1;
+}
+
+#ifdef CBCLASS
+#undef CBCLASS
+#endif
+
+#define CBCLASS HTTPReaderFactory
+START_DISPATCH;
+CB( WASERVICEFACTORY_GETSERVICETYPE, GetServiceType )
+CB( WASERVICEFACTORY_GETSERVICENAME, GetServiceName )
+CB( WASERVICEFACTORY_GETGUID, GetGUID )
+CB( WASERVICEFACTORY_GETINTERFACE, GetInterface )
+CB( WASERVICEFACTORY_SUPPORTNONLOCKINGGETINTERFACE, SupportNonLockingInterface )
+CB( WASERVICEFACTORY_RELEASEINTERFACE, ReleaseInterface )
+CB( WASERVICEFACTORY_GETTESTSTRING, GetTestString )
+CB( WASERVICEFACTORY_SERVICENOTIFY, ServiceNotify )
+END_DISPATCH;
diff --git a/Src/filereader/HTTPReaderFactory.h b/Src/filereader/HTTPReaderFactory.h
new file mode 100644
index 00000000..ad8949e5
--- /dev/null
+++ b/Src/filereader/HTTPReaderFactory.h
@@ -0,0 +1,26 @@
+#ifndef NULLSOFT_HTTPREADERFACTORY_H
+#define NULLSOFT_HTTPREADERFACTORY_H
+
+#include "api__filereader.h"
+#include <api/service/waservicefactory.h>
+#include <api/service/services.h>
+
+class HTTPReaderFactory : public waServiceFactory
+{
+public:
+ FOURCC GetServiceType();
+ const char *GetServiceName();
+ GUID GetGUID();
+ void *GetInterface( int global_lock );
+ int SupportNonLockingInterface();
+ int ReleaseInterface( void *ifc );
+ const char *GetTestString();
+ int ServiceNotify( int msg, int param1, int param2 );
+
+protected:
+ RECVS_DISPATCH;
+};
+
+
+#endif
+
diff --git a/Src/filereader/ProgressiveHTTPReader.cpp b/Src/filereader/ProgressiveHTTPReader.cpp
new file mode 100644
index 00000000..16ad697a
--- /dev/null
+++ b/Src/filereader/ProgressiveHTTPReader.cpp
@@ -0,0 +1,88 @@
+/** (c) Nullsoft, Inc. C O N F I D E N T I A L
+ ** Filename:
+ ** Project:
+ ** Description:
+ ** Author: Ben Allison benski@nullsoft.com
+ ** Created:
+ **/
+/* implementation ideas, notes and todos
+
+Memory mapped file to use as temporary storage
+mark downloaded pages with bitfield vector
+use content length header
+use content-disposition for filename, if available (instead of temp filename)
+
+*/
+#include "ProgressiveHTTPReader.h"
+#include <windows.h>
+
+int ProgressiveHTTPReader::isMine(const wchar_t *filename, int mode)
+{
+ return 0; // only want to use the progressive downloader/reader on demand.
+}
+
+int ProgressiveHTTPReader::open(const wchar_t *filename, int mode)
+{
+ pagePosition.QuadPart=0;
+
+ SYSTEM_INFO info;
+ GetSystemInfo(&info);
+ pageSize = info.dwPageSize;
+
+ char tempPath[MAX_PATH];
+ GetTempPathA(MAX_PATH, tempPath);
+ GetTempFileNameA(tempPath, "phr", 0, tempPath);
+
+ hFile=CreateFile((LPCWSTR)tempPath, GENERIC_WRITE|GENERIC_READ, 0, 0, CREATE_ALWAYS, 0, 0);
+
+
+ LARGE_INTEGER contentLength;
+ contentLength.QuadPart = 100*1024*1024; // TODO: use content length header for filesize
+
+ hMap=CreateFileMapping(hFile, 0, PAGE_READWRITE, contentLength.HighPart, contentLength.LowPart, 0);
+ // TODO: spawn a thread and start downloading data..
+ // thread should get a duplicate file handle
+
+ return 1;
+}
+
+void ProgressiveHTTPReader::IncrementPosition(uint64_t inc)
+{
+ pagePosition.QuadPart += offset;
+ pagePosition.QuadPart += inc;
+ offset = (uint32_t)(pagePosition.QuadPart & (uint64_t)pageSize);
+ pagePosition.QuadPart-=offset;
+}
+
+size_t ProgressiveHTTPReader::GetPageNumber() const
+{
+ return (size_t)(pagePosition.QuadPart / (uint64_t)pageSize);
+}
+
+size_t ProgressiveHTTPReader::read(__int8 *buffer, size_t length)
+{
+ /* TODO:
+ is this area of the file downloaded yet? If so, just return it as is
+ otherwise, what should we do? return what we can? or sit and wait until we get the data?
+ */
+ while (length)
+ {
+ // if page is available
+ {
+ // TODO: calculate maximum length we can map
+ MapViewOfFile(hMap, FILE_MAP_READ, pagePosition.HighPart, pagePosition.LowPart, pageSize);
+ // map page
+ // copy to buffer
+ // increment buffer
+ // decrement length
+ // increment position
+ }
+ //else
+ {
+ // queue up read request to background thread
+ // wait for signal
+ continue;
+ }
+ }
+ return 0;
+} \ No newline at end of file
diff --git a/Src/filereader/ProgressiveHTTPReader.h b/Src/filereader/ProgressiveHTTPReader.h
new file mode 100644
index 00000000..7f4e6159
--- /dev/null
+++ b/Src/filereader/ProgressiveHTTPReader.h
@@ -0,0 +1,27 @@
+#ifndef NULLSOFT_PROGRESSIVEHTTPREADER_H
+#define NULLSOFT_PROGRESSIVEHTTPREADER_H
+
+#include <api/service/svcs/svc_fileread.h>
+#include <windows.h>
+
+class ProgressiveHTTPReader : public svc_fileReader
+{
+public:
+ ProgressiveHTTPReader() : hFile(INVALID_HANDLE_VALUE), hMap(0), offset(0)
+ {}
+ int isMine(const wchar_t *filename, int mode=SvcFileReader::READ);
+ int open(const wchar_t *filename, int mode=SvcFileReader::READ);
+ size_t read(__int8 *buffer, size_t length);
+ void IncrementPosition(uint64_t inc);
+ size_t GetPageNumber() const;
+private:
+ char tempFile[MAX_PATH];
+ HANDLE hFile;
+ HANDLE hMap;
+ uint32_t pageSize;
+ LARGE_INTEGER pagePosition; // will always be % pageSize == 0
+ uint32_t offset; // offset into the page
+
+};
+
+#endif \ No newline at end of file
diff --git a/Src/filereader/ResourceReader.cpp b/Src/filereader/ResourceReader.cpp
new file mode 100644
index 00000000..a00e4776
--- /dev/null
+++ b/Src/filereader/ResourceReader.cpp
@@ -0,0 +1,115 @@
+#include "ResourceReader.h"
+
+ResourceReader::ResourceReader() : data(NULL), g(NULL), ptr(0)
+{}
+
+int ResourceReader::open(const wchar_t *filename, int mode)
+{
+ if (_wcsnicmp(filename, L"res://", 6)) return 0;
+ filename += 6;
+ wchar_t blah[MAX_PATH];
+ lstrcpynW(blah, filename, MAX_PATH);
+
+ wchar_t *p = blah;
+ while (p && *p && *p != ',') p++;
+ if (p && *p != ',') return 0;
+ if (p) *p++ = 0;
+ HINSTANCE hInst = (HINSTANCE)_wtoi64(blah);
+ int id = _wtoi(p);
+
+ HRSRC r = FindResource(hInst, MAKEINTRESOURCE(id), RT_RCDATA);
+ if (r == NULL) return 0;
+ g = LoadResource(hInst, r);
+ if (g == NULL) return 0;
+ data = (char*)LockResource(g);
+ if (data == NULL)
+ {
+ FreeResource(g); // see win32 doc
+ g = NULL;
+ return 0;
+ }
+ size = SizeofResource(hInst, r);
+ ptr = 0;
+
+ return 1;
+}
+
+size_t ResourceReader::read(__int8 *buffer, size_t length)
+{
+ size_t s = min(size - ptr, length);
+ if (s)
+ memcpy(buffer, data + ptr, s);
+ ptr += s;
+ return s;
+}
+
+size_t ResourceReader::write(const __int8 *buffer, size_t length)
+{
+
+ return 0;
+}
+
+void ResourceReader::close()
+{
+ if (g)
+ {
+ UnlockResource(g);
+ FreeResource(g); // see win32 doc
+ g = NULL;
+ data = NULL;
+ }
+}
+
+unsigned __int64 ResourceReader::getPos()
+{
+ return ptr;
+}
+
+unsigned __int64 ResourceReader::getLength()
+{
+ return size;
+}
+
+int ResourceReader::canSeek()
+{
+ return 1;
+}
+
+int ResourceReader::seek(unsigned __int64 position)
+{
+ ptr = (size_t)min(position, size);
+ return 1;
+}
+
+int ResourceReader::exists(const wchar_t *filename)
+{
+ return 1;
+} // always exists if open succeeded
+
+
+#define CBCLASS ResourceReader
+START_DISPATCH;
+// CB(ISMINE, isMine);
+ CB(OPEN, open);
+ CB(READ, read);
+ CB(WRITE, write);
+ VCB(CLOSE, close);
+// VCB(ABORT, abort);
+ CB(GETLENGTH, getLength);
+ CB(GETPOS, getPos);
+ CB(CANSEEK, canSeek);
+// CB(SEEK, seek);
+// CB(HASHEADERS,hasHeaders);
+// CB(GETHEADER,getHeader);
+ CB(EXISTS,exists);
+// CB(REMOVE,remove);
+// CB(REMOVEUNDOABLE,removeUndoable);
+// CB(MOVE,move);
+// CB(BYTESAVAILABLE,bytesAvailable);
+// VCB(SETMETADATACALLBACK,setMetaDataCallback);
+// CB(CANPREFETCH,canPrefetch);
+// CB(CANSETEOF, canSetEOF);
+// CB(SETEOF, setEOF);
+END_DISPATCH;
+#undef CBCLASS
+
diff --git a/Src/filereader/ResourceReader.h b/Src/filereader/ResourceReader.h
new file mode 100644
index 00000000..01eb836e
--- /dev/null
+++ b/Src/filereader/ResourceReader.h
@@ -0,0 +1,34 @@
+#ifndef NULLSOFT_RESOURCEREADER_H
+#define NULLSOFT_RESOURCEREADER_H
+
+#include <api/service/svcs/svc_fileread.h>
+class ResourceReader : public svc_fileReader
+{
+public:
+ public:
+ ResourceReader();
+ virtual ~ResourceReader() { close(); }
+
+ int open(const wchar_t *filename, int mode=SvcFileReader::READ);
+
+ size_t read(__int8 *buffer, size_t length);
+ size_t write(const __int8 *buffer, size_t length);
+ void close();
+ unsigned __int64 getPos();
+ unsigned __int64 getLength();
+ int canSeek();
+ int seek(unsigned __int64 position);
+ int exists(const wchar_t *filename);
+ /*int remove(const char *filename) { return 0; }
+ int move(const char *filename, const char *destfilename) { return 0; }*/
+protected:
+ RECVS_DISPATCH;
+private:
+ __int8 *data;
+ size_t ptr;
+ size_t size;
+ HGLOBAL g;
+
+};
+
+#endif \ No newline at end of file
diff --git a/Src/filereader/ResourceReaderFactory.cpp b/Src/filereader/ResourceReaderFactory.cpp
new file mode 100644
index 00000000..ca76c740
--- /dev/null
+++ b/Src/filereader/ResourceReaderFactory.cpp
@@ -0,0 +1,75 @@
+#include "api__filereader.h"
+#include "ResourceReaderFactory.h"
+#include "ResourceReader.h"
+
+static const char serviceName[] = "Resource reader";
+
+// {C975969A-5DFD-4f2b-B767-4EDC6C7D6484}
+static const GUID ResourceReaderGUID =
+{ 0xc975969a, 0x5dfd, 0x4f2b, { 0xb7, 0x67, 0x4e, 0xdc, 0x6c, 0x7d, 0x64, 0x84 } };
+
+
+FOURCC ResourceReaderFactory::GetServiceType()
+{
+ return WaSvc::FILEREADER;
+}
+
+const char *ResourceReaderFactory::GetServiceName()
+{
+ return serviceName;
+}
+
+GUID ResourceReaderFactory::GetGUID()
+{
+ return ResourceReaderGUID;
+}
+
+void *ResourceReaderFactory::GetInterface( int global_lock )
+{
+ ResourceReader *ifc = new ResourceReader;
+
+ if ( global_lock )
+ WASABI_API_SVC->service_lock( this, (void *)ifc );
+
+ return ifc;
+}
+
+int ResourceReaderFactory::SupportNonLockingInterface()
+{
+ return 1;
+}
+
+int ResourceReaderFactory::ReleaseInterface(void *ifc)
+{
+ //WASABI_API_SVC->service_unlock(ifc);
+ svc_fileReader *reader = static_cast<svc_fileReader *>(ifc);
+ ResourceReader *resourceReader = static_cast<ResourceReader *>(reader);
+ delete resourceReader;
+ return 1;
+}
+
+const char *ResourceReaderFactory::GetTestString()
+{
+ return 0;
+}
+
+int ResourceReaderFactory::ServiceNotify(int msg, int param1, int param2)
+{
+ return 1;
+}
+
+#ifdef CBCLASS
+#undef CBCLASS
+#endif
+
+#define CBCLASS ResourceReaderFactory
+START_DISPATCH;
+CB(WASERVICEFACTORY_GETSERVICETYPE, GetServiceType)
+CB(WASERVICEFACTORY_GETSERVICENAME, GetServiceName)
+CB(WASERVICEFACTORY_GETGUID, GetGUID)
+CB(WASERVICEFACTORY_GETINTERFACE, GetInterface)
+CB(WASERVICEFACTORY_SUPPORTNONLOCKINGGETINTERFACE, SupportNonLockingInterface)
+CB(WASERVICEFACTORY_RELEASEINTERFACE, ReleaseInterface)
+CB(WASERVICEFACTORY_GETTESTSTRING, GetTestString)
+CB(WASERVICEFACTORY_SERVICENOTIFY, ServiceNotify)
+END_DISPATCH;
diff --git a/Src/filereader/ResourceReaderFactory.h b/Src/filereader/ResourceReaderFactory.h
new file mode 100644
index 00000000..ed242441
--- /dev/null
+++ b/Src/filereader/ResourceReaderFactory.h
@@ -0,0 +1,26 @@
+#ifndef NULLSOFT_RESOURCEREADERFACTORY_H
+#define NULLSOFT_RESOURCEREADERFACTORY_H
+
+#include "api__filereader.h"
+#include <api/service/waservicefactory.h>
+#include <api/service/services.h>
+
+class ResourceReaderFactory : public waServiceFactory
+{
+public:
+ FOURCC GetServiceType();
+ const char *GetServiceName();
+ GUID GetGUID();
+ void *GetInterface(int global_lock);
+ int SupportNonLockingInterface();
+ int ReleaseInterface(void *ifc);
+ const char *GetTestString();
+ int ServiceNotify(int msg, int param1, int param2);
+
+protected:
+ RECVS_DISPATCH;
+};
+
+
+#endif
+
diff --git a/Src/filereader/WA5_FileReader.h b/Src/filereader/WA5_FileReader.h
new file mode 100644
index 00000000..90b6de12
--- /dev/null
+++ b/Src/filereader/WA5_FileReader.h
@@ -0,0 +1,15 @@
+#ifndef __WASABI_WA5_FILEREADER_H
+#define __WASABI_WA5_FILEREADER_H
+
+#include "../Agave/Component/ifc_wa5component.h"
+
+class WA5_FileReader : public ifc_wa5component
+{
+public:
+ void RegisterServices(api_service *service);
+ int RegisterServicesSafeModeOk();
+ void DeregisterServices(api_service *service);
+protected:
+ RECVS_DISPATCH;
+};
+#endif \ No newline at end of file
diff --git a/Src/filereader/api__filereader.h b/Src/filereader/api__filereader.h
new file mode 100644
index 00000000..6d0d5542
--- /dev/null
+++ b/Src/filereader/api__filereader.h
@@ -0,0 +1,14 @@
+#ifndef NULLSOFT_APIH
+#define NULLSOFT_APIH
+#include <api/service/api_service.h>
+
+extern api_service *serviceManager;
+#define WASABI_API_SVC serviceManager
+
+#include <api/application/api_application.h>
+#define WASABI_API_APP applicationApi
+
+#include "../Agave/Config/api_config.h"
+extern api_config *config;
+#define AGAVE_API_CONFIG config
+#endif \ No newline at end of file
diff --git a/Src/filereader/filereader.rc b/Src/filereader/filereader.rc
new file mode 100644
index 00000000..fcff7711
--- /dev/null
+++ b/Src/filereader/filereader.rc
@@ -0,0 +1,76 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.K.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENG)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "#include ""version.rc2""\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // English (U.K.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+#include "version.rc2"
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/Src/filereader/filereader.sln b/Src/filereader/filereader.sln
new file mode 100644
index 00000000..76551e5c
--- /dev/null
+++ b/Src/filereader/filereader.sln
@@ -0,0 +1,30 @@
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.29424.173
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "filereader", "filereader.vcxproj", "{38F1536F-1CAB-41CE-80E1-E41D8965DF9E}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Debug|x64 = Debug|x64
+ Release|Win32 = Release|Win32
+ Release|x64 = Release|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {38F1536F-1CAB-41CE-80E1-E41D8965DF9E}.Debug|Win32.ActiveCfg = Debug|Win32
+ {38F1536F-1CAB-41CE-80E1-E41D8965DF9E}.Debug|Win32.Build.0 = Debug|Win32
+ {38F1536F-1CAB-41CE-80E1-E41D8965DF9E}.Debug|x64.ActiveCfg = Debug|x64
+ {38F1536F-1CAB-41CE-80E1-E41D8965DF9E}.Debug|x64.Build.0 = Debug|x64
+ {38F1536F-1CAB-41CE-80E1-E41D8965DF9E}.Release|Win32.ActiveCfg = Release|Win32
+ {38F1536F-1CAB-41CE-80E1-E41D8965DF9E}.Release|Win32.Build.0 = Release|Win32
+ {38F1536F-1CAB-41CE-80E1-E41D8965DF9E}.Release|x64.ActiveCfg = Release|x64
+ {38F1536F-1CAB-41CE-80E1-E41D8965DF9E}.Release|x64.Build.0 = Release|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {335526B4-6A76-45B8-9BC0-6EED6F709B2C}
+ EndGlobalSection
+EndGlobal
diff --git a/Src/filereader/filereader.vcxproj b/Src/filereader/filereader.vcxproj
new file mode 100644
index 00000000..c7a50630
--- /dev/null
+++ b/Src/filereader/filereader.vcxproj
@@ -0,0 +1,262 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{38F1536F-1CAB-41CE-80E1-E41D8965DF9E}</ProjectGuid>
+ <RootNamespace>filereader</RootNamespace>
+ <WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <LinkIncremental>false</LinkIncremental>
+ <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
+ <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
+ <TargetExt>.w5s</TargetExt>
+ <IncludePath>$(IncludePath)</IncludePath>
+ <LibraryPath>$(LibraryPath)</LibraryPath>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <LinkIncremental>false</LinkIncremental>
+ <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
+ <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
+ <TargetExt>.w5s</TargetExt>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <LinkIncremental>false</LinkIncremental>
+ <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
+ <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
+ <TargetExt>.w5s</TargetExt>
+ <IncludePath>$(IncludePath)</IncludePath>
+ <LibraryPath>$(LibraryPath)</LibraryPath>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <LinkIncremental>false</LinkIncremental>
+ <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
+ <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
+ <TargetExt>.w5s</TargetExt>
+ </PropertyGroup>
+ <PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <VcpkgUseStatic>false</VcpkgUseStatic>
+ <VcpkgConfiguration>Debug</VcpkgConfiguration>
+ <VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
+ </PropertyGroup>
+ <PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
+ <VcpkgConfiguration>Debug</VcpkgConfiguration>
+ </PropertyGroup>
+ <PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
+ </PropertyGroup>
+ <PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>../Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;FILEREADER_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>false</MinimalRebuild>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <SubSystem>Windows</SubSystem>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <ImportLibrary>$(ProjectDir)x86_Debug\$(ProjectName).lib</ImportLibrary>
+ <TargetMachine>MachineX86</TargetMachine>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ </Link>
+ <PostBuildEvent>
+ <Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\
+xcopy /Y /D $(IntDir)$(TargetName).pdb ..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\</Command>
+ <Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\'</Message>
+ </PostBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>../Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN64;_DEBUG;_WINDOWS;_USRDLL;FILEREADER_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>false</MinimalRebuild>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <SubSystem>Windows</SubSystem>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <ImportLibrary>$(ProjectDir)x64_Debug\$(ProjectName).lib</ImportLibrary>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ </Link>
+ <PostBuildEvent>
+ <Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\
+xcopy /Y /D $(IntDir)$(TargetName).pdb ..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\</Command>
+ <Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\'</Message>
+ </PostBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <Optimization>MinSpace</Optimization>
+ <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
+ <AdditionalIncludeDirectories>../Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;FILEREADER_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>true</BufferSecurityCheck>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>None</DebugInformationFormat>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <GenerateDebugInformation>false</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <ImportLibrary>$(ProjectDir)x86_Release\$(ProjectName).lib</ImportLibrary>
+ <TargetMachine>MachineX86</TargetMachine>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ </Link>
+ <PostBuildEvent>
+ <Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\</Command>
+ <Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\'</Message>
+ </PostBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <Optimization>MinSpace</Optimization>
+ <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
+ <AdditionalIncludeDirectories>../Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN64;NDEBUG;_WINDOWS;_USRDLL;FILEREADER_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>true</BufferSecurityCheck>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>None</DebugInformationFormat>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <GenerateDebugInformation>false</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <ImportLibrary>$(ProjectDir)x64_Release\$(ProjectName).lib</ImportLibrary>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ </Link>
+ <PostBuildEvent>
+ <Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\</Command>
+ <Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\'</Message>
+ </PostBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClInclude Include="..\Wasabi\api\service\svcs\svc_fileread.h" />
+ <ClInclude Include="api__filereader.h" />
+ <ClInclude Include="HTTPReader.h" />
+ <ClInclude Include="HTTPReaderFactory.h" />
+ <ClInclude Include="ProgressiveHTTPReader.h" />
+ <ClInclude Include="resource.h" />
+ <ClInclude Include="ResourceReader.h" />
+ <ClInclude Include="ResourceReaderFactory.h" />
+ <ClInclude Include="WA5_FileReader.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="HTTPReader.cpp" />
+ <ClCompile Include="HTTPReaderFactory.cpp" />
+ <ClCompile Include="main.cpp" />
+ <ClCompile Include="ProgressiveHTTPReader.cpp" />
+ <ClCompile Include="ResourceReader.cpp" />
+ <ClCompile Include="ResourceReaderFactory.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="filereader.rc" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\Wasabi\Wasabi.vcxproj">
+ <Project>{3e0bfa8a-b86a-42e9-a33f-ec294f823f7f}</Project>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/Src/filereader/filereader.vcxproj.filters b/Src/filereader/filereader.vcxproj.filters
new file mode 100644
index 00000000..bcf50a67
--- /dev/null
+++ b/Src/filereader/filereader.vcxproj.filters
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <ClCompile Include="HTTPReader.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="HTTPReaderFactory.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="main.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="ProgressiveHTTPReader.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="ResourceReader.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="ResourceReaderFactory.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="api__filereader.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="HTTPReader.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="HTTPReaderFactory.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="ProgressiveHTTPReader.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="resource.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="ResourceReader.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="ResourceReaderFactory.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\Wasabi\api\service\svcs\svc_fileread.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="WA5_FileReader.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{5683a5ef-1bac-41e8-950b-cc648c668de8}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Ressource Files">
+ <UniqueIdentifier>{51a86944-b123-42de-88b8-aaddf82d88b0}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{2c44f228-9ae0-4166-af3f-dd3a13078d46}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="filereader.rc">
+ <Filter>Ressource Files</Filter>
+ </ResourceCompile>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/Src/filereader/filereader.xcodeproj/project.pbxproj b/Src/filereader/filereader.xcodeproj/project.pbxproj
new file mode 100644
index 00000000..b4c61e75
--- /dev/null
+++ b/Src/filereader/filereader.xcodeproj/project.pbxproj
@@ -0,0 +1,208 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 42;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 0CD00E6A0BC0976B0014D897 /* HTTPReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0CD00E680BC0976B0014D897 /* HTTPReader.cpp */; };
+ 0CD00E6B0BC0976B0014D897 /* HTTPReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 0CD00E690BC0976B0014D897 /* HTTPReader.h */; };
+ 0CD00F390BC09D520014D897 /* api.h in Headers */ = {isa = PBXBuildFile; fileRef = 0CD00F380BC09D520014D897 /* api.h */; };
+ 0CD00F7A0BC09EA20014D897 /* HTTPReaderFactory.h in Headers */ = {isa = PBXBuildFile; fileRef = 0CD00F780BC09EA20014D897 /* HTTPReaderFactory.h */; };
+ 0CD00F7B0BC09EA20014D897 /* HTTPReaderFactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0CD00F790BC09EA20014D897 /* HTTPReaderFactory.cpp */; };
+ 0CD00F810BC09EB10014D897 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0CD00F800BC09EB10014D897 /* main.cpp */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXFileReference section */
+ 0CD00E680BC0976B0014D897 /* HTTPReader.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = HTTPReader.cpp; sourceTree = "<group>"; };
+ 0CD00E690BC0976B0014D897 /* HTTPReader.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = HTTPReader.h; sourceTree = "<group>"; };
+ 0CD00F380BC09D520014D897 /* api.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = api.h; sourceTree = "<group>"; };
+ 0CD00F780BC09EA20014D897 /* HTTPReaderFactory.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = HTTPReaderFactory.h; sourceTree = "<group>"; };
+ 0CD00F790BC09EA20014D897 /* HTTPReaderFactory.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = HTTPReaderFactory.cpp; sourceTree = "<group>"; };
+ 0CD00F800BC09EB10014D897 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = "<group>"; };
+ D2AAC0630554660B00DB518D /* filereader.w5s */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = filereader.w5s; sourceTree = BUILT_PRODUCTS_DIR; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ D289988505E68E00004EDB86 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 08FB7794FE84155DC02AAC07 /* filereader */ = {
+ isa = PBXGroup;
+ children = (
+ 08FB7795FE84155DC02AAC07 /* Source */,
+ 1AB674ADFE9D54B511CA2CBB /* Products */,
+ );
+ name = filereader;
+ sourceTree = "<group>";
+ };
+ 08FB7795FE84155DC02AAC07 /* Source */ = {
+ isa = PBXGroup;
+ children = (
+ 0CD00F800BC09EB10014D897 /* main.cpp */,
+ 0CD00F780BC09EA20014D897 /* HTTPReaderFactory.h */,
+ 0CD00F790BC09EA20014D897 /* HTTPReaderFactory.cpp */,
+ 0CD00E680BC0976B0014D897 /* HTTPReader.cpp */,
+ 0CD00E690BC0976B0014D897 /* HTTPReader.h */,
+ 0CD00F380BC09D520014D897 /* api.h */,
+ );
+ name = Source;
+ sourceTree = "<group>";
+ };
+ 1AB674ADFE9D54B511CA2CBB /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ D2AAC0630554660B00DB518D /* filereader.w5s */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXHeadersBuildPhase section */
+ D2AAC0600554660B00DB518D /* Headers */ = {
+ isa = PBXHeadersBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 0CD00E6B0BC0976B0014D897 /* HTTPReader.h in Headers */,
+ 0CD00F390BC09D520014D897 /* api.h in Headers */,
+ 0CD00F7A0BC09EA20014D897 /* HTTPReaderFactory.h in Headers */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXHeadersBuildPhase section */
+
+/* Begin PBXNativeTarget section */
+ D2AAC0620554660B00DB518D /* filereader */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 1DEB914A08733D8E0010E9CD /* Build configuration list for PBXNativeTarget "filereader" */;
+ buildPhases = (
+ D2AAC0600554660B00DB518D /* Headers */,
+ D2AAC0610554660B00DB518D /* Sources */,
+ D289988505E68E00004EDB86 /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = filereader;
+ productName = filereader;
+ productReference = D2AAC0630554660B00DB518D /* filereader.w5s */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 08FB7793FE84155DC02AAC07 /* Project object */ = {
+ isa = PBXProject;
+ buildConfigurationList = 1DEB914E08733D8E0010E9CD /* Build configuration list for PBXProject "filereader" */;
+ hasScannedForEncodings = 1;
+ mainGroup = 08FB7794FE84155DC02AAC07 /* filereader */;
+ projectDirPath = "";
+ targets = (
+ D2AAC0620554660B00DB518D /* filereader */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXSourcesBuildPhase section */
+ D2AAC0610554660B00DB518D /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 0CD00E6A0BC0976B0014D897 /* HTTPReader.cpp in Sources */,
+ 0CD00F7B0BC09EA20014D897 /* HTTPReaderFactory.cpp in Sources */,
+ 0CD00F810BC09EB10014D897 /* main.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin XCBuildConfiguration section */
+ 1DEB914B08733D8E0010E9CD /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COPY_PHASE_STRIP = NO;
+ EXECUTABLE_EXTENSION = w5s;
+ EXECUTABLE_PREFIX = "";
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_ENABLE_FIX_AND_CONTINUE = YES;
+ GCC_MODEL_TUNING = G5;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ INSTALL_PATH = /usr/local/lib;
+ PRODUCT_NAME = filereader;
+ ZERO_LINK = YES;
+ };
+ name = Debug;
+ };
+ 1DEB914C08733D8E0010E9CD /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ARCHS = (
+ ppc,
+ i386,
+ );
+ EXECUTABLE_PREFIX = lib;
+ GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
+ GCC_MODEL_TUNING = G5;
+ INSTALL_PATH = /usr/local/lib;
+ PRODUCT_NAME = filereader;
+ };
+ name = Release;
+ };
+ 1DEB914F08733D8E0010E9CD /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ HEADER_SEARCH_PATHS = ../Wasabi;
+ PREBINDING = NO;
+ SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk;
+ };
+ name = Debug;
+ };
+ 1DEB915008733D8E0010E9CD /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ PREBINDING = NO;
+ SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk;
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 1DEB914A08733D8E0010E9CD /* Build configuration list for PBXNativeTarget "filereader" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 1DEB914B08733D8E0010E9CD /* Debug */,
+ 1DEB914C08733D8E0010E9CD /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 1DEB914E08733D8E0010E9CD /* Build configuration list for PBXProject "filereader" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 1DEB914F08733D8E0010E9CD /* Debug */,
+ 1DEB915008733D8E0010E9CD /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 08FB7793FE84155DC02AAC07 /* Project object */;
+}
diff --git a/Src/filereader/main.cpp b/Src/filereader/main.cpp
new file mode 100644
index 00000000..749e510a
--- /dev/null
+++ b/Src/filereader/main.cpp
@@ -0,0 +1,77 @@
+#include "api__filereader.h"
+#include "WA5_FileReader.h"
+#ifdef _WIN32
+#include "ResourceReaderFactory.h"
+#endif
+#include "HTTPReaderFactory.h"
+#include <bfc/platform/export.h>
+
+#ifdef _WIN32
+ResourceReaderFactory resourceReaderFactory;
+#endif
+
+HTTPReaderFactory httpReaderFactory;
+WA5_FileReader wa5_FileReader;
+api_service *WASABI_API_SVC=0;
+api_application *WASABI_API_APP=0;
+api_config *AGAVE_API_CONFIG=0;
+
+void WA5_FileReader::RegisterServices(api_service *service)
+{
+ WASABI_API_SVC = service;
+ waServiceFactory *sf = WASABI_API_SVC->service_getServiceByGuid(applicationApiServiceGuid);
+ if (sf)
+ WASABI_API_APP = (api_application *)sf->getInterface();
+ sf = WASABI_API_SVC->service_getServiceByGuid(AgaveConfigGUID);
+ if (sf)
+ AGAVE_API_CONFIG = (api_config *)sf->getInterface();
+
+ if (WASABI_API_APP && AGAVE_API_CONFIG)
+ WASABI_API_SVC->service_register(&httpReaderFactory);
+
+#ifdef _WIN32
+ WASABI_API_SVC->service_register(&resourceReaderFactory);
+#endif
+}
+
+int WA5_FileReader::RegisterServicesSafeModeOk()
+{
+ return 1;
+}
+
+void WA5_FileReader::DeregisterServices(api_service *service)
+{
+
+ if (WASABI_API_APP && AGAVE_API_CONFIG)
+ service->service_deregister(&httpReaderFactory);
+#ifdef _WIN32
+ service->service_deregister(&resourceReaderFactory);
+#endif
+ waServiceFactory *sf=0;
+ if (WASABI_API_APP)
+ {
+ sf = WASABI_API_SVC->service_getServiceByGuid(applicationApiServiceGuid);
+ if (sf)
+ sf->releaseInterface(WASABI_API_APP);
+ }
+
+ if (AGAVE_API_CONFIG)
+ {
+ sf = WASABI_API_SVC->service_getServiceByGuid(AgaveConfigGUID);
+ if (sf)
+ sf->releaseInterface(AGAVE_API_CONFIG);
+ }
+}
+
+extern "C" DLLEXPORT ifc_wa5component *GetWinamp5SystemComponent()
+{
+ return &wa5_FileReader;
+}
+
+#define CBCLASS WA5_FileReader
+START_DISPATCH;
+VCB(API_WA5COMPONENT_REGISTERSERVICES, RegisterServices)
+CB(15, RegisterServicesSafeModeOk)
+VCB(API_WA5COMPONENT_DEREEGISTERSERVICES, DeregisterServices)
+END_DISPATCH;
+#undef CBCLASS
diff --git a/Src/filereader/resource.h b/Src/filereader/resource.h
new file mode 100644
index 00000000..55aaf21d
--- /dev/null
+++ b/Src/filereader/resource.h
@@ -0,0 +1,14 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by filereader.rc
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 101
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1001
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/Src/filereader/version.rc2 b/Src/filereader/version.rc2
new file mode 100644
index 00000000..81339260
--- /dev/null
+++ b/Src/filereader/version.rc2
@@ -0,0 +1,39 @@
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+#include "../Winamp/buildType.h"
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION WINAMP_PRODUCTVER
+ PRODUCTVERSION WINAMP_PRODUCTVER
+ FILEFLAGSMASK 0x17L
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "CompanyName", "Winamp SA"
+ VALUE "FileDescription", "Winamp 5.x System Component"
+ VALUE "FileVersion", STR_WINAMP_PRODUCTVER
+ VALUE "InternalName", "filereader.w5s"
+ VALUE "LegalCopyright", "Copyright © 2005-2023 Winamp SA"
+ VALUE "LegalTrademarks", "Nullsoft and Winamp are trademarks of Winamp SA"
+ VALUE "OriginalFilename", "filereader.w5s"
+ VALUE "ProductName", "Winamp File Reader Service"
+ VALUE "ProductVersion", STR_WINAMP_PRODUCTVER
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END