Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
184 changes: 184 additions & 0 deletions core/json/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;

namespace ReaderSample
{
class Program
{
private static readonly byte[] s_nameUtf8 = Encoding.UTF8.GetBytes("name");
private static readonly byte[] s_universityOfUtf8 = Encoding.UTF8.GetBytes("University of");

public static async Task Main(string[] args)
{
// The JSON data used for the samples was borrowed from https://github.com/Hipo/university-domains-list
// under the MIT License (MIT).

string outputMessage = SyncFileExample("world_universities_and_domains.json");
Console.WriteLine("Reading JSON from file, sync: " + outputMessage);

outputMessage = await AsyncWebExample(@"http://universities.hipolabs.com/search?country=United%20States");
Console.WriteLine("Reading JSON from web, async: " + outputMessage);
outputMessage = await AsyncWebExample(@"http://universities.hipolabs.com/search?", worldWide: true);
Console.WriteLine("Reading JSON from web, async: " + outputMessage);
}

private static string SyncFileExample(string fileName)
{
// Follow the async web example if you want to read asynchronously from a FileStream instead.

ReadOnlySpan<byte> dataWorld = GetUtf8JsonFromDisk(fileName);
(int count, int total) = CountUniversityOf(dataWorld);
double ratio = (double)count / total;
return $"{count} out of {total} universities worldwide have names starting with 'University of' (i.e. {ratio.ToString("#.##%")})!";
}

private static ReadOnlySpan<byte> GetUtf8JsonFromDisk(string fileName)
{
// Read as UTF-16 and transcode to UTF-8 to return as a Span<byte>
// For example:
// string jsonString = File.ReadAllText(fileName);
// return Encoding.UTF8.GetBytes(jsonString);

// OR ReadAllBytes if the file encoding is known to be UTF-8 and skip the encoding step:
byte[] jsonBytes = File.ReadAllBytes(fileName);
return jsonBytes;
}

public static (int count, int total) CountUniversityOf(ReadOnlySpan<byte> dataUtf8)
{
int count = 0;
int total = 0;

var json = new Utf8JsonReader(dataUtf8, isFinalBlock: true, state: default);

while (json.Read())
{
JsonTokenType tokenType = json.TokenType;

switch (tokenType)
{
case JsonTokenType.StartObject:
total++;
break;
case JsonTokenType.PropertyName:
if (json.ValueSpan.SequenceEqual(s_nameUtf8))
{
bool result = json.Read();

Debug.Assert(result); // Assume valid JSON
Debug.Assert(json.TokenType == JsonTokenType.String); // Assume known, valid JSON schema

if (json.ValueSpan.StartsWith(s_universityOfUtf8))
{
count++;
}
}
break;
}
}
return (count, total);
}

private static async Task<string> AsyncWebExample(string url, bool worldWide = false)
{
using (var client = new HttpClient())
{
using (Stream stream = await client.GetStreamAsync(url))
{
(int count, int total) = await ReadJsonFromStreamUsingSpan(stream);

double ratio = (double)count / total;
string percentage = ratio.ToString("#.##%");
string outputMessage = worldWide ?
$"{count} out of {total} universities worldwide have names starting with 'University of' (i.e. {percentage})!" :
$"{count} out of {total} American universities have names starting with 'University of' (i.e. {percentage})!";

return outputMessage;
}
}
}

public static async Task<(int count, int total)> ReadJsonFromStreamUsingSpan(Stream stream)
{
// Assumes all JSON strings in the payload are small (say < 500 bytes)
var buffer = new byte[1_024];
int count = 0;
int total = 0;

JsonReaderState state = default;
int leftOver = 0;
int partialCount = 0;
int partialTotalCount = 0;
bool foundName = false;

while (true)
{
// The Memory<byte> ReadAsync overload returns ValueTask which is allocation-free
// if the operation completes synchronously
int dataLength = await stream.ReadAsync(buffer.AsMemory(leftOver, buffer.Length - leftOver));
int dataSize = dataLength + leftOver;
bool isFinalBlock = dataSize == 0;
(state, partialCount, partialTotalCount) = PartialCountUniversityOf(buffer.AsSpan(0, dataSize), isFinalBlock, ref foundName, state);

// Based on your scenario and input data, you may need to grow your buffer here
// It's possible that leftOver == dataSize (if a JSON token is too large)
// so you need to resize and read more than 1_024 bytes.
leftOver = dataSize - (int)state.BytesConsumed;
if (leftOver != 0)
{
buffer.AsSpan(dataSize - leftOver, leftOver).CopyTo(buffer);
}

count += partialCount;
total += partialTotalCount;

if (isFinalBlock)
{
break;
}
}

return (count, total);
}

public static (JsonReaderState state, int count, int total) PartialCountUniversityOf(ReadOnlySpan<byte> dataUtf8, bool isFinalBlock, ref bool foundName, JsonReaderState state)
{
int count = 0;
int total = 0;

var json = new Utf8JsonReader(dataUtf8, isFinalBlock, state);

while (json.Read())
{
JsonTokenType tokenType = json.TokenType;

switch (tokenType)
{
case JsonTokenType.StartObject:
total++;
break;
case JsonTokenType.PropertyName:
if (json.ValueSpan.SequenceEqual(s_nameUtf8))
{
foundName = true;
}
break;
case JsonTokenType.String:
if (foundName && json.ValueSpan.StartsWith(s_universityOfUtf8))
{
count++;
}
foundName = false;
break;
}
}

return (json.CurrentState, count, total);
}
}
}
9 changes: 9 additions & 0 deletions core/json/ReaderSample.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.0</TargetFramework>
<LangVersion>latest</LangVersion>
</PropertyGroup>

