2025-01-23 11:47 UTC+0100 Aleksander Czajczynski (hb fki.pl)

* contrib/hbcurl/core.c
  * contrib/hbcurl/hbcurl.ch
  * contrib/hbcurl/hbcurl.hbx
    * applied more cleanups, following Viktor Szakats guidance in hisrepo:
      6127603217
      - add `HB_CURLM_ERROR` to indicate error in hbcurl wrapper.
      - replace use of `HB_CURLM_INTERNAL_ERROR` with `HB_CURLM_ERROR`.
      - sync Harbour variable integer sizes with curl ones.
      - tidy up a variable scopes.
      - drop unused variable.
      - omit `hb_ret()` (it's a no-op).
      - formatting.
      - add functions to `hbcurl.hbx`.

    + add curl_ws_send()/curl_ws_recv() - WebSocket connectivity,
      borrowed from Viktor's fork, thanks again!
      2c71a5c940

  * src/rdd/dbcmd.c
    * note about C5.3 and Harbour extensions to
      DBAPPEND( [<lUnlockAll>=.t.] ), thanks Viktor

  * ChangeLog.txt
    ! typos
This commit is contained in:
Aleksander Czajczynski
2025-01-23 11:47:54 +01:00
parent 81bf9807b5
commit 4a4691653b
5 changed files with 156 additions and 66 deletions

View File

@@ -7,6 +7,32 @@
Entries may not always be in chronological/commit order.
See license at the end of file. */
2025-01-23 11:47 UTC+0100 Aleksander Czajczynski (hb fki.pl)
* contrib/hbcurl/core.c
* contrib/hbcurl/hbcurl.ch
* contrib/hbcurl/hbcurl.hbx
* applied more cleanups, following Viktor Szakats guidance in his repo:
https://github.com/vszakats/hb/commit/61276032177e2f4e8cfac22080c1e0b14eb0d432
- add `HB_CURLM_ERROR` to indicate error in hbcurl wrapper.
- replace use of `HB_CURLM_INTERNAL_ERROR` with `HB_CURLM_ERROR`.
- sync Harbour variable integer sizes with curl ones.
- tidy up a variable scopes.
- drop unused variable.
- omit `hb_ret()` (it's a no-op).
- formatting.
- add functions to `hbcurl.hbx`.
+ add curl_ws_send()/curl_ws_recv() - WebSocket connectivity,
borrowed from Viktor's fork, thanks again!
https://github.com/vszakats/hb/commit/2c71a5c9402cdbb7a649598e5a5ed6f3217d94b4
* src/rdd/dbcmd.c
* note about C5.3 and Harbour extensions to
DBAPPEND( [<lUnlockAll>=.t.] ), thanks Viktor
* ChangeLog.txt
! typos
2025-01-22 21:08 UTC+0100 Przemyslaw Czerpak (druzus/at/poczta.onet.pl)
* utils/hbmk2/hbmk2.prg
* do not interrupt whole build process when optional dependency package
@@ -214,7 +240,7 @@
2025-01-10 10:15 UTC+0100 Aleksander Czajczynski (hb fki.pl)
* src/rtl/listbox.prg
* merged #371 from Kamil, thanks for the patch.
* merged #372 from Kamil, thanks for the patch.
Applied minor reformat .NOT. -> ! and added a comment
about buggy ListBox:hitTest() on no-box dropdown in
Cl*pper 5.3.
@@ -246,7 +272,7 @@
+ added curl lib version guards
* minor code and code formattings
* minor code and comment formattings
+ extended function
curl_multi_info_read( <hMulti>[, <aHandles> ]) -> <aResults>

View File

@@ -137,8 +137,7 @@ typedef struct _HB_CURL
typedef struct _HB_CURLM
{
CURLM * curlm;
} HB_CURLM, * PHB_CURLM;
} HB_CURLM, *PHB_CURLM;
#endif
/* functions to keep passed string values accessible even if HVM
@@ -594,6 +593,7 @@ static void hb_curl_buff_ul_free( PHB_CURL hb_curl )
hb_curl->ul_pos = 0;
}
}
#if LIBCURL_VERSION_NUM >= 0x070100
static void hb_curl_buff_er_free( PHB_CURL hb_curl )
{
@@ -605,6 +605,7 @@ static void hb_curl_buff_er_free( PHB_CURL hb_curl )
}
}
#endif
static void hb_curl_buff_dl_free( PHB_CURL hb_curl )
{
if( hb_curl && hb_curl->dl_ptr )
@@ -671,9 +672,9 @@ static void PHB_CURL_free( PHB_CURL hb_curl, HB_BOOL bFree )
hb_curl_buff_ul_free( hb_curl );
hb_curl_buff_dl_free( hb_curl );
#if LIBCURL_VERSION_NUM >= 0x070100
#if LIBCURL_VERSION_NUM >= 0x070100
hb_curl_buff_er_free( hb_curl );
#endif
#endif
if( hb_curl->pProgressCallback )
{
@@ -979,7 +980,7 @@ HB_FUNC( CURL_EASY_SETOPT )
/* HB_CURLOPT_CONV_FROM_UTF8_FUNCTION */
/* Error */
#if LIBCURL_VERSION_NUM >= 0x070100
#if LIBCURL_VERSION_NUM >= 0x070100
case HB_CURLOPT_ER_BUFF_SETUP:
hb_curl_buff_er_free( hb_curl );
hb_curl->er_len = hb_parnldef( 3, HB_CURL_ER_BUFF_SIZE_INIT );
@@ -2551,6 +2552,77 @@ HB_FUNC( CURL_GETDATE )
hb_errRT_BASE( EG_ARG, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
}
/* CURLcode curl_ws_send(struct Curl_easy *data,
const void *buffer, size_t buflen,
size_t *sent,
curl_off_t framesize,
unsigned int sendflags) */
HB_FUNC( CURL_WS_SEND )
{
if( PHB_CURL_is( 1 ) )
{
CURLcode res = HB_CURLE_ERROR;
size_t sent = 0;
#if LIBCURL_VERSION_NUM >= 0x075600
PHB_CURL hb_curl = PHB_CURL_par( 1 );
if( hb_curl )
res = curl_ws_send( hb_curl->curl,
( const void * ) hb_parc( 2 ), ( size_t ) hb_parclen( 2 ),
&sent,
( curl_off_t ) hb_parnint( 4 ),
( unsigned int ) hb_parnl( 5 ) );
#endif
hb_storns( ( HB_SIZE ) sent, 3 );
hb_retnl( res );
}
else
hb_errRT_BASE( EG_ARG, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
}
/* CURLcode curl_ws_recv(struct Curl_easy *data,
void *buffer, size_t buflen,
size_t *recv, struct curl_ws_frame **meta) */
HB_FUNC( CURL_WS_RECV )
{
if( PHB_CURL_is( 1 ) && HB_ISBYREF( 2 ) )
{
CURLcode res = HB_CURLE_ERROR;
size_t recv = 0;
#if LIBCURL_VERSION_NUM >= 0x075600
PHB_CURL hb_curl = PHB_CURL_par( 1 );
const struct curl_ws_frame * meta = NULL;
PHB_ITEM pBuffer = hb_param( 2, HB_IT_STRING );
char * buffer;
HB_SIZE buflen;
if( hb_itemGetWriteCL( pBuffer, &buffer, &buflen ) )
res = curl_ws_recv( hb_curl->curl,
( void * ) buffer, ( size_t ) buflen,
&recv,
&meta );
hb_stornl( meta ? meta->flags : 0, 4 );
hb_stornint( meta ? meta->offset: 0, 5 );
hb_stornint( meta ? meta->bytesleft: 0, 6 );
#else
hb_stornl( 0, 4 );
hb_stornint( 0, 5 );
hb_stornint( 0, 6 );
#endif
hb_storns( ( HB_SIZE ) recv, 3 );
hb_retnl( res );
}
else
hb_errRT_BASE( EG_ARG, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
}
/* Multi interface Constructor/Destructor */
/* -------------------------------------- */
@@ -2561,7 +2633,7 @@ static void PHB_CURLM_free( PHB_CURLM hb_curlm )
hb_xfree( hb_curlm );
}
static PHB_CURLM PHB_CURLM_create( )
static PHB_CURLM PHB_CURLM_create( void )
{
CURLM * curlm = curl_multi_init();
@@ -2601,7 +2673,7 @@ static void PHB_CURLM_ret()
{
void ** ph = ( void ** ) hb_gcAllocate( sizeof( PHB_CURLM ), &s_gcCURLMFuncs );
*ph = PHB_CURLM_create( );
*ph = PHB_CURLM_create();
hb_retptrGC( ph );
}
@@ -2625,7 +2697,7 @@ static PHB_CURLM PHB_CURLM_par( int iParam )
HB_FUNC( CURL_MULTI_INIT )
{
#if LIBCURL_VERSION_NUM >= 0x070906
PHB_CURLM_ret( );
PHB_CURLM_ret();
#endif
}
@@ -2654,9 +2726,9 @@ 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 );
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 );
hb_retnl( hb_curlm && hb_curl ? ( long ) curl_multi_add_handle( hb_curlm->curlm, hb_curl->curl) : HB_CURLM_ERROR );
}
else
#endif
@@ -2669,9 +2741,9 @@ 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 );
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 );
hb_retnl( hb_curlm && hb_curl ? ( long ) curl_multi_remove_handle( hb_curlm->curlm, hb_curl->curl) : HB_CURLM_ERROR );
}
else
#endif
@@ -2684,7 +2756,7 @@ HB_FUNC( CURL_MULTI_PERFORM )
if( PHB_CURLM_is( 1 ) && HB_ISBYREF( 2 ) )
{
CURLMcode res = ( CURLMcode ) HB_CURLM_INTERNAL_ERROR;
CURLMcode res = ( CURLMcode ) HB_CURLM_ERROR;
PHB_CURLM hb_curlm = PHB_CURLM_par( 1 );
if( hb_curlm )
@@ -2707,21 +2779,17 @@ HB_FUNC( CURL_MULTI_POLL )
#if LIBCURL_VERSION_NUM >= 0x074200
if( PHB_CURLM_is( 1 ) && HB_ISNUM( 2 ) )
{
CURLMcode res = ( CURLMcode ) HB_CURLM_INTERNAL_ERROR;
CURLMcode res = ( CURLMcode ) HB_CURLM_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 );
}
res = curl_multi_poll( hb_curlm->curlm,
NULL,
0,
hb_parni(2),
NULL );
hb_retnl( ( long ) res );
}
else
#endif
@@ -2734,23 +2802,21 @@ HB_FUNC( CURL_MULTI_INFO_READ )
#if LIBCURL_VERSION_NUM >= 0x070906
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;
int msgs_in_queue = 0;
long response_code = 0;
struct CURLMsg * msg = curl_multi_info_read( hb_curlm->curlm, &msgs_in_queue );
struct CURLMsg * msg = curl_multi_info_read( hb_curlm->curlm, &msgs_in_queue );
if( msg && curl_easy_getinfo( msg->easy_handle, CURLINFO_RESPONSE_CODE, &response_code ) == CURLE_OK )
{
PHB_ITEM pHandles = hb_param( 2, HB_IT_ARRAY );
pReturn = hb_itemArrayNew( HB_CURLMSG_RESP_LAST );
PHB_ITEM 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_arraySetNI( pReturn, HB_CURLMSG_RESP_LEN, msgs_in_queue );
hb_arraySetNL( pReturn, HB_CURLMSG_RESP_RESPONSE_CODE, response_code );
hb_arraySetNL( pReturn, HB_CURLMSG_RESP_MSG, ( long ) msg->msg );
hb_arraySetNL( pReturn, HB_CURLMSG_RESP_RESULT, ( long ) msg->data.result );
hb_arraySetNI( pReturn, HB_CURLMSG_RESP_HPOS, 0 );
@@ -2766,6 +2832,7 @@ HB_FUNC( CURL_MULTI_INFO_READ )
if( ph && *ph )
{
PHB_CURL hbcurl = ( PHB_CURL ) *ph;
if( hbcurl->curl == msg->easy_handle )
{
hb_arraySetNL( pReturn, HB_CURLMSG_RESP_HPOS, ( long ) i );
@@ -2774,14 +2841,9 @@ HB_FUNC( CURL_MULTI_INFO_READ )
}
}
}
hb_itemReturnRelease( pReturn );
}
}
if( pReturn )
hb_itemReturnRelease( pReturn );
else
hb_ret();
}
else
hb_errRT_BASE( EG_ARG, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );

