2025-01-07 21:43 UTC+0100 Emanuele Zavallone (emanuele.zavallone gmail.com)
* contrib/hbcurl/easy.c
* contrib/hbcurl/hbcurl.ch
+ added multi interface implementation
This commit is contained in:
committed by
Aleksander Czajczynski
parent
cb9888c76d
commit
60663791e1
@@ -7,6 +7,11 @@
|
||||
Entries may not always be in chronological/commit order.
|
||||
See license at the end of file. */
|
||||
|
||||
2025-01-07 21:43 UTC+0100 Emanuele Zavallone (emanuele.zavallone gmail.com)
|
||||
* contrib/hbcurl/easy.c
|
||||
* contrib/hbcurl/hbcurl.ch
|
||||
+ added multi interface implementation
|
||||
|
||||
2025-01-07 12:24 UTC+0100 Aleksander Czajczynski (hb fki.pl)
|
||||
* src/common/hbver.c
|
||||
* indent cleanup
|
||||
|
||||
@@ -2499,6 +2499,222 @@ HB_FUNC( CURL_GETDATE )
|
||||
hb_errRT_BASE( EG_ARG, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
||||
}
|
||||
|
||||
/* Multi interface */
|
||||
/* ----------------- */
|
||||
|
||||
typedef struct _HB_CURLM
|
||||
{
|
||||
CURLM * curlm;
|
||||
|
||||
} HB_CURLM, * PHB_CURLM;
|
||||
|
||||
|
||||
/* Constructor/Destructor */
|
||||
/* ---------------------- */
|
||||
|
||||
static void PHB_CURLM_free( PHB_CURLM hb_curlm )
|
||||
{
|
||||
curl_multi_cleanup( hb_curlm->curlm );
|
||||
hb_xfree( hb_curlm );
|
||||
}
|
||||
|
||||
static PHB_CURLM PHB_CURLM_create( )
|
||||
{
|
||||
CURLM * curlm = curl_multi_init();
|
||||
|
||||
if( curlm )
|
||||
{
|
||||
PHB_CURLM hb_curlm = ( PHB_CURLM ) hb_xgrab( sizeof( HB_CURLM ) );
|
||||
|
||||
memset( hb_curlm, 0, sizeof( HB_CURLM ) );
|
||||
hb_curlm->curlm = curlm;
|
||||
|
||||
return hb_curlm;
|
||||
}
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static HB_GARBAGE_FUNC( PHB_CURLM_release )
|
||||
{
|
||||
PHB_CURLM * hb_curlm_ptr = ( PHB_CURLM * ) Cargo;
|
||||
|
||||
/* Check if pointer is not NULL to avoid multiple freeing */
|
||||
if( hb_curlm_ptr && *hb_curlm_ptr )
|
||||
{
|
||||
/* Destroy the object */
|
||||
PHB_CURLM_free( *hb_curlm_ptr );
|
||||
*hb_curlm_ptr = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static const HB_GC_FUNCS s_gcCURLMFuncs =
|
||||
{
|
||||
PHB_CURLM_release,
|
||||
hb_gcDummyMark
|
||||
};
|
||||
|
||||
static void PHB_CURLM_ret()
|
||||
{
|
||||
void ** ph = ( void ** ) hb_gcAllocate( sizeof( PHB_CURLM ), &s_gcCURLMFuncs );
|
||||
|
||||
*ph = PHB_CURLM_create( );
|
||||
|
||||
hb_retptrGC( ph );
|
||||
}
|
||||
|
||||
static void * PHB_CURLM_is( int iParam )
|
||||
{
|
||||
return hb_parptrGC( &s_gcCURLMFuncs, iParam );
|
||||
}
|
||||
|
||||
static PHB_CURLM PHB_CURLM_par( int iParam )
|
||||
{
|
||||
void ** ph = ( void ** ) hb_parptrGC( &s_gcCURLMFuncs, iParam );
|
||||
|
||||
return ph ? ( PHB_CURLM ) *ph : NULL;
|
||||
}
|
||||
|
||||
/* Harbour interface */
|
||||
/* ----------------- */
|
||||
|
||||
|
||||
HB_FUNC( CURL_MULTI_INIT )
|
||||
{
|
||||
PHB_CURLM_ret( );
|
||||
}
|
||||
|
||||
HB_FUNC( CURL_MULTI_CLEANUP )
|
||||
{
|
||||
if( PHB_CURLM_is( 1 ) )
|
||||
{
|
||||
void ** ph = ( void ** ) hb_parptrGC( &s_gcCURLMFuncs, 1 );
|
||||
|
||||
if( ph && *ph )
|
||||
{
|
||||
/* Destroy the object */
|
||||
PHB_CURLM_free( ( PHB_CURLM ) *ph );
|
||||
*ph = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
hb_errRT_BASE( EG_ARG, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
||||
}
|
||||
|
||||
HB_FUNC( CURL_MULTI_ADD_HANDLE )
|
||||
{
|
||||
if( PHB_CURLM_is( 1 ) && PHB_CURL_is( 2 ) )
|
||||
{
|
||||
PHB_CURLM hb_curlm = PHB_CURLM_par( 1 );
|
||||
PHB_CURL hb_curl = PHB_CURL_par( 2 );
|
||||
|
||||
hb_retnl( hb_curlm && hb_curl ? ( long ) curl_multi_add_handle( hb_curlm->curlm, hb_curl->curl) : HB_CURLM_INTERNAL_ERROR );
|
||||
}
|
||||
else
|
||||
hb_errRT_BASE( EG_ARG, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
||||
}
|
||||
|
||||
HB_FUNC( CURL_MULTI_REMOVE_HANDLE )
|
||||
{
|
||||
if( PHB_CURLM_is( 1 ) && PHB_CURL_is( 2 ) )
|
||||
{
|
||||
PHB_CURLM hb_curlm = PHB_CURLM_par( 1 );
|
||||
PHB_CURL hb_curl = PHB_CURL_par( 2 );
|
||||
|
||||
hb_retnl( hb_curlm && hb_curl ? ( long ) curl_multi_remove_handle( hb_curlm->curlm, hb_curl->curl) : HB_CURLM_INTERNAL_ERROR );
|
||||
}
|
||||
else
|
||||
hb_errRT_BASE( EG_ARG, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
||||
}
|
||||
|
||||
HB_FUNC( CURL_MULTI_PERFORM )
|
||||
{
|
||||
if( PHB_CURLM_is( 1 ) && HB_ISBYREF( 2 ) )
|
||||
{
|
||||
|
||||
CURLMcode res = ( CURLMcode ) HB_CURLM_INTERNAL_ERROR;
|
||||
PHB_CURLM hb_curlm = PHB_CURLM_par( 1 );
|
||||
|
||||
if ( hb_curlm )
|
||||
{
|
||||
int running_handles = 0;
|
||||
res = curl_multi_perform( hb_curlm->curlm, &running_handles);
|
||||
hb_stornl( running_handles, 2);
|
||||
}
|
||||
|
||||
hb_retnl( ( long ) res );
|
||||
|
||||
}
|
||||
else
|
||||
hb_errRT_BASE( EG_ARG, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
||||
}
|
||||
|
||||
HB_FUNC( CURL_MULTI_POLL )
|
||||
{
|
||||
if( PHB_CURLM_is( 1 ) && HB_ISNUM( 2 ) )
|
||||
{
|
||||
|
||||
CURLMcode res = ( CURLMcode ) HB_CURLM_INTERNAL_ERROR;
|
||||
PHB_CURLM hb_curlm = PHB_CURLM_par( 1 );
|
||||
|
||||
if ( hb_curlm )
|
||||
{
|
||||
res = curl_multi_poll( hb_curlm->curlm,
|
||||
NULL,
|
||||
0,
|
||||
hb_parni(2),
|
||||
NULL );
|
||||
}
|
||||
|
||||
hb_retnl( ( long ) res );
|
||||
|
||||
}
|
||||
else
|
||||
hb_errRT_BASE( EG_ARG, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
||||
}
|
||||
|
||||
|
||||
HB_FUNC( CURL_MULTI_INFO_READ )
|
||||
{
|
||||
if( PHB_CURLM_is( 1 ) )
|
||||
{
|
||||
|
||||
PHB_ITEM pReturn = NULL;
|
||||
PHB_CURLM hb_curlm = PHB_CURLM_par( 1 );
|
||||
|
||||
if ( hb_curlm )
|
||||
{
|
||||
int msgs_in_queue = 0;
|
||||
|
||||
struct CURLMsg *msg = curl_multi_info_read( hb_curlm->curlm, &msgs_in_queue );
|
||||
if ( msg )
|
||||
{
|
||||
|
||||
CURLcode res = ( CURLcode ) HB_CURLE_ERROR;
|
||||
long response_code = 0;
|
||||
res = curl_easy_getinfo( msg->easy_handle, CURLINFO_RESPONSE_CODE, &response_code );
|
||||
|
||||
pReturn = hb_itemArrayNew( HB_CURLMSG_RESP_LAST );
|
||||
|
||||
hb_arraySetNL( pReturn, HB_CURLMSG_RESP_LEN, ( long ) msgs_in_queue );
|
||||
hb_arraySetNL( pReturn, HB_CURLMSG_RESP_RESPONSE_CODE, ( long ) response_code );
|
||||
hb_arraySetNL( pReturn, HB_CURLMSG_RESP_MSG, ( long ) msg->msg );
|
||||
hb_arraySetNL( pReturn, HB_CURLMSG_RESP_RESULT, ( long ) msg->data.result );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if ( pReturn )
|
||||
hb_itemReturnRelease( pReturn );
|
||||
else
|
||||
hb_ret();
|
||||
|
||||
}
|
||||
else
|
||||
hb_errRT_BASE( EG_ARG, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
||||
|
||||
}
|
||||
|
||||
/* Harbour interface (session independent) */
|
||||
|
||||
/* NOTE: Obsolete, superceded by curl_easy_escape() */
|
||||
|
||||
@@ -578,4 +578,32 @@
|
||||
#define HB_CURLE_FTP_BAD_FILE_LIST 87 /* unable to parse FTP file list */
|
||||
#define HB_CURLE_CHUNK_FAILED 88 /* chunk callback reported error */
|
||||
|
||||
/* curl multi result codes. */
|
||||
|
||||
#define HB_CURLM_CALL_MULTI_PERFORM -1 /* please call curl_multi_perform() or curl_multi_socket*() soon */
|
||||
#define HB_CURLM_OK 0
|
||||
#define HB_CURLM_BAD_HANDLE 1 /* the passed-in handle is not a valid CURLM handle */
|
||||
#define HB_CURLM_BAD_EASY_HANDLE 2 /* an easy handle was not good/valid */
|
||||
#define HB_CURLM_OUT_OF_MEMORY 3 /* if you ever get this, you're in deep sh*t */
|
||||
#define HB_CURLM_INTERNAL_ERROR 4 /* this is a libcurl bug */
|
||||
#define HB_CURLM_BAD_SOCKET 5 /* the passed in socket argument did not match */
|
||||
#define HB_CURLM_UNKNOWN_OPTION 6 /* curl_multi_setopt() with unsupported option */
|
||||
#define HB_CURLM_ADDED_ALREADY 7 /* an easy handle already added to a multi handle was attempted to get added - again */
|
||||
#define HB_CURLM_RECURSIVE_API_CALL 8 /* an api function was called from inside a callback */
|
||||
#define HB_CURLM_WAKEUP_FAILURE 9 /* wakeup is unavailable or failed */
|
||||
#define HB_CURLM_BAD_FUNCTION_ARGUMENT 10 /* function called with a bad parameter */
|
||||
#define HB_CURLM_ABORTED_BY_CALLBACK 11
|
||||
#define HB_CURLM_UNRECOVERABLE_POLL 12
|
||||
|
||||
/* curl_multi_info_read result codes. */
|
||||
|
||||
#define HB_CURLMSG_NONE 0 /* first, not used */
|
||||
#define HB_CURLMSG_DONE 1 /* This easy handle has completed. 'result' contains the CURLcode of the transfer */
|
||||
|
||||
#define HB_CURLMSG_RESP_LEN 1 /* queue len */
|
||||
#define HB_CURLMSG_RESP_RESPONSE_CODE 2 /* curl_easy_getinfo( msg->easy_handle, CURLINFO_RESPONSE_CODE ) */
|
||||
#define HB_CURLMSG_RESP_MSG 3 /* CURLMSG */
|
||||
#define HB_CURLMSG_RESP_RESULT 4 /* CURLcode */
|
||||
#define HB_CURLMSG_RESP_LAST HB_CURLMSG_RESP_RESULT
|
||||
|
||||
#endif /* HBCURL_CH_ */
|
||||
|
||||
Reference in New Issue
Block a user