Class THash

Class THash

Postby Antonio Linares » Wed Oct 25, 2023 9:24 pm

Code: Select all  Expand view  RUN
#include "hbclass.ch"

function Main()

   local oHash := THash():New()
   
   oHash:one = "first"

   ? oHash:one

return nil

CLASS THash

   DATA hHash
   
   METHOD New() INLINE ::hHash := {=>}, Self

   ERROR HANDLER ONERROR()

ENDCLASS

METHOD ONERROR( uParam1 ) CLASS THash

   local cKey := __GetMessage()
   local uRet
   
   if Left( cKey, 1 ) == "_"
      cKey = SubStr( cKey, 2 )
      ::hHash[ cKey ] = uParam1
   else
      if ! hb_HHasKey( ::hHash, cKey )
         ::hHash[ cKey ] = nil
      endif        
   endif

RETURN ::hHash[ cKey ]
 
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 42118
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: Class THash

Postby Antonio Linares » Sat Oct 28, 2023 12:43 pm

Porting Class THash to C code:

This is a good example of how to implement ERROR HANDLER for a Class from C code

Code: Select all  Expand view  RUN
function Main()

   local o := THash()
   
   ? o:ClassName

   o:first = "one"
   ? o:first

   o:second = "two"
   ? o:second

return nil

#pragma BEGINDUMP

#include <hbapi.h>
#include <hbapicls.h>
#include <hbapiitm.h>
#include <hbhash.h>
#include <hbstack.h>
#include <hbvm.h>
#include <hboo.ch>

extern HB_FUN___CLSADDMSG;

HB_FUNC_STATIC( THASH_ONERROR )
{
   PHB_ITEM pHash = hb_itemNew( NULL );
   
   hb_arrayGet( hb_stackSelfItem(), 1, pHash );

   hb_vmPushSymbol( hb_dynsymSymbol( hb_dynsymFindName( "__GETMESSAGE" ) ) );
   hb_vmPushNil();
   hb_vmProc( 0 );

   if( hb_parc( -1 )[ 0 ] == '_' )
   {
       hb_retc( hb_parc( -1 ) + 1 );
       hb_hashAdd( pHash, hb_stackReturnItem(), hb_param( 1, HB_IT_ANY ) );
       hb_arraySet( hb_stackSelfItem(), 1, pHash );
       hb_ret();
   }
   else  
   {
       HB_SIZE nPos;

       hb_hashScan( pHash, hb_stackReturnItem(), &nPos );
   
       if( nPos == 0 )
       {
          hb_hashAdd( pHash, hb_stackReturnItem(), hb_param( 1, HB_IT_ANY ) );
          hb_ret();
       }  
       else
          hb_itemReturn( hb_hashGetValueAt( pHash, nPos ) );
   }    

   hb_itemRelease( pHash );
}

static HB_SYMB symOnError = { "ONERROR",  { HB_FS_STATIC }, { HB_FUNCNAME( THASH_ONERROR ) }, NULL };

HB_FUNC( THASH )
{
   static HB_USHORT uiClass = 0;

   if( uiClass == 0 )
   {
      uiClass = hb_clsCreate( 1, "THASH" );  // it has just one DATA
   
      hb_vmPushSymbol( hb_dynsymSymbol( hb_dynsymFindName( "__CLSADDMSG" ) ) );
      hb_vmPushNil();
      hb_vmPushInteger( uiClass );
      hb_vmPushString( "ONERROR", strlen( "ONERROR" ) );
      hb_vmPushSymbol( &symOnError );
      hb_vmPushInteger( HB_OO_MSG_ONERROR );
      hb_vmProc( 4 );
   }

   hb_clsAssociate( uiClass );

   if( hb_pcount() > 0 )  // it may receive an existing hash as a parameter
      hb_arraySet( hb_stackReturnItem(), 1, hb_param( 1, HB_IT_ANY ) );
   else
      hb_arraySet( hb_stackReturnItem(), 1, hb_hashNew( NULL ) );    
}

#pragma ENDDUMP
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 42118
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: Class THash

Postby Antonio Linares » Mon Oct 30, 2023 2:00 pm

Manu Expósito's version:

