Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
JsonFormatReaderGenerator.cs
Go to the documentation of this file.
6using System.Xml;
7
9
10internal sealed class JsonFormatReaderGenerator
11{
12 private sealed class CriticalHelper
13 {
14 private enum KeyParseMode
15 {
16 Fail,
20 }
21
23
25
27
29
31
33
35
37
38 [RequiresUnreferencedCode("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed. Make sure all of the required types are preserved.")]
39 public JsonFormatClassReaderDelegate GenerateClassReader(ClassDataContract classContract)
40 {
41 _ilg = new CodeGenerator();
42 bool flag = classContract.RequiresMemberAccessForRead(null);
43 try
44 {
45 BeginMethod(_ilg, "Read" + DataContract.SanitizeTypeName(classContract.StableName.Name) + "FromJson", typeof(JsonFormatClassReaderDelegate), flag);
46 }
48 {
49 if (!flag)
50 {
51 throw;
52 }
53 classContract.RequiresMemberAccessForRead(securityException);
54 }
55 InitArgs();
59 if (classContract.IsISerializable)
60 {
62 }
63 else
64 {
66 }
67 if (Globals.TypeOfIDeserializationCallback.IsAssignableFrom(classContract.UnderlyingType))
68 {
70 }
73 {
76 {
80 }
81 else if (classContract.UnderlyingType == Globals.TypeOfMemoryStreamAdapter)
82 {
86 }
87 else if (classContract.IsKeyValuePairAdapter)
88 {
89 _ilg.Call(classContract.GetKeyValuePairMethodInfo);
90 _ilg.ConvertValue(Globals.TypeOfKeyValuePair.MakeGenericType(classContract.KeyValuePairGenericArguments), _ilg.CurrentMethod.ReturnType);
91 }
92 else
93 {
95 }
96 }
97 return (JsonFormatClassReaderDelegate)_ilg.EndMethod();
98 }
99
100 [RequiresUnreferencedCode("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed. Make sure all of the required types are preserved.")]
109
110 [RequiresUnreferencedCode("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed. Make sure all of the required types are preserved.")]
111 public JsonFormatGetOnlyCollectionReaderDelegate GenerateGetOnlyCollectionReader(CollectionDataContract collectionContract)
112 {
115 return (JsonFormatGetOnlyCollectionReaderDelegate)_ilg.EndMethod();
116 }
117
119 {
120 _ilg = new CodeGenerator();
121 bool flag = collectionContract.RequiresMemberAccessForRead(null);
122 try
123 {
125 {
126 BeginMethod(_ilg, "Read" + DataContract.SanitizeTypeName(collectionContract.StableName.Name) + "FromJsonIsGetOnly", typeof(JsonFormatGetOnlyCollectionReaderDelegate), flag);
127 }
128 else
129 {
130 BeginMethod(_ilg, "Read" + DataContract.SanitizeTypeName(collectionContract.StableName.Name) + "FromJson", typeof(JsonFormatCollectionReaderDelegate), flag);
131 }
132 }
134 {
135 if (!flag)
136 {
137 throw;
138 }
139 collectionContract.RequiresMemberAccessForRead(securityException);
140 }
141 InitArgs();
143 return _ilg;
144 }
145
147 {
149 ParameterInfo[] parameters = invokeMethod.GetParameters();
150 Type[] array = new Type[parameters.Length];
151 for (int i = 0; i < parameters.Length; i++)
152 {
153 array[i] = parameters[i].ParameterType;
154 }
157 }
158
159 private void InitArgs()
160 {
165 }
166
167 [RequiresUnreferencedCode("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed. Make sure all of the required types are preserved.")]
169 {
170 _objectType = classContract.UnderlyingType;
171 Type objectType = classContract.ObjectType;
172 _objectLocal = _ilg.DeclareLocal(objectType, "objectDeserialized");
173 if (classContract.UnderlyingType == Globals.TypeOfDBNull)
174 {
175 _ilg.LoadMember(Globals.TypeOfDBNull.GetField("Value"));
177 }
178 else if (classContract.IsNonAttributedType)
179 {
180 if (objectType.IsValueType)
181 {
184 }
185 else
186 {
187 _ilg.New(classContract.GetNonAttributedTypeConstructor());
189 }
190 }
191 else
192 {
196 }
197 }
198
200 {
201 if (classContract.BaseContract != null)
202 {
204 }
205 if (classContract.OnDeserializing != null)
206 {
211 _ilg.Call(classContract.OnDeserializing);
212 }
213 }
214
216 {
217 if (classContract.BaseContract != null)
218 {
220 }
221 if (classContract.OnDeserialized != null)
222 {
227 _ilg.Call(classContract.OnDeserialized);
228 }
229 }
230
232 {
233 return Globals.TypeOfIObjectReference.IsAssignableFrom(classContract.UnderlyingType);
234 }
235
250
251 [RequiresUnreferencedCode("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed. Make sure all of the required types are preserved.")]
274
275 [RequiresUnreferencedCode("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed. Make sure all of the required types are preserved.")]
277 {
278 int num = classContract.MemberNames.Length;
280 BitFlagsGenerator bitFlagsGenerator = new BitFlagsGenerator(num, _ilg, classContract.UnderlyingType.Name + "_ExpectedElements");
281 byte[] array = new byte[bitFlagsGenerator.GetLocalCount()];
287 object forState = _ilg.For(null, null, null);
291 if (num > 0)
292 {
293 Label[] memberLabels = _ilg.Switch(num);
295 _ilg.EndSwitch();
296 }
297 else
298 {
299 _ilg.Pop();
300 }
301 _ilg.EndFor();
304 _ilg.Br(label3);
311 bitFlagsGenerator.LoadArray();
312 LoadArray(array, "requiredElements");
315 }
316
317 [RequiresUnreferencedCode("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed. Make sure all of the required types are preserved.")]
319 {
321 int num2 = 0;
322 while (num2 < classContract.Members.Count)
323 {
325 Type memberType = dataMember.MemberType;
326 _ilg.Case(memberLabels[num], dataMember.Name);
328 expectedElements.Load(num);
331 if (dataMember.IsGetOnlyCollection)
332 {
334 _ilg.LoadMember(dataMember.MemberInfo);
339 }
340 else
341 {
347 _ilg.StoreMember(dataMember.MemberInfo);
348 }
350 _ilg.EndCase();
351 num2++;
352 num++;
353 }
354 return num;
355 }
356
358 {
359 for (int i = 0; i < requiredElements.Length; i++)
360 {
361 _ilg.Load(expectedElements.GetLocal(i));
363 _ilg.And();
364 _ilg.Load(0);
365 _ilg.Ceq();
367 }
368 }
369
370 private void LoadArray(byte[] array, string name)
371 {
373 _ilg.NewArray(typeof(byte), array.Length);
375 for (int i = 0; i < array.Length; i++)
376 {
378 }
380 }
381
383 {
384 int num = ((contract.BaseContract != null) ? SetRequiredElements(contract.BaseContract, requiredElements) : 0);
386 int num2 = 0;
387 while (num2 < members.Count)
388 {
389 if (members[num2].IsRequired)
390 {
392 }
393 num2++;
394 num++;
395 }
396 return num;
397 }
398
400 {
401 int bitCount = expectedElements.GetBitCount();
402 for (int i = startIndex; i < bitCount; i++)
403 {
404 expectedElements.Store(i, value: true);
405 }
406 }
407
412
413 [RequiresUnreferencedCode("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed. Make sure all of the required types are preserved.")]
428
429 [RequiresUnreferencedCode("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed. Make sure all of the required types are preserved.")]
430 private LocalBuilder ReadValue(Type type, string name)
431 {
434 int num = 0;
435 while (type.IsGenericType && type.GetGenericTypeDefinition() == Globals.TypeOfNullable)
436 {
437 num++;
438 type = type.GetGenericArguments()[0];
439 }
441 if ((primitiveDataContract != null && primitiveDataContract.UnderlyingType != Globals.TypeOfObject) || num != 0 || type.IsValueType)
442 {
447 _ilg.If(localBuilder3, Cmp.EqualTo, null);
448 if (num != 0)
449 {
451 _ilg.InitObj(localBuilder.LocalType);
452 }
453 else if (type.IsValueType)
454 {
456 }
457 else
458 {
459 _ilg.Load(null);
461 }
465 if (type.IsValueType)
466 {
469 _ilg.EndIf();
470 }
471 if (num != 0)
472 {
474 localBuilder = _ilg.DeclareLocal(type, "innerValueRead");
475 }
476 if (primitiveDataContract != null && primitiveDataContract.UnderlyingType != Globals.TypeOfObject)
477 {
478 _ilg.Call(_xmlReaderArg, primitiveDataContract.XmlFormatReaderMethod);
480 if (!type.IsValueType)
481 {
483 }
484 }
485 else
486 {
488 }
489 _ilg.Else();
490 if (type.IsValueType)
491 {
493 }
494 else
495 {
499 }
500 _ilg.EndIf();
501 if (localBuilder2 != null)
502 {
503 _ilg.If(localBuilder3, Cmp.NotEqualTo, null);
505 _ilg.EndIf();
507 }
508 }
509 else
510 {
512 }
513 return localBuilder;
514 }
515
516 [RequiresUnreferencedCode("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed. Make sure all of the required types are preserved.")]
517 private void InternalDeserialize(LocalBuilder value, Type type, string name)
518 {
521 _ilg.Load(DataContract.GetId(type.TypeHandle));
523 _ilg.Load(name);
524 _ilg.Load(string.Empty);
526 if (type.IsPointer)
527 {
529 }
530 else
531 {
533 }
535 }
536
537 [RequiresUnreferencedCode("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed. Make sure all of the required types are preserved.")]
539 {
540 Type type = innerValue.LocalType;
541 Type localType = outerValue.LocalType;
544 for (int i = 1; i < nullables; i++)
545 {
546 Type type2 = Globals.TypeOfNullable.MakeGenericType(type);
547 _ilg.New(type2.GetConstructor(new Type[1] { type }));
548 type = type2;
549 }
550 _ilg.Call(localType.GetConstructor(new Type[1] { type }));
551 }
552
553 [RequiresUnreferencedCode("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed. Make sure all of the required types are preserved.")]
555 {
556 Type type = collectionContract.UnderlyingType;
558 bool flag = collectionContract.Kind == CollectionKind.Array;
560 if (type.IsInterface)
561 {
562 switch (collectionContract.Kind)
563 {
564 case CollectionKind.GenericDictionary:
565 type = Globals.TypeOfDictionaryGeneric.MakeGenericType(itemType2.GetGenericArguments());
566 constructor = type.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, Type.EmptyTypes);
567 break;
570 constructor = type.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, Type.EmptyTypes);
571 break;
572 case CollectionKind.GenericList:
573 case CollectionKind.GenericCollection:
574 case CollectionKind.List:
575 case CollectionKind.GenericEnumerable:
576 case CollectionKind.Collection:
577 case CollectionKind.Enumerable:
578 type = itemType2.MakeArrayType();
579 flag = true;
580 break;
581 }
582 }
583 _objectLocal = _ilg.DeclareLocal(type, "objectDeserialized");
584 if (!flag)
585 {
586 if (type.IsValueType)
587 {
590 }
591 else
592 {
596 }
597 }
599 if (flag2)
600 {
603 _ilg.If();
605 _ilg.Else();
606 }
610 bool flag3 = false;
611 if (flag && TryReadPrimitiveArray(itemType2))
612 {
613 flag3 = true;
614 _ilg.IfNot();
615 }
617 if (flag)
618 {
619 localBuilder2 = _ilg.DeclareLocal(type, "growingCollection");
622 }
624 object forState = _ilg.For(localBuilder3, 0, int.MaxValue);
626 _ilg.If();
629 if (flag)
630 {
635 }
636 else
637 {
639 }
640 _ilg.Else();
641 IsEndElement();
642 _ilg.If();
644 _ilg.Else();
646 _ilg.EndIf();
647 _ilg.EndIf();
648 _ilg.EndFor();
649 if (flag)
650 {
655 }
656 if (flag3)
657 {
658 _ilg.Else();
660 _ilg.EndIf();
661 }
662 if (flag2)
663 {
664 _ilg.EndIf();
665 }
666 [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2060:MakeGenericMethod", Justification = "The call to MakeGenericMethod is safe due to the fact that EnsureArraySizeMethod and TrimArraySizeMethod are not annotated.")]
667 static MethodInfo MakeGenericMethod(MethodInfo method, Type itemType)
668 {
669 return method.MakeGenericMethod(itemType);
670 }
671 }
672
673 [RequiresUnreferencedCode("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed. Make sure all of the required types are preserved.")]
675 {
676 Type[] genericArguments = keyValueType.GetGenericArguments();
679 int num = 0;
680 Type type3 = type;
681 while (type.IsGenericType && type.GetGenericTypeDefinition() == Globals.TypeOfNullable)
682 {
683 num++;
684 type = type.GetGenericArguments()[0];
685 }
687 DataContract memberTypeContract = classDataContract.Members[0].MemberTypeContract;
690 {
691 keyParseMode = KeyParseMode.AsString;
692 }
693 else if (type.IsEnum)
694 {
695 keyParseMode = KeyParseMode.UsingParseEnum;
696 }
697 else if (memberTypeContract.ParseMethod != null)
698 {
699 keyParseMode = KeyParseMode.UsingCustomParse;
700 }
701 if (keyParseMode == KeyParseMode.Fail)
702 {
704 return;
705 }
711 _ilg.Load(XmlNodeType.EndElement);
712 _ilg.BeginWhileBody(Cmp.NotEqualTo);
714 _ilg.Load(XmlNodeType.Element);
715 _ilg.If(Cmp.NotEqualTo);
717 _ilg.EndIf();
719 if (keyParseMode == KeyParseMode.UsingParseEnum)
720 {
721 _ilg.Load(type);
722 }
725 switch (keyParseMode)
726 {
727 case KeyParseMode.UsingParseEnum:
730 break;
731 case KeyParseMode.UsingCustomParse:
732 _ilg.Call(memberTypeContract.ParseMethod);
733 break;
734 }
737 if (num > 0)
738 {
742 }
745 _ilg.EndWhile();
746 }
747
748 [RequiresUnreferencedCode("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed. Make sure all of the required types are preserved.")]
750 {
751 Type underlyingType = collectionContract.UnderlyingType;
753 bool flag = collectionContract.Kind == CollectionKind.Array;
755 _objectLocal = _ilg.DeclareLocal(underlyingType, "objectDeserialized");
761 if (flag2)
762 {
765 _ilg.If();
766 if (!underlyingType.IsValueType)
767 {
768 _ilg.If(_objectLocal, Cmp.EqualTo, null);
770 _ilg.EndIf();
771 }
774 _ilg.Else();
775 }
777 _ilg.If();
778 if (!underlyingType.IsValueType)
779 {
780 _ilg.If(_objectLocal, Cmp.EqualTo, null);
782 _ilg.EndIf();
783 }
784 if (flag)
785 {
789 }
791 object forState = _ilg.For(localBuilder2, 0, int.MaxValue);
793 _ilg.If();
796 if (flag)
797 {
800 _ilg.Else();
802 _ilg.EndIf();
803 }
804 else
805 {
807 }
808 _ilg.Else();
809 IsEndElement();
810 _ilg.If();
812 _ilg.Else();
814 _ilg.EndIf();
815 _ilg.EndIf();
816 _ilg.EndFor();
818 _ilg.EndIf();
819 if (flag2)
820 {
821 _ilg.EndIf();
822 }
823 }
824
825 [RequiresUnreferencedCode("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed. Make sure all of the required types are preserved.")]
827 {
829 if (primitiveDataContract == null)
830 {
831 return false;
832 }
833 string text = null;
834 switch (itemType.GetTypeCode())
835 {
836 case TypeCode.Boolean:
837 text = "TryReadBooleanArray";
838 break;
839 case TypeCode.Decimal:
840 text = "TryReadDecimalArray";
841 break;
842 case TypeCode.Int32:
843 text = "TryReadInt32Array";
844 break;
845 case TypeCode.Int64:
846 text = "TryReadInt64Array";
847 break;
848 case TypeCode.Single:
849 text = "TryReadSingleArray";
850 break;
851 case TypeCode.Double:
852 text = "TryReadDoubleArray";
853 break;
854 case TypeCode.DateTime:
855 text = "TryReadJsonDateTimeArray";
856 break;
857 }
858 if (text != null)
859 {
865 _ilg.Load(-1);
867 _ilg.Call(typeof(JsonReaderDelegator).GetMethod(text, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic));
868 return true;
869 }
870 return false;
871 }
872
873 [RequiresUnreferencedCode("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed. Make sure all of the required types are preserved.")]
892
893 [RequiresUnreferencedCode("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed. Make sure all of the required types are preserved.")]
920
929
940
945
950
958
964
965 private void ThrowSerializationException(string msg, params object[] values)
966 {
967 if (values != null && values.Length != 0)
968 {
970 }
971 else
972 {
973 _ilg.Load(msg);
974 }
976 }
977
983 }
984
985 private readonly CriticalHelper _helper;
986
988 {
989 _helper = new CriticalHelper();
990 }
991
992 [RequiresUnreferencedCode("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed. Make sure all of the required types are preserved.")]
993 public JsonFormatClassReaderDelegate GenerateClassReader(ClassDataContract classContract)
994 {
996 }
997
998 [RequiresUnreferencedCode("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed. Make sure all of the required types are preserved.")]
999 public JsonFormatCollectionReaderDelegate GenerateCollectionReader(CollectionDataContract collectionContract)
1000 {
1002 }
1003
1004 [RequiresUnreferencedCode("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed. Make sure all of the required types are preserved.")]
1009}
static void SetBit(byte[] bytes, int bitIndex)
void Ldloca(LocalBuilder localBuilder)
void Ldloc(LocalBuilder localBuilder)
void NewArray(Type elementType, object len)
void Call(object thisObj, MethodInfo methodInfo)
void IfNotIsEmptyString(LocalBuilder strLocal)
void BeginMethod(DynamicMethod dynamicMethod, Type delegateType, string methodName, Type[] argTypes, bool allowPrivateMemberAccess)
void ElseIfIsEmptyString(LocalBuilder strLocal)
Type LoadMember(MemberInfo memberInfo)
void CallStringFormat(string msg, params object[] values)
void StoreMember(MemberInfo memberInfo)
void Case(Label caseLabel1, string caseLabelName)
void Set(LocalBuilder local, object value)
object For(LocalBuilder local, object start, object end)
LocalBuilder DeclareLocal(Type type, string name, object initialValue)
void StoreArrayElement(object obj, object arrayIndex, object value)
void ConvertAddress(Type source, Type target)
void ConvertValue(Type source, Type target)
void New(ConstructorInfo constructorInfo)
static int GetId(RuntimeTypeHandle typeHandle)
static string SanitizeTypeName(string typeName)
static string GetClrTypeFullName(Type type)
static DataContract GetDataContract(Type type)
static readonly string NewObjectId
Definition Globals.cs:172
LocalBuilder ReadCollectionItem(CollectionDataContract collectionContract, Type itemType)
void StoreKeyValuePair(LocalBuilder collection, CollectionDataContract collectionContract, LocalBuilder pairKey, LocalBuilder pairValue)
JsonFormatCollectionReaderDelegate GenerateCollectionReader(CollectionDataContract collectionContract)
int SetRequiredElements(ClassDataContract contract, byte[] requiredElements)
void CheckRequiredElements(BitFlagsGenerator expectedElements, byte[] requiredElements, Label throwMissingRequiredMembersLabel)
void ReadSimpleDictionary(CollectionDataContract collectionContract, Type keyValueType)
void SetExpectedElements(BitFlagsGenerator expectedElements, int startIndex)
void StoreCollectionValue(LocalBuilder collection, LocalBuilder value, CollectionDataContract collectionContract)
void BeginMethod(CodeGenerator ilg, string methodName, Type delegateType, bool allowPrivateMemberAccess)
CodeGenerator GenerateCollectionReaderHelper(CollectionDataContract collectionContract, bool isGetOnlyCollection)
void ReadMembers(ClassDataContract classContract, LocalBuilder extensionDataLocal)
int ReadMembers(ClassDataContract classContract, BitFlagsGenerator expectedElements, Label[] memberLabels, Label throwDuplicateMemberLabel, LocalBuilder memberIndexLocal)
void WrapNullableObject(LocalBuilder innerValue, LocalBuilder outerValue, int nullables)
JsonFormatClassReaderDelegate GenerateClassReader(ClassDataContract classContract)
JsonFormatGetOnlyCollectionReaderDelegate GenerateGetOnlyCollectionReader(CollectionDataContract collectionContract)
JsonFormatGetOnlyCollectionReaderDelegate GenerateGetOnlyCollectionReader(CollectionDataContract collectionContract)
JsonFormatClassReaderDelegate GenerateClassReader(ClassDataContract classContract)
JsonFormatCollectionReaderDelegate GenerateCollectionReader(CollectionDataContract collectionContract)
static PrimitiveDataContract GetPrimitiveDataContract(Type type)
static SerializationException CreateSerializationException(string errorMessage)
static string ValueTypeCannotHaveId
Definition SR.cs:302
static string Format(string resourceFormat, object p1)
Definition SR.cs:118
static string ValueTypeCannotHaveRef
Definition SR.cs:306
static string SerializationInfo_ConstructorNotFound
Definition SR.cs:662
static string ValueTypeCannotBeNull
Definition SR.cs:298
static string KeyTypeCannotBeParsedInSimpleDictionary
Definition SR.cs:630
Definition SR.cs:7
static readonly Type[] EmptyTypes
Definition Type.cs:19
TypeCode
Definition TypeCode.cs:4