|
Isis 3.0 Object Programmers' Reference |
Home |
00001 00023 #include <cstdlib> 00024 #include <fstream> 00025 #include <iostream> 00026 00027 #include "Preference.h" 00028 #include "iString.h" 00029 #include "iException.h" 00030 #include "Filename.h" 00031 00032 using namespace std; 00033 namespace Isis { 00034 00036 Filename::Filename () { 00037 p_original.clear(); 00038 } 00039 00046 Filename::Filename (const std::string &file) 00047 : QFileInfo () { 00048 p_original = file; 00049 QFileInfo::setFile ((iString)Expand (file)); 00050 } 00051 00062 Filename::Filename (const std::string &name, const std::string &extension) { 00063 Temporary (name, extension); 00064 } 00065 00067 Filename::~Filename () {} 00068 00075 void Filename::operator=(const std::string &file) { 00076 p_original = file; 00077 QFileInfo::setFile ((iString)Expand (file)); 00078 } 00079 00086 void Filename::operator=(const char *file) { 00087 p_original = file; 00088 QFileInfo::setFile ((iString)Expand (file)); 00089 } 00090 00104 std::string Filename::Path() const { 00105 return QFileInfo::absolutePath().toStdString(); 00106 } 00107 00116 std::string Filename::Basename() const { 00117 if (QFileInfo::suffix().length() == 0) { 00118 return QFileInfo::baseName().toStdString(); 00119 } 00120 else { 00121 return QFileInfo::completeBaseName().toStdString(); 00122 } 00123 } 00124 00131 std::string Filename::Name() const { 00132 return QFileInfo::fileName().toStdString(); 00133 } 00134 00140 std::string Filename::Extension () const { 00141 return QFileInfo::suffix().toStdString(); 00142 } 00143 00151 std::string Filename::Expanded () const { 00152 return QFileInfo::absoluteFilePath().toStdString(); 00153 } 00154 00160 bool Filename::Exists () { 00161 return QFileInfo::exists(); 00162 } 00163 00167 std::string Filename::OriginalPath() const { 00168 QFileInfo fi(p_original.c_str()); 00169 return fi.path().toStdString(); 00170 } 00171 00182 void Filename::AddExtension (const std::string &ext) { 00183 // Don't modify the extension if it is already there 00184 if (Extension() == ext) return; 00185 00186 // Add the argument as an extension to the current filename 00187 if (ext.length() > 0) { 00188 QFileInfo::setFile (iString(Expanded() + "." + ext)); 00189 } 00190 } 00191 00195 void Filename::RemoveExtension () { 00196 QFileInfo::setFile (iString(this->Path() + "/" + this->Basename())); 00197 } 00198 00211 void Filename::HighestVersion (){ 00212 00213 CheckVersion(); 00214 00215 int highestVersion = -1; 00216 Isis::iString highestVersionStr; 00217 00218 // Get the path of the current file and make sure it exists 00219 QDir dir((QString)(iString)Path()); 00220 if (!dir.exists()) { 00221 string msg = "The path [" + Path() + "] does not exist"; 00222 throw Isis::iException::Message(Isis::iException::Io,msg, _FILEINFO_); 00223 } 00224 00225 // Find the beginning and end of the "?"s in the versioned filename 00226 unsigned int start = Name().find_first_of("?"); 00227 unsigned int end = Name().find_last_of("?"); 00228 unsigned int charsAfterVersion = Name().length() - end - 1; 00229 00230 00231 // Loop through all files in the dir and see if they match our name 00232 for (unsigned int indx=0; indx < dir.count(); indx++) { 00233 00234 string file = dir[indx].toStdString(); 00235 bool leftSide = file.substr(0, start) == Name().substr(0, start); 00236 bool rightSide = ((int)file.length()-(int)charsAfterVersion) >= 0; 00237 if (rightSide) { 00238 rightSide = rightSide && 00239 (file.substr(file.length()-charsAfterVersion) == Name().substr(end+1)); 00240 } 00241 00242 if (leftSide && rightSide) { 00243 00244 Isis::iString version = file.substr(start, file.length()-charsAfterVersion-start); 00245 00246 if ((version.length() > 0) && 00247 (version.find_first_not_of("0123456789") == string::npos) && 00248 (version.ToInteger() > highestVersion)) { 00249 highestVersion = version.ToInteger(); 00250 highestVersionStr = version; 00251 } 00252 } 00253 } 00254 00255 // Make sure we got a version number 00256 if (highestVersion == -1) { 00257 string msg = "No versions available for file [" + Expanded() + "]"; 00258 throw Isis::iException::Message(Isis::iException::Programmer,msg, _FILEINFO_); 00259 } 00260 00261 string temp = Path() + "/" + Name().substr(0, start) + 00262 highestVersionStr + Name().substr(end+1); 00263 QFileInfo::setFile(temp.c_str()); 00264 } 00265 00281 void Filename::NewVersion (){ 00282 00283 CheckVersion(); 00284 00285 // Get the path of the current file and make sure it exists 00286 QDir dir((QString)(iString)Path()); 00287 if (!dir.exists()) { 00288 string msg = "The path [" + Path() + "] does not exist"; 00289 throw Isis::iException::Message(Isis::iException::Io,msg, _FILEINFO_); 00290 } 00291 00292 // Find the beginning and end of the "?"s in the versioned filename 00293 unsigned int start = Name().find_first_of("?"); 00294 unsigned int end = Name().find_last_of("?"); 00295 unsigned int charsAfterVersion = Name().length() - end - 1; 00296 00297 int highestVersion = 0; 00298 // Loop through all files in the dir and see if they match our name 00299 for (unsigned int indx=0; indx < dir.count(); indx++) { 00300 00301 string file = dir[indx].toStdString(); 00302 bool leftSide = file.substr(0, start) == Name().substr(0, start); 00303 bool rightSide = ((int)file.length()-(int)charsAfterVersion) >= 0; 00304 if (rightSide) { 00305 rightSide = rightSide && 00306 (file.substr(file.length()-charsAfterVersion) == Name().substr(end+1)); 00307 } 00308 00309 if (leftSide && rightSide) { 00310 00311 Isis::iString version = file.substr(start, file.length()-charsAfterVersion-start); 00312 00313 if ((version.length() > 0) && 00314 (version.find_first_not_of("0123456789") == string::npos) && 00315 (version.ToInteger() > highestVersion)) { 00316 highestVersion = version.ToInteger(); 00317 } 00318 } 00319 } 00320 //create a string with the new version number 00321 Isis::iString newVersion = ++highestVersion; 00322 00323 00324 00325 //pad each extra "?" with a 0. This maintains the length of the Filename 00326 //so that "file.???.ext" will be "file.001.ext" instead of "file.1.ext" 00327 int zeroesNeeded = end - start - newVersion.length(); 00328 for (int i = 0 ; i <= zeroesNeeded; i++){ 00329 newVersion = "0" + newVersion; 00330 } 00331 00332 string temp = Path() + "/" + Name().substr(0, start) + 00333 newVersion + Name().substr(end+1); 00334 QFileInfo::setFile(temp.c_str()); 00335 } 00336 00342 void Filename::MakeDirectory() { 00343 00344 QDir dir; 00345 if (!dir.mkdir(iString(Expanded()))) { 00346 string msg = "Unable to create directory [" + Expanded() + "]"; 00347 throw Isis::iException::Message(Isis::iException::Programmer, 00348 msg, _FILEINFO_); 00349 } 00350 00351 } 00352 00367 void Filename::Temporary (const std::string &name, const std::string &extension) { 00368 string tempDir; 00369 tempDir.clear(); 00370 // If the IsisPreference exists use it otherwise just use name as is 00371 if (!(name.at(0)=='/') && Isis::Preference::Preferences().HasGroup("DataDirectory")) { 00372 Isis::PvlGroup &dataDir = Isis::Preference::Preferences().FindGroup("DataDirectory"); 00373 if (dataDir.HasKeyword("Temporary")) { 00374 tempDir = (string) dataDir["Temporary"]; 00375 } 00376 } 00377 00378 // Start off by appending "100000" to the name if that file exists 00379 // increment it and try again 00380 int add = 100000; 00381 string tfile; 00382 00383 do { 00384 Isis::iString num(add); 00385 tfile = tempDir + "/" + name + num + "." + extension; 00386 QFileInfo f(tfile.c_str()); 00387 if (f.exists()) { 00388 add++; 00389 } 00390 else { 00391 p_original = tfile; 00392 QFileInfo::setFile (tfile.c_str()); 00393 return; 00394 } 00395 } while (add < 1000000); 00396 00397 string msg = "No temporary files available for [" + name + extension + "]"; 00398 throw Isis::iException::Message(Isis::iException::Io,msg,_FILEINFO_); 00399 00400 } 00401 00410 string Filename::Expand (const std::string &file) { 00411 00412 // Setup an index for searching strings 00413 std::string::size_type pos, pos2; 00414 00415 // Work with a tempory copy 00416 string temp = file; 00417 00418 // Strip off any cube attributes 00419 if ((pos = temp.find("+")) != std::string::npos) temp.erase(pos); 00420 00421 00422 // Expand any $xxxxx into ISIS preferences and environment variables 00423 // *** NOTE *** This may be very operating system dependent 00424 string prefVar; 00425 string var; 00426 pos = 0; 00427 00428 // Loop while there are any "$" at the current position or after 00429 // Some "$" might be skipped if no translation can be found 00430 while ((pos = temp.find("$", pos)) != std::string::npos) { 00431 pos2 = temp.find ("/", pos); 00432 var = temp.substr(pos+1, pos2-pos-1); 00433 string value; 00434 value.clear(); 00435 00436 // Find the corresponding Isis Preference if one exists 00437 if (Isis::Preference::Preferences().HasGroup("DataDirectory")) { 00438 Isis::PvlGroup &dataDir = Isis::Preference::Preferences().FindGroup("DataDirectory"); 00439 if (dataDir.HasKeyword(var)) { 00440 value = (string) dataDir[var]; 00441 } 00442 } 00443 00444 // Find the corresponding environment variable if one exists 00445 if (value.length() == 0) { 00446 char *val; 00447 val = getenv(var.c_str()); 00448 if (val != NULL) value = val; 00449 } 00450 00451 // Replace the $xxxx with the pref/env, but don't move 00452 // the pointer. We may have replaced one $ for another. 00453 // Note: May need to put a test for circular replaces in here 00454 if (value.length() > 0) { 00455 temp.replace (pos, pos2-pos, value); 00456 } 00457 // No pref or env was available so ignore this "$" and move on 00458 else { 00459 pos++; 00460 } 00461 } 00462 return temp; 00463 } 00464 00472 void Filename::CheckVersion () const { 00473 00474 // Find the series of "?" 00475 string name = Expanded(); 00476 00477 std::string::size_type start = name.find_first_of("?"); 00478 std::string::size_type end = name.find_last_of("?"); 00479 00480 // Make sure there was at least one "?" for a version number 00481 if (start == string::npos || end == string::npos) { 00482 string msg = "Filename [" + Expanded() + 00483 "] does not contain a version sequence"; 00484 throw Isis::iException::Message(Isis::iException::Programmer,msg, _FILEINFO_); 00485 } 00486 00487 // Make sure all chars between start and end are "?" 00488 for (unsigned int pos=start; pos<=end; ++pos) { 00489 if (name[pos] != '?') { 00490 string msg = "Only one version sequence is allowed per filename [" + 00491 Expanded() + "]"; 00492 throw Isis::iException::Message(Isis::iException::Programmer,msg, _FILEINFO_); 00493 } 00494 } 00495 } 00496 } // end namespace Isis