filename.I 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559
  1. // Filename: filename.I
  2. // Created by: drose (18Jan99)
  3. //
  4. ////////////////////////////////////////////////////////////////////
  5. //
  6. // PANDA 3D SOFTWARE
  7. // Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
  8. //
  9. // All use of this software is subject to the terms of the Panda 3d
  10. // Software license. You should have received a copy of this license
  11. // along with this source code; you will also find a current copy of
  12. // the license at http://etc.cmu.edu/panda3d/docs/license/ .
  13. //
  14. // To contact the maintainers of this program write to
  15. // [email protected] .
  16. //
  17. ////////////////////////////////////////////////////////////////////
  18. ////////////////////////////////////////////////////////////////////
  19. // Function: Filename::Constructor
  20. // Access: Published
  21. // Description:
  22. ////////////////////////////////////////////////////////////////////
  23. INLINE Filename::
  24. Filename(const string &filename) {
  25. _flags = 0;
  26. (*this) = filename;
  27. }
  28. ////////////////////////////////////////////////////////////////////
  29. // Function: Filename::Constructor
  30. // Access: Published
  31. // Description:
  32. ////////////////////////////////////////////////////////////////////
  33. INLINE Filename::
  34. Filename(const char *filename) {
  35. _flags = 0;
  36. (*this) = filename;
  37. }
  38. ////////////////////////////////////////////////////////////////////
  39. // Function: Filename::Copy Constructor
  40. // Access: Published
  41. // Description:
  42. ////////////////////////////////////////////////////////////////////
  43. INLINE Filename::
  44. Filename(const Filename &copy) :
  45. _filename(copy._filename),
  46. _dirname_end(copy._dirname_end),
  47. _basename_start(copy._basename_start),
  48. _basename_end(copy._basename_end),
  49. _extension_start(copy._extension_start),
  50. _hash_start(copy._hash_start),
  51. _hash_end(copy._hash_end),
  52. _flags(copy._flags)
  53. {
  54. }
  55. ////////////////////////////////////////////////////////////////////
  56. // Function: Filename::text_filename named constructor
  57. // Access: Published
  58. // Description:
  59. ////////////////////////////////////////////////////////////////////
  60. INLINE Filename Filename::
  61. text_filename(const string &filename) {
  62. Filename result(filename);
  63. result.set_text();
  64. return result;
  65. }
  66. ////////////////////////////////////////////////////////////////////
  67. // Function: Filename::binary_filename named constructor
  68. // Access: Published
  69. // Description:
  70. ////////////////////////////////////////////////////////////////////
  71. INLINE Filename Filename::
  72. binary_filename(const string &filename) {
  73. Filename result(filename);
  74. result.set_binary();
  75. return result;
  76. }
  77. ////////////////////////////////////////////////////////////////////
  78. // Function: Filename::dso_filename named constructor
  79. // Access: Published
  80. // Description:
  81. ////////////////////////////////////////////////////////////////////
  82. INLINE Filename Filename::
  83. dso_filename(const string &filename) {
  84. Filename result(filename);
  85. result.set_type(T_dso);
  86. return result;
  87. }
  88. ////////////////////////////////////////////////////////////////////
  89. // Function: Filename::executable_filename named constructor
  90. // Access: Published
  91. // Description:
  92. ////////////////////////////////////////////////////////////////////
  93. INLINE Filename Filename::
  94. executable_filename(const string &filename) {
  95. Filename result(filename);
  96. result.set_type(T_executable);
  97. return result;
  98. }
  99. ////////////////////////////////////////////////////////////////////
  100. // Function: Filename::pattern_filename named constructor
  101. // Access: Published
  102. // Description: Constructs a filename that represents a sequence of
  103. // numbered files. See set_pattern().
  104. ////////////////////////////////////////////////////////////////////
  105. INLINE Filename Filename::
  106. pattern_filename(const string &filename) {
  107. Filename result(filename);
  108. result.set_pattern(true);
  109. return result;
  110. }
  111. ////////////////////////////////////////////////////////////////////
  112. // Function: Filename::Destructor
  113. // Access: Published
  114. // Description:
  115. ////////////////////////////////////////////////////////////////////
  116. INLINE Filename::
  117. ~Filename() {
  118. }
  119. ////////////////////////////////////////////////////////////////////
  120. // Function: Filename::Assignment operator
  121. // Access: Published
  122. // Description:
  123. ////////////////////////////////////////////////////////////////////
  124. INLINE Filename &Filename::
  125. operator = (const string &filename) {
  126. _filename = filename;
  127. locate_basename();
  128. locate_extension();
  129. locate_hash();
  130. return *this;
  131. }
  132. ////////////////////////////////////////////////////////////////////
  133. // Function: Filename::Assignment operator
  134. // Access: Published
  135. // Description:
  136. ////////////////////////////////////////////////////////////////////
  137. INLINE Filename &Filename::
  138. operator = (const char *filename) {
  139. assert(filename != NULL);
  140. return (*this) = string(filename);
  141. }
  142. ////////////////////////////////////////////////////////////////////
  143. // Function: Filename::Copy assignment operator
  144. // Access: Published
  145. // Description:
  146. ////////////////////////////////////////////////////////////////////
  147. INLINE Filename &Filename::
  148. operator = (const Filename &copy) {
  149. _filename = copy._filename;
  150. _dirname_end = copy._dirname_end;
  151. _basename_start = copy._basename_start;
  152. _basename_end = copy._basename_end;
  153. _extension_start = copy._extension_start;
  154. _hash_start = copy._hash_start;
  155. _hash_end = copy._hash_end;
  156. _flags = copy._flags;
  157. return *this;
  158. }
  159. ////////////////////////////////////////////////////////////////////
  160. // Function: Filename::string typecast operator
  161. // Access: Published
  162. // Description:
  163. ////////////////////////////////////////////////////////////////////
  164. INLINE Filename::
  165. operator const string & () const {
  166. return _filename;
  167. }
  168. ////////////////////////////////////////////////////////////////////
  169. // Function: Filename::c_str
  170. // Access: Published
  171. // Description:
  172. ////////////////////////////////////////////////////////////////////
  173. INLINE const char *Filename::
  174. c_str() const {
  175. return _filename.c_str();
  176. }
  177. ////////////////////////////////////////////////////////////////////
  178. // Function: Filename::empty
  179. // Access: Published
  180. // Description:
  181. ////////////////////////////////////////////////////////////////////
  182. INLINE bool Filename::
  183. empty() const {
  184. return _filename.empty();
  185. }
  186. ////////////////////////////////////////////////////////////////////
  187. // Function: Filename::length
  188. // Access: Published
  189. // Description:
  190. ////////////////////////////////////////////////////////////////////
  191. INLINE size_t Filename::
  192. length() const {
  193. return _filename.length();
  194. }
  195. ////////////////////////////////////////////////////////////////////
  196. // Function: Filename::Indexing operator
  197. // Access: Published
  198. // Description:
  199. ////////////////////////////////////////////////////////////////////
  200. INLINE char Filename::
  201. operator [] (int n) const {
  202. assert(n >= 0 && n < (int)_filename.length());
  203. return _filename[n];
  204. }
  205. ////////////////////////////////////////////////////////////////////
  206. // Function: Filename::substr
  207. // Access: Published
  208. // Description:
  209. ////////////////////////////////////////////////////////////////////
  210. INLINE string Filename::
  211. substr(size_t begin, size_t end) const {
  212. return _filename.substr(begin, end);
  213. }
  214. ////////////////////////////////////////////////////////////////////
  215. // Function: Filename::get_fullpath
  216. // Access: Published
  217. // Description: Returns the entire filename: directory, basename,
  218. // extension. This is the same thing returned by the
  219. // string typecast operator, so this function is a
  220. // little redundant.
  221. ////////////////////////////////////////////////////////////////////
  222. INLINE string Filename::
  223. get_fullpath() const {
  224. return _filename;
  225. }
  226. ////////////////////////////////////////////////////////////////////
  227. // Function: Filename::get_dirname
  228. // Access: Published
  229. // Description: Returns the directory part of the filename. This is
  230. // everything in the filename up to, but not including
  231. // the rightmost slash.
  232. ////////////////////////////////////////////////////////////////////
  233. INLINE string Filename::
  234. get_dirname() const {
  235. return _filename.substr(0, _dirname_end);
  236. }
  237. ////////////////////////////////////////////////////////////////////
  238. // Function: Filename::get_basename
  239. // Access: Published
  240. // Description: Returns the basename part of the filename. This is
  241. // everything in the filename after the rightmost slash,
  242. // including any extensions.
  243. ////////////////////////////////////////////////////////////////////
  244. INLINE string Filename::
  245. get_basename() const {
  246. return _filename.substr(_basename_start);
  247. }
  248. ////////////////////////////////////////////////////////////////////
  249. // Function: Filename::get_fullpath_wo_extension
  250. // Access: Published
  251. // Description: Returns the full filename--directory and basename
  252. // parts--except for the extension.
  253. ////////////////////////////////////////////////////////////////////
  254. INLINE string Filename::
  255. get_fullpath_wo_extension() const {
  256. return _filename.substr(0, _basename_end);
  257. }
  258. ////////////////////////////////////////////////////////////////////
  259. // Function: Filename::get_basename_wo_extension
  260. // Access: Published
  261. // Description: Returns the basename part of the filename, without
  262. // the file extension.
  263. ////////////////////////////////////////////////////////////////////
  264. INLINE string Filename::
  265. get_basename_wo_extension() const {
  266. if (_basename_end == string::npos) {
  267. return _filename.substr(_basename_start);
  268. } else {
  269. return _filename.substr(_basename_start, _basename_end - _basename_start);
  270. }
  271. }
  272. ////////////////////////////////////////////////////////////////////
  273. // Function: Filename::get_extension
  274. // Access: Published
  275. // Description: Returns the file extension. This is everything after
  276. // the rightmost dot, if there is one, or the empty
  277. // string if there is not.
  278. ////////////////////////////////////////////////////////////////////
  279. INLINE string Filename::
  280. get_extension() const {
  281. if (_extension_start == string::npos) {
  282. return string();
  283. } else {
  284. return _filename.substr(_extension_start);
  285. }
  286. }
  287. ////////////////////////////////////////////////////////////////////
  288. // Function: Filename::set_binary
  289. // Access: Published
  290. // Description: Indicates that the filename represents a binary file.
  291. // This is primarily relevant to the read_file() and
  292. // write_file() methods, so they can set the appropriate
  293. // flags to the OS.
  294. ////////////////////////////////////////////////////////////////////
  295. INLINE void Filename::
  296. set_binary() {
  297. _flags = (_flags & ~F_text) | F_binary;
  298. }
  299. ////////////////////////////////////////////////////////////////////
  300. // Function: Filename::set_text
  301. // Access: Published
  302. // Description: Indicates that the filename represents a text file.
  303. // This is primarily relevant to the read_file() and
  304. // write_file() methods, so they can set the appropriate
  305. // flags to the OS.
  306. ////////////////////////////////////////////////////////////////////
  307. INLINE void Filename::
  308. set_text() {
  309. _flags = (_flags & ~F_binary) | F_text;
  310. }
  311. ////////////////////////////////////////////////////////////////////
  312. // Function: Filename::is_binary
  313. // Access: Published
  314. // Description: Returns true if the Filename has been indicated to
  315. // represent a binary file via a previous call to
  316. // set_binary(). It is possible that neither
  317. // is_binary() nor is_text() will be true, if neither
  318. // set_binary() nor set_text() was ever called.
  319. ////////////////////////////////////////////////////////////////////
  320. INLINE bool Filename::
  321. is_binary() const {
  322. return ((_flags & F_binary) != 0);
  323. }
  324. ////////////////////////////////////////////////////////////////////
  325. // Function: Filename::is_text
  326. // Access: Published
  327. // Description: Returns true if the Filename has been indicated to
  328. // represent a text file via a previous call to
  329. // set_text(). It is possible that neither is_binary()
  330. // nor is_text() will be true, if neither set_binary()
  331. // nor set_text() was ever called.
  332. ////////////////////////////////////////////////////////////////////
  333. INLINE bool Filename::
  334. is_text() const {
  335. return ((_flags & F_text) != 0);
  336. }
  337. ////////////////////////////////////////////////////////////////////
  338. // Function: Filename::set_type
  339. // Access: Published
  340. // Description: Sets the type of the file represented by the
  341. // filename. This is useful for to_os_specific(),
  342. // resolve_filename(), test_existence(), and all such
  343. // real-world access functions. It helps the Filename
  344. // know how to map the internal filename to the
  345. // OS-specific filename (for instance, maybe executables
  346. // should have an .exe extension).
  347. ////////////////////////////////////////////////////////////////////
  348. INLINE void Filename::
  349. set_type(Filename::Type type) {
  350. _flags = (_flags & ~F_type) | type;
  351. switch (type) {
  352. case T_dso:
  353. case T_executable:
  354. set_binary();
  355. case T_general:
  356. break;
  357. }
  358. }
  359. ////////////////////////////////////////////////////////////////////
  360. // Function: Filename::get_type
  361. // Access: Published
  362. // Description: Returns the type of the file represented by the
  363. // filename, as previously set by set_type().
  364. ////////////////////////////////////////////////////////////////////
  365. INLINE Filename::Type Filename::
  366. get_type() const {
  367. return (Type)(_flags & (int)F_type);
  368. }
  369. ////////////////////////////////////////////////////////////////////
  370. // Function: Filename::set_pattern
  371. // Access: Published
  372. // Description: Sets the flag indicating whether this is a filename
  373. // pattern. When this is true, the filename is
  374. // understood to be a placeholder for a numbered
  375. // sequence of filename, such as an image sequence. In
  376. // this case, a sequence of one or more hash characters
  377. // ("#") should appear in the filename string; these
  378. // characters will be filled in with the corresponding
  379. // number (or more) of digits representing the sequence
  380. // number. Sequence numbers always begin counting at 0.
  381. //
  382. // When this is true, methods like has_hash() and
  383. // get_hash_to_end() and get_filename_index() may be
  384. // called. Methods like is_exists() will implicitly
  385. // test for existance of filename sequence 0.
  386. ////////////////////////////////////////////////////////////////////
  387. INLINE void Filename::
  388. set_pattern(bool pattern) {
  389. if (pattern != get_pattern()) {
  390. if (pattern) {
  391. _flags |= F_pattern;
  392. } else {
  393. _flags &= ~F_pattern;
  394. }
  395. locate_hash();
  396. }
  397. }
  398. ////////////////////////////////////////////////////////////////////
  399. // Function: Filename::get_pattern
  400. // Access: Published
  401. // Description: Returns the flag indicating whether this is a
  402. // filename pattern. See set_pattern().
  403. ////////////////////////////////////////////////////////////////////
  404. INLINE bool Filename::
  405. get_pattern() const {
  406. return (_flags & F_pattern) != 0;
  407. }
  408. ////////////////////////////////////////////////////////////////////
  409. // Function: Filename::has_hash
  410. // Access: Published
  411. // Description: Returns true if the filename is indicated to be a
  412. // filename pattern (that is, set_pattern(true) was
  413. // called), and the filename pattern did include a
  414. // sequence of hash marks, or false if it was not a
  415. // filename pattern or did not include hash marks. If
  416. // this is true, then get_filename_index() will return a
  417. // different filename each time.
  418. ////////////////////////////////////////////////////////////////////
  419. INLINE bool Filename::
  420. has_hash() const {
  421. return (_hash_start != _hash_end);
  422. }
  423. ////////////////////////////////////////////////////////////////////
  424. // Function: Filename::get_hash_to_end
  425. // Access: Published
  426. // Description: Returns the part of the filename beginning at the
  427. // hash sequence (if any), and continuing to the end of
  428. // the filename.
  429. ////////////////////////////////////////////////////////////////////
  430. INLINE string Filename::
  431. get_hash_to_end() const {
  432. return _filename.substr(_hash_start);
  433. }
  434. ////////////////////////////////////////////////////////////////////
  435. // Function: Filename::is_local
  436. // Access: Published
  437. // Description: Returns true if the filename is local, e.g. does not
  438. // begin with a slash, or false if the filename is fully
  439. // specified from the root.
  440. ////////////////////////////////////////////////////////////////////
  441. INLINE bool Filename::
  442. is_local() const {
  443. return _filename.empty() || _filename[0] != '/';
  444. }
  445. ////////////////////////////////////////////////////////////////////
  446. // Function: Filename::is_fully_qualified
  447. // Access: Published
  448. // Description: Returns true if the filename is fully qualified,
  449. // e.g. begins with a slash. This is almost, but not
  450. // quite, the same thing as !is_local(). It's not
  451. // exactly the same because a special case is made for
  452. // filenames that begin with a single dot followed by a
  453. // slash--these are considered to be fully qualified
  454. // (they are explicitly relative to the current
  455. // directory, and do not refer to a filename on a search
  456. // path somewhere).
  457. ////////////////////////////////////////////////////////////////////
  458. INLINE bool Filename::
  459. is_fully_qualified() const {
  460. return
  461. (_filename.size() > 2 && _filename[0] == '.' && _filename[1] == '/') ||
  462. (!_filename.empty() && _filename[0] == '/');
  463. }
  464. ////////////////////////////////////////////////////////////////////
  465. // Function: Filename::Equality operator
  466. // Access: Published
  467. // Description:
  468. ////////////////////////////////////////////////////////////////////
  469. INLINE bool Filename::
  470. operator == (const string &other) const {
  471. return (*(string *)this) == other;
  472. }
  473. ////////////////////////////////////////////////////////////////////
  474. // Function: Filename::Inequality operator
  475. // Access: Published
  476. // Description:
  477. ////////////////////////////////////////////////////////////////////
  478. INLINE bool Filename::
  479. operator != (const string &other) const {
  480. return (*(string *)this) != other;
  481. }
  482. ////////////////////////////////////////////////////////////////////
  483. // Function: Filename::Ordering operator
  484. // Access: Published
  485. // Description:
  486. ////////////////////////////////////////////////////////////////////
  487. INLINE bool Filename::
  488. operator < (const string &other) const {
  489. return (*(string *)this) < other;
  490. }
  491. ////////////////////////////////////////////////////////////////////
  492. // Function: Filename::compare_to
  493. // Access: Published
  494. // Description:
  495. ////////////////////////////////////////////////////////////////////
  496. INLINE int Filename::
  497. compare_to(const Filename &other) const {
  498. return strcmp(_filename.c_str(), other._filename.c_str());
  499. }
  500. ////////////////////////////////////////////////////////////////////
  501. // Function: Filename::output
  502. // Access: Published
  503. // Description:
  504. ////////////////////////////////////////////////////////////////////
  505. INLINE void Filename::
  506. output(ostream &out) const {
  507. out << _filename;
  508. }