TrinityCore
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
G3D::FilePath Class Reference

Parsing of file system paths. More...

#include <FileSystem.h>

Static Public Member Functions

static std::string concat (const std::string &a, const std::string &b)
 
static bool isRoot (const std::string &f)
 
static std::string removeTrailingSlash (const std::string &f)
 
static std::string ext (const std::string &path)
 
static std::string baseExt (const std::string &path)
 
static std::string base (const std::string &path)
 
static std::string parent (const std::string &path)
 
static bool containsWildcards (const std::string &p)
 
static std::string canonicalize (std::string x)
 
static std::string expandEnvironmentVariables (const std::string &path)
 Replaces $VAR and patterns with the corresponding environment variable. Throws std::string if the environment variable is not defined. More...
 
static void parse (const std::string &filename, std::string &drive, Array< std::string > &path, std::string &base, std::string &ext)
 
static bool matches (const std::string &path, const std::string &pattern, bool caseSensitive=true)
 
static std::string makeLegalFilename (const std::string &f, size_t maxLength=100000)
 

Detailed Description

Parsing of file system paths.

None of these routines touch the disk–they are purely string manipulation.

In "/a/b/base.ext",

  • base = "base"
  • ext = "ext"
  • parentPath = "/a/b"
  • baseExt = "base.ext"

Member Function Documentation

std::string G3D::FilePath::base ( const std::string &  path)
static

Returns everything between the right-most slash and the following '.'

783  {
784  std::string filename = baseExt(path);
785  size_t i = filename.rfind(".");
786  if (i == std::string::npos) {
787  // No extension
788  return filename;
789  } else {
790  return filename.substr(0, i);
791  }
792 }
static std::string baseExt(const std::string &path)
Definition: FileSystem.cpp:765
std::string G3D::FilePath::baseExt ( const std::string &  path)
static

Returns everything to the right of the last slash (or, on Windows, the last ':')

765  {
766  size_t i = findLastSlash(filename);
767 
768 # ifdef G3D_WINDOWS
769  size_t j = filename.rfind(":");
770  if ((i == std::string::npos) && (j != std::string::npos)) {
771  i = j;
772  }
773 # endif
774 
775  if (i == std::string::npos) {
776  return filename;
777  } else {
778  return filename.substr(i + 1, filename.length() - i);
779  }
780 }
size_t findLastSlash(const std::string &f, size_t start=std::string::npos)
Definition: stringutils.h:58

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::string G3D::FilePath::canonicalize ( std::string  x)
static

Convert all slashes to '/'

832  {
833  std::transform(x.begin(), x.end(), x.begin(), fixslash);
834  return x;
835 }
static int fixslash(int c)
Definition: FileSystem.cpp:827
G3D::int16 x
Definition: Vector2int16.h:37

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::string G3D::FilePath::concat ( const std::string &  a,
const std::string &  b 
)
static

Appends file onto dirname, ensuring a / if needed.

743  {
744  // Ensure that the directory ends in a slash
745  if (! dirname.empty() &&
746  ! isSlash(dirname[dirname.size() - 1]) &&
747  (dirname[dirname.size() - 1] != ':')) {
748  return dirname + '/' + file;
749  } else {
750  return dirname + file;
751  }
752 }
bool isSlash(const unsigned char c)
Definition: stringutils.h:175

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

bool G3D::FilePath::containsWildcards ( const std::string &  p)
static

Returns true if '*' or '?' appear in the filename

813  {
814  return (filename.find('*') != std::string::npos) || (filename.find('?') != std::string::npos);
815 }

+ Here is the caller graph for this function:

std::string G3D::FilePath::expandEnvironmentVariables ( const std::string &  path)
static

Replaces $VAR and patterns with the corresponding environment variable. Throws std::string if the environment variable is not defined.

