Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Persistence/3.3/Default/Decomposers/ArrayDecomposer.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.Core;
3using HeuristicLab.Persistence.Interfaces;
4using System.Collections.Generic;
5using HeuristicLab.Persistence.Default.Decomposers.Storable;
6
7namespace HeuristicLab.Persistence.Default.Decomposers {
8
9  [EmptyStorableClass]
10  public class ArrayDecomposer : IDecomposer {
11
12    public int Priority {
13      get { return 100; }
14    }
15
16    public bool CanDecompose(Type type) {
17      return type.IsArray || type == typeof(Array);
18    }
19
20    public IEnumerable<Tag> CreateMetaInfo(object obj) {
21      Array a = (Array)obj;
22      yield return new Tag("rank", a.Rank);
23      for (int i = 0; i < a.Rank; i++) {
24        yield return new Tag("length_" + i, a.GetLength(i));
25      }
26      for (int i = 0; i < a.Rank; i++) {
27        yield return new Tag("lowerBound_" + i, a.GetLowerBound(i));
28      }
29    }
30
31    public IEnumerable<Tag> Decompose(object array) {
32      Array a = (Array)array;
33      int[] lengths = new int[a.Rank];
34      int[] lowerBounds = new int[a.Rank];
35      for (int i = 0; i < a.Rank; i++) {
36        lengths[i] = a.GetLength(i);
37      }
38      for (int i = 0; i < a.Rank; i++) {
39        lowerBounds[i] = a.GetLowerBound(i);
40      }
41      int[] positions = (int[])lowerBounds.Clone();
42      while (positions[a.Rank - 1] < lengths[a.Rank - 1] + lowerBounds[a.Rank - 1]) {
43        yield return new Tag(a.GetValue(positions));
44        positions[0] += 1;
45        for (int i = 0; i < a.Rank - 1; i++) {
46          if (positions[i] >= lowerBounds[i] + lengths[i]) {
47            positions[i] = lowerBounds[i];
48            positions[i + 1] += 1;
49          } else {
50            break;
51          }
52        }
53      }
54    }
55
56    public object CreateInstance(Type t, IEnumerable<Tag> metaInfo) {     
57      try {
58        IEnumerator<Tag> e = metaInfo.GetEnumerator();
59        e.MoveNext();
60        int rank = (int)e.Current.Value;
61        int[] lengths = new int[rank];
62        for (int i = 0; i < rank; i++) {
63          e.MoveNext();
64          lengths[i] = (int)e.Current.Value;
65        }
66        int[] lowerBounds = new int[rank];
67        for (int i = 0; i < rank; i++) {
68          e.MoveNext();
69          lowerBounds[i] = (int)e.Current.Value;
70        }
71        return Array.CreateInstance(t.GetElementType(), lengths, lowerBounds);
72      } catch (InvalidOperationException x) {
73        throw new PersistenceException("Insufficient meta information to construct array instance.", x);
74      } catch (InvalidCastException x) {
75        throw new PersistenceException("Invalid format of array metainfo.", x);
76      }     
77    }
78
79    public void Populate(object instance, IEnumerable<Tag> elements, Type t) {
80      Array a = (Array)instance;
81      int[] lengths = new int[a.Rank];
82      int[] lowerBounds = new int[a.Rank];
83      for (int i = 0; i < a.Rank; i++) {
84        lengths[i] = a.GetLength(i);
85      }
86      for (int i = 0; i < a.Rank; i++) {
87        lowerBounds[i] = a.GetLowerBound(i);
88      }
89      int[] positions = (int[])lowerBounds.Clone();
90      IEnumerator<Tag> e = elements.GetEnumerator();
91      try {
92        while (e.MoveNext()) {
93          int[] currentPositions = positions;
94          a.SetValue(e.Current.Value, currentPositions);
95          positions[0] += 1;
96          for (int i = 0; i < a.Rank - 1; i++) {
97            if (positions[i] >= lengths[i] + lowerBounds[i]) {
98              positions[i] = lowerBounds[i];
99              positions[i + 1] += 1;
100            } else {
101              break;
102            }
103          }
104        }
105      } catch (InvalidOperationException x) {
106        throw new PersistenceException("Insufficient data to fill array instance", x);
107      } catch (InvalidCastException x) {
108        throw new PersistenceException("Invalid element data. Cannot fill array", x);
109      } catch (IndexOutOfRangeException x) {
110        throw new PersistenceException("Too many elements during array deserialization", x);
111      }
112    }
113  }
114
115}
Note: See TracBrowser for help on using the repository browser.