private object PopulateMultidimensionalArray(IList list, JsonReader reader, JsonArrayContract contract, JsonProperty containerProperty, string id) { int rank = contract.UnderlyingType.GetArrayRank(); if (id != null) Serializer.ReferenceResolver.AddReference(this, id, list); contract.InvokeOnDeserializing(list, Serializer.Context); JsonContract collectionItemContract = GetContractSafe(contract.CollectionItemType); JsonConverter collectionItemConverter = GetConverter(collectionItemContract, null, contract, containerProperty); int? previousErrorIndex = null; Stack<IList> listStack = new Stack<IList>(); listStack.Push(list); IList currentList = list; bool finished = false; do { int initialDepth = reader.Depth; if (listStack.Count == rank) { try { if (ReadForType(reader, collectionItemContract, collectionItemConverter != null)) { switch (reader.TokenType) { case JsonToken.EndArray: listStack.Pop(); currentList = listStack.Peek(); previousErrorIndex = null; break; case JsonToken.Comment: break; default: object value; if (collectionItemConverter != null && collectionItemConverter.CanRead) value = collectionItemConverter.ReadJson(reader, contract.CollectionItemType, null, GetInternalSerializer()); else value = CreateValueInternal(reader, contract.CollectionItemType, collectionItemContract, null, contract, containerProperty, null); currentList.Add(value); break; } } else { break; } } catch (Exception ex) { JsonPosition errorPosition = reader.GetPosition(initialDepth); if (IsErrorHandled(list, contract, errorPosition.Position, reader.Path, ex)) { HandleError(reader, true, initialDepth); if (previousErrorIndex != null && previousErrorIndex == errorPosition.Position) { // reader index has not moved since previous error handling // break out of reading array to prevent infinite loop throw JsonSerializationException.Create(reader, "Infinite loop detected from error handling.", ex); } else { previousErrorIndex = errorPosition.Position; } } else { throw; } } } else { if (reader.Read()) { switch (reader.TokenType) { case JsonToken.StartArray: IList newList = new List<object>(); currentList.Add(newList); listStack.Push(newList); currentList = newList; break; case JsonToken.EndArray: listStack.Pop(); if (listStack.Count > 0) { currentList = listStack.Peek(); } else { finished = true; } break; case JsonToken.Comment: break; default: throw JsonSerializationException.Create(reader, "Unexpected token when deserializing multidimensional array: " + reader.TokenType); } } else { break; } } } while (!finished); if (!finished) ThrowUnexpectedEndException(reader, contract, list, "Unexpected end when deserializing array."); contract.InvokeOnDeserialized(list, Serializer.Context); return list; }
private object PopulateList(IWrappedCollection wrappedList, JsonReader reader, JsonArrayContract contract, JsonProperty containerProperty, string id) { object list = wrappedList.UnderlyingCollection; if (id != null) Serializer.ReferenceResolver.AddReference(this, id, list); // can't populate an existing array if (wrappedList.IsFixedSize) { reader.Skip(); return list; } contract.InvokeOnDeserializing(list, Serializer.Context); int initialDepth = reader.Depth; JsonContract collectionItemContract = GetContractSafe(contract.CollectionItemType); JsonConverter collectionItemConverter = GetConverter(collectionItemContract, null, contract, containerProperty); int? previousErrorIndex = null; bool finished = false; do { try { if (ReadForType(reader, collectionItemContract, collectionItemConverter != null)) { switch (reader.TokenType) { case JsonToken.EndArray: finished = true; break; case JsonToken.Comment: break; default: object value; if (collectionItemConverter != null && collectionItemConverter.CanRead) value = collectionItemConverter.ReadJson(reader, contract.CollectionItemType, null, GetInternalSerializer()); else value = CreateValueInternal(reader, contract.CollectionItemType, collectionItemContract, null, contract, containerProperty, null); wrappedList.Add(value); break; } } else { break; } } catch (Exception ex) { JsonPosition errorPosition = reader.GetPosition(initialDepth); if (IsErrorHandled(list, contract, errorPosition.Position, reader.Path, ex)) { HandleError(reader, true, initialDepth); if (previousErrorIndex != null && previousErrorIndex == errorPosition.Position) { // reader index has not moved since previous error handling // break out of reading array to prevent infinite loop throw JsonSerializationException.Create(reader, "Infinite loop detected from error handling.", ex); } else { previousErrorIndex = errorPosition.Position; } } else { throw; } } } while (!finished); if (!finished) ThrowUnexpectedEndException(reader, contract, list, "Unexpected end when deserializing array."); contract.InvokeOnDeserialized(list, Serializer.Context); return list; }