Code: Select all  Expand view  RUN
[14:57, 10/30/2023] Manu Exposito: //-----------------------------------------------------------------------------
// Gestion de hash como objetos
//-----------------------------------------------------------------------------

#include "hbapiitm.h"
#include "hbvm.h"
#include "hbstack.h"

#define _GETHASH0() hb_arrayGetPtr( hb_stackSelfItem(), 1 )
#define _GETHASH1( pSelf ) hb_arrayGetPtr( (pSelf), 1 )

//-----------------------------------------------------------------------------
// Constructor

static void THBHASH_NEW( void )
{
    PHB_ITEM pSelf = hb_stackSelfItem();
    PHB_ITEM hTable =  hb_param( 1, HB_IT_HASH ) ;

    if( !hTable )
    {
        hTable = hb_hashNew( NULL );
        hb_arraySetPtr( pSelf, 1, hTable );
    }

    hb_itemReturn( pSelf );
}

//-----------------------------------------------------------------------------
// Asigna un nuevo hash para gestionarlo desde el objeto

static void THBHASH_SETHASH( void )
{
    PHB_ITEM pSelf = hb_stackSelfItem();
    PHB_ITEM hTable =  hb_param( 1, HB_IT_HASH );
    PHB_ITEM hTableOld = hb_arrayGetPtr( pSelf, 1 );

    if( hTable )
    {
        if( hTableOld )
        {
            hb_itemReturnRelease( hTableOld );
        }

        hb_arraySetPtr( pSelf, 1, hTable );

        return;
    }

    hb_itemReturn( hTableOld );
}

//-----------------------------------------------------------------------------
// Obtiene el hash gestionado desde el objeto

static void THBHASH_GETHASH( void )
{
    PHB_ITEM pSelf = hb_stackSelfItem();

    hb_itemReturn( hb_arrayGetPtr( pSelf, 1 ) );
}

//-----------------------------------------------------------------------------

static void THBHASH_LEN( void )
{
    hb_retnint( hb_hashLen( _GETHASH0() ) );
}

//-----------------------------------------------------------------------------

static void THBHASH_DEL( void )
{
    PHB_ITEM pKey = hb_param( 1, HB_IT_HASHKEY );

    if( pKey )
    {
        hb_retl( hb_hashDel( _GETHASH0(), pKey ) );
    }
    else
    {
        hb_retl( HB_FALSE );
    }
}

//-----------------------------------------------------------------------------

static void THBHASH_SET( void )
{
    PHB_ITEM pKey = hb_param( 1, HB_IT_HASHKEY );

    if( pKey )
    {
        hb_retl( hb_hashAdd( _GETHASH0(), pKey, hb_param( 2, HB_IT_ANY ) ) );
    }
    else
    {
        hb_retl( HB_FALSE );
    }
}

//-----------------------------------------------------------------------------

static void THBHASH_CLEAR( void )
{
    hb_retl( hb_hashClear( _GETHASH0() ) );
}

//-----------------------------------------------------------------------------

static void THBHASH_SORT( void )
{
    hb_hashSort( _GETHASH0() );

}

//-----------------------------------------------------------------------------

static void THBHASH_SCAN( void )
{
    HB_SIZE nPos = 0;
    PHB_ITEM pKey = hb_param( 1, HB_IT_HASHKEY );

    if( pKey )
    {
        hb_hashScan( _GETHASH0(),  pKey, &nPos );
    }

    hb_retnint( nPos );
}

//-----------------------------------------------------------------------------

static void THBHASH_KEYS( void )
{
    hb_itemReturn( hb_hashGetKeys( _GETHASH0() ) );
}

//-----------------------------------------------------------------------------

static void THBHASH_VALUES( void )
{
    hb_itemReturn( hb_hashGetValues( _GETHASH0() ) );
}

//-----------------------------------------------------------------------------

static void THBHASH_GET( void )
{
    PHB_ITEM pKey = hb_param( 1, HB_IT_HASHKEY );

    if( pKey )
    {
        PHB_ITEM pValue = hb_hashGetItemPtr( _GETHASH0(), pKey, HB_HASH_AUTOADD_ACCESS );

        if( pValue )
        {
            hb_itemReturn( pValue );
            return;
        }
    }

    hb_ret();
}

//-----------------------------------------------------------------------------