</Project>
1 change: 1 addition & 0 deletions core/json/world_universities_and_domains.json

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

public class SignXML
{

public static void Main(String[] args)
{
try
Expand Down Expand Up @@ -41,27 +40,23 @@ public static void Main(String[] args)
// <snippet13>
xmlDoc.Save("test.xml");
// </snippet13>



}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}


// Sign an XML file.
// This document cannot be verified unless the verifying
// code has the key with which it was signed.
public static void SignXml(XmlDocument xmlDoc, RSA key)
public static void SignXml(XmlDocument xmlDoc, RSA rsaKey)
{
// Check arguments.
if (xmlDoc == null)
throw new ArgumentException("xmlDoc");
if (key == null)
throw new ArgumentException("key");
throw new ArgumentException(nameof(xmlDoc));
if (rsaKey == null)
throw new ArgumentException(nameof(rsaKey));

// Create a SignedXml object.
// <snippet5>
Expand All @@ -70,7 +65,7 @@ public static void SignXml(XmlDocument xmlDoc, RSA key)

// Add the key to the SignedXml document.
// <snippet6>
signedXml.SigningKey = key;
signedXml.SigningKey = rsaKey;
// </snippet6>

// <snippet7>
Expand Down Expand Up @@ -105,7 +100,6 @@ public static void SignXml(XmlDocument xmlDoc, RSA key)
// <snippet12>
xmlDoc.DocumentElement.AppendChild(xmlDoc.ImportNode(xmlDigitalSignature, true));
// </snippet12>

}
}
// </snippet1>
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,13 @@ static void Main(string[] args)

TestForMammals(g);

// Use the as operator to test
// an incompatible type.
SuperNova sn = new SuperNova();
TestForMammals(sn);
}

static void FeedMammals(Animal a)
{
// Use the is operator to verify the type.
// Use the is operator to verify the type
// before performing a cast.
if (a is Mammal m)
{
Expand All @@ -43,7 +41,7 @@ static void FeedMammals(Animal a)

static void TestForMammals(object o)
{
// Use the as operator and test for null
// Alternatively, use the as operator and test for null
// before referencing the variable.
if (o is Mammal m)
{
Expand Down
4 changes: 4 additions & 0 deletions snippets/csharp/keywords/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ static void Main(string[] args)
IterationKeywordsExamples.Examples();
Console.WriteLine("================= readonly Keyword Examples ======================");
ReadonlyKeywordExamples.Examples();
Console.WriteLine("================= true and false operators examples ==============");
LaunchStatusTest.Main();
Console.WriteLine("================= true and false literals examples ===============");
TrueFalseLiteralsExamples.Examples();
}
}
}
33 changes: 33 additions & 0 deletions snippets/csharp/keywords/TrueFalseLiteralsExamples.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using System;

namespace keywords
{
public static class TrueFalseLiteralsExamples
{
public static void Examples()
{
TrueExample();
FalseExample();
}

private static void TrueExample()
{
// <SnippetTrueLiteral>
bool check = true;
Console.WriteLine(check ? "Passed" : "Not passed");
// Output:
// Passed
// </SnippetTrueLiteral>
}

private static void FalseExample()
{
// <SnippetFalseLiteral>
bool check = false;
Console.WriteLine(check ? "Passed" : "Not passed");
// Output:
// Not passed
// </SnippetFalseLiteral>
}
}
}
60 changes: 60 additions & 0 deletions snippets/csharp/keywords/TrueFalseOperatorsExample.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
using System;

public struct LaunchStatus
{
public static readonly LaunchStatus Green = new LaunchStatus(0);
public static readonly LaunchStatus Yellow = new LaunchStatus(1);
public static readonly LaunchStatus Red = new LaunchStatus(2);

private int status;

private LaunchStatus(int status)
{
this.status = status;
}

public static bool operator true(LaunchStatus x) => x == Green || x == Yellow;
public static bool operator false(LaunchStatus x) => x == Red;

public static LaunchStatus operator &(LaunchStatus x, LaunchStatus y)
{
if (x == Red || y == Red || (x == Yellow && y == Yellow))
{
return Red;
}

if (x == Yellow || y == Yellow)
{
return Yellow;
}

return Green;
}

public static bool operator ==(LaunchStatus x, LaunchStatus y) => x.status == y.status;
public static bool operator !=(LaunchStatus x, LaunchStatus y) => !(x == y);

public override bool Equals(object obj) => obj is LaunchStatus other && this == other;
public override int GetHashCode() => status;
}

public class LaunchStatusTest
{
public static void Main()
{
LaunchStatus okToLaunch = GetFuelLaunchStatus() && GetNavigationLaunchStatus();
Console.WriteLine(okToLaunch ? "Ready to go!" : "Wait!");
}

static LaunchStatus GetFuelLaunchStatus()
{
Console.WriteLine("Getting fuel launch status...");
return LaunchStatus.Red;
}

static LaunchStatus GetNavigationLaunchStatus()
{
Console.WriteLine("Getting navigation launch status...");
return LaunchStatus.Yellow;
}
}
Loading