File: System\Net\ServerSentEvents\SseParser.cs
Web Access
Project: src\src\libraries\System.Net.ServerSentEvents\src\System.Net.ServerSentEvents.csproj (System.Net.ServerSentEvents)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
 
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading;
 
namespace System.Net.ServerSentEvents
{
    /// <summary>Provides a parser for parsing server-sent events.</summary>
    public static class SseParser
    {
        /// <summary>The default <see cref="SseItem{T}.EventType"/> ("message") for an event that did not explicitly specify a type.</summary>
        public const string EventTypeDefault = "message";
 
        /// <summary>Creates a parser for parsing a <paramref name="sseStream"/> of server-sent events into a sequence of <see cref="SseItem{String}"/> values.</summary>
        /// <param name="sseStream">The stream containing the data to parse.</param>
        /// <returns>
        /// The enumerable of strings, which can be enumerated synchronously or asynchronously. The strings
        /// are decoded from the UTF8-encoded bytes of the payload of each event.
        /// </returns>
        /// <exception cref="ArgumentNullException"><paramref name="sseStream"/> is null.</exception>
        /// <remarks>
        /// This overload has behavior equivalent to calling <see cref="Create{T}(Stream, SseItemParser{T})"/> with a delegate
        /// that decodes the data of each event using <see cref="Encoding.UTF8"/>'s GetString method.
        /// </remarks>
        public static SseParser<string> Create(Stream sseStream) =>
            Create(sseStream, static (_, bytes) => Utf8GetString(bytes));
 
        /// <summary>Creates a parser for parsing a <paramref name="sseStream"/> of server-sent events into a sequence of <see cref="SseItem{T}"/> values.</summary>
        /// <typeparam name="T">Specifies the type of data in each event.</typeparam>
        /// <param name="sseStream">The stream containing the data to parse.</param>
        /// <param name="itemParser">The parser to use to transform each payload of bytes into a data element.</param>
        /// <returns>The enumerable, which can be enumerated synchronously or asynchronously.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="sseStream"/> or <paramref name="itemParser"/> is null.</exception>
        public static SseParser<T> Create<T>(Stream sseStream, SseItemParser<T> itemParser)
        {
            if (sseStream is null)
            {
                ThrowHelper.ThrowArgumentNullException(nameof(sseStream));
            }
 
            if (itemParser is null)
            {
                ThrowHelper.ThrowArgumentNullException(nameof(itemParser));
            }
 
            return new SseParser<T>(sseStream, itemParser);
        }
 
        /// <summary>Encoding.UTF8.GetString(bytes)</summary>
        internal static unsafe string Utf8GetString(ReadOnlySpan<byte> bytes)
        {
#if NET
            return Encoding.UTF8.GetString(bytes);
#else
            fixed (byte* ptr = bytes)
            {
                return ptr is null ?
                    string.Empty :
                    Encoding.UTF8.GetString(ptr, bytes.Length);
            }
#endif
        }
    }
}