Skip to content
Draft
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
42 changes: 21 additions & 21 deletions src/Microsoft.OData.Core/Json/JsonReaderExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,28 +76,28 @@ internal static void ReadEndArray(this IJsonReader jsonReader)
/// </summary>
/// <param name="jsonReader">The <see cref="JsonReader"/> to read from.</param>
/// <returns>The property name of the current property node.</returns>
internal static string GetPropertyName(this IJsonReader jsonReader)
internal static ReadOnlySpan<char> GetPropertyName(this IJsonReader jsonReader)
{
Debug.Assert(jsonReader != null, "jsonReader != null");
Debug.Assert(jsonReader.NodeType == JsonNodeType.Property, "jsonReader.NodeType == JsonNodeType.Property");

// NOTE: the JSON reader already verifies that property names are strings and not null/empty
string propertyName = (string)jsonReader.GetValue();

return propertyName;
return propertyName.AsSpan();
}

/// <summary>
/// Reads the next node from the <paramref name="jsonReader"/>, verifies that it is a Property node and returns the property name.
/// </summary>
/// <param name="jsonReader">The <see cref="JsonReader"/> to read from.</param>
/// <returns>The property name of the property node read.</returns>
internal static string ReadPropertyName(this IJsonReader jsonReader)
internal static ReadOnlySpan<char> ReadPropertyName(this IJsonReader jsonReader)
{
Debug.Assert(jsonReader != null, "jsonReader != null");

jsonReader.ValidateNodeType(JsonNodeType.Property);
string propertyName = jsonReader.GetPropertyName();
ReadOnlySpan<char> propertyName = jsonReader.GetPropertyName();
jsonReader.ReadNext();
return propertyName;
}
Expand Down Expand Up @@ -260,7 +260,7 @@ internal static void SkipValue(this IJsonReader jsonReader, StringBuilder jsonRa
break;

case JsonNodeType.Property:
jsonWriter.WriteName(jsonReader.GetPropertyName());
jsonWriter.WriteName(jsonReader.GetPropertyName().ToString());
break;

default:
Expand Down Expand Up @@ -366,7 +366,7 @@ internal static ODataValue ReadODataValue(this IJsonReader jsonReader)
while (jsonReader.NodeType != JsonNodeType.EndObject)
{
ODataProperty property = new ODataProperty();
property.Name = jsonReader.ReadPropertyName();
property.Name = jsonReader.ReadPropertyName().ToString();
property.Value = jsonReader.ReadODataValue();
propertyList.Add(property);
}
Expand Down Expand Up @@ -481,7 +481,7 @@ internal static ValueTask ReadEndArrayAsync(this IJsonReader jsonReader)
/// <param name="jsonReader">The <see cref="JsonReader"/> to read from.</param>
/// <returns>A task that represents the asynchronous read operation.
/// The value of the TResult parameter contains the property name of the current property node.</returns>
internal static Task<string> GetPropertyNameAsync(this IJsonReader jsonReader)
internal static Task<ReadOnlyMemory<char>> GetPropertyNameAsync(this IJsonReader jsonReader)
{
Debug.Assert(jsonReader != null, "jsonReader != null");
Debug.Assert(jsonReader.NodeType == JsonNodeType.Property, "jsonReader.NodeType == JsonNodeType.Property");
Expand All @@ -490,16 +490,16 @@ internal static Task<string> GetPropertyNameAsync(this IJsonReader jsonReader)
Task<object> getValueTask = jsonReader.GetValueAsync();
if (getValueTask.IsCompletedSuccessfully)
{
return Task.FromResult((string)getValueTask.Result);
return Task.FromResult(((string)getValueTask.Result).AsMemory());
}

return AwaitGetValueAsync(getValueTask);

static async Task<string> AwaitGetValueAsync(Task<object> pendingGetValueTask)
static async Task<ReadOnlyMemory<char>> AwaitGetValueAsync(Task<object> pendingGetValueTask)
{
object value = await pendingGetValueTask.ConfigureAwait(false);

return (string)value;
return ((string)value).AsMemory();
}
}

Expand All @@ -509,7 +509,7 @@ static async Task<string> AwaitGetValueAsync(Task<object> pendingGetValueTask)
/// <param name="jsonReader">The <see cref="JsonReader"/> to read from.</param>
/// <returns>A task that represents the asynchronous read operation.
/// The value of the TResult parameter contains the property name of the property node read.</returns>
internal static Task<string> ReadPropertyNameAsync(this IJsonReader jsonReader)
internal static Task<ReadOnlyMemory<char>> ReadPropertyNameAsync(this IJsonReader jsonReader)
{
Debug.Assert(jsonReader != null, "jsonReader != null");

Expand All @@ -519,13 +519,13 @@ internal static Task<string> ReadPropertyNameAsync(this IJsonReader jsonReader)
}
catch (ODataException ex)
{
return Task.FromException<string>(ex);
return Task.FromException<ReadOnlyMemory<char>>(ex);
}

Task<string> getPropertyNameTask = jsonReader.GetPropertyNameAsync();
Task<ReadOnlyMemory<char>> getPropertyNameTask = jsonReader.GetPropertyNameAsync();
if (getPropertyNameTask.IsCompletedSuccessfully)
{
string propertyName = getPropertyNameTask.Result;
ReadOnlyMemory<char> propertyName = getPropertyNameTask.Result;
Task<JsonNodeType> readNextTask = jsonReader.ReadNextAsync();
if (readNextTask.IsCompletedSuccessfully)
{
Expand All @@ -537,16 +537,16 @@ internal static Task<string> ReadPropertyNameAsync(this IJsonReader jsonReader)

return AwaitGetPropertyNameAsync(jsonReader, getPropertyNameTask);

static async Task<string> AwaitReadNextAsync(Task pendingReadNextTask, string propertyName)
static async Task<ReadOnlyMemory<char>> AwaitReadNextAsync(Task pendingReadNextTask, ReadOnlyMemory<char> propertyName)
{
await pendingReadNextTask.ConfigureAwait(false);

return propertyName;
}

static async Task<string> AwaitGetPropertyNameAsync(IJsonReader jsonReaderParam, Task<string> pendingGetPropertyNameTask)
static async Task<ReadOnlyMemory<char>> AwaitGetPropertyNameAsync(IJsonReader jsonReaderParam, Task<ReadOnlyMemory<char>> pendingGetPropertyNameTask)
{
string propertyName = await pendingGetPropertyNameTask.ConfigureAwait(false);
ReadOnlyMemory<char> propertyName = await pendingGetPropertyNameTask.ConfigureAwait(false);
await jsonReaderParam.ReadNextAsync()
.ConfigureAwait(false);

Expand Down Expand Up @@ -844,9 +844,9 @@ await jsonWriter.EndObjectScopeAsync()
break;

case JsonNodeType.Property:
string propertyName = await jsonReader.GetPropertyNameAsync()
ReadOnlyMemory<char> propertyName = await jsonReader.GetPropertyNameAsync()
.ConfigureAwait(false);
await jsonWriter.WriteNameAsync(propertyName)
await jsonWriter.WriteNameAsync(propertyName.ToString())
.ConfigureAwait(false);
break;

Expand Down Expand Up @@ -1115,8 +1115,8 @@ await jsonReader.ReadStartObjectAsync()
while (jsonReader.NodeType != JsonNodeType.EndObject)
{
ODataProperty property = new ODataProperty();
property.Name = await jsonReader.ReadPropertyNameAsync()
.ConfigureAwait(false);
property.Name = (await jsonReader.ReadPropertyNameAsync()
.ConfigureAwait(false)).ToString();
property.Value = await jsonReader.ReadODataValueAsync()
.ConfigureAwait(false);
properties.Add(property);
Expand Down
12 changes: 6 additions & 6 deletions src/Microsoft.OData.Core/Json/ODataAnnotationNames.cs
Original file line number Diff line number Diff line change
Expand Up @@ -112,11 +112,11 @@ internal static class ODataAnnotationNames
/// </summary>
/// <param name="annotationName">The name of the annotation in question.</param>
/// <returns>Returns true if the <paramref name="annotationName"/> starts with "odata.", false otherwise.</returns>
internal static bool IsODataAnnotationName(string annotationName)
internal static bool IsODataAnnotationName(ReadOnlySpan<char> annotationName)
{
Debug.Assert(!string.IsNullOrEmpty(annotationName), "!string.IsNullOrEmpty(annotationName)");
Debug.Assert(!annotationName.IsEmpty, "!string.IsNullOrEmpty(annotationName)");

if (annotationName.StartsWith(ODataJsonConstants.ODataAnnotationNamespacePrefix, StringComparison.Ordinal))
if (annotationName.StartsWith(ODataJsonConstants.ODataAnnotationNamespacePrefix.AsSpan(), StringComparison.Ordinal))
{
return true;
}
Expand All @@ -129,11 +129,11 @@ internal static bool IsODataAnnotationName(string annotationName)
/// </summary>
/// <param name="annotationName">The annotation name in question.</param>
/// <returns>Returns true if the <paramref name="annotationName"/> starts with "odata." and is not one of the reserved odata annotation names; returns false otherwise.</returns>
internal static bool IsUnknownODataAnnotationName(string annotationName)
internal static bool IsUnknownODataAnnotationName(ReadOnlySpan<char> annotationName)
{
Debug.Assert(!string.IsNullOrEmpty(annotationName), "!string.IsNullOrEmpty(annotationName)");
Debug.Assert(!annotationName.IsEmpty, "!string.IsNullOrEmpty(annotationName)");

if (IsODataAnnotationName(annotationName) && !KnownODataAnnotationNames.Contains(annotationName))
if (IsODataAnnotationName(annotationName) && !KnownODataAnnotationNames.Contains(annotationName.ToString()))
{
return true;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,13 +148,13 @@ await jsonBatchPayloadItemPropertiesCache.ScanJsonPropertiesAsync()
/// </summary>
/// <param name="propertyName"> Name of the property.</param>
/// <returns>Property value. Null if not found.</returns>
internal object GetPropertyValue(string propertyName)
internal object GetPropertyValue(ReadOnlySpan<char> propertyName)
{
if (this.jsonProperties != null)
{
string canonicalPropertyName = Normalize(propertyName);
ReadOnlySpan<char> canonicalPropertyName = Normalize(propertyName);
object propertyValue;
if (this.jsonProperties.TryGetValue(canonicalPropertyName, out propertyValue))
if (this.jsonProperties.TryGetValue(canonicalPropertyName.ToString(), out propertyValue))
{
return propertyValue;
}
Expand Down Expand Up @@ -186,9 +186,11 @@ private ODataJsonBatchBodyContentReaderStream CreateJsonPayloadBodyContentStream
/// </summary>
/// <param name="propertyName">Name to be normalized.</param>
/// <returns>The normalized name.</returns>
private static string Normalize(string propertyName)
private static ReadOnlySpan<char> Normalize(ReadOnlySpan<char> propertyName)
{
return propertyName.ToUpperInvariant();
Span<char> buffer = new Span<char>(new char[propertyName.Length]);
propertyName.ToUpperInvariant(buffer);
return buffer;
}

/// <summary>
Expand All @@ -211,7 +213,7 @@ private void ScanJsonProperties()
while (this.jsonReader.NodeType != JsonNodeType.EndObject)
{
// Convert to upper case to support case-insensitive request property names
string propertyName = Normalize(this.jsonReader.ReadPropertyName());
string propertyName = Normalize(this.jsonReader.ReadPropertyName()).ToString();

// Throw an ODataException, if a duplicate json property was detected
if (jsonProperties.ContainsKey(propertyName))
Expand Down Expand Up @@ -265,7 +267,7 @@ private void ScanJsonProperties()

while (this.jsonReader.NodeType != JsonNodeType.EndObject)
{
string headerName = this.jsonReader.ReadPropertyName();
string headerName = this.jsonReader.ReadPropertyName().ToString();
string headerValue = this.jsonReader.ReadPrimitiveValue()?.ToString();

// Throw an ODataException, if a duplicate header was detected
Expand Down Expand Up @@ -362,7 +364,7 @@ await this.jsonReader.ReadStartObjectAsync()
while (this.jsonReader.NodeType != JsonNodeType.EndObject)
{
// Convert to upper case to support case-insensitive request property names
string propertyName = Normalize(await this.jsonReader.ReadPropertyNameAsync().ConfigureAwait(false));
string propertyName = Normalize((await this.jsonReader.ReadPropertyNameAsync().ConfigureAwait(false)).Span).ToString();

// Throw an ODataException, if a duplicate json property was detected
if (jsonProperties.ContainsKey(propertyName))
Expand Down Expand Up @@ -416,8 +418,8 @@ await this.jsonReader.ReadStartObjectAsync()

while (this.jsonReader.NodeType != JsonNodeType.EndObject)
{
string headerName = await this.jsonReader.ReadPropertyNameAsync()
.ConfigureAwait(false);
string headerName = (await this.jsonReader.ReadPropertyNameAsync()
.ConfigureAwait(false)).ToString();
string headerValue = (await this.jsonReader.ReadPrimitiveValueAsync().ConfigureAwait(false))?.ToString();

// Throw an ODataException, if a duplicate header was detected
Expand Down
12 changes: 6 additions & 6 deletions src/Microsoft.OData.Core/Json/ODataJsonBatchReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -500,12 +500,12 @@ private void DetectReaderMode()
this.batchStream.JsonReader.ReadNext();
this.batchStream.JsonReader.ReadStartObject();

string propertyName = this.batchStream.JsonReader.ReadPropertyName();
if (PropertyNameRequests.Equals(propertyName, StringComparison.OrdinalIgnoreCase))
ReadOnlySpan<char> propertyName = this.batchStream.JsonReader.ReadPropertyName();
if (propertyName.Equals(PropertyNameRequests.AsSpan(), StringComparison.OrdinalIgnoreCase))
{
this.mode = ReaderMode.Requests;
}
else if (PropertyNameResponses.Equals(propertyName, StringComparison.OrdinalIgnoreCase))
else if (propertyName.Equals(PropertyNameResponses.AsSpan(), StringComparison.OrdinalIgnoreCase))
{
this.mode = ReaderMode.Responses;
}
Expand Down Expand Up @@ -623,14 +623,14 @@ await this.batchStream.JsonReader.ReadNextAsync()
await this.batchStream.JsonReader.ReadStartObjectAsync()
.ConfigureAwait(false);

string propertyName = await this.batchStream.JsonReader.ReadPropertyNameAsync()
ReadOnlyMemory<char> propertyName = await this.batchStream.JsonReader.ReadPropertyNameAsync()
.ConfigureAwait(false);

if (PropertyNameRequests.Equals(propertyName, StringComparison.OrdinalIgnoreCase))
if (propertyName.Span.Equals(PropertyNameRequests.AsSpan(), StringComparison.OrdinalIgnoreCase))
{
this.mode = ReaderMode.Requests;
}
else if (PropertyNameResponses.Equals(propertyName, StringComparison.OrdinalIgnoreCase))
else if (propertyName.Span.Equals(PropertyNameResponses.AsSpan(), StringComparison.OrdinalIgnoreCase))
{
this.mode = ReaderMode.Responses;
}
Expand Down
Loading