Beispiel #1
0
const CItemInfo* CItemsInfo::FindNextMandatory(const CItemInfo* info)
{
    if (!info->GetId().HasNotag()) {
        const CMemberInfo* mem = dynamic_cast<const CMemberInfo*>(info);
        if (mem && mem->Optional()) {
            return 0;
        }
        return info;
    }
    const CItemInfo* found = 0;
    TTypeInfo type = FindRealTypeInfo(info->GetTypeInfo());
    ETypeFamily family = type->GetTypeFamily();
    if (family == eTypeFamilyClass || family == eTypeFamilyChoice) {
        const CClassTypeInfoBase* classType =
            dynamic_cast<const CClassTypeInfoBase*>(type);
        _ASSERT(classType);
        const CItemsInfo& items = classType->GetItems();
        TMemberIndex i;
        const CItemInfo* found_first = 0;
        for (i = items.FirstIndex(); i <= items.LastIndex(); ++i) {

            const CItemInfo* item = classType->GetItems().GetItemInfo(i);
            ETypeFamily item_family = item->GetTypeInfo()->GetTypeFamily();
            if (item_family == eTypeFamilyPointer) {
                const CPointerTypeInfo* ptr =
                    dynamic_cast<const CPointerTypeInfo*>(item->GetTypeInfo());
                if (ptr) {
                    item_family = ptr->GetPointedType()->GetTypeFamily();
                }
            }
            if (item_family == eTypeFamilyContainer) {
                if (item->NonEmpty()) {
                    found = FindNextMandatory( item );
                }
            } else {
                found = FindNextMandatory( item );
            }
            if (family == eTypeFamilyClass) {
                if (found) {
                    return found;
                }
            } else {
                if (!found) {
                    // this is optional choice variant
                    return 0;
                }
                if (!found_first) {
                    found_first = found;
                }
            }
        }
        return found_first;
    }
    return found;
}
Beispiel #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());
            }
        }
    }
}