1
2
3 using System;
4 using System.Collections;
5 using System.Xml;
6 using System.Xml.Serialization;
7
8 public enum Color
9 {
10 white, black, red, blue
11 }
12
13 public string ColorStr(Color color)
14 {
15 switch (color)
16 {
17 case Color.white: return "white";
18 case Color.black: return "black";
19 case Color.red: return "red";
20 case Color.blue: return "blue";
21 }
22 return "<unknown color>";
23 }
24
25 [xml]
26 public abstract class Vehicle
27 {
28 public Vehicle()
29 {
30 }
31 public virtual default ~Vehicle();
32 public void SetOwner(Person* owner_)
33 {
34 owner = owner_;
35 }
36 public void SetModel(const string& model_)
37 {
38 model = model_;
39 }
40 public inline const string& Model() const
41 {
42 return model;
43 }
44 public void SetColor(Color color_)
45 {
46 color = color_;
47 }
48 public inline Color GetColor() const
49 {
50 return color;
51 }
52 public virtual void Print()
53 {
54 Console.Out() << ClassName() << "\n";
55 if (!owner.IsNull())
56 {
57 Console.Out() << "owner: " << owner->Name() << "\n";
58 }
59 Console.Out() << "model: " << model << "\n";
60 Console.Out() << "color: " << ColorStr(color) << "\n";
61 }
62 private string model;
63 private Color color;
64 private System.Xml.Serialization.XmlPtr<Person> owner;
65 }
66
67 [xml]
68 public class Bicycle : Vehicle
69 {
70 public Bicycle()
71 {
72 }
73 public inline int Price()
74 {
75 return price;
76 }
77 public void SetPrice(int price_)
78 {
79 price = price_;
80 }
81 public override void Print()
82 {
83 base->Print();
84 Console.Out() << "price: " << price << "\n";
85 }
86 private int price;
87 }
88
89 [xml]
90 public class Car : Vehicle
91 {
92 public Car()
93 {
94 }
95 public void SetRegistrationNumber(const string& registrationNumber_)
96 {
97 registrationNumber = registrationNumber_;
98 }
99 public inline const string& RegistrationNumber() const
100 {
101 return registrationNumber;
102 }
103 public override void Print()
104 {
105 base->Print();
106 Console.Out() << "registrationNumber: " << registrationNumber << "\n";
107 }
108 private string registrationNumber;
109 }
110
111 [xml]
112 public class Person
113 {
114 public Person()
115 {
116 }
117 public Person(const string& name_) : name(name_)
118 {
119 }
120 public inline const string& Name() const
121 {
122 return name;
123 }
124 public void AddVehicle(Vehicle* vehicle)
125 {
126 vehicle->SetOwner(this);
127 vehicles.Add(System.Xml.Serialization.XmlPtr<Vehicle>(vehicle));
128 }
129 public void Print()
130 {
131 Console.Out() << "Person" << "\n";
132 Console.Out() << "name: " << name << "\n";
133 Console.Out() << "vehicles:" << "\n";
134 for (const auto& vehicle : vehicles)
135 {
136 vehicle->Print();
137 }
138 }
139 private string name;
140 private List<System.Xml.Serialization.XmlPtr<Vehicle>> vehicles;
141 }
142
143 [nodiscard]
144 Result<bool> Register()
145 {
146 auto result = Person.Register();
147 if (result.Error()) return result;
148 result = Bicycle.Register();
149 if (result.Error()) return result;
150 result = Car.Register();
151 if (result.Error()) return result;
152 return Result<bool>(true);
153 }
154
155 int main()
156 {
157 auto registerResult = Register();
158 if (registerResult.Error())
159 {
160 Console.Error() << registerResult.GetErrorMessage() << "\n";
161 return 1;
162 }
163 System.Xml.Serialization.XmlBundle bundle;
164 Person* joe = new Person("Joe Coder");
165 bundle.Add(joe);
166 Bicycle* cooper = new Bicycle();
167 cooper->SetModel("Cooper");
168 cooper->SetColor(Color.blue);
169 cooper->SetPrice(1000);
170 joe->AddVehicle(cooper);
171 bundle.Add(cooper);
172 Car* porsche = new Car();
173 porsche->SetModel("Porsche");
174 porsche->SetColor(Color.red);
175 porsche->SetRegistrationNumber("ABC-123");
176 joe->AddVehicle(porsche);
177 bundle.Add(porsche);
178 Result<UniquePtr<System.Xml.Document>> xmlDocumentResult = bundle.ToXmlDocument();
179 if (xmlDocumentResult.Error())
180 {
181 Console.Error() << xmlDocumentResult.GetErrorMessage() << "\n";
182 return 1;
183 }
184 System.Xml.Document* document = xmlDocumentResult.Value().Get();
185 System.Text.CodeFormatter formatter(Console.Out());
186 formatter.SetIndentSize(1);
187 Result<bool> writeResult = document->Write(formatter);
188 if (writeResult.Error())
189 {
190 Console.Error() << writeResult.GetErrorMessage() << "\n";
191 return 1;
192 }
193 System.Xml.Serialization.XmlBundle readBundle;
194 System.Xml.Serialization.XmlSerializationContext ctx;
195 ctx.SetFlag(System.Xml.Serialization.XmlSerializationFlags.failOnNotFoundObjects);
196 Result<bool> fromXmlResult = readBundle.FromXml(*document, ctx);
197 if (fromXmlResult.Error())
198 {
199 Console.Error() << fromXmlResult.GetErrorMessage() << "\n";
200 return 1;
201 }
202 if (readBundle.Count() != 3)
203 {
204 Console.Error() << "three objects expected" << "\n";
205 return 1;
206 }
207 System.Xml.Serialization.XmlSerializable* first = readBundle.Get(0);
208 if (first is Person*)
209 {
210 Person* person = cast<Person*>(first);
211 person->Print();
212 }
213 else
214 {
215 Console.Error() << "Person object expected" << "\n";
216 }
217 return 0;
218 }