/// <summary> /// Fills in stringIndexMap with data from stringIndex and write to stringWriter. /// Releases stringIndex as the stringTable is sealed after this point. /// </summary> private static ImmutableArray <int> SerializeStringHeap( BlobBuilder heapBuilder, Dictionary <string, StringHandle> strings, int stringHeapStartOffset) { // Sort by suffix and remove stringIndex var sorted = new List <KeyValuePair <string, StringHandle> >(strings); sorted.Sort(SuffixSort.Instance); // Create VirtIdx to Idx map and add entry for empty string int totalCount = sorted.Count + 1; var stringVirtualIndexToHeapOffsetMap = ImmutableArray.CreateBuilder <int>(totalCount); stringVirtualIndexToHeapOffsetMap.Count = totalCount; stringVirtualIndexToHeapOffsetMap[0] = 0; heapBuilder.WriteByte(0); // Find strings that can be folded string prev = string.Empty; foreach (KeyValuePair <string, StringHandle> entry in sorted) { int position = stringHeapStartOffset + heapBuilder.Count; // It is important to use ordinal comparison otherwise we'll use the current culture! if (prev.EndsWith(entry.Key, StringComparison.Ordinal) && !BlobUtilities.IsLowSurrogateChar(entry.Key[0])) { // Map over the tail of prev string. Watch for null-terminator of prev string. stringVirtualIndexToHeapOffsetMap[entry.Value.GetWriterVirtualIndex()] = position - (BlobUtilities.GetUTF8ByteCount(entry.Key) + 1); } else { stringVirtualIndexToHeapOffsetMap[entry.Value.GetWriterVirtualIndex()] = position; heapBuilder.WriteUTF8(entry.Key, allowUnpairedSurrogates: false); heapBuilder.WriteByte(0); } prev = entry.Key; } return(stringVirtualIndexToHeapOffsetMap.MoveToImmutable()); }
/// <summary> /// Fills in stringIndexMap with data from stringIndex and write to stringWriter. /// Releases stringIndex as the stringTable is sealed after this point. /// </summary> private void SerializeStringHeap() { // Sort by suffix and remove stringIndex var sorted = new List <KeyValuePair <string, StringHandle> >(_strings); sorted.Sort(new SuffixSort()); _strings = null; _stringWriter = new BlobBuilder(1024); // Create VirtIdx to Idx map and add entry for empty string _stringIndexToResolvedOffsetMap = new int[sorted.Count + 1]; _stringIndexToResolvedOffsetMap[0] = 0; _stringWriter.WriteByte(0); // Find strings that can be folded string prev = string.Empty; foreach (KeyValuePair <string, StringHandle> entry in sorted) { int position = _stringHeapStartOffset + _stringWriter.Position; // It is important to use ordinal comparison otherwise we'll use the current culture! if (prev.EndsWith(entry.Key, StringComparison.Ordinal) && !BlobUtilities.IsLowSurrogateChar(entry.Key[0])) { // Map over the tail of prev string. Watch for null-terminator of prev string. _stringIndexToResolvedOffsetMap[MetadataTokens.GetHeapOffset(entry.Value)] = position - (BlobUtilities.GetUTF8ByteCount(entry.Key) + 1); } else { _stringIndexToResolvedOffsetMap[MetadataTokens.GetHeapOffset(entry.Value)] = position; _stringWriter.WriteUTF8(entry.Key, allowUnpairedSurrogates: false); _stringWriter.WriteByte(0); } prev = entry.Key; } }