static bool SerializeObject(CLR_RT_HeapBlock* pObj, CLR_UINT8* serData, CLR_INT32& serOffset, CLR_INT32& serSize )
{
    if(pObj == NULL)
    {
        return false;
    }

    switch(pObj->DataType())
    {
        case DATATYPE_OBJECT:
            if(!SerializeObject(pObj->Dereference(), serData, serOffset, serSize)) return false;
            break;
            
        case DATATYPE_CLASS:
        case DATATYPE_VALUETYPE:
            {
                CLR_RT_TypeDef_Instance cls; cls.InitializeFromIndex( pObj->ObjectCls() );
                int                    totFields = cls.CrossReference().m_totalFields;

                while(totFields-- > 0)
                {
                    if(!SerializeObject( ++pObj, serData, serOffset, serSize )) return false;
                }
            }
            break;

        case DATATYPE_SZARRAY:
            {
                CLR_RT_HeapBlock_Array* array = (CLR_RT_HeapBlock_Array*)pObj;
                int cnt = array->m_numOfElements;

                CLR_UINT8* pData;

                if(array->m_typeOfElement <= DATATYPE_LAST_NONPOINTER && cnt < 256)
                {
                    pData = (CLR_UINT8*)array->GetFirstElement();

                    while(cnt--)
                    {
                        if(!SerializeIntrinsicType( (CLR_DataType)array->m_typeOfElement, pData, serData, serOffset, serSize )) return false;

                        pData += array->m_sizeOfElement;
                    }
                }
                else
                {
                    return false;
                }
            }
            break;

        default:
            {
                CLR_UINT64 data = (CLR_UINT64)pObj->NumericByRef().u8;
                
                if(!SerializeIntrinsicType(pObj->DataType(), (CLR_UINT8*)&data, serData, serOffset, serSize)) return false;
            }
            break;               
    }

    return true;
}
static bool DeserializeObject(CLR_RT_HeapBlock* pObj, CLR_UINT8* serData, CLR_INT32& serOffset, const CLR_INT32 serSize )
{
    if(pObj == NULL)
    {
        return false;
    }

    switch(pObj->DataType())
    {
        case DATATYPE_OBJECT:
            if(!DeserializeObject(pObj->Dereference(), serData, serOffset, serSize)) return false;
            break;
            
        case DATATYPE_CLASS:
        case DATATYPE_VALUETYPE:
            {
                CLR_RT_TypeDef_Instance cls; cls.InitializeFromIndex( pObj->ObjectCls() );
                int                    totFields = cls.CrossReference().m_totalFields;

                while(totFields-- > 0)
                {
                    if(!DeserializeObject( ++pObj, serData, serOffset, serSize )) return false;
                }
            }
            break;

        case DATATYPE_SZARRAY:
            {
                CLR_RT_HeapBlock_Array* array = (CLR_RT_HeapBlock_Array*)pObj;
                int cnt = array->m_numOfElements;

                if(array->m_typeOfElement <= DATATYPE_LAST_NONPOINTER && cnt < 256)
                {
                    CLR_UINT8* pData = (CLR_UINT8*)array->GetFirstElement();

                    int nativeSize = GetTypeSize((CLR_DataType)array->m_typeOfElement);
                    
                    if(nativeSize <= 0) return false;

                    while(cnt--)
                    {
                        int size = nativeSize;
                        int i = 0;
                        
                        while(size--)
                        {
#ifndef BIG_ENDIAN
                            pData[i++ ] = serData[serOffset++];
#else
                            pData[size] = serData[serOffset++];
#endif
                        }

                        pData += array->m_sizeOfElement;
                    }
                }
                else
                {
                    return false;
                }
            }
            break;

        default:
            {
                CLR_UINT64 data = (CLR_UINT64)pObj->NumericByRef().u8;
                
                if(!DeserializeIntrinsicType(pObj, serData, serOffset, serSize)) return false;
            }
            break;               
    }

    return true;
}