private void EnsureComparesConsistent(string left, string right) { String8 left8 = left.TestConvert(); String8 right8 = right.TestConvert(); CompareResult caseSensitiveExpected = ToResult(String.Compare(left, right, StringComparison.Ordinal)); CompareResult caseInsensitiveExpected = ToResult(String.Compare(left, right, StringComparison.OrdinalIgnoreCase)); Assert.AreEqual(caseSensitiveExpected, ToResult(left8.CompareTo(right8)), "Case sensitive comparison result incorrect."); Assert.AreEqual(caseInsensitiveExpected, ToResult(left8.CompareTo(right8, true)), "Case insensitive comparison result incorrect."); Assert.AreEqual(caseSensitiveExpected, ToResult(left8.CompareTo(right)), "Case sensitive String8 to string comparison result incorrect."); Assert.AreEqual(caseInsensitiveExpected, ToResult(left8.CompareTo(right, true)), "Case insensitive String8 to string comparison result incorrect."); // StartsWith and CompareAsPrefixTo Assert.AreEqual(left.StartsWith(right), left8.StartsWith(right8)); Assert.AreEqual(left.StartsWith(right, StringComparison.OrdinalIgnoreCase), left8.StartsWith(right8, true)); Assert.AreEqual(right.StartsWith(left), right8.StartsWith(left8)); Assert.AreEqual(right.StartsWith(left, StringComparison.OrdinalIgnoreCase), right8.StartsWith(left8, true)); // Case Insensitive Stable is the insensitive order, then the sensitive order for ties CompareResult caseInsensitiveStableExpected = (caseInsensitiveExpected == CompareResult.Equal ? caseSensitiveExpected : caseInsensitiveExpected); Assert.AreEqual(caseInsensitiveStableExpected, ToResult(left8.CompareCaseInsensitiveStableTo(right8)), "Case insensitive stable String8 to string comparison result incorrect."); }
private void SetColumnValue(String8 currentPropertyName, String8 currentPropertyValue, bool isEncoded) { if (currentPropertyName.IsEmpty()) { return; } if (isEncoded) { currentPropertyValue = DecodeBase64(currentPropertyValue); } if (currentPropertyName.CompareTo("objectSid", true) == 0) { currentPropertyValue = DecodeSid(currentPropertyValue); } // TODO: Decode ".0Z" time format // TODO: Decode NT file time format int columnIndex; if (_columnIndices8.TryGetValue(currentPropertyName, out columnIndex)) { String8 previousValue = _currentRowValues[columnIndex].ToString8(); if (!previousValue.IsEmpty()) { currentPropertyValue = _currentRowBlock.Concatenate(previousValue, MultiValueDelimiter, currentPropertyValue); } _currentRowValues[columnIndex].SetValue(currentPropertyValue); } }
public Path8 GetMemberFilePath(int memberIndex) { int fileIndex = this.DeclaredMemberLocations[memberIndex].FileIndex; if (fileIndex <= 0) { return(Path8.Empty); } // TODO: Handle '/' or '\' in ItemTree to avoid canonicalizing int pathRootIndex = this.FileTree.GetAncestorAtDepth(fileIndex, 1); String8 rootName = this.StringStore[this.FileTree.GetNameIdentifier(pathRootIndex)]; bool isUrl = rootName.CompareTo("http:", true) == 0 || rootName.CompareTo("https:", true) == 0; char delimiter = isUrl ? '/' : '\\'; return(new Path8(this.StringStore, this.FileTree, fileIndex, delimiter)); }
private static void Concatenate(string inputFilePath, string outputFilePath, String8 delimiter) { using (ITabularReader reader = TabularFactory.BuildReader(inputFilePath)) { using (ITabularWriter writer = TabularFactory.BuildWriter(outputFilePath)) { writer.SetColumns(reader.Columns); String8Block block = new String8Block(); String8[] lastValues = new String8[reader.CurrentRowColumns]; String8[] combinedValues = new String8[reader.CurrentRowColumns]; while (reader.NextRow()) { String8 firstColumn = reader.Current(0).ToString8(); if (reader.RowCountRead == 2) { // First Row - Get the first ID only combinedValues[0] = block.GetCopy(firstColumn); } else if (firstColumn.CompareTo(combinedValues[0], true) != 0) { // If we have a new ID (and not first row) // Write concatenated values for previous ID WriteCombinedRow(writer, combinedValues); // Reset for this ID block.Clear(); combinedValues[0] = block.GetCopy(firstColumn); for (int i = 1; i < combinedValues.Length; ++i) { combinedValues[i] = String8.Empty; } } // Concatenate non-duplicate values to "row in progress" for (int i = 1; i < reader.CurrentRowColumns; ++i) { String8 value = reader.Current(i).ToString8(); if (lastValues[i] != value) { lastValues[i] = value; combinedValues[i] = block.Concatenate(combinedValues[i], delimiter, value); } } } // After last row, write out values so far WriteCombinedRow(writer, combinedValues); WriteSizeSummary(reader, writer); } } }
public void String8_Basics() { byte[] b1 = null, b2 = null, b3 = null; String8 one = String8.Copy("one", ref b1); String8 two = String8.Copy("two", ref b2); String8 one2 = String8.Copy("one", ref b3); Assert.IsFalse(one.Equals(two)); Assert.AreNotEqual(one.GetHashCode(), two.GetHashCode()); Assert.IsTrue(one.Equals(one2)); Assert.AreEqual(one.GetHashCode(), one2.GetHashCode()); Assert.IsTrue(one.CompareTo(two) < 0); Assert.IsTrue(two.CompareTo(one) > 0); Assert.AreEqual(0, one.CompareTo(one2)); Assert.AreEqual(0, one.CompareTo(one)); }
public void StringStore_CaseSensitivity() { // Sample Strings: Not all in order, including casing differences, including duplicates StringStore store = new StringStore(); string[] strings = { "bool", "bool", "boolean", "Boolean", "BOOLEAN", "array", "Array", "aRRay", "ARRAY", "Array", "Collections", "ARR", "BIT" }; int[] addedIDs = new int[strings.Length]; // Add each value for (int i = 0; i < strings.Length; ++i) { addedIDs[i] = store.FindOrAddString(strings[i]); } // Verify each value comes back cased correctly (case sensitive add) for (int i = 0; i < strings.Length; ++i) { Assert.AreEqual(strings[i], store[addedIDs[i]].ToString()); } // Convert to Immutable store.ConvertToImmutable(); // Remap IDs for (int i = 0; i < strings.Length; ++i) { addedIDs[i] = store.GetSerializationIdentifier(addedIDs[i]); } // Verify each value comes back cased correctly (case sensitive values preserved on convert) for (int i = 0; i < strings.Length; ++i) { Assert.AreEqual(strings[i], store[addedIDs[i]].ToString()); } // Verify values have ascending IDs and are in case insensitive *stable* order string last = store[0].ToString(); for (int i = 1; i < store.Count; ++i) { string current = store[i].ToString(); // Verify all strings are in case insensitive order int cmp = string.Compare(last, current, StringComparison.OrdinalIgnoreCase); Assert.IsTrue(cmp <= 0); // Verify case-insensitive ties are in case sensitive order relative to each other if (cmp == 0) { Assert.IsTrue(string.Compare(last, current, StringComparison.Ordinal) < 0); } last = current; } // Verify searches return the range of capitalizations for the value byte[] buffer = new byte[20]; for (int i = 0; i < strings.Length; ++i) { String8 value8 = String8.Convert(strings[i], buffer); // Verify the string is found Range range; Assert.IsTrue(store.TryFindString(value8, out range)); // Verify the ID for the exact casing is reported within the range Assert.IsTrue(range.Contains(addedIDs[i])); // Verify every value in the range matches the value (case-insensitive) for (int j = range.Start; j <= range.End; ++j) { String8 otherMatch = store[j]; Assert.AreEqual(0, value8.CompareTo(otherMatch, true), String.Format("'{0}' in match range wasn't reported equal to '{1}' being matched", otherMatch, value8)); } // Verify the values just before and after the range don't match if (range.Start > 0) { String8 valueBefore = store[range.Start - 1]; Assert.IsTrue(value8.CompareTo(valueBefore, true) > 0, String.Format("'{0}' before match range wasn't reported before '{1}' being matched", valueBefore, value8)); } if (range.End < store.Count - 1) { String8 valueAfter = store[range.End + 1]; Assert.IsTrue(value8.CompareTo(valueAfter, true) < 0, String.Format("'{0}' after match range wasn't reported after '{1}' being matched", valueAfter, value8)); } // Ask for the case-sensitive range Range caseSensitive; Assert.IsTrue(store.TryFindString(value8, false, out caseSensitive)); // Verify every value in the range matches the value (case-sensitive) for (int j = caseSensitive.Start; j <= caseSensitive.End; ++j) { String8 otherMatch = store[j]; Assert.AreEqual(0, value8.CompareTo(otherMatch, false), String.Format("'{0}' in case sensitive range wasn't reported equal to '{1}' being matched", otherMatch, value8)); } // Verify the values just before and after the range don't match if (caseSensitive.Start > 0) { String8 valueBefore = store[caseSensitive.Start - 1]; Assert.IsTrue(value8.CompareTo(valueBefore, false) != 0, String.Format("'{0}' before case sensitive range still matches '{1}'", valueBefore, value8)); } if (caseSensitive.End < store.Count - 1) { String8 valueAfter = store[caseSensitive.End + 1]; Assert.IsTrue(value8.CompareTo(valueAfter, false) != 0, String.Format("'{0}' after case sensitive range still matches '{1}'", valueAfter, value8)); } } // Verify MakeCaseSensitive goes to empty if the provided casing isn't any of the values String8 BOOLean = String8.Convert("BOOLean", buffer); Range booleanRange; Assert.IsFalse(store.TryFindString(BOOLean, false, out booleanRange)); }