1
2
3
4
5
6 using System;
7 using System.Collections;
8
9 namespace System.Xml.Serialization
10 {
11 public class XmlContainer
12 {
13 public nothrow XmlContainer()
14 {
15 }
16 public virtual ~XmlContainer()
17 {
18 Clear();
19 }
20 public virtual nothrow void SetRootObjectId(const Uuid& objectId)
21 {
22 }
23 public nothrow long Count() const
24 {
25 return objectProxyMap.Count();
26 }
27 public nothrow bool IsEmpty() const
28 {
29 return objectProxyMap.IsEmpty();
30 }
31 public nothrow void Clear()
32 {
33 for (const Pair<void*, XmlSerializableProxy*>& p : objectProxyMap)
34 {
35 delete p.second;
36 }
37 idProxyMap.Clear();
38 objectProxyMap.Clear();
39
40 }
41 public void Add(XmlSerializable xmlSerializable)
42 {
43 XmlSerializableProxy* prev = Get(xmlSerializable.ObjectId());
44 if (prev != null)
45 {
46 throw XmlSerializationException("object '" + ToString(prev->ObjectId()) + "' already added to XML container");
47 }
48 XmlSerializableProxy* proxy = new XmlSerializableProxy(xmlSerializable);
49 idProxyMap[proxy->ObjectId()] = proxy;
50 objectProxyMap[proxy->Object()] = proxy;
51 proxy->SetContainer(this);
52 }
53 public nothrow XmlSerializableProxy* Get(const Uuid& objectId) const
54 {
55 HashMap<Uuid, XmlSerializableProxy*>.ConstIterator it = idProxyMap.CFind(objectId);
56 if (it != idProxyMap.CEnd())
57 {
58 return it->second;
59 }
60 else
61 {
62 return null;
63 }
64 }
65 public void Remove(const Uuid& objectId)
66 {
67 XmlSerializableProxy* proxy = Get(objectId);
68 if (proxy != null)
69 {
70 objectProxyMap.Remove(proxy->Object());
71 idProxyMap.Remove(objectId);
72 delete proxy;
73 }
74 }
75 public nothrow XmlSerializableProxy* GetProxy(void* object)
76 {
77 HashMap<void*, XmlSerializableProxy*>.ConstIterator it = objectProxyMap.CFind(object);
78 if (it != objectProxyMap.CEnd())
79 {
80 XmlSerializableProxy* proxy = it->second;
81 return proxy;
82 }
83 else
84 {
85 return null;
86 }
87 }
88 public List<XmlSerializableProxy*> GetProxies() const
89 {
90 List<XmlSerializableProxy*> proxies;
91 for (const Pair<void*, XmlSerializableProxy*>& p : objectProxyMap)
92 {
93 if (p.second != null)
94 {
95 proxies.Add(p.second);
96 }
97 }
98 return proxies;
99 }
100 public void AddToBundle(XmlBundle& bundle, XmlBundleKind kind, int hops, XmlSerializable intf, HashSet<Uuid>& addedSet)
101 {
102 if (intf.ObjectId() == Uuid())
103 {
104 return;
105 }
106 if (addedSet.CFind(intf.ObjectId()) != addedSet.CEnd())
107 {
108 return;
109 }
110 bundle.Add(intf);
111 addedSet.Insert(intf.ObjectId());
112 if (kind == XmlBundleKind.deep && (hops == -1 || hops > 0))
113 {
114 List<XmlPtrBase*> ptrs = intf.GetPtrs();
115 for (XmlPtrBase* ptr : ptrs)
116 {
117 if (ptr->TargetObjectId() != Uuid())
118 {
119 XmlSerializableProxy* target = Get(ptr->TargetObjectId());
120 if (target != null)
121 {
122 int nextHops = -1;
123 if (hops > 0)
124 {
125 nextHops = hops - 1;
126 }
127 AddToBundle(bundle, kind, nextHops, target->Interface(), addedSet);
128 }
129 else
130 {
131 XmlSerializable intf = ptr->Interface();
132 XmlContainer* container = intf.Container();
133 if (container != null)
134 {
135 target = container->Get(ptr->TargetObjectId());
136 if (target != null)
137 {
138 int nextHops = -1;
139 if (hops > 0)
140 {
141 nextHops = hops - 1;
142 }
143 container->AddToBundle(bundle, kind, nextHops, intf, addedSet);
144 }
145 }
146 }
147 }
148 }
149 }
150 }
151 public XmlBundle CreateBundle(void* object)
152 {
153 return CreateBundle(object, XmlBundleKind.shallow);
154 }
155 public XmlBundle CreateBundle(void* object, XmlBundleKind kind)
156 {
157 return CreateBundle(object, kind, -1);
158 }
159 public XmlBundle CreateBundle(void* object, XmlBundleKind kind, int hops)
160 {
161 HashSet<Uuid> addedSet;
162 XmlBundle bundle;
163 XmlSerializableProxy* proxy = GetProxy(object);
164 if (proxy != null)
165 {
166 bundle.SetRootObjectId(proxy->ObjectId());
167 XmlSerializable intf = proxy->Interface();
168 AddToBundle(bundle, kind, hops, intf, addedSet);
169 }
170 return bundle;
171 }
172 public HashMap<Uuid, XmlSerializableProxy*> idProxyMap;
173 public HashMap<void*, XmlSerializableProxy*> objectProxyMap;
174 }
175
176 public void Add<T>(T* object, XmlContainer* container)
177 {
178 XmlSerializable xmlSerializable(*object);
179 container->Add(xmlSerializable);
180 }
181
182 public void AddOrReplace<T>(T* object, XmlContainer* container)
183 {
184 XmlSerializable xmlSerializable(*object);
185 container->Remove(xmlSerializable.ObjectId());
186 container->Add(xmlSerializable);
187 }
188
189 public void RemoveFromContainer<T>(T* object)
190 {
191 XmlSerializable xmlSerializable(*object);
192 XmlContainer* container = xmlSerializable.Container();
193 if (container != null)
194 {
195 container->Remove(xmlSerializable.ObjectId());
196 }
197 }
198 }
199