static void CustomFormat(StringBuffer buffer, Blah blah, StringView format) { if (format == "yes") buffer.Append("World!"); else buffer.Append("(Goodbye)"); }
public void ReduceLength() { using (var buffer = new StringBuffer()) { buffer.Append("Food"); Assert.Equal((uint)5, buffer.CharCapacity); buffer.Length = 3; Assert.Equal("Foo", buffer.ToString()); // Shouldn't reduce capacity when dropping length Assert.Equal((uint)5, buffer.CharCapacity); } }
public unsafe void CreateFromString() { string testString = "Test"; using (var buffer = new StringBuffer()) { buffer.Append(testString); Assert.Equal((uint)testString.Length, buffer.Length); Assert.Equal((uint)testString.Length + 1, buffer.CharCapacity); for (int i = 0; i < testString.Length; i++) { Assert.Equal(testString[i], buffer[(uint)i]); } // Check the null termination Assert.Equal('\0', buffer.CharPointer[testString.Length]); Assert.Equal(testString, buffer.ToString()); } }
private unsafe static string TryExpandShortFileName(StringBuffer outputBuffer, string originalPath) { // We guarantee we'll expand short names for paths that only partially exist. As such, we need to find the part of the path that actually does exist. To // avoid allocating like crazy we'll create only one input array and modify the contents with embedded nulls. Contract.Assert(!PathInternal.IsPartiallyQualified(outputBuffer), "should have resolved by now"); using (StringBuffer inputBuffer = new StringBuffer(outputBuffer)) { bool success = false; uint lastIndex = outputBuffer.Length - 1; uint foundIndex = lastIndex; uint rootLength = PathInternal.GetRootLength(outputBuffer); while (!success) { uint result = Win32Native.GetLongPathNameW(inputBuffer.GetHandle(), outputBuffer.GetHandle(), outputBuffer.CharCapacity); // Replace any temporary null we added if (inputBuffer[foundIndex] == '\0') inputBuffer[foundIndex] = '\\'; if (result == 0) { // Look to see if we couldn't find the file int error = Marshal.GetLastWin32Error(); if (error != Win32Native.ERROR_FILE_NOT_FOUND && error != Win32Native.ERROR_PATH_NOT_FOUND) { // Some other failure, give up break; } // We couldn't find the path at the given index, start looking further back in the string. foundIndex--; for (; foundIndex > rootLength && inputBuffer[foundIndex] != '\\'; foundIndex--) ; if (foundIndex == rootLength) { // Can't trim the path back any further break; } else { // Temporarily set a null in the string to get Windows to look further up the path inputBuffer[foundIndex] = '\0'; } } else if (result > outputBuffer.CharCapacity) { // Not enough space. The result count for this API does not include the null terminator. outputBuffer.EnsureCharCapacity(result); } else { // Found the path success = true; outputBuffer.Length = result; if (foundIndex < lastIndex) { // It was a partial find, put the non-existant part of the path back outputBuffer.Append(inputBuffer, foundIndex, inputBuffer.Length - foundIndex); } } } StringBuffer bufferToUse = success ? outputBuffer : inputBuffer; if (bufferToUse.SubstringEquals(originalPath)) { // Use the original path to avoid allocating return originalPath; } return bufferToUse.ToString(); } }
public void AppendOverCountWithIndexThrows() { using (var buffer = new StringBuffer()) { Assert.Throws<ArgumentOutOfRangeException>(() => buffer.Append("A", startIndex: 1, count: 1)); } }
public void AppendNegativeIndexThrows() { using (var buffer = new StringBuffer()) { Assert.Throws<ArgumentOutOfRangeException>(() => buffer.Append("a", startIndex: -1)); } }
public void AppendNullStringBufferThrows() { using (var buffer = new StringBuffer()) { Assert.Throws<ArgumentNullException>(() => buffer.Append((StringBuffer)null)); } }
public void AppendTests(string source, string value, int startIndex, int count, string expected) { // From string using (var buffer = new StringBuffer(source)) { buffer.Append(value, startIndex, count); Assert.Equal(expected, buffer.ToString()); } // From buffer using (var buffer = new StringBuffer(source)) using (var valueBuffer = new StringBuffer(value)) { if (count == -1) buffer.Append(valueBuffer, (ulong)startIndex, valueBuffer.Length - (ulong)startIndex); else buffer.Append(valueBuffer, (ulong)startIndex, (ulong)count); Assert.Equal(expected, buffer.ToString()); } }
public void StartsWith(string source, string value, bool expected) { using (var buffer = new StringBuffer()) { buffer.Append(source); Assert.Equal(expected, buffer.StartsWith(value)); } }
public void CopyToBufferString(string destination, string content, uint destinationIndex, uint bufferIndex, uint count, string expected) { using (var buffer = new StringBuffer()) using (var destinationBuffer = new StringBuffer()) { buffer.Append(content); destinationBuffer.Append(destination); buffer.CopyTo(bufferIndex, destinationBuffer, destinationIndex, count); Assert.Equal(expected, destinationBuffer.ToString()); } }
public void SubstringEqualsOverSizeCountWithIndexThrows() { using (var buffer = new StringBuffer()) { buffer.Append("A"); Assert.Throws<ArgumentOutOfRangeException>(() => buffer.SubstringEquals("", startIndex: 1, count: 1)); } }
public void TrimEnd(string content, char[] trimChars, string expected) { // We want equivalence with built-in string behavior using (var buffer = new StringBuffer()) { buffer.Append(content); buffer.TrimEnd(trimChars); Assert.Equal(expected, buffer.ToString()); } }
public void CopyFromString(string content, string source, uint bufferIndex, int sourceIndex, int count, string expected) { using (var buffer = new StringBuffer()) { buffer.Append(content); buffer.CopyFrom(bufferIndex, source, sourceIndex, count); Assert.Equal(expected, buffer.ToString()); } }
public unsafe void SetLengthToFirstNullTests(string content, ulong startLength, ulong endLength) { using (var buffer = new StringBuffer()) { buffer.Append(content); // With existing content Assert.Equal(startLength, buffer.Length); buffer.SetLengthToFirstNull(); Assert.Equal(endLength, buffer.Length); // Clear the buffer & manually copy in buffer.Length = 0; fixed (char* contentPointer = content) { Buffer.MemoryCopy(contentPointer, buffer.CharPointer, (long)buffer.CharCapacity * 2, content.Length * sizeof(char)); } Assert.Equal((uint)0, buffer.Length); buffer.SetLengthToFirstNull(); Assert.Equal(endLength, buffer.Length); } }
public unsafe void SetLengthToFirstNullNoNull() { using (var buffer = new StringBuffer()) { buffer.Append("A"); // Wipe out the last null buffer.CharPointer[buffer.Length] = 'B'; buffer.SetLengthToFirstNull(); Assert.Equal((ulong)1, buffer.Length); } }
public void ToStringTest(string source, int startIndex, int count, string expected) { using (var buffer = new StringBuffer()) { buffer.Append(source); Assert.Equal(expected, buffer.Substring(startIndex: (uint)startIndex, count: count)); } }
private static string TryExpandShortFileName(StringBuffer outputBuffer, string originalPath) { // We guarantee we'll expand short names for paths that only partially exist. As such, we need to find the part of the path that actually does exist. To // avoid allocating like crazy we'll create only one input array and modify the contents with embedded nulls. Debug.Assert(!PathInternal.IsPartiallyQualified(outputBuffer), "should have resolved by now"); // We'll have one of a few cases by now (the normalized path will have already: // // 1. Dos path (C:\) // 2. Dos UNC (\\Server\Share) // 3. Dos device path (\\.\C:\, \\?\C:\) // // We want to put the extended syntax on the front if it doesn't already have it, which may mean switching from \\.\. // // Note that we will never get \??\ here as GetFullPathName() does not recognize \??\ and will return it as C:\??\ (or whatever the current drive is). uint rootLength = PathInternal.GetRootLength(outputBuffer); bool isDevice = PathInternal.IsDevice(outputBuffer); StringBuffer inputBuffer = null; bool isDosUnc = false; uint rootDifference = 0; bool wasDotDevice = false; // Add the extended prefix before expanding to allow growth over MAX_PATH if (isDevice) { // We have one of the following (\\?\ or \\.\) inputBuffer = new StringBuffer(); inputBuffer.Append(outputBuffer); if (outputBuffer[2] == '.') { wasDotDevice = true; inputBuffer[2] = '?'; } } else { isDosUnc = IsDosUnc(outputBuffer); rootDifference = GetInputBuffer(outputBuffer, isDosUnc, out inputBuffer); } rootLength += rootDifference; uint inputLength = inputBuffer.Length; bool success = false; uint foundIndex = inputBuffer.Length - 1; while (!success) { uint result = Interop.mincore.GetLongPathNameW(inputBuffer.GetHandle(), outputBuffer.GetHandle(), outputBuffer.CharCapacity); // Replace any temporary null we added if (inputBuffer[foundIndex] == '\0') inputBuffer[foundIndex] = '\\'; if (result == 0) { // Look to see if we couldn't find the file int error = Marshal.GetLastWin32Error(); if (error != Interop.mincore.Errors.ERROR_FILE_NOT_FOUND && error != Interop.mincore.Errors.ERROR_PATH_NOT_FOUND) { // Some other failure, give up break; } // We couldn't find the path at the given index, start looking further back in the string. foundIndex--; for (; foundIndex > rootLength && inputBuffer[foundIndex] != '\\'; foundIndex--) ; if (foundIndex == rootLength) { // Can't trim the path back any further break; } else { // Temporarily set a null in the string to get Windows to look further up the path inputBuffer[foundIndex] = '\0'; } } else if (result > outputBuffer.CharCapacity) { // Not enough space. The result count for this API does not include the null terminator. outputBuffer.EnsureCharCapacity(result); result = Interop.mincore.GetLongPathNameW(inputBuffer.GetHandle(), outputBuffer.GetHandle(), outputBuffer.CharCapacity); } else { // Found the path success = true; outputBuffer.Length = result; if (foundIndex < inputLength - 1) { // It was a partial find, put the non-existent part of the path back outputBuffer.Append(inputBuffer, foundIndex, inputBuffer.Length - foundIndex); } } } // Strip out the prefix and return the string StringBuffer bufferToUse = success ? outputBuffer : inputBuffer; if (wasDotDevice) bufferToUse[2] = '.'; string returnValue = null; int newLength = (int)(bufferToUse.Length - rootDifference); if (isDosUnc) { // Need to go from \\?\UNC\ to \\?\UN\\ bufferToUse[(uint)PathInternal.UncExtendedPathPrefix.Length - 1] = '\\'; } // We now need to strip out any added characters at the front of the string if (bufferToUse.SubstringEquals(originalPath, rootDifference, newLength)) { // Use the original path to avoid allocating returnValue = originalPath; } else { returnValue = bufferToUse.Substring(rootDifference, newLength); } inputBuffer.Dispose(); return returnValue; }
public void CopyToBufferThrowsIndexingBeyondSourceBufferLength(string source, uint index, uint count) { using (var buffer = new StringBuffer()) using (var targetBuffer = new StringBuffer()) { buffer.Append(source); Assert.Throws<ArgumentOutOfRangeException>(() => { buffer.CopyTo(index, targetBuffer, 0, count); }); } }
private static string TryExpandShortFileName(StringBuffer outputBuffer, string originalPath) { // We guarantee we'll expand short names for paths that only partially exist. As such, we need to find the part of the path that actually does exist. To // avoid allocating like crazy we'll create only one input array and modify the contents with embedded nulls. Debug.Assert(!PathInternal.IsRelative(outputBuffer), "should have resolved by now"); Debug.Assert(!PathInternal.IsExtended(outputBuffer), "expanding short names expects normal paths"); // Add the extended prefix before expanding to allow growth over MAX_PATH StringBuffer inputBuffer = null; ulong rootLength = PathInternal.GetRootLength(outputBuffer); bool isUnc = IsUnc(outputBuffer); ulong rootDifference = GetInputBuffer(outputBuffer, isUnc, out inputBuffer); rootLength += rootDifference; ulong inputLength = inputBuffer.Length; bool success = false; ulong foundIndex = inputBuffer.Length - 1; while (!success) { uint result = Interop.mincore.GetLongPathNameW(inputBuffer.GetHandle(), outputBuffer.GetHandle(), (uint)outputBuffer.CharCapacity); // Replace any temporary null we added if (inputBuffer[foundIndex] == '\0') inputBuffer[foundIndex] = '\\'; if (result == 0) { // Look to see if we couldn't find the file int error = Marshal.GetLastWin32Error(); if (error != Interop.mincore.Errors.ERROR_FILE_NOT_FOUND && error != Interop.mincore.Errors.ERROR_PATH_NOT_FOUND) { // Some other failure, give up break; } // We couldn't find the path at the given index, start looking further back in the string. foundIndex--; for (; foundIndex > rootLength && inputBuffer[foundIndex] != '\\'; foundIndex--) ; if (foundIndex == rootLength) { // Can't trim the path back any further break; } else { // Temporarily set a null in the string to get Windows to look further up the path inputBuffer[foundIndex] = '\0'; } } else if (result > outputBuffer.CharCapacity) { // Not enough space. The result count for this API does not include the null terminator. outputBuffer.EnsureCharCapacity(result); result = Interop.mincore.GetLongPathNameW(inputBuffer.GetHandle(), outputBuffer.GetHandle(), (uint)outputBuffer.CharCapacity); } else { // Found the path success = true; outputBuffer.Length = result; if (foundIndex < inputLength - 1) { // It was a partial find, put the non-existant part of the path back outputBuffer.Append(inputBuffer, foundIndex, inputBuffer.Length - foundIndex); } } } // Strip out the prefix and return the string StringBuffer bufferToUse = success ? outputBuffer : inputBuffer; string returnValue = null; int newLength = (int)(bufferToUse.Length - rootDifference); if (isUnc) { // Need to go from \\?\UNC\ to \\?\UN\\ bufferToUse[(ulong)PathInternal.UncExtendedPathPrefix.Length - 1] = '\\'; } if (bufferToUse.SubstringEquals(originalPath, rootDifference, newLength)) { // Use the original path to avoid allocating returnValue = originalPath; } else { returnValue = bufferToUse.Substring(rootDifference, newLength); } inputBuffer.Dispose(); return returnValue; }
public void SubstringEquals(string source, string value, int startIndex, int count, bool expected) { using (var buffer = new StringBuffer()) { buffer.Append(source); Assert.Equal(expected, buffer.SubstringEquals(value, startIndex: (uint)startIndex, count: count)); } }