static void THBHASH_END( void )
{
    hb_itemRelease( _GETHASH0() );
}

//-----------------------------------------------------------------------------
// Añade los metodos de la clase

static void addMethods( HB_USHORT usClassH )
{
    // Datas
    hb_clsAdd( usClassH, "_HASH", THBHASH_SETHASH );
    hb_clsAdd( usClassH, "HASH", THBHASH_GETHASH );


[14:57, 10/30/2023] Manu Exposito: Y un ejemplo de uso
[14:57, 10/30/2023] Manu Exposito: //-----------------------------------------------------------------------------
// Ejemplo usu de THbHash
//-----------------------------------------------------------------------------

procedure main

    local h := THbHash():new()
    local i, c, n

    alert( valtype( h ) )
    alert( valtype( h:getHash() ) )

    for i := 1 to 10
        c := hb_ntos( i )
        h:set( "key" + c, "value" + c )
    next

    ? "Numero de elementos:", n:= h:len()
    ? "------------------------------------------------------"

    for i := 1 to n
        ? "Clave:", c := "key" + hb_ntos( i ), "Valor:", h:get( c )
    next

    h:end()

    alert( "Fin" )

return
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 42118
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: Class THash

Postby paquitohm » Wed Nov 01, 2023 10:18 am

Muy bueno.

A mi parecer faltaría una declaración previa de las DATAs posibles (opcional) para evitar posibles errores en tecleo que puedan suponer auténticas quebraduras de cabeza para encontrar el error, porque...

// ... no es lo mismo ...
o:cVar: "Texto"

// ... que
o:Var:= "Texto"

Salu2
paquitohm
 
Posts: 266
Joined: Fri Jan 14, 2022 8:37 am

Re: Class THash

Postby Antonio Linares » Wed Nov 01, 2023 4:18 pm

Querido Paco,

Si, buena idea, además hoy Ritzan ha comentado que las keys pueden ser case sensitive ó no, lo cual debe contemplarlo también la clase.

Además hay que implementar métodos que accedan a las funciones que ofrecen los hashes, es algo sencillo, pero aún no se ha hecho.

Entre todos la vamos mejorando, gracias :-)
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 42118
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: Class THash

Postby FiveWiDi » Wed Nov 01, 2023 7:05 pm

paquitohm wrote:Muy bueno.

A mi parecer faltaría una declaración previa de las DATAs posibles (opcional) para evitar posibles errores en tecleo que puedan suponer auténticas quebraduras de cabeza para encontrar el error, porque...

// ... no es lo mismo ...
o:cVar: "Texto"

// ... que
o:Var:= "Texto"

Salu2

Yo estaba en lo mismo.

Entendí que la clase evolucionaría en Fivetech, de ahí que mis primeros pasos fueran renombrándola para impedir conflictos entre clases declaradas.

Mis primeros pasos
Code: Select all  Expand view  RUN
/*

Tret del foro de Fivetechsoft.com el 25/10/2023 21:24

*/



#include "hbclass.ch"

/*
function Main()

   local oHash := TMyHash():New()
   
   oHash:one = "first"

   ? oHash:one

return nil
*/


CLASS TMyHash

   DATA hHash

   DATA lUpper INIT .F.
   DATA lChivato INIT .F.
   
   METHOD New() INLINE ::hHash := {=>}, Self

   ERROR HANDLER ONERROR()

ENDCLASS

METHOD ONERROR( uParam1 ) CLASS TMyHash

   local cKey := __GetMessage()
   //local uRet
   
   cKey := If( ::lUpper, Upper( cKey ), cKey )

   if Left( cKey, 1 ) == "_"
      cKey = SubStr( cKey, 2 )
      ::hHash[ cKey ] = uParam1
   else
      if ! hb_HHasKey( ::hHash, cKey )
         ::hHash[ cKey ] = nil
         If ::lChivato
             MsgStop( "No existe Hash: " + cKey, "Error!" )      
         EndIf
      endif        
   endif

RETURN ::hHash[ cKey ]
 

La DATA lchivato se utilizaría en pruebas de desarrollo de la aplicación, una vez superadas se dejaría a .F.

Por cierto, no domino en absoluto ni conozco las posibilidades de Hash, de ahí el uso de la DATA lUpper en lugar de su característica case sensitive.
Un Saludo
Carlos G.

