📄 memberlist.cpp
字号:
!lastItem->GetId().HaveParentTag() ) tag = lastItem->GetId().GetTag() + 1; } item->GetId().SetTag(tag, false); } // add item m_Items.push_back(AutoPtr<CItemInfo>(item)); item->m_Index = LastIndex();}DEFINE_STATIC_FAST_MUTEX(s_ItemsMapMutex);const CItemsInfo::TItemsByName& CItemsInfo::GetItemsByName(void) const{ TItemsByName* items = m_ItemsByName.get(); if ( !items ) { CFastMutexGuard GUARD(s_ItemsMapMutex); items = m_ItemsByName.get(); if ( !items ) { auto_ptr<TItemsByName> keep(items = new TItemsByName); for ( CIterator i(*this); i.Valid(); ++i ) { const CItemInfo* itemInfo = GetItemInfo(i); const string& name = itemInfo->GetId().GetName(); if ( !items->insert(TItemsByName::value_type(name, *i)).second ) { if ( !name.empty() ) NCBI_THROW(CSerialException,eInvalidData, string("duplicate member name: ")+name); } } m_ItemsByName = keep; } } return *items;}const CItemsInfo::TItemsByOffset&CItemsInfo::GetItemsByOffset(void) const{ TItemsByOffset* items = m_ItemsByOffset.get(); if ( !items ) { CFastMutexGuard GUARD(s_ItemsMapMutex); items = m_ItemsByOffset.get(); if ( !items ) { // create map auto_ptr<TItemsByOffset> keep(items = new TItemsByOffset); // fill map for ( CIterator i(*this); i.Valid(); ++i ) { const CItemInfo* itemInfo = GetItemInfo(i); size_t offset = itemInfo->GetOffset(); if ( !items->insert(TItemsByOffset::value_type(offset, *i)).second ) { NCBI_THROW(CSerialException,eInvalidData, "conflict member offset"); } }/* // check overlaps size_t nextOffset = 0; for ( TItemsByOffset::const_iterator m = members->begin(); m != members->end(); ++m ) { size_t offset = m->first; if ( offset < nextOffset ) { NCBI_THROW(CSerialException,eInvalidData, "overlapping members"); } nextOffset = offset + m_Members[m->second]->GetSize(); }*/ m_ItemsByOffset = keep; } } return *items;}pair<TMemberIndex, const CItemsInfo::TItemsByTag*>CItemsInfo::GetItemsByTagInfo(void) const{ typedef pair<TMemberIndex, const TItemsByTag*> TReturn; TReturn ret(m_ZeroTagIndex, m_ItemsByTag.get()); if ( ret.first == kInvalidMember && ret.second == 0 ) { CFastMutexGuard GUARD(s_ItemsMapMutex); ret = TReturn(m_ZeroTagIndex, m_ItemsByTag.get()); if ( ret.first == kInvalidMember && ret.second == 0 ) { { CIterator i(*this); if ( i.Valid() ) { ret.first = *i-GetItemInfo(i)->GetId().GetTag(); for ( ++i; i.Valid(); ++i ) { if ( ret.first != *i-GetItemInfo(i)->GetId().GetTag() ) { ret.first = kInvalidMember; break; } } } } if ( ret.first != kInvalidMember ) { m_ZeroTagIndex = ret.first; } else { auto_ptr<TItemsByTag> items(new TItemsByTag); for ( CIterator i(*this); i.Valid(); ++i ) { const CItemInfo* itemInfo = GetItemInfo(i); TTag tag = itemInfo->GetId().GetTag(); if ( !items->insert(TItemsByTag::value_type(tag, *i)).second ) { NCBI_THROW(CSerialException,eInvalidData, "duplicate member tag"); } } ret.second = items.get(); m_ItemsByTag = items; } } } return ret;}TMemberIndex CItemsInfo::Find(const CLightString& name) const{ const TItemsByName& items = GetItemsByName(); TItemsByName::const_iterator i = items.find(name); if ( i == items.end() ) return kInvalidMember; return i->second;}TMemberIndex CItemsInfo::FindDeep(const CLightString& name) const{ TMemberIndex ind = Find(name); if (ind != kInvalidMember) { return ind; } for (CIterator item(*this); item.Valid(); ++item) { const CItemInfo* info = GetItemInfo(item); const CMemberId& id = info->GetId(); if (!id.IsAttlist() && id.HasNotag()) { const CTypeInfo* type; for (type = info->GetTypeInfo();;) { if (type->GetTypeFamily() == eTypeFamilyContainer) { const CContainerTypeInfo* cont = dynamic_cast<const CContainerTypeInfo*>(type); if (cont) { type = cont->GetElementType(); } } else if (type->GetTypeFamily() == eTypeFamilyPointer) { const CPointerTypeInfo* ptr = dynamic_cast<const CPointerTypeInfo*>(type); if (ptr) { type = ptr->GetPointedType(); } } else { break; } } const CClassTypeInfoBase* classType = dynamic_cast<const CClassTypeInfoBase*>(type); if (classType) { if (classType->GetItems().FindDeep(name) != kInvalidMember) { return *item; } } } } return kInvalidMember;}TMemberIndex CItemsInfo::FindEmpty(void) const{ for (CIterator item(*this); item.Valid(); ++item) { const CItemInfo* info = GetItemInfo(item); if (info->GetId().IsAttlist()) { continue; } const CTypeInfo* type; for (type = info->GetTypeInfo();;) { if (type->GetTypeFamily() == eTypeFamilyContainer) { // container may be empty return *item; } else if (type->GetTypeFamily() == eTypeFamilyPointer) { const CPointerTypeInfo* ptr = dynamic_cast<const CPointerTypeInfo*>(type); if (ptr) { type = ptr->GetPointedType(); } } else { break; } } } return kInvalidMember;}TMemberIndex CItemsInfo::Find(const CLightString& name, TMemberIndex pos) const{ for ( CIterator i(*this, pos); i.Valid(); ++i ) { if ( name == GetItemInfo(i)->GetId().GetName() ) return *i; } return kInvalidMember;}TMemberIndex CItemsInfo::Find(TTag tag) const{ pair<TMemberIndex, const TItemsByTag*> info = GetItemsByTagInfo(); if ( info.first != kInvalidMember ) { TMemberIndex index = tag + m_ZeroTagIndex; if ( index < FirstIndex() || index > LastIndex() ) return kInvalidMember; return index; } else { TItemsByTag::const_iterator mi = info.second->find(tag); if ( mi == info.second->end() ) return kInvalidMember; return mi->second; }}TMemberIndex CItemsInfo::Find(TTag tag, TMemberIndex pos) const{ pair<TMemberIndex, const TItemsByTag*> info = GetItemsByTagInfo(); if ( info.first != kInvalidMember ) { TMemberIndex index = tag + m_ZeroTagIndex; if ( index < pos || index > LastIndex() ) return kInvalidMember; return index; } else { for ( CIterator i(*this, pos); i.Valid(); ++i ) { if ( GetItemInfo(i)->GetId().GetTag() == tag ) return *i; } return kInvalidMember; }}END_NCBI_SCOPE
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -