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( <pConnectionSocket>,
                          <sFuncSym> | <hValue> | NIL ) -> NIL

  * harbour/contrib/hbnetio/netiomt.prg
    + added support for setting RPC filter in NETIO_MTSERVER() using its
      4-th parameter:
         NETIO_MTSERVER( [<nPort>], [<cIfAddr>], [<cRootDir>],
                         [<lRPC> | <sFuncSym> | <hValue>],
                         [<cPasswd>], [<nCompressionLevel>], [<nStrategy>] )
            -> <pListenSocket>

  * 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()
This commit is contained in:
Przemyslaw Czerpak
2010-01-13 08:38:05 +00:00
parent cddd2a7e96
commit 4475e8b0af
6 changed files with 149 additions and 25 deletions

View File

@@ -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( <pConnectionSocket>,
<sFuncSym> | <hValue> | NIL ) -> NIL
* harbour/contrib/hbnetio/netiomt.prg
+ added support for setting RPC filter in NETIO_MTSERVER() using its
4-th parameter:
NETIO_MTSERVER( [<nPort>], [<cIfAddr>], [<cRootDir>],
[<lRPC> | <sFuncSym> | <hValue>],
[<cPasswd>], [<nCompressionLevel>], [<nStrategy>] )
-> <pListenSocket>
* 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

View File

@@ -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

View File

@@ -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

View File

@@ -21,7 +21,8 @@
* -> NIL
* NETIO_RPC( <pListenSocket> | <pConnectionSocket> [, <lEnable>] )
* -> <lPrev>
* NETIO_RPCFUNC( <pConnectionSocket>, <sFuncSym> ) -> NIL
* NETIO_RPCFILTER( <pConnectionSocket>,
<sFuncSym> | <hValue> | NIL ) -> NIL
*
* Copyright 2009 Przemyslaw Czerpak <druzus / at / priv.onet.pl>
* 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( <pConnectionSocket>, <sFuncSym> ) -> NIL
/* NETIO_RPCFILTER( <pConnectionSocket>,
* <sFuncSym> | <hValue> | 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;

View File

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

View File

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