1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 #include <precomp.h>
23 #include <toolkit/out_node.hxx>
24 
25 
26 // NOT FULLY DEFINED SERVICES
27 #include <algorithm>
28 
29 
30 namespace output
31 {
32 
33 
34 namespace
35 {
36 
37 struct Less_NodePtr
38 {
operator ()output::__anon612f6cb50111::Less_NodePtr39     bool                operator()(
40                             Node *              p1,
41                             Node *              p2 ) const
42                         { return p1->Name() < p2->Name(); }
43 };
44 
45 struct Less_NodePtr     C_Less_NodePtr;
46 
47 
48 Node  C_aNullNode(Node::null_object);
49 
50 
51 }   // namepace anonymous
52 
53 
54 //**********************        Node        ***************************//
55 
56 
Node()57 Node::Node()
58     :   sName(),
59   	    pParent(0),
60   	    aChildren(),
61   	    nDepth(0),
62   	    nNameRoomId(0)
63 {
64 }
65 
Node(E_NullObject)66 Node::Node( E_NullObject )
67     :   sName(),
68   	    pParent(0),
69   	    aChildren(),
70   	    nDepth(-1),
71   	    nNameRoomId(0)
72 {
73 }
74 
Node(const String & i_name,Node & i_parent)75 Node::Node( const String &  i_name,
76             Node &          i_parent )
77     :   sName(i_name),
78         pParent(&i_parent),
79         aChildren(),
80         nDepth(i_parent.Depth()+1),
81   	    nNameRoomId(0)
82 {
83 }
84 
~Node()85 Node::~Node()
86 {
87     for ( List::iterator it = aChildren.begin();
88           it != aChildren.end();
89           ++it )
90     {
91         delete *it;
92     }
93 }
94 
95 Node &
Provide_Child(const String & i_name)96 Node::Provide_Child( const String & i_name )
97 {
98     Node *
99         ret = find_Child(i_name);
100     if (ret != 0)
101         return *ret;
102     return add_Child(i_name);
103 }
104 
105 void
Get_Path(StreamStr & o_result,intt i_maxDepth) const106 Node::Get_Path( StreamStr &         o_result,
107                 intt                i_maxDepth ) const
108 {
109     // Intentionally 'i_maxDepth != 0', so max_Depth == -1 sets no limit:
110     if (i_maxDepth != 0)
111     {
112         if (pParent != 0)
113             pParent->Get_Path(o_result, i_maxDepth-1);
114         o_result << sName << '/';
115     }
116 }
117 
118 void
Get_Chain(StringVector & o_result,intt i_maxDepth) const119 Node::Get_Chain( StringVector & o_result,
120 				 intt           i_maxDepth ) const
121 {
122     if (i_maxDepth != 0)
123     {
124         // This is called also for the toplevel Node,
125         //   but there happens nothing:
126         if (pParent != 0)
127         {
128             pParent->Get_Chain(o_result, i_maxDepth-1);
129             o_result.push_back(sName);
130         }
131     }
132 }
133 
134 Node *
find_Child(const String & i_name)135 Node::find_Child( const String & i_name )
136 {
137     Node aSearch;
138     aSearch.sName = i_name;
139 
140     List::const_iterator
141         ret = std::lower_bound( aChildren.begin(),
142 							    aChildren.end(),
143                                 &aSearch,
144 						        C_Less_NodePtr );
145     if ( ret != aChildren.end() ? (*ret)->Name() == i_name : false )
146         return *ret;
147 
148     return 0;
149 }
150 
151 Node &
add_Child(const String & i_name)152 Node::add_Child( const String & i_name )
153 {
154     DYN Node *
155         pNew = new Node(i_name,*this);
156     aChildren.insert( std::lower_bound( aChildren.begin(),
157 										aChildren.end(),
158                                         pNew,
159 										C_Less_NodePtr ),
160 			          pNew );
161     return *pNew;
162 }
163 
164 Node &
provide_Child(StringVector::const_iterator i_next,StringVector::const_iterator i_end)165 Node::provide_Child( StringVector::const_iterator i_next,
166   	                 StringVector::const_iterator i_end )
167 {
168     if (i_next == i_end)
169         return *this;
170     return Provide_Child(*i_next).provide_Child(i_next+1,i_end);
171 }
172 
173 
174 
175 
176 Node &
Null_()177 Node::Null_()
178 {
179     return C_aNullNode;
180 }
181 
182 
183 }   // namespace output
184