FiveWin 24.02 + Harbour 3.2.0dev (r2403071241), BCC 7.7 Windows 10
FiveWiDi
 
Posts: 1190
Joined: Mon Oct 10, 2005 2:38 pm

Re: Class THash

Postby paquitohm » Wed Nov 01, 2023 9:37 pm

Aquí está la lista de funciones relativas a Hash: https://github.com/Petewg/harbour-core/wiki/hb_H

Incluso esta lista podria estar mas completa: https://www.kresin.ru/en/hrbfaq_3.html#Doc8

Para el tema case sensitive parece que habria que utilizar esta:
hb_HCaseMatch(<hHash>, [<lFlag>]) ➜ lPreviousFlag
paquitohm
 
Posts: 266
Joined: Fri Jan 14, 2022 8:37 am

Re: Class THash

Postby riztan » Sat Nov 04, 2023 2:42 am

Hola!

A continuación lo realizado respecto a la clase THbHash de Manu con algunas colaboraciones aportadas acá y de este servidor. A mi parecer, la clase ya cumple con lo necesario.

La Clase:
Code: Select all  Expand view  RUN

//-----------------------------------------------------------------------------
// Gestion de hash como objetos
//-----------------------------------------------------------------------------

#include "hbapiitm.h"
#include "hbvm.h"
#include "hbstack.h"
#include "hbapicls.h"
#include "hboo.ch"
#include "hbinit.h"

#define _GETHASH0() hb_arrayGetPtr( hb_stackSelfItem(), 1 )
#define _GETHASH1( pSelf ) hb_arrayGetPtr( (pSelf), 1 )

//-----------------------------------------------------------------------------
// Constructor

static void THBHASH_NEW( void )
{
    PHB_ITEM pSelf = hb_stackSelfItem();
    PHB_ITEM hTable;
    PHB_ITEM hTablePar = hb_param( 1, HB_IT_HASH );

    if( hTablePar )
    {
        hTable = hb_itemNew( NULL );
        hb_itemMove( hTable, hTablePar );
    }
    else
    {
        hTable = hb_hashNew( NULL );
    }

    hb_hashClearFlags( hTable, HB_HASH_BINARY );
    hb_hashSetFlags( hTable, HB_HASH_IGNORECASE | HB_HASH_RESORT );
    hb_arraySetPtr( pSelf, 1, hTable );

    hb_itemReturn( pSelf );
}

//-----------------------------------------------------------------------------
// Asigna un nuevo hash para gestionarlo desde el objeto

static void THBHASH_SETHASH( void )
{
    PHB_ITEM pSelf = hb_stackSelfItem();
    PHB_ITEM hTablePar = hb_param( 1, HB_IT_HASH );
    PHB_ITEM hTableOld = _GETHASH1( pSelf );

    if( hTableOld )
    {
        hTableOld = hb_hashNew( hTableOld );
    }

    if( hTablePar )
    {
        PHB_ITEM hTable = hb_itemNew( NULL );
       
        hb_itemMove( hTable, hTablePar );

        hb_hashClearFlags( hTable, HB_HASH_BINARY );
        hb_hashSetFlags( hTable, HB_HASH_IGNORECASE | HB_HASH_RESORT );
        hb_arraySetPtr( pSelf, 1, hTable );
    }

    hb_itemReturnRelease( hTableOld );
}

//-----------------------------------------------------------------------------
// Obtiene el hash gestionado desde el objeto

static void THBHASH_GETHASH( void )
{
    PHB_ITEM pSelf = hb_stackSelfItem();

    hb_itemReturn( hb_arrayGetPtr( pSelf, 1 ) );
}

//-----------------------------------------------------------------------------

static void THBHASH_LEN( void )
{
    hb_retnint( hb_hashLen( _GETHASH0() ) );
}

//-----------------------------------------------------------------------------

static void THBHASH_DEL( void )
{
    PHB_ITEM pKey = hb_param( 1, HB_IT_HASHKEY );

    if( pKey )
    {
        hb_retl( hb_hashDel( _GETHASH0(), pKey ) );
    }
    else
    {
        hb_retl( HB_FALSE );
    }
}

//-----------------------------------------------------------------------------

