Skip to content

Commit d6edb06

Browse files
authored
Merge pull request #503 from dotnet/master
Update live with current master
2 parents f0abf94 + 4a60fd6 commit d6edb06

File tree

10 files changed

+309
-25
lines changed

10 files changed

+309
-25
lines changed

core/json/Program.cs

Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
using System;
2+
using System.Diagnostics;
3+
using System.IO;
4+
using System.Net.Http;
5+
using System.Text;
6+
using System.Text.Json;
7+
using System.Threading.Tasks;
8+
9+
namespace ReaderSample
10+
{
11+
class Program
12+
{
13+
private static readonly byte[] s_nameUtf8 = Encoding.UTF8.GetBytes("name");
14+
private static readonly byte[] s_universityOfUtf8 = Encoding.UTF8.GetBytes("University of");
15+
16+
public static async Task Main(string[] args)
17+
{
18+
// The JSON data used for the samples was borrowed from https://github.com/Hipo/university-domains-list
19+
// under the MIT License (MIT).
20+
21+
string outputMessage = SyncFileExample("world_universities_and_domains.json");
22+
Console.WriteLine("Reading JSON from file, sync: " + outputMessage);
23+
24+
outputMessage = await AsyncWebExample(@"http://universities.hipolabs.com/search?country=United%20States");
25+
Console.WriteLine("Reading JSON from web, async: " + outputMessage);
26+
outputMessage = await AsyncWebExample(@"http://universities.hipolabs.com/search?", worldWide: true);
27+
Console.WriteLine("Reading JSON from web, async: " + outputMessage);
28+
}
29+
30+
private static string SyncFileExample(string fileName)
31+
{
32+
// Follow the async web example if you want to read asynchronously from a FileStream instead.
33+
34+
ReadOnlySpan<byte> dataWorld = GetUtf8JsonFromDisk(fileName);
35+
(int count, int total) = CountUniversityOf(dataWorld);
36+
double ratio = (double)count / total;
37+
return $"{count} out of {total} universities worldwide have names starting with 'University of' (i.e. {ratio.ToString("#.##%")})!";
38+
}
39+
40+
private static ReadOnlySpan<byte> GetUtf8JsonFromDisk(string fileName)
41+
{
42+
// Read as UTF-16 and transcode to UTF-8 to return as a Span<byte>
43+
// For example:
44+
// string jsonString = File.ReadAllText(fileName);
45+
// return Encoding.UTF8.GetBytes(jsonString);
46+
47+
// OR ReadAllBytes if the file encoding is known to be UTF-8 and skip the encoding step:
48+
byte[] jsonBytes = File.ReadAllBytes(fileName);
49+
return jsonBytes;
50+
}
51+
52+
public static (int count, int total) CountUniversityOf(ReadOnlySpan<byte> dataUtf8)
53+
{
54+
int count = 0;
55+
int total = 0;
56+
57+
var json = new Utf8JsonReader(dataUtf8, isFinalBlock: true, state: default);
58+
59+
while (json.Read())
60+
{
61+
JsonTokenType tokenType = json.TokenType;
62+
63+
switch (tokenType)
64+
{
65+
case JsonTokenType.StartObject:
66+
total++;
67+
break;
68+
case JsonTokenType.PropertyName:
69+
if (json.ValueSpan.SequenceEqual(s_nameUtf8))
70+
{
71+
bool result = json.Read();
72+
73+
Debug.Assert(result); // Assume valid JSON
74+
Debug.Assert(json.TokenType == JsonTokenType.String); // Assume known, valid JSON schema
75+
76+
if (json.ValueSpan.StartsWith(s_universityOfUtf8))
77+
{
78+
count++;
79+
}
80+
}
81+
break;
82+
}
83+
}
84+
return (count, total);
85+
}
86+
87+
private static async Task<string> AsyncWebExample(string url, bool worldWide = false)
88+
{
89+
using (var client = new HttpClient())
90+
{
91+
using (Stream stream = await client.GetStreamAsync(url))
92+
{
93+
(int count, int total) = await ReadJsonFromStreamUsingSpan(stream);
94+
95+
double ratio = (double)count / total;
96+
string percentage = ratio.ToString("#.##%");
97+
string outputMessage = worldWide ?
98+
$"{count} out of {total} universities worldwide have names starting with 'University of' (i.e. {percentage})!" :
99+
$"{count} out of {total} American universities have names starting with 'University of' (i.e. {percentage})!";
100+
101+
return outputMessage;
102+
}
103+
}
104+
}
105+
106+
public static async Task<(int count, int total)> ReadJsonFromStreamUsingSpan(Stream stream)
107+
{
108+
// Assumes all JSON strings in the payload are small (say < 500 bytes)
109+
var buffer = new byte[1_024];
110+
int count = 0;
111+
int total = 0;
112+
113+
JsonReaderState state = default;
114+
int leftOver = 0;
115+
int partialCount = 0;
116+
int partialTotalCount = 0;
117+
bool foundName = false;
118+
119+
while (true)
120+
{
121+
// The Memory<byte> ReadAsync overload returns ValueTask which is allocation-free
122+
// if the operation completes synchronously
123+
int dataLength = await stream.ReadAsync(buffer.AsMemory(leftOver, buffer.Length - leftOver));
124+
int dataSize = dataLength + leftOver;
125+
bool isFinalBlock = dataSize == 0;
126+
(state, partialCount, partialTotalCount) = PartialCountUniversityOf(buffer.AsSpan(0, dataSize), isFinalBlock, ref foundName, state);
127+
128+
// Based on your scenario and input data, you may need to grow your buffer here
129+
// It's possible that leftOver == dataSize (if a JSON token is too large)
130+
// so you need to resize and read more than 1_024 bytes.
131+
leftOver = dataSize - (int)state.BytesConsumed;
132+
if (leftOver != 0)
133+
{
134+
buffer.AsSpan(dataSize - leftOver, leftOver).CopyTo(buffer);
135+
}
136+
137+
count += partialCount;
138+
total += partialTotalCount;
139+
140+
if (isFinalBlock)
141+
{
142+
break;
143+
}
144+
}
145+
146+
return (count, total);
147+
}
148+
149+
public static (JsonReaderState state, int count, int total) PartialCountUniversityOf(ReadOnlySpan<byte> dataUtf8, bool isFinalBlock, ref bool foundName, JsonReaderState state)
150+
{
151+
int count = 0;
152+
int total = 0;
153+
154+
var json = new Utf8JsonReader(dataUtf8, isFinalBlock, state);
155+
156+
while (json.Read())
157+
{
158+
JsonTokenType tokenType = json.TokenType;
159+
160+
switch (tokenType)
161+
{
162+
case JsonTokenType.StartObject:
163+
total++;
164+
break;
165+
case JsonTokenType.PropertyName:
166+
if (json.ValueSpan.SequenceEqual(s_nameUtf8))
167+
{
168+
foundName = true;
169+
}
170+
break;
171+
case JsonTokenType.String:
172+
if (foundName && json.ValueSpan.StartsWith(s_universityOfUtf8))
173+
{
174+
count++;
175+
}
176+
foundName = false;
177+
break;
178+
}
179+
}
180+
181+
return (json.CurrentState, count, total);
182+
}
183+
}
184+
}

