Exemple #1
0
void CChoiceTypeInfo::Assign(TObjectPtr dst, TConstObjectPtr src,
                             ESerialRecursionMode how) const
{
    TMemberIndex index;

    index = GetVariants().FirstIndex();
    const CVariantInfo* variantInfo = GetVariantInfo(index);
    if (variantInfo->GetId().IsAttlist()) {
        const CMemberInfo* info =
            dynamic_cast<const CMemberInfo*>(GetVariants().GetItemInfo(index));
        info->GetTypeInfo()->Assign(GetMember(info, dst),
                                    GetMember(info, src),how);
    }

    index = GetIndex(src);
    if ( index == kEmptyChoice )
        ResetIndex(dst);
    else {
        _ASSERT(index >= GetVariants().FirstIndex() &&
                index <= GetVariants().LastIndex());
        SetIndex(dst, index);
        GetVariantInfo(index)->GetTypeInfo()->Assign(GetData(dst, index),
                GetData(src, index), how);
    }

    // User defined assignment
    CallUserOp_Assign(dst, src);
}
Exemple #2
0
void CChoicePointerTypeInfo::SetPointerType(TTypeInfo base)
{
    m_NullPointerIndex = kEmptyChoice;

    if ( base->GetTypeFamily() != eTypeFamilyPointer )
        NCBI_THROW(CSerialException,eInvalidData,
                     "invalid argument: must be CPointerTypeInfo");
    const CPointerTypeInfo* ptrType =
        CTypeConverter<CPointerTypeInfo>::SafeCast(base);
    m_PointerTypeInfo = ptrType;

    if ( ptrType->GetPointedType()->GetTypeFamily() != eTypeFamilyClass )
        NCBI_THROW(CSerialException,eInvalidData,
                     "invalid argument: data must be CClassTypeInfo");
    const CClassTypeInfo* classType =
        CTypeConverter<CClassTypeInfo>::SafeCast(ptrType->GetPointedType());
    /* Do we really need it to be CObject???
    if ( !classType->IsCObject() )
        NCBI_THROW(CSerialException,eInvalidData,
                     "invalid argument:: choice ptr type must be CObject");
    */
    const CClassTypeInfo::TSubClasses* subclasses =
        classType->SubClasses();
    if ( !subclasses )
        return;

    TTypeInfo nullTypeInfo = CNullTypeInfo::GetTypeInfo();

    for ( CClassTypeInfo::TSubClasses::const_iterator i = subclasses->begin();
          i != subclasses->end(); ++i ) {
        TTypeInfo variantType = i->second.Get();
        if ( !variantType ) {
            // null
            variantType = nullTypeInfo;
        }
        AddVariant(i->first, 0, variantType)->SetSubClass();
        TMemberIndex index = GetVariants().LastIndex();
        if ( variantType == nullTypeInfo ) {
            if ( m_NullPointerIndex == kEmptyChoice )
                m_NullPointerIndex = index;
            else {
                ERR_POST_X(1, "double null");
            }
        }
        else {
            const type_info* id = &CTypeConverter<CClassTypeInfo>::SafeCast(variantType)->GetId();
            if ( !m_VariantsByType.insert(TVariantsByType::value_type(id, index)).second ) {
                NCBI_THROW(CSerialException,eInvalidData,
                           "conflict subclasses: "+variantType->GetName());
            }
        }
    }
}
Exemple #3
0
bool CChoiceTypeInfo::Equals(TConstObjectPtr object1, TConstObjectPtr object2,
                             ESerialRecursionMode how) const
{
    // User defined comparison
    if ( IsCObject() ) {
        if ( const CSerialUserOp* op1 =
                    dynamic_cast<const CSerialUserOp*>
                    (static_cast<const CObject*>(object1)) ) {
            if ( const CSerialUserOp* op2 =
                        dynamic_cast<const CSerialUserOp*>
                        (static_cast<const CObject*>(object2)) ) {
                if ( !op1->UserOp_Equals(*op2) )
                    return false;
            }
        }
    }

    TMemberIndex index;

    index = GetVariants().FirstIndex();
    const CVariantInfo* variantInfo = GetVariantInfo(index);
    if (variantInfo->GetId().IsAttlist()) {
        const CMemberInfo* info =
            dynamic_cast<const CMemberInfo*>(GetVariants().GetItemInfo(index));
        if ( !info->GetTypeInfo()->Equals(GetMember(info, object1),
                                          GetMember(info, object2), how) ) {
            return false;
        }
    }

    // Default comparison
    index = GetIndex(object1);
    if ( index != GetIndex(object2) )
        return false;
    if ( index == kEmptyChoice )
        return true;
    return
        GetVariantInfo(index)->GetTypeInfo()->Equals(GetData(object1, index),
                GetData(object2, index), how);
}
Exemple #4
0
CVariantInfo* CChoiceTypeInfo::AddVariant(const CMemberId& memberId,
        const void* memberPtr,
        const CTypeRef& memberType)
{
    if ( GetVariants().Size() == 1 &&
            !GetVariantInfo(kFirstMemberIndex)->GetId().IsAttlist() ) {
        // simple
        SetReadFunction(&TFunc::ReadChoiceSimple);
        SetSkipFunction(&TFunc::SkipChoiceSimple);
    }
    CVariantInfo* variantInfo = new CVariantInfo(this, memberId,
            TPointerOffsetType(memberPtr),
            memberType);
    GetItems().AddItem(variantInfo);
    return variantInfo;
}