Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/CompactNumberArray2StringSerializer.cs @ 3913

Last change on this file since 3913 was 3742, checked in by gkronber, 15 years ago

Fixed GPL license headers and deleted files which are not referenced by projects. #893

File size: 5.0 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2010 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 HeuristicLab.Persistence.Interfaces;
24using HeuristicLab.Persistence.Core;
25using System.Collections.Generic;
26using System.Reflection;
27using System.Globalization;
28using System.Text;
29using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
30
31namespace HeuristicLab.Persistence.Default.CompositeSerializers {
32
33  [StorableClass]
34  internal sealed class CompactNumberArray2StringSerializer : ICompositeSerializer {
35
36    public int Priority {
37      get { return 200; }
38    }
39
40    private static readonly Number2StringSerializer numberConverter =
41      new Number2StringSerializer();
42
43    public bool CanSerialize(Type type) {
44      return
45        (type.IsArray || type == typeof(Array)) &&
46        numberConverter.CanSerialize(type.GetElementType());
47    }
48
49    public string JustifyRejection(Type type) {
50      if (!type.IsArray && type != typeof(Array))
51        return "not an array";
52      return string.Format("number converter cannot serialize elements: " +
53        numberConverter.JustifyRejection(type.GetElementType()));
54    }
55
56    public IEnumerable<Tag> CreateMetaInfo(object obj) {
57      Array a = (Array)obj;
58      int[] lengths = new int[a.Rank];
59      int[] lowerBounds = new int[a.Rank];
60      StringBuilder sb = new StringBuilder();
61      sb.Append(a.Rank).Append(';');
62      for (int i = 0; i < a.Rank; i++) {
63        sb.Append(a.GetLength(i)).Append(';');
64        lengths[i] = a.GetLength(i);
65      }
66      for (int i = 0; i < a.Rank; i++) {
67        sb.Append(a.GetLowerBound(i)).Append(';');
68        lowerBounds[i] = a.GetLowerBound(i);
69      }
70      int[] positions = (int[])lowerBounds.Clone();
71      while (positions[a.Rank - 1] < lengths[a.Rank - 1] + lowerBounds[a.Rank - 1]) {
72        sb.Append(numberConverter.Format(a.GetValue(positions))).Append(';');
73        positions[0] += 1;
74        for (int i = 0; i < a.Rank - 1; i++) {
75          if (positions[i] >= lengths[i] + lowerBounds[i]) {
76            positions[i] = lowerBounds[i];
77            positions[i + 1] += 1;
78          } else {
79            break;
80          }
81        }
82      }
83      yield return new Tag("compact array", sb.ToString());
84    }
85
86    public IEnumerable<Tag> Decompose(object obj) {
87      return new Tag[] { };
88    }
89
90    public object CreateInstance(Type type, IEnumerable<Tag> metaInfo) {
91      try {
92        var tagIter = metaInfo.GetEnumerator();
93        tagIter.MoveNext();
94        var valueIter = ((string)tagIter.Current.Value)
95          .Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries)
96          .GetEnumerator();
97        valueIter.MoveNext();
98        int rank = int.Parse((string)valueIter.Current);
99        int[] lengths = new int[rank];
100        int[] lowerBounds = new int[rank];
101        for (int i = 0; i < rank; i++) {
102          valueIter.MoveNext();
103          lengths[i] = int.Parse((string)valueIter.Current);
104        }
105        for (int i = 0; i < rank; i++) {
106          valueIter.MoveNext();
107          lowerBounds[i] = int.Parse((string)valueIter.Current);
108        }
109        Type elementType = type.GetElementType();
110        Array a = Array.CreateInstance(elementType, lengths, lowerBounds);
111        int[] positions = (int[])lowerBounds.Clone();
112        while (valueIter.MoveNext()) {
113          a.SetValue(
114            numberConverter.Parse((string)valueIter.Current, elementType),
115            positions);
116          positions[0] += 1;
117          for (int i = 0; i < rank - 1; i++) {
118            if (positions[i] >= lengths[i] + lowerBounds[i]) {
119              positions[i + 1] += 1;
120              positions[i] = lowerBounds[i];
121            } else {
122              break;
123            }
124          }
125        }
126        return a;
127      } catch (InvalidOperationException e) {
128        throw new PersistenceException("Insufficient data to deserialize compact array", e);
129      } catch (InvalidCastException e) {
130        throw new PersistenceException("Invalid element data during compact array deserialization", e);
131      }
132    }
133
134    public void Populate(object instance, IEnumerable<Tag> tags, Type type) {
135      // Nothing to do: Compact arrays are already populated during instance creation.
136    }
137
138  }
139
140}
Note: See TracBrowser for help on using the repository browser.