Ok, working on writing better code, and creating samples of my work so I can perhaps get back into this field. I got my libcurl wrapper working for what I needed it for. So before I move on to adding some extra features to it that are common requests for libcurl wrappers, I would you guys to tear it up and tell me everything I did wrong, or at least ask me to explain why I did something one way when you can think of a better way.
I want to be able to take this code to interviews (once I expand it a bit) so be harsh on it.
Header:
Code:
#ifndef CURLWRAPPER_H
#define CURLWRAPPER_H
#include <curl/curl.h>
#include <string>
namespace Wraithan {
size_t writer(const char *data, size_t size, size_t nmemb, std::string *buffer);
class curlwrapper {
public:
static curlwrapper* getInstance();
~curlwrapper();
void addPost(const std::string &name,const std::string &content);
std::string fetchPage(const std::string &url,int usepost=0);
const std::string lastError();
void setCookiesFile(const std::string &cookieFile = "cookie.jar");
void destroyInstance();
private:
curlwrapper();
curlwrapper(const curlwrapper &c) {};
curlwrapper& operator=(const curlwrapper& c) { return *this; }
CURL *handle;
curl_httppost* post;
curl_httppost* last;
std::string writeBuffer;
char errorBuffer[CURL_ERROR_SIZE];
bool useCookies;
static curlwrapper* instance;
};
} //namespace Wraithan
#endif // CURLWRAPPER_H
CPP:
Code:
#include "curlwrapper.h"
namespace Wraithan {
size_t writer(const char *data, size_t size, size_t nmemb, std::string *buffer) {
size_t result = 0;
if (buffer != NULL) {
buffer->append(data,size*nmemb);
result = size * nmemb;
}
return result;
}
//public:
curlwrapper* curlwrapper::getInstance() {
if(instance == 0) {
instance = new curlwrapper;
}
return instance;
}
curlwrapper::~curlwrapper() {
/* Clean up everything */
curl_easy_cleanup(handle);
curl_global_cleanup();
}
void curlwrapper::addPost(const std::string &name,const std::string &content) {
curl_formadd(&post, &last,
CURLFORM_COPYNAME, name.c_str(),
CURLFORM_COPYCONTENTS, content.c_str(),
CURLFORM_END);
return;
}
std::string curlwrapper::fetchPage(const std::string &url,int usepost) {
if(usepost != 0) {
curl_easy_setopt(handle,CURLOPT_HTTPPOST,post);
}
curl_easy_setopt(handle,CURLOPT_URL,url.c_str());
if(curl_easy_perform(handle) == CURLE_OK) {
if(usepost != 0) {
curl_formfree(post);
}
std::string retval(writeBuffer);
writeBuffer = "";
return retval;
} else {
return "";
}
}
const std::string curlwrapper::lastError() {
return errorBuffer;
}
void curlwrapper::setCookiesFile(const std::string &cookieFile) {
curl_easy_setopt(handle,CURLOPT_COOKIEFILE,cookieFile.c_str());
curl_easy_setopt(handle,CURLOPT_COOKIEJAR,cookieFile.c_str());
useCookies = true;
return;
}
void curlwrapper::destroyInstance() {
delete instance;
return;
}
//Private:
curlwrapper::curlwrapper() {
/* Initiate libcurl */
curl_global_init(CURL_GLOBAL_ALL);
/* Get connection handle */
handle = curl_easy_init();
/* Set all standard options */
curl_easy_setopt(handle,CURLOPT_ERRORBUFFER,&errorBuffer);
curl_easy_setopt(handle,CURLOPT_HEADER,0);
curl_easy_setopt(handle,CURLOPT_FOLLOWLOCATION,1);
curl_easy_setopt(handle,CURLOPT_WRITEFUNCTION,writer);
curl_easy_setopt(handle,CURLOPT_WRITEDATA,&writeBuffer);
/* NULL out post variables */
post = NULL;
last = NULL;
errorBuffer[0]='\0';
writeBuffer = "";
}
curlwrapper* curlwrapper::instance = 0;
} //namespace Wraithan
Also, this works so if someone needed a basic C++ wrapper for libcurl, here ya go!