[C/C++] cURL C++ Wrapper

Dieses Thema im Forum "Projekte / Codes" wurde erstellt von terraNova, 23. Dezember 2010 .

Schlagworte:
  1. 23. Dezember 2010
    cURL C++ Wrapper

    Heyho

    Hab für mein Projekt 'nen kleinen cURL Wrapper geschrieben. Ist nur ne vorläufige Version und falls ich das Teil noch überarbeite werde ich den Code im Thread mit Datum aktualisieren.

    Beispiel:
    Spoiler
    Code:
    #include <iostream>
    #include "curl.h"
    
    using namespace std;
    
    int main( void ) {
     cURL curl;
    
     curl.Download("http://ftp.gwdg.de/pub/linux/slackware/unsupported/bootdisks/speakaha.s", "test.txt");
     cout << curl.getDLSpeed()/1024 << " kbps\n";
    
     return 0;
    }
    

    curl.h:
    Spoiler
    Code:
    #ifndef CURL_H_
    #define CURL_H_
    
    #include <curl/curl.h>
    #include <vector>
    #include <ctime>
    
    namespace {
     class cURL_Init {
     public:
     cURL_Init() {
    # ifdef WIN32
     curl_global_init(CURL_GLOBAL_WIN32);
    # else
     curl_global_init(CURL_GLOBAL_DEFAULT);
    # endif
     }
    
     ~cURL_Init() {
     curl_global_cleanup();
     }
     } ocURL_Init;
    } /* ns _anon_ */;
    
    class cURLEvent;
    class cURL;
    
    struct cURLData {
     public:
     cURL *pHandle;
     
    // protected:
     time_t tUP,
     tDL,
    
     tDLQ,
     tUPQ;
    
     size_t bytesUP,
     bytesDL;
    
     public:
     cURLData() {
     pHandle = nullptr;
    
     tUP = 0; tDL = 0;
     tUPQ = 0; tDLQ = 0;
     bytesUP = 0; bytesDL = 0;
     }
    } /* struct cURLData */;
    
    class cURL { 
     friend class cURLEvent;
    
     private:
     CURL *hCURL;
     CURLcode lastErr;
     std::vector<char> cvBuffer;
     
     cURLData sData;
    
     public:
     cURL( void );
     ~cURL( void );
    
     void setParam( CURLoption option, void *param );
     void Process( void );
     void Download( const char* link, const char* save = nullptr );
    
     const char* getData( void );
     size_t getData( char *buffer, size_t bufsize = 0 );
     void clearData( void );
    
     CURLcode getError( void );
    
     float getDLSpeed( void );
     float getUPSpeed( void );
    
     protected:
     std::vector<char>& getBuffer( void );
    } /* class cURL */;
    
    class cURLEvent {
     public:
     static size_t Out(void *buffer, size_t size, size_t nmemb, void *udata);
     static size_t In(void *buffer, size_t size, size_t nmemb, void *udata);
    } /* class cURLEvent */;
    
    #endif /* CURL_H_ */
    

    curl.cpp
    Spoiler
    Code:
    #include "curl.h"
    
    //
    // CURL
    //
    cURL::cURL( void ) {
     hCURL = curl_easy_init();
    
     sData.pHandle = this;
    
     curl_easy_setopt(hCURL, CURLOPT_READFUNCTION, cURLEvent::Out);
     curl_easy_setopt(hCURL, CURLOPT_READDATA, &sData);
    
     curl_easy_setopt(hCURL, CURLOPT_WRITEFUNCTION, cURLEvent::In);
     curl_easy_setopt(hCURL, CURLOPT_WRITEDATA, &sData);
    
     curl_easy_setopt(hCURL, CURLOPT_VERBOSE, 0L);
    }
    
    cURL::~cURL( void ) {
     curl_easy_cleanup(hCURL);
    }
    
    void cURL::setParam( CURLoption option, void *param ) {
     lastErr = curl_easy_setopt(hCURL, option, param);
    }
    
    void cURL::Process( void ) {
     time_t tStart = time(0);
     
     lastErr = curl_easy_perform(hCURL);
     
     sData.tDL += (sData.tDLQ-tStart);
     sData.tUP += (sData.tUPQ-tStart);
    }
    
    void cURL::Download( const char* link, const char* save ) {
     setParam(CURLOPT_URL, (void*)(link));
     Process();
     
     if(save == nullptr)
     return;
     
     if(cvBuffer.empty() == true)
     return;
    
     FILE *fdOut = fopen(save, "a+");
     char *buf = new char[cvBuffer.size()];
    
     memset(buf, 0, cvBuffer.size());
     getData(buf, cvBuffer.size());
    
     fwrite(buf, cvBuffer.size(), 1, fdOut);
    
     delete [] buf;
     fclose(fdOut);
    }
    
    const char* cURL::getData ( void ) {
     static std::string out;
     out.assign(cvBuffer.begin(), cvBuffer.end());
     return out.c_str();
    }
    
    size_t cURL::getData( char *buffer, size_t bufsize ) {
     if(buffer != nullptr && bufsize >= bufsize) {
     memcpy(buffer, &cvBuffer[0], cvBuffer.size());
     }
     
     return cvBuffer.size();
    }
    
    void cURL::clearData( void ) {
     cvBuffer.clear();
    }
    
    CURLcode cURL::getError( void ) {
     return lastErr;
    }
    
    float cURL::getDLSpeed( void ) {
     time_t tDL = (sData.tDL == 0?1:sData.tDL);
     return (float)(sData.bytesDL/tDL);
    }
    
    float cURL::getUPSpeed( void ) {
     time_t tUP = (sData.tUP == 0?1:sData.tUP);
     return (float)(sData.bytesUP/tUP);
    }
    
    std::vector<char>& cURL::getBuffer( void ) {
     return cvBuffer;
    }
    
    //
    // CURL EVENT
    //
    size_t cURLEvent::Out( void *buffer, size_t size, size_t nmemb, void *udata ) {
     size_t totalSize = size*nmemb;
     cURLData *pCURL = reinterpret_cast<cURLData*>(udata);
    
     if(totalSize > 0) {
     pCURL->bytesUP += totalSize;
     pCURL->tUPQ = time(0);
     }
    
     return totalSize;
    }
    
    size_t cURLEvent::In( void *buffer, size_t size, size_t nmemb, void *udata ) {
     size_t totalSize = size*nmemb;
     cURLData *pCURL = reinterpret_cast<cURLData*>(udata);
    
     if(totalSize > 0) {
     pCURL->bytesDL += totalSize;
     pCURL->tDLQ = time(0);
    
     for(size_t i=0; i<totalSize; i++)
     pCURL->pHandle->getBuffer().push_back(reinterpret_cast<char*>(buffer)[i]);
     }
    
     return totalSize;
    }

    Sollte dank cURL Thread-Safe sein. Ich habe, da ich es in einem Projekt brauche, noch eine Upload und Speed Funktion eingebaut. Eventuell werde ich die cURLEvent Klasse noch überabeiten und einen globalen Container bauen, der dann auf das jeweilige cURLEvent Objekt zugreift, damit man die Klasse dann vererben kann und seine eigenen Funktionen einbauen kann (falls nötig).

    Benötigt wird natürlich cURL und zLib (Beides findet man auf der cURL-HP).

    Viel Spaß damit.
     
  2. Video Script

    Videos zum Themenbereich

    * gefundene Videos auf YouTube, anhand der Überschrift.