Changeset 1330


Ignore:
Timestamp:
03/12/09 12:19:32 (12 years ago)
Author:
epitzer
Message:

More compact XML Formatting (no empty names, referencable primitives, compact arrays & lists). (#506)

Location:
branches/New Persistence Exploration/Persistence/Persistence
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • branches/New Persistence Exploration/Persistence/Persistence/DeSerializer.cs

    r1329 r1330  
    135135      Primitive primitive = (Primitive)token;
    136136      object value = primitiveSerializers[primitive.Type].DeSerialize(primitive.SerializedValue);
    137       this.SetValue(primitive.Name, value);
     137      if ( ! value.GetType().IsValueType )
     138        id2obj[(int)primitive.Id] = value;
     139      SetValue(primitive.Name, value);
    138140    }
    139141    private void ReferenceHandler(IParseToken token) {
  • branches/New Persistence Exploration/Persistence/Persistence/PrimitiveSerializers.cs

    r1315 r1330  
    11using System;
     2using System.Collections;
     3using System.Collections.Generic;
    24using System.Text;
    35using System.Globalization;
     
    2022      StringBuilder sb = new StringBuilder();
    2123      foreach (string s in ((string)o).Split(
    22         new string[] { "<![CDATA[", "]]>" },
     24        new[] { "<![CDATA[", "]]>" },
    2325        StringSplitOptions.RemoveEmptyEntries)) {
    2426        sb.Append(s);
     
    2729    }
    2830  }
     31
    2932  public class Int2XMLSerializer : IPrimitiveSerializer {
    3033    public Type Type { get { return typeof(int); } }
     
    3639    }
    3740  }
     41
    3842  public class Double2XmlSerializer : IPrimitiveSerializer {   
    3943    public Type Type { get { return typeof(double); } }       
     
    4549    }
    4650  }
     51
    4752  public class Boolean2XmlSerializer : IPrimitiveSerializer {   
    4853    public Type Type { get { return typeof(bool); } }   
     
    5459    }
    5560  }
     61
    5662  public class DateTime2XmlSerializer : IPrimitiveSerializer {   
    5763    public Type Type { get { return typeof(DateTime); } }     
     
    6369    }
    6470  }
     71
     72  public abstract class NumberArray2XmlSerializer : IPrimitiveSerializer {
     73    public abstract Type Type { get; }   
     74    protected virtual string Separator { get { return ";"; } }
     75    protected abstract string formatValue(object o);
     76    protected abstract object parseValue(string o);
     77    public object Serialize(object obj) {     
     78      Array a = (Array)obj;
     79      StringBuilder sb = new StringBuilder();
     80      sb.Append(a.Rank);     
     81      for (int i = 0; i < a.Rank; i++) {
     82        sb.Append(Separator);
     83        sb.Append(a.GetLength(i));
     84      }
     85      foreach (object o in a) {
     86        sb.Append(Separator);
     87        sb.Append(formatValue(o));
     88      }
     89      return sb.ToString();
     90    }
     91    public object DeSerialize(object o) {
     92      IEnumerator values =
     93        ((string) o)
     94        .Split(new[] {Separator},
     95        StringSplitOptions.RemoveEmptyEntries).GetEnumerator();
     96      values.MoveNext();
     97      int rank = int.Parse((string)values.Current);
     98      int[] lengths = new int[rank];
     99      for ( int i = 0; i<rank; i++ ) {
     100        values.MoveNext();
     101        lengths[i] = int.Parse((string)values.Current);
     102      }
     103      Array a = Array.CreateInstance(this.Type.GetElementType(), lengths);
     104      int[] positions = new int[rank];
     105      while ( values.MoveNext() ) {
     106        a.SetValue(parseValue((string)values.Current), positions);
     107        positions[0] += 1;
     108        for ( int i = 0; i<rank-1; i++) {
     109          if (positions[i] >= lengths[i]) {
     110            positions[i] = 0;
     111            positions[i + 1] += 1;
     112          } else {
     113            break;
     114          }
     115        }
     116      }
     117      return a;
     118    }
     119  }
     120  public class IntArray2XmlSerializer : NumberArray2XmlSerializer {
     121    public override Type Type { get { return typeof(int[]); } }
     122    protected override string formatValue(object o) { return o.ToString(); }
     123    protected override object parseValue(string o) { return int.Parse(o); }
     124  }
     125  public class Int2DArray2XmlSerializer : IntArray2XmlSerializer {
     126    public override Type Type { get { return typeof (int[,]); } }
     127  }
     128  public class Int3DArray2XmlSerializer : IntArray2XmlSerializer {
     129    public override Type Type { get { return typeof(int[,,]); } }
     130  }
     131  public class DoubleArray2XmlSerializer : NumberArray2XmlSerializer {
     132    public override Type Type { get { return typeof(double[]); } }
     133    protected override string formatValue(object o) { return ((double) o).ToString("r"); }
     134    protected override object parseValue(string o) { return double.Parse(o); }   
     135  }
     136  public class Double2DArray2XmlSerializer : DoubleArray2XmlSerializer {
     137    public override Type Type { get { return typeof(double[,]); } }   
     138  }
     139  public class Double3DArray2XmlSerializer : DoubleArray2XmlSerializer {
     140    public override Type Type { get { return typeof(double[,,]); } }
     141  }
     142
     143  public abstract class NumberEnumeration2XmlSerializer : IPrimitiveSerializer {
     144    public abstract Type Type { get; }
     145    protected virtual string Separator { get { return ";"; } }
     146    protected abstract void Add(IEnumerable enumeration, object o);
     147    protected abstract object Instantiate();
     148    protected abstract string formatValue(object o);
     149    protected abstract object parseValue(string o);   
     150    public object Serialize(object o) {
     151      StringBuilder sb = new StringBuilder();
     152      foreach (var value in (IEnumerable) o) {       
     153        sb.Append(formatValue(value));
     154        sb.Append(Separator);
     155      }
     156      return sb.ToString();
     157    } 
     158    public object DeSerialize(object o) {
     159      IEnumerable enumeration = (IEnumerable) Instantiate();       
     160      string[] values = ((string) o).Split(new[] {Separator}, StringSplitOptions.RemoveEmptyEntries);
     161      foreach ( var value in values ) {
     162        Add(enumeration, parseValue(value));
     163      }
     164      return enumeration;
     165    }
     166  }
     167  public class IntList2XmlSerializer : NumberEnumeration2XmlSerializer {
     168    public override Type Type { get { return typeof(List<int>); } }
     169    protected override void Add(IEnumerable enumeration, object o) { ((List<int>)enumeration).Add((int)o); }
     170    protected override object Instantiate() { return new List<int>(); }
     171    protected override string formatValue(object o) { return o.ToString(); }
     172    protected override object parseValue(string o) { return int.Parse(o); }
     173  } 
    65174}
  • branches/New Persistence Exploration/Persistence/Persistence/Serializer.cs

    r1323 r1330  
    5252      if (value == null) {
    5353        yield return new NullReferenceToken(accessor.Name);
    54       } else if (primitiveSerializers.ContainsKey(value.GetType())) {
    55         yield return new PrimitiveToken(accessor, primitiveSerializers[value.GetType()].Serialize(value));
    5654      } else if (obj2id.ContainsKey(value)) {
    5755        yield return new ReferenceToken(accessor.Name, obj2id[value]);
     56      } else if (primitiveSerializers.ContainsKey(value.GetType())) {
     57        int? id = null;
     58        if ( ! value.GetType().IsValueType ) {
     59          id = obj2id.Count;
     60          obj2id.Add(value, (int)id);
     61        }
     62        yield return new PrimitiveToken(
     63          accessor,
     64          primitiveSerializers[value.GetType()].Serialize(value),
     65          id);     
    5866      } else {
    5967        int id = obj2id.Count;
  • branches/New Persistence Exploration/Persistence/Persistence/StorableAttribute.cs

    r1324 r1330  
    232232        if (!propertyInfo.CanRead || !propertyInfo.CanWrite) {
    233233          throw new NotSupportedException(
    234             "Storable properties must implement both a Get and a Set accessor. ");
     234            "Storable properties must implement both a Get and a Set Accessor. ");
    235235        }
    236236        getter = () => propertyInfo.GetValue(obj, null);
     
    255255    }
    256256
    257     public DataMemberAccessor(object o) {
    258       Name = "";
     257    public DataMemberAccessor(object o) {     
    259258      Type = o.GetType();
    260259      DefaultValue = null;
  • branches/New Persistence Exploration/Persistence/Persistence/Tokens.cs

    r1280 r1330  
    77  }
    88  public class BeginToken : ISerializationToken {
    9     public DataMemberAccessor Accessor;
    10     public int Id;
     9    public readonly DataMemberAccessor Accessor;
     10    public readonly int Id;
    1111    public BeginToken(DataMemberAccessor accessor, int id) {
    12       this.Accessor = accessor;
    13       this.Id = id;
     12      Accessor = accessor;
     13      Id = id;
    1414    }
    1515  }
    1616  public class EndToken : ISerializationToken {
    17     public DataMemberAccessor Accessor;
    18     public int Id;
     17    public readonly DataMemberAccessor Accessor;
     18    public readonly int Id;
    1919    public EndToken(DataMemberAccessor accessor, int id) {
    20       this.Accessor = accessor;
    21       this.Id = id;
     20      Accessor = accessor;
     21      Id = id;
    2222    }
    2323  }
    2424  public class PrimitiveToken : ISerializationToken {
    25     public DataMemberAccessor accessor;
    26     public object Data;
    27     public PrimitiveToken(DataMemberAccessor accessor, object data) {
    28       this.accessor = accessor;
    29       this.Data = data;
     25    public readonly DataMemberAccessor Accessor;
     26    public readonly object Data;
     27    public readonly int? Id;
     28    public PrimitiveToken(DataMemberAccessor accessor, object data, int? id) {
     29      Accessor = accessor;
     30      Data = data;
     31      Id = id;
    3032    }
    3133  }
    3234  public class ReferenceToken : ISerializationToken {
    33     public string Name;
    34     public int Id;
     35    public readonly string Name;
     36    public readonly int Id;
    3537    public ReferenceToken(string name, int id) {
    36       this.Name = name;
    37       this.Id = id;
     38      Name = name;
     39      Id = id;
    3840    }
    3941  }
    4042  public class NullReferenceToken : ISerializationToken {
    41     public string Name;
     43    public readonly string Name;
    4244    public NullReferenceToken(string name) {
    43       this.Name = name;
     45      Name = name;
    4446    }
    4547  }
     
    5153
    5254  public class CompositeStart : IParseToken {
    53     public string Name;
    54     public Type Type;
    55     public int Id;
     55    public readonly string Name;
     56    public readonly Type Type;
     57    public readonly int Id;
    5658    public CompositeStart(string name, Type type, int id) {
    57       this.Name = name;
    58       this.Type = type;
    59       this.Id = id;
     59      Name = name;
     60      Type = type;
     61      Id = id;
    6062    }
    6163  }
    6264  public class CompositeEnd : IParseToken {
    63     public string Name;
    64     public Type Type;
    65     public int Id;
     65    public readonly string Name;
     66    public readonly Type Type;
     67    public readonly int Id;
    6668    public CompositeEnd(string name, Type type, int id) {
    67       this.Name = name;
    68       this.Type = type;
    69       this.Id = id;
     69      Name = name;
     70      Type = type;
     71      Id = id;
    7072    }
    7173  }
    7274  public class Primitive : IParseToken {
    73     public string Name;
    74     public Type Type;
    75     public string SerializedValue;
    76     public Primitive(string name, Type type, string serilaizedValue) {
    77       this.Name = name;
    78       this.Type = type;
    79       this.SerializedValue = serilaizedValue;
     75    public readonly string Name;
     76    public readonly Type Type;
     77    public readonly string SerializedValue;
     78    public readonly int? Id;
     79    public Primitive(string name, Type type, string serilaizedValue, int? id) {
     80      Name = name;
     81      Type = type;
     82      SerializedValue = serilaizedValue;
     83      Id = id;
    8084    }
    8185  }
    8286  public class Reference : IParseToken {
    83     public string Name;
    84     public int Id;
     87    public readonly string Name;
     88    public readonly int Id;
    8589    public Reference(string name, int id) {
    86       this.Name = name;
    87       this.Id = id;
     90      Name = name;
     91      Id = id;
    8892    }
    8993  }
    9094  public class Null : IParseToken {
    91     public string Name;
     95    public readonly string Name;
    9296    public Null(string name) {
    93       this.Name = name;
     97      Name = name;
    9498    }
    9599  }
  • branches/New Persistence Exploration/Persistence/Persistence/XmlFormatter.cs

    r1323 r1330  
    11using System.Collections.Generic;
    22using System;
     3using System.Xml;
     4using System.Text;
    35namespace Persistence {
    46  public class XmlFormatter {
     
    1315                       {typeof (BeginToken), FormatBegin},
    1416                       {typeof (EndToken), FormatEnd},
    15                        {typeof (PrimitiveToken), FormatData},
     17                       {typeof (PrimitiveToken), FormatPrimitive},
    1618                       {typeof (ReferenceToken), FormatReference},
    1719                       {typeof (NullReferenceToken), FormatNullReference}
    1820                     };
    1921      depth = 0;
     22    }
     23
     24    private enum NodeType { Start, End, Inline } ;
     25
     26    private static string FormatNode(string name, Dictionary<string, string> attributes, NodeType type) {
     27      StringBuilder sb = new StringBuilder();
     28      sb.Append('<');
     29      if (type == NodeType.End)
     30        sb.Append('/');
     31      sb.Append(name);     
     32      foreach (var attribute in attributes) {
     33        sb.Append(' ');
     34        sb.Append(attribute.Key);
     35        sb.Append("=\"");
     36        sb.Append(attribute.Value);
     37        sb.Append('"');
     38      }
     39      if (type == NodeType.Inline)
     40        sb.Append('/');
     41      sb.Append(">");
     42      return sb.ToString();     
    2043    }
    2144
     
    3053    private string FormatBegin(ISerializationToken token) {
    3154      BeginToken beginToken = (BeginToken)token;
    32       string result =
    33         String.Format("{0}<COMPOSITE name=\"{1}\" type=\"{2}\" id=\"{3}\">\n",
    34           Prefix, beginToken.Accessor.Name, beginToken.Accessor.Get().GetType(), beginToken.Id);
     55      string result = Prefix +
     56                      FormatNode("COMPOSITE",
     57                                 new Dictionary<string, string>
     58                                   {
     59                                     {"name", beginToken.Accessor.Name},
     60                                     {"type", beginToken.Accessor.Get().GetType().ToString()},
     61                                     {"id", beginToken.Id.ToString()}
     62                                   }, NodeType.Start) + "\n";
    3563      depth += 1;
    3664      return result;
    3765    }
    3866
    39     private string FormatEnd(ISerializationToken token) {
     67    private string FormatEnd(ISerializationToken token) {     
    4068      depth -= 1;
    4169      return Prefix + "</COMPOSITE>\n";
    4270    }
    4371
    44     private string FormatData(ISerializationToken token) {
     72    private string FormatPrimitive(ISerializationToken token) {
    4573      PrimitiveToken dataToken = (PrimitiveToken)token;
    46       return String.Format("{0}<PRIMITIVE name=\"{1}\" type=\"{2}\">{3}</PRIMITIVE>\n",
    47         Prefix, dataToken.accessor.Name, dataToken.accessor.Get().GetType(), dataToken.Data);
     74      Dictionary<string, string> attributes =
     75        new Dictionary<string, string> {
     76            {"type", dataToken.Accessor.Get().GetType().ToString()}};
     77      if ( dataToken.Accessor.Name != "" )
     78        attributes.Add("name", dataToken.Accessor.Name);
     79      if ( dataToken.Id != null )
     80        attributes.Add("id", dataToken.Id.ToString());
     81      return Prefix +
     82        FormatNode("PRIMITIVE", attributes, NodeType.Start) +
     83        dataToken.Data + "</PRIMITIVE>\n";     
    4884    }
    4985
    5086    private string FormatReference(ISerializationToken token) {
    51       ReferenceToken refToken = (ReferenceToken)token;
    52       return String.Format("{0}<REFERENCE name=\"{1}\" ref=\"{2}\"/>\n",
    53         Prefix, refToken.Name, refToken.Id);
     87      ReferenceToken refToken = (ReferenceToken) token;
     88      Dictionary<string, string> attributes =
     89        new Dictionary<string, string> {{"ref", refToken.Id.ToString()}};
     90      if ( refToken.Name != null )
     91        attributes.Add("name", refToken.Name);
     92      return Prefix + FormatNode("REFERENCE", attributes, NodeType.Inline) + "\n"; 
    5493    }
    5594
    5695    private string FormatNullReference(ISerializationToken token) {
    5796      NullReferenceToken nullRefToken = (NullReferenceToken)token;
    58       return String.Format("{0}<NULL name=\"{1}\"/>\n",
    59         Prefix, nullRefToken.Name);
     97      Dictionary<string, string> attributes = new Dictionary<string, string>();
     98      if (nullRefToken.Name != null)
     99        attributes.Add("name", nullRefToken.Name);
     100      return Prefix + FormatNode("NULL", attributes, NodeType.Inline) + "\n";
    60101    }
    61102  }
  • branches/New Persistence Exploration/Persistence/Persistence/XmlParser.cs

    r1280 r1330  
    88  public class XmlParser : IEnumerable<IParseToken> {
    99
    10     private XmlReader reader;
     10    private readonly XmlReader reader;
    1111    private delegate IEnumerator<IParseToken> Handler();
    12     private Dictionary<string, Handler> handlers;
     12    private readonly Dictionary<string, Handler> handlers;
    1313
    14     public XmlParser(StreamReader input) {
    15       XmlReaderSettings settings = new XmlReaderSettings();
    16       settings.ConformanceLevel = ConformanceLevel.Document;
    17       settings.IgnoreWhitespace = true;
    18       settings.IgnoreComments = true;
    19       this.reader = XmlReader.Create(input, settings);
    20       this.handlers = new Dictionary<string, Handler>();
    21       this.handlers.Add("PRIMITIVE", new Handler(ParsePrimitive));
    22       this.handlers.Add("COMPOSITE", new Handler(ParseComposite));
    23       this.handlers.Add("REFERENCE", new Handler(ParseReference));
    24       this.handlers.Add("NULL", new Handler(ParseNull));
     14    public XmlParser(TextReader input) {
     15      XmlReaderSettings settings = new XmlReaderSettings {
     16                                       ConformanceLevel = ConformanceLevel.Document,
     17                                       IgnoreWhitespace = true,
     18                                       IgnoreComments = true
     19                                     };
     20      reader = XmlReader.Create(input, settings);
     21      handlers = new Dictionary<string, Handler> {
     22                     {"PRIMITIVE", ParsePrimitive},
     23                     {"COMPOSITE", ParseComposite},
     24                     {"REFERENCE", ParseReference},
     25                     {"NULL", ParseNull}
     26                   };
    2527    }
    2628    public IEnumerator<IParseToken> GetEnumerator() {
    27       while (this.reader.Read()) {
     29      while (reader.Read()) {
    2830        if (!reader.IsStartElement()) {
    2931          break;
     
    4446    }
    4547    private IEnumerator<IParseToken> ParsePrimitive() {
     48      int? id = null;
     49      string idString = reader.GetAttribute("id");
     50      if (idString != null)
     51        id = int.Parse(idString);
    4652      yield return new Primitive(
    47         this.reader.GetAttribute("name"),
    48         Type.GetType(this.reader.GetAttribute("type")),
    49         this.reader.ReadString());
     53        reader.GetAttribute("name"),
     54        Type.GetType(reader.GetAttribute("type")),
     55        reader.ReadString(),
     56        id);
    5057    }
    5158    private IEnumerator<IParseToken> ParseComposite() {
    52       string name = this.reader.GetAttribute("name");
    53       Type type = Type.GetType(this.reader.GetAttribute("type"));
    54       int id = int.Parse(this.reader.GetAttribute("id"));
     59      string name = reader.GetAttribute("name");
     60      Type type = Type.GetType(reader.GetAttribute("type"));
     61      int id = int.Parse(reader.GetAttribute("id"));
    5562      yield return new CompositeStart(name, type, id);
    56       IEnumerator<IParseToken> iterator = this.GetEnumerator();
     63      IEnumerator<IParseToken> iterator = GetEnumerator();
    5764      while (iterator.MoveNext())
    5865        yield return iterator.Current;
     
    6168    private IEnumerator<IParseToken> ParseReference() {
    6269      yield return new Reference(
    63         this.reader.GetAttribute("name"),
    64         int.Parse(this.reader.GetAttribute("ref")));
     70        reader.GetAttribute("name"),
     71        int.Parse(reader.GetAttribute("ref")));
    6572    }
    6673    private IEnumerator<IParseToken> ParseNull() {
    67       yield return new Null(this.reader.GetAttribute("name"));
     74      yield return new Null(reader.GetAttribute("name"));
    6875    }
    6976    IEnumerator IEnumerable.GetEnumerator() {
    70       return this.GetEnumerator();
     77      return GetEnumerator();
    7178    }
    7279  } 
Note: See TracChangeset for help on using the changeset viewer.