From 4475e8b0af5cd68ee5b39cd54ea03a2ec9c7659a Mon Sep 17 00:00:00 2001 From: Przemyslaw Czerpak Date: Wed, 13 Jan 2010 08:38:05 +0000 Subject: [PATCH] 2010-01-13 09:37 UTC+0100 Przemyslaw Czerpak (druzus/at/priv.onet.pl) * harbour/include/hbapi.h * harbour/src/vm/hashes.c + added new function hb_hashGetCItemPtr() which accepts ASCIIZ string as index. * harbour/contrib/hbnetio/netiosrv.c + added support for using HASH arrays as RPC filter. Such hash array should be indexed by function/procedure name set of codeblocks or function references or even objects which understand EVAL method. Please remember that function names passed from client side are case sensitive so if you do not need it then please disable case matching in the hash array, i.e. using HB_HSETCASEMATCH( hValue, .F. ). * renamed NETIO_RPCFUNC() to NETIO_RPCFILTER() it's better name now because we added support for using hash arrays as RPC filters: NETIO_RPCFILTER( , | | NIL ) -> NIL * harbour/contrib/hbnetio/netiomt.prg + added support for setting RPC filter in NETIO_MTSERVER() using its 4-th parameter: NETIO_MTSERVER( [], [], [], [ | | ], [], [], [] ) -> * harbour/contrib/hbclipsm/environ.c ! fixed GPF in FILEDRIVE() function on platforms which do not support drive letters or when path does not contain drive. % small optimization in FILEPATH(), FILEBASE(), FILEEXT(), FILEDRIVE() --- harbour/ChangeLog | 32 +++++++++++++ harbour/contrib/hbclipsm/environ.c | 27 +++++++---- harbour/contrib/hbnetio/netiomt.prg | 21 ++++++-- harbour/contrib/hbnetio/netiosrv.c | 74 ++++++++++++++++++++++++----- harbour/include/hbapi.h | 1 + harbour/src/vm/hashes.c | 19 ++++++++ 6 files changed, 149 insertions(+), 25 deletions(-) diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 8f35f927ae..ba941a4abf 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -17,6 +17,38 @@ past entries belonging to author(s): Viktor Szakats. */ +2010-01-13 09:37 UTC+0100 Przemyslaw Czerpak (druzus/at/priv.onet.pl) + * harbour/include/hbapi.h + * harbour/src/vm/hashes.c + + added new function hb_hashGetCItemPtr() which accepts ASCIIZ string + as index. + + * harbour/contrib/hbnetio/netiosrv.c + + added support for using HASH arrays as RPC filter. + Such hash array should be indexed by function/procedure name set of + codeblocks or function references or even objects which understand + EVAL method. + Please remember that function names passed from client side are case + sensitive so if you do not need it then please disable case matching + in the hash array, i.e. using HB_HSETCASEMATCH( hValue, .F. ). + * renamed NETIO_RPCFUNC() to NETIO_RPCFILTER() it's better name now + because we added support for using hash arrays as RPC filters: + NETIO_RPCFILTER( , + | | NIL ) -> NIL + + * harbour/contrib/hbnetio/netiomt.prg + + added support for setting RPC filter in NETIO_MTSERVER() using its + 4-th parameter: + NETIO_MTSERVER( [], [], [], + [ | | ], + [], [], [] ) + -> + + * harbour/contrib/hbclipsm/environ.c + ! fixed GPF in FILEDRIVE() function on platforms which do not support + drive letters or when path does not contain drive. + % small optimization in FILEPATH(), FILEBASE(), FILEEXT(), FILEDRIVE() + 2010-01-11 18:12 UTC-0800 Pritpal Bedi (pritpal@vouchcac.com) * contrib/hbqt/generator/hbqtgen.prg * contrib/hbqt/qth/QTextCodec.qth diff --git a/harbour/contrib/hbclipsm/environ.c b/harbour/contrib/hbclipsm/environ.c index 488e3f7ed8..418c9fad8b 100644 --- a/harbour/contrib/hbclipsm/environ.c +++ b/harbour/contrib/hbclipsm/environ.c @@ -59,9 +59,10 @@ */ HB_FUNC( FILEPATH ) { - if( HB_ISCHAR( 1 ) ) + const char * szPath = hb_parc( 1 ); + if( szPath ) { - PHB_FNAME pFileName = hb_fsFNameSplit( hb_parc( 1 ) ); + PHB_FNAME pFileName = hb_fsFNameSplit( szPath ); hb_retc( pFileName->szPath ); hb_xfree( pFileName ); } @@ -73,9 +74,10 @@ HB_FUNC( FILEPATH ) */ HB_FUNC( FILEBASE ) { - if( HB_ISCHAR( 1 ) ) + const char * szPath = hb_parc( 1 ); + if( szPath ) { - PHB_FNAME pFileName = hb_fsFNameSplit( hb_parc( 1 ) ); + PHB_FNAME pFileName = hb_fsFNameSplit( szPath ); hb_retc( pFileName->szName ); hb_xfree( pFileName ); } @@ -87,11 +89,12 @@ HB_FUNC( FILEBASE ) */ HB_FUNC( FILEEXT ) { - if( HB_ISCHAR( 1 ) ) + const char * szPath = hb_parc( 1 ); + if( szPath ) { - PHB_FNAME pFileName = hb_fsFNameSplit( hb_parc( 1 ) ); + PHB_FNAME pFileName = hb_fsFNameSplit( szPath ); if( pFileName->szExtension != NULL ) - hb_retc( ( pFileName->szExtension ) + 1 ); /* Skip the dot */ + hb_retc( pFileName->szExtension + 1 ); /* Skip the dot */ else hb_retc_null(); hb_xfree( pFileName ); @@ -104,10 +107,14 @@ HB_FUNC( FILEEXT ) */ HB_FUNC( FILEDRIVE ) { - if( HB_ISCHAR( 1 ) ) + const char * szPath = hb_parc( 1 ); + if( szPath ) { - PHB_FNAME pFileName = hb_fsFNameSplit( hb_parc( 1 ) ); - hb_retclen( pFileName->szDrive, 1 ); /* Only the drive letter */ + PHB_FNAME pFileName = hb_fsFNameSplit( szPath ); + if( pFileName->szDrive ) + hb_retclen( pFileName->szDrive, 1 ); /* Only the drive letter */ + else + hb_retc_null(); hb_xfree( pFileName ); } else diff --git a/harbour/contrib/hbnetio/netiomt.prg b/harbour/contrib/hbnetio/netiomt.prg index 6b3f450c7f..2915f42f35 100644 --- a/harbour/contrib/hbnetio/netiomt.prg +++ b/harbour/contrib/hbnetio/netiomt.prg @@ -58,18 +58,28 @@ * */ -FUNCTION NETIO_MTSERVER( nPort, cIfAddr, cRootDir, lRPC, ... ) - LOCAL pListenSocket +FUNCTION NETIO_MTSERVER( nPort, cIfAddr, cRootDir, xRPC, ... ) + LOCAL pListenSocket, lRPC IF hb_mtvm() + SWITCH ValType( xRPC ) + CASE "S" + CASE "H" + lRPC := .T. + EXIT + CASE "L" + lRPC := xRPC + OTHERWISE + xRPC := NIL + ENDSWITCH pListenSocket := netio_listen( nPort, cIfAddr, cRootDir, lRPC ) IF !Empty( pListenSocket ) - hb_threadDetach( hb_threadStart( @netio_srvloop(), pListenSocket, ... ) ) + hb_threadDetach( hb_threadStart( @netio_srvloop(), pListenSocket, xRPC, ... ) ) ENDIF ENDIF RETURN pListenSocket -STATIC FUNCTION NETIO_SRVLOOP( pListenSocket, ... ) +STATIC FUNCTION NETIO_SRVLOOP( pListenSocket, xRPC, ... ) LOCAL pConnectionSocket WHILE .T. @@ -77,6 +87,9 @@ STATIC FUNCTION NETIO_SRVLOOP( pListenSocket, ... ) IF Empty( pConnectionSocket ) EXIT ENDIF + IF xRPC != NIL + netio_rpcfilter( pConnectionSocket, xRPC ) + ENDIF hb_threadDetach( hb_threadStart( @netio_server(), pConnectionSocket ) ) pConnectionSocket := NIL ENDDO diff --git a/harbour/contrib/hbnetio/netiosrv.c b/harbour/contrib/hbnetio/netiosrv.c index 0c6761a9ee..a21ea5f03d 100644 --- a/harbour/contrib/hbnetio/netiosrv.c +++ b/harbour/contrib/hbnetio/netiosrv.c @@ -21,7 +21,8 @@ * -> NIL * NETIO_RPC( | [, ] ) * -> - * NETIO_RPCFUNC( , ) -> NIL + * NETIO_RPCFILTER( , + | | NIL ) -> NIL * * Copyright 2009 Przemyslaw Czerpak * www - http://www.harbour-project.org @@ -96,6 +97,7 @@ typedef struct _HB_CONSRV BOOL rpc; BOOL login; PHB_SYMB rpcFunc; + PHB_SYMB rpcFilter; int rootPathLen; char rootPath[ HB_PATH_MAX ]; } @@ -232,6 +234,9 @@ static void s_consrv_close( PHB_CONSRV conn ) { int i = 0; + if( conn->rpcFilter ) + hb_itemRelease( conn->rpcFilter ); + if( conn->sd != HB_NO_SOCKET ) hb_socketClose( conn->sd ); @@ -266,10 +271,18 @@ static HB_GARBAGE_FUNC( s_consrv_destructor ) } } +static HB_GARBAGE_FUNC( s_consrv_mark ) +{ + PHB_CONSRV * conn_ptr = ( PHB_CONSRV * ) Cargo; + + if( *conn_ptr && ( *conn_ptr )->rpcFilter ) + hb_gcMark( ( *conn_ptr )->rpcFilter ); +} + static const HB_GC_FUNCS s_gcConSrvFuncs = { s_consrv_destructor, - hb_gcDummyMark + s_consrv_mark }; static PHB_CONSRV s_consrvParam( int iParam ) @@ -459,14 +472,29 @@ HB_FUNC( NETIO_RPC ) hb_retl( fRPC ); } -/* NETIO_RPCFUNC( , ) -> NIL +/* NETIO_RPCFILTER( , + * | | NIL ) -> NIL */ -HB_FUNC( NETIO_RPCFUNC ) +HB_FUNC( NETIO_RPCFILTER ) { PHB_CONSRV conn = s_consrvParam( 1 ); if( conn ) { + if( conn->rpcFilter ) + { + hb_itemRelease( conn->rpcFilter ); + conn->rpcFilter = NULL; + } conn->rpcFunc = hb_itemGetSymbol( hb_param( 2, HB_IT_SYMBOL ) ); + if( !conn->rpcFunc ) + { + PHB_ITEM pHash = hb_param( 2, HB_IT_HASH ); + if( pHash ) + { + conn->rpcFilter = hb_itemNew( pHash ); + hb_gcUnlock( conn->rpcFilter ); + } + } } } @@ -982,19 +1010,40 @@ HB_FUNC( NETIO_SERVER ) errCode = NETIO_ERR_WRONG_PARAM; else { - PHB_DYNS pDynSym = hb_dynsymFindName( data ); - if( !pDynSym || !hb_dynsymIsFunction( pDynSym ) ) - errCode = NETIO_ERR_NOT_EXISTS; - else if( uiMsg != NETIO_PROCIS ) + PHB_DYNS pDynSym = NULL; + PHB_ITEM pItem = NULL; + + if( conn->rpcFilter ) + { + pItem = hb_hashGetCItemPtr( conn->rpcFilter, data ); + if( !pItem ) + errCode = NETIO_ERR_NOT_EXISTS; + } + else + { + pDynSym = hb_dynsymFindName( data ); + if( !pDynSym || !hb_dynsymIsFunction( pDynSym ) ) + errCode = NETIO_ERR_NOT_EXISTS; + } + + if( uiMsg != NETIO_PROCIS && errCode == 0 ) { if( hb_vmRequestReenter() ) { ULONG ulSize = size - size2; USHORT uiPCount = 0; + BOOL fSend = FALSE; data += size2; - if( conn->rpcFunc ) + if( pItem ) { + fSend = TRUE; + hb_vmPushEvalSym(); + hb_vmPush( pItem ); + } + else if( conn->rpcFunc ) + { + fSend = TRUE; hb_vmPushSymbol( conn->rpcFunc ); hb_vmPushNil(); hb_vmPushDynSym( pDynSym ); @@ -1007,7 +1056,7 @@ HB_FUNC( NETIO_SERVER ) } while( ulSize ) { - PHB_ITEM pItem = hb_itemDeserialize( &data, &ulSize ); + pItem = hb_itemDeserialize( &data, &ulSize ); if( !pItem ) { ulSize = 1; @@ -1027,7 +1076,10 @@ HB_FUNC( NETIO_SERVER ) } else { - hb_vmProc( uiPCount ); + if( fSend ) + hb_vmSend( uiPCount ); + else + hb_vmProc( uiPCount ); if( uiMsg == NETIO_FUNC ) { ULONG itmSize; diff --git a/harbour/include/hbapi.h b/harbour/include/hbapi.h index 3ff2aefa3c..0e6674873e 100644 --- a/harbour/include/hbapi.h +++ b/harbour/include/hbapi.h @@ -887,6 +887,7 @@ extern HB_EXPORT void * hb_hashId( PHB_ITEM pHash ); /* retrieves the hash un /* these hb_hashGet*() functions are dangerous, be sure that base HASH value will not be changed */ extern HB_EXPORT PHB_ITEM hb_hashGetItemPtr( PHB_ITEM pHash, PHB_ITEM pKey, int iFlags ); extern HB_EXPORT PHB_ITEM hb_hashGetItemRefPtr( PHB_ITEM pHash, PHB_ITEM pKey ); +extern HB_EXPORT PHB_ITEM hb_hashGetCItemPtr( PHB_ITEM pHash, const char * pszKey ); extern HB_EXPORT PHB_ITEM hb_hashGetKeyAt( PHB_ITEM pHash, ULONG ulPos ); extern HB_EXPORT PHB_ITEM hb_hashGetValueAt( PHB_ITEM pHash, ULONG ulPos ); diff --git a/harbour/src/vm/hashes.c b/harbour/src/vm/hashes.c index e9f1e30ed8..5e6f1872ed 100644 --- a/harbour/src/vm/hashes.c +++ b/harbour/src/vm/hashes.c @@ -475,6 +475,25 @@ PHB_ITEM hb_hashGetItemPtr( PHB_ITEM pHash, PHB_ITEM pKey, int iFlags ) return NULL; } +PHB_ITEM hb_hashGetCItemPtr( PHB_ITEM pHash, const char * pszKey ) +{ + HB_TRACE(HB_TR_DEBUG, ("hb_hashGetCItemPtr(%p,%s)", pHash, pszKey)); + + if( HB_IS_HASH( pHash ) ) + { + /* we will not make any copy of pKey (autoadd is disabled) so it's + * safe to use hb_itemPutCConst() + */ + PHB_ITEM pKey = hb_itemPutCConst( hb_stackAllocItem(), pszKey ); + PHB_ITEM pDest = hb_hashValuePtr( pHash->item.asHash.value, pKey, FALSE ); + hb_stackPop(); + if( pDest ) + return HB_IS_BYREF( pDest ) ? hb_itemUnRef( pDest ) : pDest; + } + + return NULL; +} + PHB_ITEM hb_hashGetItemRefPtr( PHB_ITEM pHash, PHB_ITEM pKey ) { HB_TRACE(HB_TR_DEBUG, ("hb_hashGetItemRefPtr(%p,%p)", pHash, pKey));