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
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_soltools.hxx"
26
27
28 #include <gi_list.hxx>
29
30
31 #include <gen_info.hxx>
32
33
34
35 const char C_cKeySeparator = '/';
36
37
List_GenericInfo()38 List_GenericInfo::List_GenericInfo()
39 {
40 }
41
List_GenericInfo(const List_GenericInfo & i_rList)42 List_GenericInfo::List_GenericInfo( const List_GenericInfo & i_rList )
43 : aChildren(i_rList.aChildren)
44 {
45 }
46
~List_GenericInfo()47 List_GenericInfo::~List_GenericInfo()
48 {
49 }
50
51 List_GenericInfo &
operator =(const List_GenericInfo & i_rList)52 List_GenericInfo::operator=( const List_GenericInfo & i_rList )
53 {
54 aChildren = i_rList.aChildren;
55 return *this;
56 }
57
58 const GenericInfo *
operator [](KeyPath i_sKeyPath) const59 List_GenericInfo::operator[]( KeyPath i_sKeyPath ) const
60 {
61 return const_cast< List_GenericInfo& >(*this)[i_sKeyPath];
62 }
63
64 GenericInfo *
operator [](KeyPath i_sKeyPath)65 List_GenericInfo::operator[]( KeyPath i_sKeyPath )
66 {
67 bool bExists = false;
68 const char * sNextPathSegment = 0;
69 sub_iterator it = lower_bound(bExists, sNextPathSegment, i_sKeyPath);
70
71 if ( bExists )
72 {
73 if ( sNextPathSegment == 0 )
74 return (*it);
75 else
76 return (*it)->SubList()[sNextPathSegment];
77 }
78 else
79 {
80 return 0;
81 }
82 }
83
84 bool
InsertInfo(GenericInfo * let_dpInfo,bool i_bOverwrite)85 List_GenericInfo::InsertInfo( GenericInfo * let_dpInfo,
86 bool i_bOverwrite )
87 {
88 if ( let_dpInfo == 0 )
89 return false;
90
91 bool bExists = false;
92 const char * sNextPathSegment = 0;
93 sub_iterator it = lower_bound(bExists, sNextPathSegment, let_dpInfo->Key() );
94
95 if ( ! bExists )
96 {
97 aChildren.insert( it, let_dpInfo );
98 }
99 else if ( i_bOverwrite )
100 {
101 delete (*it);
102 (*it) = let_dpInfo;
103 }
104 else
105 {
106 delete let_dpInfo;
107 return false;
108 }
109
110 return true;
111 }
112
113 bool
InsertInfoByPath(GenericInfo * let_dpInfo,KeyPath i_sKeyPath,bool i_bCreatePath,bool i_bOverwrite)114 List_GenericInfo::InsertInfoByPath( GenericInfo * let_dpInfo,
115 KeyPath i_sKeyPath,
116 bool i_bCreatePath,
117 bool i_bOverwrite )
118 {
119 if ( let_dpInfo == 0 )
120 return false;
121
122 if ( i_sKeyPath == 0 ? true : *i_sKeyPath == 0 )
123 return InsertInfo(let_dpInfo, i_bOverwrite);
124
125 bool bExists = false;
126 const char * sNextPathSegment = 0;
127 sub_iterator it = lower_bound(bExists, sNextPathSegment, i_sKeyPath);
128
129 if ( bExists )
130 {
131 return (*it)->SubList().InsertInfoByPath(
132 let_dpInfo,
133 sNextPathSegment,
134 i_bCreatePath,
135 i_bOverwrite );
136 }
137 else if ( i_bCreatePath )
138 {
139 Simstr aKey( i_sKeyPath,
140 0,
141 sNextPathSegment -
142 ( *sNextPathSegment == 0 ? 0 : 1)
143 - i_sKeyPath );
144
145 GenericInfo * pNew = new GenericInfo(aKey);
146 InsertInfo(pNew,false);
147
148 return pNew->SubList().InsertInfoByPath(
149 let_dpInfo,
150 sNextPathSegment,
151 i_bCreatePath,
152 i_bOverwrite );
153 }
154 else
155 {
156 delete let_dpInfo;
157 return false;
158 }
159 }
160
161 GenericInfo *
ReleaseInfo(KeyPath i_sKeyPath)162 List_GenericInfo::ReleaseInfo( KeyPath i_sKeyPath )
163 {
164 bool bExists = false;
165 const char * sNextPathSegment = 0;
166 sub_iterator it = lower_bound(bExists, sNextPathSegment, i_sKeyPath );
167
168 if ( bExists )
169 {
170 if ( *sNextPathSegment == 0 )
171 return (*it);
172 else
173 return (*it)->SubList().ReleaseInfo(sNextPathSegment);
174 }
175 else
176 {
177 return 0;
178 }
179 }
180
181 void
DeleteInfo(KeyPath i_sKeyPath)182 List_GenericInfo::DeleteInfo( KeyPath i_sKeyPath )
183 {
184 bool bExists = false;
185 const char * sNextPathSegment = 0;
186 sub_iterator it = lower_bound(bExists, sNextPathSegment, i_sKeyPath );
187
188 if ( bExists )
189 {
190 if ( *sNextPathSegment == 0 )
191 {
192 aChildren.remove(it);
193 }
194 else
195 {
196 (*it)->SubList().DeleteInfo(sNextPathSegment);
197 }
198 }
199 }
200
201 List_GenericInfo::sub_iterator
lower_bound(bool & o_bExists,const char * & o_sNextPathSegment,KeyPath i_sKeyPath)202 List_GenericInfo::lower_bound( bool & o_bExists,
203 const char * & o_sNextPathSegment,
204 KeyPath i_sKeyPath )
205 {
206 o_sNextPathSegment = strchr(i_sKeyPath, '/');
207 Simstr sKey( i_sKeyPath, (o_sNextPathSegment == 0 ? strlen(i_sKeyPath) : o_sNextPathSegment++ - i_sKeyPath) );
208 GenericInfo aSearch(sKey);
209
210 unsigned low = 0;
211 unsigned high = aChildren.size();
212
213 for ( unsigned cur = high / 2; high > low; cur = (low + high) / 2 )
214 {
215 if ( *aChildren[cur] < aSearch )
216 {
217 low = cur+1;
218 }
219 else
220 {
221 high = cur;
222 }
223 } // end for
224
225 o_bExists = low < aChildren.size()
226 ? !(aSearch < *aChildren[low] )
227 : false;
228 return &aChildren[low];
229 }
230
231