Skip to content

Commit

Permalink
Add System.Formats.Sse
Browse files Browse the repository at this point in the history
  • Loading branch information
stephentoub committed May 19, 2024
1 parent 5474ab5 commit 27c10ea
Show file tree
Hide file tree
Showing 12 changed files with 1,812 additions and 0 deletions.
48 changes: 48 additions & 0 deletions src/libraries/System.Formats.Sse/System.Formats.Sse.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.11.34910.147
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Formats.Sse", "ref\System.Formats.Sse.csproj", "{ACB7E0BF-015F-43DC-A2F5-85506173B223}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Formats.Sse", "src\System.Formats.Sse.csproj", "{ACDB56AF-7B9F-4762-9764-D6FF09118D09}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Formats.Sse.Tests", "tests\System.Formats.Sse.Tests.csproj", "{804B5D44-05A3-491E-A6AB-35C592E6703E}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{2BD73108-47D7-40E6-BFCB-169E6AD42A81}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ref", "ref", "{E6AF8CEE-6550-4190-97D4-D51C5B114919}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{D908DCBE-EFA4-4CCA-9A1C-AEB48D59C504}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{ACB7E0BF-015F-43DC-A2F5-85506173B223}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{ACB7E0BF-015F-43DC-A2F5-85506173B223}.Debug|Any CPU.Build.0 = Debug|Any CPU
{ACB7E0BF-015F-43DC-A2F5-85506173B223}.Release|Any CPU.ActiveCfg = Release|Any CPU
{ACB7E0BF-015F-43DC-A2F5-85506173B223}.Release|Any CPU.Build.0 = Release|Any CPU
{ACDB56AF-7B9F-4762-9764-D6FF09118D09}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{ACDB56AF-7B9F-4762-9764-D6FF09118D09}.Debug|Any CPU.Build.0 = Debug|Any CPU
{ACDB56AF-7B9F-4762-9764-D6FF09118D09}.Release|Any CPU.ActiveCfg = Release|Any CPU
{ACDB56AF-7B9F-4762-9764-D6FF09118D09}.Release|Any CPU.Build.0 = Release|Any CPU
{804B5D44-05A3-491E-A6AB-35C592E6703E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{804B5D44-05A3-491E-A6AB-35C592E6703E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{804B5D44-05A3-491E-A6AB-35C592E6703E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{804B5D44-05A3-491E-A6AB-35C592E6703E}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{ACB7E0BF-015F-43DC-A2F5-85506173B223} = {E6AF8CEE-6550-4190-97D4-D51C5B114919}
{ACDB56AF-7B9F-4762-9764-D6FF09118D09} = {D908DCBE-EFA4-4CCA-9A1C-AEB48D59C504}
{804B5D44-05A3-491E-A6AB-35C592E6703E} = {2BD73108-47D7-40E6-BFCB-169E6AD42A81}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {01DAF96B-AF8E-4576-A1BC-57D19BDB317E}
EndGlobalSection
EndGlobal
33 changes: 33 additions & 0 deletions src/libraries/System.Formats.Sse/ref/System.Formats.Sse.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// ------------------------------------------------------------------------------
// Changes to this file must follow the https://aka.ms/api-review process.
// ------------------------------------------------------------------------------

namespace System.Formats.Sse
{
public sealed partial class SseEnumerable<T> : System.Collections.Generic.IAsyncEnumerable<System.Formats.Sse.SseItem<T>>, System.Collections.Generic.IEnumerable<System.Formats.Sse.SseItem<T>>, System.Collections.IEnumerable
{
internal SseEnumerable() { }
public string LastEventId { get { throw null; } }
public System.TimeSpan ReconnectionInterval { get { throw null; } }
public System.Collections.Generic.IAsyncEnumerator<System.Formats.Sse.SseItem<T>> GetAsyncEnumerator(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public System.Collections.Generic.IEnumerator<System.Formats.Sse.SseItem<T>> GetEnumerator() { throw null; }
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; }
}
public delegate T SseItemParser<out T>(string eventType, System.ReadOnlySpan<byte> data);
public readonly partial struct SseItem<T>
{
private readonly T _Data_k__BackingField;
private readonly object _dummy;
private readonly int _dummyPrimitive;
public SseItem(T data, string eventType) { throw null; }
public T Data { get { throw null; } }
public string EventType { get { throw null; } }
}
public static partial class SseParser
{
public static System.Formats.Sse.SseEnumerable<string> Parse(System.IO.Stream sseStream) { throw null; }
public static System.Formats.Sse.SseEnumerable<T> Parse<T>(System.IO.Stream sseStream, System.Formats.Sse.SseItemParser<T> itemParser) { throw null; }
}
}
16 changes: 16 additions & 0 deletions src/libraries/System.Formats.Sse/ref/System.Formats.Sse.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>$(NetCoreAppCurrent);$(NetCoreAppPrevious);$(NetCoreAppMinimum);netstandard2.0;$(NetFrameworkMinimum)</TargetFrameworks>
</PropertyGroup>

<ItemGroup>
<Compile Include="System.Formats.Sse.cs" />
</ItemGroup>

<ItemGroup Condition="'$(TargetFrameworkIdentifier)' != '.NETCoreApp'">
<PackageReference Include="System.Memory" Version="$(SystemMemoryVersion)" />
<ProjectReference Include="$(LibrariesProjectRoot)Microsoft.Bcl.AsyncInterfaces\ref\Microsoft.Bcl.AsyncInterfaces.csproj" />
</ItemGroup>

</Project>
50 changes: 50 additions & 0 deletions src/libraries/System.Formats.Sse/src/PACKAGE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
## About

<!-- A description of the package and where one can find more documentation -->

System.Formats.Sse introduces the `SseParser` type, which provides factory methods for creating enumerables of the events in a stream of server-sent events (SSE).

## Key Features

<!-- The key features of this package -->

* Parser for server-sent events (SSE)

## How to Use

<!-- A compelling example on how to use this package with code, as well as any specific guidelines for when to use the package -->

Asynchronously parsing event contents as strings

```csharp
using HttpClient client = new();
using Stream response = await client.GetStreamAsync("https://localhost:12345/sse");
await foreach (SseItem<string> item in SseParser.Parse(response))
{
Console.WriteLine(item.Data);
}
```

Synchronously parsing event contents as JSON

```csharp
MemoryStream stream = new MemoryStream(data);
foreach (SseItem<Book> item in SseParser.Parse(response, (eventType, bytes) => JsonSerializer.Deserialize<Book>(bytes)))
{
Console.WriteLine(item.Author);
}
```

## Main Types

<!-- The main types provided in this library -->

The main types provided by this library are:

* `System.Formats.Sse.SseParser`

## Feedback & Contributing

<!-- How to provide feedback on this package and contribute to it -->

System.Formats.Sse is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime).
126 changes: 126 additions & 0 deletions src/libraries/System.Formats.Sse/src/Resources/Strings.resx
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="InvalidOperation_EnumerateOnlyOnce" xml:space="preserve">
<value>The enumerable may be enumerated only once.</value>
</data>
<data name="InvalidOperation_InvalidStreamNegativeBytes" xml:space="preserve">
<value>The Stream implementation is invalid, returning a negative number from a read operation.</value>
</data>
</root>
32 changes: 32 additions & 0 deletions src/libraries/System.Formats.Sse/src/System.Formats.Sse.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>$(NetCoreAppCurrent);$(NetCoreAppPrevious);$(NetCoreAppMinimum);netstandard2.0;$(NetFrameworkMinimum)</TargetFrameworks>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<UseCompilerGeneratedDocXmlFile>true</UseCompilerGeneratedDocXmlFile>
<IsPackable>true</IsPackable>
<PackageDescription>Provides a simple parser for server-sent events (SSE).

Commonly Used Types:
System.Formats.Sse.SseParser</PackageDescription>

<!-- Disabling baseline validation since this is a brand new package.
Once this package has shipped a stable version, the following line
should be removed in order to re-enable validation. -->
<DisablePackageBaselineValidation>true</DisablePackageBaselineValidation>
</PropertyGroup>

<ItemGroup>
<Compile Include="System\Formats\Sse\SseEnumerable.cs" />
<Compile Include="System\Formats\Sse\SseItem.cs" />
<Compile Include="System\Formats\Sse\SseItemParser.cs" />
<Compile Include="System\Formats\Sse\SseParser.cs" />
</ItemGroup>

<ItemGroup Condition="'$(TargetFrameworkIdentifier)' != '.NETCoreApp'">
<ProjectReference Include="$(LibrariesProjectRoot)Microsoft.Bcl.AsyncInterfaces\src\Microsoft.Bcl.AsyncInterfaces.csproj" />
<PackageReference Include="System.Memory" Version="$(SystemMemoryVersion)" />
<PackageReference Include="System.Threading.Tasks.Extensions" Version="$(SystemThreadingTasksExtensionsVersion)" />
</ItemGroup>

</Project>
Loading

0 comments on commit 27c10ea

Please sign in to comment.