public void NavigatorToWriter( CurratedDocsPayload payload, SerializationFormat sourceFormat, SerializationFormat destinationFormat) { IJsonNavigator navigator = sourceFormat switch { SerializationFormat.Text => JsonNavigator.Create(payload.Text), SerializationFormat.BinaryWithDictionaryEncoding => JsonNavigator.Create( payload.BinaryWithDictionaryEncoding.binary, payload.BinaryWithDictionaryEncoding.dictionary), SerializationFormat.Binary => JsonNavigator.Create(payload.Binary), _ => throw new ArgumentException($"Unexpected {nameof(sourceFormat)} of type: '{sourceFormat}'"), }; IJsonWriter writer = destinationFormat switch { SerializationFormat.Text => JsonWriter.Create(JsonSerializationFormat.Text), SerializationFormat.Binary => JsonWriter.Create(JsonSerializationFormat.Binary), SerializationFormat.BinaryWithDictionaryEncoding => JsonWriter.Create( JsonSerializationFormat.Binary, sourceFormat == SerializationFormat.BinaryWithDictionaryEncoding ? payload.BinaryWithDictionaryEncoding.dictionary : new JsonStringDictionary(capacity: 128)), SerializationFormat.NewtonsoftText => NewtonsoftToCosmosDBWriter.CreateTextWriter(), _ => throw new ArgumentException($"Unexpected {nameof(destinationFormat)} of type: {destinationFormat}"), }; navigator.WriteNode(navigator.GetRootNode(), writer); }
private static async Task RewriteStreamAsTextAsync(ResponseMessage responseMessage, QueryRequestOptions requestOptions, ITrace trace) { using (ITrace rewriteTrace = trace.StartChild("Rewrite Stream as Text", TraceComponent.Json, TraceLevel.Info)) { // Rewrite the payload to be in the specified format. // If it's already in the correct format, then the following will be a memcpy. MemoryStream memoryStream; if (responseMessage.Content is MemoryStream responseContentAsMemoryStream) { memoryStream = responseContentAsMemoryStream; } else { memoryStream = new MemoryStream(); await responseMessage.Content.CopyToAsync(memoryStream); } ReadOnlyMemory <byte> buffer; if (memoryStream.TryGetBuffer(out ArraySegment <byte> segment)) { buffer = segment.Array.AsMemory().Slice(start: segment.Offset, length: segment.Count); } else { buffer = memoryStream.ToArray(); } IJsonNavigator jsonNavigator = JsonNavigator.Create(buffer); if (jsonNavigator.SerializationFormat == JsonSerializationFormat.Text) { // Exit to avoid the memory allocation. return; } IJsonWriter jsonWriter; if (requestOptions?.CosmosSerializationFormatOptions != null) { jsonWriter = requestOptions.CosmosSerializationFormatOptions.CreateCustomWriterCallback(); } else { jsonWriter = JsonWriter.Create(JsonSerializationFormat.Text); } jsonNavigator.WriteNode(jsonNavigator.GetRootNode(), jsonWriter); ReadOnlyMemory <byte> result = jsonWriter.GetResult(); MemoryStream rewrittenMemoryStream; if (MemoryMarshal.TryGetArray(result, out ArraySegment <byte> rewrittenSegment)) { rewrittenMemoryStream = new MemoryStream(rewrittenSegment.Array, index: rewrittenSegment.Offset, count: rewrittenSegment.Count, writable: false, publiclyVisible: true); } else { byte[] toArray = result.ToArray(); rewrittenMemoryStream = new MemoryStream(toArray, index: 0, count: toArray.Length, writable: false, publiclyVisible: true); } responseMessage.Content = rewrittenMemoryStream; } }