downloadmanager.cpp
字号:
if(*cp == 0x20)
cp++;
char *end;
for(end = cp; end < buffer + total; end++)
if(*end=='\r' || *end == '\n') break;
*end = 0x00;
if (305 == returnCode) // proxy
{
char* proxy = new char[strlen(cp) +
strlen(item->SourceURL().c_str()) + 1];
sprintf(proxy, "%s%s", cp, item->SourceURL().c_str());
item->SetSourceURL(proxy);
delete [] proxy;
}
else // redirect of some type
{
item->SetSourceURL(cp);
}
result = Download(item);
}
break;
}
// 4xx: Client Error - The request contains bad syntax or cannot
// be fulfilled
case '4':
{
//*m_debug << "HTTP Error: " << returnCode << endl;
switch(returnCode)
{
case 400:
result = kError_BadHTTPRequest;
break;
case 401:
result = kError_AccessNotAuthorized;
break;
case 403:
result = kError_DownloadDenied;
break;
case 404:
result = kError_HTTPFileNotFound;
break;
case 416:
// try to grab the whole thing...
item->SetBytesReceived(0);
result = Download(item);
break;
default:
result = kError_UnknownErr;
break;
}
break;
}
// 5xx: Server Error - The server failed to fulfill an apparently
// valid request
case '5':
{
result = kError_UnknownServerError;
break;
}
}
}
// cleanup
if(buffer)
free(buffer);
}
// cleanup
if(s > 0)
closesocket(s);
if(destPath)
delete [] destPath;
}
return result;
}
void DownloadManager::CleanUpDownload(DownloadItem* item)
{
//cout << "Cleaning item: " << item->SourceURL() << endl;
char path[_MAX_PATH];
uint32 length = sizeof(path);
m_context->prefs->GetPrefString(kSaveMusicDirPref, path, &length);
strcat(path, DIR_MARKER_STR);
strcat(path, item->DestinationFile().c_str());
remove(path);
item->SetBytesReceived(0);
}
Error DownloadManager::SubmitToDatabase(DownloadItem* item)
{
Error result = kError_InvalidParam;
assert(item);
if(item)
{
//cout << "Submitting item: " << item->SourceURL() << endl;
char path[_MAX_PATH];
uint32 length = sizeof(path);
m_context->prefs->GetPrefString(kSaveMusicDirPref, path, &length);
strcat(path, DIR_MARKER_STR);
strcat(path, item->DestinationFile().c_str());
uint32 urlLength = strlen(path) + 10;
char *url = new char[urlLength];
if (IsntError(FilePathToURL(path, url, &urlLength)))
{
if (!item->IsNormalDownload())
m_context->catalog->WriteMetaDataToDatabase(url,
item->GetMetaData());
m_context->catalog->AddSong(url);
}
delete [] url;
}
return result;
}
void DownloadManager::PauseDownloads(void)
{
m_downloadsPaused = true;
}
void DownloadManager::ResumeDownloads(void)
{
m_downloadsPaused = false;
m_queueSemaphore.Signal();
}
bool DownloadManager::IsPaused(void)
{
return m_downloadsPaused;
}
void DownloadManager::DownloadThreadFunction()
{
DownloadItem* item;
Error result;
m_quitMutex.Acquire();
while(m_runDownloadThread)
{
if (m_downloadsPaused)
{
m_queueSemaphore.Wait();
continue;
}
item = GetNextQueuedItem();
if(item)
{
item->SetState(kDownloadItemState_Downloading);
SendStateChangedMessage(item);
result = Download(item);
if(IsntError(result))
{
item->SetState(kDownloadItemState_Done);
result = SubmitToDatabase(item);
}
else
if(result == kError_UserCancel)
{
if(item->GetState() == kDownloadItemState_Cancelled)
{
CleanUpDownload(item);
}
}
else
{
item->SetState(kDownloadItemState_Error);
CleanUpDownload(item);
}
item->SetDownloadError(result);
SendStateChangedMessage(item);
}
else
{
m_queueSemaphore.Wait();
}
}
m_quitMutex.Release();
}
void DownloadManager::download_thread_function(void* arg)
{
DownloadManager* dlm = (DownloadManager*)arg;
dlm->DownloadThreadFunction();
}
// Messaging functions
void DownloadManager::SendItemAddedMessage(DownloadItem* item)
{
m_context->target->AcceptEvent(new DownloadItemAddedEvent(item));
}
void DownloadManager::SendItemRemovedMessage(DownloadItem* item)
{
m_context->target->AcceptEvent(new DownloadItemRemovedEvent(item));
}
void DownloadManager::SendStateChangedMessage(DownloadItem* item)
{
m_context->target->AcceptEvent(new DownloadItemNewStateEvent(item));
}
void DownloadManager::SendProgressMessage(DownloadItem* item)
{
m_context->target->AcceptEvent(new DownloadItemProgressEvent(item));
}
void DownloadManager::SaveResumableDownloadItems()
{
char path[_MAX_PATH];
uint32 length = sizeof(path);
m_context->prefs->GetPrefString(kDatabaseDirPref, path, &length);
if(DoesDBDirExist(path))
{
strcat(path, DIR_MARKER_STR);
strcat(path, "ResumeDownloadDB");
Database database(path);
if(database.Working())
{
uint32 size = 0;
DownloadItem* item = NULL;
size = m_itemList.size();
for(uint32 index = 0; index < size; index++)
{
item = m_itemList[index];
if(item &&
(item->GetState() == kDownloadItemState_Paused ||
item->GetState() == kDownloadItemState_Queued))
{
ostringstream ost;
char num[256];
const char* kDatabaseDelimiter = " ";
MetaData metadata = item->GetMetaData();
// write out the number of elements we have
ost << 16 << kDatabaseDelimiter;
// next record the length of each element
ost << item->SourceURL().size() << kDatabaseDelimiter;
ost << item->SourceCookie().size() << kDatabaseDelimiter;
ost << item->DestinationFile().size() << kDatabaseDelimiter;
ost << item->PlaylistName().size() << kDatabaseDelimiter;
sprintf(num, "%ld", (long int)item->GetTotalBytes());
ost << strlen(num) << kDatabaseDelimiter;
sprintf(num, "%ld", (long int)item->GetBytesReceived());
ost << strlen(num) << kDatabaseDelimiter;
// metadata lengths
ost << metadata.Artist().size() << kDatabaseDelimiter;
ost << metadata.Album().size() << kDatabaseDelimiter;
ost << metadata.Title().size() << kDatabaseDelimiter;
ost << metadata.Comment().size() << kDatabaseDelimiter;
ost << metadata.Genre().size() << kDatabaseDelimiter;
sprintf(num, "%ld", (long int)metadata.Year());
ost << strlen(num) << kDatabaseDelimiter;
sprintf(num, "%ld", (long int)metadata.Track());
ost << strlen(num) << kDatabaseDelimiter;
sprintf(num, "%ld", (long int)metadata.Time());
ost << strlen(num) << kDatabaseDelimiter;
sprintf(num, "%ld", (long int)metadata.Size());
ost << strlen(num) << kDatabaseDelimiter;
sprintf(num, "%ld", (long int)item->GetState());
ost << strlen(num) << kDatabaseDelimiter;
// now stuff all the data in there
ost << item->SourceURL();
ost << item->SourceCookie();
ost << item->DestinationFile();
ost << item->PlaylistName();
ost << item->GetTotalBytes();
ost << item->GetBytesReceived();
ost << metadata.Artist();
ost << metadata.Album();
ost << metadata.Title();
ost << metadata.Comment();
ost << metadata.Genre();
ost << metadata.Year();
ost << metadata.Track();
ost << metadata.Time();
ost << metadata.Size();
sprintf(num, "%ld", (long int)item->GetState());
ost << num;
ost << '\0';
sprintf(num, "%ld", (long int)index);
#ifdef WIN32
database.Insert(num, (char*)ost.str().c_str());
#else
database.Insert(num, (char*)ost.str());
#endif
}
}
}
}
}
void DownloadManager::LoadResumableDownloadItems()
{
char path[_MAX_PATH];
uint32 length = sizeof(path);
m_context->prefs->GetPrefString(kDatabaseDirPref, path, &length);
if(DoesDBDirExist(path))
{
strcat(path, DIR_MARKER_STR);
strcat(path, "ResumeDownloadDB");
Database database(path);
if(database.Working())
{
char *key = NULL;
while ((key = database.NextKey(key)))
{
char* value = database.Value(key);
if (!value)
continue;
uint32 numFields = 0;
int offset = 0;
sscanf(value,"%lu%n", (long unsigned int *)&numFields, &offset);
uint32* fieldLength = new uint32[numFields];
for(uint32 i = 0; i < numFields; i++)
{
int temp;
sscanf(value + offset, " %lu %n",
(long unsigned int *)&fieldLength[i], &temp);
if (i == numFields - 1) {
char intholder[10];
sprintf(intholder, "%lu",
(long unsigned int)fieldLength[i]);
offset += strlen(intholder) + 1;
}
else
offset += temp;
}
string data = value;
data.erase(0, offset);
delete value;
value = NULL;
DownloadItem* item = new DownloadItem();
MetaData metadata;
uint32 count = 0;
for(uint32 j = 0; j < numFields; j++)
{
switch(j)
{
case 0:
item->SetSourceURL(data.substr(count, fieldLength[j]).c_str());
break;
case 1:
item->SetSourceCookie(data.substr(count, fieldLength[j]).c_str());
break;
case 2:
item->SetDestinationFile(data.substr(count, fieldLength[j]).c_str());
break;
case 3:
item->SetPlaylistName(data.substr(count, fieldLength[j]).c_str());
break;
case 4:
item->SetTotalBytes(atoi(data.substr(count, fieldLength[j]).c_str()));
break;
case 5:
item->SetBytesReceived(atoi(data.substr(count, fieldLength[j]).c_str()));
break;
case 6:
metadata.SetArtist(data.substr(count, fieldLength[j]).c_str());
break;
case 7:
metadata.SetAlbum(data.substr(count, fieldLength[j]).c_str());
break;
case 8:
metadata.SetTitle(data.substr(count, fieldLength[j]).c_str());
break;
case 9:
metadata.SetComment(data.substr(count, fieldLength[j]).c_str());
break;
case 10:
metadata.SetGenre(data.substr(count, fieldLength[j]).c_str());
break;
case 11:
metadata.SetYear(atoi(data.substr(count, fieldLength[j]).c_str()));
break;
case 12:
metadata.SetTrack(atoi(data.substr(count, fieldLength[j]).c_str()));
break;
case 13:
metadata.SetTime(atoi(data.substr(count, fieldLength[j]).c_str()));
break;
case 14:
metadata.SetSize(atoi(data.substr(count, fieldLength[j]).c_str()));
break;
case 15:
item->SetState((DownloadItemState)atoi(data.substr(count, fieldLength[j]).c_str()));
break;
default:
break;
}
count += fieldLength[j];
}
delete [] fieldLength;
fieldLength = NULL;
item->SetMetaData(&metadata);
m_itemList.push_back(item);
SendItemAddedMessage(item);
}
while ((key = database.NextKey(NULL)))
{
database.Remove(key);
delete key;
}
}
}
}
bool DownloadManager::DoesDBDirExist(char* path)
{
bool result = false;
struct stat st;
if(-1 != stat(path, &st))
{
if(st.st_mode & S_IFDIR)
result = true;
}
return result;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -