diff --git a/harbour/ChangeLog b/harbour/ChangeLog index f0ccf4b4fa..ff298c628f 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -8,6 +8,24 @@ 2002-12-01 13:30 UTC+0100 Foo Bar */ +2007-04-17 04:10 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl) + * harbour/include/hbapi.h + * harbour/source/vm/dynsym.c + * changed some declarations from 'char *' to 'const char *' + + * harbour/include/hbapicls.h + * harbour/source/vm/classes.c + * changed some declarations from 'char *' to 'const char *' + + added hb_clsFuncName(), hb_clsFindClass(), hb_objSetClass() + + * harbour/source/rtl/itemseri.c + ! fixed some stupid typos in previous commit + * added support for serialization of object variables - I'm + not sure it's good idea anyhow people ask about it so we + have it. Probably we should add some special method like + OnError(), f.e.: OnRestore() or sth like that and execute + it after deserialization or object cloning. + 2007-04-17 01:55 UTC+0100 Antonio Linares (alinares@fivetechsoft.com) + contrib/ole2/make_b32.bat + contrib/ole2/makefile.bc diff --git a/harbour/include/hbapi.h b/harbour/include/hbapi.h index e346cce7ad..8af6c12efa 100644 --- a/harbour/include/hbapi.h +++ b/harbour/include/hbapi.h @@ -802,24 +802,24 @@ extern HB_EXPORT void hb_put_le_uint64( BYTE * ptr, double d ); #endif /* dynamic symbol table management */ -extern HB_EXPORT PHB_DYNS hb_dynsymGet( char * szName ); /* finds and creates a dynamic symbol if not found */ -extern HB_EXPORT PHB_DYNS hb_dynsymGetCase( char * szName ); /* finds and creates a dynamic symbol if not found - case sensitive */ +extern HB_EXPORT PHB_DYNS hb_dynsymGet( const char * szName ); /* finds and creates a dynamic symbol if not found */ +extern HB_EXPORT PHB_DYNS hb_dynsymGetCase( const char * szName ); /* finds and creates a dynamic symbol if not found - case sensitive */ extern HB_EXPORT PHB_DYNS hb_dynsymNew( PHB_SYMB pSymbol ); /* creates a new dynamic symbol based on a local one */ -extern HB_EXPORT PHB_DYNS hb_dynsymFind( char * szName ); /* finds a dynamic symbol */ -extern HB_EXPORT PHB_DYNS hb_dynsymFindName( char * szName ); /* converts to uppercase and finds a dynamic symbol */ +extern HB_EXPORT PHB_DYNS hb_dynsymFind( const char * szName ); /* finds a dynamic symbol */ +extern HB_EXPORT PHB_DYNS hb_dynsymFindName( const char * szName ); /* converts to uppercase and finds a dynamic symbol */ extern HB_EXPORT void hb_dynsymLog( void ); /* displays all dynamic symbols */ extern HB_EXPORT void hb_dynsymRelease( void ); /* releases the memory of the dynamic symbol table */ extern HB_EXPORT void hb_dynsymEval( PHB_DYNS_FUNC pFunction, void * Cargo ); /* enumerates all dynamic symbols */ -extern HB_EXPORT PHB_SYMB hb_dynsymGetSymbol( char * szName ); /* finds and creates a dynamic symbol if not found and return pointer to its HB_SYMB structure */ -extern HB_EXPORT PHB_SYMB hb_dynsymFindSymbol( char * szName ); /* finds a dynamic symbol and return pointer to its HB_SYMB structure */ +extern HB_EXPORT PHB_SYMB hb_dynsymGetSymbol( const char * szName ); /* finds and creates a dynamic symbol if not found and return pointer to its HB_SYMB structure */ +extern HB_EXPORT PHB_SYMB hb_dynsymFindSymbol( const char * szName ); /* finds a dynamic symbol and return pointer to its HB_SYMB structure */ extern HB_EXPORT PHB_SYMB hb_dynsymSymbol( PHB_DYNS pDynSym ); -extern HB_EXPORT char * hb_dynsymName( PHB_DYNS pDynSym ); /* return dynamic symbol name */ +extern HB_EXPORT const char * hb_dynsymName( PHB_DYNS pDynSym ); /* return dynamic symbol name */ extern HB_EXPORT HB_HANDLE hb_dynsymMemvarHandle( PHB_DYNS pDynSym ); /* return memvar handle number bound with given dynamic symbol */ extern HB_EXPORT int hb_dynsymAreaHandle( PHB_DYNS pDynSym ); /* return work area number bound with given dynamic symbol */ extern HB_EXPORT void hb_dynsymSetAreaHandle( PHB_DYNS pDynSym, int iArea ); /* set work area number for a given dynamic symbol */ /* Symbol management */ -extern HB_EXPORT PHB_SYMB hb_symbolNew( char * szName ); /* create a new symbol */ +extern HB_EXPORT PHB_SYMB hb_symbolNew( const char * szName ); /* create a new symbol */ /* Command line and environment argument management */ extern HB_EXPORT void hb_cmdargInit( int argc, char * argv[] ); /* initialize command line argument API's */ diff --git a/harbour/include/hbapicls.h b/harbour/include/hbapicls.h index bb4e85510c..406e8c89b3 100644 --- a/harbour/include/hbapicls.h +++ b/harbour/include/hbapicls.h @@ -110,23 +110,26 @@ extern void hb_mthAddTime( ULONG ); /* profiler from classes.c */ /* class management */ HB_EXPORT extern char * hb_clsName( USHORT uiClass ); -HB_EXPORT extern BOOL hb_clsIsParent( USHORT uiClass, char * szParentName ); /* is a class handle inherited from szParentName Class ? */ +HB_EXPORT extern char * hb_clsFuncName( USHORT uiClass ); +HB_EXPORT extern BOOL hb_clsIsParent( USHORT uiClass, const char * szParentName ); /* is a class handle inherited from szParentName Class ? */ +HB_EXPORT extern USHORT hb_clsFindClass( const char * szClass, const char * szFunc ); /* object management */ HB_EXPORT extern USHORT hb_objGetClass( PHB_ITEM pItem ); /* get object class handle */ +HB_EXPORT extern USHORT hb_objSetClass( PHB_ITEM pItem, const char * szClass, const char * szFunc ); /* get object class handle using class name and class function name */ HB_EXPORT extern char * hb_objGetClsName( PHB_ITEM pObject ); /* retrieves an object class name */ -HB_EXPORT extern char * hb_objGetRealClsName( PHB_ITEM pObject, char * szString ); /* retrieves an object class name for a specific message */ +HB_EXPORT extern char * hb_objGetRealClsName( PHB_ITEM pObject, const char * szString ); /* retrieves an object class name for a specific message */ -HB_EXPORT extern BOOL hb_objHasMsg( PHB_ITEM pObject, char * szString ); /* returns TRUE/FALSE whether szString is an existing message for object */ +HB_EXPORT extern BOOL hb_objHasMsg( PHB_ITEM pObject, const char * szString ); /* returns TRUE/FALSE whether szString is an existing message for object */ HB_EXPORT extern BOOL hb_objHasMessage( PHB_ITEM pObject, PHB_DYNS pMessage ); -HB_EXPORT extern void hb_objSendMsg( PHB_ITEM pObj, char *sMsg, ULONG ulArg, ... ); +HB_EXPORT extern void hb_objSendMsg( PHB_ITEM pObj, const char *sMsg, ULONG ulArg, ... ); HB_EXPORT extern void hb_objSendMessage( PHB_ITEM pObj, PHB_DYNS pMessage, ULONG ulArg, ... ); /* Harbour equivalent for Clipper internal __mdCreate() */ -USHORT hb_clsCreate( USHORT usSize, char * szClassName ); +USHORT hb_clsCreate( USHORT usSize, const char * szClassName ); /* Harbour equivalent for Clipper internal __mdAdd() */ -void hb_clsAdd( USHORT usClassH, char * szMethodName, PHB_FUNC pFuncPtr ); +void hb_clsAdd( USHORT usClassH, const char * szMethodName, PHB_FUNC pFuncPtr ); /* Harbour equivalent for Clipper internal __mdAssociate() */ void hb_clsAssociate( USHORT usClassH ); diff --git a/harbour/source/rtl/itemseri.c b/harbour/source/rtl/itemseri.c index 624a2d6fbc..bb08a0445c 100644 --- a/harbour/source/rtl/itemseri.c +++ b/harbour/source/rtl/itemseri.c @@ -52,6 +52,7 @@ #include "hbapi.h" #include "hbapiitm.h" +#include "hbapicls.h" /* @@ -89,6 +90,7 @@ UCHAR [ 1 ] - item type 25. HASHREF32 4+n 26. SYMBOL 1+n 27. CYCLIC REFERENCE 4 + 28. OBJECT MARKER n+1+m+1 */ #define HB_SERIAL_NIL 0 @@ -119,6 +121,7 @@ UCHAR [ 1 ] - item type #define HB_SERIAL_HASHREF32 25 #define HB_SERIAL_SYMBOL 26 #define HB_SERIAL_REF 27 +#define HB_SERIAL_OBJ 28 #define HB_SERIAL_DUMMYOFFSET ( ( ULONG ) -1 ) @@ -216,6 +219,7 @@ static void hb_itemSerialOffsetSet( PHB_CYCLIC_REF pRef, PHB_ITEM pItem, if( pRef->ulOffset == ulOffset ) { pRef->value = ( void * ) pItem; + return; break; } pRef = pRef->pNext; @@ -230,6 +234,7 @@ static void hb_itemSerialOffsetGet( PHB_CYCLIC_REF pRef, PHB_ITEM pItem, if( pRef->ulOffset == ulOffset ) { hb_itemCopy( pItem, ( PHB_ITEM ) pRef->value ); + return; break; } pRef = pRef->pNext; @@ -251,7 +256,8 @@ static ULONG hb_itemSerialSize( PHB_ITEM pItem, PHB_CYCLIC_REF * pRefPtr, ULONG ULONG ulSize, ulLen, u; HB_LONG lVal; double d; - + USHORT uiClass; + switch( hb_itemType( pItem ) ) { case HB_IT_NIL: @@ -304,7 +310,16 @@ static ULONG hb_itemSerialSize( PHB_ITEM pItem, PHB_CYCLIC_REF * pRefPtr, ULONG break; case HB_IT_ARRAY: - if( hb_itemSerialValueRef( pRefPtr, hb_arrayId( pItem ), ulOffset ) ) + ulSize = 0; + uiClass = hb_objGetClass( pItem ); + if( uiClass ) + { + char * szClass = hb_clsName( uiClass ), + * szFunc = hb_clsFuncName( uiClass ); + if( szClass && szFunc ) + ulSize += strlen( szClass ) + strlen( szFunc ) + 3; + } + if( hb_itemSerialValueRef( pRefPtr, hb_arrayId( pItem ), ulOffset + ulSize ) ) { ulSize = 5; } @@ -312,11 +327,11 @@ static ULONG hb_itemSerialSize( PHB_ITEM pItem, PHB_CYCLIC_REF * pRefPtr, ULONG { ulLen = hb_arrayLen( pItem ); if( ulLen <= 255 ) - ulSize = 2; + ulSize += 2; else if( ulLen <= UINT16_MAX ) - ulSize = 3; + ulSize += 3; else - ulSize = 5; + ulSize += 5; for( u = 1; u <= ulLen; u++ ) ulSize += hb_itemSerialSize( hb_arrayGetItemPtr( pItem, u ), pRefPtr, ulOffset + ulSize ); @@ -477,6 +492,22 @@ static ULONG hb_serializeItem( PHB_ITEM pItem, UCHAR * pBuffer, } else { + USHORT uiClass = hb_objGetClass( pItem ); + if( uiClass ) + { + char * szClass = hb_clsName( uiClass ), + * szFunc = hb_clsFuncName( uiClass ); + if( szClass && szFunc ) + { + pBuffer[ ulOffset++ ] = HB_SERIAL_OBJ; + ulLen = strlen( szClass ) + 1; + memcpy( &pBuffer[ ulOffset ], szClass, ulLen ); + ulOffset += ulLen; + ulLen = strlen( szFunc ) + 1; + memcpy( &pBuffer[ ulOffset ], szFunc, ulLen ); + ulOffset += ulLen; + } + } ulLen = hb_arrayLen( pItem ); if( ulLen <= 255 ) { @@ -715,6 +746,18 @@ static ULONG hb_deserializeItem( PHB_ITEM pItem, UCHAR * pBuffer, ulOffset += 4; break; + case HB_SERIAL_OBJ: + { + char * szClass, * szFunc; + szClass = ( char * ) &pBuffer[ ulOffset ]; + ulLen = strlen( szClass ); + szFunc = szClass + ulLen + 1; + ulOffset = hb_deserializeItem( pItem, pBuffer, + ulOffset + ulLen + strlen( szFunc ) + 2, pRef ); + hb_objSetClass( pItem, szClass, szFunc ); + break; + } + default: hb_itemClear( pItem ); break; @@ -729,6 +772,9 @@ static BOOL hb_deserializeTest( UCHAR ** pBufferPtr, ULONG * pulSize, UCHAR * pBuffer = * pBufferPtr; ULONG ulSize = * pulSize, ulLen = 0; + if( ulSize == 0 ) + return FALSE; + switch( *pBuffer++ ) { case HB_SERIAL_NIL: @@ -756,13 +802,13 @@ static BOOL hb_deserializeTest( UCHAR ** pBufferPtr, ULONG * pulSize, break; case HB_SERIAL_SYMBOL: case HB_SERIAL_STRING8: - ulSize = 1 + ( ulSize >= 2 ? *pBuffer : ulSize ); + ulSize = 2 + ( ulSize >= 2 ? *pBuffer : ulSize ); break; case HB_SERIAL_STRING16: - ulSize = 1 + ( ulSize >= 3 ? HB_GET_LE_UINT16( pBuffer ) : ulSize ); + ulSize = 3 + ( ulSize >= 3 ? HB_GET_LE_UINT16( pBuffer ) : ulSize ); break; case HB_SERIAL_STRING32: - ulSize = 1 + ( ulSize >= 5 ? HB_GET_LE_UINT32( pBuffer ) : ulSize ); + ulSize = 5 + ( ulSize >= 5 ? HB_GET_LE_UINT32( pBuffer ) : ulSize ); break; case HB_SERIAL_ARRAYREF8: if( hb_itemSerialOffsetRef( pRefPtr, NULL, ulOffset ) ) @@ -841,6 +887,20 @@ static BOOL hb_deserializeTest( UCHAR ** pBufferPtr, ULONG * pulSize, return FALSE; ulSize = 5; break; + case HB_SERIAL_OBJ: + ulLen = hb_strnlen( ( char * ) pBuffer, ulSize - 1 ) + 1; + if( ulLen >= ulSize ) + ulSize++; + else + { + ulLen += hb_strnlen( ( char * ) pBuffer + ulLen, ulSize - ulLen - 1 ) + 2; + if( ulLen >= ulSize ) + ulSize++; + else + ulSize = ulLen; + } + ulLen = 1; + break; default: ulSize = 1; break; @@ -858,7 +918,7 @@ static BOOL hb_deserializeTest( UCHAR ** pBufferPtr, ULONG * pulSize, ulSize = * pulSize; if( !hb_deserializeTest( pBufferPtr, pulSize, ulOffset, pRefPtr ) ) return FALSE; - ulOffset += ulSize - * pulSize; + ulSize -= * pulSize; --ulLen; } diff --git a/harbour/source/vm/classes.c b/harbour/source/vm/classes.c index 6c6c2e5863..3b7685fac5 100644 --- a/harbour/source/vm/classes.c +++ b/harbour/source/vm/classes.c @@ -1098,7 +1098,7 @@ void hb_clsIsClassRef( void ) #endif } -HB_EXPORT BOOL hb_clsIsParent( USHORT uiClass, char * szParentName ) +HB_EXPORT BOOL hb_clsIsParent( USHORT uiClass, const char * szParentName ) { if( uiClass && uiClass <= s_uiClasses ) { @@ -1126,6 +1126,20 @@ HB_EXPORT USHORT hb_objGetClass( PHB_ITEM pItem ) return 0; } +/* get object class handle using class name and class function name */ +HB_EXPORT USHORT hb_objSetClass( PHB_ITEM pItem, const char * szClass, const char * szFunc ) +{ + USHORT uiClass = 0; + + if( pItem && HB_IS_ARRAY( pItem ) && + pItem->item.asArray.value->uiClass == 0 ) + { + uiClass = pItem->item.asArray.value->uiClass = + hb_clsFindClass( szClass, szFunc ); + } + return uiClass; +} + /* ================================================ */ /* @@ -1182,12 +1196,37 @@ HB_EXPORT char * hb_clsName( USHORT uiClass ) return NULL; } +HB_EXPORT char * hb_clsFuncName( USHORT uiClass ) +{ + if( uiClass && uiClass <= s_uiClasses ) + return s_pClasses[ uiClass ].pClassFuncSym ? + s_pClasses[ uiClass ].pClassFuncSym->szName : ( char * ) ""; + else + return NULL; +} + +HB_EXPORT USHORT hb_clsFindClass( const char * szClass, const char * szFunc ) +{ + USHORT uiClass; + + for( uiClass = 1; uiClass <= s_uiClasses; uiClass++ ) + { + if( strcmp( szClass, s_pClasses[ uiClass ].szName ) == 0 && + ( !szFunc || ( !s_pClasses[ uiClass ].pClassFuncSym ? !*szFunc : + strcmp( szFunc, s_pClasses[ uiClass ].pClassFuncSym->szName ) == 0 ) ) ) + { + return uiClass; + } + } + return 0; +} + /* * Get the real class name of an object message * Will return the class name from wich the message is inherited in case * of inheritance. */ -HB_EXPORT char * hb_objGetRealClsName( PHB_ITEM pObject, char * szName ) +HB_EXPORT char * hb_objGetRealClsName( PHB_ITEM pObject, const char * szName ) { HB_TRACE(HB_TR_DEBUG, ("hb_objGetrealClsName(%p)", pObject)); @@ -1792,7 +1831,7 @@ HB_EXPORT BOOL hb_objHasMessage( PHB_ITEM pObject, PHB_DYNS pMessage ) * * should be read as a boolean */ -HB_EXPORT BOOL hb_objHasMsg( PHB_ITEM pObject, char *szString ) +HB_EXPORT BOOL hb_objHasMsg( PHB_ITEM pObject, const char *szString ) { PHB_DYNS pDynSym; @@ -1836,7 +1875,7 @@ HB_EXPORT void hb_objSendMessage( PHB_ITEM pObject, PHB_DYNS pMsgSym, ULONG ulAr } } -HB_EXPORT void hb_objSendMsg( PHB_ITEM pObject, char *sMsg, ULONG ulArg, ... ) +HB_EXPORT void hb_objSendMsg( PHB_ITEM pObject, const char *sMsg, ULONG ulArg, ... ) { hb_vmPushSymbol( hb_dynsymGet( sMsg )->pSymbol ); hb_vmPush( pObject ); @@ -2052,7 +2091,7 @@ static HB_TYPE hb_clsGetItemType( PHB_ITEM pItem ) * HB_OO_MSG_CLSASSIGN : / * HB_OO_MSG_SUPER : Superclass handle */ -static BOOL hb_clsAddMsg( USHORT uiClass, char * szMessage, +static BOOL hb_clsAddMsg( USHORT uiClass, const char * szMessage, USHORT uiType, USHORT uiScope, PHB_ITEM pFunction, PHB_ITEM pInit ) { @@ -2512,7 +2551,7 @@ HB_FUNC( __CLSADDMSG ) * when true all functions and classes from the same * module as pClassFunc are defined as friends */ -static USHORT hb_clsNew( char * szClassName, USHORT uiDatas, +static USHORT hb_clsNew( const char * szClassName, USHORT uiDatas, PHB_ITEM pSuperArray, PHB_SYMB pClassFunc, BOOL fModuleFriendly ) { @@ -3954,13 +3993,13 @@ HB_FUNC( HB_SETCLSHANDLE ) /* ( oObject, nClassHandle ) --> nPrevClassHandle */ } /* Harbour equivalent for Clipper internal __mdCreate() */ -USHORT hb_clsCreate( USHORT usSize, char * szClassName ) +USHORT hb_clsCreate( USHORT usSize, const char * szClassName ) { return hb_clsNew( szClassName, usSize, NULL, NULL, FALSE ); } /* Harbour equivalent for Clipper internal __mdAdd() */ -void hb_clsAdd( USHORT usClassH, char * szMethodName, PHB_FUNC pFuncPtr ) +void hb_clsAdd( USHORT usClassH, const char * szMethodName, PHB_FUNC pFuncPtr ) { PHB_SYMB pExecSym; PHB_ITEM pFuncItem; diff --git a/harbour/source/vm/dynsym.c b/harbour/source/vm/dynsym.c index 32cd66b3f3..70a11a0613 100644 --- a/harbour/source/vm/dynsym.c +++ b/harbour/source/vm/dynsym.c @@ -89,7 +89,7 @@ void hb_dynsymLog( void ) printf( "%i %s\n", uiPos + 1, s_pDynItems[ uiPos ].pDynSym->pSymbol->szName ); } -HB_EXPORT PHB_SYMB hb_symbolNew( char * szName ) /* Create a new symbol */ +HB_EXPORT PHB_SYMB hb_symbolNew( const char * szName ) /* Create a new symbol */ { PHB_SYM_HOLDER pHolder; int iLen; @@ -168,7 +168,7 @@ HB_EXPORT PHB_DYNS hb_dynsymNew( PHB_SYMB pSymbol ) /* creates a new dynamic return pDynSym; } -HB_EXPORT PHB_DYNS hb_dynsymGetCase( char * szName ) /* finds and creates a symbol if not found */ +HB_EXPORT PHB_DYNS hb_dynsymGetCase( const char * szName ) /* finds and creates a symbol if not found */ { PHB_DYNS pDynSym; @@ -181,7 +181,7 @@ HB_EXPORT PHB_DYNS hb_dynsymGetCase( char * szName ) /* finds and creates a sym return pDynSym; } -HB_EXPORT PHB_DYNS hb_dynsymGet( char * szName ) /* finds and creates a symbol if not found */ +HB_EXPORT PHB_DYNS hb_dynsymGet( const char * szName ) /* finds and creates a symbol if not found */ { PHB_DYNS pDynSym; char szUprName[ HB_SYMBOL_NAME_LEN + 1 ]; @@ -226,7 +226,7 @@ HB_EXPORT PHB_DYNS hb_dynsymGet( char * szName ) /* finds and creates a symbol return pDynSym; } -HB_EXPORT PHB_DYNS hb_dynsymFindName( char * szName ) /* finds a symbol */ +HB_EXPORT PHB_DYNS hb_dynsymFindName( const char * szName ) /* finds a symbol */ { char szUprName[ HB_SYMBOL_NAME_LEN + 1 ]; @@ -265,7 +265,7 @@ HB_EXPORT PHB_DYNS hb_dynsymFindName( char * szName ) /* finds a symbol */ return hb_dynsymFind( szUprName ); } -HB_EXPORT PHB_DYNS hb_dynsymFind( char * szName ) +HB_EXPORT PHB_DYNS hb_dynsymFind( const char * szName ) { HB_TRACE(HB_TR_DEBUG, ("hb_dynsymFind(%s)", szName)); @@ -331,14 +331,14 @@ HB_EXPORT PHB_DYNS hb_dynsymFind( char * szName ) return NULL; } -HB_EXPORT PHB_SYMB hb_dynsymGetSymbol( char * szName ) +HB_EXPORT PHB_SYMB hb_dynsymGetSymbol( const char * szName ) { HB_TRACE(HB_TR_DEBUG, ("hb_dynsymGetSymbol(%s)", szName)); return hb_dynsymGet( szName )->pSymbol; } -HB_EXPORT PHB_SYMB hb_dynsymFindSymbol( char * szName ) +HB_EXPORT PHB_SYMB hb_dynsymFindSymbol( const char * szName ) { PHB_DYNS pDynSym; @@ -355,7 +355,7 @@ HB_EXPORT PHB_SYMB hb_dynsymSymbol( PHB_DYNS pDynSym ) return pDynSym->pSymbol; } -HB_EXPORT char * hb_dynsymName( PHB_DYNS pDynSym ) +HB_EXPORT const char * hb_dynsymName( PHB_DYNS pDynSym ) { HB_TRACE(HB_TR_DEBUG, ("hb_dynsymName(%p)", pDynSym));