00001 // Filename: filename.I 00002 // Created by: drose (18Jan99) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved 00008 // 00009 // All use of this software is subject to the terms of the Panda 3d 00010 // Software license. You should have received a copy of this license 00011 // along with this source code; you will also find a current copy of 00012 // the license at http://www.panda3d.org/license.txt . 00013 // 00014 // To contact the maintainers of this program write to 00015 // panda3d@yahoogroups.com . 00016 // 00017 //////////////////////////////////////////////////////////////////// 00018 00019 //////////////////////////////////////////////////////////////////// 00020 // Function: Filename::Constructor 00021 // Access: Public 00022 // Description: 00023 //////////////////////////////////////////////////////////////////// 00024 INLINE Filename:: 00025 Filename(const string &filename) { 00026 (*this) = filename; 00027 _flags = 0; 00028 } 00029 00030 //////////////////////////////////////////////////////////////////// 00031 // Function: Filename::Constructor 00032 // Access: Public 00033 // Description: 00034 //////////////////////////////////////////////////////////////////// 00035 INLINE Filename:: 00036 Filename(const char *filename) { 00037 (*this) = filename; 00038 _flags = 0; 00039 } 00040 00041 00042 //////////////////////////////////////////////////////////////////// 00043 // Function: Filename::Copy Constructor 00044 // Access: Public 00045 // Description: 00046 //////////////////////////////////////////////////////////////////// 00047 INLINE Filename:: 00048 Filename(const Filename ©) 00049 : _filename(copy._filename), 00050 _dirname_end(copy._dirname_end), 00051 _basename_start(copy._basename_start), 00052 _basename_end(copy._basename_end), 00053 _extension_start(copy._extension_start), 00054 _flags(copy._flags) 00055 { 00056 } 00057 00058 //////////////////////////////////////////////////////////////////// 00059 // Function: Filename::text_filename named constructor 00060 // Access: Public 00061 // Description: 00062 //////////////////////////////////////////////////////////////////// 00063 INLINE Filename Filename:: 00064 text_filename(const string &filename) { 00065 Filename result(filename); 00066 result.set_text(); 00067 return result; 00068 } 00069 00070 //////////////////////////////////////////////////////////////////// 00071 // Function: Filename::binary_filename named constructor 00072 // Access: Public 00073 // Description: 00074 //////////////////////////////////////////////////////////////////// 00075 INLINE Filename Filename:: 00076 binary_filename(const string &filename) { 00077 Filename result(filename); 00078 result.set_binary(); 00079 return result; 00080 } 00081 00082 //////////////////////////////////////////////////////////////////// 00083 // Function: Filename::dso_filename named constructor 00084 // Access: Public 00085 // Description: 00086 //////////////////////////////////////////////////////////////////// 00087 INLINE Filename Filename:: 00088 dso_filename(const string &filename) { 00089 Filename result(filename); 00090 result.set_type(T_dso); 00091 return result; 00092 } 00093 00094 //////////////////////////////////////////////////////////////////// 00095 // Function: Filename::executable_filename named constructor 00096 // Access: Public 00097 // Description: 00098 //////////////////////////////////////////////////////////////////// 00099 INLINE Filename Filename:: 00100 executable_filename(const string &filename) { 00101 Filename result(filename); 00102 result.set_type(T_executable); 00103 return result; 00104 } 00105 00106 //////////////////////////////////////////////////////////////////// 00107 // Function: Filename::Destructor 00108 // Access: Public 00109 // Description: 00110 //////////////////////////////////////////////////////////////////// 00111 INLINE Filename:: 00112 ~Filename() { 00113 } 00114 00115 00116 //////////////////////////////////////////////////////////////////// 00117 // Function: Filename::Assignment operator 00118 // Access: Public 00119 // Description: 00120 //////////////////////////////////////////////////////////////////// 00121 INLINE Filename &Filename:: 00122 operator = (const string &filename) { 00123 _filename = filename; 00124 00125 locate_basename(); 00126 locate_extension(); 00127 return *this; 00128 } 00129 00130 //////////////////////////////////////////////////////////////////// 00131 // Function: Filename::Assignment operator 00132 // Access: Public 00133 // Description: 00134 //////////////////////////////////////////////////////////////////// 00135 INLINE Filename &Filename:: 00136 operator = (const char *filename) { 00137 assert(filename != NULL); 00138 return (*this) = string(filename); 00139 } 00140 00141 //////////////////////////////////////////////////////////////////// 00142 // Function: Filename::Copy assignment operator 00143 // Access: Public 00144 // Description: 00145 //////////////////////////////////////////////////////////////////// 00146 INLINE Filename &Filename:: 00147 operator = (const Filename ©) { 00148 _filename = copy._filename; 00149 _dirname_end = copy._dirname_end; 00150 _basename_start = copy._basename_start; 00151 _basename_end = copy._basename_end; 00152 _extension_start = copy._extension_start; 00153 _flags = copy._flags; 00154 return *this; 00155 } 00156 00157 00158 //////////////////////////////////////////////////////////////////// 00159 // Function: Filename::string typecast operator 00160 // Access: Public 00161 // Description: 00162 //////////////////////////////////////////////////////////////////// 00163 INLINE Filename:: 00164 operator const string & () const { 00165 return _filename; 00166 } 00167 00168 //////////////////////////////////////////////////////////////////// 00169 // Function: Filename::c_str 00170 // Access: Public 00171 // Description: 00172 //////////////////////////////////////////////////////////////////// 00173 INLINE const char *Filename:: 00174 c_str() const { 00175 return _filename.c_str(); 00176 } 00177 00178 //////////////////////////////////////////////////////////////////// 00179 // Function: Filename::empty 00180 // Access: Public 00181 // Description: 00182 //////////////////////////////////////////////////////////////////// 00183 INLINE bool Filename:: 00184 empty() const { 00185 return _filename.empty(); 00186 } 00187 00188 //////////////////////////////////////////////////////////////////// 00189 // Function: Filename::length 00190 // Access: Public 00191 // Description: 00192 //////////////////////////////////////////////////////////////////// 00193 INLINE size_t Filename:: 00194 length() const { 00195 return _filename.length(); 00196 } 00197 00198 //////////////////////////////////////////////////////////////////// 00199 // Function: Filename::Indexing operator 00200 // Access: Public 00201 // Description: 00202 //////////////////////////////////////////////////////////////////// 00203 INLINE char Filename:: 00204 operator [] (int n) const { 00205 assert(n >= 0 && n < (int)_filename.length()); 00206 return _filename[n]; 00207 } 00208 00209 00210 //////////////////////////////////////////////////////////////////// 00211 // Function: Filename::get_fullpath 00212 // Access: Public 00213 // Description: Returns the entire filename: directory, basename, 00214 // extension. This is the same thing returned by the 00215 // string typecast operator, so this function is a 00216 // little redundant. 00217 //////////////////////////////////////////////////////////////////// 00218 INLINE string Filename:: 00219 get_fullpath() const { 00220 return _filename; 00221 } 00222 00223 //////////////////////////////////////////////////////////////////// 00224 // Function: Filename::get_dirname 00225 // Access: Public 00226 // Description: Returns the directory part of the filename. This is 00227 // everything in the filename up to, but not including 00228 // the rightmost slash. 00229 //////////////////////////////////////////////////////////////////// 00230 INLINE string Filename:: 00231 get_dirname() const { 00232 return _filename.substr(0, _dirname_end); 00233 } 00234 00235 //////////////////////////////////////////////////////////////////// 00236 // Function: Filename::get_basename 00237 // Access: Public 00238 // Description: Returns the basename part of the filename. This is 00239 // everything in the filename after the rightmost slash, 00240 // including any extensions. 00241 //////////////////////////////////////////////////////////////////// 00242 INLINE string Filename:: 00243 get_basename() const { 00244 return _filename.substr(_basename_start); 00245 } 00246 00247 00248 //////////////////////////////////////////////////////////////////// 00249 // Function: Filename::get_fullpath_wo_extension 00250 // Access: Public 00251 // Description: Returns the full filename--directory and basename 00252 // parts--except for the extension. 00253 //////////////////////////////////////////////////////////////////// 00254 INLINE string Filename:: 00255 get_fullpath_wo_extension() const { 00256 return _filename.substr(0, _basename_end); 00257 } 00258 00259 00260 //////////////////////////////////////////////////////////////////// 00261 // Function: Filename::get_basename_wo_extension 00262 // Access: Public 00263 // Description: Returns the basename part of the filename, without 00264 // the file extension. 00265 //////////////////////////////////////////////////////////////////// 00266 INLINE string Filename:: 00267 get_basename_wo_extension() const { 00268 if (_basename_end == string::npos) { 00269 return _filename.substr(_basename_start); 00270 } else { 00271 return _filename.substr(_basename_start, _basename_end - _basename_start); 00272 } 00273 } 00274 00275 00276 //////////////////////////////////////////////////////////////////// 00277 // Function: Filename::get_extension 00278 // Access: Public 00279 // Description: Returns the file extension. This is everything after 00280 // the rightmost dot, if there is one, or the empty 00281 // string if there is not. 00282 //////////////////////////////////////////////////////////////////// 00283 INLINE string Filename:: 00284 get_extension() const { 00285 if (_extension_start == string::npos) { 00286 return string(); 00287 } else { 00288 return _filename.substr(_extension_start); 00289 } 00290 } 00291 00292 //////////////////////////////////////////////////////////////////// 00293 // Function: Filename::set_binary 00294 // Access: Public 00295 // Description: Indicates that the filename represents a binary file. 00296 // This is primarily relevant to the read_file() and 00297 // write_file() methods, so they can set the appropriate 00298 // flags to the OS. 00299 //////////////////////////////////////////////////////////////////// 00300 INLINE void Filename:: 00301 set_binary() { 00302 _flags = (_flags & ~F_text) | F_binary; 00303 } 00304 00305 //////////////////////////////////////////////////////////////////// 00306 // Function: Filename::set_text 00307 // Access: Public 00308 // Description: Indicates that the filename represents a text file. 00309 // This is primarily relevant to the read_file() and 00310 // write_file() methods, so they can set the appropriate 00311 // flags to the OS. 00312 //////////////////////////////////////////////////////////////////// 00313 INLINE void Filename:: 00314 set_text() { 00315 _flags = (_flags & ~F_binary) | F_text; 00316 } 00317 00318 //////////////////////////////////////////////////////////////////// 00319 // Function: Filename::is_binary 00320 // Access: Public 00321 // Description: Returns true if the Filename has been indicated to 00322 // represent a binary file via a previous call to 00323 // set_binary(). It is possible that neither 00324 // is_binary() nor is_text() will be true, if neither 00325 // set_binary() nor set_text() was ever called. 00326 //////////////////////////////////////////////////////////////////// 00327 INLINE bool Filename:: 00328 is_binary() const { 00329 return ((_flags & F_binary) != 0); 00330 } 00331 00332 //////////////////////////////////////////////////////////////////// 00333 // Function: Filename::is_text 00334 // Access: Public 00335 // Description: Returns true if the Filename has been indicated to 00336 // represent a text file via a previous call to 00337 // set_text(). It is possible that neither is_binary() 00338 // nor is_text() will be true, if neither set_binary() 00339 // nor set_text() was ever called. 00340 //////////////////////////////////////////////////////////////////// 00341 INLINE bool Filename:: 00342 is_text() const { 00343 return ((_flags & F_text) != 0); 00344 } 00345 00346 //////////////////////////////////////////////////////////////////// 00347 // Function: Filename::set_type 00348 // Access: Public 00349 // Description: Sets the type of the file represented by the 00350 // filename. This is useful for to_os_specific(), 00351 // resolve_filename(), test_existence(), and all such 00352 // real-world access functions. It helps the Filename 00353 // know how to map the internal filename to the 00354 // OS-specific filename (for instance, maybe executables 00355 // should have an .exe extension). 00356 //////////////////////////////////////////////////////////////////// 00357 INLINE void Filename:: 00358 set_type(Filename::Type type) { 00359 _flags = (_flags & ~F_type) | type; 00360 switch (type) { 00361 case T_dso: 00362 case T_executable: 00363 set_binary(); 00364 00365 case T_general: 00366 break; 00367 } 00368 } 00369 00370 //////////////////////////////////////////////////////////////////// 00371 // Function: Filename::get_type 00372 // Access: Public 00373 // Description: Returns the type of the file represented by the 00374 // filename, as previously set by set_type(). 00375 //////////////////////////////////////////////////////////////////// 00376 INLINE Filename::Type Filename:: 00377 get_type() const { 00378 return (Type)(_flags & (int)F_type); 00379 } 00380 00381 //////////////////////////////////////////////////////////////////// 00382 // Function: Filename::is_local 00383 // Access: Public 00384 // Description: Returns true if the filename is local, e.g. does not 00385 // begin with a slash, or false if the filename is fully 00386 // specified from the root. 00387 //////////////////////////////////////////////////////////////////// 00388 INLINE bool Filename:: 00389 is_local() const { 00390 return _filename.empty() || _filename[0] != '/'; 00391 } 00392 00393 //////////////////////////////////////////////////////////////////// 00394 // Function: Filename::is_fully_qualified 00395 // Access: Public 00396 // Description: Returns true if the filename is fully qualified, 00397 // e.g. begins with a slash. This is almost, but not 00398 // quite, the same thing as !is_local(). It's not 00399 // exactly the same because a special case is made for 00400 // filenames that begin with a single dot followed by a 00401 // slash--these are considered to be fully qualified 00402 // (they are explicitly relative to the current 00403 // directory, and do not refer to a filename on a search 00404 // path somewhere). 00405 //////////////////////////////////////////////////////////////////// 00406 INLINE bool Filename:: 00407 is_fully_qualified() const { 00408 return 00409 (_filename.size() > 2 && _filename[0] == '.' && _filename[1] == '/') || 00410 (!_filename.empty() && _filename[0] == '/'); 00411 } 00412 00413 //////////////////////////////////////////////////////////////////// 00414 // Function: Filename::Equality operator 00415 // Access: Public 00416 // Description: 00417 //////////////////////////////////////////////////////////////////// 00418 INLINE bool Filename:: 00419 operator == (const string &other) const { 00420 return (*(string *)this) == other; 00421 } 00422 00423 //////////////////////////////////////////////////////////////////// 00424 // Function: Filename::Inequality operator 00425 // Access: Public 00426 // Description: 00427 //////////////////////////////////////////////////////////////////// 00428 INLINE bool Filename:: 00429 operator != (const string &other) const { 00430 return (*(string *)this) != other; 00431 } 00432 00433 //////////////////////////////////////////////////////////////////// 00434 // Function: Filename::Ordering operator 00435 // Access: Public 00436 // Description: 00437 //////////////////////////////////////////////////////////////////// 00438 INLINE bool Filename:: 00439 operator < (const string &other) const { 00440 return (*(string *)this) < other; 00441 } 00442 00443 00444 //////////////////////////////////////////////////////////////////// 00445 // Function: Filename::output 00446 // Access: Public 00447 // Description: 00448 //////////////////////////////////////////////////////////////////// 00449 INLINE void Filename:: 00450 output(ostream &out) const { 00451 out << _filename; 00452 }