diff --git a/core/deps/chdr/chdr.cpp b/core/deps/chdr/chdr.cpp index ba765b6c2..af700f15b 100644 --- a/core/deps/chdr/chdr.cpp +++ b/core/deps/chdr/chdr.cpp @@ -302,22 +302,239 @@ static const codec_interface codec_interfaces[] = }, }; +#pragma comment (lib, "wsock32.lib") +#include +#include -int core_fread(FILE* f, void* buff, size_t len) -{ - return fread(buff,1,len,f); +size_t HTTP_GET(string host, int port,string path, size_t offs, size_t len, void* pdata){ + string request; + string response; + int resp_leng; + + struct sockaddr_in serveraddr; + int sock; + + std::stringstream request2; + + if (len) { + request2 << "GET " << path << " HTTP/1.1"<h_addr_list[0]; + serveraddr.sin_port = htons((unsigned short) port); + if (connect(sock, (struct sockaddr *) &serveraddr, sizeof(serveraddr)) < 0) + return -1; + + BOOL v = FALSE; + + setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (const char*)&v, sizeof(v)); + //send request + if (send(sock, request.c_str(), request.length(), 0) != request.length()) + return -1; + + /* + //get response + response = ""; + resp_leng= BUFFERSIZE; + + */ + + /* + parse headers .. + */ + size_t content_length = 0; + + for (;;) { + stringstream ss; + for (;;) { + char t; + if (recv(sock, &t, 1, 0) <= 0) + goto _cleanup; + + if (t != '\n'){ + ss << t; + continue; + } + + string ln = ss.str(); + + if (ln.size() == 1) + goto _data; + string CL = "Content-Length:"; + + if (ln.substr(0, CL.size()) == CL) { + sscanf(ln.substr(CL.size(), ln.npos).c_str(),"%d", &content_length); + } + + break; + } + } + +_data: + + size_t rv = content_length; + if (len == 0) { + + } + else { + verify(len == content_length); + u8* ptr = (u8*)pdata; + do + { + int rcv = recv(sock, (char*)ptr, len, 0); + verify(rcv > 0 && len>= rcv); + len -= rcv; + ptr += rcv; + } + while (len >0); + } + + _cleanup: + //disconnect + closesocket(sock); + + /* + //cleanup + WSACleanup(); + */ + + return rv; } -size_t core_fsize(FILE* f) + +struct CORE_FILE { + FILE* f; + string path; + size_t seek_ptr; + + string host; + int port; +}; + +core_file* core_fopen(const char* filename) { - size_t p=ftell(f); - fseek(f,0,SEEK_END); - size_t rv=ftell(f); - fseek(f,p,SEEK_SET); - return rv; + string p = filename; + + CORE_FILE* rv = new CORE_FILE(); + rv->f = 0; + rv->path = p; + + if (p.substr(0,7)=="http://") { + rv->host = p.substr(7,p.npos); + rv->host = rv->host.substr(0, rv->host.find_first_of("/")); + + rv->path = p.substr(p.find("/", 7), p.npos); + + rv->port = 80; + size_t pos = rv->host.find_first_of(":"); + if (pos != rv->host.npos) { + string port = rv->host.substr(pos, rv->host.npos ); + rv->host = rv->host.substr(0, rv->host.find_first_of(":")); + sscanf(port.c_str(),"%d",&rv->port); + } + } else { + rv->f = fopen(filename, "rb"); + } + + return (core_file*)rv; } -#define core_fseek fseek + +size_t core_fseek(core_file* fc, size_t offs, size_t origin) { + CORE_FILE* f = (CORE_FILE*)fc; + + if (origin == SEEK_SET) + f->seek_ptr = offs; + else if (origin == SEEK_CUR) + f->seek_ptr += offs; + else + die("Invalid code path"); + + if (f->f) + fseek((FILE*)f, f->seek_ptr, SEEK_SET); + + return 0; +} + +int core_fread(core_file* fc, void* buff, size_t len) +{ + CORE_FILE* f = (CORE_FILE*)fc; + + if (f->f) { + fread(buff,1,len,f->f); + } else { + HTTP_GET(f->host, f->port, f->path, f->seek_ptr, len, buff); + } + + f->seek_ptr += len; + + return len; +} + +int core_fclose(core_file* fc) +{ + CORE_FILE* f = (CORE_FILE*)fc; + + if (f->f) { + fclose((FILE*)f); + } + else { + + } + + delete f; + + return 0; +} + +size_t core_fsize(core_file* fc) +{ + CORE_FILE* f = (CORE_FILE*)fc; + + if (f->f) { + size_t p=ftell(f->f); + fseek(f->f,0,SEEK_END); + size_t rv=ftell(f->f); + fseek(f->f,p,SEEK_SET); + return rv; + } + else { + return HTTP_GET(f->host, f->port, f->path, 0, 0,0); + } +} + #define MIN min #define MAX max /*************************************************************************** @@ -593,7 +810,7 @@ chd_error chd_open(const wchar *filename, int mode, chd_file *parent, chd_file * } /* open the file */ - file=fopen(filename, "rb"); + file=core_fopen(filename); if (file == 0) { err = CHDERR_FILE_NOT_FOUND; @@ -610,7 +827,7 @@ chd_error chd_open(const wchar *filename, int mode, chd_file *parent, chd_file * cleanup: if ((err != CHDERR_NONE) && (file != NULL)) - fclose(file); + core_fclose(file); return err; } @@ -653,7 +870,7 @@ void chd_close(chd_file *chd) /* close the file */ if (chd->owns_file && chd->file != NULL) - fclose(chd->file); + core_fclose(chd->file); if (PRINTF_MAX_HUNK) printf("Max hunk = %d/%d\n", chd->maxhunk, chd->header.totalhunks); @@ -807,7 +1024,7 @@ chd_error chd_get_metadata(chd_file *chd, UINT32 searchtag, UINT32 searchindex, /* read the metadata */ outputlen = min(outputlen, metaentry.length); - fseek(chd->file, metaentry.offset + METADATA_HEADER_SIZE, SEEK_SET); + core_fseek(chd->file, metaentry.offset + METADATA_HEADER_SIZE, SEEK_SET); count = core_fread(chd->file, output, outputlen); if (count != outputlen) return CHDERR_READ_ERROR; diff --git a/core/deps/chdr/coretypes.h b/core/deps/chdr/coretypes.h index e7f39c4c1..de2a4a284 100644 --- a/core/deps/chdr/coretypes.h +++ b/core/deps/chdr/coretypes.h @@ -15,6 +15,7 @@ typedef s8 INT8; #define INLINE inline #endif -#define core_file FILE +//#define core_file FILE +typedef void* core_file; #define ARRAY_LENGTH(x) (sizeof(x)/sizeof(x[0])) \ No newline at end of file