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 36 Directory::Directory() 37 { 38 } 39 40 Directory::Directory( const Path & i_rPath ) 41 : aPath(i_rPath) 42 // sPath 43 { 44 } 45 46 Directory::Directory( const Directory & i_rDir ) 47 : Persistent(), aPath(i_rDir.aPath) 48 // sPath 49 { 50 } 51 52 Directory::Directory( const char * i_rLocation ) 53 : aPath(i_rLocation, true) 54 { 55 } 56 57 Directory::Directory( const String & i_rLocation ) 58 : aPath(i_rLocation.c_str(), true) 59 { 60 } 61 62 Directory::~Directory() 63 { 64 } 65 66 Directory & 67 Directory::operator+=( const String & i_sName ) 68 { 69 InvalidatePath(); 70 aPath.DirChain() += i_sName; 71 return *this; 72 } 73 74 Directory & 75 Directory::operator+=( const DirectoryChain & i_sDirChain ) 76 { 77 InvalidatePath(); 78 aPath.DirChain() += i_sDirChain; 79 return *this; 80 } 81 82 Directory & 83 Directory::operator-=( uintt i_nLevels ) 84 { 85 InvalidatePath(); 86 aPath.DirChain().PopBack(i_nLevels); 87 return *this; 88 } 89 90 bool 91 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 104 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 143 Directory::PhysicalCreate_Dir( const char * i_sStr ) const 144 { 145 return mkdir( i_sStr ) == 0; 146 } 147 148 void 149 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 176 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 239 Directory::PhysicalCreate_Dir( const char * i_sStr ) const 240 { 241 return mkdir( i_sStr, 00777 ) == 0; 242 } 243 244 void 245 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 273 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 & 349 Directory::inq_MyPath() const 350 { 351 return aPath; 352 } 353 354 355 356 } // namespace ploc 357 } // namespace csv 358 359 360 361