core/json/ReaderSample.csproj

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>netcoreapp3.0</TargetFramework>
6+
<LangVersion>latest</LangVersion>
7+
</PropertyGroup>
8+
9+
</Project>

core/json/world_universities_and_domains.json

Lines changed: 1 addition & 0 deletions
Large diffs are not rendered by default.

snippets/csharp/VS_Snippets_CLR/HowToSignXMLDocumentRSA/cs/sample.cs

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66

77
public class SignXML
88
{
9-
109
public static void Main(String[] args)
1110
{
1211
try
@@ -41,27 +40,23 @@ public static void Main(String[] args)
4140
// <snippet13>
4241
xmlDoc.Save("test.xml");
4342
// </snippet13>
44-
45-
46-
4743
}
4844
catch (Exception e)
4945
{
5046
Console.WriteLine(e.Message);
5147
}
5248
}
5349

54-
5550
// Sign an XML file.
5651
// This document cannot be verified unless the verifying
5752
// code has the key with which it was signed.
58-
public static void SignXml(XmlDocument xmlDoc, RSA key)
53+
public static void SignXml(XmlDocument xmlDoc, RSA rsaKey)
5954
{
6055
// Check arguments.
6156
if (xmlDoc == null)
62-
throw new ArgumentException("xmlDoc");
63-
if (key == null)
64-
throw new ArgumentException("key");
57+
throw new ArgumentException(nameof(xmlDoc));
58+
if (rsaKey == null)
59+
throw new ArgumentException(nameof(rsaKey));
6560

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

7166
// Add the key to the SignedXml document.
7267
// <snippet6>
73-
signedXml.SigningKey = key;
68+
signedXml.SigningKey = rsaKey;
7469
// </snippet6>
7570

7671
// <snippet7>
@@ -105,7 +100,6 @@ public static void SignXml(XmlDocument xmlDoc, RSA key)
105100
// <snippet12>
106101
xmlDoc.DocumentElement.AppendChild(xmlDoc.ImportNode(xmlDigitalSignature, true));
107102
// </snippet12>
108-
109103
}
110104
}
111105
// </snippet1>

