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

📄 headlines.cpp

📁 freeamp有名的媒体播放器
💻 CPP
字号:
/*____________________________________________________________________________
        
   FreeAmp - The Free MP3 Player

   Copyright (C) 2000 EMusic.com

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
        
   $Id: Headlines.cpp,v 1.3.4.1.4.1 2000/04/10 23:10:09 robert Exp $
____________________________________________________________________________*/

#include <stdio.h> 
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>    

#ifdef WIN32
#include <io.h>
#else
#undef socklen_t
#include <sys/socket.h>
#include <netdb.h>
#include <unistd.h>
#endif

#if defined(unix) || defined(__BEOS__)
#define SOCKET int
#endif

#if defined(unix)
#include <arpa/inet.h>
#define closesocket(x) close(x)
#define O_BINARY 0
#endif  

#include "Headlines.h"
#include "eventdata.h"
#include "event.h"
#include "debug.h"

#define DB printf("%s:%d\n", __FILE__, __LINE__);

HeadlineInfo::HeadlineInfo(const string &oUrl,
                           const string &oXMLPath, 
                           const string &oXMLURLPath, 
                           int iDownloadInterval,
                           int iHeadlineChangeInterval)
{
    m_oUrl = oUrl;
    m_oXMLPath = oXMLPath;
    m_oXMLURLPath = oXMLURLPath;
    m_iDownloadInterval = iDownloadInterval;
    m_iHeadlineChangeInterval = iHeadlineChangeInterval;
}

HeadlineInfo::~HeadlineInfo(void)
{

}

void HeadlineInfo::operator=(const HeadlineInfo &oOther)
{
    m_oUrl = oOther.m_oUrl;
    m_oXMLPath = oOther.m_oXMLPath;
    m_oXMLURLPath = oOther.m_oXMLURLPath;
    m_iDownloadInterval = oOther.m_iDownloadInterval;
    m_iHeadlineChangeInterval = oOther.m_iHeadlineChangeInterval;
}

Headlines::Headlines(FAContext * context)
{
    m_pContext = context;
    m_pWakeSem = new Semaphore();
    m_bPause = false;
    m_lLastDownload = 0;
    m_iIndex = 0;

    m_pThread = Thread::CreateThread();
    m_pThread->Create(worker_thread, this);
}

Headlines::~Headlines()
{

    delete m_pThread;
    delete m_pWakeSem;
}

void Headlines::SetInfo(HeadlineInfo &oInfo)
{
    m_oInfo = oInfo;
    m_lLastDownload = 0;
    m_iIndex = 0;
}

void Headlines::Pause(void)
{
    m_bPause = true;    
}

void Headlines::Resume(void)
{
    m_bPause = false;    
    m_pWakeSem->Signal();
}

void Headlines::worker_thread(void* arg)
{
    ((Headlines *)arg)->WorkerThread();
}

void Headlines::WorkerThread(void)
{
    time_t t;

    m_pWakeSem->Wait();

    for(;;)
    {
        if (m_bPause)
           m_pWakeSem->Wait();

        time(&t);
        if (m_lLastDownload + m_oInfo.m_iDownloadInterval < t || m_oHeadlines.size() == 0)
        {
            if (IsntError(Download()))
                m_lLastDownload = t;
        }

        if (m_oHeadlines.size())
        {
            m_iIndex = m_iIndex % m_oHeadlines.size();
            m_pContext->target->AcceptEvent(new HeadlineMessageEvent(
                    m_oHeadlines[m_iIndex].c_str(),
                    (m_iIndex >= m_oHeadlineURLs.size()) ? "" : 
                     m_oHeadlineURLs[m_iIndex].c_str()));
                                       
            m_iIndex++;
        }
        usleep(m_oInfo.m_iHeadlineChangeInterval * 1000000);
    }
}

Error Headlines::Download(void)
{
    string oPage;
    Error  eRet;

    m_pContext->target->AcceptEvent(new StatusMessageEvent("Downloading headlines..."));
    eRet = DownloadHeadlines(m_oInfo.m_oUrl, oPage);
    if (eRet != kError_NoErr)
    {
       m_pContext->target->AcceptEvent(new StatusMessageEvent("Headline download failed."));
       return eRet;
    }   

    m_pContext->target->AcceptEvent(new StatusMessageEvent(""));
    m_oHeadlines.clear(); 

    printf("Page: '%s'\n", oPage.c_str());
    eRet = ParseString(oPage);
    if (IsntError(eRet))
    {
        if (m_oHeadlines.size() != m_oHeadlineURLs.size())
            m_oHeadlineURLs.clear();
    }
    
    return eRet;
}

Error Headlines::BeginElement(string &oElement, AttrMap &oAttrMap)
{
    m_oPath += string("/") + oElement;

    return kError_NoErr;
}

Error Headlines::PCData(string &oData)
{
    if (m_oPath == m_oInfo.m_oXMLPath)
    {
        m_oHeadlines.push_back(oData);
        return kError_NoErr;
    }
    if (m_oPath == m_oInfo.m_oXMLURLPath)
    {
        m_oHeadlineURLs.push_back(oData);
        return kError_NoErr;
    }
    return kError_NoErr;
} 

