winamp/Src/filereader/ProgressiveHTTPReader.cpp

88 lines
2.3 KiB
C++

/** (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;
}