Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Core/GameEngine/Include/Common/FileSystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,8 @@ class FileSystem : public SubsystemInterface
static bool removeExtension(AsciiString& path);
static bool removeExtension(UnicodeString& path);

static void appendPathSeparator(AsciiString& path); ///< appends the platform separator, unless the path is empty or already ends with either separator.

protected:
#if ENABLE_FILESYSTEM_EXISTENCE_CACHE
struct FileExistData
Expand Down
11 changes: 11 additions & 0 deletions Core/GameEngine/Source/Common/System/FileSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,17 @@ bool FileSystem::removeExtension(AsciiString& path)
return false;
}

//============================================================================
// FileSystem::appendPathSeparator
//============================================================================
void FileSystem::appendPathSeparator(AsciiString& path)
{
if (path.isNotEmpty() && !isPathSeparator(path.getCharAt(path.getLength() - 1)))
{
path.concat(getNativePathSeparator());
}
}

//============================================================================
// FileSystem::removeExtension - Unicode handling variant
//============================================================================
Expand Down
57 changes: 21 additions & 36 deletions Core/GameEngine/Source/GameNetwork/FileTransfer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,12 @@

#include "PreRTS.h" // This must go first in EVERY cpp file in the GameEngine

#include "Common/FileSystem.h"
#include "GameClient/LoadScreen.h"
#include "GameClient/Shell.h"
#include "GameNetwork/FileTransfer.h"
#include "GameNetwork/networkutil.h"
#include "Lib/PathUtil.h"

//-------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------
Expand Down Expand Up @@ -137,7 +139,7 @@ static Bool doFileTransfer( AsciiString filename, MapTransferLoadScreen *ls, Int

AsciiString GetBasePathFromPath( AsciiString path )
{
const char *s = path.reverseFind('\\');
const char *s = getLastPathSeparator(path.str());
if (s)
{
Int len = s - path.str();
Expand All @@ -153,10 +155,7 @@ AsciiString GetBasePathFromPath( AsciiString path )

AsciiString GetFileFromPath( AsciiString path )
{
const char *s = path.reverseFind('\\');
if (s)
return s+1;
return path;
return getFileName(path.str());
}

AsciiString GetExtensionFromFile( AsciiString fname )
Expand All @@ -183,59 +182,45 @@ AsciiString GetBaseFileFromFile( AsciiString fname )
return AsciiString::TheEmptyString;
}

AsciiString GetPreviewFromMap( AsciiString path )
static AsciiString GetFileInMapDirectory( const AsciiString &mapPath, const AsciiString &filename )
{
AsciiString fname = GetBaseFileFromFile(GetFileFromPath(path));
AsciiString base = GetBasePathFromPath(path);
const char *file = getFileName(mapPath.str());
AsciiString path;
path.set(mapPath.str(), file - mapPath.str());
path.concat(filename);
return path;
}

AsciiString out;
out.format("%s\\%s.tga", base.str(), fname.str());
return out;
AsciiString GetPreviewFromMap( AsciiString path )
{
FileSystem::removeExtension(path);
path.concat(".tga");
return path;
}

AsciiString GetINIFromMap( AsciiString path )
{
AsciiString base = GetBasePathFromPath(path);

AsciiString out;
out.format("%s\\map.ini", base.str());
return out;
return GetFileInMapDirectory(path, "map.ini");
}

AsciiString GetStrFileFromMap( AsciiString path )
{
AsciiString base = GetBasePathFromPath(path);

AsciiString out;
out.format("%s\\map.str", base.str());
return out;
return GetFileInMapDirectory(path, "map.str");
}

AsciiString GetSoloINIFromMap( AsciiString path )
{
AsciiString base = GetBasePathFromPath(path);

AsciiString out;
out.format("%s\\solo.ini", base.str());
return out;
return GetFileInMapDirectory(path, "solo.ini");
}

AsciiString GetAssetUsageFromMap( AsciiString path )
{
AsciiString base = GetBasePathFromPath(path);

AsciiString out;
out.format("%s\\assetusage.txt", base.str());
return out;
return GetFileInMapDirectory(path, "assetusage.txt");
}

AsciiString GetReadmeFromMap( AsciiString path )
{
AsciiString base = GetBasePathFromPath(path);

AsciiString out;
out.format("%s\\readme.txt", base.str());
return out;
return GetFileInMapDirectory(path, "readme.txt");
}

//-------------------------------------------------------------------------------------
Expand Down
43 changes: 38 additions & 5 deletions Core/Libraries/Include/Lib/PathUtil.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@
#include "BaseType.h"
#include <string.h>

inline bool isPathSeparator(char ch)
// Returns true for a separator the host platform uses to open files.
inline bool isNativePathSeparator(char ch)
{
#ifdef _WIN32
return ch == '\\' || ch == '/';
Expand All @@ -32,21 +33,27 @@ inline bool isPathSeparator(char ch)
#endif
}

// Returns true for either separator. Game data paths carry '\\' on every platform.
inline bool isPathSeparator(char ch)
{
return ch == '/' || ch == '\\';
}

inline bool isAbsolutePath(const char* path)
{
if (path == nullptr)
{
return false;
}

if (isPathSeparator(path[0]))
if (isNativePathSeparator(path[0]))
{
return true;
}

#ifdef _WIN32
const bool hasDriveLetter = (path[0] >= 'A' && path[0] <= 'Z') || (path[0] >= 'a' && path[0] <= 'z');
if (hasDriveLetter && path[1] == ':' && isPathSeparator(path[2]))
if (hasDriveLetter && path[1] == ':' && isNativePathSeparator(path[2]))
{
return true;
}
Expand All @@ -55,6 +62,32 @@ inline bool isAbsolutePath(const char* path)
return false;
}

inline char getNativePathSeparator()
{
#ifdef _WIN32
return '\\';
#else
return '/';
#endif
}

inline const char* getLastPathSeparator(const char* path)
{
return path ? maxPtr(strrchr(path, '/'), strrchr(path, '\\')) : nullptr;
}

inline const wchar_t* getLastPathSeparator(const wchar_t* path)
{
return path ? maxPtr(wcsrchr(path, L'/'), wcsrchr(path, L'\\')) : nullptr;
}

// Returns the whole path when it contains no separator
inline const char* getFileName(const char* path)
{
const char* lastSeparator = getLastPathSeparator(path);
return lastSeparator ? lastSeparator + 1 : path;
}

inline const char* getExtension(const char* path)
{
const char* lastDot = strrchr(path, '.');
Expand All @@ -64,7 +97,7 @@ inline const char* getExtension(const char* path)
return nullptr;
}

const char* lastSeparator = maxPtr(strrchr(path, '/'), strrchr(path, '\\'));
const char* lastSeparator = getLastPathSeparator(path);

// Check if the dot is contained in the filename
if (lastSeparator && lastDot < lastSeparator)
Expand All @@ -84,7 +117,7 @@ inline const wchar_t* getExtension(const wchar_t* path)
return nullptr;
}

const wchar_t* lastSeparator = maxPtr(wcsrchr(path, L'/'), wcsrchr(path, L'\\'));
const wchar_t* lastSeparator = getLastPathSeparator(path);

// Check if the dot is contained in the filename
if (lastSeparator && lastDot < lastSeparator)
Expand Down
Loading