Browse Source

Convert plFileName to "has-a" model for better semantics.

You're welcome, branan ;)
Michael Hansen 12 years ago
parent
commit
f736d81cd8
  1. 3
      Sources/Plasma/CoreLib/hsStream.h
  2. 77
      Sources/Plasma/CoreLib/plString.cpp
  3. 50
      Sources/Plasma/CoreLib/plString.h

3
Sources/Plasma/CoreLib/hsStream.h

@ -84,7 +84,8 @@ public:
virtual ~hsStream() { } virtual ~hsStream() { }
// Pre-filename-stringification shortcut: // Pre-filename-stringification shortcut:
bool Open_TEMP(const plFileName & filename, const char * mode = "rb") { return Open(filename.c_str(), mode); } bool Open_TEMP(const plFileName & filename, const char * mode = "rb")
{ return Open(filename.AsString().c_str(), mode); }
virtual bool Open(const char *, const char * = "rb")=0; virtual bool Open(const char *, const char * = "rb")=0;
virtual bool Open(const wchar_t *, const wchar_t * = L"rb")=0; virtual bool Open(const wchar_t *, const wchar_t * = L"rb")=0;

77
Sources/Plasma/CoreLib/plString.cpp

@ -880,88 +880,107 @@ size_t ustrlen(const UniChar *ustr, size_t max)
/* plFileName */ /* plFileName */
static_assert(sizeof(plFileName) == sizeof(plString),
"plFileName should be a thin wrapper around plString");
plString plFileName::GetFileName() const plString plFileName::GetFileName() const
{ {
int end = FindLast('/'); int end = fName.FindLast('/');
if (end < 0) if (end < 0)
end = FindLast('\\'); end = fName.FindLast('\\');
if (end < 0) if (end < 0)
return *this; return fName;
return Substr(end + 1); return fName.Substr(end + 1);
} }
plString plFileName::GetFileExt() const plString plFileName::GetFileExt() const
{ {
int dot = FindLast('.'); int dot = fName.FindLast('.');
// Be sure not to get a dot in the directory! // Be sure not to get a dot in the directory!
int end = FindLast('/'); int end = fName.FindLast('/');
if (end < 0) if (end < 0)
end = FindLast('\\'); end = fName.FindLast('\\');
if (dot > end) if (dot > end)
return Substr(dot + 1); return fName.Substr(dot + 1);
return plString::Null; return plString::Null;
} }
plString plFileName::GetFileNameNoExt() const plString plFileName::GetFileNameNoExt() const
{ {
int dot = FindLast('.'); int dot = fName.FindLast('.');
int end = FindLast('/'); int end = fName.FindLast('/');
if (end < 0) if (end < 0)
end = FindLast('\\'); end = fName.FindLast('\\');
// Be sure not to get a dot in the directory! // Be sure not to get a dot in the directory!
if (dot > end) if (dot > end)
return Substr(end + 1, dot - end - 1); return fName.Substr(end + 1, dot - end - 1);
return Substr(end + 1); return fName.Substr(end + 1);
} }
plFileName plFileName::StripFileName() const plFileName plFileName::StripFileName() const
{ {
int end = FindLast('/'); int end = fName.FindLast('/');
if (end < 0) if (end < 0)
end = FindLast('\\'); end = fName.FindLast('\\');
if (end < 0) if (end < 0)
return *this; return *this;
return Left(end); return fName.Left(end);
} }
plFileName plFileName::StripFileExt() const plFileName plFileName::StripFileExt() const
{ {
int dot = FindLast('.'); int dot = fName.FindLast('.');
// Be sure not to get a dot in the directory! // Be sure not to get a dot in the directory!
int end = FindLast('/'); int end = fName.FindLast('/');
if (end < 0) if (end < 0)
end = FindLast('\\'); end = fName.FindLast('\\');
if (dot > end) if (dot > end)
return Left(dot); return fName.Left(dot);
return *this; return *this;
} }
plFileName plFileName::Normalize(char slash) const
{
plStringBuffer<char> norm;
char *norm_p = norm.CreateWritableBuffer(fName.GetSize());
for (const char *p = fName.c_str(); *p; ++p) {
if (*p == '/' || *p == '\\')
*norm_p++ = slash;
else
*norm_p++ = *p;
}
*norm_p = 0;
return plString(norm);
}
plFileName plFileName::Join(const plFileName &base, const plFileName &path) plFileName plFileName::Join(const plFileName &base, const plFileName &path)
{ {
if (base.IsEmpty()) if (!base.IsValid())
return path; return path;
if (path.IsEmpty()) if (!path.IsValid())
return base; return base;
char last = base.CharAt(base.GetSize() - 1); char last = base.fName.CharAt(base.GetSize() - 1);
char first = path.CharAt(0); char first = path.fName.CharAt(0);
if (last != '/' && last != '\\') { if (last != '/' && last != '\\') {
if (first != '/' && first != '\\') if (first != '/' && first != '\\') {
return plString::Format("%s" PATH_SEPARATOR_STR "%s", base.c_str(), path.c_str()); return plString::Format("%s" PATH_SEPARATOR_STR "%s",
return base + path; base.fName.c_str(), path.fName.c_str());
}
return base.fName + path.fName;
} else if (first != '/' && first != '\\') { } else if (first != '/' && first != '\\') {
return base + path; return base.fName + path.fName;
} }
// Both have a slash, but we only need one // Both have a slash, but we only need one
return base + path.Substr(1); return base.fName + path.fName.Substr(1);
} }

