1
2
3
4
5
6 using System;
7
8 namespace System.Xml
9 {
10 public abstract class ParentNode : Node
11 {
12 public ParentNode(NodeKind kind_, const System.Lex.Span& span_, int fileIndex_, const string& name_) :
13 base(kind_, span_, fileIndex_, name_), firstChild(null), lastChild(null)
14 {
15 }
16 public override ~ParentNode()
17 {
18 Node* child = firstChild;
19 while (child != null)
20 {
21 Node* toDel = child;
22 child = child->Next();
23 delete toDel;
24 }
25 }
26 public Node* FirstChild() const
27 {
28 return firstChild;
29 }
30 public Node* LastChild() const
31 {
32 return lastChild;
33 }
34 public virtual void AppendChild(Node* child)
35 {
36 if (OwnerDocument() != null)
37 {
38 OwnerDocument()->InvalidateIndex();
39 }
40 if (child->Parent() != null)
41 {
42 child = child->Parent()->RemoveChild(child).Release();
43 }
44 if (child->IsDocumentFragmentNode())
45 {
46 DocumentFragment* documentFragment = cast<DocumentFragment*>(child);
47 Node* docFragChild = documentFragment->FirstChild();
48 Node* nodeInserted = null;
49 while (docFragChild != null)
50 {
51 UniquePtr<Node> docFragChildRemoved = documentFragment->RemoveChild(docFragChild);
52 AppendChild(docFragChildRemoved.Release());
53 docFragChild = documentFragment->FirstChild();
54 }
55 }
56 else
57 {
58 if (lastChild != null)
59 {
60 lastChild->LinkAfter(child);
61 }
62 if (firstChild == null)
63 {
64 firstChild = child;
65 }
66 child->SetOwnerDocument(OwnerDocument());
67 child->SetParent(this);
68 lastChild = child;
69 }
70 }
71 public virtual void InsertBefore(Node* newChild, Node* refChild)
72 {
73 if (refChild == null)
74 {
75 AppendChild(newChild);
76 }
77 if (OwnerDocument() != null)
78 {
79 OwnerDocument()->InvalidateIndex();
80 }
81 if (newChild->IsDocumentFragmentNode())
82 {
83 DocumentFragment* documentFragment = cast<DocumentFragment*>(newChild);
84 Node* docFragChild = documentFragment->FirstChild();
85 Node* nodeInserted = null;
86 while (docFragChild != null)
87 {
88 UniquePtr<Node> docFragChildRemoved = documentFragment->RemoveChild(docFragChild);
89 InsertBefore(docFragChildRemoved.Release(), refChild);
90 docFragChild = documentFragment->FirstChild();
91 }
92 }
93 else
94 {
95 if (newChild->Parent() != null)
96 {
97 newChild = newChild->Parent()->RemoveChild(newChild).Release();
98 }
99 if (firstChild == refChild)
100 {
101 firstChild = newChild;
102 }
103 newChild->SetParent(this);
104 newChild->SetOwnerDocument(OwnerDocument());
105 refChild->LinkBefore(newChild);
106 }
107 }
108 public virtual UniquePtr<Node> RemoveChild(Node* child)
109 {
110 if (OwnerDocument() != null)
111 {
112 OwnerDocument()->InvalidateIndex();
113 }
114 child->Unlink();
115 if (child == firstChild)
116 {
117 firstChild = child->Next();
118 }
119 if (child == lastChild)
120 {
121 lastChild = child->Prev();
122 }
123 UniquePtr<Node> removedNode = UniquePtr<Node>(child);
124 removedNode->SetOwnerDocument(null);
125 removedNode->SetParent(null);
126 return removedNode;
127 }
128 public virtual UniquePtr<Node> ReplaceChild(Node* newChild, Node* oldChild)
129 {
130 if (OwnerDocument() != null)
131 {
132 OwnerDocument()->InvalidateIndex();
133 }
134 if (newChild->Parent() != null)
135 {
136 newChild = newChild->Parent()->RemoveChild(newChild).Release();
137 }
138 InsertBefore(newChild, oldChild);
139 return RemoveChild(oldChild);
140 }
141 public override bool HasChildNodes() const
142 {
143 return firstChild != null;
144 }
145 public override void Accept(Visitor& visitor)
146 {
147 Node* child = firstChild;
148 while (child != null)
149 {
150 child->Accept(visitor);
151 child = child->Next();
152 }
153 }
154 [nodiscard]
155 public override Result<bool> Write(System.Text.CodeFormatter& formatter)
156 {
157 if (formatter.Error())
158 {
159 return Result<bool>(ErrorId(formatter.GetErrorId()));
160 }
161 Node* child = firstChild;
162 while (child != null)
163 {
164 child->Write(formatter);
165 child = child->Next();
166 }
167 return Result<bool>(true);
168 }
169 public override void WalkChildren(NodeOperation& operation)
170 {
171 Node* child = firstChild;
172 while (child != null)
173 {
174 operation.Apply(child);
175 child = child->Next();
176 }
177 }
178 public override void WalkDescendant(NodeOperation& operation)
179 {
180 Node* child = firstChild;
181 while (child != null)
182 {
183 child->WalkDescendantOrSelf(operation);
184 child = child->Next();
185 }
186 }
187 public override void WalkDescendantOrSelf(NodeOperation& operation)
188 {
189 base->WalkDescendantOrSelf(operation);
190 Node* child = firstChild;
191 while (child != null)
192 {
193 child->WalkDescendantOrSelf(operation);
194 child = child->Next();
195 }
196 }
197 public override void WalkPreceding(NodeOperation& operation)
198 {
199 Node* preceding = Prev();
200 if (preceding != null)
201 {
202 preceding->WalkPrecedingOrSelf(operation);
203 }
204 }
205 public override void WalkPrecedingOrSelf(NodeOperation& operation)
206 {
207 base->WalkPrecedingOrSelf(operation);
208 Node* child = lastChild;
209 while (child != null)
210 {
211 child->WalkPrecedingOrSelf(operation);
212 child = child->Prev();
213 }
214 }
215 private Node* firstChild;
216 private Node* lastChild;
217 }
218 }