internal static JsonTokenInfo[] GetTokensFromNode(IJsonNavigatorNode node, IJsonNavigator navigator, bool performCorrectnessCheck) { switch (navigator.GetNodeType(node)) { case JsonNodeType.Null: return(new JsonTokenInfo[] { JsonTokenInfo.Null() }); case JsonNodeType.False: return(new JsonTokenInfo[] { JsonTokenInfo.Boolean(false) }); case JsonNodeType.True: return(new JsonTokenInfo[] { JsonTokenInfo.Boolean(true) }); case JsonNodeType.Number: return(new JsonTokenInfo[] { JsonTokenInfo.Number(navigator.GetNumberValue(node)) }); case JsonNodeType.String: return(new JsonTokenInfo[] { JsonTokenInfo.String(navigator.GetStringValue(node)) }); case JsonNodeType.Array: return(JsonNavigatorTests.GetTokensFromArrayNode(node, navigator, performCorrectnessCheck)); case JsonNodeType.Object: return(JsonNavigatorTests.GetTokensFromObjectNode(node, navigator, performCorrectnessCheck)); case JsonNodeType.FieldName: return(new JsonTokenInfo[] { JsonTokenInfo.FieldName(navigator.GetStringValue(node)) }); default: throw new InvalidOperationException(); } }
private static JsonToken[] GetTokensFromNode(IJsonNavigatorNode node, IJsonNavigator navigator, bool performCorrectnessCheck) { switch (navigator.GetNodeType(node)) { case JsonNodeType.Null: return(new JsonToken[] { JsonToken.Null() }); case JsonNodeType.False: return(new JsonToken[] { JsonToken.Boolean(false) }); case JsonNodeType.True: return(new JsonToken[] { JsonToken.Boolean(true) }); case JsonNodeType.Number64: return(new JsonToken[] { JsonToken.Number(navigator.GetNumber64Value(node)) }); case JsonNodeType.String: return(new JsonToken[] { JsonToken.String(navigator.GetStringValue(node)) }); case JsonNodeType.Array: return(JsonNavigatorTests.GetTokensFromArrayNode(node, navigator, performCorrectnessCheck)); case JsonNodeType.Object: return(JsonNavigatorTests.GetTokensFromObjectNode(node, navigator, performCorrectnessCheck)); case JsonNodeType.FieldName: return(new JsonToken[] { JsonToken.FieldName(navigator.GetStringValue(node)) }); case JsonNodeType.Int8: return(new JsonToken[] { JsonToken.Int8(navigator.GetInt8Value(node)) }); case JsonNodeType.Int16: return(new JsonToken[] { JsonToken.Int16(navigator.GetInt16Value(node)) }); case JsonNodeType.Int32: return(new JsonToken[] { JsonToken.Int32(navigator.GetInt32Value(node)) }); case JsonNodeType.Int64: return(new JsonToken[] { JsonToken.Int64(navigator.GetInt64Value(node)) }); case JsonNodeType.UInt32: return(new JsonToken[] { JsonToken.UInt32(navigator.GetUInt32Value(node)) }); case JsonNodeType.Float32: return(new JsonToken[] { JsonToken.Float32(navigator.GetFloat32Value(node)) }); case JsonNodeType.Float64: return(new JsonToken[] { JsonToken.Float64(navigator.GetFloat64Value(node)) }); case JsonNodeType.Guid: return(new JsonToken[] { JsonToken.Guid(navigator.GetGuidValue(node)) }); case JsonNodeType.Binary: return(new JsonToken[] { JsonToken.Binary(navigator.GetBinaryValue(node)) }); default: throw new InvalidOperationException(); } }
public void LargeArrayBinaryJsonTest() { StringBuilder builder = new StringBuilder((1 << 24) + 50); builder.Append('['); for (int x = 1 << 24; x < (1 << 24) + 3355450; ++x) { builder.Append(x); builder.Append(','); } builder.Append("\"string_one\""); builder.Append(','); builder.Append("\"string_two\""); builder.Append(','); builder.Append("\"string_two\""); builder.Append(']'); string json = builder.ToString(); byte[] binaryJson = JsonTestUtils.ConvertTextToBinary(json); IJsonNavigator navigator = JsonNavigator.Create(binaryJson); int count = navigator.GetArrayItemCount(navigator.GetRootNode()); IJsonNavigatorNode node = navigator.GetArrayItemAt(navigator.GetRootNode(), count - 1); string stringValue = navigator.GetStringValue(node); Assert.AreEqual("string_two", stringValue); }
internal static JsonTokenInfo[] GetTokensFromObjectNode(IJsonNavigatorNode node, IJsonNavigator navigator, bool performCorrectnessCheck) { // Get the tokens through .GetObjectProperties List <JsonTokenInfo> tokensFromGetProperties = new List <JsonTokenInfo>(); IEnumerable <ObjectProperty> properties = navigator.GetObjectProperties(node); tokensFromGetProperties.Add(JsonTokenInfo.ObjectStart()); foreach (ObjectProperty property in properties) { string fieldname = navigator.GetStringValue(property.NameNode); tokensFromGetProperties.Add(JsonTokenInfo.FieldName(fieldname)); tokensFromGetProperties.AddRange(JsonNavigatorTests.GetTokensFromNode(property.ValueNode, navigator, performCorrectnessCheck)); } tokensFromGetProperties.Add(JsonTokenInfo.ObjectEnd()); if (performCorrectnessCheck) { // Get the tokens again through .TryGetObjectProperty List <JsonTokenInfo> tokensFromTryGetProperty = new List <JsonTokenInfo>(); tokensFromTryGetProperty.Add(JsonTokenInfo.ObjectStart()); foreach (ObjectProperty objectProperty in properties) { ObjectProperty propertyFromTryGetProperty; string fieldname = navigator.GetStringValue(objectProperty.NameNode); if (navigator.TryGetObjectProperty(node, fieldname, out propertyFromTryGetProperty)) { tokensFromTryGetProperty.Add(JsonTokenInfo.FieldName(fieldname)); tokensFromTryGetProperty.AddRange(JsonNavigatorTests.GetTokensFromNode(propertyFromTryGetProperty.ValueNode, navigator, performCorrectnessCheck)); } else { Assert.Fail($"Failed to get object property with name: {fieldname}"); } } tokensFromTryGetProperty.Add(JsonTokenInfo.ObjectEnd()); Assert.AreEqual(properties.Count(), navigator.GetObjectPropertyCount(node)); Assert.IsTrue(tokensFromGetProperties.SequenceEqual(tokensFromTryGetProperty)); } return(tokensFromGetProperties.ToArray()); }
/// <summary> /// Writes a json node to the internal buffer. /// </summary> /// <param name="jsonNavigator">The navigator to use to navigate the node</param> /// <param name="jsonNavigatorNode">The node to write.</param> public void WriteJsonNode(IJsonNavigator jsonNavigator, IJsonNavigatorNode jsonNavigatorNode) { if (jsonNavigator == null) { throw new ArgumentNullException($"{nameof(jsonNavigator)} can not be null"); } if (jsonNavigatorNode == null) { throw new ArgumentNullException($"{nameof(jsonNavigatorNode)} can not be null"); } // For now short circuit this to false until we figure out how to optimize this. bool sameFormat = jsonNavigator.SerializationFormat == this.SerializationFormat && (this.SerializationFormat == JsonSerializationFormat.Binary || this.SerializationFormat == JsonSerializationFormat.HybridRow); JsonNodeType jsonNodeType = jsonNavigator.GetNodeType(jsonNavigatorNode); // See if we can write the node without looking at it's value switch (jsonNodeType) { case JsonNodeType.Null: this.WriteNullValue(); return; case JsonNodeType.False: this.WriteBoolValue(false); return; case JsonNodeType.True: this.WriteBoolValue(true); return; } // If the navigator has the same format as this writer then we try to retrieve the node raw JSON IReadOnlyList <byte> bufferedRawJson; if (sameFormat && jsonNavigator.TryGetBufferedRawJson(jsonNavigatorNode, out bufferedRawJson)) { // Token type really doesn't make any difference other than whether this is a field name JsonTokenType jsonTokenType = (jsonNodeType == JsonNodeType.FieldName ? JsonTokenType.FieldName : JsonTokenType.Null); this.WriteRawJsonToken(jsonTokenType, bufferedRawJson); } else { // Either the formats did not match or we couldn't retrieve the buffered raw JSON switch (jsonNodeType) { case JsonNodeType.Number: double numberValue = jsonNavigator.GetNumberValue(jsonNavigatorNode); this.WriteNumberValue(numberValue); break; case JsonNodeType.String: case JsonNodeType.FieldName: bool fieldName = jsonNodeType == JsonNodeType.FieldName; IReadOnlyList <byte> bufferedStringValue; if (jsonNavigator.TryGetBufferedStringValue(jsonNavigatorNode, out bufferedStringValue)) { if (fieldName) { this.WriteRawJsonToken(JsonTokenType.FieldName, bufferedStringValue); } else { this.WriteRawJsonToken(JsonTokenType.String, bufferedStringValue); } } else { string value = jsonNavigator.GetStringValue(jsonNavigatorNode); if (fieldName) { this.WriteFieldName(value); } else { this.WriteStringValue(value); } } break; case JsonNodeType.Int8: { sbyte number = jsonNavigator.GetInt8Value(jsonNavigatorNode); this.WriteInt8Value(number); break; } case JsonNodeType.Int16: { short number = jsonNavigator.GetInt16Value(jsonNavigatorNode); this.WriteInt16Value(number); break; } case JsonNodeType.Int32: { int number = jsonNavigator.GetInt32Value(jsonNavigatorNode); this.WriteInt32Value(number); break; } case JsonNodeType.Int64: { long number = jsonNavigator.GetInt64Value(jsonNavigatorNode); this.WriteInt64Value(number); break; } case JsonNodeType.UInt32: { uint number = jsonNavigator.GetUInt32Value(jsonNavigatorNode); this.WriteUInt32Value(number); break; } case JsonNodeType.Float32: { float number = jsonNavigator.GetFloat32Value(jsonNavigatorNode); this.WriteFloat32Value(number); break; } case JsonNodeType.Float64: { double number = jsonNavigator.GetFloat64Value(jsonNavigatorNode); this.WriteFloat64Value(number); break; } case JsonNodeType.Guid: { Guid number = jsonNavigator.GetGuidValue(jsonNavigatorNode); this.WriteGuidValue(number); break; } case JsonNodeType.Binary: { IReadOnlyList <byte> bufferedBinaryValue; if (jsonNavigator.TryGetBufferedBinaryValue(jsonNavigatorNode, out bufferedBinaryValue)) { this.WriteRawJsonToken(JsonTokenType.Binary, bufferedBinaryValue); } else { IReadOnlyList <byte> value = jsonNavigator.GetBinaryValue(jsonNavigatorNode); this.WriteBinaryValue(value); } break; } case JsonNodeType.Array: this.WriteArrayStart(); foreach (IJsonNavigatorNode arrayItem in jsonNavigator.GetArrayItems(jsonNavigatorNode)) { this.WriteJsonNode(jsonNavigator, arrayItem); } this.WriteArrayEnd(); break; case JsonNodeType.Object: this.WriteObjectStart(); foreach (ObjectProperty objectProperty in jsonNavigator.GetObjectProperties(jsonNavigatorNode)) { this.WriteJsonNode(jsonNavigator, objectProperty.NameNode); this.WriteJsonNode(jsonNavigator, objectProperty.ValueNode); } this.WriteObjectEnd(); break; default: throw new ArgumentException($"Unexpected JsonNodeType: {jsonNodeType}"); } } }
/// <summary> /// Converts a list of CosmosElements into a memory stream. /// </summary> /// <param name="memoryStream">The memory stream response from Azure Cosmos</param> /// <param name="resourceType">The resource type</param> /// <param name="cosmosSerializationOptions">The custom serialization options. This allows custom serialization types like BSON, JSON, or other formats</param> /// <returns>Returns a memory stream of cosmos elements. By default the memory stream will contain JSON.</returns> internal static CosmosArray ToCosmosElements( MemoryStream memoryStream, ResourceType resourceType, CosmosSerializationFormatOptions cosmosSerializationOptions = null) { if (!memoryStream.CanRead) { throw new InvalidDataException("Stream can not be read"); } // Execute the callback an each element of the page // For example just could get a response like this // { // "_rid": "qHVdAImeKAQ=", // "Documents": [{ // "id": "03230", // "_rid": "qHVdAImeKAQBAAAAAAAAAA==", // "_self": "dbs\/qHVdAA==\/colls\/qHVdAImeKAQ=\/docs\/qHVdAImeKAQBAAAAAAAAAA==\/", // "_etag": "\"410000b0-0000-0000-0000-597916b00000\"", // "_attachments": "attachments\/", // "_ts": 1501107886 // }], // "_count": 1 // } // And you should execute the callback on each document in "Documents". long responseLengthBytes = memoryStream.Length; byte[] content = memoryStream.ToArray(); IJsonNavigator jsonNavigator = null; // Use the users custom navigator if (cosmosSerializationOptions != null) { jsonNavigator = cosmosSerializationOptions.CreateCustomNavigatorCallback(content); if (jsonNavigator == null) { throw new InvalidOperationException("The CosmosSerializationOptions did not return a JSON navigator."); } } else { jsonNavigator = JsonNavigator.Create(new ArraySegment <byte>(content)); } string resourceName = CosmosElementSerializer.GetRootNodeName(resourceType); CosmosArray documents; if ((jsonNavigator.SerializationFormat == JsonSerializationFormat.Binary) && jsonNavigator.TryGetObjectProperty( jsonNavigator.GetRootNode(), "stringDictionary", out ObjectProperty stringDictionaryProperty)) { // Payload is string dictionary encode so we have to decode using the string dictionary. IJsonNavigatorNode stringDictionaryNode = stringDictionaryProperty.ValueNode; JsonStringDictionary jsonStringDictionary = JsonStringDictionary.CreateFromStringArray( jsonNavigator .GetArrayItems(stringDictionaryNode) .Select(item => jsonNavigator.GetStringValue(item)) .ToList()); if (!jsonNavigator.TryGetObjectProperty( jsonNavigator.GetRootNode(), resourceName, out ObjectProperty resourceProperty)) { throw new InvalidOperationException($"Response Body Contract was violated. QueryResponse did not have property: {resourceName}"); } IJsonNavigatorNode resources = resourceProperty.ValueNode; if (!jsonNavigator.TryGetBufferedBinaryValue(resources, out ReadOnlyMemory <byte> resourceBinary)) { resourceBinary = jsonNavigator.GetBinaryValue(resources); } IJsonNavigator navigatorWithStringDictionary = JsonNavigator.Create(resourceBinary, jsonStringDictionary); if (!(CosmosElement.Dispatch( navigatorWithStringDictionary, navigatorWithStringDictionary.GetRootNode()) is CosmosArray cosmosArray)) { throw new InvalidOperationException($"QueryResponse did not have an array of : {resourceName}"); } documents = cosmosArray; } else { // Payload is not string dictionary encoded so we can just do for the documents as is. if (!jsonNavigator.TryGetObjectProperty( jsonNavigator.GetRootNode(), resourceName, out ObjectProperty objectProperty)) { throw new InvalidOperationException($"Response Body Contract was violated. QueryResponse did not have property: {resourceName}"); } if (!(CosmosElement.Dispatch( jsonNavigator, objectProperty.ValueNode) is CosmosArray cosmosArray)) { throw new InvalidOperationException($"QueryResponse did not have an array of : {resourceName}"); } documents = cosmosArray; } return(documents); }