snippets/csharp/how-to/safelycast/patternmatching/Program.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,13 @@ static void Main(string[] args)
2525

2626
TestForMammals(g);
2727

28-
// Use the as operator to test
29-
// an incompatible type.
3028
SuperNova sn = new SuperNova();
3129
TestForMammals(sn);
3230
}
3331

3432
static void FeedMammals(Animal a)
3533
{
36-
// Use the is operator to verify the type.
34+
// Use the is operator to verify the type
3735
// before performing a cast.
3836
if (a is Mammal m)
3937
{
@@ -43,7 +41,7 @@ static void FeedMammals(Animal a)
4341

4442
static void TestForMammals(object o)
4543
{
46-
// Use the as operator and test for null
44+
// Alternatively, use the as operator and test for null
4745
// before referencing the variable.
4846
if (o is Mammal m)
4947
{

snippets/csharp/keywords/Program.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ static void Main(string[] args)
1616
IterationKeywordsExamples.Examples();
1717
Console.WriteLine("================= readonly Keyword Examples ======================");
1818
ReadonlyKeywordExamples.Examples();
19+
Console.WriteLine("================= true and false operators examples ==============");
20+
LaunchStatusTest.Main();
21+
Console.WriteLine("================= true and false literals examples ===============");
22+
TrueFalseLiteralsExamples.Examples();
1923
}
2024
}
2125
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
using System;
2+
3+
namespace keywords
4+
{
5+
public static class TrueFalseLiteralsExamples
6+
{
7+
public static void Examples()
8+
{
9+
TrueExample();
10+
FalseExample();
11+
}
12+
13+
private static void TrueExample()
14+
{
15+
// <SnippetTrueLiteral>
16+
bool check = true;
17+
Console.WriteLine(check ? "Passed" : "Not passed");
18+
// Output:
19+
// Passed
20+
// </SnippetTrueLiteral>
21+
}
22+
23+
private static void FalseExample()
24+
{
25+
// <SnippetFalseLiteral>
26+
bool check = false;
27+
Console.WriteLine(check ? "Passed" : "Not passed");
28+
// Output:
29+
// Not passed
30+
// </SnippetFalseLiteral>
31+
}
32+
}
33+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
using System;
2+
3+
public struct LaunchStatus
4+
{
5+
public static readonly LaunchStatus Green = new LaunchStatus(0);
6+
public static readonly LaunchStatus Yellow = new LaunchStatus(1);
7+
public static readonly LaunchStatus Red = new LaunchStatus(2);
8+
9+
private int status;
10+
11+
private LaunchStatus(int status)
12+
{
13+
this.status = status;
14+
}
15+
16+
public static bool operator true(LaunchStatus x) => x == Green || x == Yellow;
17+
public static bool operator false(LaunchStatus x) => x == Red;
18+
19+
public static LaunchStatus operator &(LaunchStatus x, LaunchStatus y)
20+
{
21+
if (x == Red || y == Red || (x == Yellow && y == Yellow))
22+
{
23+
return Red;
24+
}
25+
26+
if (x == Yellow || y == Yellow)
27+
{
28+
return Yellow;
29+
}
30+
31+
return Green;
32+
}
33+
34+
public static bool operator ==(LaunchStatus x, LaunchStatus y) => x.status == y.status;
35+
public static bool operator !=(LaunchStatus x, LaunchStatus y) => !(x == y);
36+
37+
public override bool Equals(object obj) => obj is LaunchStatus other && this == other;
38+
public override int GetHashCode() => status;
39+
}
40+
41+
public class LaunchStatusTest
42+
{
43+
public static void Main()
44+
{
45+
LaunchStatus okToLaunch = GetFuelLaunchStatus() && GetNavigationLaunchStatus();
46+
Console.WriteLine(okToLaunch ? "Ready to go!" : "Wait!");
47+
}
48+
49+
static LaunchStatus GetFuelLaunchStatus()
50+
{
51+
Console.WriteLine("Getting fuel launch status...");
52+
return LaunchStatus.Red;
53+
}
54+
55+
static LaunchStatus GetNavigationLaunchStatus()
56+
{
57+
Console.WriteLine("Getting navigation launch status...");
58+
return LaunchStatus.Yellow;
59+
}
60+
}

0 commit comments

Comments
 (0)