Browse Source

Merge pull request #1800 from MineGame159/string_changes

String changes
Brian Fiete 2 years ago
parent
commit
7abecdbdb5
1 changed files with 102 additions and 47 deletions
  1. 102 47
      BeefLibs/corlib/src/String.bf

+ 102 - 47
BeefLibs/corlib/src/String.bf

@@ -2125,18 +2125,18 @@ namespace System
 			return UTF8.Decode(ptr + idx, mLength - idx).c == c;
 		}
 
-		private void ReplaceLargerHelper(String find, String replace)
+		private void ReplaceLargerHelper(StringView find, StringView replace)
 		{
 			List<int> replaceEntries = scope List<int>(8192);
 			
-			int_strsize moveOffset = replace.mLength - find.mLength;
+			int_strsize moveOffset = (.) (replace.Length - find.Length);
 
-			for (int startIdx = 0; startIdx <= mLength - find.mLength; startIdx++)
+			for (int startIdx = 0; startIdx <= mLength - find.Length; startIdx++)
 			{
-				if (EqualsHelper(Ptr + startIdx, find.Ptr, find.mLength))
+				if (EqualsHelper(Ptr + startIdx, find.Ptr, find.Length))
 				{
 					replaceEntries.Add(startIdx);
-					startIdx += find.mLength - 1;
+					startIdx += find.Length - 1;
 				}
 			}
 
@@ -2154,14 +2154,14 @@ namespace System
 			for (int moveIdx = replaceEntries.Count - 1; moveIdx >= 0; moveIdx--)
 			{
 				int srcStartIdx = replaceEntries[moveIdx];
-				int srcEndIdx = srcStartIdx + find.mLength;
+				int srcEndIdx = srcStartIdx + find.Length;
 				int destStartIdx = srcStartIdx + moveIdx * moveOffset;
-				int destEndIdx = destStartIdx + replace.mLength;
+				int destEndIdx = destStartIdx + replace.Length;
 
 				for (int i = lastDestStartIdx - destEndIdx - 1; i >= 0; i--)
 					ptr[destEndIdx + i] = ptr[srcEndIdx + i];
 
-				for (int i < replace.mLength)
+				for (int i < replace.Length)
 					ptr[destStartIdx + i] = replacePtr[i];
 
 				lastDestStartIdx = destStartIdx;
@@ -2170,9 +2170,9 @@ namespace System
 			mLength = (int_strsize)destLength;
 		}
 
-		public void Replace(String find, String replace)
+		public void Replace(StringView find, StringView replace)
 		{
-			if (replace.mLength > find.mLength)
+			if (replace.Length > find.Length)
 			{
 				ReplaceLargerHelper(find, replace);
 				return;
@@ -2193,10 +2193,10 @@ namespace System
 				{
 					if (ptr[inIdx] == findC)
 					{
-						for (int i = 0; i < replace.mLength; i++)
+						for (int i = 0; i < replace.Length; i++)
 							ptr[outIdx++] = replacePtr[i];
 
-						inIdx += find.mLength;
+						inIdx += (.) find.Length;
 					}
 					else if (inIdx == outIdx)
 					{
@@ -2211,14 +2211,14 @@ namespace System
 			}
 			else
 			{
-				while (inIdx <= mLength - find.mLength)
+				while (inIdx <= mLength - find.Length)
 				{
-					if (EqualsHelper(ptr + inIdx, findPtr, find.mLength))
+					if (EqualsHelper(ptr + inIdx, findPtr, find.Length))
 					{
-						for (int i = 0; i < replace.mLength; i++)
+						for (int i = 0; i < replace.Length; i++)
 							ptr[outIdx++] = replacePtr[i];
 
-						inIdx += find.mLength;
+						inIdx += (.) find.Length;
 					}
 					else if (inIdx == outIdx)
 					{
@@ -2248,6 +2248,53 @@ namespace System
 			mLength = outIdx;
 		}
 
+		public void Replace(int start, int length, StringView replaceWith)
+		{
+			Debug.Assert(start >= 0 && start <= Length);
+			Debug.Assert(length >= 0 && length <= Length - start);
+
+			if (replaceWith.IsEmpty)
+				return;
+
+			if (replaceWith.Length == length)
+			{
+				Internal.MemCpy(&Ptr[start], replaceWith.Ptr, length);
+			}
+			else if (replaceWith.Length > length)
+			{
+				int additional = replaceWith.Length - length;
+				CalculatedReserve(Length + additional);
+				
+				if (start + length < Length)
+					Internal.MemMove(&Ptr[start + replaceWith.Length], &Ptr[start + length], Length - (start + length));
+
+				mLength += (.) additional;
+
+				Internal.MemCpy(&Ptr[start], replaceWith.Ptr, replaceWith.Length);
+			}
+			else
+			{
+				int difference = length - replaceWith.Length;
+
+				Internal.MemCpy(&Ptr[start], replaceWith.Ptr, replaceWith.Length);
+
+				if (start + length < Length)
+					Internal.MemMove(&Ptr[start + replaceWith.Length], &Ptr[start + length], Length - (start + length));
+
+				mLength -= (.) difference;
+			}
+		}
+		
+		public void Replace(IndexRange range, StringView replaceWith)
+		{
+			StringView view = this;
+
+			int start = view.[Friend]GetRangeStart(range);
+			int end = view.[Friend]GetRangeEnd(range);
+
+			Replace(start, end - start, replaceWith);
+		}
+
 		public void TrimEnd()
 		{
 			let ptr = Ptr;
@@ -3461,43 +3508,51 @@ namespace System
 #endif
 			get
 			{
-				char8* start;
-				switch (range.[Friend]mStart)
+				int start = GetRangeStart(range);
+				int end = GetRangeEnd(range);
+
+				return .(mPtr + start, end - start);
+			}
+		}
+
+		private int GetRangeStart(IndexRange range)
+		{
+			switch (range.Start)
+			{
+			case .FromFront(let offset):
+				Debug.Assert((uint)offset <= (uint)mLength);
+				return offset;
+			case .FromEnd(let offset):
+				Debug.Assert((uint)offset <= (uint)mLength);
+				return mLength - offset;
+			}
+		}
+
+		private int GetRangeEnd(IndexRange range)
+		{
+			if (range.IsClosed)
+			{
+				switch (range.End)
 				{
 				case .FromFront(let offset):
-					Debug.Assert((uint)offset <= (uint)mLength);
-					start = mPtr + offset;
+					Debug.Assert((uint)offset < (uint)mLength);
+					return offset + 1;
 				case .FromEnd(let offset):
-					Debug.Assert((uint)offset <= (uint)mLength);
-					start = mPtr + mLength - offset;
-				}
-				char8* end;
-				if (range.[Friend]mIsClosed)
-				{
-					switch (range.[Friend]mEnd)
-					{
-					case .FromFront(let offset):
-						Debug.Assert((uint)offset < (uint)mLength);
-						end = mPtr + offset + 1;
-					case .FromEnd(let offset):
-						Debug.Assert((uint)(offset - 1) <= (uint)mLength);
-						end = mPtr + mLength - offset + 1;
-					}
+					Debug.Assert((uint)(offset - 1) <= (uint)mLength);
+					return mLength - offset + 1;
 				}
-				else
+			}
+			else
+			{
+				switch (range.End)
 				{
-					switch (range.[Friend]mEnd)
-					{
-					case .FromFront(let offset):
-						Debug.Assert((uint)offset <= (uint)mLength);
-						end = mPtr + offset;
-					case .FromEnd(let offset):
-						Debug.Assert((uint)offset <= (uint)mLength);
-						end = mPtr + mLength - offset;
-					}
+				case .FromFront(let offset):
+					Debug.Assert((uint)offset <= (uint)mLength);
+					return offset;
+				case .FromEnd(let offset):
+					Debug.Assert((uint)offset <= (uint)mLength);
+					return mLength - offset;
 				}
-
-				return .(start, end - start);
 			}
 		}