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