Changeset 1274 for branches/New Persistence Exploration
- Timestamp:
- 03/06/09 14:36:10 (16 years ago)
- Location:
- branches/New Persistence Exploration/Persistence/Persistence
- Files:
-
- 1 added
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/New Persistence Exploration/Persistence/Persistence/NewSerializationTest.cs
r1264 r1274 3 3 using System.Text; 4 4 using System.Collections; 5 using System.IO; 5 6 6 7 namespace Persistence { … … 14 15 [Storable] 15 16 public ArrayList intArray = new ArrayList(new int[] { 1, 2, 3 }); 17 [Storable] 18 public List<int> intList = new List<int>(new int[] { 321, 312, 321 }); 16 19 [Storable] 17 20 public Custom c; … … 38 41 Serializer s = new Serializer(r, serializers); 39 42 Persistence.XmlFormatter xmlFormatter = new Persistence.XmlFormatter(); 43 StreamWriter writer = new StreamWriter("test.xml"); 40 44 foreach (ISerializationToken token in s) { 41 Console.Write(xmlFormatter.Format(token)); 45 string line = xmlFormatter.Format(token); 46 writer.Write(line); 47 Console.Out.Write(line); 42 48 } 49 writer.Close(); 50 XmlParser parser = new XmlParser(new StreamReader("test.xml")); 51 DeSerializer deSerializer = new DeSerializer(); 52 object o = deSerializer.DeSerialize(parser); 53 Console.Out.WriteLine(Util.AutoFormat(o, true)); 43 54 Console.In.ReadLine(); 44 55 } -
branches/New Persistence Exploration/Persistence/Persistence/Persistence.csproj
r1264 r1274 49 49 </ItemGroup> 50 50 <ItemGroup> 51 <Compile Include="Util.cs" /> 51 52 <Compile Include="StorableAttributeTests.cs" /> 52 53 <Compile Include="StorableAttribute.cs" /> -
branches/New Persistence Exploration/Persistence/Persistence/PersistenceManager.cs
r1264 r1274 5 5 using System.Collections; 6 6 using System.Reflection; 7 using System.Xml; 7 8 8 9 namespace Persistence { … … 85 86 #endregion 86 87 87 #region Generics (incomplete)88 #region Custom 88 89 public interface ICustomSerializer { 89 90 bool CanSerialize(Type type); … … 127 128 } 128 129 129 public object DeSerialize(IEnumerable o, Type t) { 130 throw new NotImplementedException(); 131 } 132 133 } 130 public object DeSerialize(IEnumerable elements, Type t) { 131 List<object> allElements = new List<object>(); 132 foreach (object obj in elements) { 133 allElements.Add(obj); 134 } 135 Array array = 136 Array.CreateInstance(t.GetElementType(), allElements.Count); 137 for (int i = 0; i < array.Length; i++) { 138 array.SetValue(allElements[i], i); 139 } 140 return array; 141 } 142 143 } 134 144 #endregion 135 145 … … 172 182 173 183 private IEnumerator<ISerializationToken> Serialize(DataMemberAccessor accessor) { 174 object value = accessor.Get(); 184 object value = accessor.Get(); 175 185 if (value == null) { 176 186 yield return new NullReferenceToken(accessor.Name); 177 } else if (this.primitiveSerializers.ContainsKey( accessor.Type)) {178 yield return new PrimitiveToken(accessor, this.primitiveSerializers[ accessor.Type].Serialize(value));187 } else if (this.primitiveSerializers.ContainsKey(value.GetType())) { 188 yield return new PrimitiveToken(accessor, this.primitiveSerializers[value.GetType()].Serialize(value)); 179 189 } else if (this.obj2id.ContainsKey(value)) { 180 190 yield return new ReferenceToken(accessor.Name, this.obj2id[value]); … … 183 193 this.obj2id.Add(value, id); 184 194 yield return new BeginToken(accessor, id); 185 ICustomSerializer customSerializer = this.FindCustomSerializer( accessor.Type);195 ICustomSerializer customSerializer = this.FindCustomSerializer(value.GetType()); 186 196 if (customSerializer != null) { 187 197 foreach (object obj in customSerializer.Serialize(value)) { … … 200 210 yield return new EndToken(accessor, id); 201 211 } 202 } 212 } 203 213 204 214 private ICustomSerializer FindCustomSerializer(Type type) { … … 209 219 return null; 210 220 } 221 } 222 223 public class DeSerializer { 224 225 class AccessibleObject { 226 public object obj; 227 public Dictionary<string, DataMemberAccessor> accessorDict; 228 public List<object> customValues; 229 public AccessibleObject(object obj, Dictionary<string, DataMemberAccessor> accessorDict) { 230 this.obj = obj; 231 this.accessorDict = new Dictionary<string, DataMemberAccessor>(); 232 this.customValues = new List<object>(); 233 foreach (KeyValuePair<string, DataMemberAccessor> pair in accessorDict) { 234 this.accessorDict.Add( 235 pair.Value.Name, 236 pair.Value); 237 } 238 } 239 public void SetValue(string name, object value) { 240 if (name == "") { 241 customValues.Add(value); 242 } else { 243 accessorDict[name].Set(value); 244 } 245 } 246 public void SetAllDefaultValues() { 247 } 248 } 249 250 private delegate void Handler(IParseToken token); 251 252 private Dictionary<int, object> id2obj; 253 private Dictionary<Type, Handler> handlers; 254 private Stack<AccessibleObject> compositeStack; 255 256 private Dictionary<Type, IPrimitiveSerializer> primitiveSerializers; 257 private List<ICustomSerializer> customSerializers; 258 259 public DeSerializer() { 260 id2obj = new Dictionary<int, object>(); 261 compositeStack = new Stack<AccessibleObject>(); 262 handlers = new Dictionary<Type, Handler>(); 263 handlers.Add(typeof(CompositeStart), new Handler(CompositeStartHandler)); 264 handlers.Add(typeof(CompositeEnd), new Handler(CompositeEndHandler)); 265 handlers.Add(typeof(Primitive), new Handler(PrimitiveHandler)); 266 handlers.Add(typeof(Reference), new Handler(ReferenceHandler)); 267 handlers.Add(typeof(Null), new Handler(NullHandler)); 268 // TODO: make this configurable 269 primitiveSerializers = new Dictionary<Type, IPrimitiveSerializer>(); 270 primitiveSerializers.Add(typeof(int), new Int2XMLSerializer()); 271 primitiveSerializers.Add(typeof(string), new String2XMLSerializer()); 272 customSerializers = new List<ICustomSerializer>(); 273 customSerializers.Add(new ArraySerializer()); 274 customSerializers.Add(new EnumerableSerializer()); 275 } 276 public object DeSerialize(IEnumerable<IParseToken> tokens) { 277 foreach (IParseToken token in tokens) { 278 handlers[token.GetType()].Invoke(token); 279 } 280 return compositeStack.Pop().obj; 281 } 282 private void CompositeStartHandler(IParseToken token) { 283 CompositeStart start = (CompositeStart)token; 284 object instance = null; 285 if (this.FindCustomSerializer(start.Type) != null) { 286 instance = null; 287 compositeStack.Push(new AccessibleObject(null, new Dictionary<string, DataMemberAccessor>())); 288 id2obj.Add(start.Id, null); 289 // TODO: add warning proxy 290 } else { 291 instance = Activator.CreateInstance(start.Type); 292 Dictionary<string, DataMemberAccessor> accessorDict = 293 StorableAttribute.GetAutostorableAccessors(instance); 294 compositeStack.Push(new AccessibleObject(instance, accessorDict)); 295 id2obj.Add(start.Id, instance); 296 } 297 } 298 private void CompositeEndHandler(IParseToken token) { 299 CompositeEnd end = (CompositeEnd)token; 300 AccessibleObject accessibleObject = compositeStack.Pop(); 301 ICustomSerializer customSerializer = this.FindCustomSerializer(end.Type); 302 if (customSerializer != null) { 303 this.SetValue(end.Name, 304 customSerializer.DeSerialize(accessibleObject.customValues, end.Type)); 305 } else { 306 this.SetValue(end.Name, accessibleObject.obj); 307 } 308 } 309 private ICustomSerializer FindCustomSerializer(Type type) { 310 foreach (ICustomSerializer serializer in customSerializers) { 311 if (serializer.CanSerialize(type)) 312 return serializer; 313 } 314 return null; 315 } 316 private void PrimitiveHandler(IParseToken token) { 317 Primitive primitive = (Primitive)token; 318 object value = primitiveSerializers[primitive.Type].DeSerialize(primitive.SerializedValue); 319 this.SetValue(primitive.Name, value); 320 } 321 private void ReferenceHandler(IParseToken token) { 322 Reference reference = (Reference)token; 323 this.SetValue(reference.Name, this.id2obj[reference.Id]); 324 } 325 private void NullHandler(IParseToken token) { 326 Null nil = (Null)token; 327 this.SetValue(nil.Name, null); 328 } 329 private void SetValue(string name, object value) { 330 if (compositeStack.Count == 0) { 331 compositeStack.Push(new AccessibleObject(value, new Dictionary<string,DataMemberAccessor>())); 332 } else { 333 compositeStack.Peek().SetValue(name, value); 334 } 335 } 211 336 } 212 337 … … 271 396 272 397 } 273 398 399 #region parsing tokens 400 public interface IParseToken { } 401 public class CompositeStart : IParseToken { 402 public string Name; 403 public Type Type; 404 public int Id; 405 public CompositeStart(string name, Type type, int id) { 406 this.Name = name; 407 this.Type = type; 408 this.Id = id; 409 } 410 } 411 public class CompositeEnd : IParseToken { 412 public string Name; 413 public Type Type; 414 public int Id; 415 public CompositeEnd(string name, Type type, int id) { 416 this.Name = name; 417 this.Type = type; 418 this.Id = id; 419 } 420 } 421 public class Primitive : IParseToken { 422 public string Name; 423 public Type Type; 424 public string SerializedValue; 425 public Primitive(string name, Type type, string serilaizedValue) { 426 this.Name = name; 427 this.Type = type; 428 this.SerializedValue = serilaizedValue; 429 } 430 } 431 public class Reference : IParseToken { 432 public string Name; 433 public int Id; 434 public Reference(string name, int id) { 435 this.Name = name; 436 this.Id = id; 437 } 438 } 439 public class Null : IParseToken { 440 public string Name; 441 public Null(string name) { 442 this.Name = name; 443 } 444 } 445 #endregion 446 447 448 public class XmlParser : IEnumerable<IParseToken> { 449 450 private XmlReader reader; 451 private delegate IEnumerator<IParseToken> Handler(); 452 private Dictionary<string, Handler> handlers; 453 454 public XmlParser(StreamReader input) { 455 XmlReaderSettings settings = new XmlReaderSettings(); 456 settings.ConformanceLevel = ConformanceLevel.Document; 457 settings.IgnoreWhitespace = true; 458 settings.IgnoreComments = true; 459 this.reader = XmlReader.Create(input, settings); 460 this.handlers = new Dictionary<string, Handler>(); 461 this.handlers.Add("PRIMITIVE", new Handler(ParsePrimitive)); 462 this.handlers.Add("COMPOSITE", new Handler(ParseComposite)); 463 this.handlers.Add("REFERENCE", new Handler(ParseReference)); 464 this.handlers.Add("NULL", new Handler(ParseNull)); 465 } 466 public IEnumerator<IParseToken> GetEnumerator() { 467 while (this.reader.Read()) { 468 if (!reader.IsStartElement()) { 469 break; 470 } 471 IEnumerator<IParseToken> iterator; 472 try { 473 iterator = handlers[reader.Name].Invoke(); 474 } catch (KeyNotFoundException) { 475 throw new InvalidOperationException(String.Format( 476 "No handler for XML tag \"{0}\" installed", 477 reader.Name)); 478 } 479 while (iterator.MoveNext()) { 480 yield return iterator.Current; 481 } 482 } 483 } 484 private IEnumerator<IParseToken> ParsePrimitive() { 485 yield return new Primitive( 486 this.reader.GetAttribute("name"), 487 Type.GetType(this.reader.GetAttribute("type")), 488 this.reader.ReadString()); 489 } 490 private IEnumerator<IParseToken> ParseComposite() { 491 string name = this.reader.GetAttribute("name"); 492 Type type = Type.GetType(this.reader.GetAttribute("type")); 493 int id = int.Parse(this.reader.GetAttribute("id")); 494 yield return new CompositeStart(name, type, id); 495 IEnumerator<IParseToken> iterator = this.GetEnumerator(); 496 while (iterator.MoveNext()) 497 yield return iterator.Current; 498 yield return new CompositeEnd(name, type, id); 499 } 500 private IEnumerator<IParseToken> ParseReference() { 501 yield return new Reference( 502 this.reader.GetAttribute("name"), 503 int.Parse(this.reader.GetAttribute("ref"))); 504 } 505 private IEnumerator<IParseToken> ParseNull() { 506 yield return new Null(this.reader.GetAttribute("name")); 507 } 508 IEnumerator IEnumerable.GetEnumerator() { 509 return this.GetEnumerator(); 510 } 511 } 274 512 }
Note: See TracChangeset
for help on using the changeset viewer.