static void THBHASH_SET( void )
{
    PHB_ITEM pKey = hb_param( 1, HB_IT_HASHKEY );

    if( pKey )
    {
        hb_retl( hb_hashAdd( _GETHASH0(), pKey, hb_param( 2, HB_IT_ANY ) ) );
    }
    else
    {
        hb_retl( HB_FALSE );
    }
}

//-----------------------------------------------------------------------------

static void THBHASH_CLEAR( void )
{
    hb_retl( hb_hashClear( _GETHASH0() ) );
}

//-----------------------------------------------------------------------------

static void THBHASH_SORT( void )
{
    hb_hashSort( _GETHASH0() );

}

//-----------------------------------------------------------------------------

static void THBHASH_SCAN( void )
{
    HB_SIZE nPos = 0;
    PHB_ITEM pKey = hb_param( 1, HB_IT_HASHKEY );

    if( pKey )
    {
        hb_hashScan( _GETHASH0(), pKey, &nPos );
    }

    hb_retnint( nPos );
}

//-----------------------------------------------------------------------------

static void THBHASH_KEYS( void )
{
    hb_itemReturnRelease( hb_hashGetKeys( _GETHASH0() ) );
}

//-----------------------------------------------------------------------------

static void THBHASH_VALUES( void )
{
    hb_itemReturnRelease( hb_hashGetValues( _GETHASH0() ) );
}

//-----------------------------------------------------------------------------

static void THBHASH_GET( void )
{
    PHB_ITEM pKey = hb_param( 1, HB_IT_HASHKEY );

    if( pKey )
    {
        PHB_ITEM pValue = hb_hashGetItemPtr( _GETHASH0(), pKey, HB_HASH_AUTOADD_ACCESS );

        if( pValue )
        {
            hb_itemReturn( pValue );
            return;
        }
    }

    hb_ret();
}

//-----------------------------------------------------------------------------

static void THBHASH_VALUEAT( void )
{
    PHB_ITEM pPos = hb_param( 1, HB_IT_NUMERIC );

    if( pPos )
    {
        PHB_ITEM pValue = hb_hashGetValueAt( _GETHASH0(), hb_itemGetNS( pPos ) );

        if( pValue )
        {
            hb_itemReturn( pValue );
            return;
        }
    }

    hb_ret();
}

//-----------------------------------------------------------------------------

static void THBHASH_KEYAT( void )
{
    PHB_ITEM pPos = hb_param( 1, HB_IT_NUMERIC );

    if( pPos )
    {
        PHB_ITEM pKey = hb_hashGetKeyAt( _GETHASH0(), hb_itemGetNS( pPos ) );

        if( pKey )
        {
            hb_itemReturn( pKey );
            return;
        }
    }

    hb_ret();
}

//-----------------------------------------------------------------------------

static void THBHASH_DELAT( void )
{
    PHB_ITEM pPos = hb_param( 1, HB_IT_NUMERIC );

    if( pPos )
    {
        if( hb_hashDelAt( _GETHASH0(), hb_itemGetNS( pPos ) ) )
        {
            hb_retl( HB_TRUE );
            return;
        }
    }

    hb_retl( HB_FALSE );
}

//-----------------------------------------------------------------------------

static void THBHASH_HASKEY( void )
{
    PHB_ITEM pKey = hb_param( 1, HB_IT_HASHKEY );

    if( pKey )
    {
        HB_SIZE nPos;
        hb_retl( hb_hashScanSoft( _GETHASH0(), pKey, &nPos ) );
        hb_storns( nPos, 3 );
    }

    hb_ret();

}

//-----------------------------------------------------------------------------

static void THBHASH_SETFLAGS( void )
{
    PHB_ITEM nFlags = hb_param( 1, HB_IT_INTEGER );

    if( nFlags )
    {
        hb_hashSetFlags( _GETHASH0(), hb_itemGetNI( nFlags ) );
    }
}

//-----------------------------------------------------------------------------

static void THBHASH_GETFLAGS( void )
{
    hb_retni( hb_hashGetFlags( _GETHASH0() ) );
}

//-----------------------------------------------------------------------------

