EasyCurl简单封装了一下libcurl调用,对外的提供抽象化的接口,下面就把源码分享出来,此源码和接口还带进一步完善优化,尤其是一些curl_set_opt()的上层封装。大家可以自己写哈,最后写一个满足自己需求的Curl。
ubplus_curl.h : EasyCurl的类定义和接口,还有一些宏
/*
* =====================================================================================
*
* Filename: ubplus_curl.h
*
* Description: A curl wrapper of libcurl
*
* Created: 08/16/2012 04:55:34 PM
* Compiler: g++ 4.6.1
*
* Author: Michael LiuXin
*
* =====================================================================================
*/
#include <stdlib.h>
#include <stdint.h>
#include <memory.h>
#include <string>
#include <curl/curl.h>
//#define NO_USE_UB_LOG
#include "ub_log.h"
#define UBPLUS_CURL_OK 0 /* OK */
#define UBPLUS_CURL_GLOBAL_INIT_FAILD 1 /* curl_global_init */
#define UBPLUS_CURL_EASY_INIT_FAILD 2 /* curl_easy_init */
#define UBPLUS_CURL_PERFORM_FAILD 3 /* curl_easy_perform */
#define UBPLUS_CURL_SET_OPTION_FAILD 4 /* curl_easy_setopt */
#define UBPLUS_CURL_HANDLE_NOT_VAILD 5 /* CURL* bad*/
#define UBPLUS_CURL_URL_NOT_VAILD 6 /* url string bad */
#define UBPLUS_CURL_POST_NOT_VAILD 7 /* post data bad */
#define UBPLUS_CURL_USER_BUFFER_NOT_VAILD 8 /* user buffer bad */
#define UBPLUS_CURL_TIMEOUT_NOT_VAILD 9 /* time bad */
namespace ubplus
{
typedef size_t (*CURL_CALLBACK)(char*,size_t,size_t,void*);
extern const char* ERROR_MSG[];
/**
* Wrapper of libcurl
*/
class EasyCurl
{
public:
/**
* @brief : constructor , initialize libcrul
*/
EasyCurl();
/**
* @brief : destroy CURL*
*/
~EasyCurl();
/**
* @brief : do curl action
*
* @return : curl ok or not , get_error() will set
*/
int fetch();
/**
* @brief : set user's buffer , if we do fetch() then we
* write the content to buffer if user set their
* own callback , this buffer will ignore
*
* @param : [out] user buffer
* [in] buffer length
*
* @return : if buffer is invaild , get_error() will set
*/
int set_user_buffer(char** buf,size_t len);
/**
* @brief : give curl a callback which is called
* when fetched data is ready to copy
*
* @param : function pointer
*/
int set_curl_callback(CURL_CALLBACK);
/**
* @brief : pass to callback lastest param
*
* @param : function pointer
*/
int set_curl_callback_context(void*);
/**
* @brief : curl_set_opt(CURLOPT_URL)
*
* @param : [in] url , url string
*
* @return : if CURL* not vaild , get_error() will set
*/
int set_url(std::string url);
/**
* @brief : curl_set_opt(CURLOPT_TIMEOUT)
*
* @param : [in] timeout , time in seconds
*
* @return : if CURL* not vaild , get_error() will set
*/
int set_timeout(unsigned long time);
/**
* @brief : enable post method and set post data
*
* @param : [in] post , post data
*
* @return : if CURL* not vaild , get_error() will set
*/
int set_post_data(void* post);
/**
* @brief : test the curl is good to using
*
* @return : true , would be used
*/
bool is_good() {return this->is_good_;}
uint8_t get_error(){return this->error_;}
const char* get_error_msg(){return ERROR_MSG[this->error_];}
bool __global_init();
static size_t __data_callback(char*,size_t,size_t,void*);
static size_t total_size(){return total_size_;}
protected :
static bool global_init_;
/* user buffer */
typedef struct __curl_buffer {
__curl_buffer(){mem=NULL;offset=0;max=0;}
char* mem;
size_t offset;
size_t max;
}curl_buffer;
static curl_buffer user_buffer;
static size_t total_size_;
private :
CURL* curl_;
uint8_t error_;
bool is_good_;
}; // end of class
} // end of namespace
ubplus_curl.cc : 实现,用到了ub_log.h日志组件
/*
* =====================================================================================
*
* Filename: ubplus_curl.cc
*
* Description: A curl wrapper of libcurl
*
* Created: 08/16/2012 04:55:34 PM
* Compiler: g++ 4.6.1
*
* Author: Michael LiuXin
*
* =====================================================================================
*/
#include "ubplus_curl.h"
#define CURL_OK 0
namespace ubplus
{
#define CURL_GLOBAL_INIT_ONCE __global_init();
const char* ERROR_MSG[] = {
"EasyCurl OK",
"Global Init Failed",
"Easy Init Failed",
"Easy Perform Failed",
"Easy SetOption Failed",
"Curl Handle Not Vaild",
"Curl URL Not Vaild",
"Curl PostData Not Vaild",
"Curl User Buffer Not Vaild",
"Curl TimeOut Not Vaild",
"Unkown Error"
};
// ***********************************************************
size_t EasyCurl::__data_callback(char* content,size_t size,size_t n,void* null)
{
UB_LOG_DEBUG("[ok=curl] Default callback invoke");
// copy to buffer(this is from user) and ensure space is enough
if (NULL != EasyCurl::user_buffer.mem) {
size_t full = n*size;
// we have no space
if (EasyCurl::user_buffer.offset >= EasyCurl::user_buffer.max) {
UB_LOG_TRACE("[ok=curl] User buffer has no space , ignore ");
return full;
}
// as write enough as we can
size_t to_write = (EasyCurl::user_buffer.offset+n*size<EasyCurl::user_buffer.max
? n*size : (EasyCurl::user_buffer.max-EasyCurl::user_buffer.offset));
memcpy(EasyCurl::user_buffer.mem+EasyCurl::user_buffer.offset,content,to_write);
UB_LOG_DEBUG("[ok=memory] Copy memory to user buffer");
EasyCurl::user_buffer.offset += to_write;
EasyCurl::total_size_ += to_write;
}
return n*size;
}
// ***********************************************************
bool EasyCurl::__global_init()
{
if (!EasyCurl::global_init_) {
// call global init only one time
CURLcode code = curl_global_init(CURL_GLOBAL_ALL);
if (CURL_OK != code) {
this->is_good_ = false;
this->error_ = UBPLUS_CURL_GLOBAL_INIT_FAILD;
UB_LOG_FATAL("[err=curl] Curl global init error[%s]",curl_easy_strerror(code));
return false;
} else {
UB_LOG_TRACE("[ok=curl] Curl global init");
EasyCurl::global_init_ = true;
return true;
}
} else
return true;
}
// ***********************************************************
EasyCurl::EasyCurl()
{
CURL_GLOBAL_INIT_ONCE
// curl initial
this->curl_ = curl_easy_init();
if (!this->curl_) {
this->error_ = UBPLUS_CURL_EASY_INIT_FAILD;
this->is_good_ = false;
UB_LOG_WARNNING("[warn=curl] Curl easy init failed");
return;
} else {
// set our default write function
if (CURL_OK != curl_easy_setopt(this->curl_,CURLOPT_WRITEFUNCTION,EasyCurl::__data_callback)) {
this->error_ = UBPLUS_CURL_SET_OPTION_FAILD;
this->is_good_ = false;
} else {
this->error_ = UBPLUS_CURL_OK;
this->is_good_ = true;
}
}
}
// ***********************************************************
EasyCurl::~EasyCurl()
{
if (this->curl_) {
UB_LOG_DEBUG("[ok=curl] Curl cleanup ok");
curl_easy_cleanup(this->curl_);
}
}
// ***********************************************************
int EasyCurl::set_curl_callback(CURL_CALLBACK func)
{
if (!this->curl_ || !this->is_good_)
return this->error_ = UBPLUS_CURL_HANDLE_NOT_VAILD;
if (CURL_OK == curl_easy_setopt(this->curl_,CURLOPT_WRITEFUNCTION,func))
return UBPLUS_CURL_OK;
else {
UB_LOG_WARNNING("[warn=curl] set option[call_back] failed");
this->error_ = UBPLUS_CURL_SET_OPTION_FAILD;
return UBPLUS_CURL_SET_OPTION_FAILD;
}
}
// ***********************************************************
int EasyCurl::set_curl_callback_context(void* user_context)
{
if (!this->curl_ || !this->is_good_)
return this->error_ = UBPLUS_CURL_HANDLE_NOT_VAILD;
if (CURL_OK == curl_easy_setopt(this->curl_,CURLOPT_WRITEDATA,user_context))
return UBPLUS_CURL_OK;
else {
UB_LOG_WARNNING("[warn=curl] set option[call_back_context] failed");
this->error_ = UBPLUS_CURL_SET_OPTION_FAILD;
return UBPLUS_CURL_SET_OPTION_FAILD;
}
}
// ***********************************************************
int EasyCurl::set_user_buffer(char** user,size_t len)
{
if (NULL == user || NULL == *user || 0 == len) {
this->is_good_ = false;
return this->error_ = UBPLUS_CURL_USER_BUFFER_NOT_VAILD;
}
EasyCurl::user_buffer.mem = *user;
memset(EasyCurl::user_buffer.mem,0,len);
EasyCurl::user_buffer.offset = 0;
EasyCurl::user_buffer.max = len;
UB_LOG_DEBUG("[ok=curl] User Buffer set");
return UBPLUS_CURL_OK;
}
// ***********************************************************
int EasyCurl::fetch()
{
if (!this->curl_ || !this->is_good_)
return this->error_ = UBPLUS_CURL_HANDLE_NOT_VAILD;
// actual perform curl
CURLcode code = curl_easy_perform(this->curl_);
// don't forget to clear user buffer
EasyCurl::user_buffer.offset = 0;
if (CURL_OK == code) {
return UBPLUS_CURL_OK;
} else {
UB_LOG_WARNNING("[warn=curl] curl perform error[%s]",curl_easy_strerror(code));
this->error_ = UBPLUS_CURL_PERFORM_FAILD;
return UBPLUS_CURL_PERFORM_FAILD;
}
}
// ***********************************************************
int EasyCurl::set_timeout(unsigned long time)
{
if (!this->curl_ || !this->is_good_)
return this->error_ = UBPLUS_CURL_HANDLE_NOT_VAILD;
if (0 == time)
return this->error_ = UBPLUS_CURL_TIMEOUT_NOT_VAILD;
if (CURL_OK == curl_easy_setopt(this->curl_,CURLOPT_TIMEOUT,time))
return UBPLUS_CURL_OK;
else {
UB_LOG_WARNNING("[warn=curl] set option[timeout] failed");
this->error_ = UBPLUS_CURL_SET_OPTION_FAILD;
return UBPLUS_CURL_SET_OPTION_FAILD;
}
}
// ***********************************************************
int EasyCurl::set_url(std::string url)
{
if (!this->curl_ || !this->is_good_)
return this->error_ = UBPLUS_CURL_HANDLE_NOT_VAILD;
if (url.length()<5)
return this->error_ = UBPLUS_CURL_URL_NOT_VAILD;
if (CURL_OK == curl_easy_setopt(this->curl_,CURLOPT_URL,url.c_str()))
return UBPLUS_CURL_OK;
else {
UB_LOG_WARNNING("[warn=curl] set option[url] failed");
this->error_ = UBPLUS_CURL_URL_NOT_VAILD;
return UBPLUS_CURL_URL_NOT_VAILD;
}
}
// ***********************************************************
int EasyCurl::set_post_data(void* post_data)
{
if (!this->curl_ || !this->is_good_)
return this->error_ = UBPLUS_CURL_HANDLE_NOT_VAILD;
if (NULL == post_data)
return this->error_ = UBPLUS_CURL_POST_NOT_VAILD;
if (CURL_OK == curl_easy_setopt(this->curl_,CURLOPT_POSTFIELDS,post_data))
return UBPLUS_CURL_OK;
else {
UB_LOG_WARNNING("[warn=curl] set option[post] failed");
this->error_ = UBPLUS_CURL_POST_NOT_VAILD;
return UBPLUS_CURL_POST_NOT_VAILD;
}
}
size_t EasyCurl::total_size_ = 0;
bool EasyCurl::global_init_ = false;
EasyCurl::curl_buffer EasyCurl::user_buffer;
} // end of namespace
分享到:
相关推荐
DS90UB928Q-Q1 928QSQ FPD-link解串器芯片手册。 The DS90UB928Q-Q1 deserializer, in conjunction with a DS90UB925Q-Q1 or DS90UB927Q-Q1 serializer, provides a solution for distribution of digital video and...
audacity-macosx-ub-2.1.1-screen-reader.dmg audacity-macosx-ub-2.1.1-screen-reader.dmg audacity-macosx-ub-2.1.1-screen-reader.dmg
newifi3固件用一个路由器上传工具,名字一时想不起来,很简单,从adbyby下载文件,直接上传到路由器tmp目录下,然后进路由器点击右上角adbyby就可以打开了!
H大2019.11.24日版newifi2D1固件RT-N56UB1-newifi2D1-512M_3.4.3.9-099
H大2021.6.19日版RT-N56UB1-M1-512M_3.4.3.9-099.trx
MT7601+MT6622 蓝牙+WiFI二合一模块(WL-UB163BN-V1.1)规格书
ds90ub954-q1 数据手册
百灵达UB1202_UB1002_UB802_UB502中文说明书_快速开始
H大2021.6.19日版newifi3D2固件RT-N56UB1-newifi3D2-512M_3.4.3.9-099.trx
newif3D2padvan0923版本自留保存资源侵权删除
所做的C程序用在检测PCB电容触摸板测试,P0口模拟4组I2C信号主机接收,触摸板作为从机,从机地址0x0D
DS90UB933-Q1 适用于1MP/60fps 摄像头10/12 位、100MHz的FPD-Link III 串行
DS90UB953硬件EVM和DATASHEET。DS90UB954硬件EVM和DATASHEET。
ds90ub964-q1 数据手册 ds90ub964-q1 数据手册 ds90ub964-q1 数据手册
ds90ub953-q1.pdf TI官方规格书
ub-Help-GitHub-Actions-语言和框架指南-GitHub-Actions-for-Java
语义web服务发现模型,在外国网站下的好东西啊
支持ubuntu10.04以上版本使用,用于备份系统.