949  {
950  // Search for pattern
951  size_t end = path.find_first_of('$', 0);
952  if (end == std::string::npos) {
953  // Pattern does not exist
954  return path;
955  }
956 
957  size_t start = 0;
958  std::string result;
959  while (end != std::string::npos) {
960  const std::string& before = path.substr(start, end - start);
961  result += before;
962  start = end + 1;
963  std::string var;
964  if (path[start] == '(') {
965  // Search for close paren
966  end = path.find_first_of(')', start + 1);
967  if (end == std::string::npos) {
968  throw std::string("Missing close paren in environment variable in \"") + path + "\"";
969  }
970  var = path.substr(start + 1, end - start - 1);
971  } else {
972  // Search for slash or end of string
973  end = path.find_first_of('/', start);
974  size_t i = path.find_first_of('\\', start);
975  if ((size_t(i) != std::string::npos) && ((end == std::string::npos) || (size_t(i) < end))) {
976  end = i;
977  }
978  if (end == std::string::npos) {
979  // If the varible goes to the end of the string, it is the rest of the string
980  end = path.size();
981  } else {
982  --end;
983  }
984  var = path.substr(start, end - start + 1);
985  }
986 
987  if (! var.empty()) {
988  const char* value = getenv(var.c_str());
989 
990  if (value == NULL) {
991  throw (std::string("LocalLightingEnvironment variable \"") + var + "\" not defined for path \"" + path + "\"");
992  } else {
993  result += value;
994  }
995  } else {
996  // We just parsed an "empty" variable, which was probably a default share on Windows, e.g.,
997  // "\\mycomputer\c$", and not a variable name.
998  result += "$";
999  }
1000 
1001  start = end + 1;
1002  end = path.find_first_of('$', start);
1003  }
1004 
1005  // Paste on the remainder of the source path
1006  if (start < path.size()) {
1007  result += path.substr(start);
1008  }
1009 
1010  return result;
1011 }
static void var(TextOutput &t, const std::string &name, const std::string &val)
Definition: System.cpp:1582
arena_t NULL
Definition: jemalloc_internal.h:624
const FieldDescriptor value
Definition: descriptor.h:1522

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::string G3D::FilePath::ext ( const std::string &  path)
static

Returns everything to the right of the last '.'

755  {
756  size_t i = filename.rfind(".");
757  if (i != std::string::npos) {
758  return filename.substr(i + 1, filename.length() - i);
759  } else {
760  return "";
761  }
762 }

+ Here is the caller graph for this function:

bool G3D::FilePath::isRoot ( const std::string &  f)
static

Returns true if f specifies a path that parses as root of the filesystem. On OS X and other Unix-based operating systems, "/" is the only root. On Windows, drive letters and shares are roots, e.g., "c:\", "\\foo\". Does not check on Windows to see if the root is actually mounted or a legal drive letter–this is a purely string based test.

698  {
699 # ifdef G3D_WINDOWS
700  if (f.length() < 2) {
701  return false;
702  }
703 
704  if (f[1] == ':') {
705  if (f.length() == 2) {
706  // e.g., "x:"
707  return true;
708  } else if ((f.length() == 3) && isSlash(f[2])) {
709  // e.g., "x:\"
710  return true;
711  }
712  }
713 
714  // Windows shares are considered roots, but only if this does not include a path inside the share
715  if (isSlash(f[0]) && isSlash(f[1])) {
716  size_t i = f.find("/", 3);
717  size_t j = f.find("\\", 3);
718 
719  if (i == std::string::npos) {
720  i = j;
721  }
722 
723  // e.g., "\\foo\", "\\foo"
724  return ((i == std::string::npos) || (i == f.length() - 1));
725  }
726 # else
727  if (f == "/") {
728  return true;
729  }
730 # endif
731 
732  return false;
733 }
bool isSlash(const unsigned char c)
Definition: stringutils.h:175

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::string G3D::FilePath::makeLegalFilename ( const std::string &  f,
size_t  maxLength = 100000 
)
static

Replaces characters that are illegal in a filename with legal equivalents.

Generate a unique filename based on the provided hint

1015  {
1016  std::string tentative;
1017 
1018  for (size_t i = 0; i < G3D::min(maxLength, f.size()); ++i) {
1019  const char c = f[i];
1020  if (isLetter(c) || isDigit(c) || (c == '-') || (c == '+') || (c == '=') || (c == '(') || (c == ')')) {
1021  tentative += c;
1022  } else {
1023  tentative += "_";
1024  }
1025  }
1026 
1027  return tentative;
1028 }
T min(const T &x, const T &y)
Definition: g3dmath.h:305
bool isDigit(const unsigned char c)
Definition: stringutils.h:164
bool isLetter(const unsigned char c)
Definition: stringutils.h:171

+ Here is the call graph for this function:

bool G3D::FilePath::matches ( const std::string &  path,
const std::string &  pattern,
bool  caseSensitive = true 
)
static

Returns true if path matches pattern, with standard filesystem wildcards.

818  {
819  int flags = FNM_PERIOD | FNM_NOESCAPE | FNM_PATHNAME;
820  if (! caseSensitive) {
821  flags |= FNM_CASEFOLD;
822  }
823  return g3dfnmatch(pattern.c_str(), path.c_str(), flags) == 0;
824 }
int g3dfnmatch(const char *pattern, const char *string, int flags)
Definition: g3dfnmatch.cpp:217
uint8 flags
Definition: DisableMgr.cpp:44

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::string G3D::FilePath::parent ( const std::string &  path)
static

Returns everything to the left of the right-most slash

