1 /*  $Id: seq_entry_info.cpp 603374 2020-03-10 19:52:03Z vasilche $
2 * ===========================================================================
3 *
4 *                            PUBLIC DOMAIN NOTICE
5 *               National Center for Biotechnology Information
6 *
7 *  This software/database is a "United States Government Work" under the
8 *  terms of the United States Copyright Act.  It was written as part of
9 *  the author's official duties as a United States Government employee and
10 *  thus cannot be copyrighted.  This software/database is freely available
11 *  to the public for use. The National Library of Medicine and the U.S.
12 *  Government have not placed any restriction on its use or reproduction.
13 *
14 *  Although all reasonable efforts have been taken to ensure the accuracy
15 *  and reliability of the software and data, the NLM and the U.S.
16 *  Government do not and cannot warrant the performance or results that
17 *  may be obtained by using this software or data. The NLM and the U.S.
18 *  Government disclaim all warranties, express or implied, including
19 *  warranties of performance, merchantability or fitness for any particular
20 *  purpose.
21 *
22 *  Please cite the author in any work or product based on this material.
23 *
24 * ===========================================================================
25 *
26 * Author: Eugene Vasilchenko
27 *
28 * File Description:
29 *   CSeq_entry_Info info -- entry for data source information about Seq-entry
30 *
31 */
32 
33 
34 #include <ncbi_pch.hpp>
35 #include <objmgr/impl/seq_entry_info.hpp>
36 #include <objmgr/impl/tse_info.hpp>
37 #include <objmgr/impl/seq_annot_info.hpp>
38 #include <objmgr/impl/bioseq_info.hpp>
39 #include <objmgr/impl/bioseq_set_info.hpp>
40 #include <objmgr/impl/data_source.hpp>
41 #include <objmgr/objmgr_exception.hpp>
42 
43 #include <objects/general/Object_id.hpp>
44 #include <objects/seqloc/Seq_id.hpp>
45 #include <objects/seqset/Seq_entry.hpp>
46 #include <objects/seqset/Bioseq_set.hpp>
47 #include <objects/seq/Bioseq.hpp>
48 #include <objects/seq/Seq_annot.hpp>
49 #include <objects/seq/Seqdesc.hpp>
50 
51 BEGIN_NCBI_SCOPE
52 BEGIN_SCOPE(objects)
53 
54 
55 static const int kBioseqChunkId = kMax_Int;
56 
57 
CSeq_entry_Info(void)58 CSeq_entry_Info::CSeq_entry_Info(void)
59     : m_Which(CSeq_entry::e_not_set)
60 {
61 }
62 
63 
CSeq_entry_Info(CSeq_entry & entry)64 CSeq_entry_Info::CSeq_entry_Info(CSeq_entry& entry)
65     : m_Which(CSeq_entry::e_not_set)
66 {
67     x_SetObject(entry);
68 }
69 
70 
CSeq_entry_Info(const CSeq_entry_Info & info,TObjectCopyMap * copy_map)71 CSeq_entry_Info::CSeq_entry_Info(const CSeq_entry_Info& info,
72                                  TObjectCopyMap* copy_map)
73     : TParent(info, copy_map),
74       m_Which(CSeq_entry::e_not_set)
75 {
76     if ( !copy_map ) {
77         info.x_UpdateComplete();
78     }
79     x_SetObject(info, copy_map);
80 }
81 
82 
~CSeq_entry_Info(void)83 CSeq_entry_Info::~CSeq_entry_Info(void)
84 {
85 }
86 
87 
GetParentBioseq_set_Info(void) const88 const CBioseq_set_Info& CSeq_entry_Info::GetParentBioseq_set_Info(void) const
89 {
90     return static_cast<const CBioseq_set_Info&>(GetBaseParent_Info());
91 }
92 
93 
GetParentBioseq_set_Info(void)94 CBioseq_set_Info& CSeq_entry_Info::GetParentBioseq_set_Info(void)
95 {
96     return static_cast<CBioseq_set_Info&>(GetBaseParent_Info());
97 }
98 
99 
GetParentSeq_entry_Info(void) const100 const CSeq_entry_Info& CSeq_entry_Info::GetParentSeq_entry_Info(void) const
101 {
102     return GetParentBioseq_set_Info().GetParentSeq_entry_Info();
103 }
104 
105 
GetParentSeq_entry_Info(void)106 CSeq_entry_Info& CSeq_entry_Info::GetParentSeq_entry_Info(void)
107 {
108     return GetParentBioseq_set_Info().GetParentSeq_entry_Info();
109 }
110 
111 
x_CheckWhich(E_Choice which) const112 void CSeq_entry_Info::x_CheckWhich(E_Choice which) const
113 {
114     if ( Which() != which ) {
115         switch ( which ) {
116         case CSeq_entry::e_Seq:
117             NCBI_THROW(CUnassignedMember,eGet,"Seq_entry.seq");
118         case CSeq_entry::e_Set:
119             NCBI_THROW(CUnassignedMember,eGet,"Seq_entry.set");
120         default:
121             NCBI_THROW(CUnassignedMember,eGet,"Seq_entry.not_set");
122         }
123     }
124 }
125 
126 
GetXrefTSE() const127 const CSeq_entry_Info& CSeq_entry_Info::GetXrefTSE() const
128 {
129     if ( !HasParent_Info() ) {
130         return *this;
131     }
132     const CBioseq_set_Info* bss = 0;
133     if ( IsSet() ) {
134         bss = &GetSet();
135     }
136     else if ( HasParent_Info() ) {
137         bss = &GetParentBioseq_set_Info();
138     }
139     else {
140         return *this;
141     }
142     if ( bss->GetClass() == CBioseq_set::eClass_parts ) {
143         const CSeq_entry_Info& parent = bss->GetParentSeq_entry_Info();
144         if ( parent.HasParent_Info() ) {
145             bss = &parent.GetParentBioseq_set_Info();
146         }
147         else {
148             return parent;
149         }
150     }
151     if ( bss->GetClass() == CBioseq_set::eClass_segset ) {
152         const CSeq_entry_Info& parent = bss->GetParentSeq_entry_Info();
153         if ( parent.HasParent_Info() ) {
154             bss = &parent.GetParentBioseq_set_Info();
155         }
156         else {
157             return parent;
158         }
159     }
160     return bss->GetParentSeq_entry_Info();
161 }
162 
163 
GetSeq(void) const164 const CBioseq_Info& CSeq_entry_Info::GetSeq(void) const
165 {
166     x_CheckWhich(CSeq_entry::e_Seq);
167     x_Update(fNeedUpdate_bioseq);
168     const CBioseq_Base_Info& base = *m_Contents;
169     return dynamic_cast<const CBioseq_Info&>(base);
170 }
171 
172 
SetSeq(void)173 CBioseq_Info& CSeq_entry_Info::SetSeq(void)
174 {
175     x_CheckWhich(CSeq_entry::e_Seq);
176     x_Update(fNeedUpdate_bioseq);
177     CBioseq_Base_Info& base = *m_Contents;
178     return dynamic_cast<CBioseq_Info&>(base);
179 }
180 
181 
GetSet(void) const182 const CBioseq_set_Info& CSeq_entry_Info::GetSet(void) const
183 {
184     x_CheckWhich(CSeq_entry::e_Set);
185     const CBioseq_Base_Info& base = *m_Contents;
186     return dynamic_cast<const CBioseq_set_Info&>(base);
187 }
188 
189 
SetSet(void)190 CBioseq_set_Info& CSeq_entry_Info::SetSet(void)
191 {
192     x_CheckWhich(CSeq_entry::e_Set);
193     CBioseq_Base_Info& base = *m_Contents;
194     return dynamic_cast<CBioseq_set_Info&>(base);
195 }
196 
197 
x_Select(CSeq_entry::E_Choice which,CRef<CBioseq_Base_Info> contents)198 void CSeq_entry_Info::x_Select(CSeq_entry::E_Choice which,
199                                CRef<CBioseq_Base_Info> contents)
200 {
201     if ( Which() != which || m_Contents != contents ) {
202         if ( m_Contents ) {
203             x_DetachContents();
204             m_Contents.Reset();
205         }
206         m_Which = which;
207         m_Contents = contents;
208         switch ( m_Which ) {
209         case CSeq_entry::e_Seq:
210             m_Object->SetSeq(SetSeq().x_GetObject());
211             break;
212         case CSeq_entry::e_Set:
213             m_Object->SetSet(SetSet().x_GetObject());
214             break;
215         default:
216             m_Object->Reset();
217             break;
218         }
219         x_AttachContents();
220     }
221 }
222 
223 
224 inline
x_Select(CSeq_entry::E_Choice which,CBioseq_Base_Info * contents)225 void CSeq_entry_Info::x_Select(CSeq_entry::E_Choice which,
226                                CBioseq_Base_Info* contents)
227 {
228     x_Select(which, Ref(contents));
229 }
230 
231 
Reset(void)232 void CSeq_entry_Info::Reset(void)
233 {
234     x_Select(CSeq_entry::e_not_set, 0);
235     SetBioObjectId(GetTSE_Info().x_RegisterBioObject(*this));
236 }
237 
238 
SelectSet(CBioseq_set_Info & seqset)239 CBioseq_set_Info& CSeq_entry_Info::SelectSet(CBioseq_set_Info& seqset)
240 {
241     if ( Which() != CSeq_entry::e_not_set ) {
242         NCBI_THROW(CObjMgrException, eModifyDataError,
243                    "Reset CSeq_entry_Handle before selecting set");
244     }
245     x_Select(CSeq_entry::e_Set, &seqset);
246     return SetSet();
247 }
248 
249 
SelectSet(CBioseq_set & seqset)250 CBioseq_set_Info& CSeq_entry_Info::SelectSet(CBioseq_set& seqset)
251 {
252     return SelectSet(*new CBioseq_set_Info(seqset));
253 }
254 
255 
SelectSet(void)256 CBioseq_set_Info& CSeq_entry_Info::SelectSet(void)
257 {
258     if ( !IsSet() ) {
259         SelectSet(*new CBioseq_set);
260     }
261     return SetSet();
262 }
263 
264 
SelectSeq(CBioseq_Info & seq)265 CBioseq_Info& CSeq_entry_Info::SelectSeq(CBioseq_Info& seq)
266 {
267     if ( Which() != CSeq_entry::e_not_set ) {
268         NCBI_THROW(CObjMgrException, eModifyDataError,
269                    "Reset CSeq_entry_Handle before selecting seq");
270     }
271     x_Select(CSeq_entry::e_Seq, &seq);
272     return SetSeq();
273 }
274 
275 
SelectSeq(CBioseq & seq)276 CBioseq_Info& CSeq_entry_Info::SelectSeq(CBioseq& seq)
277 {
278     return SelectSeq(*new CBioseq_Info(seq));
279 }
280 
281 
x_DoUpdate(TNeedUpdateFlags flags)282 void CSeq_entry_Info::x_DoUpdate(TNeedUpdateFlags flags)
283 {
284     if ( flags & fNeedUpdate_bioseq ) {
285         x_LoadChunk(kBioseqChunkId);
286     }
287     if ( (flags & fNeedUpdate_children) && m_Contents ) {
288         m_Contents->x_Update((flags & fNeedUpdate_children) |
289                              (flags >> kNeedUpdate_bits));
290         _ASSERT(Which()==m_Object->Which());
291     }
292     TParent::x_DoUpdate(flags);
293 }
294 
295 
x_SetNeedUpdateContents(TNeedUpdateFlags flags)296 void CSeq_entry_Info::x_SetNeedUpdateContents(TNeedUpdateFlags flags)
297 {
298     x_SetNeedUpdate(flags);
299 }
300 
301 
GetCompleteSeq_entry(void) const302 CConstRef<CSeq_entry> CSeq_entry_Info::GetCompleteSeq_entry(void) const
303 {
304     x_UpdateComplete();
305     return m_Object;
306 }
307 
308 
GetSeq_entryCore(void) const309 CConstRef<CSeq_entry> CSeq_entry_Info::GetSeq_entryCore(void) const
310 {
311     x_UpdateCore();
312     return m_Object;
313 }
314 
x_ParentAttach(CBioseq_set_Info & parent)315 void CSeq_entry_Info::x_ParentAttach(CBioseq_set_Info& parent)
316 {
317     x_BaseParentAttach(parent);
318     if ( parent.HasParent_Info() ) {
319         CSeq_entry& entry = parent.GetParentSeq_entry_Info().x_GetObject();
320         if ( m_Object->GetParentEntry() != &entry ) {
321             m_Object->SetParentEntry(&entry);
322             //entry.ParentizeOneLevel(); this call is too slow
323         }
324         _ASSERT(m_Object->GetParentEntry() == &entry);
325     }
326 }
327 
328 
x_ParentDetach(CBioseq_set_Info & parent)329 void CSeq_entry_Info::x_ParentDetach(CBioseq_set_Info& parent)
330 {
331     m_Object->ResetParentEntry();
332     x_BaseParentDetach(parent);
333 }
334 
335 
x_TSEAttachContents(CTSE_Info & tse)336 void CSeq_entry_Info::x_TSEAttachContents(CTSE_Info& tse)
337 {
338     TParent::x_TSEAttachContents(tse);
339     if ( m_Contents ) {
340         m_Contents->x_TSEAttach(tse);
341     }
342 }
343 
344 
x_TSEDetachContents(CTSE_Info & tse)345 void CSeq_entry_Info::x_TSEDetachContents(CTSE_Info& tse)
346 {
347     if ( m_Contents ) {
348         m_Contents->x_TSEDetach(tse);
349     }
350     TParent::x_TSEDetachContents(tse);
351 }
352 
353 
x_DSAttachContents(CDataSource & ds)354 void CSeq_entry_Info::x_DSAttachContents(CDataSource& ds)
355 {
356     TParent::x_DSAttachContents(ds);
357     if ( m_Object ) {
358         x_DSMapObject(m_Object, ds);
359     }
360     if ( m_Contents ) {
361         m_Contents->x_DSAttach(ds);
362     }
363 }
364 
365 
x_DSDetachContents(CDataSource & ds)366 void CSeq_entry_Info::x_DSDetachContents(CDataSource& ds)
367 {
368     if ( m_Contents ) {
369         m_Contents->x_DSDetach(ds);
370     }
371     if ( m_Object ) {
372         x_DSUnmapObject(m_Object, ds);
373     }
374     TParent::x_DSDetachContents(ds);
375 }
376 
377 
x_DSMapObject(CConstRef<TObject> obj,CDataSource & ds)378 void CSeq_entry_Info::x_DSMapObject(CConstRef<TObject> obj, CDataSource& ds)
379 {
380     ds.x_Map(obj, this);
381 }
382 
383 
x_DSUnmapObject(CConstRef<TObject> obj,CDataSource & ds)384 void CSeq_entry_Info::x_DSUnmapObject(CConstRef<TObject> obj, CDataSource& ds)
385 {
386     ds.x_Unmap(obj, this);
387 }
388 
389 
x_SetObject(TObject & obj)390 void CSeq_entry_Info::x_SetObject(TObject& obj)
391 {
392     // x_CheckWhich(CSeq_entry::e_not_set);
393     _ASSERT(!m_Object);
394     _ASSERT(!m_Contents);
395 
396     m_Object.Reset(&obj);
397     if ( HasDataSource() ) {
398         x_DSMapObject(m_Object, GetDataSource());
399     }
400     switch ( (m_Which = obj.Which()) ) {
401     case CSeq_entry::e_Seq:
402         m_Contents.Reset(new CBioseq_Info(obj.SetSeq()));
403         break;
404     case CSeq_entry::e_Set:
405         m_Contents.Reset(new CBioseq_set_Info(obj.SetSet()));
406         break;
407     default:
408         break;
409     }
410     x_AttachContents();
411 }
412 
413 
x_SetObject(const CSeq_entry_Info & info,TObjectCopyMap * copy_map)414 void CSeq_entry_Info::x_SetObject(const CSeq_entry_Info& info,
415                                   TObjectCopyMap* copy_map)
416 {
417     //x_CheckWhich(CSeq_entry::e_not_set);
418     _ASSERT(!m_Object);
419     _ASSERT(!m_Contents);
420 
421     m_Object.Reset(new CSeq_entry);
422     if ( HasDataSource() ) {
423         x_DSMapObject(m_Object, GetDataSource());
424     }
425     CRef<CBioseq_Base_Info> cinfo;
426     switch ( info.Which() ) {
427     case CSeq_entry::e_Seq:
428         cinfo.Reset(new CBioseq_Info(info.GetSeq(), copy_map));
429         break;
430     case CSeq_entry::e_Set:
431         cinfo.Reset(new CBioseq_set_Info(info.GetSet(), copy_map));
432         break;
433     default:
434         break;
435     }
436     x_Select(info.Which(), cinfo);
437 }
438 
439 
x_AttachContents(void)440 void CSeq_entry_Info::x_AttachContents(void)
441 {
442     if ( m_Contents ) {
443         m_Contents->x_ParentAttach(*this);
444         x_AttachObject(*m_Contents);
445     }
446 }
447 
448 
x_DetachContents(void)449 void CSeq_entry_Info::x_DetachContents(void)
450 {
451     if ( m_Contents ) {
452         x_DetachObject(*m_Contents);
453         m_Contents->x_ParentDetach(*this);
454     }
455 }
456 
457 
UpdateAnnotIndex(void) const458 void CSeq_entry_Info::UpdateAnnotIndex(void) const
459 {
460     if ( x_DirtyAnnotIndex() ) {
461         GetTSE_Info().UpdateAnnotIndex(*this);
462     }
463 }
464 
465 
x_UpdateAnnotIndexContents(CTSE_Info & tse)466 void CSeq_entry_Info::x_UpdateAnnotIndexContents(CTSE_Info& tse)
467 {
468     if ( m_Contents ) {
469         m_Contents->x_UpdateAnnotIndex(tse);
470     }
471     TParent::x_UpdateAnnotIndexContents(tse);
472 }
473 
474 
475 inline
x_UpdateSkeleton() const476 void CSeq_entry_Info::x_UpdateSkeleton() const
477 {
478     if ( !m_Object ) {
479         GetTSE_Info().x_LoadDelayedMainChunk();
480     }
481 }
482 
483 
x_Update(TNeedUpdateFlags flags) const484 void CSeq_entry_Info::x_Update(TNeedUpdateFlags flags) const
485 {
486     x_UpdateSkeleton();
487     TParent::x_Update(flags);
488 }
489 
490 
Which(void) const491 CSeq_entry::E_Choice CSeq_entry_Info::Which(void) const
492 {
493     x_UpdateSkeleton();
494     return m_Which;
495 }
496 
497 
GetSeq_entrySkeleton(void) const498 CConstRef<CSeq_entry> CSeq_entry_Info::GetSeq_entrySkeleton(void) const
499 {
500     x_UpdateSkeleton();
501     return m_Object;
502 }
503 
504 
x_GetObject(void)505 CSeq_entry& CSeq_entry_Info::x_GetObject(void)
506 {
507     x_UpdateSkeleton();
508     return *m_Object;
509 }
510 
511 
x_GetObject(void) const512 const CSeq_entry& CSeq_entry_Info::x_GetObject(void) const
513 {
514     x_UpdateSkeleton();
515     return *m_Object;
516 }
517 
518 
x_GetBaseInfo(void) const519 const CBioseq_Base_Info& CSeq_entry_Info::x_GetBaseInfo(void) const
520 {
521     x_UpdateSkeleton();
522     return *m_Contents;
523 }
524 
525 
IsSetDescr(void) const526 bool CSeq_entry_Info::IsSetDescr(void) const
527 {
528     x_UpdateSkeleton();
529     // x_Update(fNeedUpdate_descr);
530     return m_Contents && m_Contents->IsSetDescr();
531 }
532 
533 
GetDescr(void) const534 const CSeq_descr& CSeq_entry_Info::GetDescr(void) const
535 {
536     x_Update(fNeedUpdate_descr);
537     return m_Contents->GetDescr();
538 }
539 
540 
SetDescr(TDescr & v)541 void CSeq_entry_Info::SetDescr(TDescr& v)
542 {
543     x_Update(fNeedUpdate_descr);
544     m_Contents->SetDescr(v);
545 }
546 
547 
SetDescr(void)548 CSeq_entry_Info::TDescr& CSeq_entry_Info::SetDescr(void)
549 {
550     x_Update(fNeedUpdate_descr);
551     return m_Contents->SetDescr();
552 }
553 
554 
ResetDescr(void)555 void CSeq_entry_Info::ResetDescr(void)
556 {
557     x_Update(fNeedUpdate_descr);
558     m_Contents->ResetDescr();
559 }
560 
561 
AddSeqdesc(CSeqdesc & d)562 bool CSeq_entry_Info::AddSeqdesc(CSeqdesc& d)
563 {
564     x_Update(fNeedUpdate_descr);
565     return m_Contents->AddSeqdesc(d);
566 }
567 
568 
RemoveSeqdesc(const CSeqdesc & d)569 CRef<CSeqdesc> CSeq_entry_Info::RemoveSeqdesc(const CSeqdesc& d)
570 {
571     x_Update(fNeedUpdate_descr);
572     return m_Contents->RemoveSeqdesc(d);
573 }
574 
575 
ReplaceSeqdesc(const CSeqdesc & old_desc,CSeqdesc & new_desc)576 CRef<CSeqdesc> CSeq_entry_Info::ReplaceSeqdesc(const CSeqdesc& old_desc, CSeqdesc& new_desc)
577 {
578     x_Update(fNeedUpdate_descr);
579     return m_Contents->ReplaceSeqdesc(old_desc, new_desc);
580 }
581 
582 /*
583 void CSeq_entry_Info::AddDescr(CSeq_entry_Info& src)
584 {
585     x_Update(fNeedUpdate_descr);
586     if ( src.IsSetDescr() ) {
587         m_Contents->AddSeq_descr(src.m_Contents->SetDescr());
588     }
589 }
590 */
AddSeq_descr(const TDescr & v)591 void CSeq_entry_Info::AddSeq_descr(const TDescr& v)
592 {
593     x_Update(fNeedUpdate_descr);
594     m_Contents->AddSeq_descr(v);
595 }
596 
597 
598 
x_IsEndDesc(TDesc_CI iter) const599 bool CSeq_entry_Info::x_IsEndDesc(TDesc_CI iter) const
600 {
601     return m_Contents->x_IsEndDesc(iter);
602 }
603 
604 
605 CSeq_entry_Info::TDesc_CI
x_GetFirstDesc(TDescTypeMask types) const606 CSeq_entry_Info::x_GetFirstDesc(TDescTypeMask types) const
607 {
608     return m_Contents->x_GetFirstDesc(types);
609 }
610 
611 
612 CSeq_entry_Info::TDesc_CI
x_GetNextDesc(TDesc_CI iter,TDescTypeMask types) const613 CSeq_entry_Info::x_GetNextDesc(TDesc_CI iter, TDescTypeMask types) const
614 {
615     return m_Contents->x_GetNextDesc(iter, types);
616 }
617 
618 
AddAnnot(CSeq_annot & annot)619 CRef<CSeq_annot_Info> CSeq_entry_Info::AddAnnot(CSeq_annot& annot)
620 {
621     return m_Contents->AddAnnot(annot);
622 }
623 
624 
AddAnnot(CRef<CSeq_annot_Info> annot)625 void CSeq_entry_Info::AddAnnot(CRef<CSeq_annot_Info> annot)
626 {
627     m_Contents->AddAnnot(annot);
628 }
629 
630 
RemoveAnnot(CRef<CSeq_annot_Info> annot)631 void CSeq_entry_Info::RemoveAnnot(CRef<CSeq_annot_Info> annot)
632 {
633     m_Contents->RemoveAnnot(annot);
634 }
635 
636 
x_SetBioseqChunkId(TChunkId _DEBUG_ARG (chunk_id))637 void CSeq_entry_Info::x_SetBioseqChunkId(TChunkId _DEBUG_ARG(chunk_id))
638 {
639     _ASSERT(chunk_id == kBioseqChunkId);
640     //x_CheckWhich(CSeq_entry::e_not_set);
641     _ASSERT(!m_Object);
642     _ASSERT(!m_Contents);
643     x_SetNeedUpdate(CTSE_Info::fNeedUpdate_bioseq);
644     m_Which = CSeq_entry::e_Seq;
645 }
646 
647 
AddEntry(CSeq_entry & entry,int index)648 CRef<CSeq_entry_Info> CSeq_entry_Info::AddEntry(CSeq_entry& entry,
649                                                   int index)
650 {
651     x_CheckWhich(CSeq_entry::e_Set);
652     return SetSet().AddEntry(entry, index);
653 }
654 
655 
AddEntry(CRef<CSeq_entry_Info> entry,int index)656 void CSeq_entry_Info::AddEntry(CRef<CSeq_entry_Info> entry, int index)
657 {
658     x_CheckWhich(CSeq_entry::e_Set);
659     SetSet().AddEntry(entry, index);
660 }
661 
662 
RemoveEntry(CRef<CSeq_entry_Info> entry)663 void CSeq_entry_Info::RemoveEntry(CRef<CSeq_entry_Info> entry)
664 {
665     x_CheckWhich(CSeq_entry::e_Set);
666     SetSet().RemoveEntry(entry);
667 }
668 
GetBioObjectId(void) const669 const CBioObjectId& CSeq_entry_Info::GetBioObjectId(void) const
670 {
671     if (m_Contents)
672         return m_Contents->GetBioObjectId();
673     return TParent::GetBioObjectId();
674 }
675 
GetLoadedAnnot(void) const676 const CSeq_entry_Info::TAnnot& CSeq_entry_Info::GetLoadedAnnot(void) const
677 {
678     _ASSERT(m_Contents);
679     if (!m_Contents)
680         NCBI_THROW(CObjMgrException, eInvalidHandle,
681                    "The CSeq_entry_Handle must be selected first.");
682     return m_Contents->GetLoadedAnnot();
683 }
684 
685 
686 namespace {
x_SortUnique(CTSE_Info::TSeqIds & ids)687     static inline void x_SortUnique(CTSE_Info::TSeqIds& ids)
688     {
689         sort(ids.begin(), ids.end());
690         ids.erase(unique(ids.begin(), ids.end()), ids.end());
691     }
692 }
693 
694 
x_GetBioseqsIds(TSeqIds & ids) const695 void CSeq_entry_Info::x_GetBioseqsIds(TSeqIds& ids) const
696 {
697     if ( IsSet() ) {
698         const CBioseq_set_Info& seqset = GetSet();
699         ITERATE ( CBioseq_set_Info::TSeq_set, it, seqset.GetSeq_set() ) {
700             (*it)->x_GetBioseqsIds(ids);
701         }
702     }
703     if ( IsSeq() ) {
704         const CBioseq_Info::TId& seq_ids = GetSeq().GetId();
705         ids.insert(ids.end(), seq_ids.begin(), seq_ids.end());
706     }
707 }
708 
709 
x_GetAnnotIds(TSeqIds & ids) const710 void CSeq_entry_Info::x_GetAnnotIds(TSeqIds& ids) const
711 {
712     if ( IsSet() ) {
713         const CBioseq_set_Info& seqset = GetSet();
714         ITERATE ( CBioseq_set_Info::TSeq_set, it, seqset.GetSeq_set() ) {
715             (*it)->x_GetBioseqsIds(ids);
716         }
717     }
718     if ( Which() != CSeq_entry::e_not_set ) {
719         const CBioseq_Base_Info::TAnnot& annots = x_GetBaseInfo().GetAnnot();
720         ITERATE ( CBioseq_Base_Info::TAnnot, it, annots ) {
721             const CSeq_annot_Info::TAnnotObjectKeys& keys =
722                 (*it)->GetAnnotObjectKeys();
723             ITERATE ( CSeq_annot_Info::TAnnotObjectKeys, kit, keys ) {
724                 const CSeq_id_Handle id = kit->m_Handle;
725                 if ( !id ) {
726                     continue;
727                 }
728                 if ( !ids.empty() && id == ids.back() ) {
729                     continue;
730                 }
731                 ids.push_back(id);
732             }
733         }
734     }
735 }
736 
737 
GetBioseqsIds(TSeqIds & ids) const738 void CSeq_entry_Info::GetBioseqsIds(TSeqIds& ids) const
739 {
740     x_GetBioseqsIds(ids);
741     x_SortUnique(ids);
742 }
743 
744 
GetAnnotIds(TSeqIds & ids) const745 void CSeq_entry_Info::GetAnnotIds(TSeqIds& ids) const
746 {
747     GetTSE_Info().UpdateAnnotIndex(*this);
748     x_GetAnnotIds(ids);
749     x_SortUnique(ids);
750 }
751 
752 
GetSeqAndAnnotIds(TSeqIds & seq_ids,TSeqIds & annot_ids) const753 void CSeq_entry_Info::GetSeqAndAnnotIds(TSeqIds& seq_ids,
754                                         TSeqIds& annot_ids) const
755 {
756     GetBioseqsIds(seq_ids);
757     GetAnnotIds(annot_ids);
758 }
759 
760 
761 END_SCOPE(objects)
762 END_NCBI_SCOPE
763