@@ -199,33 +199,7 @@ private static bool DoesTemplateMatchPropertyCount(ReadOnlySpan<char> template,
199199 {
200200 if ( template . IsEmpty ) { return false ; }
201201
202- var cache = s_formattedPropertiesCache . GetAlternateLookup < ReadOnlySpan < char > > ( ) ;
203-
204- if ( cache . TryGetValue ( template , out string [ ] ? dataNodes ) )
205- {
206- return dataNodes . Length == eventPropertyCount ;
207- }
208-
209- List < string > temp = [ ] ;
210- ReadOnlySpan < char > outTypeAttribute = "outType=\" " ;
211-
212- foreach ( var line in template . EnumerateLines ( ) )
213- {
214- int templateIndex = line . IndexOf ( outTypeAttribute , StringComparison . Ordinal ) ;
215-
216- if ( templateIndex == - 1 ) { continue ; }
217-
218- templateIndex += outTypeAttribute . Length ;
219- int endIndex = line [ templateIndex ..] . IndexOf ( '"' ) ;
220-
221- if ( endIndex != - 1 )
222- {
223- temp . Add ( new string ( line . Slice ( templateIndex , endIndex ) ) ) ;
224- }
225- }
226-
227- dataNodes = [ .. temp ] ;
228- cache . TryAdd ( template , dataNodes ) ;
202+ string [ ] dataNodes = GetOrParseTemplateDataNodes ( template ) ;
229203
230204 return dataNodes . Length == 0 || dataNodes . Length == eventPropertyCount ;
231205 }
@@ -235,30 +209,9 @@ private static List<string> GetFormattedProperties(ReadOnlySpan<char> template,
235209 string [ ] ? dataNodes = null ;
236210 List < string > providers = [ ] ;
237211
238- var cache = s_formattedPropertiesCache . GetAlternateLookup < ReadOnlySpan < char > > ( ) ;
239-
240- if ( ! template . IsEmpty && ! cache . TryGetValue ( template , out dataNodes ) )
212+ if ( ! template . IsEmpty )
241213 {
242- List < string > temp = [ ] ;
243- ReadOnlySpan < char > outTypeAttribute = "outType=\" " ;
244-
245- foreach ( var line in template . EnumerateLines ( ) )
246- {
247- int templateIndex = line . IndexOf ( outTypeAttribute , StringComparison . Ordinal ) ;
248-
249- if ( templateIndex == - 1 ) { continue ; }
250-
251- templateIndex += outTypeAttribute . Length ;
252- int endIndex = line [ templateIndex ..] . IndexOf ( '"' ) ;
253-
254- if ( endIndex != - 1 )
255- {
256- temp . Add ( new string ( line . Slice ( templateIndex , endIndex ) ) ) ;
257- }
258- }
259-
260- dataNodes = [ .. temp ] ;
261- cache . TryAdd ( template , dataNodes ) ;
214+ dataNodes = GetOrParseTemplateDataNodes ( template ) ;
262215 }
263216
264217 int index = 0 ;
@@ -308,6 +261,67 @@ private static List<string> GetFormattedProperties(ReadOnlySpan<char> template,
308261 return providers ;
309262 }
310263
264+ private static string [ ] GetOrParseTemplateDataNodes ( ReadOnlySpan < char > template )
265+ {
266+ var cache = s_formattedPropertiesCache . GetAlternateLookup < ReadOnlySpan < char > > ( ) ;
267+
268+ if ( cache . TryGetValue ( template , out string [ ] ? dataNodes ) )
269+ {
270+ return dataNodes ;
271+ }
272+
273+ List < string > temp = [ ] ;
274+ ReadOnlySpan < char > dataElement = "<data " ;
275+ ReadOnlySpan < char > outTypeAttribute = "outType=\" " ;
276+
277+ int searchStart = 0 ;
278+
279+ while ( searchStart < template . Length )
280+ {
281+ int dataIndex = template [ searchStart ..] . IndexOf ( dataElement , StringComparison . OrdinalIgnoreCase ) ;
282+
283+ if ( dataIndex == - 1 ) { break ; }
284+
285+ dataIndex += searchStart ;
286+
287+ // Find the end of this element
288+ int elementEnd = template [ dataIndex ..] . IndexOf ( "/>" ) ;
289+
290+ if ( elementEnd == - 1 )
291+ {
292+ elementEnd = template [ dataIndex ..] . IndexOf ( '>' ) ;
293+ }
294+
295+ if ( elementEnd == - 1 ) { break ; }
296+
297+ elementEnd += dataIndex ;
298+
299+ ReadOnlySpan < char > element = template [ dataIndex ..elementEnd ] ;
300+ int outTypeIndex = element . IndexOf ( outTypeAttribute , StringComparison . Ordinal ) ;
301+
302+ if ( outTypeIndex != - 1 )
303+ {
304+ outTypeIndex += outTypeAttribute . Length ;
305+ int endIndex = element [ outTypeIndex ..] . IndexOf ( '"' ) ;
306+
307+ temp . Add ( endIndex != - 1 ?
308+ new string ( element . Slice ( outTypeIndex , endIndex ) ) :
309+ string . Empty ) ;
310+ }
311+ else
312+ {
313+ temp . Add ( string . Empty ) ;
314+ }
315+
316+ searchStart = elementEnd + 1 ;
317+ }
318+
319+ dataNodes = [ .. temp ] ;
320+ cache . TryAdd ( template , dataNodes ) ;
321+
322+ return dataNodes ;
323+ }
324+
311325 private static void ResizeBuffer ( ref char [ ] buffer , ref Span < char > source , int sizeToAdd )
312326 {
313327 char [ ] newBuffer = ArrayPool < char > . Shared . Rent ( source . Length + sizeToAdd ) ;
0 commit comments