📄 downloadmanager.cpp
字号:
}
}
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 ||
item->GetState() == kDownloadItemState_Error))
{
ostringstream ost;
char num[256];
const char* kDatabaseDelimiter = " ";
MetaData metadata = item->GetMetaData();
if (item->GetState() == kDownloadItemState_Error)
item->SetState(kDownloadItemState_Queued);
// 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());
if (item->MTime().length())
{
int iTimeSize = strlen(num) + 1 + item->MTime().length();
ost << iTimeSize << kDatabaseDelimiter;
}
else
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();
if (item->MTime().length())
ost << " " << item->MTime();
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 = string(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]));
break;
case 1:
item->SetSourceCookie(data.substr(count, fieldLength[j]));
break;
case 2:
item->SetDestinationFile(data.substr(count, fieldLength[j]));
break;
case 3:
item->SetPlaylistName(data.substr(count, fieldLength[j]));
break;
case 4:
item->SetTotalBytes(atoi(data.substr(count, fieldLength[j]).c_str()));
break;
case 5:
{
string val;
string::size_type pos;
val = data.substr(count, fieldLength[j]).c_str();
item->SetBytesReceived(atoi(val.c_str()));
pos = val.find(string(" "), 0);
if (pos != string::npos)
{
val.erase(0, pos + 1);
item->SetMTime(val.c_str());
}
break;
}
case 6:
metadata.SetArtist(data.substr(count, fieldLength[j]));
break;
case 7:
metadata.SetAlbum(data.substr(count, fieldLength[j]));
break;
case 8:
metadata.SetTitle(data.substr(count, fieldLength[j]));
break;
case 9:
metadata.SetComment(data.substr(count, fieldLength[j]));
break;
case 10:
metadata.SetGenre(data.substr(count, fieldLength[j]));
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;
}
Error DownloadManager::Connect(int hHandle, const sockaddr *pAddr,
int &iRet, DownloadItem *item)
{
fd_set sSet;
struct timeval sTv;
#if defined(WIN32)
unsigned long lMicrosoftSucksBalls = 1;
ioctlsocket(hHandle, FIONBIO, &lMicrosoftSucksBalls);
#elif defined(__BEOS__)
// int on = 1;
// setsockopt( hHandle, SOL_SOCKET, SO_NONBLOCK, &on, sizeof( on ) );
#else
fcntl(hHandle, F_SETFL, fcntl(hHandle, F_GETFL) | O_NONBLOCK);
#endif
iRet = connect(hHandle, (const sockaddr *)pAddr,sizeof(*pAddr));
#ifndef WIN32
if (iRet == -1 && errno != EINPROGRESS)
{
perror("connect");
return kError_NoErr;
}
#endif
for(; iRet && !m_exit &&
item->GetState() == kDownloadItemState_Downloading;)
{
sTv.tv_sec = 0; sTv.tv_usec = 0;
FD_ZERO(&sSet); FD_SET(hHandle, &sSet);
iRet = select(hHandle + 1, NULL, &sSet, NULL, &sTv);
if (!iRet)
{
usleep(100000);
continue;
}
if (iRet < 0)
return kError_NoErr;
break;
}
if (m_exit || item->GetState() != kDownloadItemState_Downloading)
return kError_Interrupt;
return kError_NoErr;
}
Error DownloadManager::Recv(int hHandle, char *pBuffer, int iSize,
int iFlags, int &iRead, DownloadItem *item)
{
fd_set sSet;
struct timeval sTv;
int iRet;
iRead = 0;
for(; !m_exit && item->GetState() == kDownloadItemState_Downloading;)
{
sTv.tv_sec = 0; sTv.tv_usec = 0;
FD_ZERO(&sSet); FD_SET(hHandle, &sSet);
iRet = select(hHandle + 1, &sSet, NULL, NULL, &sTv);
if (!iRet)
{
usleep(10000);
continue;
}
iRead = recv(hHandle, pBuffer, iSize, iFlags);
if (iRead < 0)
{
return kError_NoErr;
}
break;
}
if (m_exit || item->GetState() != kDownloadItemState_Downloading)
return kError_Interrupt;
return kError_NoErr;
}
Error DownloadManager::Send(int hHandle, char *pBuffer, int iSize,
int iFlags, int &iRead, DownloadItem *item)
{
fd_set sSet;
struct timeval sTv;
int iRet;
iRead = 0;
for(; !m_exit && item->GetState() == kDownloadItemState_Downloading;)
{
sTv.tv_sec = 0; sTv.tv_usec = 0;
FD_ZERO(&sSet); FD_SET(hHandle, &sSet);
iRet = select(hHandle + 1, NULL, &sSet, NULL, &sTv);
if (!iRet)
{
usleep(10000);
continue;
}
iRead = send(hHandle, pBuffer, iSize, iFlags);
if (iRead < 0)
{
perror("Send failed:");
return kError_NoErr;
}
break;
}
if (m_exit || item->GetState() != kDownloadItemState_Downloading)
return kError_Interrupt;
return kError_NoErr;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -