⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 downloadmanager.cpp

📁 FreeAMP(MP3播放)程序源代码-用来研究MP3解码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
        }    
    }

    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 + -