795  {
796  size_t i = findLastSlash(removeTrailingSlash(path));
797 
798 # ifdef G3D_WINDOWS
799  size_t j = path.rfind(":");
800  if ((i == std::string::npos) && (j != std::string::npos)) {
801  i = j;
802  }
803 # endif
804 
805  if (i == std::string::npos) {
806  return "";
807  } else {
808  return path.substr(0, i + 1);
809  }
810 }
size_t findLastSlash(const std::string &f, size_t start=std::string::npos)
Definition: stringutils.h:58
static std::string removeTrailingSlash(const std::string &f)
Definition: FileSystem.cpp:736

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void G3D::FilePath::parse ( const std::string &  filename,
std::string &  drive,
Array< std::string > &  path,
std::string &  base,
std::string &  ext 
)
static

Parses a filename into four useful pieces.

Examples:

c:\a\b\d.e root = "c:\\" path = "a" "b" base = "d" ext = "e"

/a/b/d.e root = "/" path = "a" "b" base = "d" ext = "e"

/a/b root = "/" path = "a" base = "b" ext = "e"

842  {
843 
844  std::string f = filename;
845 
846  root = "";
847  path.clear();
848  base = "";
849  ext = "";
850 
851  if (f == "") {
852  // Empty filename
853  return;
854  }
855 
856  // See if there is a root/drive spec.
857  if ((f.size() >= 2) && (f[1] == ':')) {
858 
859  if ((f.size() > 2) && isSlash(f[2])) {
860 
861  // e.g. c:\foo
862  root = f.substr(0, 3);
863  f = f.substr(3, f.size() - 3);
864 
865  } else {
866 
867  // e.g. c:foo
868  root = f.substr(2);
869  f = f.substr(2, f.size() - 2);
870 
871  }
872 
873  } else if ((f.size() >= 2) && isSlash(f[0]) && isSlash(f[1])) {
874 
875  // e.g. //foo
876  root = f.substr(0, 2);
877  f = f.substr(2, f.size() - 2);
878 
879  } else if (isSlash(f[0])) {
880 
881  root = f.substr(0, 1);
882  f = f.substr(1, f.size() - 1);
883 
884  }
885 
886  // Pull the extension off
887  {
888  // Find the period
889  size_t i = f.rfind('.');
890 
891  if (i != std::string::npos) {
892  // Make sure it is after the last slash!
893  size_t j = findLastSlash(f);
894  if ((j == std::string::npos) || (i > j)) {
895  ext = f.substr(i + 1, f.size() - i - 1);
896  f = f.substr(0, i);
897  }
898  }
899  }
900 
901  // Pull the basename off
902  {
903  // Find the last slash
904  size_t i = findLastSlash(f);
905 
906  if (i == std::string::npos) {
907 
908  // There is no slash; the basename is the whole thing
909  base = f;
910  f = "";
911 
912  } else if ((i != std::string::npos) && (i < f.size() - 1)) {
913 
914  base = f.substr(i + 1, f.size() - i - 1);
915  f = f.substr(0, i);
916 
917  }
918  }
919 
920  // Parse what remains into path.
921  size_t prev, cur = 0;
922 
923  while (cur < f.size()) {
924  prev = cur;
925 
926  // Allow either slash
927  size_t i = f.find('/', prev + 1);
928  size_t j = f.find('\\', prev + 1);
929  if (i == std::string::npos) {
930  i = f.size();
931  }
932 
933  if (j == std::string::npos) {
934  j = f.size();
935  }
936 
937  cur = min(i, j);
938 
939  if (cur == std::string::npos) {
940  cur = f.size();
941  }
942 
943  path.append(f.substr(prev, cur - prev));
944  ++cur;
945  }
946 }
size_t findLastSlash(const std::string &f, size_t start=std::string::npos)
Definition: stringutils.h:58
T min(const T &x, const T &y)
Definition: g3dmath.h:305
bool isSlash(const unsigned char c)
Definition: stringutils.h:175
static std::string ext(const std::string &path)
Definition: FileSystem.cpp:755
void clear(bool shrink=true)
Definition: Array.h:407
static std::string base(const std::string &path)
Definition: FileSystem.cpp:783
int prev(int i, int n)
Definition: RecastContour.cpp:468
void append(const T &value)
Definition: Array.h:583

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::string G3D::FilePath::removeTrailingSlash ( const std::string &  f)
static

Removes the trailing slash unless f is a filesystem root

736  {
737  bool removeSlash = ((endsWith(f, "/") || endsWith(f, "\\"))) && ! isRoot(f);
738 
739  return removeSlash ? f.substr(0, f.length() - 1) : f;
740 }
static bool isRoot(const std::string &f)
Definition: FileSystem.cpp:698
bool endsWith(const std::string &test, const std::string &pattern)
Returns true if the test string ends with the pattern string.
Definition: stringutils.cpp:127

+ Here is the call graph for this function:

+ Here is the caller graph for this function:


The documentation for this class was generated from the following files: