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 #include <precomp.h>
25 #include <cosv/ploc_dir.hxx>
26
27 // NOT FULLY DECLARED SERVICES
28 #include <cosv/ploc.hxx>
29
30
31 namespace csv
32 {
33 namespace ploc
34 {
35
Directory()36 Directory::Directory()
37 {
38 }
39
Directory(const Path & i_rPath)40 Directory::Directory( const Path & i_rPath )
41 : aPath(i_rPath)
42 // sPath
43 {
44 }
45
Directory(const Directory & i_rDir)46 Directory::Directory( const Directory & i_rDir )
47 : Persistent(), aPath(i_rDir.aPath)
48 // sPath
49 {
50 }
51
Directory(const char * i_rLocation)52 Directory::Directory( const char * i_rLocation )
53 : aPath(i_rLocation, true)
54 {
55 }
56
Directory(const String & i_rLocation)57 Directory::Directory( const String & i_rLocation )
58 : aPath(i_rLocation.c_str(), true)
59 {
60 }
61
~Directory()62 Directory::~Directory()
63 {
64 }
65
66 Directory &
operator +=(const String & i_sName)67 Directory::operator+=( const String & i_sName )
68 {
69 InvalidatePath();
70 aPath.DirChain() += i_sName;
71 return *this;
72 }
73
74 Directory &
operator +=(const DirectoryChain & i_sDirChain)75 Directory::operator+=( const DirectoryChain & i_sDirChain )
76 {
77 InvalidatePath();
78 aPath.DirChain() += i_sDirChain;
79 return *this;
80 }
81
82 Directory &
operator -=(uintt i_nLevels)83 Directory::operator-=( uintt i_nLevels )
84 {
85 InvalidatePath();
86 aPath.DirChain().PopBack(i_nLevels);
87 return *this;
88 }
89
90 bool
PhysicalCreate(bool i_bCreateParentsIfNecessary) const91 Directory::PhysicalCreate( bool i_bCreateParentsIfNecessary ) const
92 {
93 bool ret = PhysicalCreate_Dir( StrPath() );
94 if ( ret OR NOT i_bCreateParentsIfNecessary )
95 return ret;
96
97 ret = Check_Parent();
98 if (ret)
99 ret = PhysicalCreate_Dir( StrPath() );
100 return ret;
101 }
102
103 bool
Check_Parent() const104 Directory::Check_Parent() const
105 {
106 // There is no parent of root directories:
107 if ( aPath.DirChain().Size() == 0 )
108 return false;
109
110 // Become my own parent:
111 String sLastToken = aPath.DirChain().Back();
112 const_cast< Directory* >(this)->operator-=(1);
113
114 // Begin behaving as parent:
115 bool ret = Exists();
116 if (NOT ret)
117 {
118 ret = Check_Parent();
119 if (ret)
120 ret = PhysicalCreate_Dir( StrPath() );
121 }
122 // End behaving as parent.
123
124 // Become myself again:
125 const_cast< Directory* >(this)->operator+=(sLastToken);
126 return ret;
127 }
128
129 } // namespace ploc
130 } // namespace csv
131
132
133 #ifdef WNT
134 #include <direct.h>
135 #include <io.h>
136
137 namespace csv
138 {
139 namespace ploc
140 {
141
142 bool
PhysicalCreate_Dir(const char * i_sStr) const143 Directory::PhysicalCreate_Dir( const char * i_sStr ) const
144 {
145 return mkdir( i_sStr ) == 0;
146 }
147
148 void
GetContainedDirectories(StringVector & o_rResult) const149 Directory::GetContainedDirectories( StringVector & o_rResult ) const
150 {
151 const char * c_sANYDIR = "\\*.*";
152 String sNew;
153
154 StreamStr sFilter(200);
155 sFilter << StrPath()
156 << c_sANYDIR;
157
158 struct _finddata_t
159 aEntry;
160 long hFile = _findfirst( sFilter.c_str(), &aEntry );
161
162 for ( int bFindMore = (hFile == -1 ? 1 : 0);
163 bFindMore == 0;
164 bFindMore = _findnext( hFile, &aEntry ) )
165 {
166 if ( (aEntry.attrib & _A_SUBDIR) AND *aEntry.name != '.' )
167 {
168 sNew = aEntry.name;
169 o_rResult.push_back( sNew );
170 }
171 } // end for
172 _findclose(hFile);
173 }
174
175 void
GetContainedFiles(StringVector & o_rResult,const char * i_sFilter,E_Recursivity i_eRecursivity) const176 Directory::GetContainedFiles( StringVector & o_rResult,
177 const char * i_sFilter,
178 E_Recursivity i_eRecursivity ) const
179 {
180 StreamStr sNew(240);
181 sNew << aPath;
182 StreamStr::size_type
183 nStartFilename = sNew.tellp();
184
185 StreamStr sFilter(200);
186 sFilter << StrPath()
187 << "\\"
188 << i_sFilter;
189
190 struct _finddata_t
191 aEntry;
192 long hFile = _findfirst( sFilter.c_str(), &aEntry );
193 for ( int bFindMore = (hFile == -1 ? 1 : 0);
194 bFindMore == 0;
195 bFindMore = _findnext( hFile, &aEntry ) )
196 {
197 sNew.seekp(nStartFilename);
198 sNew << aEntry.name;
199 String sNewAsString( sNew.c_str() );
200 o_rResult.push_back(sNewAsString);
201 } // end for
202
203 _findclose(hFile);
204 if ( i_eRecursivity == flat )
205 return;
206
207 // gathering from subdirectories:
208 StringVector aSubDirectories;
209 GetContainedDirectories( aSubDirectories );
210
211 StringVector::const_iterator dEnd = aSubDirectories.end();
212 for ( StringVector::const_iterator d = aSubDirectories.begin();
213 d != dEnd;
214 ++d )
215 {
216 Directory aSub(*this);
217 aSub += *d;
218 aSub.GetContainedFiles( o_rResult,
219 i_sFilter,
220 i_eRecursivity );
221 }
222 }
223
224 } // namespace ploc
225 } // namespace csv
226
227
228 #elif defined(UNX)
229 #include <sys/types.h>
230 #include <sys/stat.h>
231 #include <dirent.h>
232
233 namespace csv
234 {
235 namespace ploc
236 {
237
238 bool
PhysicalCreate_Dir(const char * i_sStr) const239 Directory::PhysicalCreate_Dir( const char * i_sStr ) const
240 {
241 return mkdir( i_sStr, 00777 ) == 0;
242 }
243
244 void
GetContainedDirectories(StringVector & o_rResult) const245 Directory::GetContainedDirectories( StringVector & o_rResult ) const
246 {
247 StreamStr sNew(240);
248 sNew << aPath;
249 StreamStr::size_type
250 nStartFilename = sNew.tellp();
251
252 DIR * pDir = opendir( StrPath() );
253 dirent * pEntry = 0;
254 struct stat aEntryStatus;
255
256 while ( (pEntry = readdir(pDir)) != 0 )
257 {
258 sNew.seekp(nStartFilename);
259 sNew << pEntry->d_name;
260
261 stat(sNew.c_str(), &aEntryStatus);
262 if ( (aEntryStatus.st_mode & S_IFDIR) == S_IFDIR
263 AND *pEntry->d_name != '.' )
264 {
265 String sNew2(pEntry->d_name);
266 o_rResult.push_back(sNew2);
267 } // endif (aEntry.attrib == _A_SUBDIR)
268 } // end while
269 closedir( pDir );
270 }
271
272 void
GetContainedFiles(StringVector & o_rResult,const char * i_sFilter,E_Recursivity i_eRecursivity) const273 Directory::GetContainedFiles( StringVector & o_rResult,
274 const char * i_sFilter,
275 E_Recursivity i_eRecursivity ) const
276 {
277 StreamStr sNew(240);
278 sNew << aPath;
279 StreamStr::size_type
280 nStartFilename = sNew.tellp();
281
282 bool bUseFilter = strcmp( i_sFilter, "*.*" ) != 0
283 AND strncmp( i_sFilter, "*.", 2) == 0;
284
285 DIR * pDir = opendir( StrPath() );
286 dirent * pEntry = 0;
287 struct stat aEntryStatus;
288
289 while ( (pEntry = readdir(pDir)) != 0 )
290 {
291 sNew.seekp(nStartFilename);
292 sNew << pEntry->d_name;
293
294 stat(sNew.c_str(), &aEntryStatus);
295 if ( (aEntryStatus.st_mode & S_IFDIR) == S_IFDIR )
296 continue; // Don't gather directories.
297
298 if ( bUseFilter )
299 {
300 const char * pEnding = strrchr(pEntry->d_name,'.');
301 if (pEnding == 0)
302 continue;
303 if ( strcasecmp( pEnding + 1, i_sFilter + 2 ) != 0 )
304 continue;
305 }
306
307 sNew.seekp(nStartFilename);
308 sNew << pEntry->d_name;
309 String sNewAsString( sNew.c_str() );
310 o_rResult.push_back(sNewAsString);
311 } // end while
312
313 closedir( pDir );
314 if ( i_eRecursivity == flat )
315 return;
316
317 // gathering from subdirectories:
318 StringVector aSubDirectories;
319 GetContainedDirectories( aSubDirectories );
320
321 StringVector::const_iterator dEnd = aSubDirectories.end();
322 for ( StringVector::const_iterator d = aSubDirectories.begin();
323 d != dEnd;
324 ++d )
325 {
326 Directory aSub(*this);
327 aSub += *d;
328 aSub.GetContainedFiles( o_rResult,
329 i_sFilter,
330 i_eRecursivity );
331 }
332 }
333
334 } // namespace ploc
335 } // namespace csv
336
337
338 #else
339 #error For using csv::ploc there has to be defined: WNT or UNX.
340 #endif
341
342
343 namespace csv
344 {
345 namespace ploc
346 {
347
348 const Path &
inq_MyPath() const349 Directory::inq_MyPath() const
350 {
351 return aPath;
352 }
353
354
355
356 } // namespace ploc
357 } // namespace csv
358
359
360
361