2014-08-27 18:19 UTC+0200 Przemyslaw Czerpak (druzus/at/poczta.onet.pl)

* include/hbserial.ch
  * src/rtl/itemseri.c
    + added HB_SERIALIZE_IGNOREREF flag.
      This flag fully disables logic used to detect multireferences to the
      same complex (sub)items like arrays or hashes. It increses the speed
      of serialization but serialized data does not contain any information
      about refences, i.e. aVal[ 1 ] and aVal[ 2 ] in code below:
         aSub := { 1, 2, 3 }
         aVal := { aSub, aSub }
      are serialized as separated arrays. Additionally items with cyclic
      references like:
         aSub[ 2 ] := aSub
      cannot be serialized at all with HB_SERIALIZE_IGNOREREF flag because
      it will create infinite serialization loop and crash with out of
      memory message.

  * src/rtl/itemseri.c
    % rewritten algorithm used to detect cyclic and multi references in
      serialized items. The original algorithm has very high overhead when
      huge arrays were serialized, i.e. serialization of array with 1'000'000
      of subarrays needed about 30 minutes on my i5@3.30GHz. Now it needs
      less then a second and this time is only a little bit bigger then
      used by serialization with HB_SERIALIZE_IGNOREREF flag.
      This modification improve performance also in other code using Harbour
      serialization mechanism like I18N files, HBNETIO, GTNET, ... when large
      arrays or hashes are saved or transmitted.

  * include/hbapi.h
  * include/hbapicls.h
  * src/vm/arrays.c
  * src/vm/classes.c
  * src/vm/hashes.c
  * src/vm/itemapi.c
    * replaced algorithm used to detect cyclic and multi references in
      array and hash clone operations with new one similar to current
      item serial code. The speed improvement for very large arrays is
      the same as in case of serialization code.

  * src/rtl/gtsln/mousesln.c
    ! typo in while loop - synced with Viktor's branch
This commit is contained in:
Przemysław Czerpak
2014-08-27 18:19:36 +02:00
parent e222fc9080
commit 2e65a28363
10 changed files with 478 additions and 304 deletions

View File

@@ -10,6 +10,48 @@
* Change, ! Fix, % Optimization, + Addition, - Removal, ; Comment
*/
2014-08-27 18:19 UTC+0200 Przemyslaw Czerpak (druzus/at/poczta.onet.pl)
* include/hbserial.ch
* src/rtl/itemseri.c
+ added HB_SERIALIZE_IGNOREREF flag.
This flag fully disables logic used to detect multireferences to the
same complex (sub)items like arrays or hashes. It increses the speed
of serialization but serialized data does not contain any information
about refences, i.e. aVal[ 1 ] and aVal[ 2 ] in code below:
aSub := { 1, 2, 3 }
aVal := { aSub, aSub }
are serialized as separated arrays. Additionally items with cyclic
references like:
aSub[ 2 ] := aSub
cannot be serialized at all with HB_SERIALIZE_IGNOREREF flag because
it will create infinite serialization loop and crash with out of
memory message.
* src/rtl/itemseri.c
% rewritten algorithm used to detect cyclic and multi references in
serialized items. The original algorithm has very high overhead when
huge arrays were serialized, i.e. serialization of array with 1'000'000
of subarrays needed about 30 minutes on my i5@3.30GHz. Now it needs
less then a second and this time is only a little bit bigger then
used by serialization with HB_SERIALIZE_IGNOREREF flag.
This modification improve performance also in other code using Harbour
serialization mechanism like I18N files, HBNETIO, GTNET, ... when large
arrays or hashes are saved or transmitted.
* include/hbapi.h
* include/hbapicls.h
* src/vm/arrays.c
* src/vm/classes.c
* src/vm/hashes.c
* src/vm/itemapi.c
* replaced algorithm used to detect cyclic and multi references in
array and hash clone operations with new one similar to current
item serial code. The speed improvement for very large arrays is
the same as in case of serialization code.
* src/rtl/gtsln/mousesln.c
! typo in while loop - synced with Viktor's branch
2014-08-22 14:41 UTC+0200 Przemyslaw Czerpak (druzus/at/poczta.onet.pl)
* src/vm/hvm.c
* map 0 and 1 byte length strings to the same addresses

View File

@@ -459,11 +459,17 @@ typedef struct _HB_EXTREF
HB_EXTREF_FUNC0 mark;
} HB_EXTREF, * PHB_EXTREF;
typedef struct _HB_NESTED_CLONED
typedef struct
{
void * value;
PHB_ITEM pDest;
struct _HB_NESTED_CLONED * pNext;
} HB_NESTED_REF, * PHB_NESTED_REF;
typedef struct
{
HB_SIZE nSize;
HB_SIZE nCount;
PHB_NESTED_REF pRefs;
} HB_NESTED_CLONED, * PHB_NESTED_CLONED;
#endif /* _HB_API_INTERNAL_ */
@@ -862,8 +868,10 @@ extern HB_EXPORT HB_LONGLONG hb_arrayGetNLL( PHB_ITEM pArray, HB_SIZE nIndex );
/* internal array API not exported */
extern void hb_arrayPushBase( PHB_BASEARRAY pBaseArray );
extern void hb_arraySwap( PHB_ITEM pArray1, PHB_ITEM pArray2 );
extern void hb_cloneNested( PHB_ITEM pDstItem, PHB_ITEM pSrcItem, PHB_NESTED_CLONED pClonedList );
extern void hb_hashCloneBody( PHB_ITEM pHash, PHB_ITEM pDest, PHB_NESTED_CLONED pClonedList );
extern void hb_nestedCloneInit( PHB_NESTED_CLONED pClonedList, void * pValue, PHB_ITEM pDest );
extern void hb_nestedCloneFree( PHB_NESTED_CLONED pClonedList );
extern void hb_nestedCloneDo( PHB_ITEM pDstItem, PHB_ITEM pSrcItem, PHB_NESTED_CLONED pClonedList );
extern void hb_hashCloneBody( PHB_ITEM pDest, PHB_ITEM pHash, PHB_NESTED_CLONED pClonedList );
#endif

View File

@@ -100,7 +100,8 @@ extern HB_BOOL hb_objGetVarRef( PHB_ITEM pObject, PHB_SYMB pMessage, PHB_STAC
extern HB_BOOL hb_objHasOperator( PHB_ITEM pObject, HB_USHORT uiOperator );
extern HB_BOOL hb_objOperatorCall( HB_USHORT uiOperator, PHB_ITEM pResult, PHB_ITEM pObject, PHB_ITEM pMsgArg1, PHB_ITEM pMsgArg2 );
extern void hb_objDestructorCall( PHB_ITEM pObject );
extern void hb_objCloneTo( PHB_ITEM pDest, PHB_ITEM pSource, PHB_NESTED_CLONED pClonedList );
extern PHB_ITEM hb_objCloneTo( PHB_ITEM pDest, PHB_ITEM pObject );
extern void hb_objCloneBody( PHB_ITEM pDest, PHB_ITEM pObject, PHB_NESTED_CLONED pClonedList );
#ifndef HB_NO_PROFILER
/* profiler for object management */

View File

@@ -54,5 +54,6 @@
#define HB_SERIALIZE_NUMSIZE 0x01
#define HB_SERIALIZE_OBJECTSTRUCT 0x02
#define HB_SERIALIZE_COMPRESS 0x04
#define HB_SERIALIZE_IGNOREREF 0x08
#endif /* HB_SERIAL_CH_ */

View File

@@ -368,7 +368,7 @@ void hb_gt_sln_mouse_Init( void )
s_bMousePresent = HB_TRUE;
while( GetGpmEvent( &Evt ) );
while( GetGpmEvent( &Evt ) )
{
s_iMouseRow = Evt.y;
s_iMouseCol = Evt.x;

View File

@@ -185,74 +185,191 @@ complex ones:
#define HB_SERIAL_DUMMYOFFSET ( ( HB_SIZE ) -1 )
typedef struct _HB_CYCLIC_REF
#define HB_SERIAL_REFLSTINIT 16
typedef struct
{
void * value;
HB_SIZE nOffset;
int iRefs;
int iType;
struct _HB_CYCLIC_REF * pNext;
} HB_CYCLIC_REF, * PHB_CYCLIC_REF;
} HB_REF_ITEM, * PHB_REF_ITEM;
typedef struct
{
HB_SIZE nSize;
HB_SIZE nCount;
PHB_REF_ITEM pRefs;
} HB_REF_LIST, * PHB_REF_LIST;
static HB_SIZE hb_deserializeItem( PHB_ITEM pItem,
PHB_CODEPAGE cdpIn, PHB_CODEPAGE cdpOut,
const HB_UCHAR * pBuffer, HB_SIZE nOffset,
PHB_CYCLIC_REF pRef );
PHB_REF_LIST pRefList );
/* used by hb_itemSerialSize() for HB_IT_ARRAY and HB_IT_HASH */
static HB_BOOL hb_itemSerialValueRef( PHB_CYCLIC_REF * pRefPtr, void * value,
HB_SIZE nOffset )
/*
static void hb_itemSerialRefListShow( PHB_REF_LIST pRefList )
{
while( *pRefPtr )
HB_SIZE nPos;
printf( "\n================================\n" );
printf( "pRefList->nSize=%ld, pRefList->nCount=%ld\n", pRefList->nSize, pRefList->nCount );
for( nPos = 0; nPos < pRefList->nCount; ++nPos )
{
if( ( *pRefPtr )->value == value )
printf( "\t%ld] value=0x%p, nOffset=%ld, iRefs=%d, iType=%d\n", nPos,
pRefList->pRefs[ nPos ].value,
pRefList->pRefs[ nPos ].nOffset,
pRefList->pRefs[ nPos ].iRefs,
pRefList->pRefs[ nPos ].iType );
}
printf( "================================\n" ); fflush( stdout );
}
*/
static void hb_itemSerialRefListInit( PHB_REF_LIST pRefList )
{
memset( pRefList, 0, sizeof( HB_REF_LIST ) );
}
static void hb_itemSerialRefListFree( PHB_REF_LIST pRefList )
{
if( pRefList->nSize )
hb_xfree( pRefList->pRefs );
}
static PHB_REF_ITEM hb_itemSerialValueFind( PHB_REF_LIST pRefList, void * value,
HB_SIZE * pnPos )
{
HB_SIZE nFirst, nLast, nMiddle;
nFirst = 0;
nLast = pRefList->nCount;
nMiddle = ( nFirst + nLast ) >> 1;
while( nFirst < nLast )
{
if( ( HB_PTRUINT ) pRefList->pRefs[ nMiddle ].value < ( HB_PTRUINT ) value )
nFirst = nMiddle + 1;
else if( ( HB_PTRUINT ) pRefList->pRefs[ nMiddle ].value > ( HB_PTRUINT ) value )
nLast = nMiddle;
else
{
( *pRefPtr )->iRefs = 1;
return HB_TRUE;
* pnPos = nMiddle;
return &pRefList->pRefs[ nMiddle ];
}
pRefPtr = &( *pRefPtr )->pNext;
nMiddle = ( nFirst + nLast ) >> 1;
}
*pRefPtr = ( PHB_CYCLIC_REF ) hb_xgrab( sizeof( HB_CYCLIC_REF ) );
( *pRefPtr )->value = value;
( *pRefPtr )->nOffset = nOffset;
( *pRefPtr )->iRefs = 0;
( *pRefPtr )->iType = 0;
( *pRefPtr )->pNext = NULL;
* pnPos = nMiddle;
return NULL;
}
static PHB_REF_ITEM hb_itemSerialOffsetFind( PHB_REF_LIST pRefList, HB_SIZE nOffset,
int iType, HB_SIZE * pnPos )
{
HB_SIZE nFirst, nLast, nMiddle;
nFirst = 0;
nLast = pRefList->nCount;
nMiddle = ( nFirst + nLast ) >> 1;
while( nFirst < nLast )
{
if( pRefList->pRefs[ nMiddle ].nOffset < nOffset )
nFirst = nMiddle + 1;
else if( pRefList->pRefs[ nMiddle ].nOffset > nOffset )
nLast = nMiddle;
else if( pRefList->pRefs[ nMiddle ].iType < iType )
nFirst = nMiddle + 1;
else if( pRefList->pRefs[ nMiddle ].iType > iType )
nLast = nMiddle;
else
{
* pnPos = nMiddle;
return &pRefList->pRefs[ nMiddle ];
}
nMiddle = ( nFirst + nLast ) >> 1;
}
* pnPos = nMiddle;
return NULL;
}
/* used by hb_itemSerialSize() for HB_IT_ARRAY and HB_IT_HASH */
static HB_BOOL hb_itemSerialValueRef( PHB_REF_LIST pRefList, void * value,
HB_SIZE nOffset )
{
PHB_REF_ITEM pRef;
HB_SIZE nPos;
if( ( pRef = hb_itemSerialValueFind( pRefList, value, &nPos ) ) != NULL )
{
pRef->iRefs = 1;
return HB_TRUE;
}
if( pRefList->nCount >= pRefList->nSize )
{
if( pRefList->nSize == 0 )
pRefList->nSize = HB_SERIAL_REFLSTINIT;
else
pRefList->nSize += pRefList->nSize >> 1;
pRefList->pRefs = ( PHB_REF_ITEM )
hb_xrealloc( pRefList->pRefs,
pRefList->nSize * sizeof( HB_REF_ITEM ) );
}
pRef = &pRefList->pRefs[ nPos ];
if( nPos < pRefList->nCount )
memmove( pRef + 1, pRef, ( pRefList->nCount - nPos ) * sizeof( HB_REF_ITEM ) );
pRefList->nCount++;
pRef->value = value;
pRef->nOffset = nOffset;
pRef->iRefs = 0;
pRef->iType = 0;
return HB_FALSE;
}
/* used between hb_itemSerialSize() and hb_serializeItem() */
static void hb_itemSerialUnRefFree( PHB_CYCLIC_REF * pRefPtr )
static void hb_itemSerialUnusedFree( PHB_REF_LIST pRefList )
{
PHB_CYCLIC_REF pRef;
while( *pRefPtr )
if( pRefList->nSize )
{
pRef = *pRefPtr;
if( pRef->iRefs == 0 )
HB_SIZE nPos, nCount;
for( nPos = nCount = 0; nPos < pRefList->nCount; ++nPos )
{
*pRefPtr = pRef->pNext;
hb_xfree( pRef );
if( pRefList->pRefs[ nPos ].iRefs != 0 )
{
if( nCount != nPos )
memcpy( &pRefList->pRefs[ nCount ], &pRefList->pRefs[ nPos ],
sizeof( HB_REF_ITEM ) );
++nCount;
}
}
else
pRefPtr = &pRef->pNext;
pRefList->nSize = pRefList->nCount = nCount;
pRefList->pRefs = ( PHB_REF_ITEM )
hb_xrealloc( pRefList->pRefs,
nCount * sizeof( HB_REF_ITEM ) );
}
}
/* used by hb_serializeItem() for HB_IT_ARRAY and HB_IT_HASH */
static HB_BOOL hb_itemSerialValueOffset( PHB_CYCLIC_REF pRef, void * value,
static HB_BOOL hb_itemSerialValueOffset( PHB_REF_LIST pRefList, void * value,
HB_SIZE nOffset, HB_SIZE * pnRef )
{
while( pRef )
PHB_REF_ITEM pRef;
HB_SIZE nPos;
if( ( pRef = hb_itemSerialValueFind( pRefList, value, &nPos ) ) != NULL )
{
if( pRef->value == value )
{
*pnRef = pRef->nOffset;
return pRef->nOffset < nOffset;
}
pRef = pRef->pNext;
*pnRef = pRef->nOffset;
return pRef->nOffset < nOffset;
}
*pnRef = HB_SERIAL_DUMMYOFFSET;
@@ -261,128 +378,129 @@ static HB_BOOL hb_itemSerialValueOffset( PHB_CYCLIC_REF pRef, void * value,
/* used by hb_deserializeTest()
for HB_SERIAL_ARRAYREF*, HB_SERIAL_HASHREF*, HB_SERIAL_REF */
static HB_BOOL hb_itemSerialOffsetRef( PHB_CYCLIC_REF * pRefPtr, HB_SIZE nOffset )
static HB_BOOL hb_itemSerialOffsetRef( PHB_REF_LIST pRefList, HB_SIZE nOffset )
{
while( *pRefPtr )
PHB_REF_ITEM pRef;
HB_SIZE nPos;
if( hb_itemSerialOffsetFind( pRefList, nOffset, 0, &nPos ) != NULL )
return HB_TRUE;
if( pRefList->nCount >= pRefList->nSize )
{
if( ( *pRefPtr )->nOffset == nOffset )
return HB_TRUE;
pRefPtr = &( *pRefPtr )->pNext;
if( pRefList->nSize == 0 )
pRefList->nSize = HB_SERIAL_REFLSTINIT;
else
pRefList->nSize += pRefList->nSize >> 1;
pRefList->pRefs = ( PHB_REF_ITEM )
hb_xrealloc( pRefList->pRefs,
pRefList->nSize * sizeof( HB_REF_ITEM ) );
}
*pRefPtr = ( PHB_CYCLIC_REF ) hb_xgrab( sizeof( HB_CYCLIC_REF ) );
( *pRefPtr )->value = NULL;
( *pRefPtr )->nOffset = nOffset;
( *pRefPtr )->iRefs = 0;
( *pRefPtr )->iType = 0;
( *pRefPtr )->pNext = NULL;
pRef = &pRefList->pRefs[ nPos ];
if( nPos < pRefList->nCount )
memmove( pRef + 1, pRef, ( pRefList->nCount - nPos ) * sizeof( HB_REF_ITEM ) );
pRefList->nCount++;
pRef->value = NULL;
pRef->nOffset = nOffset;
pRef->iRefs = 0;
pRef->iType = 0;
return HB_FALSE;
}
/* used by hb_deserializeTest() for HB_SERIAL_XHB_R */
static void hb_itemSerialTypedRef( PHB_CYCLIC_REF * pRefPtr, int iType,
static void hb_itemSerialTypedRef( PHB_REF_LIST pRefList, int iType,
HB_SIZE nIndex )
{
PHB_CYCLIC_REF pRef;
HB_SIZE nPos;
while( *pRefPtr )
if( hb_itemSerialOffsetFind( pRefList, nIndex, iType, &nPos ) == NULL )
{
if( ( *pRefPtr )->iType == iType && ( *pRefPtr )->nOffset <= nIndex )
{
if( ( *pRefPtr )->nOffset == nIndex )
return;
else
break;
}
pRefPtr = &( *pRefPtr )->pNext;
}
PHB_REF_ITEM pRef;
pRef = ( PHB_CYCLIC_REF ) hb_xgrab( sizeof( HB_CYCLIC_REF ) );
pRef->value = NULL;
pRef->nOffset = nIndex;
pRef->iRefs = 0;
pRef->iType = iType;
pRef->pNext = *pRefPtr;
*pRefPtr = pRef;
if( pRefList->nCount >= pRefList->nSize )
{
if( pRefList->nSize == 0 )
pRefList->nSize = HB_SERIAL_REFLSTINIT;
else
pRefList->nSize += pRefList->nSize >> 1;
pRefList->pRefs = ( PHB_REF_ITEM )
hb_xrealloc( pRefList->pRefs,
pRefList->nSize * sizeof( HB_REF_ITEM ) );
}
pRef = &pRefList->pRefs[ nPos ];
if( nPos < pRefList->nCount )
memmove( pRef + 1, pRef, ( pRefList->nCount - nPos ) * sizeof( HB_REF_ITEM ) );
pRefList->nCount++;
pRef->value = NULL;
pRef->nOffset = nIndex;
pRef->iRefs = 0;
pRef->iType = iType;
}
}
/* used by hb_deserializeItem()
for HB_SERIAL_ARRAYREF* and HB_SERIAL_HASHREF* */
static void hb_itemSerialOffsetSet( PHB_CYCLIC_REF pRef, PHB_ITEM pItem,
static void hb_itemSerialOffsetSet( PHB_REF_LIST pRefList, PHB_ITEM pItem,
HB_SIZE nOffset )
{
while( pRef )
{
if( pRef->nOffset == nOffset && pRef->iRefs == 0 )
{
pRef->value = ( void * ) pItem;
break;
}
pRef = pRef->pNext;
}
PHB_REF_ITEM pRef;
HB_SIZE nPos;
if( ( pRef = hb_itemSerialOffsetFind( pRefList, nOffset, 0, &nPos ) ) != NULL )
pRef->value = ( void * ) pItem;
}
/* used by hb_deserializeItem() for HB_SERIAL_REF */
static void hb_itemSerialOffsetGet( PHB_CYCLIC_REF pRef, PHB_ITEM pItem,
static void hb_itemSerialOffsetGet( PHB_REF_LIST pRefList, PHB_ITEM pItem,
HB_SIZE nOffset )
{
while( pRef )
{
if( pRef->nOffset == nOffset && pRef->iRefs == 0 )
{
hb_itemCopy( pItem, ( PHB_ITEM ) pRef->value );
break;
}
pRef = pRef->pNext;
}
PHB_REF_ITEM pRef;
HB_SIZE nPos;
if( ( pRef = hb_itemSerialOffsetFind( pRefList, nOffset, 0, &nPos ) ) != NULL )
hb_itemCopy( pItem, ( PHB_ITEM ) pRef->value );
}
/* used by hb_deserializeItem() for
HB_SERIAL_XHB_A, HB_SERIAL_XHB_H, HB_SERIAL_XHB_Q, HB_SERIAL_XHB_O */
static void hb_itemSerialTypedSet( PHB_CYCLIC_REF pRef, PHB_ITEM pItem, int iType )
static void hb_itemSerialTypedSet( PHB_REF_LIST pRefList, PHB_ITEM pItem, int iType )
{
while( pRef )
HB_SIZE nPos = pRefList->nCount;
while( nPos-- )
{
PHB_REF_ITEM pRef = &pRefList->pRefs[ nPos ];
if( pRef->iType == iType && pRef->value == NULL )
{
if( ( HB_SIZE ) ++pRef->iRefs == pRef->nOffset )
pRef->value = ( void * ) pItem;
}
pRef = pRef->pNext;
}
}
/* used by hb_deserializeItem() for HB_SERIAL_XHB_R */
static void hb_itemSerialTypedGet( PHB_CYCLIC_REF pRef, PHB_ITEM pItem,
static void hb_itemSerialTypedGet( PHB_REF_LIST pRefList, PHB_ITEM pItem,
int iType, HB_SIZE nIndex )
{
while( pRef )
{
if( pRef->iType == iType && pRef->nOffset == nIndex )
{
if( pRef->value )
hb_itemCopy( pItem, ( PHB_ITEM ) pRef->value );
break;
}
pRef = pRef->pNext;
}
}
PHB_REF_ITEM pRef;
HB_SIZE nPos;
/* free reference list after serialization/deserialization process */
static void hb_itemSerialRefFree( PHB_CYCLIC_REF pRef )
{
while( pRef )
if( ( pRef = hb_itemSerialOffsetFind( pRefList, nIndex, iType, &nPos ) ) != NULL )
{
PHB_CYCLIC_REF pFree = pRef;
pRef = pRef->pNext;
hb_xfree( pFree );
if( pRef->value )
hb_itemCopy( pItem, ( PHB_ITEM ) pRef->value );
}
}
static HB_SIZE hb_itemSerialSize( PHB_ITEM pItem, int iFlags,
PHB_CODEPAGE cdpIn, PHB_CODEPAGE cdpOut,
PHB_CYCLIC_REF * pRefPtr, HB_SIZE nOffset )
PHB_REF_LIST pRefList, HB_SIZE nOffset )
{
HB_SIZE nSize, nLen, u;
HB_MAXINT lVal;
@@ -470,7 +588,8 @@ static HB_SIZE hb_itemSerialSize( PHB_ITEM pItem, int iFlags,
if( szClass && szFunc )
nSize += strlen( szClass ) + strlen( szFunc ) + 3;
}
if( hb_itemSerialValueRef( pRefPtr, hb_arrayId( pItem ), nOffset + nSize ) )
if( ( iFlags & HB_SERIALIZE_IGNOREREF ) == 0 &&
hb_itemSerialValueRef( pRefList, hb_arrayId( pItem ), nOffset + nSize ) )
{
nSize = 5;
}
@@ -485,12 +604,13 @@ static HB_SIZE hb_itemSerialSize( PHB_ITEM pItem, int iFlags,
nSize += 5;
for( u = 1; u <= nLen; u++ )
nSize += hb_itemSerialSize( hb_arrayGetItemPtr( pItem, u ), iFlags,
cdpIn, cdpOut, pRefPtr, nOffset + nSize );
cdpIn, cdpOut, pRefList, nOffset + nSize );
}
break;
case HB_IT_HASH:
if( hb_itemSerialValueRef( pRefPtr, hb_hashId( pItem ), nOffset ) )
if( ( iFlags & HB_SERIALIZE_IGNOREREF ) == 0 &&
hb_itemSerialValueRef( pRefList, hb_hashId( pItem ), nOffset ) )
{
nSize = 5;
}
@@ -505,7 +625,7 @@ static HB_SIZE hb_itemSerialSize( PHB_ITEM pItem, int iFlags,
{
nSize++;
nSize += hb_itemSerialSize( pDefVal, iFlags,
cdpIn, cdpOut, pRefPtr, nOffset + nSize );
cdpIn, cdpOut, pRefList, nOffset + nSize );
}
nLen = hb_hashLen( pItem );
if( nLen <= 255 )
@@ -517,9 +637,9 @@ static HB_SIZE hb_itemSerialSize( PHB_ITEM pItem, int iFlags,
for( u = 1; u <= nLen; u++ )
{
nSize += hb_itemSerialSize( hb_hashGetKeyAt( pItem, u ), iFlags,
cdpIn, cdpOut, pRefPtr, nOffset + nSize );
cdpIn, cdpOut, pRefList, nOffset + nSize );
nSize += hb_itemSerialSize( hb_hashGetValueAt( pItem, u ), iFlags,
cdpIn, cdpOut, pRefPtr, nOffset + nSize );
cdpIn, cdpOut, pRefList, nOffset + nSize );
}
}
break;
@@ -535,7 +655,7 @@ static HB_SIZE hb_itemSerialSize( PHB_ITEM pItem, int iFlags,
static HB_SIZE hb_serializeItem( PHB_ITEM pItem, HB_BOOL iFlags,
PHB_CODEPAGE cdpIn, PHB_CODEPAGE cdpOut,
HB_UCHAR * pBuffer, HB_SIZE nOffset,
PHB_CYCLIC_REF pRef )
PHB_REF_LIST pRefList )
{
HB_MAXINT lVal;
double d;
@@ -756,7 +876,7 @@ static HB_SIZE hb_serializeItem( PHB_ITEM pItem, HB_BOOL iFlags,
break;
case HB_IT_ARRAY:
if( hb_itemSerialValueOffset( pRef, hb_arrayId( pItem ), nOffset, &nRef ) )
if( hb_itemSerialValueOffset( pRefList, hb_arrayId( pItem ), nOffset, &nRef ) )
{
pBuffer[ nOffset++ ] = HB_SERIAL_REF;
HB_PUT_LE_UINT32( &pBuffer[ nOffset ], nRef );
@@ -803,12 +923,12 @@ static HB_SIZE hb_serializeItem( PHB_ITEM pItem, HB_BOOL iFlags,
}
for( n = 1; n <= nLen; n++ )
nOffset = hb_serializeItem( hb_arrayGetItemPtr( pItem, n ), iFlags,
cdpIn, cdpOut, pBuffer, nOffset, pRef );
cdpIn, cdpOut, pBuffer, nOffset, pRefList );
}
break;
case HB_IT_HASH:
if( hb_itemSerialValueOffset( pRef, hb_hashId( pItem ), nOffset, &nRef ) )
if( hb_itemSerialValueOffset( pRefList, hb_hashId( pItem ), nOffset, &nRef ) )
{
pBuffer[ nOffset++ ] = HB_SERIAL_REF;
HB_PUT_LE_UINT32( &pBuffer[ nOffset ], nRef );
@@ -829,7 +949,7 @@ static HB_SIZE hb_serializeItem( PHB_ITEM pItem, HB_BOOL iFlags,
{
pBuffer[ nOffset++ ] = HB_SERIAL_HASHDEFVAL;
nOffset = hb_serializeItem( pDefVal, iHashFlags,
cdpIn, cdpOut, pBuffer, nOffset, pRef );
cdpIn, cdpOut, pBuffer, nOffset, pRefList );
}
nLen = hb_hashLen( pItem );
if( nLen <= 255 )
@@ -855,9 +975,9 @@ static HB_SIZE hb_serializeItem( PHB_ITEM pItem, HB_BOOL iFlags,
for( n = 1; n <= nLen; n++ )
{
nOffset = hb_serializeItem( hb_hashGetKeyAt( pItem, n ), iFlags,
cdpIn, cdpOut, pBuffer, nOffset, pRef );
cdpIn, cdpOut, pBuffer, nOffset, pRefList );
nOffset = hb_serializeItem( hb_hashGetValueAt( pItem, n ), iFlags,
cdpIn, cdpOut, pBuffer, nOffset, pRef );
cdpIn, cdpOut, pBuffer, nOffset, pRefList );
}
}
break;
@@ -872,7 +992,7 @@ static HB_SIZE hb_serializeItem( PHB_ITEM pItem, HB_BOOL iFlags,
}
static HB_BOOL hb_deserializeTest( const HB_UCHAR ** pBufferPtr, HB_SIZE * pnSize,
HB_SIZE nOffset, PHB_CYCLIC_REF * pRefPtr )
HB_SIZE nOffset, PHB_REF_LIST pRefList )
{
const HB_UCHAR * pBuffer = *pBufferPtr;
HB_SIZE nSize = *pnSize, nLen = 0;
@@ -939,7 +1059,7 @@ static HB_BOOL hb_deserializeTest( const HB_UCHAR ** pBufferPtr, HB_SIZE * pnSiz
nSize = 9 + ( nSize >= 9 ? HB_GET_LE_UINT32( pBuffer ) : nSize );
break;
case HB_SERIAL_ARRAYREF8:
if( hb_itemSerialOffsetRef( pRefPtr, nOffset ) )
if( hb_itemSerialOffsetRef( pRefList, nOffset ) )
return HB_FALSE;
case HB_SERIAL_ARRAY8:
if( nSize >= 2 )
@@ -951,7 +1071,7 @@ static HB_BOOL hb_deserializeTest( const HB_UCHAR ** pBufferPtr, HB_SIZE * pnSiz
nSize++;
break;
case HB_SERIAL_ARRAYREF16:
if( hb_itemSerialOffsetRef( pRefPtr, nOffset ) )
if( hb_itemSerialOffsetRef( pRefList, nOffset ) )
return HB_FALSE;
case HB_SERIAL_ARRAY16:
if( nSize >= 3 )
@@ -963,7 +1083,7 @@ static HB_BOOL hb_deserializeTest( const HB_UCHAR ** pBufferPtr, HB_SIZE * pnSiz
nSize++;
break;
case HB_SERIAL_ARRAYREF32:
if( hb_itemSerialOffsetRef( pRefPtr, nOffset ) )
if( hb_itemSerialOffsetRef( pRefList, nOffset ) )
return HB_FALSE;
case HB_SERIAL_ARRAY32:
if( nSize >= 5 )
@@ -975,7 +1095,7 @@ static HB_BOOL hb_deserializeTest( const HB_UCHAR ** pBufferPtr, HB_SIZE * pnSiz
nSize++;
break;
case HB_SERIAL_HASHREF8:
if( hb_itemSerialOffsetRef( pRefPtr, nOffset ) )
if( hb_itemSerialOffsetRef( pRefList, nOffset ) )
return HB_FALSE;
case HB_SERIAL_HASH8:
if( nSize >= 2 )
@@ -987,7 +1107,7 @@ static HB_BOOL hb_deserializeTest( const HB_UCHAR ** pBufferPtr, HB_SIZE * pnSiz
nSize++;
break;
case HB_SERIAL_HASHREF16:
if( hb_itemSerialOffsetRef( pRefPtr, nOffset ) )
if( hb_itemSerialOffsetRef( pRefList, nOffset ) )
return HB_FALSE;
case HB_SERIAL_HASH16:
if( nSize >= 3 )
@@ -999,7 +1119,7 @@ static HB_BOOL hb_deserializeTest( const HB_UCHAR ** pBufferPtr, HB_SIZE * pnSiz
nSize++;
break;
case HB_SERIAL_HASHREF32:
if( hb_itemSerialOffsetRef( pRefPtr, nOffset ) )
if( hb_itemSerialOffsetRef( pRefList, nOffset ) )
return HB_FALSE;
case HB_SERIAL_HASH32:
if( nSize >= 5 )
@@ -1011,7 +1131,7 @@ static HB_BOOL hb_deserializeTest( const HB_UCHAR ** pBufferPtr, HB_SIZE * pnSiz
nSize++;
break;
case HB_SERIAL_REF:
if( ! hb_itemSerialOffsetRef( pRefPtr, HB_GET_LE_UINT32( pBuffer ) ) )
if( ! hb_itemSerialOffsetRef( pRefList, HB_GET_LE_UINT32( pBuffer ) ) )
return HB_FALSE;
nSize = 5;
break;
@@ -1115,7 +1235,7 @@ static HB_BOOL hb_deserializeTest( const HB_UCHAR ** pBufferPtr, HB_SIZE * pnSiz
case HB_SERIAL_XHB_A:
case HB_SERIAL_XHB_H:
case HB_SERIAL_XHB_O:
hb_itemSerialTypedRef( pRefPtr, pBuffer[ 0 ],
hb_itemSerialTypedRef( pRefList, pBuffer[ 0 ],
( HB_SIZE ) HB_GET_BE_UINT64( &pBuffer[ 1 ] ) );
case HB_SERIAL_XHB_B:
nSize = 10;
@@ -1139,7 +1259,7 @@ static HB_BOOL hb_deserializeTest( const HB_UCHAR ** pBufferPtr, HB_SIZE * pnSiz
{
nOffset += nSize;
nSize = *pnSize;
if( ! hb_deserializeTest( pBufferPtr, pnSize, nOffset, pRefPtr ) )
if( ! hb_deserializeTest( pBufferPtr, pnSize, nOffset, pRefList ) )
return HB_FALSE;
nSize -= *pnSize;
--nLen;
@@ -1151,11 +1271,9 @@ static HB_BOOL hb_deserializeTest( const HB_UCHAR ** pBufferPtr, HB_SIZE * pnSiz
static HB_SIZE hb_deserializeHash( PHB_ITEM pItem,
PHB_CODEPAGE cdpIn, PHB_CODEPAGE cdpOut,
const HB_UCHAR * pBuffer, HB_SIZE nOffset,
HB_SIZE nLen, PHB_CYCLIC_REF pRef, int iType )
HB_SIZE nLen, PHB_REF_LIST pRefList )
{
hb_hashNew( pItem );
if( iType != 0 )
hb_itemSerialTypedSet( pRef, pItem, iType );
if( nLen )
{
@@ -1166,8 +1284,8 @@ static HB_SIZE hb_deserializeHash( PHB_ITEM pItem,
hb_hashPreallocate( pItem, nLen );
while( nLen-- )
{
nOffset = hb_deserializeItem( pKey, cdpIn, cdpOut, pBuffer, nOffset, pRef );
nOffset = hb_deserializeItem( pVal, cdpIn, cdpOut, pBuffer, nOffset, pRef );
nOffset = hb_deserializeItem( pKey, cdpIn, cdpOut, pBuffer, nOffset, pRefList );
nOffset = hb_deserializeItem( pVal, cdpIn, cdpOut, pBuffer, nOffset, pRefList );
hb_hashAdd( pItem, pKey, pVal );
}
hb_itemRelease( pKey );
@@ -1181,8 +1299,8 @@ static HB_SIZE hb_deserializeHash( PHB_ITEM pItem,
{
if( hb_hashAllocNewPair( pItem, &pKey, &pVal ) )
{
nOffset = hb_deserializeItem( pKey, cdpIn, cdpOut, pBuffer, nOffset, pRef );
nOffset = hb_deserializeItem( pVal, cdpIn, cdpOut, pBuffer, nOffset, pRef );
nOffset = hb_deserializeItem( pKey, cdpIn, cdpOut, pBuffer, nOffset, pRefList );
nOffset = hb_deserializeItem( pVal, cdpIn, cdpOut, pBuffer, nOffset, pRefList );
}
}
#endif
@@ -1194,16 +1312,15 @@ static HB_SIZE hb_deserializeHash( PHB_ITEM pItem,
static HB_SIZE hb_deserializeArray( PHB_ITEM pItem,
PHB_CODEPAGE cdpIn, PHB_CODEPAGE cdpOut,
const HB_UCHAR * pBuffer, HB_SIZE nOffset,
HB_SIZE nLen, PHB_CYCLIC_REF pRef, int iType )
HB_SIZE nLen, PHB_REF_LIST pRefList )
{
HB_SIZE u;
hb_arrayNew( pItem, nLen );
if( iType != 0 )
hb_itemSerialTypedSet( pRef, pItem, iType );
for( u = 1; u <= nLen; u++ )
nOffset = hb_deserializeItem( hb_arrayGetItemPtr( pItem, u ),
cdpIn, cdpOut, pBuffer, nOffset, pRef );
cdpIn, cdpOut, pBuffer, nOffset, pRefList );
return nOffset;
}
@@ -1211,7 +1328,7 @@ static HB_SIZE hb_deserializeArray( PHB_ITEM pItem,
static HB_SIZE hb_deserializeItem( PHB_ITEM pItem,
PHB_CODEPAGE cdpIn, PHB_CODEPAGE cdpOut,
const HB_UCHAR * pBuffer, HB_SIZE nOffset,
PHB_CYCLIC_REF pRef )
PHB_REF_LIST pRefList )
{
HB_SIZE nLen, nPad, nSize;
char * szVal;
@@ -1386,45 +1503,45 @@ static HB_SIZE hb_deserializeItem( PHB_ITEM pItem,
break;
case HB_SERIAL_ARRAYREF8:
hb_itemSerialOffsetSet( pRef, pItem, nOffset - 1 );
hb_itemSerialOffsetSet( pRefList, pItem, nOffset - 1 );
case HB_SERIAL_ARRAY8:
nLen = pBuffer[ nOffset++ ];
nOffset = hb_deserializeArray( pItem, cdpIn, cdpOut, pBuffer, nOffset, nLen, pRef, 0 );
nOffset = hb_deserializeArray( pItem, cdpIn, cdpOut, pBuffer, nOffset, nLen, pRefList );
break;
case HB_SERIAL_ARRAYREF16:
hb_itemSerialOffsetSet( pRef, pItem, nOffset - 1 );
hb_itemSerialOffsetSet( pRefList, pItem, nOffset - 1 );
case HB_SERIAL_ARRAY16:
nLen = HB_GET_LE_UINT16( &pBuffer[ nOffset ] );
nOffset = hb_deserializeArray( pItem, cdpIn, cdpOut, pBuffer, nOffset + 2, nLen, pRef, 0 );
nOffset = hb_deserializeArray( pItem, cdpIn, cdpOut, pBuffer, nOffset + 2, nLen, pRefList );
break;
case HB_SERIAL_ARRAYREF32:
hb_itemSerialOffsetSet( pRef, pItem, nOffset - 1 );
hb_itemSerialOffsetSet( pRefList, pItem, nOffset - 1 );
case HB_SERIAL_ARRAY32:
nLen = HB_GET_LE_UINT32( &pBuffer[ nOffset ] );
nOffset = hb_deserializeArray( pItem, cdpIn, cdpOut, pBuffer, nOffset + 4, nLen, pRef, 0 );
nOffset = hb_deserializeArray( pItem, cdpIn, cdpOut, pBuffer, nOffset + 4, nLen, pRefList );
break;
case HB_SERIAL_HASHREF8:
hb_itemSerialOffsetSet( pRef, pItem, nOffset - 1 );
hb_itemSerialOffsetSet( pRefList, pItem, nOffset - 1 );
case HB_SERIAL_HASH8:
nLen = pBuffer[ nOffset++ ];
nOffset = hb_deserializeHash( pItem, cdpIn, cdpOut, pBuffer, nOffset, nLen, pRef, 0 );
nOffset = hb_deserializeHash( pItem, cdpIn, cdpOut, pBuffer, nOffset, nLen, pRefList );
break;
case HB_SERIAL_HASHREF16:
hb_itemSerialOffsetSet( pRef, pItem, nOffset - 1 );
hb_itemSerialOffsetSet( pRefList, pItem, nOffset - 1 );
case HB_SERIAL_HASH16:
nLen = HB_GET_LE_UINT16( &pBuffer[ nOffset ] );
nOffset = hb_deserializeHash( pItem, cdpIn, cdpOut, pBuffer, nOffset + 2, nLen, pRef, 0 );
nOffset = hb_deserializeHash( pItem, cdpIn, cdpOut, pBuffer, nOffset + 2, nLen, pRefList );
break;
case HB_SERIAL_HASHREF32:
hb_itemSerialOffsetSet( pRef, pItem, nOffset - 1 );
hb_itemSerialOffsetSet( pRefList, pItem, nOffset - 1 );
case HB_SERIAL_HASH32:
nLen = HB_GET_LE_UINT32( &pBuffer[ nOffset ] );
nOffset = hb_deserializeHash( pItem, cdpIn, cdpOut, pBuffer, nOffset + 4, nLen, pRef, 0 );
nOffset = hb_deserializeHash( pItem, cdpIn, cdpOut, pBuffer, nOffset + 4, nLen, pRefList );
break;
case HB_SERIAL_REF:
hb_itemSerialOffsetGet( pRef, pItem,
hb_itemSerialOffsetGet( pRefList, pItem,
HB_GET_LE_UINT32( &pBuffer[ nOffset ] ) );
nOffset += 4;
break;
@@ -1436,7 +1553,7 @@ static HB_SIZE hb_deserializeItem( PHB_ITEM pItem,
nLen = strlen( szClass );
szFunc = szClass + nLen + 1;
nOffset = hb_deserializeItem( pItem, cdpIn, cdpOut, pBuffer,
nOffset + nLen + strlen( szFunc ) + 2, pRef );
nOffset + nLen + strlen( szFunc ) + 2, pRefList );
hb_objSetClass( pItem, szClass, szFunc );
break;
}
@@ -1445,7 +1562,7 @@ static HB_SIZE hb_deserializeItem( PHB_ITEM pItem,
{
int iHashFlags = HB_GET_LE_UINT16( &pBuffer[ nOffset ] );
nOffset = hb_deserializeItem( pItem, cdpIn, cdpOut, pBuffer,
nOffset + 2, pRef );
nOffset + 2, pRefList );
hb_hashClearFlags( pItem, HB_HASH_FLAG_MASK );
if( ( iHashFlags & ( HB_HASH_KEEPORDER | HB_HASH_BINARY ) ) != HB_HASH_BINARY )
iHashFlags |= HB_HASH_RESORT;
@@ -1457,9 +1574,9 @@ static HB_SIZE hb_deserializeItem( PHB_ITEM pItem,
{
PHB_ITEM pDefVal = hb_itemNew( NULL );
nOffset = hb_deserializeItem( pDefVal, cdpIn, cdpOut, pBuffer,
nOffset, pRef );
nOffset, pRefList );
nOffset = hb_deserializeItem( pItem, cdpIn, cdpOut, pBuffer,
nOffset, pRef );
nOffset, pRefList );
hb_hashSetDefault( pItem, pDefVal );
hb_itemRelease( pDefVal );
break;
@@ -1476,13 +1593,15 @@ static HB_SIZE hb_deserializeItem( PHB_ITEM pItem,
{
case HB_ZLIB_RES_OK:
{
PHB_CYCLIC_REF pRefZ = NULL;
HB_REF_LIST refListZ;
hb_itemSerialRefListInit( &refListZ );
pBuffer = ( const HB_UCHAR * ) szVal;
if( hb_deserializeTest( &pBuffer, &nLen, 0, &pRefZ ) )
hb_deserializeItem( pItem, cdpIn, cdpOut, ( const HB_UCHAR * ) szVal, 0, pRefZ );
if( hb_deserializeTest( &pBuffer, &nLen, 0, &refListZ ) )
hb_deserializeItem( pItem, cdpIn, cdpOut, ( const HB_UCHAR * ) szVal, 0, &refListZ );
else
hb_itemClear( pItem );
hb_itemSerialRefFree( pRefZ );
hb_itemSerialRefListFree( &refListZ );
break;
}
case HB_ZLIB_RES_UNSUPPORTED:
@@ -1551,20 +1670,20 @@ static HB_SIZE hb_deserializeItem( PHB_ITEM pItem,
break;
case HB_SERIAL_XHB_A:
nLen = ( HB_SIZE ) HB_GET_BE_UINT64( &pBuffer[ nOffset ] );
nOffset = hb_deserializeArray( pItem, cdpIn, cdpOut, pBuffer,
nOffset + 8, nLen, pRef, HB_SERIAL_XHB_A );
hb_itemSerialTypedSet( pRefList, pItem, HB_SERIAL_XHB_A );
nOffset = hb_deserializeArray( pItem, cdpIn, cdpOut, pBuffer, nOffset + 8, nLen, pRefList );
break;
case HB_SERIAL_XHB_B:
nOffset = hb_deserializeItem( pItem, cdpIn, cdpOut, pBuffer,
nOffset, pRef );
nOffset, pRefList );
/* we do not support codeblock deserialization: HB_RestoreBlock( pItem ) */
/* hb_itemSerialTypedSet( pRef, pItem, HB_SERIAL_XHB_O ); */
/* hb_itemSerialTypedSet( pRefList, pItem, HB_SERIAL_XHB_B ); */
hb_itemClear( pItem );
break;
case HB_SERIAL_XHB_H:
nLen = ( HB_SIZE ) HB_GET_BE_UINT64( &pBuffer[ nOffset ] );
nOffset = hb_deserializeHash( pItem, cdpIn, cdpOut, pBuffer,
nOffset + 8, nLen, pRef, HB_SERIAL_XHB_H );
hb_itemSerialTypedSet( pRefList, pItem, HB_SERIAL_XHB_H );
nOffset = hb_deserializeHash( pItem, cdpIn, cdpOut, pBuffer, nOffset + 8, nLen, pRefList );
hb_hashSetFlags( pItem, HB_HASH_KEEPORDER | HB_HASH_RESORT );
break;
case HB_SERIAL_XHB_O:
@@ -1574,7 +1693,7 @@ static HB_SIZE hb_deserializeItem( PHB_ITEM pItem,
nLen = ( HB_SIZE ) HB_GET_BE_UINT64( &pBuffer[ nOffset ] );
/* deserialize :className */
nOffset = hb_deserializeItem( pItem, cdpIn, cdpOut, pBuffer,
nOffset + 8, pRef );
nOffset + 8, pRefList );
/* find class handle */
uiClass = hb_clsFindClass( hb_itemGetCPtr( pItem ), NULL );
if( uiClass && hb_vmRequestReenter() )
@@ -1584,14 +1703,14 @@ static HB_SIZE hb_deserializeItem( PHB_ITEM pItem,
hb_clsAssociate( uiClass );
hb_itemMove( pItem, hb_stackReturnItem() );
hb_itemSerialTypedSet( pRef, pItem, HB_SERIAL_XHB_O );
hb_itemSerialTypedSet( pRefList, pItem, HB_SERIAL_XHB_O );
while( nLen-- )
{
nOffset = hb_deserializeItem( pMsg, cdpIn, cdpOut, pBuffer,
nOffset, pRef );
nOffset, pRefList );
nOffset = hb_deserializeItem( pVal, cdpIn, cdpOut, pBuffer,
nOffset, pRef );
nOffset, pRefList );
if( hb_vmRequestQuery() == 0 )
{
char szMsg[ HB_SYMBOL_NAME_LEN ];
@@ -1605,13 +1724,13 @@ static HB_SIZE hb_deserializeItem( PHB_ITEM pItem,
}
else
{
hb_itemSerialTypedSet( pRef, pItem, HB_SERIAL_XHB_O );
hb_itemSerialTypedSet( pRefList, pItem, HB_SERIAL_XHB_O );
while( nLen-- )
{
nOffset = hb_deserializeItem( pItem, cdpIn, cdpOut, pBuffer,
nOffset, pRef );
nOffset, pRefList );
nOffset = hb_deserializeItem( pItem, cdpIn, cdpOut, pBuffer,
nOffset, pRef );
nOffset, pRefList );
}
hb_itemClear( pItem );
}
@@ -1624,7 +1743,7 @@ static HB_SIZE hb_deserializeItem( PHB_ITEM pItem,
nPad = ( HB_SIZE ) HB_GET_BE_UINT64( &pBuffer[ nOffset ] ) + nOffset + 8;
/* deserialize :className */
nOffset = hb_deserializeItem( pItem, cdpIn, cdpOut, pBuffer,
nOffset + 8, pRef );
nOffset + 8, pRefList );
nLen = nPad - nOffset;
/* get serialized HBPERSISTENT text */
szVal = hb_cdpnDup( ( const char * ) &pBuffer[ nOffset ], &nLen,
@@ -1646,11 +1765,11 @@ static HB_SIZE hb_deserializeItem( PHB_ITEM pItem,
}
else
hb_itemClear( pItem );
hb_itemSerialTypedSet( pRef, pItem, HB_SERIAL_XHB_O );
hb_itemSerialTypedSet( pRefList, pItem, HB_SERIAL_XHB_O );
break;
}
case HB_SERIAL_XHB_R:
hb_itemSerialTypedGet( pRef, pItem, pBuffer[ nOffset ],
hb_itemSerialTypedGet( pRefList, pItem, pBuffer[ nOffset ],
( HB_SIZE ) HB_GET_BE_UINT64( &pBuffer[ nOffset + 1 ] ) );
nOffset += 9;
break;
@@ -1670,13 +1789,16 @@ char * hb_itemSerializeCP( PHB_ITEM pItem, int iFlags,
PHB_CODEPAGE cdpIn, PHB_CODEPAGE cdpOut,
HB_SIZE * pnSize )
{
PHB_CYCLIC_REF pRef = NULL;
HB_SIZE nSize = hb_itemSerialSize( pItem, iFlags, cdpIn, cdpOut, &pRef, 0 );
HB_UCHAR * pBuffer = ( HB_UCHAR * ) hb_xgrab( nSize + 1 );
HB_REF_LIST refList;
HB_UCHAR * pBuffer;
HB_SIZE nSize;
hb_itemSerialUnRefFree( &pRef );
hb_serializeItem( pItem, iFlags, cdpIn, cdpOut, pBuffer, 0, pRef );
hb_itemSerialRefFree( pRef );
hb_itemSerialRefListInit( &refList );
nSize = hb_itemSerialSize( pItem, iFlags, cdpIn, cdpOut, &refList, 0 );
pBuffer = ( HB_UCHAR * ) hb_xgrab( nSize + 1 );
hb_itemSerialUnusedFree( &refList );
hb_serializeItem( pItem, iFlags, cdpIn, cdpOut, pBuffer, 0, &refList );
hb_itemSerialRefListFree( &refList );
if( ( iFlags & HB_SERIALIZE_COMPRESS ) != 0 && nSize > 20 )
{
@@ -1713,16 +1835,17 @@ char * hb_itemSerialize( PHB_ITEM pItem, int iFlags, HB_SIZE *pnSize )
PHB_ITEM hb_itemDeserializeCP( const char ** pBufferPtr, HB_SIZE * pnSize,
PHB_CODEPAGE cdpIn, PHB_CODEPAGE cdpOut )
{
PHB_CYCLIC_REF pRef = NULL;
const HB_UCHAR * pBuffer = ( const HB_UCHAR * ) *pBufferPtr;
PHB_ITEM pItem = NULL;
HB_REF_LIST refList;
if( ! pnSize || hb_deserializeTest( ( const HB_UCHAR ** ) pBufferPtr, pnSize, 0, &pRef ) )
hb_itemSerialRefListInit( &refList );
if( ! pnSize || hb_deserializeTest( ( const HB_UCHAR ** ) pBufferPtr, pnSize, 0, &refList ) )
{
pItem = hb_itemNew( NULL );
hb_deserializeItem( pItem, cdpIn, cdpOut, pBuffer, 0, pRef );
hb_deserializeItem( pItem, cdpIn, cdpOut, pBuffer, 0, &refList );
}
hb_itemSerialRefFree( pRef );
hb_itemSerialRefListFree( &refList );
return pItem;
}

View File

@@ -1467,112 +1467,117 @@ HB_BOOL hb_arrayCopy( PHB_ITEM pSrcArray, PHB_ITEM pDstArray, HB_SIZE * pnStart,
return HB_FALSE;
}
static void hb_arrayCloneBody( PHB_BASEARRAY pSrcBaseArray, PHB_BASEARRAY pDstBaseArray, PHB_NESTED_CLONED pClonedList )
static void hb_arrayCloneBody( PHB_ITEM pDest, PHB_ITEM pArray, PHB_NESTED_CLONED pClonedList )
{
PHB_ITEM pSrcItem, pDstItem;
HB_SIZE nLen;
HB_TRACE( HB_TR_DEBUG, ( "hb_arrayCloneBody(%p, %p, %p)", pSrcBaseArray, pDstBaseArray, pClonedList ) );
HB_TRACE( HB_TR_DEBUG, ( "hb_arrayCloneBody(%p, %p, %p)", pDest, pArray, pClonedList ) );
pSrcItem = pSrcBaseArray->pItems;
pDstItem = pDstBaseArray->pItems;
nLen = pArray->item.asArray.value->nLen;
hb_arrayNew( pDest, nLen );
pDest->item.asArray.value->uiClass = pArray->item.asArray.value->uiClass;
pSrcItem = pArray->item.asArray.value->pItems;
pDstItem = pDest->item.asArray.value->pItems;
pDstBaseArray->uiClass = pSrcBaseArray->uiClass;
for( nLen = pSrcBaseArray->nLen; nLen; --nLen, ++pSrcItem, ++pDstItem )
hb_cloneNested( pDstItem, pSrcItem, pClonedList );
while( nLen-- )
hb_nestedCloneDo( pDstItem++, pSrcItem++, pClonedList );
}
void hb_cloneNested( PHB_ITEM pDstItem, PHB_ITEM pSrcItem, PHB_NESTED_CLONED pClonedList )
void hb_nestedCloneInit( PHB_NESTED_CLONED pClonedList, void * pValue, PHB_ITEM pDest )
{
pClonedList->nSize = 16;
pClonedList->nCount = 1;
pClonedList->pRefs = ( PHB_NESTED_REF )
hb_xgrab( pClonedList->nSize * sizeof( HB_NESTED_REF ) );
pClonedList->pRefs[ 0 ].value = pValue;
pClonedList->pRefs[ 0 ].pDest = pDest;
}
void hb_nestedCloneFree( PHB_NESTED_CLONED pClonedList )
{
hb_xfree( pClonedList->pRefs );
}
static HB_BOOL hb_nestedCloneFind( PHB_NESTED_CLONED pClonedList, void * pValue, PHB_ITEM pDest )
{
HB_SIZE nFirst, nLast, nMiddle;
PHB_NESTED_REF pRef;
nFirst = 0;
nLast = pClonedList->nCount;
nMiddle = ( nFirst + nLast ) >> 1;
pRef = pClonedList->pRefs;
while( nFirst < nLast )
{
if( ( HB_PTRUINT ) pRef[ nMiddle ].value < ( HB_PTRUINT ) pValue )
nFirst = nMiddle + 1;
else if( ( HB_PTRUINT ) pRef[ nMiddle ].value > ( HB_PTRUINT ) pValue )
nLast = nMiddle;
else
{
hb_itemCopy( pDest, pRef[ nMiddle ].pDest );
return HB_TRUE;
}
nMiddle = ( nFirst + nLast ) >> 1;
}
if( pClonedList->nCount >= pClonedList->nSize )
{
pClonedList->nSize += pClonedList->nSize >> 1;
pClonedList->pRefs = ( PHB_NESTED_REF )
hb_xrealloc( pClonedList->pRefs,
pClonedList->nSize * sizeof( HB_NESTED_REF ) );
}
pRef = &pClonedList->pRefs[ nMiddle ];
if( nMiddle < pClonedList->nCount )
memmove( pRef + 1, pRef,
( pClonedList->nCount - nMiddle ) * sizeof( HB_NESTED_REF ) );
pClonedList->nCount++;
pRef->value = pValue;
pRef->pDest = pDest;
return HB_FALSE;
}
void hb_nestedCloneDo( PHB_ITEM pDstItem, PHB_ITEM pSrcItem, PHB_NESTED_CLONED pClonedList )
{
/* Clipper clones nested array ONLY if NOT an Object!!! */
if( HB_IS_ARRAY( pSrcItem ) )
{
PHB_NESTED_CLONED pCloned = pClonedList;
PHB_BASEARRAY pBaseArray = pSrcItem->item.asArray.value;
do
if( ! hb_nestedCloneFind( pClonedList, ( void * ) pSrcItem->item.asArray.value, pDstItem ) )
{
if( pCloned->value == ( void * ) pBaseArray )
break;
pCloned = pCloned->pNext;
}
while( pCloned );
if( pCloned )
hb_itemCopy( pDstItem, pCloned->pDest );
else if( pSrcItem->item.asArray.value->uiClass != 0 )
hb_objCloneTo( pDstItem, pSrcItem, pClonedList );
else
{
hb_arrayNew( pDstItem, pBaseArray->nLen );
pCloned = ( PHB_NESTED_CLONED ) hb_xgrab( sizeof( HB_NESTED_CLONED ) );
pCloned->value = ( void * ) pBaseArray;
pCloned->pDest = pDstItem;
pCloned->pNext = pClonedList->pNext;
pClonedList->pNext = pCloned;
hb_arrayCloneBody( pBaseArray, pDstItem->item.asArray.value, pClonedList );
if( pSrcItem->item.asArray.value->uiClass != 0 )
hb_objCloneBody( pDstItem, pSrcItem, pClonedList );
else
hb_arrayCloneBody( pDstItem, pSrcItem, pClonedList );
}
}
else if( HB_IS_HASH( pSrcItem ) )
{
PHB_NESTED_CLONED pCloned = pClonedList;
PHB_BASEHASH pBaseHash = pSrcItem->item.asHash.value;
do
{
if( pCloned->value == ( void * ) pBaseHash )
break;
pCloned = pCloned->pNext;
}
while( pCloned );
if( pCloned )
hb_itemCopy( pDstItem, pCloned->pDest );
else
{
pCloned = ( PHB_NESTED_CLONED ) hb_xgrab( sizeof( HB_NESTED_CLONED ) );
pCloned->value = ( void * ) pBaseHash;
pCloned->pDest = pDstItem;
pCloned->pNext = pClonedList->pNext;
pClonedList->pNext = pCloned;
hb_hashCloneBody( pSrcItem, pDstItem, pClonedList );
}
if( ! hb_nestedCloneFind( pClonedList, ( void * ) pSrcItem->item.asHash.value, pDstItem ) )
hb_hashCloneBody( pDstItem, pSrcItem, pClonedList );
}
else
hb_itemCopy( pDstItem, pSrcItem );
}
PHB_ITEM hb_arrayCloneTo( PHB_ITEM pDstArray, PHB_ITEM pSrcArray )
PHB_ITEM hb_arrayCloneTo( PHB_ITEM pDest, PHB_ITEM pArray )
{
HB_TRACE( HB_TR_DEBUG, ( "hb_arrayCloneTo(%p,%p)", pDstArray, pSrcArray ) );
HB_TRACE( HB_TR_DEBUG, ( "hb_arrayCloneTo(%p,%p)", pDest, pArray ) );
if( HB_IS_ARRAY( pSrcArray ) )
if( HB_IS_ARRAY( pArray ) )
{
PHB_NESTED_CLONED pClonedList, pCloned;
PHB_BASEARRAY pSrcBaseArray = pSrcArray->item.asArray.value;
HB_SIZE nSrcLen = pSrcBaseArray->nLen;
HB_NESTED_CLONED clonedList;
hb_arrayNew( pDstArray, nSrcLen );
pClonedList = ( PHB_NESTED_CLONED ) hb_xgrab( sizeof( HB_NESTED_CLONED ) );
pClonedList->value = ( void * ) pSrcBaseArray;
pClonedList->pDest = pDstArray;
pClonedList->pNext = NULL;
hb_arrayCloneBody( pSrcBaseArray, pDstArray->item.asArray.value, pClonedList );
do
{
pCloned = pClonedList;
pClonedList = pClonedList->pNext;
hb_xfree( pCloned );
}
while( pClonedList );
hb_nestedCloneInit( &clonedList, ( void * ) pArray->item.asArray.value, pDest );
hb_arrayCloneBody( pDest, pArray, &clonedList );
hb_nestedCloneFree( &clonedList );
}
return pDstArray;
return pDest;
}
PHB_ITEM hb_arrayClone( PHB_ITEM pArray )

View File

@@ -2689,15 +2689,25 @@ static PHB_SYMB hb_objGetFuncSym( PHB_ITEM pItem )
}
/* clone object if user defined clone method or copy it */
void hb_objCloneTo( PHB_ITEM pDest, PHB_ITEM pSource, PHB_NESTED_CLONED pClonedList )
void hb_objCloneBody( PHB_ITEM pDest, PHB_ITEM pObject, PHB_NESTED_CLONED pClonedList )
{
HB_TRACE( HB_TR_DEBUG, ( "hb_objCloneTo(%p,%p,%p)", pDest, pSource, pClonedList ) );
HB_TRACE( HB_TR_DEBUG, ( "hb_objCloneBody(%p,%p,%p)", pDest, pObject, pClonedList ) );
HB_SYMBOL_UNUSED( pClonedList );
/* TODO: add support for user defined clone operation */
hb_itemCopy( pDest, pSource );
hb_itemCopy( pDest, pObject );
}
/* clone object if user defined clone method or copy it */
PHB_ITEM hb_objCloneTo( PHB_ITEM pDest, PHB_ITEM pObject )
{
HB_TRACE( HB_TR_DEBUG, ( "hb_objCloneTo(%p,%p)", pDest, pObject ) );
hb_objCloneBody( pDest, pObject, NULL );
return pDest;
}
/* send message which allows to set execution context for debugger */

View File

@@ -949,11 +949,11 @@ void * hb_hashId( PHB_ITEM pHash )
return NULL;
}
void hb_hashCloneBody( PHB_ITEM pHash, PHB_ITEM pDest, PHB_NESTED_CLONED pClonedList )
void hb_hashCloneBody( PHB_ITEM pDest, PHB_ITEM pHash, PHB_NESTED_CLONED pClonedList )
{
HB_SIZE nPos;
HB_TRACE( HB_TR_DEBUG, ( "hb_hashCloneBody(%p,%p,%p)", pHash, pDest, pClonedList ) );
HB_TRACE( HB_TR_DEBUG, ( "hb_hashCloneBody(%p,%p,%p)", pDest, pHash, pClonedList ) );
hb_hashNew( pDest );
pDest->item.asHash.value->iFlags = pHash->item.asHash.value->iFlags;
@@ -976,7 +976,7 @@ void hb_hashCloneBody( PHB_ITEM pHash, PHB_ITEM pDest, PHB_NESTED_CLONED pCloned
hb_itemCopy( &pDest->item.asHash.value->pPairs[ nPos ].key,
&pHash->item.asHash.value->pPairs[ nPos ].key );
pDest->item.asHash.value->nLen++;
hb_cloneNested( &pDest->item.asHash.value->pPairs[ nPos ].value, pValue, pClonedList );
hb_nestedCloneDo( &pDest->item.asHash.value->pPairs[ nPos ].value, pValue, pClonedList );
}
}
@@ -986,22 +986,11 @@ PHB_ITEM hb_hashCloneTo( PHB_ITEM pDest, PHB_ITEM pHash )
if( HB_IS_HASH( pHash ) )
{
PHB_NESTED_CLONED pClonedList, pCloned;
HB_NESTED_CLONED clonedList;
pClonedList = ( PHB_NESTED_CLONED ) hb_xgrab( sizeof( HB_NESTED_CLONED ) );
pClonedList->value = ( void * ) pHash->item.asHash.value;
pClonedList->pDest = pDest;
pClonedList->pNext = NULL;
hb_hashCloneBody( pHash, pDest, pClonedList );
do
{
pCloned = pClonedList;
pClonedList = pClonedList->pNext;
hb_xfree( pCloned );
}
while( pClonedList );
hb_nestedCloneInit( &clonedList, ( void * ) pHash->item.asHash.value, pDest );
hb_hashCloneBody( pDest, pHash, &clonedList );
hb_nestedCloneFree( &clonedList );
}
return pDest;

View File

@@ -2144,12 +2144,7 @@ PHB_ITEM hb_itemClone( PHB_ITEM pItem )
if( HB_IS_ARRAY( pItem ) )
{
if( HB_IS_OBJECT( pItem ) )
{
PHB_ITEM pResult = hb_itemNew( NULL );
hb_objCloneTo( pResult, pItem, NULL );
return pResult;
}
return hb_objCloneTo( hb_itemNew( NULL ), pItem );
else
return hb_arrayClone( pItem );
}
@@ -2166,7 +2161,7 @@ void hb_itemCloneTo( PHB_ITEM pDest, PHB_ITEM pSource )
if( HB_IS_ARRAY( pSource ) )
{
if( HB_IS_OBJECT( pSource ) )
hb_objCloneTo( pDest, pSource, NULL );
hb_objCloneTo( pDest, pSource );
else
hb_arrayCloneTo( pDest, pSource );
}