public void TrimStartRemovesLeadingWhiteSpace(InterningTestData.TestDatum datum) { SpanBasedStringBuilder stringBuilder = MakeSpanBasedStringBuilder(datum); stringBuilder.TrimStart(); new InternableString(stringBuilder).ExpensiveConvertToString().ShouldBe(datum.ToString().TrimStart()); }
public void ClearRemovesAllCharacters(InterningTestData.TestDatum datum) { SpanBasedStringBuilder stringBuilder = MakeSpanBasedStringBuilder(datum); stringBuilder.Clear(); stringBuilder.Length.ShouldBe(0); stringBuilder.GetEnumerator().MoveNext().ShouldBeFalse(); }
public void EnumeratorEnumeratesCharacters(InterningTestData.TestDatum datum) { SpanBasedStringBuilder stringBuilder = MakeSpanBasedStringBuilder(datum); int index = 0; foreach (char ch in stringBuilder) { ch.ShouldBe(datum[index]); index++; } }
public void SpanBasedOperations_CacheHit() { SpanBasedStringBuilder sbsb = _pooledSpanBasedStringBuilder; sbsb.Clear(); foreach (string subString in _subStrings) { sbsb.Append(subString); } sbsb.ToString(); }
public void SpanBasedOperations_CacheMiss() { SpanBasedStringBuilder sbsb = _pooledSpanBasedStringBuilder; sbsb.Clear(); foreach (string subString in _subStrings) { sbsb.Append(subString); } sbsb.Append(_uniqueStringCounter++.ToString("X8")); sbsb.ToString(); }
[InlineData("0123456789")] // even number of characters public void GetHashCodeIsStableRegardlessOfSpanLength(string testString) { int hashCode = new InternableString(testString).GetHashCode(); // Chop the string into 2-3 parts and verify that the hash code is unchanged. for (int i = 0; i < testString.Length - 1; i++) { for (int j = i + 1; j < testString.Length; j++) { SpanBasedStringBuilder stringBuilder = new SpanBasedStringBuilder(); stringBuilder.Append(testString.Substring(0, i)); stringBuilder.Append(testString.Substring(i, j - i)); stringBuilder.Append(testString.Substring(j)); InternableString internableString = new InternableString(stringBuilder); internableString.GetHashCode().ShouldBe(hashCode); } } }
private SpanBasedStringBuilder MakeSpanBasedStringBuilder(InterningTestData.TestDatum datum, bool appendSubStrings = false) { bool wrapFirstFragment = datum.Fragments.Length > 0 && datum.Fragments[0] != null; SpanBasedStringBuilder stringBuilder = wrapFirstFragment ? new SpanBasedStringBuilder(datum.Fragments[0]) : new SpanBasedStringBuilder(); for (int i = 1; i < datum.Fragments.Length; i++) { if (appendSubStrings) { int index = datum.Fragments[i].Length / 2; stringBuilder.Append(datum.Fragments[i], 0, index); stringBuilder.Append(datum.Fragments[i], index, datum.Fragments[i].Length - index); } else { stringBuilder.Append(datum.Fragments[i]); } } return(stringBuilder); }
public void AppendAppendsSubstring(InterningTestData.TestDatum datum) { SpanBasedStringBuilder stringBuilder = MakeSpanBasedStringBuilder(datum, true); new InternableString(stringBuilder).ExpensiveConvertToString().ShouldBe(datum.ToString()); }
internal static bool GetTableWithEscaping(TaskLoggingHelper log, string parameterName, string syntaxName, string[] propertyNameValueStrings, out Dictionary <string, string> finalPropertiesTable) { finalPropertiesTable = null; if (propertyNameValueStrings != null) { finalPropertiesTable = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase); var finalPropertiesList = new List <PropertyNameValuePair>(); // Loop through the array. Each string in the array should be of the form: // MyPropName=MyPropValue foreach (string propertyNameValueString in propertyNameValueStrings) { // Find the first '=' sign in the string. int indexOfEqualsSign = propertyNameValueString.IndexOf('='); if (indexOfEqualsSign != -1) { // If we found one, then grab the stuff before it and put it into "propertyName", // and grab the stuff after it and put it into "propertyValue". But trim the // whitespace from beginning and end of both name and value. (When authoring a // project/targets file, people like to use whitespace and newlines to pretty up // the file format.) string propertyName = propertyNameValueString.Substring(0, indexOfEqualsSign).Trim(); string propertyValue = EscapingUtilities.Escape(propertyNameValueString.Substring(indexOfEqualsSign + 1).Trim()); // Make sure we have a property name and property value (though the value is allowed to be blank). if (propertyName.Length == 0) { // No property name? That's no good to us. log?.LogErrorWithCodeFromResources("General.InvalidPropertyError", syntaxName, propertyNameValueString); return(false); } // Store the property in our list. finalPropertiesList.Add(new PropertyNameValuePair(propertyName, propertyValue)); } else { // There's no '=' sign in the string. When this happens, we treat this string as basically // an appendage on the value of the previous property. For example, if the project file contains // // <PropertyGroup> // <WarningsAsErrors>1234;5678;9999</WarningsAsErrors> // </PropertyGroup> // <Target Name="Build"> // <MSBuild Projects="ConsoleApplication1.csproj" // Properties="WarningsAsErrors=$(WarningsAsErrors)"/> // </Target> // // , then this method (GetTableWithEscaping) will see this: // // propertyNameValueStrings[0] = "WarningsAsErrors=1234" // propertyNameValueStrings[1] = "5678" // propertyNameValueStrings[2] = "9999" // // And what we actually want to end up with in our final hashtable is this: // // NAME VALUE // =================== ================================ // WarningsAsErrors 1234;5678;9999 // if (finalPropertiesList.Count > 0) { // There was a property definition previous to this one. Append the current string // to that previous value, using semicolon as a separator. string propertyValue = EscapingUtilities.Escape(propertyNameValueString.Trim()); finalPropertiesList[finalPropertiesList.Count - 1].Value.Add(propertyValue); } else { // No equals sign in the very first property? That's a problem. log?.LogErrorWithCodeFromResources("General.InvalidPropertyError", syntaxName, propertyNameValueString); return(false); } } } // Convert the data in the List to a Hashtable, because that's what the MSBuild task eventually // needs to pass onto the engine. log?.LogMessageFromText(parameterName, MessageImportance.Low); using SpanBasedStringBuilder stringBuilder = Strings.GetSpanBasedStringBuilder(); foreach (PropertyNameValuePair propertyNameValuePair in finalPropertiesList) { stringBuilder.Clear(); bool needsSemicolon = false; foreach (string valueFragment in propertyNameValuePair.Value) { if (needsSemicolon) { stringBuilder.Append(";"); } needsSemicolon = true; stringBuilder.Append(valueFragment); } string propertyValue = stringBuilder.ToString(); finalPropertiesTable[propertyNameValuePair.Name] = propertyValue; log?.LogMessageFromText( $" {propertyNameValuePair.Name}={propertyValue}", MessageImportance.Low); } } return(true); }