source: trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/Number2StringSerializer.cs @ 9456

Last change on this file since 9456 was 9456, checked in by swagner, 6 years ago

Updated copyright year and added some missing license headers (#1889)

File size: 7.3 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Collections.Generic;
24using System.Linq;
25using HeuristicLab.Persistence.Auxiliary;
26using HeuristicLab.Persistence.Core;
27using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
28using HeuristicLab.Persistence.Default.Xml;
29using HeuristicLab.Persistence.Default.Xml.Primitive;
30using HeuristicLab.Persistence.Interfaces;
31
32namespace HeuristicLab.Persistence.Default.CompositeSerializers {
33
34  /// <summary>
35  /// Serializes a primitive number type using the ToString() method and an
36  /// approriate precision and parses back the generated string using
37  /// the number type's Parse() method.
38  ///
39  /// This serializer has Priorty below zero and is disabled by default
40  /// but can be useful in generating custom serializers.
41  /// </summary>
42  [StorableClass]
43  public sealed class Number2StringSerializer : ICompositeSerializer {
44
45    [StorableConstructor]
46    private Number2StringSerializer(bool deserializing) { }
47    public Number2StringSerializer() { }
48
49    private static readonly Dictionary<Type, IPrimitiveSerializer> numberSerializerMap;
50    private static readonly List<IPrimitiveSerializer> numberSerializers = new List<IPrimitiveSerializer> {
51      new Bool2XmlSerializer(),
52      new Byte2XmlSerializer(),
53      new SByte2XmlSerializer(),
54      new Short2XmlSerializer(),
55      new UShort2XmlSerializer(),
56      new Int2XmlSerializer(),
57      new UInt2XmlSerializer(),
58      new Long2XmlSerializer(),
59      new ULong2XmlSerializer(),
60      new Float2XmlSerializer(),
61      new Double2XmlSerializer(),
62      new Decimal2XmlSerializer(),
63    };
64
65    static Number2StringSerializer() {
66      numberSerializerMap = new Dictionary<Type, IPrimitiveSerializer>();
67      foreach (var s in numberSerializers) {
68        numberSerializerMap[s.SourceType] = s;
69      }
70    }
71
72    /// <summary>
73    /// Determines for every type whether the composite serializer is applicable.
74    /// </summary>
75    /// <param name="type">The type.</param>
76    /// <returns>
77    ///   <c>true</c> if this instance can serialize the specified type; otherwise, <c>false</c>.
78    /// </returns>
79    public bool CanSerialize(Type type) {
80      return numberSerializerMap.ContainsKey(type);
81    }
82
83    /// <summary>
84    /// Give a reason if possibly why the given type cannot be serialized by this
85    /// ICompositeSerializer.
86    /// </summary>
87    /// <param name="type">The type.</param>
88    /// <returns>
89    /// A string justifying why type cannot be serialized.
90    /// </returns>
91    public string JustifyRejection(Type type) {
92      return string.Format("not a number type (one of {0})",
93        string.Join(", ", numberSerializers.Select(n => n.SourceType.Name).ToArray()));
94    }
95
96    /// <summary>
97    /// Formats the specified obj.
98    /// </summary>
99    /// <param name="obj">The obj.</param>
100    /// <returns></returns>
101    public string Format(object obj) {
102      return ((XmlString)numberSerializerMap[obj.GetType()].Format(obj)).Data;
103    }
104
105    /// <summary>
106    /// Parses the specified string value.
107    /// </summary>
108    /// <param name="stringValue">The string value.</param>
109    /// <param name="type">The type.</param>
110    /// <returns></returns>
111    public object Parse(string stringValue, Type type) {
112      try {
113        return numberSerializerMap[type].Parse(new XmlString(stringValue));
114      }
115      catch (FormatException e) {
116        throw new PersistenceException("Invalid element data during number parsing.", e);
117      }
118      catch (OverflowException e) {
119        throw new PersistenceException("Overflow during number parsing.", e);
120      }
121    }
122
123
124
125    /// <summary>
126    /// Defines the Priorty of this composite serializer. Higher number means
127    /// higher prioriy. Negative numbers are fallback serializers that are
128    /// disabled by default.
129    /// All default generic composite serializers have priority 100. Specializations
130    /// have priority 200 so they will  be tried first. Priorities are
131    /// only considered for default configurations.
132    /// </summary>
133    /// <value></value>
134    public int Priority {
135      get { return -100; }
136    }
137
138    /// <summary>
139    /// Generate MetaInfo necessary for instance creation. (e.g. dimensions
140    /// necessary for array creation.
141    /// </summary>
142    /// <param name="obj">An object.</param>
143    /// <returns>An enumerable of <see cref="Tag"/>s.</returns>
144    public IEnumerable<Tag> CreateMetaInfo(object obj) {
145      yield return new Tag(Format(obj));
146    }
147
148    /// <summary>
149    /// Decompose an object into <see cref="Tag"/>s, the tag name can be null,
150    /// the order in which elements are generated is guaranteed to be
151    /// the same as they will be supplied to the Populate method.
152    /// </summary>
153    /// <param name="obj">An object.</param>
154    /// <returns>An enumerable of <see cref="Tag"/>s.</returns>
155    public IEnumerable<Tag> Decompose(object obj) {
156      // numbers are composed just of meta info
157      return new Tag[] { };
158    }
159
160    /// <summary>
161    /// Create an instance of the object using the provided meta information.
162    /// </summary>
163    /// <param name="type">A type.</param>
164    /// <param name="metaInfo">The meta information.</param>
165    /// <returns>A fresh instance of the provided type.</returns>
166    public object CreateInstance(Type type, IEnumerable<Tag> metaInfo) {
167      var it = metaInfo.GetEnumerator();
168      try {
169        it.MoveNext();
170        return Parse((string)it.Current.Value, type);
171      }
172      catch (InvalidOperationException e) {
173        throw new PersistenceException(
174          String.Format("Insufficient meta information to reconstruct number of type {0}.",
175          type.VersionInvariantName()), e);
176      }
177      catch (InvalidCastException e) {
178        throw new PersistenceException("Invalid meta information element type", e);
179      }
180    }
181
182    /// <summary>
183    /// Fills an object with values from the previously generated <see cref="Tag"/>s
184    /// in Decompose. The order in which the values are supplied is
185    /// the same as they where generated. <see cref="Tag"/> names might be null.
186    /// </summary>
187    /// <param name="instance">An empty object instance.</param>
188    /// <param name="tags">The tags.</param>
189    /// <param name="type">The type.</param>
190    public void Populate(object instance, IEnumerable<Tag> tags, Type type) {
191      // numbers are composed just of meta info, no need to populate
192    }
193  }
194}
Note: See TracBrowser for help on using the repository browser.