Error Headlines::EndElement(string &oElement)
{
    char *pPtr;
    int   iOffset;

    pPtr = strrchr(m_oPath.c_str(), '/');
    if (pPtr == NULL)
       return kError_NoErr;

    iOffset = pPtr - m_oPath.c_str();
    m_oPath.erase(iOffset, m_oPath.length() - iOffset);

    return kError_NoErr;
}

const uint8 kHttpPort = 80;
const uint32 kMaxHostNameLen = 64;

Error Headlines::DownloadHeadlines(string &oUrl, string &oPage)
{
    Error result = kError_InvalidParam;

    char hostname[kMaxHostNameLen + 1];
    char localname[kMaxHostNameLen + 1];
    char proxyname[kMaxHostNameLen + 1];
    unsigned short port;
    struct sockaddr_in  addr;
    struct hostent      host;
    SOCKET s = -1;
    bool useProxy;
    char *buffer = NULL, *file;

    int32 numFields;
    uint32 length;

    result = kError_NoErr;  

    m_pContext->prefs->GetUseProxyServer(&useProxy);

    length = sizeof(proxyname);
    m_pContext->prefs->GetProxyServerAddress(proxyname, &length);

    if(useProxy)
    {
         numFields = sscanf(proxyname, "http://%[^:/]:%hu", hostname, &port);

         strcpy(proxyname, oUrl.c_str());
         file = proxyname;
    }
    else
    {
         numFields = sscanf(oUrl.c_str(), "http://%[^:/]:%hu", hostname, &port);
         file = strchr(oUrl.c_str() + 7, '/');
    }

    if(numFields < 1)
    {
         result = kError_InvalidURL;     
    }

    if(numFields < 2)
    {
         port = kHttpPort;
    }            

    // get hostname
    if(IsntError(result))
    {
        struct hostent* hostByName;
        struct hostent  hostByIP;

        //*m_debug << "gethostbyname: " << hostname << endl;
        hostByName = gethostbyname(hostname);

        // On some stacks a numeric IP address
        // will not parse with gethostbyname.  
        // If that didn't work try to convert it as a
        // numeric address before giving up.
        if(!hostByName)
        {
            static unsigned long ip;
            static char *addr_ptr[2] = {(char*)&ip, NULL};

            if((ip = inet_addr(hostname)) < 0) 
                result =  kError_CantFindHost;
            else
            {
                hostByIP.h_length = sizeof(uint32);
                hostByIP.h_addrtype = AF_INET;
                hostByIP.h_addr_list = (char**)&addr_ptr;
                hostByName = &hostByIP;
            }
        }

        if(IsntError(result))
        {
            memcpy(&host, hostByName, sizeof(struct hostent));
        }
    }

    // open socket
    if(IsntError(result))
    {
        memset(&addr, 0x00, sizeof(struct sockaddr_in));
        memcpy(&addr.sin_addr, host.h_addr, host.h_length);
        addr.sin_family= host.h_addrtype;
        addr.sin_port= htons(port); 

        s = socket(host.h_addrtype, SOCK_STREAM, 0);

        if(s < 0)
            result = kError_CantCreateSocket;
    }

    // connect and send request
    if(IsntError(result))
    {
        if(connect(s,(const struct sockaddr*)&addr, sizeof(struct sockaddr)))
            result = kError_CannotBind;

        if(IsntError(result))
        {
            gethostname(localname, kMaxHostNameLen);    

            const char* kHTTPQuery = "GET %s HTTP/1.1\n"
                                     "Host: %s\n"
                                     "Accept: */*\n" 
                                     "User-Agent: FreeAmp/%s\n\n";

            // the magic 58 is enough for fixed length time in
            // HTTP time format + 2 terabyte length range numbers.
            // the 2 extra bytes on the end is an extra \n and 0x00 byte
            char* query = new char[ strlen(kHTTPQuery) +
                                    strlen(file) +
                                    strlen(localname) +
                                        strlen(FREEAMP_VERSION)+ 2];

            sprintf(query, kHTTPQuery, file, localname, FREEAMP_VERSION);  

            int count;

            count = send(s, query, strlen(query), 0);
            if(count != (int)strlen(query))
            {
                result = kError_IOError;
            }

            delete [] query;
        }
    }

    // receive response
    if(IsntError(result))
    {
        uint32 bufferSize = 4096;
        int count;
        uint32 total = 0;

        buffer = (char*)malloc(bufferSize);

        result = kError_OutOfMemory;

        if(buffer)
        {
            result = kError_NoErr;

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

                    buffer = (char*) realloc(buffer, bufferSize);
                    if(!buffer)
                    {
                        result = kError_OutOfMemory;
                        break;
                    }
                }

                count = recv(s, buffer + total, bufferSize - total - 1, 0);
                if(count > 0)
                    total += count;
                else
                    break;
            }

            if (IsntError(result))
            {
                buffer[total] = 0;

                if (strstr(buffer, "\r\n\r\n"))
                   oPage = string(strstr(buffer, "\r\n\r\n") + 2);
                else
                   oPage = string(buffer);
            }
        }
    }

    // cleanup
    if(s > 0)
        closesocket(s);

    free(buffer);

    return result;
}

⌨️ 快捷键说明

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