static void THBHASH_CLEARFLAGS( void )
{
    PHB_ITEM nFlags = hb_param( 1, HB_IT_INTEGER );

    if( nFlags )
    {
        hb_hashClearFlags( _GETHASH0(), hb_itemGetNI( nFlags ) );
    }
}

//-----------------------------------------------------------------------------

static void THBHASH_END( void )
{
    hb_itemRelease( _GETHASH0() );
}

//-----------------------------------------------------------------------------

HB_FUNC_STATIC( THBHASH_ONERROR )
{
    PHB_ITEM pKey;
    char *szKey;
    PHB_ITEM hTable = _GETHASH0();

    hb_vmPushSymbol( hb_dynsymSymbol( hb_dynsymFindName( "__GETMESSAGE" ) ) );
    hb_vmPushNil();
    hb_vmProc( 0 );

    pKey = hb_stackReturnItem();
    szKey = hb_itemGetC( pKey );

    if( szKey [ 0 ] == '_' )    // SET
    {
        hb_itemPutC( pKey, szKey + 1 );
        hb_hashAdd( hTable, pKey, hb_param( 1, HB_IT_ANY ) );
    }
    else    // GET
    {
        HB_SIZE nPos;

        if( hb_hashScan( hTable, pKey, &nPos ) )
        {
            hb_itemReturn( hb_hashGetValueAt( hTable, nPos ) );
        }
    }

    hb_xfree( szKey );
}

//-----------------------------------------------------------------------------
// Añade los metodos de la clase

static void addMethods( HB_USHORT usClassH )
{
    static HB_SYMB symOnError = { "ONERROR", { HB_FS_STATIC }, { HB_FUNCNAME( THBHASH_ONERROR ) }, NULL };

    // Data hash
    hb_clsAdd( usClassH, "_HASH", THBHASH_SETHASH );
    hb_clsAdd( usClassH, "HASH", THBHASH_GETHASH );
    // Data flags
    hb_clsAdd( usClassH, "_FLAGS", THBHASH_SETFLAGS );
    hb_clsAdd( usClassH, "FLAGS", THBHASH_GETFLAGS );
    // Metodos
    hb_clsAdd( usClassH, "NEW", THBHASH_NEW );
    hb_clsAdd( usClassH, "SETHASH", THBHASH_SETHASH );
    hb_clsAdd( usClassH, "GETHASH", THBHASH_GETHASH );
    hb_clsAdd( usClassH, "LEN", THBHASH_LEN );
    hb_clsAdd( usClassH, "DEL", THBHASH_DEL );
    hb_clsAdd( usClassH, "ADD", THBHASH_SET );
    hb_clsAdd( usClassH, "SET", THBHASH_SET );
    hb_clsAdd( usClassH, "GET", THBHASH_GET );
    hb_clsAdd( usClassH, "CLEAR", THBHASH_CLEAR );
    hb_clsAdd( usClassH, "SORT", THBHASH_SORT );
    hb_clsAdd( usClassH, "SCAN", THBHASH_SCAN );
    hb_clsAdd( usClassH, "KEYS", THBHASH_KEYS );
    hb_clsAdd( usClassH, "VALUES", THBHASH_VALUES );
    hb_clsAdd( usClassH, "VALUEAT", THBHASH_VALUEAT );
    hb_clsAdd( usClassH, "KEYAT", THBHASH_KEYAT );
    hb_clsAdd( usClassH, "DELAT", THBHASH_DELAT );
    hb_clsAdd( usClassH, "HASKEY", THBHASH_HASKEY );
    hb_clsAdd( usClassH, "SETFLAGS", THBHASH_SETFLAGS );
    hb_clsAdd( usClassH, "GETFLAGS", THBHASH_GETFLAGS );
    hb_clsAdd( usClassH, "CLEARFLAGS", THBHASH_CLEARFLAGS );
    hb_clsAdd( usClassH, "END", THBHASH_END );

    // Añade el metodo ONERROR como gestor de errores de la clase
    hb_vmPushSymbol( hb_dynsymFindSymbol( "__CLSADDMSG" ) );
    hb_vmPushNil();
    hb_vmPushInteger( usClassH );
    hb_vmPushString( "ONERROR", strlen( "ONERROR" ) );
    hb_vmPushSymbol( &symOnError );
    hb_vmPushInteger( HB_OO_MSG_ONERROR );
    hb_vmProc( 4 );
}

