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));