1 /* $Id: seq_entry_ci.cpp 483569 2015-11-02 17:27:19Z 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: Aleksey Grichenko, Eugene Vasilchenko
27 *
28 * File Description:
29 * Handle to Seq-entry object
30 *
31 */
32
33 #include <ncbi_pch.hpp>
34 #include <objmgr/seq_entry_ci.hpp>
35
36 #include <objmgr/impl/seq_entry_info.hpp>
37 #include <objmgr/impl/scope_impl.hpp>
38 #include <objmgr/impl/bioseq_set_info.hpp>
39
40 #include <objects/seqset/Bioseq_set.hpp>
41
42
43 BEGIN_NCBI_SCOPE
BEGIN_SCOPE(objects)44 BEGIN_SCOPE(objects)
45
46
47 /////////////////////////////////////////////////////////////////////////////
48 // CSeq_entry_CI
49 /////////////////////////////////////////////////////////////////////////////
50
51
52 CSeq_entry_CI::CSeq_entry_CI(const CSeq_entry_Handle& entry,
53 TFlags flags,
54 CSeq_entry::E_Choice type_filter )
55 : m_Flags(flags),
56 m_Filter(type_filter)
57 {
58 if ( m_Flags & fIncludeGivenEntry ) {
59 m_Current = entry;
60 while ((*this) && !x_ValidType()) {
61 x_Next();
62 }
63 } else {
64 if ( entry.IsSet() ) {
65 x_Initialize( entry.GetSet() );
66 }
67 }
68 }
69
70
CSeq_entry_CI(const CBioseq_set_Handle & seqset,TFlags flags,CSeq_entry::E_Choice type_filter)71 CSeq_entry_CI::CSeq_entry_CI(const CBioseq_set_Handle& seqset,
72 TFlags flags,
73 CSeq_entry::E_Choice type_filter )
74 : m_Flags(flags),
75 m_Filter(type_filter)
76 {
77 x_Initialize(seqset);
78 }
79
80
CSeq_entry_CI(const CSeq_entry_CI & iter)81 CSeq_entry_CI::CSeq_entry_CI(const CSeq_entry_CI& iter)
82 {
83 *this = iter;
84 }
85
86
operator =(const CSeq_entry_CI & iter)87 CSeq_entry_CI& CSeq_entry_CI::operator =(const CSeq_entry_CI& iter)
88 {
89 if (this != &iter) {
90 m_Parent = iter.m_Parent;
91 m_Index = iter.m_Index;
92 m_Current = iter.m_Current;
93 m_Flags = iter.m_Flags;
94 m_Filter = iter.m_Filter;
95 if ( iter.m_SubIt.get() ) {
96 m_SubIt.reset(new CSeq_entry_CI(*iter.m_SubIt));
97 }
98 }
99 return *this;
100 }
101
102
x_Initialize(const CBioseq_set_Handle & seqset)103 void CSeq_entry_CI::x_Initialize(const CBioseq_set_Handle& seqset)
104 {
105 if ( seqset ) {
106 m_Parent = seqset;
107 m_Index = 0;
108 x_SetCurrentEntry();
109 while ((*this) && !x_ValidType()) {
110 x_Next();
111 }
112 }
113 }
114
115
x_SetCurrentEntry(void)116 void CSeq_entry_CI::x_SetCurrentEntry(void)
117 {
118 if ( m_Parent ) {
119 const vector< CRef<CSeq_entry_Info> >& entries =
120 m_Parent.x_GetInfo().GetSeq_set();
121 if ( m_Index < entries.size() ) {
122 m_Current = CSeq_entry_Handle(*entries[m_Index],
123 m_Parent.GetTSE_Handle());
124 return;
125 }
126 }
127 m_Current.Reset();
128 }
129
130
operator ++(void)131 CSeq_entry_CI& CSeq_entry_CI::operator ++(void)
132 {
133 do {
134 x_Next();
135 }
136 while ((*this) && !x_ValidType());
137 return *this;
138 }
139
140
x_ValidType(void) const141 bool CSeq_entry_CI::x_ValidType(void) const
142 {
143 _ASSERT(*this);
144 switch ( m_Filter ) {
145 case CSeq_entry::e_Seq:
146 return (*this)->IsSeq();
147 case CSeq_entry::e_Set:
148 return (*this)->IsSet();
149 default:
150 break;
151 }
152 return true;
153 }
154
155
x_Next(void)156 void CSeq_entry_CI::x_Next(void)
157 {
158 if ( !(*this) ) {
159 return;
160 }
161
162 if ( m_SubIt.get() ) {
163 // There should not even be a m_SubIt unless we're
164 // in recursive mode
165 _ASSERT(m_Flags & fRecursive);
166 // m_SubIt implies m_Parent
167 _ASSERT( m_Parent );
168 // Already inside sub-entry - try to move forward.
169 ++(*m_SubIt);
170 if ( *m_SubIt ) {
171 return;
172 }
173 // End of sub-entry, continue to the next entry.
174 m_SubIt.reset();
175 }
176 else if ( m_Current.IsSet() ) {
177 // don't set up m_SubIt unless parent is already set up
178 if( ! m_Parent ) {
179 x_Initialize(m_Current.GetSet());
180 return;
181 } else if( m_Flags & fRecursive ) {
182 // Current entry is a seq-set and we're in recursive mode,
183 // so iterate sub-entries.
184 m_SubIt.reset(new CSeq_entry_CI(
185 m_Current,
186 (m_Flags & ~fIncludeGivenEntry), // some flags don't get passed down recursively
187 m_Filter ));
188 if ( *m_SubIt ) {
189 return;
190 }
191 // Empty sub-entry, continue to the next entry.
192 m_SubIt.reset();
193 }
194 }
195
196 // "if m_Parent" is really just a proxy for seeing if m_Index is valid,
197 // otherwise incrementing is undefined
198 if( m_Parent ) {
199 ++m_Index;
200 }
201 x_SetCurrentEntry();
202 }
203
204
GetDepth(void) const205 int CSeq_entry_CI::GetDepth(void) const
206 {
207 // first, calculate depth assuming the "given" entry has
208 // a depth of zero
209 const int iDepthFromGiven =
210 ( m_SubIt.get() ?
211 2 + m_SubIt->GetDepth() :
212 ( m_Parent ? 1 : 0 )
213 );
214
215 if( (m_Flags & fIncludeGivenEntry) ) {
216 return iDepthFromGiven;
217 } else {
218 // if given entry is not supposed to be included in the iteration,
219 // it's children get a depth of zero, so we subtract by 1.
220 _ASSERT( iDepthFromGiven > 0 );
221 return (iDepthFromGiven - 1);
222 }
223 }
224
225
226 /////////////////////////////////////////////////////////////////////////////
227 // CSeq_entry_I
228 /////////////////////////////////////////////////////////////////////////////
229
230
CSeq_entry_I(const CSeq_entry_EditHandle & entry,TFlags flags,CSeq_entry::E_Choice type_filter)231 CSeq_entry_I::CSeq_entry_I(const CSeq_entry_EditHandle& entry,
232 TFlags flags,
233 CSeq_entry::E_Choice type_filter)
234 : CSeq_entry_CI(entry, flags, type_filter)
235 {
236 }
237
238
CSeq_entry_I(const CBioseq_set_EditHandle & seqset,TFlags flags,CSeq_entry::E_Choice type_filter)239 CSeq_entry_I::CSeq_entry_I(const CBioseq_set_EditHandle& seqset,
240 TFlags flags,
241 CSeq_entry::E_Choice type_filter)
242 : CSeq_entry_CI(seqset, flags, type_filter)
243 {
244 }
245
246
CSeq_entry_I(const CSeq_entry_I & iter)247 CSeq_entry_I::CSeq_entry_I(const CSeq_entry_I& iter)
248 {
249 *this = iter;
250 }
251
252
operator =(const CSeq_entry_I & iter)253 CSeq_entry_I& CSeq_entry_I::operator =(const CSeq_entry_I& iter)
254 {
255 CSeq_entry_CI::operator=(iter);
256 return *this;
257 }
258
259
260 END_SCOPE(objects)
261 END_NCBI_SCOPE
262