Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
StringHeap.cs
Go to the documentation of this file.
3using System.Text;
4
6
7internal struct StringHeap
8{
9 private static string[] s_virtualValues;
10
11 internal readonly MemoryBlock Block;
12
14
15 internal StringHeap(MemoryBlock block, MetadataKind metadataKind)
16 {
17 _lazyVirtualHeap = null;
18 if (s_virtualValues == null && metadataKind != 0)
19 {
20 s_virtualValues = new string[71]
21 {
22 "System.Runtime.WindowsRuntime", "System.Runtime", "System.ObjectModel", "System.Runtime.WindowsRuntime.UI.Xaml", "System.Runtime.InteropServices.WindowsRuntime", "System.Numerics.Vectors", "Dispose", "AttributeTargets", "AttributeUsageAttribute", "Color",
23 "CornerRadius", "DateTimeOffset", "Duration", "DurationType", "EventHandler`1", "EventRegistrationToken", "Exception", "GeneratorPosition", "GridLength", "GridUnitType",
24 "ICommand", "IDictionary`2", "IDisposable", "IEnumerable", "IEnumerable`1", "IList", "IList`1", "INotifyCollectionChanged", "INotifyPropertyChanged", "IReadOnlyDictionary`2",
25 "IReadOnlyList`1", "KeyTime", "KeyValuePair`2", "Matrix", "Matrix3D", "Matrix3x2", "Matrix4x4", "NotifyCollectionChangedAction", "NotifyCollectionChangedEventArgs", "NotifyCollectionChangedEventHandler",
26 "Nullable`1", "Plane", "Point", "PropertyChangedEventArgs", "PropertyChangedEventHandler", "Quaternion", "Rect", "RepeatBehavior", "RepeatBehaviorType", "Size",
27 "System", "System.Collections", "System.Collections.Generic", "System.Collections.Specialized", "System.ComponentModel", "System.Numerics", "System.Windows.Input", "Thickness", "TimeSpan", "Type",
28 "Uri", "Vector2", "Vector3", "Vector4", "Windows.Foundation", "Windows.UI", "Windows.UI.Xaml", "Windows.UI.Xaml.Controls.Primitives", "Windows.UI.Xaml.Media", "Windows.UI.Xaml.Media.Animation",
29 "Windows.UI.Xaml.Media.Media3D"
30 };
31 }
32 Block = TrimEnd(block);
33 }
34
35 private static MemoryBlock TrimEnd(MemoryBlock block)
36 {
37 if (block.Length == 0)
38 {
39 return block;
40 }
41 int num = block.Length - 1;
42 while (num >= 0 && block.PeekByte(num) == 0)
43 {
44 num--;
45 }
46 if (num == block.Length - 1)
47 {
48 return block;
49 }
50 return block.GetMemoryBlockAt(0, num + 2);
51 }
52
53 internal string GetString(StringHandle handle, MetadataStringDecoder utf8Decoder)
54 {
55 if (!handle.IsVirtual)
56 {
57 return GetNonVirtualString(handle, utf8Decoder, null);
58 }
59 return GetVirtualHandleString(handle, utf8Decoder);
60 }
61
63 {
64 if (!handle.IsVirtual)
65 {
67 }
69 }
70
72 {
73 return s_virtualValues[(int)index];
74 }
75
76 private string GetNonVirtualString(StringHandle handle, MetadataStringDecoder utf8Decoder, byte[] prefixOpt)
77 {
78 char terminator = ((handle.StringKind == StringKind.DotTerminated) ? '.' : '\0');
79 int numberOfBytesRead;
80 return Block.PeekUtf8NullTerminated(handle.GetHeapOffset(), prefixOpt, utf8Decoder, out numberOfBytesRead, terminator);
81 }
82
84 {
85 char terminator = ((handle.StringKind == StringKind.DotTerminated) ? '.' : '\0');
86 int heapOffset = handle.GetHeapOffset();
87 int numberOfBytesRead;
88 int utf8NullTerminatedLength = Block.GetUtf8NullTerminatedLength(heapOffset, out numberOfBytesRead, terminator);
89 return new MemoryBlock(Block.Pointer + heapOffset, utf8NullTerminatedLength);
90 }
91
92 private unsafe byte[] GetNonVirtualStringBytes(StringHandle handle, byte[] prefix)
93 {
94 MemoryBlock nonVirtualStringMemoryBlock = GetNonVirtualStringMemoryBlock(handle);
95 byte[] array = new byte[prefix.Length + nonVirtualStringMemoryBlock.Length];
96 Buffer.BlockCopy(prefix, 0, array, 0, prefix.Length);
97 Marshal.Copy((IntPtr)nonVirtualStringMemoryBlock.Pointer, array, prefix.Length, nonVirtualStringMemoryBlock.Length);
98 return array;
99 }
100
102 {
103 return handle.StringKind switch
104 {
105 StringKind.Virtual => GetVirtualString(handle.GetVirtualIndex()),
106 StringKind.WinRTPrefixed => GetNonVirtualString(handle, utf8Decoder, MetadataReader.WinRTPrefix),
107 _ => throw ExceptionUtilities.UnexpectedValue(handle.StringKind),
108 };
109 }
110
112 {
114 lock (orCreateVirtualHeap)
115 {
116 if (!orCreateVirtualHeap.TryGetMemoryBlock(handle.RawValue, out var block))
117 {
118 byte[] value = handle.StringKind switch
119 {
120 StringKind.Virtual => Encoding.UTF8.GetBytes(GetVirtualString(handle.GetVirtualIndex())),
121 StringKind.WinRTPrefixed => GetNonVirtualStringBytes(handle, MetadataReader.WinRTPrefix),
122 _ => throw ExceptionUtilities.UnexpectedValue(handle.StringKind),
123 };
124 return orCreateVirtualHeap.AddBlob(handle.RawValue, value);
125 }
126 return block;
127 }
128 }
129
134
136 {
137 if (handle.IsVirtual)
138 {
139 return default(StringHandle);
140 }
141 int num = Block.IndexOf(0, handle.GetHeapOffset());
142 if (num == -1 || num == Block.Length - 1)
143 {
144 return default(StringHandle);
145 }
146 return StringHandle.FromOffset(num + 1);
147 }
148
149 internal bool Equals(StringHandle handle, string value, MetadataStringDecoder utf8Decoder, bool ignoreCase)
150 {
151 if (handle.IsVirtual)
152 {
153 return string.Equals(GetString(handle, utf8Decoder), value, ignoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal);
154 }
155 if (handle.IsNil)
156 {
157 return value.Length == 0;
158 }
159 char terminator = ((handle.StringKind == StringKind.DotTerminated) ? '.' : '\0');
160 return Block.Utf8NullTerminatedEquals(handle.GetHeapOffset(), value, utf8Decoder, terminator, ignoreCase);
161 }
162
163 internal bool StartsWith(StringHandle handle, string value, MetadataStringDecoder utf8Decoder, bool ignoreCase)
164 {
165 if (handle.IsVirtual)
166 {
167 return GetString(handle, utf8Decoder).StartsWith(value, ignoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal);
168 }
169 if (handle.IsNil)
170 {
171 return value.Length == 0;
172 }
173 char terminator = ((handle.StringKind == StringKind.DotTerminated) ? '.' : '\0');
174 return Block.Utf8NullTerminatedStartsWith(handle.GetHeapOffset(), value, utf8Decoder, terminator, ignoreCase);
175 }
176
177 internal bool EqualsRaw(StringHandle rawHandle, string asciiString)
178 {
179 return Block.CompareUtf8NullTerminatedStringWithAsciiString(rawHandle.GetHeapOffset(), asciiString) == 0;
180 }
181
182 internal int IndexOfRaw(int startIndex, char asciiChar)
183 {
185 }
186
187 internal bool StartsWithRaw(StringHandle rawHandle, string asciiPrefix)
188 {
190 }
191
192 internal int BinarySearchRaw(string[] asciiKeys, StringHandle rawHandle)
193 {
194 return Block.BinarySearch(asciiKeys, rawHandle.GetHeapOffset());
195 }
196}
static void BlockCopy(Array src, int srcOffset, Array dst, int dstOffset, int count)
Definition Buffer.cs:102
static Exception UnexpectedValue(object value)
MemoryBlock AddBlob(uint rawHandle, byte[] value)
bool TryGetMemoryBlock(uint rawHandle, out MemoryBlock block)
static VirtualHeap GetOrCreateVirtualHeap(ref VirtualHeap? lazyHeap)
static void Copy(int[] source, int startIndex, IntPtr destination, int length)
Definition Marshal.cs:800
static Encoding UTF8
Definition Encoding.cs:526
unsafe MemoryBlock GetMemoryBlockAt(int offset, int length)
bool Utf8NullTerminatedEquals(int offset, string text, MetadataStringDecoder utf8Decoder, char terminator, bool ignoreCase)
unsafe int Utf8NullTerminatedOffsetOfAsciiChar(int startOffset, char asciiChar)
unsafe string PeekUtf8NullTerminated(int offset, byte[]? prefix, MetadataStringDecoder utf8Decoder, out int numberOfBytesRead, char terminator='\0')
unsafe bool Utf8NullTerminatedStringStartsWithAsciiPrefix(int offset, string asciiPrefix)
unsafe int GetUtf8NullTerminatedLength(int offset, out int numberOfBytesRead, char terminator='\0')
int BinarySearch(string[] asciiKeys, int offset)
unsafe int CompareUtf8NullTerminatedStringWithAsciiString(int offset, string asciiString)
bool Utf8NullTerminatedStartsWith(int offset, string text, MetadataStringDecoder utf8Decoder, char terminator, bool ignoreCase)
bool StartsWithRaw(StringHandle rawHandle, string asciiPrefix)
StringHandle GetNextHandle(StringHandle handle)
unsafe byte[] GetNonVirtualStringBytes(StringHandle handle, byte[] prefix)
Definition StringHeap.cs:92
MemoryBlock GetMemoryBlock(StringHandle handle)
Definition StringHeap.cs:62
int BinarySearchRaw(string[] asciiKeys, StringHandle rawHandle)
string GetNonVirtualString(StringHandle handle, MetadataStringDecoder utf8Decoder, byte[] prefixOpt)
Definition StringHeap.cs:76
bool Equals(StringHandle handle, string value, MetadataStringDecoder utf8Decoder, bool ignoreCase)
BlobReader GetBlobReader(StringHandle handle)
string GetString(StringHandle handle, MetadataStringDecoder utf8Decoder)
Definition StringHeap.cs:53
int IndexOfRaw(int startIndex, char asciiChar)
StringHeap(MemoryBlock block, MetadataKind metadataKind)
Definition StringHeap.cs:15
bool StartsWith(StringHandle handle, string value, MetadataStringDecoder utf8Decoder, bool ignoreCase)
static string GetVirtualString(StringHandle.VirtualIndex index)
Definition StringHeap.cs:71
MemoryBlock GetVirtualHandleMemoryBlock(StringHandle handle)
unsafe MemoryBlock GetNonVirtualStringMemoryBlock(StringHandle handle)
Definition StringHeap.cs:83
bool EqualsRaw(StringHandle rawHandle, string asciiString)
string GetVirtualHandleString(StringHandle handle, MetadataStringDecoder utf8Decoder)
static MemoryBlock TrimEnd(MemoryBlock block)
Definition StringHeap.cs:35
static StringHandle FromOffset(int heapOffset)