//-----------------------------------------------------------------------------
// Funcion de clase para usar desde Harbour
//-----------------------------------------------------------------------------

HB_FUNC( THBHASH )
{
    static HB_USHORT usClassH = 0;

    if( usClassH == 0 )
    {
        usClassH = hb_clsCreate( 1, "THBHASH" );
        addMethods( usClassH );
    }

    // Instancia un objeto de la clase THBARRAY y lo mete en la pila
    hb_clsAssociate( usClassH );

    // Asigna el objeto C++ a la data del objeto de xBase
    hb_arraySetPtr( hb_stackReturnItem(), 1, NULL );
}

//=============================================================================
// Inicializa los simbolos de las clase en la tabla de simbolos de harbour.
//=============================================================================

HB_INIT_SYMBOLS_BEGIN( THBHASH__InitSymbols )
    { "THBHASH", { HB_FS_PUBLIC | HB_FS_LOCAL }, { HB_FUNCNAME( THBHASH ) }, NULL }
HB_INIT_SYMBOLS_END( THBPGPP__InitSymbols )

#if defined( HB_PRAGMA_STARTUP )
    #pragma startup THBHASH__InitSymbols
#elif defined( HB_DATASEG_STARTUP )
    #define HB_DATASEG_BODY HB_DATASEG_FUNC( THBHASH__InitSymbols )
    #include "hbiniseg.h"
#endif

//-----------------------------------------------------------------------------
 


test00.prg
Code: Select all  Expand view  RUN

//-----------------------------------------------------------------------------
// Ejemplo uso de THbHash
//-----------------------------------------------------------------------------

procedure main

    local h := THbHash():new()
    local i, c, n

    alert( valtype( h ) )
    alert( valtype( h:getHash() ) )

    for i := 1 to 10
        c := hb_ntos( i )
        h:set( "key" + c, "value" + c )
    next

    ? "Numero de elementos:", n:= h:len()
    ? "------------------------------------------------------"

    for i := 1 to n
        ? "Clave:", c := "key" + hb_ntos( i ), "Valor:", h:get( c )
    next

    ? h:key1, h:get( "key1" )

    h:autor := "Manu Exposito"
    ? h:autor, h:get( "autor" )
   
    ? "------------------------------------------------------"
    ? "Keys:"
    ? hb_valtoexp( h:keys() )
    ? "Values:"
    ? hb_valtoexp( h:values() )

    h:end()

    alert( "Fin" )

return


test01.prg
Code: Select all  Expand view  RUN

//-----------------------------------------------------------------------------
// Ejemplo uso de THbHash
//-----------------------------------------------------------------------------

procedure main

    local hash := { "key1" => "valor1", "key2" => "valor2", "key3" => "valor3"}
    local h := THbHash():new( hash )

    ? "Numero de elementos:", h:len(), len( hash )
 
    h:autor := "Manu Exposito"
    ? h:autor, h:get( "autor" )

    hash[ "prueba" ] = "prueba desde fuera"
   
    ? "------------------------------------------------------"
    ? "Keys:"
    ? hb_valtoexp( h:keys() )
    ? "Values:"
    ? hb_valtoexp( h:values() )
    ? "Todo:"
    ? hb_valtoexp( hash )

    h:end()

    ? "Todo despues del end:"
    ? hb_valtoexp( hash )

    alert( "Fin" )

return
 


test02.prg
Code: Select all  Expand view  RUN

//-----------------------------------------------------------------------------
// Ejemplo uso de THbHash
//-----------------------------------------------------------------------------

procedure main

    local hash := { "key1" => "valor1", "key2" => "valor2", "key3" => "valor3"}
    local h := THbHash():new()

    ? "Numero de elementos:", h:len(), len( hash )
 
    h:setHash( hash )

    ? "Numero de elementos:", h:len(), len( hash )

    h:autor := "Manu Exposito"
    ? h:autor, h:get( "autor" )
 
    hash[ "prueba" ] = "prueba desde fuera"
   
    ? "------------------------------------------------------"
    ? "Keys:"
    ? hb_valtoexp( h:keys() )
    ? "Values:"
    ? hb_valtoexp( h:values() )
    ? "Todo:"
    ? hb_valtoexp( hash )

    h:end()

    ? "Todo despues del end:"
    ? hb_valtoexp( hash )

    alert( "Fin" )

