00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include "file.h"
00036 #include "common/wave_ex.h"
00037
00038 #include <ctype.h>
00039 #include <sstream>
00040
00041
00042
00043 static const char s_separator =
00044 #ifdef WIN32
00045 '/';
00046
00047 #else
00048 '/';
00049 #endif // WIN32
00050
00051
00052
00053
00054
00055
00056
00057
00058 const char *
00059 GetExtension
00060 (
00061 IN const char * filename
00062 )
00063 throw()
00064 {
00065 const char * p = filename;
00066 if (!p)
00067 return p;
00068
00069
00070 while (*p) {
00071 p++;
00072 }
00073
00074
00075 while (*p != '.' && p > filename) {
00076 p--;
00077 }
00078
00079 if (*p == '.') {
00080 return p + 1;
00081 }
00082
00083 ASSERT(p == filename, "Should be at beginning of string");
00084 return NULL;
00085 }
00086
00087
00088
00089 bool
00090 hasExtension
00091 (
00092 IN const char * filename,
00093 IN const char * extension
00094 )
00095 throw()
00096 {
00097 ASSERT(filename, "null");
00098 ASSERT(extension, "null");
00099
00100 const char * ext = GetExtension(filename);
00101 if (!ext)
00102 return false;
00103
00104 return !strcasecmp(ext, extension);
00105 }
00106
00107
00108
00109 void
00110 GetFileRoot
00111 (
00112 IN const char * filename,
00113 OUT std::string& root_name
00114 )
00115 {
00116 ASSERT(filename, "NULL filename");
00117
00118 const char * start = NULL;
00119 const char * end = NULL;
00120 const char * p = filename;
00121
00122
00123 while (*p) {
00124 p++;
00125 }
00126
00127
00128 while (!start) {
00129 p--;
00130 if (p < filename)
00131 start = filename;
00132
00133 if (!end && '.' == *p)
00134 end = p;
00135 else if (s_separator == *p)
00136 start = p + 1;
00137 }
00138
00139 ASSERT(start, "never found a root filename: %s", filename);
00140
00141
00142
00143
00144 root_name = "";
00145 while (*start && start != end) {
00146 root_name += *start;
00147 ++start;
00148 }
00149 }
00150
00151
00152 void
00153 GetParentDirectory
00154 (
00155 IN const char * filename,
00156 OUT std::string& directory
00157 )
00158 throw()
00159 {
00160 ASSERT(filename, "NULL filename");
00161 ASSERT(*filename, "empty file");
00162 directory.clear();
00163
00164 const char * p = filename;
00165
00166
00167 while (*p) {
00168 p++;
00169 }
00170
00171
00172 while (p > filename && *p != s_separator) {
00173 --p;
00174 }
00175
00176 if (s_separator != *p) {
00177
00178 return;
00179 }
00180
00181 if (p == filename) {
00182
00183 directory = s_separator;
00184 return;
00185 }
00186
00187
00188 while (filename < p) {
00189 directory += *filename;
00190 filename++;
00191 }
00192 }
00193
00194
00195
00196 const char *
00197 getTopDirectory
00198 (
00199 IN const char * filename,
00200 OUT std::string& topDir
00201 )
00202 {
00203 ASSERT(filename, "null");
00204 topDir.clear();
00205
00206
00207 const char * p = filename;
00208 while (*p && *p != s_separator) {
00209 topDir += *p;
00210 ++p;
00211
00212 }
00213 if (!*p) {
00214
00215 topDir.clear();
00216 return filename;
00217 }
00218
00219 return p + 1;
00220 }
00221
00222
00223
00224 const char *
00225 GetFilename
00226 (
00227 IN const char * path
00228 )
00229 throw()
00230 {
00231 const char * p = path;
00232
00233 ASSERT(path, "NULL path");
00234 ASSERT(*path, "empty path");
00235
00236
00237 while (*p) {
00238 p++;
00239 }
00240
00241
00242 while (p > path && *p != s_separator) {
00243 --p;
00244 }
00245
00246
00247 if (s_separator == *p)
00248 p++;
00249
00250
00251 return p;
00252 }
00253
00254
00255
00256 void
00257 getTempfile
00258 (
00259 IN const char * filename,
00260 OUT std::string& tempfile
00261 )
00262 throw()
00263 {
00264 ASSERT(filename, "null");
00265
00266
00267 std::string directory;
00268 GetParentDirectory(filename, directory);
00269
00270 int x = rand() % 10000;
00271
00272
00273
00274
00275 dword_t thread_id =
00276 #ifdef WIN32
00277 GetCurrentThreadId();
00278 #else // WIN32
00279 pthread_self();
00280 #endif // WIN32
00281 long pid = *(long *)(&thread_id);
00282
00283
00284 std::ostringstream temp;
00285 temp << directory << "~" << GetFilename(filename);
00286 temp << "." << pid << "-" << x << ".tmp";
00287 tempfile = temp.str();
00288
00289
00290 }
00291
00292
00293
00294 void
00295 getUserHomePath
00296 (
00297 OUT std::string& path
00298 )
00299 {
00300 #ifdef WIN32
00301 path = "c:/Users/";
00302 #else // WIN32
00303
00304 path = "/home/";
00305
00306
00307 const char * login = getenv("LOGNAME");
00308 if (!login)
00309 login = getlogin();
00310
00311
00312 if (login)
00313 path += login;
00314 #endif // WIN32
00315 }
00316
00317
00318
00319 bool
00320 ContainsWhitespace
00321 (
00322 IN const char * test
00323 )
00324 throw()
00325 {
00326 if (!test)
00327 return false;
00328
00329 const char * p = test;
00330 while (*p) {
00331 if (isspace(*p))
00332 return true;
00333 ++p;
00334 }
00335 return false;
00336 }
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366 #ifdef WIN32
00367 #include <sys/stat.h>
00368 #define stat(path, ptr) _stat(path, ptr)
00369 typedef struct _stat stat_t;
00370 #else // WIN32
00371 typedef struct stat stat_t;
00372 #endif // WIN32
00373
00374
00375 bool
00376 doesPathExist
00377 (
00378 IN const char * path
00379 )
00380 throw()
00381 {
00382 ASSERT(path, "null");
00383
00384 stat_t buf;
00385 int retval = stat(path, &buf);
00386
00387
00388
00389 if (-1 == retval) {
00390 return false;
00391 }
00392 return true;
00393 }
00394
00395
00396
00397 void
00398 createEmptyFileIfDoesNotExist
00399 (
00400 IN const char * path
00401 )
00402 throw()
00403 {
00404 ASSERT(path, "null");
00405
00406 if (doesPathExist(path))
00407 return;
00408
00409
00410 std::string cmd = "/bin/touch ";
00411 cmd += path;
00412 system(cmd.c_str());
00413 }
00414
00415
00416
00417 bool
00418 matchesExtension
00419 (
00420 IN const char * filename,
00421 IN const char * extension
00422 )
00423 throw()
00424 {
00425 ASSERT(filename, "null");
00426
00427
00428 if (!extension)
00429 return true;
00430
00431
00432 int extLen = strlen(extension);
00433 int fileLen = strlen(filename);
00434
00435 int delta = fileLen - extLen;
00436 if (delta <= 0)
00437 return false;
00438
00439 const char * fileExt = filename + delta;
00440 return !strcasecmp(fileExt, extension);
00441 }
00442
00443
00444
00445 void
00446 walkDirectoryTree
00447 (
00448 IN const char * rootDir,
00449 IN const char * matchExt,
00450 OUT VecString& paths
00451 )
00452 {
00453 ASSERT(rootDir, "null");
00454
00455 paths.clear();
00456
00457 DPRINTF("Walking directory: %s", rootDir);
00458
00459 SetString all;
00460
00461
00462 DIR * dir = opendir(rootDir);
00463 THROW(dir , "Failed to open directory: " << rootDir);
00464 while (true) {
00465 dirent * entry = readdir(dir);
00466 if (!entry) {
00467 DPRINTF(" end of directory!");
00468 break;
00469 }
00470 if ('.' == entry->d_name[0]) {
00471 continue;
00472 }
00473 all.insert(entry->d_name);
00474 }
00475 closedir(dir);
00476
00477
00478 VecString children;
00479 for (SetString::iterator i = all.begin(); i != all.end(); ++i) {
00480 const char * name = i->c_str();
00481
00482 std::string full_path = rootDir;
00483 full_path += s_separator;
00484 full_path += name;
00485
00486 DPRINTF(" Examining %s", full_path.c_str());
00487
00488
00489 stat_t sb;
00490 if (!stat(full_path.c_str(), &sb)) {
00491 if (S_IFDIR & sb.st_mode) {
00492
00493 children.push_back(name);
00494 } else if (matchesExtension(name, matchExt)) {
00495
00496 DPRINTF(" File! %s", name);
00497 paths.push_back(name);
00498 }
00499 }
00500 }
00501
00502
00503 for (VecString::const_iterator i = children.begin();
00504 i != children.end(); ++i) {
00505 const char * name = i->c_str();
00506
00507 std::string newRoot = rootDir;
00508 newRoot += s_separator;
00509 newRoot += name;
00510
00511 VecString subEntries;
00512 walkDirectoryTree(newRoot.c_str(), matchExt, subEntries);
00513
00514
00515 for (VecString::const_iterator j = subEntries.begin();
00516 j != subEntries.end(); ++j) {
00517 const char * subName = j->c_str();
00518
00519 std::string relPath = name;
00520 relPath += s_separator;
00521 relPath += subName;
00522
00523 DPRINTF(" Adding sub-entry: %s", relPath.c_str());
00524 paths.push_back(relPath.c_str());
00525 }
00526 }
00527 }
00528
00529
00530
00531 std::string
00532 getPathRelativeTo
00533 (
00534 IN const char * startFile,
00535 IN const char * relPath
00536 )
00537 {
00538 ASSERT(startFile, "null");
00539 ASSERT(relPath, "null");
00540
00541 std::string path;
00542 if (*startFile) {
00543 GetParentDirectory(startFile, path);
00544 }
00545 if (path.length() > 0) {
00546 path += s_separator;
00547 }
00548 path += relPath;
00549
00550 return path;
00551 }
00552
00553
00554
00555 void
00556 appendPath
00557 (
00558 IN const char * parentDirectory,
00559 IN const char * nextPath,
00560 OUT std::string& path
00561 )
00562 {
00563 ASSERT(parentDirectory, "null");
00564 ASSERT(nextPath, "null");
00565
00566 path = parentDirectory;
00567
00568
00569 int len = strlen(parentDirectory);
00570 if (len > 0 &&
00571 s_separator != parentDirectory[len - 1] &&
00572 nextPath[0] &&
00573 s_separator != nextPath[0]) {
00574 path += s_separator;
00575 }
00576 path += nextPath;
00577 }
00578
00579
00580
00581 #ifdef WIN32
00582
00583 DIR *
00584 opendir
00585 (
00586 IN const char * path
00587 )
00588 {
00589 ASSERT(path, "null");
00590
00591 DIR * pdir = new DIR;
00592 ASSERT(pdir, "out of memory");
00593 pdir->path = path;
00594 ASSERT(!pdir->h, "should be null");
00595
00596 return pdir;
00597 }
00598
00599
00600
00601 struct dirent *
00602 readdir
00603 (
00604 IO DIR * dir
00605 )
00606 {
00607 ASSERT(dir, "null");
00608
00609
00610 static dirent s_d;
00611 WIN32_FIND_DATA wfd;
00612 if (!dir->h) {
00613
00614 std::string search = dir->path;
00615 search += "\\*";
00616 dir->h = FindFirstFile(search.c_str(), &wfd);
00617 if (INVALID_HANDLE_VALUE == dir->h ||
00618 ERROR_FILE_NOT_FOUND == (long) dir->h) {
00619 DPRINTF("Failed to find first file: %s",
00620 search.c_str());
00621 return NULL;
00622 }
00623 strncpy(s_d.d_name, wfd.cFileName, MAX_PATH);
00624 return &s_d;
00625 } else {
00626
00627 int retval = FindNextFile(dir->h, &wfd);
00628 if (!retval || ERROR_NO_MORE_FILES == retval) {
00629 return NULL;
00630 }
00631 strncpy(s_d.d_name, wfd.cFileName, MAX_PATH);
00632 return &s_d;
00633 }
00634 }
00635
00636
00637
00638 int
00639 closedir
00640 (
00641 IN DIR * dir
00642 )
00643 {
00644 ASSERT(dir, "null");
00645
00646 if (dir->h) {
00647 FindClose(dir->h);
00648 }
00649 delete dir;
00650 return 0;
00651 }
00652
00653
00654
00655 #endif // WIN32