Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Persistence/3.3/Default/Decomposers/CompactNumberArray2StringDecomposer.cs @ 1625

Last change on this file since 1625 was 1625, checked in by epitzer, 15 years ago

Added PersistenceException used consistently for all error conditions in the persistence framework (#548)

File size: 3.9 KB
Line 
1using System;
2using HeuristicLab.Persistence.Interfaces;
3using HeuristicLab.Persistence.Core;
4using System.Collections.Generic;
5using System.Reflection;
6using System.Globalization;
7using System.Text;
8using HeuristicLab.Persistence.Default.Decomposers.Storable;
9
10namespace HeuristicLab.Persistence.Default.Decomposers {
11
12  [EmptyStorableClass]
13  public class CompactNumberArray2StringDecomposer : IDecomposer {
14
15    public int Priority {
16      get { return 200; }
17    }
18
19    private static readonly Number2StringConverter numberConverter =
20      new Number2StringConverter();
21
22    public bool CanDecompose(Type type) {
23      return
24        (type.IsArray || type == typeof(Array)) &&
25        numberConverter.CanDecompose(type.GetElementType());
26    }
27
28    public IEnumerable<Tag> CreateMetaInfo(object obj) {
29      Array a = (Array)obj;
30      int[] lengths = new int[a.Rank];
31      int[] lowerBounds = new int[a.Rank];
32      StringBuilder sb = new StringBuilder();
33      sb.Append(a.Rank).Append(';');
34      for (int i = 0; i < a.Rank; i++) {
35        sb.Append(a.GetLength(i)).Append(';');
36        lengths[i] = a.GetLength(i);
37      }
38      for (int i = 0; i < a.Rank; i++) {
39        sb.Append(a.GetLowerBound(i)).Append(';');
40        lowerBounds[i] = a.GetLowerBound(i);
41      }
42      int[] positions = (int[])lowerBounds.Clone();
43      while (positions[a.Rank - 1] < lengths[a.Rank - 1] + lowerBounds[a.Rank - 1]) {
44        sb.Append(numberConverter.Format(a.GetValue(positions))).Append(';');
45        positions[0] += 1;
46        for (int i = 0; i < a.Rank - 1; i++) {
47          if (positions[i] >= lengths[i] + lowerBounds[i]) {
48            positions[i] = lowerBounds[i];
49            positions[i + 1] += 1;
50          } else {
51            break;
52          }
53        }
54      }
55      yield return new Tag("compact array", sb.ToString());
56    }
57
58    public IEnumerable<Tag> Decompose(object obj) {
59      return new Tag[] { };
60    }
61
62    public object CreateInstance(Type type, IEnumerable<Tag> metaInfo) {
63      try {
64        var tagIter = metaInfo.GetEnumerator();
65        tagIter.MoveNext();     
66        var valueIter = ((string)tagIter.Current.Value)
67          .Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries)
68          .GetEnumerator();
69        valueIter.MoveNext();
70        int rank = int.Parse((string)valueIter.Current);
71        int[] lengths = new int[rank];
72        int[] lowerBounds = new int[rank];
73        for (int i = 0; i < rank; i++) {
74          valueIter.MoveNext();
75          lengths[i] = int.Parse((string)valueIter.Current);
76        }
77        for (int i = 0; i < rank; i++) {
78          valueIter.MoveNext();
79          lowerBounds[i] = int.Parse((string)valueIter.Current);
80        }
81        Type elementType = type.GetElementType();
82        Array a = Array.CreateInstance(elementType, lengths, lowerBounds);
83        int[] positions = (int[])lowerBounds.Clone();
84        while (valueIter.MoveNext()) {
85          a.SetValue(
86            numberConverter.Parse((string)valueIter.Current, elementType),
87            positions);
88          positions[0] += 1;
89          for (int i = 0; i < rank - 1; i++) {
90            if (positions[i] >= lengths[i] + lowerBounds[i]) {
91              positions[i + 1] += 1;
92              positions[i] = lowerBounds[i];
93            } else {
94              break;
95            }
96          }
97        }
98        return a;
99      } catch (InvalidOperationException e) {
100        throw new PersistenceException("Insufficient data to deserialize compact array", e);
101      } catch (InvalidCastException e) {
102        throw new PersistenceException("Invalid element data during compact array deserialization", e);
103      }     
104    }
105
106    public void Populate(object instance, IEnumerable<Tag> tags, Type type) {
107      // Nothing to do: Compact arrays are already populated during instance creation.
108    }
109
110  }
111
112}
Note: See TracBrowser for help on using the repository browser.