View File

@@ -584,34 +584,33 @@
#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. */
/* multi interface result codes. */
#define HB_CURLM_ERROR -9 /* request not passed to libcurl */
#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
#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 */
/* 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_HANDLE 5 /* handle to original curl_easy_init */
#define HB_CURLMSG_RESP_HPOS 6 /* position in handle <array> passed to curl_multi_info_read(, <array> ) */
#define HB_CURLMSG_RESP_LAST HB_CURLMSG_RESP_HPOS
#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_HANDLE 5 /* handle to original curl_easy_init */
#define HB_CURLMSG_RESP_HPOS 6 /* position in handle <array> passed to curl_multi_info_read(, <array> ) */
#define HB_CURLMSG_RESP_LAST HB_CURLMSG_RESP_HPOS
#endif /* HBCURL_CH_ */

View File

@@ -50,6 +50,8 @@ DYNAMIC curl_multi_remove_handle
DYNAMIC curl_unescape
DYNAMIC curl_version
DYNAMIC curl_version_info
DYNAMIC curl_ws_recv
DYNAMIC curl_ws_send
#if defined( __HBEXTREQ__ ) .OR. defined( __HBEXTERN__HBCURL__REQUEST )
#uncommand DYNAMIC <fncs,...> => EXTERNAL <fncs>

View File

@@ -264,13 +264,14 @@ HB_FUNC( DBAPPEND )
if( pArea )
{
/* NOTE: parameter is Clipper 5.3 extension, 5.2 always unlocks */
HB_BOOL bUnLockAll = hb_parldef( 1, HB_TRUE );
HB_ERRCODE errCode;
/* Clipper clears NETERR flag before APPEND */
hb_rddSetNetErr( HB_FALSE );
errCode = SELF_APPEND( pArea, bUnLockAll );
hb_retl( errCode == HB_SUCCESS );
hb_retl( errCode == HB_SUCCESS ); /* HB_EXTENSION */
}
else
hb_errRT_DBCMD( EG_NOTABLE, EDBCMD_NOTABLE, NULL, HB_ERR_FUNCNAME );