Quellcode durchsuchen

Added GetRelativePath

Brian Fiete vor 2 Jahren
Ursprung
Commit
990b509111
2 geänderte Dateien mit 135 neuen und 42 gelöschten Zeilen
  1. 134 42
      BeefySysLib/Common.cpp
  2. 1 0
      BeefySysLib/Common.h

+ 134 - 42
BeefySysLib/Common.cpp

@@ -2,7 +2,7 @@
 #include "util/BumpAllocator.h"
 #include "util/UTF8.h"
 #include "util/String.h"
-//#include "farts.z"   
+//#include "farts.z"
 #include <string.h>
 #include "platform/PlatformHelper.h"
 
@@ -48,11 +48,11 @@ UTF16String Beefy::ToWString(const StringImpl& theString)
 
 // String Beefy::ToString(const UTF16String& theString)
 // {
-// 	String newString;	
+// 	String newString;
 // 	newString.Reserve((intptr)theString.length());
 // 	for (int i = 0; i < (int)theString.length(); ++i)
 // 	{
-// 		const unsigned int c = (unsigned int)theString[i];		
+// 		const unsigned int c = (unsigned int)theString[i];
 // 		newString.Append(char(c & 0xFF));
 // 	}
 // 	return newString;
@@ -67,9 +67,9 @@ String Beefy::ToUpper(const StringImpl& theString)
 }
 
 void Beefy::MakeUpper(StringImpl& theString)
-{	
+{
 	for (int i = 0; i < (int)theString.length(); ++i)
-		theString[i] = toupper(theString[i]);	
+		theString[i] = toupper(theString[i]);
 }
 
 UTF16String Beefy::ToUpper(const UTF16String& theString)
@@ -101,14 +101,14 @@ String Beefy::ToLower(const StringImpl& theString)
 // 	int left = 0;
 // 	while ((left < (int) theString.length() - 1) && (iswspace(theString[left])))
 // 		left++;
-// 
+//
 // 	int right = (int)theString.length() - 1;
 // 	while ((right >= left) && (iswspace(theString[right])))
 // 		right--;
-// 
+//
 // 	if ((left == 0) && (right == theString.length() - 1))
 // 		return theString;
-// 	
+//
 // 	return theString.substr(left, right - left + 1);
 // }
 
@@ -124,7 +124,7 @@ String Beefy::Trim(const StringImpl& theString)
 
 	if ((left == 0) && (right == theString.length() - 1))
 		return theString;
-	
+
 	return theString.Substring(left, right - left + 1);
 }
 
