private void ReadSimpleDictionary(CollectionDataContract collectionContract, Type keyValueType)
{
Type[] keyValueTypes = keyValueType.GetGenericArguments();
Type keyType = keyValueTypes[0];
Type valueType = keyValueTypes[1];
int keyTypeNullableDepth = 0;
Type keyTypeOriginal = keyType;
while (keyType.GetTypeInfo().IsGenericType && keyType.GetGenericTypeDefinition() == Globals.TypeOfNullable)
{
keyTypeNullableDepth++;
keyType = keyType.GetGenericArguments()[0];
}
ClassDataContract keyValueDataContract = (ClassDataContract)collectionContract.ItemContract;
DataContract keyDataContract = keyValueDataContract.Members[0].MemberTypeContract;
KeyParseMode keyParseMode = KeyParseMode.Fail;
if (keyType == Globals.TypeOfString || keyType == Globals.TypeOfObject)
{
keyParseMode = KeyParseMode.AsString;
}
else if (keyType.GetTypeInfo().IsEnum)
{
keyParseMode = KeyParseMode.UsingParseEnum;
}
else if (keyDataContract.ParseMethod != null)
{
keyParseMode = KeyParseMode.UsingCustomParse;
}
if (keyParseMode == KeyParseMode.Fail)
{
ThrowSerializationException(
SR.Format(
SR.KeyTypeCannotBeParsedInSimpleDictionary,
DataContract.GetClrTypeFullName(collectionContract.UnderlyingType),
DataContract.GetClrTypeFullName(keyType)));
}
else
{
LocalBuilder nodeType = _ilg.DeclareLocal(typeof(XmlNodeType), "nodeType");
_ilg.BeginWhileCondition();
_ilg.Call(_xmlReaderArg, JsonFormatGeneratorStatics.MoveToContentMethod);
_ilg.Stloc(nodeType);
_ilg.Load(nodeType);
_ilg.Load(XmlNodeType.EndElement);
_ilg.BeginWhileBody(Cmp.NotEqualTo);
_ilg.Load(nodeType);
_ilg.Load(XmlNodeType.Element);
_ilg.If(Cmp.NotEqualTo);
ThrowUnexpectedStateException(XmlNodeType.Element);
_ilg.EndIf();
_ilg.Call(_contextArg, XmlFormatGeneratorStatics.IncrementItemCountMethod, 1);
if (keyParseMode == KeyParseMode.UsingParseEnum)
{
_ilg.Load(keyType);
}
_ilg.Load(_xmlReaderArg);
_ilg.Call(JsonFormatGeneratorStatics.GetJsonMemberNameMethod);
if (keyParseMode == KeyParseMode.UsingParseEnum)
{
_ilg.Call(JsonFormatGeneratorStatics.ParseEnumMethod);
_ilg.ConvertValue(Globals.TypeOfObject, keyType);
}
else if (keyParseMode == KeyParseMode.UsingCustomParse)
{
_ilg.Call(keyDataContract.ParseMethod);
}
LocalBuilder pairKey = _ilg.DeclareLocal(keyType, "key");
_ilg.Stloc(pairKey);
if (keyTypeNullableDepth > 0)
{
LocalBuilder pairKeyNullable = _ilg.DeclareLocal(keyTypeOriginal, "keyOriginal");
WrapNullableObject(pairKey, pairKeyNullable, keyTypeNullableDepth);
pairKey = pairKeyNullable;
}
LocalBuilder pairValue = ReadValue(valueType, String.Empty);
StoreKeyValuePair(_objectLocal, collectionContract, pairKey, pairValue);
_ilg.EndWhile();
}
}