50
Sources/Plasma/CoreLib/plString.h

@ -672,20 +672,52 @@ size_t ustrlen(const UniChar *ustr, size_t max = plString::kSizeAuto);
/** Subclass of plString with specific methods to help deal with common /** Subclass of plString with specific methods to help deal with common
* filename manipulation tasks. * filename manipulation tasks.
*/ */
class plFileName : public plString class plFileName
{ {
public: public:
/** Construct an empty filename. */ /** Construct an empty filename. */
plFileName() { } plFileName() { }
/** Construct a filename from the UTF-8 character data in \a cstr. */ /** Construct a filename from the UTF-8 character data in \a cstr. */
plFileName(const char *cstr) : plString(cstr) { } plFileName(const char *cstr) : fName(cstr) { }
/** Construct a filename from the plString argument \a copy. */ /** Construct a filename from the plString argument \a copy. */
plFileName(const plString &copy) : plString(copy) { } plFileName(const plString &copy) : fName(copy) { }
/** Copy constructor. */ /** Copy constructor. */
plFileName(const plFileName &copy) : plString(copy) { } plFileName(const plFileName &copy) : fName(copy.fName) { }
/** Assignment operator. Same as plFileName(const char *). */
plFileName &operator=(const char *cstr)
{
fName.operator=(cstr);
return *this;
}
/** Assignment operator. Same as plFileName(const plString &). */
plFileName &operator=(const plString &copy)
{
fName.operator=(copy);
return *this;
}
/** Assignment operator. Same as plFileName(const plFileName &). */
plFileName &operator=(const plFileName &copy)
{
fName.operator=(copy.fName);
return *this;
}
/** Return whether this filename is valid (not empty). */
bool IsValid() const { return !fName.IsEmpty(); }
/** Return the length of the filename string (UTF-8). */
size_t GetSize() const { return fName.GetSize(); }
/** Convert the filename to a string. This does not resolve relative
* paths or normalize slashes, it just returns the stored name string.
*/
const plString &AsString() const { return fName; }
/** Return the name portion of the path (including extension). /** Return the name portion of the path (including extension).
* For example: * For example:
@ -717,6 +749,13 @@ public:
*/ */
plFileName StripFileExt() const; plFileName StripFileExt() const;
/** Normalize slashes to a particular format. By default, we use the
* OS's native slash format.
* For example:
* <pre>plFileName("C:\\Path/Filename.ext").Normalize("\\") => "C:\\Path\\Filename.ext"</pre>
*/
plFileName Normalize(char slash = PATH_SEPARATOR) const;
/** Join two path components together with the correct path separator. /** Join two path components together with the correct path separator.
* For example: * For example:
* <pre>plFileName::Join("C:\\Path", "Filename.ext") => "C:\\Path\\Filename.ext"</pre> * <pre>plFileName::Join("C:\\Path", "Filename.ext") => "C:\\Path\\Filename.ext"</pre>
@ -736,6 +775,9 @@ public:
static plFileName Join(const plFileName &base, const plFileName &path, static plFileName Join(const plFileName &base, const plFileName &path,
const plFileName& path2, const plFileName &path3) const plFileName& path2, const plFileName &path3)
{ return Join(Join(Join(base, path), path2), path3); } { return Join(Join(Join(base, path), path2), path3); }
private:
plString fName;
}; };
#endif //plString_Defined #endif //plString_Defined

Loading…
Cancel
Save