1
2
3
4
5
6 using System;
7 using System.Collections;
8
9 namespace System.Xml.Serialization
10 {
11 delegate void* FactoryFunction();
12
13 public abstract class XmlSerializableExtractor
14 {
15 public virtual default ~XmlSerializableExtractor();
16 public abstract nothrow XmlSerializable ExtractXmlSerializable(void* object);
17 }
18
19 public class ConcreteXmlSerializableExtractor<T> : XmlSerializableExtractor
20 {
21 public override nothrow XmlSerializable ExtractXmlSerializable(void* object)
22 {
23 if (object != null)
24 {
25 T* obj = cast<T*>(object);
26 XmlSerializable intf = *obj;
27 return intf;
28 }
29 else
30 {
31 return XmlSerializable();
32 }
33 }
34 }
35
36 public XmlSerializableExtractor* MakeXmlSerializableExtractor<T>()
37 {
38 ConcreteXmlSerializableExtractor<T>* extractor = new ConcreteXmlSerializableExtractor<T>();
39 return extractor;
40 }
41
42 public class XmlClassRegistry
43 {
44 static XmlClassRegistry() : instance(new XmlClassRegistry())
45 {
46 }
47 public static XmlClassRegistry& Instance()
48 {
49 return *instance;
50 }
51 private nothrow XmlClassRegistry()
52 {
53 }
54 public void Register(int classId, FactoryFunction factoryFunction, XmlSerializableExtractor* extractor)
55 {
56 factoryMap[classId] = factoryFunction;
57 if (extractor != null)
58 {
59 extractorMap[classId] = extractor;
60 extractors.Add(UniquePtr<XmlSerializableExtractor>(extractor));
61 }
62 }
63 public XmlSerializable CreateXmlSerializable(int classId)
64 {
65 Map<int, XmlSerializableExtractor*>.ConstIterator it = extractorMap.CFind(classId);
66 if (it != extractorMap.CEnd())
67 {
68 XmlSerializableExtractor* extractor = it->second;
69 void* object = Create(classId);
70 return extractor->ExtractXmlSerializable(object);
71 }
72 else
73 {
74 throw XmlSerializationException("interface extractor for class id " + ToString(classId) + " not registered");
75 }
76 }
77 public void* Create(int classId)
78 {
79 Map<int, FactoryFunction>.ConstIterator it = factoryMap.CFind(classId);
80 if (it != factoryMap.CEnd())
81 {
82 FactoryFunction factoryFunction = it->second;
83 return factoryFunction();
84 }
85 else
86 {
87 throw XmlSerializationException("class having id " + ToString(classId) + " not registered");
88 }
89 }
90 private static UniquePtr<XmlClassRegistry> instance;
91 private Map<int, FactoryFunction> factoryMap;
92 private Map<int, XmlSerializableExtractor*> extractorMap;
93 private List<UniquePtr<XmlSerializableExtractor>> extractors;
94 }
95
96 public void XmlRegister<T>(int classId)
97 {
98 XmlClassRegistry.Instance().Register(classId, T.Create, MakeXmlSerializableExtractor<T>());
99 }
100 }
101