Skip to content

Commit 8d50e05

Browse files
committed
Implemented filesystem::getShortPathForm()
1 parent 24ecb80 commit 8d50e05

File tree

2 files changed

+79
-0
lines changed

2 files changed

+79
-0
lines changed

src/common/filesystemfunc.cpp

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include "filesystemfunc.h"
66

77
#include <direct.h> //for _getcwd()
8+
#include <algorithm> //for std::transform()
89

910
#include <sys/types.h>
1011
#include <sys/stat.h>
@@ -13,6 +14,7 @@
1314
#endif
1415
#ifdef WIN32
1516
#define stat _stat
17+
#include <Windows.h> //for GetShortPathName()
1618
#endif
1719

1820
namespace filesystem
@@ -106,6 +108,74 @@ namespace filesystem
106108
return parent;
107109
}
108110

111+
std::string getShortPathForm(const std::string & iPath)
112+
{
113+
//ASSERT_TRUE(getShortPathForm("a b c.txt") == "ABC~1.TXT");
114+
//ASSERT_TRUE(getShortPathForm("abcdefgh.text") == "ABCDEF~1.TEX");
115+
//ASSERT_TRUE(getShortPathForm("abcdefghijklmnopqrstuvwxyz.txt") == "ABCDEF~1.TXT");
116+
//ASSERT_TRUE(getShortPathForm("abcde.t x t") == "ABCDE~1.TXT");
117+
//ASSERT_TRUE(getShortPathForm("Program Files (x86)") == "PROGRA~1");
118+
119+
std::string shortPath;
120+
#ifdef _WIN32
121+
// First obtain the size needed by passing NULL and 0.
122+
long length = GetShortPathName(iPath.c_str(), NULL, 0);
123+
if (length == 0)
124+
return "";
125+
126+
// Dynamically allocate the correct size
127+
// (terminating null char was included in length)
128+
char * buffer = new char[length];
129+
130+
// Now simply call again using same long path.
131+
length = GetShortPathName(iPath.c_str(), buffer, length);
132+
if (length == 0)
133+
return "";
134+
135+
shortPath = buffer;
136+
137+
delete [] buffer;
138+
#else
139+
std::vector<std::string> pathElements;
140+
splitPath(iPath, pathElements);
141+
for(size_t i=0; i<pathElements.size(); i++)
142+
{
143+
const std::string & element = pathElements[i];
144+
if (element.size() > 12 || element.find(' ') != std::string::npos)
145+
{
146+
std::string element83 = element;
147+
std::string ext = getFileExtention(element);
148+
stringfunc::strReplace(element83, (std::string(".")+ext).c_str(), ""); //remove extension from filename
149+
stringfunc::strReplace(ext, " ", ""); //remove spaces in extension
150+
ext = ext.substr(0, 3); //truncate file extension
151+
stringfunc::strReplace(element83, " ", ""); //remove spaces
152+
element83 = element83.substr(0, 6); //truncate file name
153+
element83.append("~1");
154+
if (!ext.empty())
155+
{
156+
element83.append(".");
157+
element83.append(ext);
158+
}
159+
160+
//uppercase everything
161+
std::transform(element83.begin(), element83.end(), element83.begin(), ::toupper);
162+
163+
//add to shortPath
164+
if (!shortPath.empty())
165+
shortPath.append("\\");
166+
shortPath.append(element83);
167+
}
168+
else
169+
{
170+
if (!shortPath.empty())
171+
shortPath.append("\\");
172+
shortPath.append(element);
173+
}
174+
}
175+
#endif
176+
return shortPath;
177+
}
178+
109179
void splitPath(const std::string & iPath, std::string & oFolder, std::string & oFilename)
110180
{
111181
oFolder = "";

src/common/filesystemfunc.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,15 @@ namespace filesystem
6161
///<return>Returns the parent element of a path.<return>
6262
std::string getParentPath(const std::string & iPath);
6363

64+
///<summary>
65+
///Convert a long file path to the short path form (8.3 format).
66+
///If the system does not support automatic conversion, an estimated
67+
///version is returned.
68+
///</summary>
69+
///<param name="iPath">The input path to convert.</param>
70+
///<return>Returns the short path form of the given path.<return>
71+
std::string getShortPathForm(const std::string & iPath);
72+
6473
///<summary>
6574
///Splits a path into a folder and a filename.
6675
///</summary>

0 commit comments

Comments
 (0)