return
 


test03.prg
Code: Select all  Expand view  RUN

//-----------------------------------------------------------------------------
// Ejemplo usu de THbHash
//-----------------------------------------------------------------------------

procedure main

    local h := THbHash():new()
    local i, c, cKey
   
    CLS

    h:cAuthor := "Manu Exposito"
    ? "Author: ", h:cAuthor, "Key con mayusculas y minusculas:", h:cAuThOr
    h:cAuthor := "YO Exposito"

    ? "valtype( h ) => ", valtype( h ) , " | "
    ?? "valtype( h:getHash() ) => ", valtype( h:getHash() )

    ? "------------------------------------------------------"
    ? "List of Methods:"
    ? hb_valtoexp( __objGetMethodList( h ) )

    for i := 1 to 10
        c := hb_ntos( i )
        h:set( "key" + c, "value" + c )
    next

    h:key1 := { 1, 2, 3, 4 }
    h:add( "key11", {|| alert("Fin!") } )
    ? "------------------------------------------------------"
    ? "Delete key10.       =>  h:del('key10')   => ", h:del( "key10" )
    ? "Scan the key5       =>  h:scan('key5')   => ", hb_valtoexp( h:scan( "key5" ) ), " ( Return value in key5 ) "
    ? "Value in position 6 =>  h:valueAt( 6 )   => ", hb_valtoexp( h:valueAt( 6 ) )
    ? "Is defined 'key8'?  =>  h:hasKey('key8') => ", h:hasKey( "key8" )

    ? "------------------------------------------------------"
    ? "Number of elements:", hb_ntos( h:len() )

    ? "Keys:"
    ? hb_valtoexp( h:keys() )
    ? "Values:"
    ? hb_valtoexp( h:values() )

    ? "------------------------------------------------------"
    FOR EACH cKey IN h:Keys()
       ? cKey, "=>" , hb_valtoexp( h:get(cKey) )
       if hb_isBlock( h:get(cKey) ) ; EVAL( h:get(cKey) ) ; endif
    NEXT

    h:end()

return
 



Saludos cordiales.
User avatar
riztan
 
Posts: 2
Joined: Sat May 13, 2006 8:21 pm
Location: Maracay - Venezuela

Re: Class THash

Postby riztan » Sun Nov 05, 2023 4:05 pm

User avatar
riztan
 
Posts: 2
Joined: Sat May 13, 2006 8:21 pm
Location: Maracay - Venezuela

Re: Class THash

Postby Antonio Linares » Sun Nov 05, 2023 6:35 pm

Querido Ritzan,

gracias! :-)
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 42118
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: Class THash

Postby FiveWiDi » Mon Nov 06, 2023 10:50 am

Hola a todos,

Antes de nada vaya por delante mi respeto y admiración por el trabajo de Manu Expósito, yo sigo utilizando su fantástica clase TDBF (en sintaxis prg no en c).
(Perdona Manu, te debo una respuesta desde hace tiempo, pero no doy más de mi).

No tengo ni nociones de 'C'; si que me desenvuelvo bastante bien con código en sintaxis PRG.

Por lo expuesto sólo puedo apuntarme a la clase que provea FiveTech, tanto da si es en C como en PRG, pero que forme parte de su producto.
Necesito poder actualizarme a las nuevas versiones de Harbour y FWH sin contratiempos. El tiempo que puedo dedicar a "investigar" cuando "sucede algo" es muy limitado.

Yo no soy capaz de modificar/ampliar/mantener una clase en C, de ahí esa decisión.

Os acordáis de TSBrowse? Pués ahí estamos.

Aún así agradezco muchísimo (no os lo imagináis), el que personas como Ustedes esten investigando y desarrollando en este campo.

Un abrazo,
Un Saludo
Carlos G.

FiveWin 24.02 + Harbour 3.2.0dev (r2403071241), BCC 7.7 Windows 10
FiveWiDi
 
Posts: 1190
Joined: Mon Oct 10, 2005 2:38 pm


Return to Utilities / Utilidades

Who is online

Users browsing this forum: No registered users and 1 guest