xref: /aoo41x/main/soltools/giparser/gi_list.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_soltools.hxx"
30 
31 
32 #include <gi_list.hxx>
33 
34 
35 #include <gen_info.hxx>
36 
37 
38 
39 const char C_cKeySeparator = '/';
40 
41 
42 List_GenericInfo::List_GenericInfo()
43 {
44 }
45 
46 List_GenericInfo::List_GenericInfo( const List_GenericInfo & i_rList )
47     :   aChildren(i_rList.aChildren)
48 {
49 }
50 
51 List_GenericInfo::~List_GenericInfo()
52 {
53 }
54 
55 List_GenericInfo &
56 List_GenericInfo::operator=( const List_GenericInfo & i_rList )
57 {
58     aChildren = i_rList.aChildren;
59     return *this;
60 }
61 
62 const GenericInfo *
63 List_GenericInfo::operator[]( KeyPath i_sKeyPath ) const
64 {
65     return const_cast< List_GenericInfo& >(*this)[i_sKeyPath];
66 }
67 
68 GenericInfo *
69 List_GenericInfo::operator[]( KeyPath i_sKeyPath )
70 {
71     bool bExists = false;
72     const char * sNextPathSegment = 0;
73     sub_iterator it = lower_bound(bExists, sNextPathSegment, i_sKeyPath);
74 
75     if ( bExists )
76     {
77         if ( sNextPathSegment == 0 )
78             return (*it);
79         else
80             return (*it)->SubList()[sNextPathSegment];
81     }
82     else
83     {
84         return 0;
85     }
86 }
87 
88 bool
89 List_GenericInfo::InsertInfo( GenericInfo *       let_dpInfo,
90                               bool                i_bOverwrite )
91 {
92     if ( let_dpInfo == 0 )
93         return false;
94 
95     bool bExists = false;
96     const char * sNextPathSegment = 0;
97     sub_iterator it = lower_bound(bExists, sNextPathSegment, let_dpInfo->Key() );
98 
99     if ( ! bExists )
100     {
101         aChildren.insert( it, let_dpInfo );
102     }
103     else if ( i_bOverwrite )
104     {
105         delete (*it);
106         (*it) = let_dpInfo;
107     }
108     else
109     {
110      	delete let_dpInfo;
111         return false;
112     }
113 
114     return true;
115 }
116 
117 bool
118 List_GenericInfo::InsertInfoByPath( GenericInfo *       let_dpInfo,
119                                     KeyPath             i_sKeyPath,
120                                     bool                i_bCreatePath,
121                                     bool                i_bOverwrite )
122 {
123     if ( let_dpInfo == 0 )
124         return false;
125 
126     if ( i_sKeyPath == 0 ? true : *i_sKeyPath == 0 )
127      	return InsertInfo(let_dpInfo, i_bOverwrite);
128 
129     bool bExists = false;
130     const char * sNextPathSegment = 0;
131     sub_iterator it = lower_bound(bExists, sNextPathSegment, i_sKeyPath);
132 
133     if ( bExists )
134     {
135         return (*it)->SubList().InsertInfoByPath(
136                                     let_dpInfo,
137                                     sNextPathSegment,
138                                     i_bCreatePath,
139                                     i_bOverwrite );
140     }
141     else if ( i_bCreatePath )
142     {
143         Simstr aKey( i_sKeyPath,
144                      0,
145                      sNextPathSegment -
146                         ( *sNextPathSegment == 0 ? 0 : 1)
147                         - i_sKeyPath );
148 
149         GenericInfo * pNew = new GenericInfo(aKey);
150         InsertInfo(pNew,false);
151 
152         return pNew->SubList().InsertInfoByPath(
153                                     let_dpInfo,
154                                     sNextPathSegment,
155                                     i_bCreatePath,
156                                     i_bOverwrite );
157     }
158     else
159     {
160      	delete let_dpInfo;
161         return false;
162     }
163 }
164 
165 GenericInfo *
166 List_GenericInfo::ReleaseInfo( KeyPath i_sKeyPath )
167 {
168     bool bExists = false;
169     const char * sNextPathSegment = 0;
170     sub_iterator it = lower_bound(bExists, sNextPathSegment, i_sKeyPath );
171 
172     if ( bExists )
173     {
174         if ( *sNextPathSegment == 0 )
175             return (*it);
176         else
177             return (*it)->SubList().ReleaseInfo(sNextPathSegment);
178     }
179     else
180     {
181      	return 0;
182     }
183 }
184 
185 void
186 List_GenericInfo::DeleteInfo( KeyPath i_sKeyPath )
187 {
188     bool bExists = false;
189     const char * sNextPathSegment = 0;
190     sub_iterator it = lower_bound(bExists, sNextPathSegment, i_sKeyPath );
191 
192     if ( bExists )
193     {
194         if ( *sNextPathSegment == 0 )
195         {
196             aChildren.remove(it);
197         }
198         else
199         {
200             (*it)->SubList().DeleteInfo(sNextPathSegment);
201         }
202     }
203 }
204 
205 List_GenericInfo::sub_iterator
206 List_GenericInfo::lower_bound( bool &              o_bExists,
207                                const char * &      o_sNextPathSegment,
208                                KeyPath             i_sKeyPath )
209 {
210     o_sNextPathSegment = strchr(i_sKeyPath, '/');
211     Simstr sKey( i_sKeyPath, (o_sNextPathSegment == 0 ? strlen(i_sKeyPath) : o_sNextPathSegment++ - i_sKeyPath) );
212     GenericInfo aSearch(sKey);
213 
214     unsigned low = 0;
215     unsigned high = aChildren.size();
216 
217     for ( unsigned cur = high / 2; high > low; cur = (low + high) / 2 )
218     {
219         if ( *aChildren[cur] < aSearch )
220         {
221             low = cur+1;
222         }
223         else
224         {
225             high = cur;
226         }
227     }   // end for
228 
229     o_bExists = low < aChildren.size()
230                     ? !(aSearch < *aChildren[low] )
231                     : false;
232     return &aChildren[low];
233 }
234 
235