@@ -155,7 +155,7 @@ String Beefy::SlashString(const StringImpl& str, bool utf8decode, bool utf8encod
 {
 	bool prevEndedInSlashedNum = false;
 	String outStr;
-	
+
 	bool noNextHex = false;
 
 	bool lastWasVisibleChar = false;
@@ -217,7 +217,7 @@ String Beefy::SlashString(const StringImpl& str, bool utf8decode, bool utf8encod
 				// Need to break string to allow proper evaluation of slashed string
 				if (prevEndedInSlashedNum)
 					outStr += "\" \"";
-			}			
+			}
 
 			// May be UTF8 byte.  Make sure it's valid before we add it, otherwise write the bytes in direct "\x" style
 			if (((uint8)c >= 0x80) && (utf8decode))
@@ -295,7 +295,7 @@ String Beefy::SlashString(const StringImpl& str, bool utf8decode, bool utf8encod
 			}
 
 			if (((uint8)c >= 0x80) && (utf8encode))
-			{				
+			{
 				outStr += (char)(0xC0 | (((uint8)c & 0xFF) >> 6));
 				outStr += (char)(0x80 | ((uint8)c & 0x3F));
 				isVisibleChar = true;
@@ -330,7 +330,7 @@ String Beefy::SlashString(const StringImpl& str, bool utf8decode, bool utf8encod
 UTF16String Beefy::UTF8Decode(const StringImpl& theString)
 {
 	UTF16String strOut;
-	
+
 	int strLen = 0;
 	char* cPtr = (char*)theString.c_str();
 	int lenLeft = (int)theString.length();
@@ -345,7 +345,7 @@ UTF16String Beefy::UTF8Decode(const StringImpl& theString)
 		cPtr += seqLen;
 		lenLeft -= seqLen;
 	}
-	
+
 	strOut.ResizeRaw(strLen + 1);
 	strOut[strLen] = 0;
 
@@ -360,12 +360,12 @@ UTF16String Beefy::UTF8Decode(const StringImpl& theString)
 		if ((c32 >= 0x10000) && (sizeof(wchar_t) == 2))
 		{
 			*(wcPtr++) = (wchar_t)(((c32 - 0x10000) >> 10) + 0xD800);
-			*(wcPtr++) = (wchar_t)(((c32 - 0x10000) & 0x3FF) + 0xDC00);			
+			*(wcPtr++) = (wchar_t)(((c32 - 0x10000) & 0x3FF) + 0xDC00);
 			wcLenLeft -= 2;
 		}
 		else
 		{
-			*(wcPtr++) = (wchar_t)c32;			
+			*(wcPtr++) = (wchar_t)c32;
 			wcLenLeft -= 1;
 		}
 		cPtr += seqLen;
@@ -382,7 +382,7 @@ String Beefy::UTF8Encode(const uint16* theString, int length)
 
 	String strOut;
 	int utf8Len = 0;
-	uint16 utf16hi = 0;	
+	uint16 utf16hi = 0;
 	for (int i = 0; i < length; i++)
 	{
 		uint16 c = theString[i];
@@ -406,7 +406,7 @@ String Beefy::UTF8Encode(const uint16* theString, int length)
 	for (int i = 0; i < length; i++)
 	{
 		uint16 c = theString[i];
-		uint32 c32 = c;			
+		uint32 c32 = c;
 		if ((c >= 0xD800) && (c < 0xDC00))
 		{
 			utf16hi = (uint16)c;
@@ -452,7 +452,7 @@ UTF16String Beefy::UTF16Decode(const uint16* theString)
 		for (int pos = 0; pos < len; pos++)
 			str[pos] = (wchar_t)theString[pos];
 		return str;
-	}	
+	}
 }
 
 static const char gHexChar[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
@@ -466,13 +466,13 @@ String Beefy::FileNameToURI(const StringImpl& fileName)
 	for (int i = 0; i < (int)fileName.length(); i++)
 	{
 		char c = out[i];
-		
-		bool isValid = 
+
+		bool isValid =
 			((c >= '@' && c <= 'Z') ||
 			 (c >= 'a' && c <= 'z') ||
 			 (c >= '&' && c < 0x3b) ||
 			 (c == '!') || (c == '$') || (c == '_') || (c == '=') || (c == '~'));
-		
+
 		if ((((unsigned char)c) >= 0x80) || (!isValid))
 		{
 			out += '%';
@@ -515,14 +515,14 @@ static const char c64bToChar[] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
 	'W', 'X', 'Y', 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.', '_'};
 void Beefy::EncodeULEB32(uint64 value, StringImpl& buffer)
 {
-	do 
+	do
 	{
 		uint8 byteVal = value & 0x1f;
 		value >>= 5;
 		if (value != 0)
 			byteVal |= 0x20; // Mark this byte to show that more bytes will follow
 		buffer.Append(c64bToChar[byteVal]);
-	} 
+	}
 	while (value != 0);
 }
 
@@ -601,7 +601,7 @@ void Beefy::ExactMinimalDoubleToStr(double d, char* str)
 	{
 		char c = cPtrLast[1];
 		if ((c == 0) || (c == 'e'))
-			break;	
+			break;
 		cPtrLast++;
 	}
 	char* cStrEnd = cPtrLast + 1;
@@ -622,10 +622,10 @@ void Beefy::ExactMinimalDoubleToStr(double d, char* str)
 	else
 	{
 		return; // Not a 'transitional' representation
-	}	
+	}
 
 	do
-	{	
+	{
 		*cPtrLast = 0;
 		cPtrLast--;
 	}
@@ -637,7 +637,7 @@ void Beefy::ExactMinimalDoubleToStr(double d, char* str)
 
 	// Verify that our pretty representation is equivalent
 	double checkD = 0;
-	sscanf(str, "%lf", &checkD);	
+	sscanf(str, "%lf", &checkD);
 	if (d == checkD)
 		return;
 
@@ -823,7 +823,7 @@ String Beefy::vformat(const char* fmt, va_list argPtr)
 }
 #endif
 
-String Beefy::StrFormat(const char* fmt ...) 
+String Beefy::StrFormat(const char* fmt ...)
 {
     va_list argList;
     va_start(argList, fmt);
@@ -899,7 +899,7 @@ char* Beefy::LoadTextData(const StringImpl& path, int* size)
 	{
 		//UTF16 LE
 
-		int dataLen = fileSize - 2;		
+		int dataLen = fileSize - 2;
 		char* data = new char[dataLen + 2];
 		data[0] = (char)charHeader[2];
 		data[dataLen] = 0;
@@ -910,7 +910,7 @@ char* Beefy::LoadTextData(const StringImpl& path, int* size)
 
 		// UTF16
 		UTF16String str;
-		str.Set((wchar_t*)data);		
+		str.Set((wchar_t*)data);
 		delete [] data;
 
 		String utf8Str = UTF8Encode(str);
@@ -923,18 +923,18 @@ char* Beefy::LoadTextData(const StringImpl& path, int* size)
 		return utf8Data;
 	}
 	else if ((charHeader[0] == 0xEF) && (charHeader[1] == 0xBB) && (charHeader[2] == 0xBF))
-	{		
+	{
 		strLen = fileSize - 3;
-		char* data = new char[strLen + 1];		
+		char* data = new char[strLen + 1];
 		data[strLen] = 0;
 		if (size != NULL)
 			*size = strLen;
 		int readSize = (int)fread(data, 1, strLen, fP);
 		(void)readSize;
-		fclose(fP);		
+		fclose(fP);
 		return data;
 	}
-	
+
 	if (size != NULL)
 		*size = strLen;
 	char* data = new char[strLen + 1];
@@ -957,7 +957,7 @@ bool Beefy::LoadTextData(const StringImpl& path, StringImpl& str)
 	if (data == NULL)
 		return false;
 	if ((str.mAllocSizeAndFlags & StringImpl::DynAllocFlag) != 0)
-		str.Release();	
+		str.Release();
 	str.mPtr = data;
 	str.mAllocSizeAndFlags = size | StringImpl::DynAllocFlag | StringImpl::StrPtrFlag;
 	str.mLength = size;
@@ -1044,6 +1044,98 @@ String Beefy::GetFileExtension(const StringImpl& path)
 	return path.Substring(dotPos);
 }
 
+static String GetDriveStringTo(String path)
+{
+	if ((path.length() >= 2) && (path[1] == ':'))
+		return String(path, 0, 2);
+	return "";
+}
+
+String Beefy::GetRelativePath(const StringImpl& fullPath, const StringImpl& curDir)
+{
+	String curPath1 = String(curDir);
+	String curPath2 = String(fullPath);
+
+	for (int i = 0; i < (int)curPath1.length(); i++)
+		if (curPath1[i] == DIR_SEP_CHAR_ALT)
+			curPath1[i] = DIR_SEP_CHAR;
+
+	for (int i = 0; i < (int)curPath2.length(); i++)
+		if (curPath2[i] == DIR_SEP_CHAR_ALT)
+			curPath2[i] = DIR_SEP_CHAR;
+
+	String driveString1 = GetDriveStringTo(curPath1);
+	String driveString2 = GetDriveStringTo(curPath2);
+
+#ifdef _WIN32
+	StringImpl::CompareKind compareType = StringImpl::CompareKind_OrdinalIgnoreCase;
+#else
+	StringImpl::CompareKind compareType = StringImpl::CompareKind_Ordinal;
+#endif
+
+	// On separate drives?
+	if (!driveString1.Equals(driveString2, compareType))
+	{
+		return fullPath;
+	}
+
+	if (driveString1.mLength > 0)
+		curPath1.Remove(0, BF_MIN(driveString1.mLength + 1, curPath1.mLength));
+	if (driveString2.mLength > 0)
+		curPath2.Remove(0, BF_MIN(driveString2.mLength + 1, curPath2.mLength));
+
+	while ((curPath1.mLength > 0) && (curPath2.mLength > 0))
+	{
+		int slashPos1 = (int)curPath1.IndexOf(DIR_SEP_CHAR);
+		if (slashPos1 == -1)
+			slashPos1 = curPath1.mLength;
+		int slashPos2 = (int)curPath2.IndexOf(DIR_SEP_CHAR);
+		if (slashPos2 == -1)
+			slashPos2 = curPath2.mLength;
+
+		String section1;
+		section1.Append(StringView(curPath1, 0, slashPos1));
+		String section2;
+		section2.Append(StringView(curPath2, 0, slashPos2));
+
+		if (!section1.Equals(section2, compareType))
+		{
+			// a/b/c
+			// d/e/f
+
+			while (curPath1.mLength > 0)
+			{
+				slashPos1 = (int)curPath1.IndexOf(DIR_SEP_CHAR);
+				if (slashPos1 == -1)
+					slashPos1 = curPath1.mLength;
+
+				if (slashPos1 + 1 >= curPath1.mLength)
+					curPath1.Clear();
+				else
+					curPath1.Remove(0, slashPos1 + 1);
+				if (DIR_SEP_CHAR == '\\')
+					curPath2.Insert(0, "..\\");
+				else
+					curPath2.Insert(0, "../");
+			}
+		}
+		else
+		{
+			if (slashPos1 + 1 >= curPath1.mLength)
+				curPath1.Clear();
+			else
+				curPath1.Remove(0, slashPos1 + 1);
+
+			if (slashPos2 + 2 >= curPath2.mLength)
+				curPath1 = "";
+			else
+				curPath2.Remove(0, slashPos2 + 1);
+		}
+	}
+
+	return curPath2;
+}
+
 String Beefy::GetAbsPath(const StringImpl& relPathIn, const StringImpl& dir)
 {
 	String relPath = relPathIn;
@@ -1119,7 +1211,7 @@ String Beefy::GetAbsPath(const StringImpl& relPathIn, const StringImpl& dir)
 		}
 		else if (chDir != ".")
 		{
-			newPath += chDir + slashChar;			
+			newPath += chDir + slashChar;
 			break;
 		}
 	}
@@ -1129,7 +1221,7 @@ String Beefy::GetAbsPath(const StringImpl& relPathIn, const StringImpl& dir)
 	newPath += relPath.Substring(relIdx);
 
 	return newPath;
-} 
+}
 
 String Beefy::FixPath(const StringImpl& pathIn)
 {
@@ -1144,7 +1236,7 @@ String Beefy::FixPath(const StringImpl& pathIn)
 			for (int checkIdx = i - 3; checkIdx >= 0; checkIdx--)
 			{
 				if ((path[checkIdx] == '\\') || (path[checkIdx] == '/'))
-				{					
+				{
 					path = path.Substring(0, checkIdx) + path.Substring(i + 1);
 					i = checkIdx;
 					break;
@@ -1189,10 +1281,10 @@ String Beefy::RemoveTrailingSlash(const StringImpl& str)
 
 bool Beefy::FileNameEquals(const StringImpl& filePathA, const StringImpl& filePathB)
 {
-#ifdef _WIN32	
+#ifdef _WIN32
 	if (filePathA.length() != filePathB.length())
 		return false;
-	
+
 	const char* aPtr = filePathA.c_str();
 	const char* bPtr = filePathB.c_str();
 	while (true)
@@ -1250,7 +1342,7 @@ bool Beefy::RecursiveDeleteDirectory(const StringImpl& dirPath)
 	BfpFileResult result;
 	BfpFindFileData* findFileData = BfpFindFileData_FindFirstFile(findSpec.c_str(), (BfpFindFileFlags)(BfpFindFileFlag_Directories | BfpFindFileFlag_Files), &result);
 	if (result == BfpFileResult_Ok)
-	{		
+	{
 		while (true)
 		{
 			Beefy::String fileName;

+ 1 - 0
BeefySysLib/Common.h

@@ -226,6 +226,7 @@ int64 GetFileTimeWrite(const StringImpl& path);
 String GetFileDir(const StringImpl& path);
 String GetFileName(const StringImpl& path);
 String GetFileExtension(const StringImpl& path);
+String GetRelativePath(const StringImpl& fullPath, const StringImpl& curDir);
 String GetAbsPath(const StringImpl& relPath, const StringImpl& dir);
 String FixPath(const StringImpl& path);
 String FixPathAndCase(const StringImpl& path);