Panda3D

filename.I

00001 // Filename: filename.I
00002 // Created by:  drose (18Jan99)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 ////////////////////////////////////////////////////////////////////
00016 //     Function: Filename::Constructor
00017 //       Access: Published
00018 //  Description:
00019 ////////////////////////////////////////////////////////////////////
00020 INLINE Filename::
00021 Filename(const string &filename) {
00022   _flags = 0;
00023   (*this) = filename;
00024 }
00025 
00026 ////////////////////////////////////////////////////////////////////
00027 //     Function: Filename::Constructor
00028 //       Access: Published
00029 //  Description:
00030 ////////////////////////////////////////////////////////////////////
00031 INLINE Filename::
00032 Filename(const wstring &filename) {
00033   _flags = 0;
00034   (*this) = filename;
00035 }
00036 
00037 ////////////////////////////////////////////////////////////////////
00038 //     Function: Filename::Constructor
00039 //       Access: Published
00040 //  Description:
00041 ////////////////////////////////////////////////////////////////////
00042 INLINE Filename::
00043 Filename(const char *filename) {
00044   _flags = 0;
00045   (*this) = filename;
00046 }
00047 
00048 
00049 ////////////////////////////////////////////////////////////////////
00050 //     Function: Filename::Copy Constructor
00051 //       Access: Published
00052 //  Description:
00053 ////////////////////////////////////////////////////////////////////
00054 INLINE Filename::
00055 Filename(const Filename &copy) :
00056   _filename(copy._filename.c_str()),
00057   _dirname_end(copy._dirname_end),
00058   _basename_start(copy._basename_start),
00059   _basename_end(copy._basename_end),
00060   _extension_start(copy._extension_start),
00061   _hash_start(copy._hash_start),
00062   _hash_end(copy._hash_end),
00063   _flags(copy._flags)
00064 {
00065 }
00066 
00067 ////////////////////////////////////////////////////////////////////
00068 //     Function: Filename::text_filename named constructor
00069 //       Access: Published
00070 //  Description:
00071 ////////////////////////////////////////////////////////////////////
00072 INLINE Filename Filename::
00073 text_filename(const Filename &filename) {
00074   Filename result(filename);
00075   result.set_text();
00076   return result;
00077 }
00078 
00079 ////////////////////////////////////////////////////////////////////
00080 //     Function: Filename::text_filename named constructor
00081 //       Access: Published
00082 //  Description:
00083 ////////////////////////////////////////////////////////////////////
00084 INLINE Filename Filename::
00085 text_filename(const string &filename) {
00086   Filename result(filename);
00087   result.set_text();
00088   return result;
00089 }
00090 
00091 ////////////////////////////////////////////////////////////////////
00092 //     Function: Filename::binary_filename named constructor
00093 //       Access: Published
00094 //  Description:
00095 ////////////////////////////////////////////////////////////////////
00096 INLINE Filename Filename::
00097 binary_filename(const Filename &filename) {
00098   Filename result(filename);
00099   result.set_binary();
00100   return result;
00101 }
00102 
00103 ////////////////////////////////////////////////////////////////////
00104 //     Function: Filename::binary_filename named constructor
00105 //       Access: Published
00106 //  Description:
00107 ////////////////////////////////////////////////////////////////////
00108 INLINE Filename Filename::
00109 binary_filename(const string &filename) {
00110   Filename result(filename);
00111   result.set_binary();
00112   return result;
00113 }
00114 
00115 ////////////////////////////////////////////////////////////////////
00116 //     Function: Filename::dso_filename named constructor
00117 //       Access: Published
00118 //  Description:
00119 ////////////////////////////////////////////////////////////////////
00120 INLINE Filename Filename::
00121 dso_filename(const string &filename) {
00122   Filename result(filename);
00123   result.set_type(T_dso);
00124   return result;
00125 }
00126 
00127 ////////////////////////////////////////////////////////////////////
00128 //     Function: Filename::executable_filename named constructor
00129 //       Access: Published
00130 //  Description:
00131 ////////////////////////////////////////////////////////////////////
00132 INLINE Filename Filename::
00133 executable_filename(const string &filename) {
00134   Filename result(filename);
00135   result.set_type(T_executable);
00136   return result;
00137 }
00138 
00139 ////////////////////////////////////////////////////////////////////
00140 //     Function: Filename::pattern_filename named constructor
00141 //       Access: Published
00142 //  Description: Constructs a filename that represents a sequence of
00143 //               numbered files.  See set_pattern().
00144 ////////////////////////////////////////////////////////////////////
00145 INLINE Filename Filename::
00146 pattern_filename(const string &filename) {
00147   Filename result(filename);
00148   result.set_pattern(true);
00149   return result;
00150 }
00151 
00152 ////////////////////////////////////////////////////////////////////
00153 //     Function: Filename::Destructor
00154 //       Access: Published
00155 //  Description:
00156 ////////////////////////////////////////////////////////////////////
00157 INLINE Filename::
00158 ~Filename() {
00159 }
00160 
00161 
00162 ////////////////////////////////////////////////////////////////////
00163 //     Function: Filename::Assignment operator
00164 //       Access: Published
00165 //  Description:
00166 ////////////////////////////////////////////////////////////////////
00167 INLINE Filename &Filename::
00168 operator = (const string &filename) {
00169   _filename = filename;
00170 
00171   locate_basename();
00172   locate_extension();
00173   locate_hash();
00174   return *this;
00175 }
00176 
00177 ////////////////////////////////////////////////////////////////////
00178 //     Function: Filename::Assignment operator
00179 //       Access: Published
00180 //  Description:
00181 ////////////////////////////////////////////////////////////////////
00182 INLINE Filename &Filename::
00183 operator = (const wstring &filename) {
00184   TextEncoder encoder;
00185   encoder.set_encoding(get_filesystem_encoding());
00186   encoder.set_wtext(filename);
00187   return operator = (encoder.get_text());
00188 }
00189 
00190 ////////////////////////////////////////////////////////////////////
00191 //     Function: Filename::Assignment operator
00192 //       Access: Published
00193 //  Description:
00194 ////////////////////////////////////////////////////////////////////
00195 INLINE Filename &Filename::
00196 operator = (const char *filename) {
00197   assert(filename != NULL);
00198   return (*this) = string(filename);
00199 }
00200 
00201 ////////////////////////////////////////////////////////////////////
00202 //     Function: Filename::Copy assignment operator
00203 //       Access: Published
00204 //  Description:
00205 ////////////////////////////////////////////////////////////////////
00206 INLINE Filename &Filename::
00207 operator = (const Filename &copy) {
00208   _filename = copy._filename;
00209   _dirname_end = copy._dirname_end;
00210   _basename_start = copy._basename_start;
00211   _basename_end = copy._basename_end;
00212   _extension_start = copy._extension_start;
00213   _hash_start = copy._hash_start;
00214   _hash_end = copy._hash_end;
00215   _flags = copy._flags;
00216   return *this;
00217 }
00218 
00219 
00220 ////////////////////////////////////////////////////////////////////
00221 //     Function: Filename::string typecast operator
00222 //       Access: Published
00223 //  Description:
00224 ////////////////////////////////////////////////////////////////////
00225 INLINE Filename::
00226 operator const string & () const {
00227   return _filename;
00228 }
00229 
00230 ////////////////////////////////////////////////////////////////////
00231 //     Function: Filename::c_str
00232 //       Access: Published
00233 //  Description:
00234 ////////////////////////////////////////////////////////////////////
00235 INLINE const char *Filename::
00236 c_str() const {
00237   return _filename.c_str();
00238 }
00239 
00240 ////////////////////////////////////////////////////////////////////
00241 //     Function: Filename::empty
00242 //       Access: Published
00243 //  Description:
00244 ////////////////////////////////////////////////////////////////////
00245 INLINE bool Filename::
00246 empty() const {
00247   return _filename.empty();
00248 }
00249 
00250 ////////////////////////////////////////////////////////////////////
00251 //     Function: Filename::length
00252 //       Access: Published
00253 //  Description:
00254 ////////////////////////////////////////////////////////////////////
00255 INLINE size_t Filename::
00256 length() const {
00257   return _filename.length();
00258 }
00259 
00260 ////////////////////////////////////////////////////////////////////
00261 //     Function: Filename::Indexing operator
00262 //       Access: Published
00263 //  Description:
00264 ////////////////////////////////////////////////////////////////////
00265 INLINE char Filename::
00266 operator [] (int n) const {
00267   assert(n >= 0 && n < (int)_filename.length());
00268   return _filename[n];
00269 }
00270 
00271 ////////////////////////////////////////////////////////////////////
00272 //     Function: Filename::substr
00273 //       Access: Published
00274 //  Description:
00275 ////////////////////////////////////////////////////////////////////
00276 INLINE string Filename::
00277 substr(size_t begin, size_t end) const {
00278   return _filename.substr(begin, end);
00279 }
00280 
00281 ////////////////////////////////////////////////////////////////////
00282 //     Function: Filename::operator +=
00283 //       Access: Published
00284 //  Description: Appends the other filename onto the end of this one.
00285 //               This does not introduce an intervening slash, but see
00286 //               the Filename constructor that takes two parameters.
00287 ////////////////////////////////////////////////////////////////////
00288 INLINE void Filename::
00289 operator += (const string &other) {
00290   _filename += other;
00291   locate_basename();
00292   locate_extension();
00293   locate_hash();
00294 }
00295 
00296 ////////////////////////////////////////////////////////////////////
00297 //     Function: Filename::operator +
00298 //       Access: Published
00299 //  Description: Returns a new Filename representing the concatenation
00300 //               of the two filenames.
00301 ////////////////////////////////////////////////////////////////////
00302 INLINE Filename Filename::
00303 operator + (const string &other) const {
00304   Filename a(*this);
00305   a += other;
00306   return a;
00307 }
00308 
00309 
00310 ////////////////////////////////////////////////////////////////////
00311 //     Function: Filename::get_fullpath
00312 //       Access: Published
00313 //  Description: Returns the entire filename: directory, basename,
00314 //               extension.  This is the same thing returned by the
00315 //               string typecast operator.
00316 ////////////////////////////////////////////////////////////////////
00317 INLINE string Filename::
00318 get_fullpath() const {
00319   return _filename;
00320 }
00321 
00322 ////////////////////////////////////////////////////////////////////
00323 //     Function: Filename::get_fullpath_w
00324 //       Access: Published
00325 //  Description: Returns the entire filename as a wide-character
00326 //               string.
00327 ////////////////////////////////////////////////////////////////////
00328 INLINE wstring Filename::
00329 get_fullpath_w() const {
00330   TextEncoder encoder;
00331   encoder.set_encoding(get_filesystem_encoding());
00332   encoder.set_text(get_fullpath());
00333   return encoder.get_wtext();
00334 }
00335 
00336 ////////////////////////////////////////////////////////////////////
00337 //     Function: Filename::get_dirname
00338 //       Access: Published
00339 //  Description: Returns the directory part of the filename.  This is
00340 //               everything in the filename up to, but not including
00341 //               the rightmost slash.
00342 ////////////////////////////////////////////////////////////////////
00343 INLINE string Filename::
00344 get_dirname() const {
00345   return _filename.substr(0, _dirname_end);
00346 }
00347 
00348 ////////////////////////////////////////////////////////////////////
00349 //     Function: Filename::get_basename
00350 //       Access: Published
00351 //  Description: Returns the basename part of the filename.  This is
00352 //               everything in the filename after the rightmost slash,
00353 //               including any extensions.
00354 ////////////////////////////////////////////////////////////////////
00355 INLINE string Filename::
00356 get_basename() const {
00357   return _filename.substr(_basename_start);
00358 }
00359 
00360 
00361 ////////////////////////////////////////////////////////////////////
00362 //     Function: Filename::get_fullpath_wo_extension
00363 //       Access: Published
00364 //  Description: Returns the full filename--directory and basename
00365 //               parts--except for the extension.
00366 ////////////////////////////////////////////////////////////////////
00367 INLINE string Filename::
00368 get_fullpath_wo_extension() const {
00369   return _filename.substr(0, _basename_end);
00370 }
00371 
00372 
00373 ////////////////////////////////////////////////////////////////////
00374 //     Function: Filename::get_basename_wo_extension
00375 //       Access: Published
00376 //  Description: Returns the basename part of the filename, without
00377 //               the file extension.
00378 ////////////////////////////////////////////////////////////////////
00379 INLINE string Filename::
00380 get_basename_wo_extension() const {
00381   if (_basename_end == string::npos) {
00382     return _filename.substr(_basename_start);
00383   } else {
00384     return _filename.substr(_basename_start, _basename_end - _basename_start);
00385   }
00386 }
00387 
00388 
00389 ////////////////////////////////////////////////////////////////////
00390 //     Function: Filename::get_extension
00391 //       Access: Published
00392 //  Description: Returns the file extension.  This is everything after
00393 //               the rightmost dot, if there is one, or the empty
00394 //               string if there is not.
00395 ////////////////////////////////////////////////////////////////////
00396 INLINE string Filename::
00397 get_extension() const {
00398   if (_extension_start == string::npos) {
00399     return string();
00400   } else {
00401     return _filename.substr(_extension_start);
00402   }
00403 }
00404 
00405 ////////////////////////////////////////////////////////////////////
00406 //     Function: Filename::set_binary
00407 //       Access: Published
00408 //  Description: Indicates that the filename represents a binary file.
00409 //               This is primarily relevant to the read_file() and
00410 //               write_file() methods, so they can set the appropriate
00411 //               flags to the OS.
00412 ////////////////////////////////////////////////////////////////////
00413 INLINE void Filename::
00414 set_binary() {
00415   _flags = (_flags & ~F_text) | F_binary;
00416 }
00417 
00418 ////////////////////////////////////////////////////////////////////
00419 //     Function: Filename::set_text
00420 //       Access: Published
00421 //  Description: Indicates that the filename represents a text file.
00422 //               This is primarily relevant to the read_file() and
00423 //               write_file() methods, so they can set the appropriate
00424 //               flags to the OS.
00425 ////////////////////////////////////////////////////////////////////
00426 INLINE void Filename::
00427 set_text() {
00428   _flags = (_flags & ~F_binary) | F_text;
00429 }
00430 
00431 ////////////////////////////////////////////////////////////////////
00432 //     Function: Filename::is_binary
00433 //       Access: Published
00434 //  Description: Returns true if the Filename has been indicated to
00435 //               represent a binary file via a previous call to
00436 //               set_binary().  It is possible that neither
00437 //               is_binary() nor is_text() will be true, if neither
00438 //               set_binary() nor set_text() was ever called.
00439 ////////////////////////////////////////////////////////////////////
00440 INLINE bool Filename::
00441 is_binary() const {
00442   return ((_flags & F_binary) != 0);
00443 }
00444 
00445 ////////////////////////////////////////////////////////////////////
00446 //     Function: Filename::is_binary_or_text
00447 //       Access: Published
00448 //  Description: Returns true either is_binary() or is_text() is true;
00449 //               that is, that the filename has been specified as
00450 //               either binary or text.  If this is false, the
00451 //               filename has not been specified.
00452 ////////////////////////////////////////////////////////////////////
00453 INLINE bool Filename::
00454 is_binary_or_text() const {
00455   return ((_flags & (F_binary | F_text)) != 0);
00456 }
00457 
00458 ////////////////////////////////////////////////////////////////////
00459 //     Function: Filename::is_text
00460 //       Access: Published
00461 //  Description: Returns true if the Filename has been indicated to
00462 //               represent a text file via a previous call to
00463 //               set_text().  It is possible that neither is_binary()
00464 //               nor is_text() will be true, if neither set_binary()
00465 //               nor set_text() was ever called.
00466 ////////////////////////////////////////////////////////////////////
00467 INLINE bool Filename::
00468 is_text() const {
00469   return ((_flags & F_text) != 0);
00470 }
00471 
00472 ////////////////////////////////////////////////////////////////////
00473 //     Function: Filename::set_type
00474 //       Access: Published
00475 //  Description: Sets the type of the file represented by the
00476 //               filename.  This is useful for to_os_specific(),
00477 //               resolve_filename(), test_existence(), and all such
00478 //               real-world access functions.  It helps the Filename
00479 //               know how to map the internal filename to the
00480 //               OS-specific filename (for instance, maybe executables
00481 //               should have an .exe extension).
00482 ////////////////////////////////////////////////////////////////////
00483 INLINE void Filename::
00484 set_type(Filename::Type type) {
00485   _flags = (_flags & ~F_type) | type;
00486   switch (type) {
00487   case T_dso:
00488   case T_executable:
00489     set_binary();
00490 
00491   case T_general:
00492     break;
00493   }
00494 }
00495 
00496 ////////////////////////////////////////////////////////////////////
00497 //     Function: Filename::get_type
00498 //       Access: Published
00499 //  Description: Returns the type of the file represented by the
00500 //               filename, as previously set by set_type().
00501 ////////////////////////////////////////////////////////////////////
00502 INLINE Filename::Type Filename::
00503 get_type() const {
00504   return (Type)(_flags & (int)F_type);
00505 }
00506 
00507 ////////////////////////////////////////////////////////////////////
00508 //     Function: Filename::set_pattern
00509 //       Access: Published
00510 //  Description: Sets the flag indicating whether this is a filename
00511 //               pattern.  When this is true, the filename is
00512 //               understood to be a placeholder for a numbered
00513 //               sequence of filename, such as an image sequence.  In
00514 //               this case, a sequence of one or more hash characters
00515 //               ("#") should appear in the filename string; these
00516 //               characters will be filled in with the corresponding
00517 //               number (or more) of digits representing the sequence
00518 //               number.  Sequence numbers always begin counting at 0.
00519 //
00520 //               When this is true, methods like has_hash() and
00521 //               get_hash_to_end() and get_filename_index() may be
00522 //               called.  Methods like is_exists() will implicitly
00523 //               test for existance of filename sequence 0.
00524 ////////////////////////////////////////////////////////////////////
00525 INLINE void Filename::
00526 set_pattern(bool pattern) {
00527   if (pattern != get_pattern()) {
00528     if (pattern) {
00529       _flags |= F_pattern;
00530     } else {
00531       _flags &= ~F_pattern;
00532     }
00533     locate_hash();
00534   }
00535 }
00536 
00537 ////////////////////////////////////////////////////////////////////
00538 //     Function: Filename::get_pattern
00539 //       Access: Published
00540 //  Description: Returns the flag indicating whether this is a
00541 //               filename pattern.  See set_pattern().
00542 ////////////////////////////////////////////////////////////////////
00543 INLINE bool Filename::
00544 get_pattern() const {
00545   return (_flags & F_pattern) != 0;
00546 }
00547 
00548 ////////////////////////////////////////////////////////////////////
00549 //     Function: Filename::has_hash
00550 //       Access: Published
00551 //  Description: Returns true if the filename is indicated to be a
00552 //               filename pattern (that is, set_pattern(true) was
00553 //               called), and the filename pattern did include a
00554 //               sequence of hash marks, or false if it was not a
00555 //               filename pattern or did not include hash marks.  If
00556 //               this is true, then get_filename_index() will return a
00557 //               different filename each time.
00558 ////////////////////////////////////////////////////////////////////
00559 INLINE bool Filename::
00560 has_hash() const {
00561   return (_hash_start != _hash_end);
00562 }
00563 
00564 ////////////////////////////////////////////////////////////////////
00565 //     Function: Filename::get_hash_to_end
00566 //       Access: Published
00567 //  Description: Returns the part of the filename beginning at the
00568 //               hash sequence (if any), and continuing to the end of
00569 //               the filename.
00570 ////////////////////////////////////////////////////////////////////
00571 INLINE string Filename::
00572 get_hash_to_end() const {
00573   return _filename.substr(_hash_start);
00574 }
00575 
00576 ////////////////////////////////////////////////////////////////////
00577 //     Function: Filename::is_local
00578 //       Access: Published
00579 //  Description: Returns true if the filename is local, e.g. does not
00580 //               begin with a slash, or false if the filename is fully
00581 //               specified from the root.
00582 ////////////////////////////////////////////////////////////////////
00583 INLINE bool Filename::
00584 is_local() const {
00585   return _filename.empty() || _filename[0] != '/';
00586 }
00587 
00588 ////////////////////////////////////////////////////////////////////
00589 //     Function: Filename::is_fully_qualified
00590 //       Access: Published
00591 //  Description: Returns true if the filename is fully qualified,
00592 //               e.g. begins with a slash.  This is almost, but not
00593 //               quite, the same thing as !is_local().  It's not
00594 //               exactly the same because a special case is made for
00595 //               filenames that begin with a single dot followed by a
00596 //               slash--these are considered to be fully qualified
00597 //               (they are explicitly relative to the current
00598 //               directory, and do not refer to a filename on a search
00599 //               path somewhere).
00600 ////////////////////////////////////////////////////////////////////
00601 INLINE bool Filename::
00602 is_fully_qualified() const {
00603   return
00604     (_filename.size() > 2 && _filename[0] == '.' && _filename[1] == '/') ||
00605     (!_filename.empty() && _filename[0] == '/');
00606 }
00607 
00608 ////////////////////////////////////////////////////////////////////
00609 //     Function: Filename::Equality operator
00610 //       Access: Published
00611 //  Description:
00612 ////////////////////////////////////////////////////////////////////
00613 INLINE bool Filename::
00614 operator == (const string &other) const {
00615   return (*(string *)this) == other;
00616 }
00617 
00618 ////////////////////////////////////////////////////////////////////
00619 //     Function: Filename::Inequality operator
00620 //       Access: Published
00621 //  Description:
00622 ////////////////////////////////////////////////////////////////////
00623 INLINE bool Filename::
00624 operator != (const string &other) const {
00625   return (*(string *)this) != other;
00626 }
00627 
00628 ////////////////////////////////////////////////////////////////////
00629 //     Function: Filename::Ordering operator
00630 //       Access: Published
00631 //  Description:
00632 ////////////////////////////////////////////////////////////////////
00633 INLINE bool Filename::
00634 operator < (const string &other) const {
00635   return (*(string *)this) < other;
00636 }
00637 
00638 ////////////////////////////////////////////////////////////////////
00639 //     Function: Filename::compare_to
00640 //       Access: Published
00641 //  Description:
00642 ////////////////////////////////////////////////////////////////////
00643 INLINE int Filename::
00644 compare_to(const Filename &other) const {
00645   return strcmp(_filename.c_str(), other._filename.c_str());
00646 }
00647 
00648 
00649 ////////////////////////////////////////////////////////////////////
00650 //     Function: Filename::__nonzero__
00651 //       Access: Published
00652 //  Description: Returns true if the Filename is valid (not empty),
00653 //               or false if it is an empty string.
00654 //
00655 //               This implements the Python equivalent to operator
00656 //               bool.  Defining an actual operator bool method for
00657 //               C++ use would work too, but it seems to cause too
00658 //               many ambiguities for the C++ compiler, so we use this
00659 //               Python-only approach instead.
00660 ////////////////////////////////////////////////////////////////////
00661 INLINE bool Filename::
00662 __nonzero__() const {
00663   return !_filename.empty();
00664 }
00665 
00666 ////////////////////////////////////////////////////////////////////
00667 //     Function: Filename::output
00668 //       Access: Published
00669 //  Description:
00670 ////////////////////////////////////////////////////////////////////
00671 INLINE void Filename::
00672 output(ostream &out) const {
00673   out << _filename;
00674 }
00675 
00676 ////////////////////////////////////////////////////////////////////
00677 //     Function: Filename::set_filesystem_encoding
00678 //       Access: Published, Static
00679 //  Description: Specifies the default encoding to be used for all
00680 //               subsequent Filenames.  This is used to represent
00681 //               wide-character (Unicode) filenames internally.  On
00682 //               non-Windows-based systems, the encoded filename is
00683 //               also passed to the underlying operating system.
00684 ////////////////////////////////////////////////////////////////////
00685 INLINE void Filename::
00686 set_filesystem_encoding(TextEncoder::Encoding encoding) {
00687   _filesystem_encoding = encoding;
00688 }
00689 
00690 ////////////////////////////////////////////////////////////////////
00691 //     Function: Filename::get_filesystem_encoding
00692 //       Access: Published, Static
00693 //  Description: Specifies the default encoding to be used for all
00694 //               subsequent Filenames objects.  See
00695 //               set_filesystem_encoding().
00696 ////////////////////////////////////////////////////////////////////
00697 INLINE TextEncoder::Encoding Filename::
00698 get_filesystem_encoding() {
00699   return _filesystem_encoding;
00700 }
 All Classes Functions Variables Enumerations