private void BuildPositions() { using (Stream stream = _streamProvider()) using (JsonPositionedTextReader reader = new JsonPositionedTextReader(() => stream)) { stream.Seek(_start, SeekOrigin.Begin); reader.Read(); BuildPositions(reader, _start); } }
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { JsonPositionedTextReader r = reader as JsonPositionedTextReader; if (r == null) { throw new InvalidOperationException($"{nameof(DeferredListConverter<T>)} requires a {nameof(JsonPositionedTextReader)} be used for deserialization."); } return(new DeferredList <T>(serializer, r)); }
public DeferredList(JsonSerializer jsonSerializer, JsonPositionedTextReader reader, bool buildPositionsNow = true) { _jsonSerializer = jsonSerializer; _streamProvider = reader.StreamProvider; _start = reader.TokenPosition; _count = -1; if (buildPositionsNow) { BuildPositions(reader, 0); } else { // We have to skip the array; it is free to get the count now so we don't have to walk again to get it. CountOnly(reader); } }
public DeferredDictionary(JsonSerializer jsonSerializer, JsonPositionedTextReader reader, bool buildPositionsNow = false) { _jsonSerializer = jsonSerializer; _streamProvider = reader.StreamProvider; _start = reader.TokenPosition; // We have the JsonTextReader, which must scan to after the collection to resume building the outer object // We may as well make the map of element positions. if (buildPositionsNow) { BuildPositions(reader, 0); } else { reader.Skip(); } }
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { if (reader is JsonInnerTextReader) { // Nested in another deferred container, read the list non-deferred return(serializer.Deserialize <List <T> >(reader)); } // If we don't have a positioned reader, we must return an error JsonPositionedTextReader r = reader as JsonPositionedTextReader; if (r == null) { throw new InvalidOperationException($"{nameof(DeferredListConverter<T>)} requires a {nameof(JsonPositionedTextReader)} be used for deserialization."); } return(new DeferredList <T>(serializer, r)); }
private void BuildPositions(JsonPositionedTextReader reader, long currentOffset) { List <long> positions = new List <long>(); while (true) { reader.Read(); if (reader.TokenType == JsonToken.EndArray) { break; } positions.Add(currentOffset + reader.TokenPosition); reader.Skip(); } _itemPositions = positions.ToArray(); _count = positions.Count; }
private void CountOnly(JsonPositionedTextReader reader) { int count = 0; // StartArray reader.Read(); while (true) { reader.Read(); if (reader.TokenType == JsonToken.EndArray) { break; } count++; reader.Skip(); } _count = count; }
private void BuildPositions(JsonPositionedTextReader reader, long currentOffset) { var result = new Dictionary <int, long>(); while (true) { // Find the position just before the PropertyName (we need to read it back later to confirm the string matches) long keyPosition = currentOffset + reader.TokenPosition + 1; reader.Read(); if (reader.TokenType == JsonToken.EndObject) { break; } if (reader.TokenType != JsonToken.PropertyName) { throw new InvalidDataException($"@({reader.LineNumber}, {reader.LinePosition}): Expected property name, found {reader.TokenType} \"{reader.Value}\"."); } // Read JSON object name (Dictionary key) string key = (string)reader.Value; int keyHash = key.GetHashCode(); // Skip the value reader.Read(); reader.Skip(); // Add the hash to the position to our Dictionary; resolve collisions by incrementing while (result.ContainsKey(keyHash)) { keyHash++; } result[keyHash] = keyPosition; } _itemPositions = result; }
private static void CompareReadNormalToReadDeferred(string filePath) { LogModelSampleBuilder.EnsureSamplesBuilt(); JsonSerializer serializer = new JsonSerializer(); Log expected; Log actual; // Read normally (JsonSerializer -> JsonTextReader -> StreamReader) using (JsonTextReader reader = new JsonTextReader(new StreamReader(filePath))) { expected = serializer.Deserialize <Log>(reader); Assert.IsType <Dictionary <string, CodeContext> >(expected.CodeContexts); Assert.IsType <List <LogMessage> >(expected.Messages); } // Read with Deferred collections serializer.ContractResolver = new LogModelDeferredContractResolver(); using (JsonPositionedTextReader reader = new JsonPositionedTextReader(filePath)) { actual = serializer.Deserialize <Log>(reader); Assert.IsType <DeferredDictionary <CodeContext> >(actual.CodeContexts); Assert.IsType <DeferredList <LogMessage> >(actual.Messages); } // Deep compare objects which were returned AssertEqual(expected, actual); // DeferredList Code Coverage - CopyTo() LogMessage[] messages = new LogMessage[actual.Messages.Count + 1]; actual.Messages.CopyTo(messages, 1); if (actual.Messages.Count > 0) { Assert.Equal <LogMessage>(actual.Messages[0], messages[1]); } // DeferredDictionary Code Coverage CodeContext context; // TryGetValue Assert.False(actual.CodeContexts.TryGetValue("missing", out context)); if (actual.CodeContexts.Count > 0) { Assert.True(actual.CodeContexts.TryGetValue("load", out context)); } // ContainsKey Assert.False(actual.CodeContexts.ContainsKey("missing")); if (actual.CodeContexts.Count > 0) { Assert.True(actual.CodeContexts.ContainsKey("load")); } // Contains context = new CodeContext() { Name = "LoadRules()", Type = CodeContextType.Method, ParentContextID = "run" }; Assert.False(actual.CodeContexts.Contains(new KeyValuePair <string, CodeContext>("missing", context))); // Missing Key Assert.False(actual.CodeContexts.Contains(new KeyValuePair <string, CodeContext>("run", context))); // Different Value if (actual.CodeContexts.Count > 0) { Assert.True(actual.CodeContexts.Contains(new KeyValuePair <string, CodeContext>("load", context))); // Match Assert.False(actual.CodeContexts.Contains(new KeyValuePair <string, CodeContext>("load", null))); // Match vs. Null } // CopyTo KeyValuePair <string, CodeContext>[] contexts = new KeyValuePair <string, CodeContext> [actual.CodeContexts.Count + 1]; actual.CodeContexts.CopyTo(contexts, 1); if (actual.CodeContexts.Count > 0) { Assert.Equal(actual.CodeContexts.First(), contexts[1]); } // Enumeration Dictionary <string, CodeContext> contextsCopy = new Dictionary <string, CodeContext>(); foreach (KeyValuePair <string, CodeContext> pair in actual.CodeContexts) { contextsCopy[pair.Key] = pair.Value; } Assert.Equal(actual.CodeContexts.Count, contextsCopy.Count); // Enumerate Keys int keyCount = 0; foreach (string key in actual.CodeContexts.Keys) { Assert.True(contextsCopy.ContainsKey(key)); keyCount++; } Assert.Equal(contextsCopy.Count, keyCount); // Enumerate Values int valueCount = 0; foreach (CodeContext value in actual.CodeContexts.Values) { Assert.True(contextsCopy.ContainsValue(value)); valueCount++; } Assert.Equal(contextsCopy.Count, valueCount); }