00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <vector>
00021 #include <string>
00022 #include <iostream>
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #if defined(MACOS) || defined(BEOS)
00038 #error "MatchString(): Port me, maties!"
00039
00040
00041
00042
00043
00044 static bool MatchString( const char *str, const std::string& inPat );
00045 static bool MatchString( const char *str, const std::string& inPat )
00046 {
00047 const char *pat = inPat.c_str();
00048
00049 const char *p = NULL;
00050 const char *q = NULL;
00051
00052 for(;;)
00053 {
00054 switch(*pat)
00055 {
00056 case '*':
00057 p = ++pat;
00058 q = str;
00059 break;
00060
00061 default:
00062 if(*pat != *str)
00063 {
00064 if(p)
00065 {
00066 pat = p;
00067 str = ++q;
00068 if(!*str)
00069 return !*pat;
00070 break;
00071 }
00072 else
00073 return false;
00074 }
00075
00076 case '?':
00077 if(!*str)
00078 return !*pat;
00079 pat++;
00080 str++;
00081 }
00082 }
00083 }
00084
00085 #endif
00086
00087
00088
00089 #if defined(WIN32)
00090
00091
00092 #include <windows.h>
00093 #include <malloc.h>
00094 #include <tchar.h>
00095
00096 int FileSystem::ListFiles(const std::string mask, FileList& files)
00097 {
00098 std::string path(mask);
00099 const TCHAR *lpszT;
00100 WIN32_FIND_DATA fileinfo;
00101 HANDLE handle;
00102 char *stripped_path;
00103 int i, nLen, nLen2;
00104
00105 if(path[0]=='@')
00106 rewrite_virtual_path(path);
00107
00108 #ifdef UNICODE
00109 const char *name = path.c_str();
00110 nLen = strlen(name)+1;
00111 LPTSTR lpszT2 = (LPTSTR) _alloca(nLen*2);
00112 lpszT = lpszT2;
00113 MultiByteToWideChar(CP_ACP, 0, name, -1, lpszT2, nLen);
00114 #else
00115 lpszT = path.c_str();
00116 #endif
00117
00118 handle = FindFirstFile (lpszT, &fileinfo);
00119
00120 stripped_path = new char [path.length()+1];
00121 std::strcpy (stripped_path, path.c_str());
00122
00123 for (i = std::strlen (stripped_path)-1; i; i--)
00124 if (stripped_path[i] == '\\' || stripped_path[i] == '/')
00125 break;
00126
00127 if (stripped_path[i] == '\\' || stripped_path[i] == '/')
00128 stripped_path[i+1] = 0;
00129
00130
00131 #ifdef DEBUG
00132 perr << "FileSystem::ListFiles(): " << mask << " = " << path << std::endl;
00133 #endif
00134
00135
00136 if (handle != INVALID_HANDLE_VALUE)
00137 {
00138 do
00139 {
00140 nLen = std::strlen(stripped_path);
00141 nLen2 = _tcslen (fileinfo.cFileName)+1;
00142 char *filename = new char [nLen+nLen2];
00143 strcpy (filename, stripped_path);
00144 #ifdef UNICODE
00145 WideCharToMultiByte(CP_ACP, 0, fileinfo.cFileName, -1, filename+nLen, nLen2, NULL, NULL);
00146 #else
00147 std::strcat (filename, fileinfo.cFileName);
00148 #endif
00149
00150 files.push_back(filename);
00151 #ifdef DEBUG
00152 perr << filename << std::endl;
00153 #endif
00154 delete [] filename;
00155 } while (FindNextFile( handle, &fileinfo ));
00156 }
00157
00158 if (GetLastError() != ERROR_NO_MORE_FILES) {
00159 LPTSTR lpMsgBuf;
00160 char* str;
00161 FormatMessage(
00162 FORMAT_MESSAGE_ALLOCATE_BUFFER |
00163 FORMAT_MESSAGE_FROM_SYSTEM |
00164 FORMAT_MESSAGE_IGNORE_INSERTS,
00165 NULL,
00166 GetLastError(),
00167 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
00168 (LPTSTR) &lpMsgBuf,
00169 0,
00170 NULL
00171 );
00172 #ifdef UNICODE
00173 nLen2 = _tcslen (lpMsgBuf) + 1;
00174 str = (char*) _alloca(nLen);
00175 WideCharToMultiByte(CP_ACP, 0, lpMsgBuf, -1, str, nLen2, NULL, NULL);
00176 #else
00177 str = lpMsgBuf;
00178 #endif
00179 perr << "FileSystem::ListFiles(): Error while listing files: " << str << std::endl;
00180 LocalFree( lpMsgBuf );
00181 }
00182
00183 #ifdef DEBUG
00184 perr << files.size() << " filenames" << std::endl;
00185 #endif
00186
00187 delete [] stripped_path;
00188 FindClose (handle);
00189 return 0;
00190 }
00191
00192 #elif defined(MACOS)
00193 #error "ListFiles(): Port me! I'm an engineer, not a MACOS porter Capt'n!"
00194
00195 #include <Files.h>
00196 #include <TextUtils.h>
00197
00198
00199 OSErr GetCatInfoNoName(short vRefNum, long dirID, std::string name, CInfoPBPtr pb);
00200 OSErr GetCatInfoNoName(short vRefNum, long dirID, std::string name, CInfoPBPtr pb)
00201 {
00202 Str255 tempName;
00203 OSErr err;
00204
00205 CopyCStringToPascal(name.c_str(), tempName);
00206
00207 if (tempName[0] == 0)
00208 pb->dirInfo.ioFDirIndex = -1;
00209 else
00210 pb->dirInfo.ioFDirIndex = 0;
00211
00212 pb->dirInfo.ioNamePtr = tempName;
00213 pb->dirInfo.ioVRefNum = vRefNum;
00214 pb->dirInfo.ioDrDirID = dirID;
00215 err = PBGetCatInfoSync(pb);
00216 pb->dirInfo.ioNamePtr = NULL;
00217 return err;
00218 }
00219
00220
00221 int U7ListFiles(const std::string pathMask, FileList& files)
00222 {
00223 CInfoPBRec cPB;
00224 Str63 itemName;
00225 OSErr err;
00226 short index = 0;
00227 short vRefNum;
00228 long dirID;
00229 char filename[256];
00230 string path(get_system_path(pathMask));
00231 string mask;
00232 string::size_type pos;
00233
00234 pos = path.rfind(':');
00235 if(pos == string::npos)
00236 {
00237 mask = path;
00238 path.clear();
00239 }
00240 else
00241 {
00242 mask = path.substr(pos+1);
00243 path = path.substr(0,pos);
00244 }
00245
00246 err = HGetVol( NULL, &vRefNum, &dirID );
00247 if (err != noErr)
00248 return err;
00249
00250 err = GetCatInfoNoName(vRefNum,dirID,path,&cPB);
00251 if (err != noErr)
00252 return err;
00253 dirID = cPB.dirInfo.ioDrDirID;
00254
00255 itemName[0] = 0;
00256 cPB.hFileInfo.ioNamePtr = (StringPtr)&itemName;
00257
00258 do
00259 {
00260
00261
00262 ++index;
00263 cPB.dirInfo.ioFDirIndex = index;
00264 cPB.dirInfo.ioDrDirID = dirID;
00265 err = PBGetCatInfoSync(&cPB);
00266
00267 if (err == noErr)
00268 {
00269
00270 if ( (cPB.hFileInfo.ioFlAttrib & kioFlAttribDirMask) == 0 )
00271 {
00272 CopyPascalStringToC(itemName, filename);
00273 if (MatchString(filename, mask))
00274 {
00275 pout << "File name: " << filename << endl;
00276 files.push_back(filename);
00277 }
00278 }
00279 }
00280
00281 } while (err == noErr );
00282
00283 if ( (err == fnfErr) ||
00284 (err == afpAccessDenied) )
00285 {
00286 err = noErr;
00287 }
00288
00289 return err;
00290 }
00291
00292 #elif defined(BEOS)
00293 #error "ListFiles(): Needs porting to BEOS! I must admit I will be a little surprised if anyone sees this error compiling this... *grin*"
00294
00295 #include <be/storage/Directory.h>
00296 #include <be/storage/Entry.h>
00297
00298 int U7ListFiles(const std::string pathMask, FileList& files)
00299 {
00300 char filename[255];
00301 string path(get_system_path(pathMask));
00302 string mask;
00303 string::size_type pos;
00304
00305 pos = path.rfind('/');
00306 if(pos == string::npos)
00307 {
00308 mask = path;
00309 path = "";
00310 }
00311 else
00312 {
00313 mask = path.substr(pos+1);
00314 path = path.substr(0,pos);
00315 }
00316
00317 BDirectory dir(path.c_str());
00318
00319 if (dir.InitCheck() != B_OK)
00320 return -1;
00321
00322 do {
00323 BEntry entry;
00324 if (dir.GetNextEntry(&entry, true) == B_ENTRY_NOT_FOUND)
00325 break;
00326
00327
00328 if (!entry.IsFile())
00329 continue;
00330
00331 entry.GetName(filename);
00332 if (MatchString(filename, mask)) {
00333 pout << "Filename: " << filename << endl;
00334 files.push_back(filename);
00335 }
00336 } while (true);
00337
00338 return 0;
00339 }
00340
00341 #elif defined(__MORPHOS__) || defined(AMIGA)
00342 #error "ListFiles(): Port me! Please?"
00343
00344 #define NO_PPCINLINE_VARARGS
00345 #define NO_PPCINLINE_STDARG
00346 #include <proto/dos.h>
00347
00348 static struct AnchorPath ap __attribute__((aligned(4)));
00349
00350 int U7ListFiles(const std::string mask, FileList& files)
00351 {
00352 string path(get_system_path(mask));
00353 char buffer[ 256 ];
00354 size_t pos;
00355
00356
00357 while( (pos = path.find( '*' )) != string::npos )
00358 path.replace( pos, 1, "#?" );
00359
00360 if( ParsePattern( path.c_str(), buffer, sizeof( buffer ) ) != -1 )
00361 {
00362 LONG error = MatchFirst( buffer, &ap );
00363
00364 while( error == DOSFALSE )
00365 {
00366 char *filename = (char *)malloc( strlen( ap.ap_Info.fib_FileName )+1 );
00367 strcpy( filename, ap.ap_Info.fib_FileName );
00368 files.push_back( filename );
00369 error = MatchNext( &ap );
00370 }
00371
00372 MatchEnd( &ap );
00373 }
00374 else
00375 pout << "ParsePattern() failed." << endl;
00376
00377 return 0;
00378 }
00379
00380
00381 #else // This system has glob.h
00382
00383 #include <glob.h>
00384
00385 int FileSystem::ListFiles(const std::string mask, FileList& files)
00386
00387 {
00388 glob_t globres;
00389 std::string name(mask);
00390
00391
00392 const std::string rootpath(name.substr(0, name.find('/')));
00393
00394
00395 if (!rewrite_virtual_path(name)) {
00396 perr << "Warning: FileSystem sandbox violation when accessing:"
00397 << std::endl << "\t" << mask << std::endl;
00398 return -1;
00399 }
00400
00401 #if 0
00402 pout << "Root: " << rootpath << std::endl;
00403 pout << name << "\t" << name.size() << std::endl;
00404 pout << mask << '\t' << mask.size() << std::endl;
00405 #endif
00406
00407
00408
00409 uint32 newplen = name.size() - mask.size() + rootpath.size();
00410
00411 int err = glob(name.c_str(), GLOB_NOSORT, 0, &globres);
00412
00413 switch (err) {
00414 case 0:
00415 for(unsigned int i=0; i<globres.gl_pathc; i++)
00416 {
00417 std::string newfname(globres.gl_pathv[i]);
00418 #if 0
00419 pout << newfname << std::endl;
00420 #endif
00421 newfname = rootpath + newfname.substr(newplen);
00422
00423
00424 #if 0
00425 pout << newfname << std::endl;
00426 #endif
00427 files.push_back(newfname);
00428 }
00429 globfree(&globres);
00430 return 0;
00431 case 3:
00432 return 0;
00433 default:
00434 perr << "Glob error " << err << std::endl;
00435 return err;
00436 }
00437 }
00438
00439 #endif
00440