00001 /* 00002 File: FileName.cc 00003 00004 Function: Implements FileName.h 00005 00006 Author: Andrew Willmott 00007 00008 Notes: 00009 */ 00010 00011 #include "cl/FileName.h" 00012 #include "cl/CLConfig.h" 00013 #include <stdio.h> 00014 #include <sys/stat.h> 00015 #include <stdlib.h> 00016 #include <unistd.h> 00017 00018 Void FileName::RemoveExtension() 00019 { 00020 Int dotPos; 00021 00022 dotPos = name.FindCharLast('.'); 00023 00024 if (dotPos >= 0) 00025 { 00026 extension = name.Suffix(-1 - dotPos); 00027 name = name.Prefix(dotPos); 00028 } 00029 else 00030 extension = ""; 00031 } 00032 00033 Void FileName::AddExtension(StrConst ext) 00034 { 00035 name = name + "." + extension; 00036 extension = ext; 00037 } 00038 00039 String FileName::GetPath() const 00040 { 00041 String result; 00042 00043 #ifdef CL_MACOS 00044 result.Printf("%s.%s", name.CString(), extension.CString()); 00045 #else 00046 if (extension == "") 00047 result.Printf("%s/%s", path.CString(), name.CString()); 00048 else 00049 result.Printf("%s/%s.%s", path.CString(), name.CString(), extension.CString()); 00050 #endif 00051 00052 return(result); 00053 } 00054 00055 FileName &FileName::SetPath(StrConst filePath) 00056 { 00057 Int slashPos; 00058 TempString thePath = SubstituteEnvVars(filePath); 00059 00060 slashPos = thePath.FindCharLast('/'); 00061 00062 if (slashPos >= 0) 00063 { 00064 path = thePath.Prefix(slashPos); 00065 name = thePath.Suffix(-1 - slashPos); 00066 } 00067 else 00068 { 00069 path = "."; 00070 name = thePath; 00071 } 00072 00073 RemoveExtension(); 00074 00075 return(SELF); 00076 } 00077 00078 FileName &FileName::SetRelPath(StrConst filePath) 00079 { 00080 Int slashPos; 00081 TempString thePath = SubstituteEnvVars(filePath); 00082 00083 if (thePath[0] == '/') 00084 // absolute path 00085 return(SetPath(filePath)); 00086 00087 slashPos = thePath.FindCharLast('/'); 00088 00089 if (slashPos >= 0) 00090 { 00091 path = path + "/" + thePath.Prefix(slashPos); 00092 name = thePath.Suffix(-(slashPos + 1)); 00093 } 00094 else 00095 name = thePath; 00096 00097 RemoveExtension(); 00098 00099 return(SELF); 00100 } 00101 00102 Bool FileName::Exists() const 00103 { 00104 return(access(GetPath().CString(), F_OK) == 0); 00105 } 00106 00107 Bool FileName::IsReadable() const 00108 { 00109 return(access(GetPath().CString(), R_OK) == 0); 00110 } 00111 00112 Bool FileName::IsWritable() const 00113 { 00114 return(access(GetPath().CString(), W_OK) == 0); 00115 } 00116 00117 Long FileName::GetTimeStamp() const 00118 { 00119 struct stat statInfo; 00120 00121 stat(GetPath().CString(), &statInfo); 00122 00123 return(statInfo.st_mtime); 00124 } 00125 00126 String TempPath() 00127 { 00128 String result = SubstituteEnvVars("$TMPDIR"); 00129 00130 if (result[0] == '<') 00131 result = "/tmp"; 00132 00133 return(result); 00134 } 00135 00136 StrConst tCompressExtensions[] = 00137 { 00138 "gz", 00139 "bz2", 00140 "Z", 00141 0 00142 }; 00143 00144 00145 Int FileName::FindFileExtension(StrConst extensions[], Bool allowCompressed) 00162 { 00163 Int i, j; 00164 Bool extWasSet; 00165 00166 flags.Clear(); 00167 00168 extWasSet = (extension != ""); 00169 00170 if (extWasSet) 00171 // an extension is already set -- at most we might have to 00172 // tack on a compression suffix. 00173 { 00174 // remove any compression suffix 00175 if (allowCompressed) 00176 for (j = 0; !tCompressExtensions[j].IsNull(); j++) 00177 if (extension == tCompressExtensions[j]) 00178 { 00179 if (IsReadable()) 00180 flags.Set(1 << j); 00181 RemoveExtension(); 00182 break; 00183 } 00184 00185 // check that the extension is valid 00186 for (i = 0; !extensions[i].IsNull(); i++) 00187 if (extension == extensions[i]) 00188 break; 00189 00190 if (extensions[i].IsNull()) 00191 return(kBadExtension); 00192 00193 if (flags.IsSet(FN_IsCompressed) || IsReadable()) 00194 return(i); 00195 else 00196 { 00197 if (allowCompressed) 00198 // try it with a compression extension 00199 { 00200 AddExtension(""); 00201 00202 for (j = 0; !tCompressExtensions[j].IsNull(); j++) 00203 { 00204 SetExtension(tCompressExtensions[j]); 00205 00206 if (IsReadable()) 00207 { 00208 RemoveExtension(); 00209 flags.Set(1 << j); 00210 00211 return(i); 00212 } 00213 } 00214 00215 RemoveExtension(); 00216 } 00217 00218 return(kFileNotFound); 00219 } 00220 } 00221 00222 // try all possible extensions and compressions 00223 for (i = 0; !extensions[i].IsNull(); i++) 00224 { 00225 SetExtension(extensions[i]); 00226 00227 if (IsReadable()) 00228 return(i); 00229 00230 // try it with a compression extension 00231 if (allowCompressed) 00232 { 00233 AddExtension(""); 00234 00235 for (j = 0; !tCompressExtensions[j].IsNull(); j++) 00236 { 00237 SetExtension(tCompressExtensions[j]); 00238 00239 if (IsReadable()) 00240 { 00241 RemoveExtension(); 00242 flags.Set(1 << j); 00243 00244 return(i); 00245 } 00246 } 00247 00248 RemoveExtension(); 00249 } 00250 } 00251 00252 SetExtension(""); 00253 00254 return(kFileNotFound); 00255 } 00256 00257 FileName &FileName::MakeUnique() 00258 { 00259 if (Exists()) 00260 { 00261 String origName = name; 00262 Int i = 0; 00263 00264 do 00265 { 00266 i++; 00267 name.Printf("%s-%d", origName.CString(), i); 00268 } 00269 while (Exists()); 00270 } 00271 00272 return(SELF); 00273 } 00274 00275 Void FileName::AddCompExt() 00276 { 00277 if (flags.IsSet(FN_Gzipped)) 00278 AddExtension("gz"); 00279 else if (flags.IsSet(FN_Bz2ed)) 00280 AddExtension("bz2"); 00281 else if (flags.IsSet(FN_Compress)) 00282 AddExtension("Z"); 00283 } 00284 00285 Int FileName::DecompressSetup() 00286 { 00287 if (flags.IsSet(FN_IsCompressed)) 00288 { 00289 String origFile; 00290 StrConst cmd; 00291 Int err; 00292 00293 AddCompExt(); 00294 origFile = GetPath(); 00295 RemoveExtension(); 00296 SetDir(TempPath()); 00297 00298 if (flags.IsSet(FN_Gzipped)) 00299 cmd = "gunzip -c"; 00300 else if (flags.IsSet(FN_Bz2ed)) 00301 cmd = "bunzip2 -c"; 00302 else if (flags.IsSet(FN_Compress)) 00303 cmd = "compress -c"; 00304 00305 if (system(cmd + " " + origFile + " > " + GetPath()) != 0) 00306 return(-1); 00307 } 00308 00309 return(0); 00310 } 00311 00312 Void FileName::DecompressCleanup() 00313 { 00314 if (flags.IsSet(FN_IsCompressed)) 00315 unlink(GetPath()); 00316 }