private bool WriteStartArray(JsonWriter writer, object values, JsonArrayContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty)
		{
			bool isReference = ResolveIsReference(contract, member, containerContract, containerProperty) ?? HasFlag(Serializer._preserveReferencesHandling, PreserveReferencesHandling.Arrays);
			bool includeTypeDetails = ShouldWriteType(TypeNameHandling.Arrays, contract, member, containerContract, containerProperty);
			bool writeMetadataObject = isReference || includeTypeDetails;

			if (writeMetadataObject)
			{
				writer.WriteStartObject();

				if (isReference)
				{
					WriteReferenceIdProperty(writer, contract.UnderlyingType, values);
				}
				if (includeTypeDetails)
				{
					WriteTypeProperty(writer, values.GetType());
				}
				writer.WritePropertyName(JsonTypeReflector.ArrayValuesPropertyName, false);
			}

			if (contract.ItemContract == null)
				contract.ItemContract = Serializer._contractResolver.ResolveContract(contract.CollectionItemType ?? typeof(object));

			return writeMetadataObject;
		}
		private void SerializeMultidimensionalArray(JsonWriter writer, Array values, JsonArrayContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
		{
			OnSerializing(writer, contract, values);

			_serializeStack.Add(values);

			bool hasWrittenMetadataObject = WriteStartArray(writer, values, contract, member, collectionContract, containerProperty);

			SerializeMultidimensionalArray(writer, values, contract, member, writer.Top, new int[0]);

			if (hasWrittenMetadataObject)
				writer.WriteEndObject();

			_serializeStack.RemoveAt(_serializeStack.Count - 1);

			OnSerialized(writer, contract, values);
		}
		private void SerializeMultidimensionalArray(JsonWriter writer, Array values, JsonArrayContract contract, JsonProperty member, int initialDepth, int[] indices)
		{
			int dimension = indices.Length;
			int[] newIndices = new int[dimension + 1];
			for (int i = 0; i < dimension; i++)
			{
				newIndices[i] = indices[i];
			}

			writer.WriteStartArray();

			for (int i = 0; i < values.GetLength(dimension); i++)
			{
				newIndices[dimension] = i;
				bool isTopLevel = (newIndices.Length == values.Rank);

				if (isTopLevel)
				{
					object value = values.GetValue(newIndices);

					try
					{
						JsonContract valueContract = contract.FinalItemContract ?? GetContractSafe(value);

						if (ShouldWriteReference(value, null, valueContract, contract, member))
						{
							WriteReference(writer, value);
						}
						else
						{
							if (CheckForCircularReference(writer, value, null, valueContract, contract, member))
							{
								SerializeValue(writer, value, valueContract, null, contract, member);
							}
						}
					}
					catch (Exception ex)
					{
						if (IsErrorHandled(values, contract, i, null, writer.ContainerPath, ex))
							HandleError(writer, initialDepth + 1);
						else
							throw;
					}
				}
				else
				{
					SerializeMultidimensionalArray(writer, values, contract, member, initialDepth + 1, newIndices);
				}
			}

			writer.WriteEndArray();
		}
        private void SerializeList(JsonWriter writer, IEnumerable values, JsonArrayContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
        {
            IWrappedCollection wrappedCollection = values as IWrappedCollection;
            object underlyingList = wrappedCollection != null ? wrappedCollection.UnderlyingCollection : values;

            OnSerializing(writer, contract, underlyingList);

            _serializeStack.Add(underlyingList);

            bool hasWrittenMetadataObject = WriteStartArray(writer, underlyingList, contract, member, collectionContract, containerProperty);

            writer.WriteStartArray();

            int initialDepth = writer.Top;

            int index = 0;
            IEnumerator enumerator;
            try
            {
                enumerator = values.GetEnumerator();
            }
            catch (Exception e)
            {
                throw new InvalidOperationException("Could not get enumerator for property: " + member, e);
            }
            using (enumerator as IDisposable)
            {
                while (true)
                {
                    try
                    {
                        if (enumerator.MoveNext() == false)
                            break;
                    }
                    catch (Exception e)
                    {
                        throw new InvalidOperationException("Could not move to next value for property: " + member, e);

                    }
                    object value;
                    try
                    {
                        value = enumerator.Current;
                    }
                    catch (Exception e)
                    {
                        throw new InvalidOperationException("Could not get current value for property: " + member, e);

                    }
                    try
                    {
                        JsonContract valueContract = contract.FinalItemContract ?? GetContractSafe(value);

                        if (ShouldWriteReference(value, null, valueContract, contract, member))
                        {
                            WriteReference(writer, value);
                        }
                        else
                        {
                            if (CheckForCircularReference(writer, value, null, valueContract, contract, member))
                            {
                                SerializeValue(writer, value, valueContract, null, contract, member);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        if (IsErrorHandled(underlyingList, contract, index, null, writer.ContainerPath, ex))
                            HandleError(writer, initialDepth);
                        else
                            throw;
                    }
                    finally
                    {
                        index++;
                    }
                }
            }

            writer.WriteEndArray();

            if (hasWrittenMetadataObject)
                writer.WriteEndObject();

            _serializeStack.RemoveAt(_serializeStack.Count - 1);

            OnSerialized(writer, contract, underlyingList);
        }
		private void SerializeList(JsonWriter writer, IEnumerable values, JsonArrayContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
		{
			IWrappedCollection wrappedCollection = values as IWrappedCollection;
			object underlyingList = wrappedCollection != null ? wrappedCollection.UnderlyingCollection : values;

			OnSerializing(writer, contract, underlyingList);

			_serializeStack.Add(underlyingList);

			bool hasWrittenMetadataObject = WriteStartArray(writer, underlyingList, contract, member, collectionContract, containerProperty);

			writer.WriteStartArray();

			int initialDepth = writer.Top;

			int index = 0;
			// note that an error in the IEnumerable won't be caught
			foreach (object value in values)
			{
				try
				{
					JsonContract valueContract = contract.FinalItemContract ?? GetContractSafe(value);

					if (ShouldWriteReference(value, null, valueContract, contract, member))
					{
						WriteReference(writer, value);
					}
					else
					{
						if (CheckForCircularReference(writer, value, null, valueContract, contract, member))
						{
							SerializeValue(writer, value, valueContract, null, contract, member);
						}
					}
				}
				catch (Exception ex)
				{
					if (IsErrorHandled(underlyingList, contract, index, null, writer.ContainerPath, ex))
						HandleError(writer, initialDepth);
					else
						throw;
				}
				finally
				{
					index++;
				}
			}

			writer.WriteEndArray();

			if (hasWrittenMetadataObject)
				writer.WriteEndObject();

			_serializeStack.RemoveAt(_serializeStack.Count - 1);

			OnSerialized(writer, contract, underlyingList);
		}
    private object PopulateMultidimensionalArray(IList list, JsonReader reader, JsonArrayContract contract, JsonProperty containerProperty, string id)
    {
      int rank = contract.UnderlyingType.GetArrayRank();

      if (id != null)
        AddReference(reader, id, list);

      OnDeserializing(reader, contract, list);

      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 = DeserializeConvertable(collectionItemConverter, reader, contract.CollectionItemType, null);
                  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 as IJsonLineInfo, 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.");

      OnDeserialized(reader, contract, list);
      return list;
    }
Ejemplo n.º 7
0
    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;

      while (true)
      {
        try
        {
          if (ReadForType(reader, collectionItemContract, collectionItemConverter != null))
          {
            switch (reader.TokenType)
            {
              case JsonToken.EndArray:
                contract.InvokeOnDeserialized(list, Serializer.Context);

                return list;
              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;
          }
        }
      }

      throw JsonSerializationException.Create(reader, "Unexpected end when deserializing array.");
    }
        private object PopulateList(IList list, JsonReader reader, JsonArrayContract contract, JsonProperty containerProperty, string id)
        {
            IWrappedCollection wrappedCollection = list as IWrappedCollection;
            object underlyingList = wrappedCollection != null ? wrappedCollection.UnderlyingCollection : list;

            if (id != null)
                AddReference(reader, id, underlyingList);

            // can't populate an existing array
            if (list.IsFixedSize)
            {
                reader.Skip();
                return underlyingList;
            }

            OnDeserializing(reader, contract, underlyingList);

            int initialDepth = reader.Depth;

            if (contract.ItemContract == null)
                contract.ItemContract = GetContractSafe(contract.CollectionItemType);

            JsonConverter collectionItemConverter = GetConverter(contract.ItemContract, null, contract, containerProperty);

            int? previousErrorIndex = null;

            bool finished = false;
            do
            {
                try
                {
                    if (ReadForType(reader, contract.ItemContract, collectionItemConverter != null))
                    {
                        switch (reader.TokenType)
                        {
                            case JsonToken.EndArray:
                                finished = true;
                                break;
                            case JsonToken.Comment:
                                break;
                            default:
                                object value;

                                if (collectionItemConverter != null && collectionItemConverter.CanRead)
                                    value = DeserializeConvertable(collectionItemConverter, reader, contract.CollectionItemType, null);
                                else
                                    value = CreateValueInternal(reader, contract.CollectionItemType, contract.ItemContract, null, contract, containerProperty, null);

                                list.Add(value);
                                break;
                        }
                    }
                    else
                    {
                        break;
                    }
                }
                catch (Exception ex)
                {
                    JsonPosition errorPosition = reader.GetPosition(initialDepth);

                    if (IsErrorHandled(underlyingList, contract, errorPosition.Position, reader as IJsonLineInfo, 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, underlyingList, "Unexpected end when deserializing array.");

            OnDeserialized(reader, contract, underlyingList);
            return underlyingList;
        }
        private IList CreateNewList(JsonReader reader, JsonArrayContract contract, out bool createdFromNonDefaultCreator)
        {
            // some types like non-generic IEnumerable can be serialized but not deserialized
            if (!contract.CanDeserialize)
                throw JsonSerializationException.Create(reader, "Cannot create and populate list type {0}.".FormatWith(CultureInfo.InvariantCulture, contract.CreatedType));

            if (contract.IsReadOnlyOrFixedSize)
            {
                createdFromNonDefaultCreator = true;
                IList list = contract.CreateTemporaryCollection();

                if (contract.ShouldCreateWrapper)
                    list = contract.CreateWrapper(list);

                return list;
            }
            else if (contract.DefaultCreator != null && (!contract.DefaultCreatorNonPublic || Serializer._constructorHandling == ConstructorHandling.AllowNonPublicDefaultConstructor))
            {
                object list = contract.DefaultCreator();

                if (contract.ShouldCreateWrapper)
                    list = contract.CreateWrapper(list);

                createdFromNonDefaultCreator = false;
                return (IList)list;
            }
            else if (contract.HasParametrizedCreator)
            {
                createdFromNonDefaultCreator = true;
                return contract.CreateTemporaryCollection();
            }
            else
            {
                if (!contract.IsInstantiable)
                    throw JsonSerializationException.Create(reader, "Could not create an instance of type {0}. Type is an interface or abstract class and cannot be instantiated.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType));

                throw JsonSerializationException.Create(reader, "Unable to find a constructor to use for type {0}.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType));
            }
        }
Ejemplo n.º 10
0
        private void SerializeList(JsonWriter writer, IWrappedCollection values, JsonArrayContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
        {
            OnSerializing(writer, contract, values.UnderlyingCollection);

            _serializeStack.Add(values.UnderlyingCollection);

            bool hasWrittenMetadataObject = WriteStartArray(writer, values.UnderlyingCollection, contract, member, collectionContract, containerProperty);

            writer.WriteStartArray();

            int initialDepth = writer.Top;

            int index = 0;

            // note that an error in the IEnumerable won't be caught
            foreach (object value in values)
            {
                try
                {
                    JsonContract valueContract = contract.FinalItemContract ?? GetContractSafe(value);

                    if (ShouldWriteReference(value, null, valueContract, contract, member))
                    {
                        WriteReference(writer, value);
                    }
                    else
                    {
                        if (CheckForCircularReference(writer, value, null, valueContract, contract, member))
                        {
                            SerializeValue(writer, value, valueContract, null, contract, member);
                        }
                    }
                }
                catch (Exception ex)
                {
                    if (IsErrorHandled(values.UnderlyingCollection, contract, index, null, writer.ContainerPath, ex))
                    {
                        HandleError(writer, initialDepth);
                    }
                    else
                    {
                        throw;
                    }
                }
                finally
                {
                    index++;
                }
            }

            writer.WriteEndArray();

            if (hasWrittenMetadataObject)
            {
                writer.WriteEndObject();
            }

            _serializeStack.RemoveAt(_serializeStack.Count - 1);

            OnSerialized(writer, contract, values.UnderlyingCollection);
        }
Ejemplo n.º 11
0
        private void SerializeValue(JsonWriter writer, object value, JsonContract valueContract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty)
        {
            if (value == null)
            {
                writer.WriteNull();
                return;
            }

            JsonConverter converter;

            if ((((converter = (member != null) ? member.Converter : null) != null) ||
                 ((converter = (containerProperty != null) ? containerProperty.ItemConverter : null) != null) ||
                 ((converter = (containerContract != null) ? containerContract.ItemConverter : null) != null) ||
                 ((converter = valueContract.Converter) != null) ||
                 ((converter = Serializer.GetMatchingConverter(valueContract.UnderlyingType)) != null) ||
                 ((converter = valueContract.InternalConverter) != null)) &&
                converter.CanWrite)
            {
                SerializeConvertable(writer, converter, value, valueContract, containerContract, containerProperty);
                return;
            }

            switch (valueContract.ContractType)
            {
            case JsonContractType.Object:
                SerializeObject(writer, value, (JsonObjectContract)valueContract, member, containerContract, containerProperty);
                break;

            case JsonContractType.Array:
                JsonArrayContract arrayContract = (JsonArrayContract)valueContract;
                if (!arrayContract.IsMultidimensionalArray)
                {
                    SerializeList(writer, arrayContract.CreateWrapper(value), arrayContract, member, containerContract, containerProperty);
                }
                else
                {
                    SerializeMultidimensionalArray(writer, (Array)value, arrayContract, member, containerContract, containerProperty);
                }
                break;

            case JsonContractType.Primitive:
                SerializePrimitive(writer, value, (JsonPrimitiveContract)valueContract, member, containerContract, containerProperty);
                break;

            case JsonContractType.String:
                SerializeString(writer, value, (JsonStringContract)valueContract);
                break;

            case JsonContractType.Dictionary:
                JsonDictionaryContract dictionaryContract = (JsonDictionaryContract)valueContract;
                SerializeDictionary(writer, dictionaryContract.CreateWrapper(value), dictionaryContract, member, containerContract, containerProperty);
                break;

#if !(NET35 || NET20 || WINDOWS_PHONE || PORTABLE)
            case JsonContractType.Dynamic:
                SerializeDynamic(writer, (IDynamicMetaObjectProvider)value, (JsonDynamicContract)valueContract, member, containerContract, containerProperty);
                break;
#endif
#if !(SILVERLIGHT || NETFX_CORE || PORTABLE)
            case JsonContractType.Serializable:
                SerializeISerializable(writer, (ISerializable)value, (JsonISerializableContract)valueContract, member, containerContract, containerProperty);
                break;
#endif
            case JsonContractType.Linq:
                ((JToken)value).WriteTo(writer, (Serializer.Converters != null) ? Serializer.Converters.ToArray() : null);
                break;
            }
        }
        private void SerializeList(JsonWriter writer, IEnumerable values, JsonArrayContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
        {
            IWrappedCollection wrappedCollection = values as IWrappedCollection;
            object             underlyingList    = wrappedCollection != null ? wrappedCollection.UnderlyingCollection : values;

            OnSerializing(writer, contract, underlyingList);

            _serializeStack.Add(underlyingList);

            bool hasWrittenMetadataObject = WriteStartArray(writer, underlyingList, contract, member, collectionContract, containerProperty);

            writer.WriteStartArray();

            int initialDepth = writer.Top;

            int         index = 0;
            IEnumerator enumerator;

            try
            {
                enumerator = values.GetEnumerator();
            }
            catch (Exception e)
            {
                throw new InvalidOperationException("Could not get enumerator for property: " + member, e);
            }
            using (enumerator as IDisposable)
            {
                while (true)
                {
                    try
                    {
                        if (enumerator.MoveNext() == false)
                        {
                            break;
                        }
                    }
                    catch (Exception e)
                    {
                        throw new InvalidOperationException("Could not move to next value for property: " + member, e);
                    }
                    object value;
                    try
                    {
                        value = enumerator.Current;
                    }
                    catch (Exception e)
                    {
                        throw new InvalidOperationException("Could not get current value for property: " + member, e);
                    }
                    try
                    {
                        JsonContract valueContract = contract.FinalItemContract ?? GetContractSafe(value);

                        if (ShouldWriteReference(value, null, valueContract, contract, member))
                        {
                            WriteReference(writer, value);
                        }
                        else
                        {
                            if (CheckForCircularReference(writer, value, null, valueContract, contract, member))
                            {
                                SerializeValue(writer, value, valueContract, null, contract, member);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        if (IsErrorHandled(underlyingList, contract, index, null, writer.ContainerPath, ex))
                        {
                            HandleError(writer, initialDepth);
                        }
                        else
                        {
                            throw;
                        }
                    }
                    finally
                    {
                        index++;
                    }
                }
            }

            writer.WriteEndArray();

            if (hasWrittenMetadataObject)
            {
                writer.WriteEndObject();
            }

            _serializeStack.RemoveAt(_serializeStack.Count - 1);

            OnSerialized(writer, contract, underlyingList);
        }