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

📄 downloadmanager.cpp

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

                delete [] query;
            }
        }

        // receive response
        if(IsntError(result))
        {
            uint32 bufferSize = 2048;
            char* buffer = NULL;
            int count;
            uint32 total = 0;

            buffer = (char*)malloc(bufferSize);

            result = kError_OutOfMemory;

            if(buffer)
            {
                Error err;
                result = kError_NoErr;

                do
                {
                    if(total >= bufferSize - 1)
                    {
                        bufferSize *= 2;

                        buffer = (char*) realloc(buffer, bufferSize);

                        if(!buffer)
                        {
                            result = kError_OutOfMemory;
                            break;
                        }
                    }

                    err = Recv(s, buffer + total, bufferSize - total - 1, 0, count, item);
                    if (IsError(err))
                        result = kError_UserCancel;

                    if(count > 0)
                        total += count;
                    else
                    {
                        result = kError_IOError;
                    }

                    if(item->GetState() != kDownloadItemState_Downloading)
                        result = kError_UserCancel;


                }while(IsntError(result) && !IsHTTPHeaderComplete(buffer, total));
            }

            // parse header
            if(IsntError(result))
            {
                uint32 returnCode = atoi(buffer+9);
                buffer[total] = 0x00;
                //cout << buffer << endl;

                //cout << returnCode << endl;

                switch(buffer[9])
                {
                    // 1xx: Informational - Request received, continuing process
                    case '1':
                    {
                        // not sure what to do here... continue receiving???
                    }    

                    // 2xx: Success - The action was successfully received,
                    // understood, and accepted
                    case '2':
                    {
                        result = kError_UnknownErr;

                        int32 fileSize = GetContentLengthFromHeader(buffer);
                
                        //cout << destPath << endl;

                        int openFlags = O_BINARY|O_CREAT|O_RDWR|O_APPEND;

                        if(returnCode != 206) // server didn't ok partial
                        {
                            string mTime;

                            item->SetBytesReceived(0);
                            openFlags |= O_TRUNC;
                            
                            GetContentTimeFromHeader(buffer, mTime);
                            item->SetMTime(mTime.c_str());
                            if(fileSize > 0)
                               item->SetTotalBytes(fileSize);
                        }

                        int fd = open(destPath, openFlags, S_IREAD | S_IWRITE);

                        if(fd >= 0)
                        {
                            Error err;

                            lseek(fd, 0, SEEK_END);

                            result = kError_NoErr;
                            int wcount = 0;

                            char* cp = strstr(buffer, "\n\n");

                            if(cp)
                                cp += 2;
                            else
                            {
                                cp = strstr(buffer, "\r\n\r\n");

                                if(cp)
                                    cp += 4;
                            }

                            if(cp)
                            {
                                if(cp - buffer < (int)total)
                                {
                                    wcount = write(fd, cp, total - (cp - buffer));
                                    item->SetBytesReceived(total - (cp - buffer) + item->GetBytesReceived());
                                    SendProgressMessage(item);
                                }
                            }

                            do
                            {
                            
                                err = Recv(s, buffer, bufferSize, 0, count, item);
                                if (IsError(err))
                                    result = kError_UserCancel;
                                else 
                                   if(count > 0)
                                   {
                                       wcount = write(fd, buffer, count);
                                       item->SetBytesReceived(count + item->GetBytesReceived());
                                       SendProgressMessage(item);
                                   }

                                if(count < 0) 
                                    result = kError_IOError;
                                
                                if(wcount < 0)
                                    result = kError_WriteFile;

                                if(item->GetState() != kDownloadItemState_Downloading)
                                    result = kError_UserCancel;

                            }while(count > 0 && IsntError(result) && 
                                   m_runDownloadThread && wcount >= 0 && 
                                   (item->GetTotalBytes() > item->GetBytesReceived()));
                            close(fd);                           
                        }
                        else
                        {
                            //*m_debug << "error opening  file: " <<  endl;

                            switch(errno)
                            {
                                case EEXIST:
                                    result = kError_FileExists;
                                    break;

                                case EACCES:
                                    result = kError_FileNoAccess;
                                    break;

                                case ENOENT:
                                    result = kError_FileNotFound;
                                    break;

                                case EMFILE:
                                    result = kError_FileNoHandles;
                                    break;

                                case EINVAL:
                                    result = kError_FileInvalidArg;
                                    break;
                
                            }
                        }
                        
                        break;
                    }

                    // 3xx: Redirection - Further action must be taken in order to
                    // complete the request
                    case '3':
                    {
                        char* cp = strstr(buffer, "Location:");
                        //int32 length;

                        if(cp)
                        {
                            cp += 9;

                            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)))
        {
            PlaylistItem *newtrack;
            
            if (item->IsNormalDownload())
               newtrack = new PlaylistItem(url);
            else   
               newtrack = new PlaylistItem(url, &(item->GetMetaData()));
               
            m_context->plm->RetrieveMetaDataNow(newtrack);

            MetaData tempdata = (MetaData)(newtrack->GetMetaData());
            m_context->catalog->WriteMetaDataToDatabase(url, tempdata);
            m_context->catalog->AddSong(url);

            delete newtrack;
        }

        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);
                if (result != kError_IOError)
                    CleanUpDownload(item);
            }

            item->SetDownloadError(result);

            SendStateChangedMessage(item);
        }
        else
        {
            m_queueSemaphore.Wait();

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -