Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
MemberSerializerGenerated.cs
Go to the documentation of this file.
1 // Copyright (c) 2014 Silicon Studio Corp. (http://siliconstudio.co.jp)
2 // This file is distributed under GPL v3. See LICENSE.md for details.
3 using System;
4 using System.Reflection;
5 using SiliconStudio.Core.Storage;
6 
7 namespace SiliconStudio.Core.Serialization
8 {
9  public unsafe static class MemberNullableSerializer
10  {
11  public static void SerializeExtended(SerializationStream stream, Type objType, ref object obj, ArchiveMode mode, DataSerializer dataSerializer = null)
12  {
13  var context = stream.Context;
14 
15  if (objType.GetTypeInfo().IsValueType)
16  {
17  if (dataSerializer == null)
18  {
19  dataSerializer = context.SerializerSelector.GetSerializer(objType);
20 
21  // If we still have no serializer, throw an exception
22  if (dataSerializer == null)
23  throw new ArgumentException("No serializer available for type " + objType.FullName);
24  }
25 
26  // Structure, no need to check for inheritance or null values.
27  dataSerializer.Serialize(ref obj, mode, stream);
28 
29  return;
30  }
31 
32 
33 
34  if (mode == ArchiveMode.Serialize)
35  {
36  if (object.ReferenceEquals(obj, null))
37  {
38  // Null contentRef
39  stream.Write((byte)SerializeClassFlags.IsNull);
40  }
41  else
42  {
43 
44 
45  // Serialize flags
46  stream.Write((byte)SerializeClassFlags.None);
47 
48  {
49  if (dataSerializer == null)
50  {
51  dataSerializer = context.SerializerSelector.GetSerializer(objType);
52 
53  // If we still have no serializer, throw an exception
54  if (dataSerializer == null)
55  throw new ArgumentException("No serializer available for type " + objType.FullName);
56  }
57 
58  // Serialize object
59  dataSerializer.PreSerialize(ref obj, mode, stream);
60  dataSerializer.Serialize(ref obj, mode, stream);
61  }
62  }
63  }
64  else
65  {
66 
67  bool isNull = ((SerializeClassFlags)stream.ReadByte() & SerializeClassFlags.IsNull) == SerializeClassFlags.IsNull;
68 
69  if (isNull)
70  {
71  obj = null;
72  }
73  else
74  {
75  {
76  if (dataSerializer == null)
77  {
78  dataSerializer = context.SerializerSelector.GetSerializer(objType);
79 
80  // If we still have no serializer, throw an exception
81  if (dataSerializer == null)
82  throw new ArgumentException("No serializer available for type " + objType.FullName);
83  }
84 
85  // Serialize object
86  dataSerializer.PreSerialize(ref obj, mode, stream);
87 
88 
89  dataSerializer.Serialize(ref obj, mode, stream);
90  }
91 
92  }
93  }
94  }
95  }
96 
97  public unsafe class MemberNullableSerializer<T> : MemberSerializer<T>
98  {
99  public MemberNullableSerializer(DataSerializer<T> dataSerializer) : base(dataSerializer)
100  {
101  }
102 
103  public override void Serialize(ref T obj, ArchiveMode mode, SerializationStream stream)
104  {
105 
106 
107 
108  if (mode == ArchiveMode.Serialize)
109  {
110  if (object.ReferenceEquals(obj, null))
111  {
112  // Null contentRef
113  stream.Write((byte)SerializeClassFlags.IsNull);
114  }
115  else
116  {
117 
118 
119  // Serialize flags
120  stream.Write((byte)SerializeClassFlags.None);
121 
122  {
123  // Serialize object
124  dataSerializer.PreSerialize(ref obj, mode, stream);
125  dataSerializer.Serialize(ref obj, mode, stream);
126  }
127  }
128  }
129  else
130  {
131 
132  bool isNull = ((SerializeClassFlags)stream.ReadByte() & SerializeClassFlags.IsNull) == SerializeClassFlags.IsNull;
133 
134  if (isNull)
135  {
136  obj = default(T);
137  }
138  else
139  {
140  {
141  // Serialize object
142  dataSerializer.PreSerialize(ref obj, mode, stream);
143 
144 
145  dataSerializer.Serialize(ref obj, mode, stream);
146  }
147 
148  }
149  }
150  }
151 
152  internal static void SerializeExtended(ref T obj, ArchiveMode mode, SerializationStream stream, DataSerializer<T> dataSerializer = null)
153  {
154  var context = stream.Context;
155 
156  if (isValueType)
157  {
158  if (dataSerializer == null)
159  {
160  dataSerializer = (DataSerializer<T>)context.SerializerSelector.GetSerializer(typeof(T));
161 
162  // If we still have no serializer, throw an exception
163  if (dataSerializer == null)
164  throw new ArgumentException("No serializer available for type " + typeof(T).FullName);
165  }
166 
167  // Structure, no need to check for inheritance or null values.
168  dataSerializer.Serialize(ref obj, mode, stream);
169 
170  return;
171  }
172 
173 
174 
175  if (mode == ArchiveMode.Serialize)
176  {
177  if (object.ReferenceEquals(obj, null))
178  {
179  // Null contentRef
180  stream.Write((byte)SerializeClassFlags.IsNull);
181  }
182  else
183  {
184 
185 
186  // Serialize flags
187  stream.Write((byte)SerializeClassFlags.None);
188 
189  {
190  if (dataSerializer == null)
191  {
192  dataSerializer = (DataSerializer<T>)context.SerializerSelector.GetSerializer(typeof(T));
193 
194  // If we still have no serializer, throw an exception
195  if (dataSerializer == null)
196  throw new ArgumentException("No serializer available for type " + typeof(T).FullName);
197  }
198 
199  // Serialize object
200  dataSerializer.PreSerialize(ref obj, mode, stream);
201  dataSerializer.Serialize(ref obj, mode, stream);
202  }
203  }
204  }
205  else
206  {
207 
208  bool isNull = ((SerializeClassFlags)stream.ReadByte() & SerializeClassFlags.IsNull) == SerializeClassFlags.IsNull;
209 
210  if (isNull)
211  {
212  obj = default(T);
213  }
214  else
215  {
216  {
217  if (dataSerializer == null)
218  {
219  dataSerializer = (DataSerializer<T>)context.SerializerSelector.GetSerializer(typeof(T));
220 
221  // If we still have no serializer, throw an exception
222  if (dataSerializer == null)
223  throw new ArgumentException("No serializer available for type " + typeof(T).FullName);
224  }
225 
226  // Serialize object
227  dataSerializer.PreSerialize(ref obj, mode, stream);
228 
229 
230  dataSerializer.Serialize(ref obj, mode, stream);
231  }
232 
233  }
234  }
235  }
236  }
237 
238  public unsafe class MemberNullableSerializerObject<T> : MemberSerializer<T>
239  {
240  public MemberNullableSerializerObject(DataSerializer<T> dataSerializer) : base(dataSerializer)
241  {
242  }
243 
244  public override void Serialize(ref T obj, ArchiveMode mode, SerializationStream stream)
245  {
246 
247  if (isValueType)
248  {
249 
250  // Structure, no need to check for inheritance or null values.
251  dataSerializer.Serialize(ref obj, mode, stream);
252 
253  return;
254  }
255 
256 
257 
258  if (mode == ArchiveMode.Serialize)
259  {
260  if (object.ReferenceEquals(obj, null))
261  {
262  // Null contentRef
263  stream.Write((byte)SerializeClassFlags.IsNull);
264  }
265  else
266  {
267 
268 
269  // Serialize flags
270  stream.Write((byte)SerializeClassFlags.None);
271 
272  {
273  // Serialize object
274  dataSerializer.PreSerialize(ref obj, mode, stream);
275  dataSerializer.Serialize(ref obj, mode, stream);
276  }
277  }
278  }
279  else
280  {
281 
282  bool isNull = ((SerializeClassFlags)stream.ReadByte() & SerializeClassFlags.IsNull) == SerializeClassFlags.IsNull;
283 
284  if (isNull)
285  {
286  obj = default(T);
287  }
288  else
289  {
290  {
291  // Serialize object
292  dataSerializer.PreSerialize(ref obj, mode, stream);
293 
294 
295  dataSerializer.Serialize(ref obj, mode, stream);
296  }
297 
298  }
299  }
300  }
301  }
302 
303  public unsafe static class MemberNonSealedSerializer
304  {
305  public static void SerializeExtended(SerializationStream stream, Type objType, ref object obj, ArchiveMode mode, DataSerializer dataSerializer = null)
306  {
307  var context = stream.Context;
308 
309  if (objType.GetTypeInfo().IsValueType)
310  {
311  if (dataSerializer == null)
312  {
313  dataSerializer = context.SerializerSelector.GetSerializer(objType);
314 
315  // If we still have no serializer, throw an exception
316  if (dataSerializer == null)
317  throw new ArgumentException("No serializer available for type " + objType.FullName);
318  }
319 
320  // Structure, no need to check for inheritance or null values.
321  dataSerializer.Serialize(ref obj, mode, stream);
322 
323  return;
324  }
325 
326 
327  // Serialize either with dataSerializer if obj is really of type T, otherwise look for appropriate serializer.
329  bool hasTypeInfo;
330  DataSerializer objectDataSerializer;
331  Type type;
332 
333  if (mode == ArchiveMode.Serialize)
334  {
335  if (object.ReferenceEquals(obj, null))
336  {
337  // Null contentRef
338  stream.Write((byte)SerializeClassFlags.IsNull);
339  }
340  else
341  {
342  flags = SerializeClassFlags.None;
343 
344  // If real type is not expected type, we need to store type info as well.
345  var expectedType = objType;
346  type = objType.GetTypeInfo().IsSealed ? expectedType : obj.GetType();
347  hasTypeInfo = type != expectedType;
348  objectDataSerializer = null;
349  if (hasTypeInfo)
350  {
351  // Find matching serializer (always required w/ typeinfo, since type was different than expected)
352  objectDataSerializer = context.SerializerSelector.GetSerializer(type);
353 
354  if (objectDataSerializer == null)
355  throw new ArgumentException("No serializer available for type " + type.FullName);
356 
357  // Update expected type
358  type = objectDataSerializer.SerializationType;
359 
360  // Special case: serializer reports the actual serialized type, and it might actually match the expected type
361  // (i.e. there is a hidden inherited type, such as PropertyInfo/RuntimePropertyInfo).
362  // Let's detect it here.
363  if (type == expectedType)
364  {
365  // Cancel type info
366  hasTypeInfo = false;
367  }
368  else
369  {
370  // Continue as expected with type info
371  flags |= SerializeClassFlags.IsTypeInfo;
372  }
373  }
374 
375  // Serialize flags
376  stream.Write((byte)flags);
377 
378  if (hasTypeInfo)
379  {
380  // Serialize type info
381  fixed (ObjectId* serializationTypeId = &objectDataSerializer.SerializationTypeId)
382  stream.Serialize((IntPtr)serializationTypeId, ObjectId.HashSize);
383 
384  // Serialize object
385  objectDataSerializer.PreSerialize(ref obj, mode, stream);
386  objectDataSerializer.Serialize(ref obj, mode, stream);
387  }
388  else
389  {
390  if (dataSerializer == null)
391  {
392  dataSerializer = context.SerializerSelector.GetSerializer(expectedType);
393 
394  // If we still have no serializer, throw an exception
395  if (dataSerializer == null)
396  throw new ArgumentException("No serializer available for type " + expectedType.FullName);
397  }
398 
399  // Serialize object
400  dataSerializer.PreSerialize(ref obj, mode, stream);
401  dataSerializer.Serialize(ref obj, mode, stream);
402  }
403  }
404  }
405  else
406  {
407 
408  flags = (SerializeClassFlags)stream.ReadByte();
409  bool isNull = (flags & SerializeClassFlags.IsNull) == SerializeClassFlags.IsNull;
410  hasTypeInfo = (flags & SerializeClassFlags.IsTypeInfo) == SerializeClassFlags.IsTypeInfo;
411 
412  if (isNull)
413  {
414  obj = null;
415  }
416  else
417  {
418  if (hasTypeInfo)
419  {
420  ObjectId serializationTypeId;
421  stream.Serialize((IntPtr)Interop.FixedOut(out serializationTypeId), ObjectId.HashSize);
422 
423  objectDataSerializer = context.SerializerSelector.GetSerializer(ref serializationTypeId);
424  if (objectDataSerializer == null)
425  throw new ArgumentException("No serializer available for type id " + serializationTypeId + " and base type " + objType.FullName);
426 
427  objectDataSerializer.PreSerialize(ref obj, mode, stream);
428 
429 
430  objectDataSerializer.Serialize(ref obj, mode, stream);
431  }
432  else
433  {
434  if (dataSerializer == null)
435  {
436  dataSerializer = context.SerializerSelector.GetSerializer(objType);
437 
438  // If we still have no serializer, throw an exception
439  if (dataSerializer == null)
440  throw new ArgumentException("No serializer available for type " + objType.FullName);
441  }
442 
443  // Serialize object
444  dataSerializer.PreSerialize(ref obj, mode, stream);
445 
446 
447  dataSerializer.Serialize(ref obj, mode, stream);
448  }
449 
450  }
451  }
452  }
453  }
454 
455  public unsafe class MemberNonSealedSerializer<T> : MemberSerializer<T>
456  {
457  public MemberNonSealedSerializer(DataSerializer<T> dataSerializer) : base(dataSerializer)
458  {
459  }
460 
461  public override void Serialize(ref T obj, ArchiveMode mode, SerializationStream stream)
462  {
463  var context = stream.Context;
464 
465 
466  // Serialize either with dataSerializer if obj is really of type T, otherwise look for appropriate serializer.
468  bool hasTypeInfo;
469  object objCopy;
470  DataSerializer objectDataSerializer;
471  Type type;
472 
473  if (mode == ArchiveMode.Serialize)
474  {
475  if (object.ReferenceEquals(obj, null))
476  {
477  // Null contentRef
478  stream.Write((byte)SerializeClassFlags.IsNull);
479  }
480  else
481  {
482  flags = SerializeClassFlags.None;
483 
484  // If real type is not expected type, we need to store type info as well.
485  var expectedType = typeof(T);
486  type = isSealed ? expectedType : obj.GetType();
487  hasTypeInfo = type != expectedType;
488  objectDataSerializer = null;
489  if (hasTypeInfo)
490  {
491  // Find matching serializer (always required w/ typeinfo, since type was different than expected)
492  objectDataSerializer = context.SerializerSelector.GetSerializer(type);
493 
494  if (objectDataSerializer == null)
495  throw new ArgumentException("No serializer available for type " + type.FullName);
496 
497  // Update expected type
498  type = objectDataSerializer.SerializationType;
499 
500  // Special case: serializer reports the actual serialized type, and it might actually match the expected type
501  // (i.e. there is a hidden inherited type, such as PropertyInfo/RuntimePropertyInfo).
502  // Let's detect it here.
503  if (type == expectedType)
504  {
505  // Cancel type info
506  hasTypeInfo = false;
507  }
508  else
509  {
510  // Continue as expected with type info
511  flags |= SerializeClassFlags.IsTypeInfo;
512  }
513  }
514 
515  // Serialize flags
516  stream.Write((byte)flags);
517 
518  if (hasTypeInfo)
519  {
520  // Serialize type info
521  fixed (ObjectId* serializationTypeId = &objectDataSerializer.SerializationTypeId)
522  stream.Serialize((IntPtr)serializationTypeId, ObjectId.HashSize);
523 
524  // Serialize object
525  objCopy = obj;
526  objectDataSerializer.PreSerialize(ref objCopy, mode, stream);
527  objectDataSerializer.Serialize(ref objCopy, mode, stream);
528  obj = (T)objCopy;
529  }
530  else
531  {
532  // Serialize object
533  dataSerializer.PreSerialize(ref obj, mode, stream);
534  dataSerializer.Serialize(ref obj, mode, stream);
535  }
536  }
537  }
538  else
539  {
540 
541  flags = (SerializeClassFlags)stream.ReadByte();
542  bool isNull = (flags & SerializeClassFlags.IsNull) == SerializeClassFlags.IsNull;
543  hasTypeInfo = (flags & SerializeClassFlags.IsTypeInfo) == SerializeClassFlags.IsTypeInfo;
544 
545  if (isNull)
546  {
547  obj = default(T);
548  }
549  else
550  {
551  if (hasTypeInfo)
552  {
553  ObjectId serializationTypeId;
554  stream.Serialize((IntPtr)Interop.FixedOut(out serializationTypeId), ObjectId.HashSize);
555 
556  objectDataSerializer = context.SerializerSelector.GetSerializer(ref serializationTypeId);
557  if (objectDataSerializer == null)
558  throw new ArgumentException("No serializer available for type id " + serializationTypeId + " and base type " + typeof(T).FullName);
559 
560  objCopy = obj;
561  objectDataSerializer.PreSerialize(ref objCopy, mode, stream);
562 
563 
564  objectDataSerializer.Serialize(ref objCopy, mode, stream);
565  obj = (T)objCopy;
566  }
567  else
568  {
569  // Serialize object
570  dataSerializer.PreSerialize(ref obj, mode, stream);
571 
572 
573  dataSerializer.Serialize(ref obj, mode, stream);
574  }
575 
576  }
577  }
578  }
579 
580  internal static void SerializeExtended(ref T obj, ArchiveMode mode, SerializationStream stream, DataSerializer<T> dataSerializer = null)
581  {
582  var context = stream.Context;
583 
584  if (isValueType)
585  {
586  if (dataSerializer == null)
587  {
588  dataSerializer = (DataSerializer<T>)context.SerializerSelector.GetSerializer(typeof(T));
589 
590  // If we still have no serializer, throw an exception
591  if (dataSerializer == null)
592  throw new ArgumentException("No serializer available for type " + typeof(T).FullName);
593  }
594 
595  // Structure, no need to check for inheritance or null values.
596  dataSerializer.Serialize(ref obj, mode, stream);
597 
598  return;
599  }
600 
601 
602  // Serialize either with dataSerializer if obj is really of type T, otherwise look for appropriate serializer.
604  bool hasTypeInfo;
605  object objCopy;
606  DataSerializer objectDataSerializer;
607  Type type;
608 
609  if (mode == ArchiveMode.Serialize)
610  {
611  if (object.ReferenceEquals(obj, null))
612  {
613  // Null contentRef
614  stream.Write((byte)SerializeClassFlags.IsNull);
615  }
616  else
617  {
618  flags = SerializeClassFlags.None;
619 
620  // If real type is not expected type, we need to store type info as well.
621  var expectedType = typeof(T);
622  type = isSealed ? expectedType : obj.GetType();
623  hasTypeInfo = type != expectedType;
624  objectDataSerializer = null;
625  if (hasTypeInfo)
626  {
627  // Find matching serializer (always required w/ typeinfo, since type was different than expected)
628  objectDataSerializer = context.SerializerSelector.GetSerializer(type);
629 
630  if (objectDataSerializer == null)
631  throw new ArgumentException("No serializer available for type " + type.FullName);
632 
633  // Update expected type
634  type = objectDataSerializer.SerializationType;
635 
636  // Special case: serializer reports the actual serialized type, and it might actually match the expected type
637  // (i.e. there is a hidden inherited type, such as PropertyInfo/RuntimePropertyInfo).
638  // Let's detect it here.
639  if (type == expectedType)
640  {
641  // Cancel type info
642  hasTypeInfo = false;
643  }
644  else
645  {
646  // Continue as expected with type info
647  flags |= SerializeClassFlags.IsTypeInfo;
648  }
649  }
650 
651  // Serialize flags
652  stream.Write((byte)flags);
653 
654  if (hasTypeInfo)
655  {
656  // Serialize type info
657  fixed (ObjectId* serializationTypeId = &objectDataSerializer.SerializationTypeId)
658  stream.Serialize((IntPtr)serializationTypeId, ObjectId.HashSize);
659 
660  // Serialize object
661  objCopy = obj;
662  objectDataSerializer.PreSerialize(ref objCopy, mode, stream);
663  objectDataSerializer.Serialize(ref objCopy, mode, stream);
664  obj = (T)objCopy;
665  }
666  else
667  {
668  if (dataSerializer == null)
669  {
670  dataSerializer = (DataSerializer<T>)context.SerializerSelector.GetSerializer(expectedType);
671 
672  // If we still have no serializer, throw an exception
673  if (dataSerializer == null)
674  throw new ArgumentException("No serializer available for type " + expectedType.FullName);
675  }
676 
677  // Serialize object
678  dataSerializer.PreSerialize(ref obj, mode, stream);
679  dataSerializer.Serialize(ref obj, mode, stream);
680  }
681  }
682  }
683  else
684  {
685 
686  flags = (SerializeClassFlags)stream.ReadByte();
687  bool isNull = (flags & SerializeClassFlags.IsNull) == SerializeClassFlags.IsNull;
688  hasTypeInfo = (flags & SerializeClassFlags.IsTypeInfo) == SerializeClassFlags.IsTypeInfo;
689 
690  if (isNull)
691  {
692  obj = default(T);
693  }
694  else
695  {
696  if (hasTypeInfo)
697  {
698  ObjectId serializationTypeId;
699  stream.Serialize((IntPtr)Interop.FixedOut(out serializationTypeId), ObjectId.HashSize);
700 
701  objectDataSerializer = context.SerializerSelector.GetSerializer(ref serializationTypeId);
702  if (objectDataSerializer == null)
703  throw new ArgumentException("No serializer available for type id " + serializationTypeId + " and base type " + typeof(T).FullName);
704 
705  objCopy = obj;
706  objectDataSerializer.PreSerialize(ref objCopy, mode, stream);
707 
708 
709  objectDataSerializer.Serialize(ref objCopy, mode, stream);
710  obj = (T)objCopy;
711  }
712  else
713  {
714  if (dataSerializer == null)
715  {
716  dataSerializer = (DataSerializer<T>)context.SerializerSelector.GetSerializer(typeof(T));
717 
718  // If we still have no serializer, throw an exception
719  if (dataSerializer == null)
720  throw new ArgumentException("No serializer available for type " + typeof(T).FullName);
721  }
722 
723  // Serialize object
724  dataSerializer.PreSerialize(ref obj, mode, stream);
725 
726 
727  dataSerializer.Serialize(ref obj, mode, stream);
728  }
729 
730  }
731  }
732  }
733  }
734 
735  public unsafe class MemberNonSealedSerializerObject<T> : MemberSerializer<T>
736  {
737  public MemberNonSealedSerializerObject(DataSerializer<T> dataSerializer) : base(dataSerializer)
738  {
739  }
740 
741  public override void Serialize(ref T obj, ArchiveMode mode, SerializationStream stream)
742  {
743  var context = stream.Context;
744 
745  if (isValueType)
746  {
747 
748  // Structure, no need to check for inheritance or null values.
749  dataSerializer.Serialize(ref obj, mode, stream);
750 
751  return;
752  }
753 
754 
755  // Serialize either with dataSerializer if obj is really of type T, otherwise look for appropriate serializer.
757  bool hasTypeInfo;
758  object objCopy;
759  DataSerializer objectDataSerializer;
760  Type type;
761 
762  if (mode == ArchiveMode.Serialize)
763  {
764  if (object.ReferenceEquals(obj, null))
765  {
766  // Null contentRef
767  stream.Write((byte)SerializeClassFlags.IsNull);
768  }
769  else
770  {
771  flags = SerializeClassFlags.None;
772 
773  // If real type is not expected type, we need to store type info as well.
774  var expectedType = typeof(T);
775  type = isSealed ? expectedType : obj.GetType();
776  hasTypeInfo = type != expectedType;
777  objectDataSerializer = null;
778  if (hasTypeInfo)
779  {
780  // Find matching serializer (always required w/ typeinfo, since type was different than expected)
781  objectDataSerializer = context.SerializerSelector.GetSerializer(type);
782 
783  if (objectDataSerializer == null)
784  throw new ArgumentException("No serializer available for type " + type.FullName);
785 
786  // Update expected type
787  type = objectDataSerializer.SerializationType;
788 
789  // Special case: serializer reports the actual serialized type, and it might actually match the expected type
790  // (i.e. there is a hidden inherited type, such as PropertyInfo/RuntimePropertyInfo).
791  // Let's detect it here.
792  if (type == expectedType)
793  {
794  // Cancel type info
795  hasTypeInfo = false;
796  }
797  else
798  {
799  // Continue as expected with type info
800  flags |= SerializeClassFlags.IsTypeInfo;
801  }
802  }
803 
804  // Serialize flags
805  stream.Write((byte)flags);
806 
807  if (hasTypeInfo)
808  {
809  // Serialize type info
810  fixed (ObjectId* serializationTypeId = &objectDataSerializer.SerializationTypeId)
811  stream.Serialize((IntPtr)serializationTypeId, ObjectId.HashSize);
812 
813  // Serialize object
814  objCopy = obj;
815  objectDataSerializer.PreSerialize(ref objCopy, mode, stream);
816  objectDataSerializer.Serialize(ref objCopy, mode, stream);
817  obj = (T)objCopy;
818  }
819  else
820  {
821  // Serialize object
822  dataSerializer.PreSerialize(ref obj, mode, stream);
823  dataSerializer.Serialize(ref obj, mode, stream);
824  }
825  }
826  }
827  else
828  {
829 
830  flags = (SerializeClassFlags)stream.ReadByte();
831  bool isNull = (flags & SerializeClassFlags.IsNull) == SerializeClassFlags.IsNull;
832  hasTypeInfo = (flags & SerializeClassFlags.IsTypeInfo) == SerializeClassFlags.IsTypeInfo;
833 
834  if (isNull)
835  {
836  obj = default(T);
837  }
838  else
839  {
840  if (hasTypeInfo)
841  {
842  ObjectId serializationTypeId;
843  stream.Serialize((IntPtr)Interop.FixedOut(out serializationTypeId), ObjectId.HashSize);
844 
845  objectDataSerializer = context.SerializerSelector.GetSerializer(ref serializationTypeId);
846  if (objectDataSerializer == null)
847  throw new ArgumentException("No serializer available for type id " + serializationTypeId + " and base type " + typeof(T).FullName);
848 
849  objCopy = obj;
850  objectDataSerializer.PreSerialize(ref objCopy, mode, stream);
851 
852 
853  objectDataSerializer.Serialize(ref objCopy, mode, stream);
854  obj = (T)objCopy;
855  }
856  else
857  {
858  // Serialize object
859  dataSerializer.PreSerialize(ref obj, mode, stream);
860 
861 
862  dataSerializer.Serialize(ref obj, mode, stream);
863  }
864 
865  }
866  }
867  }
868  }
869 
870  public unsafe static class MemberReuseSerializer
871  {
872  public static void SerializeExtended(SerializationStream stream, Type objType, ref object obj, ArchiveMode mode, DataSerializer dataSerializer = null)
873  {
874  var context = stream.Context;
875 
876  if (objType.GetTypeInfo().IsValueType)
877  {
878  if (dataSerializer == null)
879  {
880  dataSerializer = context.SerializerSelector.GetSerializer(objType);
881 
882  // If we still have no serializer, throw an exception
883  if (dataSerializer == null)
884  throw new ArgumentException("No serializer available for type " + objType.FullName);
885  }
886 
887  // Structure, no need to check for inheritance or null values.
888  dataSerializer.Serialize(ref obj, mode, stream);
889 
890  return;
891  }
892 
893 
894  // Serialize either with dataSerializer if obj is really of type T, otherwise look for appropriate serializer.
896  bool reuseReferences = context.SerializerSelector.ReuseReferences;
897  int index;
898  bool hasTypeInfo;
899  DataSerializer objectDataSerializer;
900  Type type;
901 
902  if (mode == ArchiveMode.Serialize)
903  {
904  if (object.ReferenceEquals(obj, null))
905  {
906  // Null contentRef
907  stream.Write((byte)SerializeClassFlags.IsNull);
908  }
909  else
910  {
911  flags = SerializeClassFlags.None;
912  index = -1;
913  if (reuseReferences)
914  {
915  var objectReferences = context.Get(MemberSerializer.ObjectSerializeReferences);
916  if (objectReferences.TryGetValue(obj, out index))
917  {
918  // Already serialized, just write its contentRef index
919  flags |= SerializeClassFlags.IsReference;
920  stream.Write((byte)flags);
921  stream.Write(index);
922  return;
923  }
924 
925  // First time it is serialized, add it to objectReferences.
926  objectReferences.Add(obj, index = objectReferences.Count);
927  }
928 
929  // If real type is not expected type, we need to store type info as well.
930  var expectedType = objType;
931  type = objType.GetTypeInfo().IsSealed ? expectedType : obj.GetType();
932  hasTypeInfo = type != expectedType;
933  objectDataSerializer = null;
934  if (hasTypeInfo)
935  {
936  // Find matching serializer (always required w/ typeinfo, since type was different than expected)
937  objectDataSerializer = context.SerializerSelector.GetSerializer(type);
938 
939  if (objectDataSerializer == null)
940  throw new ArgumentException("No serializer available for type " + type.FullName);
941 
942  // Update expected type
943  type = objectDataSerializer.SerializationType;
944 
945  // Special case: serializer reports the actual serialized type, and it might actually match the expected type
946  // (i.e. there is a hidden inherited type, such as PropertyInfo/RuntimePropertyInfo).
947  // Let's detect it here.
948  if (type == expectedType)
949  {
950  // Cancel type info
951  hasTypeInfo = false;
952  }
953  else
954  {
955  // Continue as expected with type info
956  flags |= SerializeClassFlags.IsTypeInfo;
957  }
958  }
959 
960  // Serialize flags
961  stream.Write((byte)flags);
962 
963  // Serialize object index (if required)
964  if (reuseReferences)
965  stream.Write(index);
966 
967  if (hasTypeInfo)
968  {
969  // Serialize type info
970  fixed (ObjectId* serializationTypeId = &objectDataSerializer.SerializationTypeId)
971  stream.Serialize((IntPtr)serializationTypeId, ObjectId.HashSize);
972 
973  // Serialize object
974  objectDataSerializer.PreSerialize(ref obj, mode, stream);
975  objectDataSerializer.Serialize(ref obj, mode, stream);
976  }
977  else
978  {
979  if (dataSerializer == null)
980  {
981  dataSerializer = context.SerializerSelector.GetSerializer(expectedType);
982 
983  // If we still have no serializer, throw an exception
984  if (dataSerializer == null)
985  throw new ArgumentException("No serializer available for type " + expectedType.FullName);
986  }
987 
988  // Serialize object
989  dataSerializer.PreSerialize(ref obj, mode, stream);
990  dataSerializer.Serialize(ref obj, mode, stream);
991  }
992  }
993  }
994  else
995  {
996 
997  flags = (SerializeClassFlags)stream.ReadByte();
998  bool isNull = (flags & SerializeClassFlags.IsNull) == SerializeClassFlags.IsNull;
999  var objectReferences = reuseReferences ? context.Get(MemberSerializer.ObjectDeserializeReferences) : null;
1000  bool isReference = (flags & SerializeClassFlags.IsReference) == SerializeClassFlags.IsReference;
1001  index = reuseReferences && !isNull ? stream.ReadInt32() : -1;
1002  hasTypeInfo = (flags & SerializeClassFlags.IsTypeInfo) == SerializeClassFlags.IsTypeInfo;
1003 
1004  if (isNull)
1005  {
1006  obj = null;
1007  }
1008  else if (reuseReferences && isReference)
1009  {
1010  obj = objectReferences[index];
1011  }
1012  else
1013  {
1014  if (reuseReferences)
1015  {
1016  if (objectReferences.Count != index)
1017  throw new InvalidOperationException("Serialization contentRef indices are out of sync.");
1018  objectReferences.Add(null);
1019  }
1020  if (hasTypeInfo)
1021  {
1022  ObjectId serializationTypeId;
1023  stream.Serialize((IntPtr)Interop.FixedOut(out serializationTypeId), ObjectId.HashSize);
1024 
1025  objectDataSerializer = context.SerializerSelector.GetSerializer(ref serializationTypeId);
1026  if (objectDataSerializer == null)
1027  throw new ArgumentException("No serializer available for type id " + serializationTypeId + " and base type " + objType.FullName);
1028 
1029  objectDataSerializer.PreSerialize(ref obj, mode, stream);
1030 
1031  if (reuseReferences)
1032  {
1033  // Register object so that later references to it are working.
1034  objectReferences[index] = obj;
1035  }
1036 
1037  objectDataSerializer.Serialize(ref obj, mode, stream);
1038  }
1039  else
1040  {
1041  if (dataSerializer == null)
1042  {
1043  dataSerializer = context.SerializerSelector.GetSerializer(objType);
1044 
1045  // If we still have no serializer, throw an exception
1046  if (dataSerializer == null)
1047  throw new ArgumentException("No serializer available for type " + objType.FullName);
1048  }
1049 
1050  // Serialize object
1051  dataSerializer.PreSerialize(ref obj, mode, stream);
1052 
1053  if (reuseReferences)
1054  {
1055  // Register object so that later references to it are working.
1056  objectReferences[index] = obj;
1057  }
1058 
1059  dataSerializer.Serialize(ref obj, mode, stream);
1060  }
1061 
1062  if (reuseReferences)
1063  {
1064  // Register object so that later references to it are working.
1065  objectReferences[index] = obj;
1066  }
1067  }
1068  }
1069  }
1070  }
1071 
1072  public unsafe class MemberReuseSerializer<T> : MemberSerializer<T>
1073  {
1074  public MemberReuseSerializer(DataSerializer<T> dataSerializer) : base(dataSerializer)
1075  {
1076  }
1077 
1078  public override void Serialize(ref T obj, ArchiveMode mode, SerializationStream stream)
1079  {
1080  var context = stream.Context;
1081 
1082 
1083  // Serialize either with dataSerializer if obj is really of type T, otherwise look for appropriate serializer.
1085  bool reuseReferences = context.SerializerSelector.ReuseReferences;
1086  int index;
1087  bool hasTypeInfo;
1088  object objCopy;
1089  DataSerializer objectDataSerializer;
1090  Type type;
1091 
1092  if (mode == ArchiveMode.Serialize)
1093  {
1094  if (object.ReferenceEquals(obj, null))
1095  {
1096  // Null contentRef
1097  stream.Write((byte)SerializeClassFlags.IsNull);
1098  }
1099  else
1100  {
1101  flags = SerializeClassFlags.None;
1102  index = -1;
1103  if (reuseReferences)
1104  {
1105  var objectReferences = context.Get(MemberSerializer.ObjectSerializeReferences);
1106  if (objectReferences.TryGetValue(obj, out index))
1107  {
1108  // Already serialized, just write its contentRef index
1109  flags |= SerializeClassFlags.IsReference;
1110  stream.Write((byte)flags);
1111  stream.Write(index);
1112  return;
1113  }
1114 
1115  // First time it is serialized, add it to objectReferences.
1116  objectReferences.Add(obj, index = objectReferences.Count);
1117  }
1118 
1119  // If real type is not expected type, we need to store type info as well.
1120  var expectedType = typeof(T);
1121  type = isSealed ? expectedType : obj.GetType();
1122  hasTypeInfo = type != expectedType;
1123  objectDataSerializer = null;
1124  if (hasTypeInfo)
1125  {
1126  // Find matching serializer (always required w/ typeinfo, since type was different than expected)
1127  objectDataSerializer = context.SerializerSelector.GetSerializer(type);
1128 
1129  if (objectDataSerializer == null)
1130  throw new ArgumentException("No serializer available for type " + type.FullName);
1131 
1132  // Update expected type
1133  type = objectDataSerializer.SerializationType;
1134 
1135  // Special case: serializer reports the actual serialized type, and it might actually match the expected type
1136  // (i.e. there is a hidden inherited type, such as PropertyInfo/RuntimePropertyInfo).
1137  // Let's detect it here.
1138  if (type == expectedType)
1139  {
1140  // Cancel type info
1141  hasTypeInfo = false;
1142  }
1143  else
1144  {
1145  // Continue as expected with type info
1146  flags |= SerializeClassFlags.IsTypeInfo;
1147  }
1148  }
1149 
1150  // Serialize flags
1151  stream.Write((byte)flags);
1152 
1153  // Serialize object index (if required)
1154  if (reuseReferences)
1155  stream.Write(index);
1156 
1157  if (hasTypeInfo)
1158  {
1159  // Serialize type info
1160  fixed (ObjectId* serializationTypeId = &objectDataSerializer.SerializationTypeId)
1161  stream.Serialize((IntPtr)serializationTypeId, ObjectId.HashSize);
1162 
1163  // Serialize object
1164  objCopy = obj;
1165  objectDataSerializer.PreSerialize(ref objCopy, mode, stream);
1166  objectDataSerializer.Serialize(ref objCopy, mode, stream);
1167  obj = (T)objCopy;
1168  }
1169  else
1170  {
1171  // Serialize object
1172  dataSerializer.PreSerialize(ref obj, mode, stream);
1173  dataSerializer.Serialize(ref obj, mode, stream);
1174  }
1175  }
1176  }
1177  else
1178  {
1179 
1180  flags = (SerializeClassFlags)stream.ReadByte();
1181  bool isNull = (flags & SerializeClassFlags.IsNull) == SerializeClassFlags.IsNull;
1182  var objectReferences = reuseReferences ? context.Get(MemberSerializer.ObjectDeserializeReferences) : null;
1183  bool isReference = (flags & SerializeClassFlags.IsReference) == SerializeClassFlags.IsReference;
1184  index = reuseReferences && !isNull ? stream.ReadInt32() : -1;
1185  hasTypeInfo = (flags & SerializeClassFlags.IsTypeInfo) == SerializeClassFlags.IsTypeInfo;
1186 
1187  if (isNull)
1188  {
1189  obj = default(T);
1190  }
1191  else if (reuseReferences && isReference)
1192  {
1193  obj = (T)objectReferences[index];
1194  }
1195  else
1196  {
1197  if (reuseReferences)
1198  {
1199  if (objectReferences.Count != index)
1200  throw new InvalidOperationException("Serialization contentRef indices are out of sync.");
1201  objectReferences.Add(null);
1202  }
1203  if (hasTypeInfo)
1204  {
1205  ObjectId serializationTypeId;
1206  stream.Serialize((IntPtr)Interop.FixedOut(out serializationTypeId), ObjectId.HashSize);
1207 
1208  objectDataSerializer = context.SerializerSelector.GetSerializer(ref serializationTypeId);
1209  if (objectDataSerializer == null)
1210  throw new ArgumentException("No serializer available for type id " + serializationTypeId + " and base type " + typeof(T).FullName);
1211 
1212  objCopy = obj;
1213  objectDataSerializer.PreSerialize(ref objCopy, mode, stream);
1214 
1215  if (reuseReferences)
1216  {
1217  // Register object so that later references to it are working.
1218  objectReferences[index] = objCopy;
1219  }
1220 
1221  objectDataSerializer.Serialize(ref objCopy, mode, stream);
1222  obj = (T)objCopy;
1223  }
1224  else
1225  {
1226  // Serialize object
1227  dataSerializer.PreSerialize(ref obj, mode, stream);
1228 
1229  if (reuseReferences)
1230  {
1231  // Register object so that later references to it are working.
1232  objectReferences[index] = obj;
1233  }
1234 
1235  dataSerializer.Serialize(ref obj, mode, stream);
1236  }
1237 
1238  if (reuseReferences)
1239  {
1240  // Register object so that later references to it are working.
1241  objectReferences[index] = obj;
1242  }
1243  }
1244  }
1245  }
1246 
1247  internal static void SerializeExtended(ref T obj, ArchiveMode mode, SerializationStream stream, DataSerializer<T> dataSerializer = null)
1248  {
1249  var context = stream.Context;
1250 
1251  if (isValueType)
1252  {
1253  if (dataSerializer == null)
1254  {
1255  dataSerializer = (DataSerializer<T>)context.SerializerSelector.GetSerializer(typeof(T));
1256 
1257  // If we still have no serializer, throw an exception
1258  if (dataSerializer == null)
1259  throw new ArgumentException("No serializer available for type " + typeof(T).FullName);
1260  }
1261 
1262  // Structure, no need to check for inheritance or null values.
1263  dataSerializer.Serialize(ref obj, mode, stream);
1264 
1265  return;
1266  }
1267 
1268 
1269  // Serialize either with dataSerializer if obj is really of type T, otherwise look for appropriate serializer.
1271  bool reuseReferences = context.SerializerSelector.ReuseReferences;
1272  int index;
1273  bool hasTypeInfo;
1274  object objCopy;
1275  DataSerializer objectDataSerializer;
1276  Type type;
1277 
1278  if (mode == ArchiveMode.Serialize)
1279  {
1280  if (object.ReferenceEquals(obj, null))
1281  {
1282  // Null contentRef
1283  stream.Write((byte)SerializeClassFlags.IsNull);
1284  }
1285  else
1286  {
1287  flags = SerializeClassFlags.None;
1288  index = -1;
1289  if (reuseReferences)
1290  {
1291  var objectReferences = context.Get(MemberSerializer.ObjectSerializeReferences);
1292  if (objectReferences.TryGetValue(obj, out index))
1293  {
1294  // Already serialized, just write its contentRef index
1295  flags |= SerializeClassFlags.IsReference;
1296  stream.Write((byte)flags);
1297  stream.Write(index);
1298  return;
1299  }
1300 
1301  // First time it is serialized, add it to objectReferences.
1302  objectReferences.Add(obj, index = objectReferences.Count);
1303  }
1304 
1305  // If real type is not expected type, we need to store type info as well.
1306  var expectedType = typeof(T);
1307  type = isSealed ? expectedType : obj.GetType();
1308  hasTypeInfo = type != expectedType;
1309  objectDataSerializer = null;
1310  if (hasTypeInfo)
1311  {
1312  // Find matching serializer (always required w/ typeinfo, since type was different than expected)
1313  objectDataSerializer = context.SerializerSelector.GetSerializer(type);
1314 
1315  if (objectDataSerializer == null)
1316  throw new ArgumentException("No serializer available for type " + type.FullName);
1317 
1318  // Update expected type
1319  type = objectDataSerializer.SerializationType;
1320 
1321  // Special case: serializer reports the actual serialized type, and it might actually match the expected type
1322  // (i.e. there is a hidden inherited type, such as PropertyInfo/RuntimePropertyInfo).
1323  // Let's detect it here.
1324  if (type == expectedType)
1325  {
1326  // Cancel type info
1327  hasTypeInfo = false;
1328  }
1329  else
1330  {
1331  // Continue as expected with type info
1332  flags |= SerializeClassFlags.IsTypeInfo;
1333  }
1334  }
1335 
1336  // Serialize flags
1337  stream.Write((byte)flags);
1338 
1339  // Serialize object index (if required)
1340  if (reuseReferences)
1341  stream.Write(index);
1342 
1343  if (hasTypeInfo)
1344  {
1345  // Serialize type info
1346  fixed (ObjectId* serializationTypeId = &objectDataSerializer.SerializationTypeId)
1347  stream.Serialize((IntPtr)serializationTypeId, ObjectId.HashSize);
1348 
1349  // Serialize object
1350  objCopy = obj;
1351  objectDataSerializer.PreSerialize(ref objCopy, mode, stream);
1352  objectDataSerializer.Serialize(ref objCopy, mode, stream);
1353  obj = (T)objCopy;
1354  }
1355  else
1356  {
1357  if (dataSerializer == null)
1358  {
1359  dataSerializer = (DataSerializer<T>)context.SerializerSelector.GetSerializer(expectedType);
1360 
1361  // If we still have no serializer, throw an exception
1362  if (dataSerializer == null)
1363  throw new ArgumentException("No serializer available for type " + expectedType.FullName);
1364  }
1365 
1366  // Serialize object
1367  dataSerializer.PreSerialize(ref obj, mode, stream);
1368  dataSerializer.Serialize(ref obj, mode, stream);
1369  }
1370  }
1371  }
1372  else
1373  {
1374 
1375  flags = (SerializeClassFlags)stream.ReadByte();
1376  bool isNull = (flags & SerializeClassFlags.IsNull) == SerializeClassFlags.IsNull;
1377  var objectReferences = reuseReferences ? context.Get(MemberSerializer.ObjectDeserializeReferences) : null;
1378  bool isReference = (flags & SerializeClassFlags.IsReference) == SerializeClassFlags.IsReference;
1379  index = reuseReferences && !isNull ? stream.ReadInt32() : -1;
1380  hasTypeInfo = (flags & SerializeClassFlags.IsTypeInfo) == SerializeClassFlags.IsTypeInfo;
1381 
1382  if (isNull)
1383  {
1384  obj = default(T);
1385  }
1386  else if (reuseReferences && isReference)
1387  {
1388  obj = (T)objectReferences[index];
1389  }
1390  else
1391  {
1392  if (reuseReferences)
1393  {
1394  if (objectReferences.Count != index)
1395  throw new InvalidOperationException("Serialization contentRef indices are out of sync.");
1396  objectReferences.Add(null);
1397  }
1398  if (hasTypeInfo)
1399  {
1400  ObjectId serializationTypeId;
1401  stream.Serialize((IntPtr)Interop.FixedOut(out serializationTypeId), ObjectId.HashSize);
1402 
1403  objectDataSerializer = context.SerializerSelector.GetSerializer(ref serializationTypeId);
1404  if (objectDataSerializer == null)
1405  throw new ArgumentException("No serializer available for type id " + serializationTypeId + " and base type " + typeof(T).FullName);
1406 
1407  objCopy = obj;
1408  objectDataSerializer.PreSerialize(ref objCopy, mode, stream);
1409 
1410  if (reuseReferences)
1411  {
1412  // Register object so that later references to it are working.
1413  objectReferences[index] = objCopy;
1414  }
1415 
1416  objectDataSerializer.Serialize(ref objCopy, mode, stream);
1417  obj = (T)objCopy;
1418  }
1419  else
1420  {
1421  if (dataSerializer == null)
1422  {
1423  dataSerializer = (DataSerializer<T>)context.SerializerSelector.GetSerializer(typeof(T));
1424 
1425  // If we still have no serializer, throw an exception
1426  if (dataSerializer == null)
1427  throw new ArgumentException("No serializer available for type " + typeof(T).FullName);
1428  }
1429 
1430  // Serialize object
1431  dataSerializer.PreSerialize(ref obj, mode, stream);
1432 
1433  if (reuseReferences)
1434  {
1435  // Register object so that later references to it are working.
1436  objectReferences[index] = obj;
1437  }
1438 
1439  dataSerializer.Serialize(ref obj, mode, stream);
1440  }
1441 
1442  if (reuseReferences)
1443  {
1444  // Register object so that later references to it are working.
1445  objectReferences[index] = obj;
1446  }
1447  }
1448  }
1449  }
1450  }
1451 
1452  public unsafe class MemberReuseSerializerObject<T> : MemberSerializer<T>
1453  {
1454  public MemberReuseSerializerObject(DataSerializer<T> dataSerializer) : base(dataSerializer)
1455  {
1456  }
1457 
1458  public override void Serialize(ref T obj, ArchiveMode mode, SerializationStream stream)
1459  {
1460  var context = stream.Context;
1461 
1462  if (isValueType)
1463  {
1464 
1465  // Structure, no need to check for inheritance or null values.
1466  dataSerializer.Serialize(ref obj, mode, stream);
1467 
1468  return;
1469  }
1470 
1471 
1472  // Serialize either with dataSerializer if obj is really of type T, otherwise look for appropriate serializer.
1474  bool reuseReferences = context.SerializerSelector.ReuseReferences;
1475  int index;
1476  bool hasTypeInfo;
1477  object objCopy;
1478  DataSerializer objectDataSerializer;
1479  Type type;
1480 
1481  if (mode == ArchiveMode.Serialize)
1482  {
1483  if (object.ReferenceEquals(obj, null))
1484  {
1485  // Null contentRef
1486  stream.Write((byte)SerializeClassFlags.IsNull);
1487  }
1488  else
1489  {
1490  flags = SerializeClassFlags.None;
1491  index = -1;
1492  if (reuseReferences)
1493  {
1494  var objectReferences = context.Get(MemberSerializer.ObjectSerializeReferences);
1495  if (objectReferences.TryGetValue(obj, out index))
1496  {
1497  // Already serialized, just write its contentRef index
1498  flags |= SerializeClassFlags.IsReference;
1499  stream.Write((byte)flags);
1500  stream.Write(index);
1501  return;
1502  }
1503 
1504  // First time it is serialized, add it to objectReferences.
1505  objectReferences.Add(obj, index = objectReferences.Count);
1506  }
1507 
1508  // If real type is not expected type, we need to store type info as well.
1509  var expectedType = typeof(T);
1510  type = isSealed ? expectedType : obj.GetType();
1511  hasTypeInfo = type != expectedType;
1512  objectDataSerializer = null;
1513  if (hasTypeInfo)
1514  {
1515  // Find matching serializer (always required w/ typeinfo, since type was different than expected)
1516  objectDataSerializer = context.SerializerSelector.GetSerializer(type);
1517 
1518  if (objectDataSerializer == null)
1519  throw new ArgumentException("No serializer available for type " + type.FullName);
1520 
1521  // Update expected type
1522  type = objectDataSerializer.SerializationType;
1523 
1524  // Special case: serializer reports the actual serialized type, and it might actually match the expected type
1525  // (i.e. there is a hidden inherited type, such as PropertyInfo/RuntimePropertyInfo).
1526  // Let's detect it here.
1527  if (type == expectedType)
1528  {
1529  // Cancel type info
1530  hasTypeInfo = false;
1531  }
1532  else
1533  {
1534  // Continue as expected with type info
1535  flags |= SerializeClassFlags.IsTypeInfo;
1536  }
1537  }
1538 
1539  // Serialize flags
1540  stream.Write((byte)flags);
1541 
1542  // Serialize object index (if required)
1543  if (reuseReferences)
1544  stream.Write(index);
1545 
1546  if (hasTypeInfo)
1547  {
1548  // Serialize type info
1549  fixed (ObjectId* serializationTypeId = &objectDataSerializer.SerializationTypeId)
1550  stream.Serialize((IntPtr)serializationTypeId, ObjectId.HashSize);
1551 
1552  // Serialize object
1553  objCopy = obj;
1554  objectDataSerializer.PreSerialize(ref objCopy, mode, stream);
1555  objectDataSerializer.Serialize(ref objCopy, mode, stream);
1556  obj = (T)objCopy;
1557  }
1558  else
1559  {
1560  // Serialize object
1561  dataSerializer.PreSerialize(ref obj, mode, stream);
1562  dataSerializer.Serialize(ref obj, mode, stream);
1563  }
1564  }
1565  }
1566  else
1567  {
1568 
1569  flags = (SerializeClassFlags)stream.ReadByte();
1570  bool isNull = (flags & SerializeClassFlags.IsNull) == SerializeClassFlags.IsNull;
1571  var objectReferences = reuseReferences ? context.Get(MemberSerializer.ObjectDeserializeReferences) : null;
1572  bool isReference = (flags & SerializeClassFlags.IsReference) == SerializeClassFlags.IsReference;
1573  index = reuseReferences && !isNull ? stream.ReadInt32() : -1;
1574  hasTypeInfo = (flags & SerializeClassFlags.IsTypeInfo) == SerializeClassFlags.IsTypeInfo;
1575 
1576  if (isNull)
1577  {
1578  obj = default(T);
1579  }
1580  else if (reuseReferences && isReference)
1581  {
1582  obj = (T)objectReferences[index];
1583  }
1584  else
1585  {
1586  if (reuseReferences)
1587  {
1588  if (objectReferences.Count != index)
1589  throw new InvalidOperationException("Serialization contentRef indices are out of sync.");
1590  objectReferences.Add(null);
1591  }
1592  if (hasTypeInfo)
1593  {
1594  ObjectId serializationTypeId;
1595  stream.Serialize((IntPtr)Interop.FixedOut(out serializationTypeId), ObjectId.HashSize);
1596 
1597  objectDataSerializer = context.SerializerSelector.GetSerializer(ref serializationTypeId);
1598  if (objectDataSerializer == null)
1599  throw new ArgumentException("No serializer available for type id " + serializationTypeId + " and base type " + typeof(T).FullName);
1600 
1601  objCopy = obj;
1602  objectDataSerializer.PreSerialize(ref objCopy, mode, stream);
1603 
1604  if (reuseReferences)
1605  {
1606  // Register object so that later references to it are working.
1607  objectReferences[index] = objCopy;
1608  }
1609 
1610  objectDataSerializer.Serialize(ref objCopy, mode, stream);
1611  obj = (T)objCopy;
1612  }
1613  else
1614  {
1615  // Serialize object
1616  dataSerializer.PreSerialize(ref obj, mode, stream);
1617 
1618  if (reuseReferences)
1619  {
1620  // Register object so that later references to it are working.
1621  objectReferences[index] = obj;
1622  }
1623 
1624  dataSerializer.Serialize(ref obj, mode, stream);
1625  }
1626 
1627  if (reuseReferences)
1628  {
1629  // Register object so that later references to it are working.
1630  objectReferences[index] = obj;
1631  }
1632  }
1633  }
1634  }
1635  }
1636 }
_In_ size_t _In_ DXGI_FORMAT _In_ size_t _In_ DXGI_FORMAT _In_ DWORD flags
Definition: DirectXTexP.h:170
override void Serialize(ref T obj, ArchiveMode mode, SerializationStream stream)
override void Serialize(ref T obj, ArchiveMode mode, SerializationStream stream)
static void SerializeExtended(SerializationStream stream, Type objType, ref object obj, ArchiveMode mode, DataSerializer dataSerializer=null)
Base class for implementation of SerializationStream.
override void Serialize(ref T obj, ArchiveMode mode, SerializationStream stream)
static void SerializeExtended(SerializationStream stream, Type objType, ref object obj, ArchiveMode mode, DataSerializer dataSerializer=null)
override void Serialize(ref T obj, ArchiveMode mode, SerializationStream stream)
static void SerializeExtended(SerializationStream stream, Type objType, ref object obj, ArchiveMode mode, DataSerializer dataSerializer=null)
override void Serialize(ref T obj, ArchiveMode mode, SerializationStream stream)
SerializeClassFlags
Specifies flags used when serializing reference types.
A hash to uniquely identify data.
Definition: ObjectId.cs:13
Describes how to serialize and deserialize an object without knowing its type. Used as a common base ...
ArchiveMode
Enumerates the different mode of serialization (either serialization or deserialization).
Definition: ArchiveMode.cs:8
Describes how to serialize and deserialize an object of a given type.
override void Serialize(ref T obj, ArchiveMode mode, SerializationStream stream)