Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Persistence/3.3/Default/Decomposers/ArrayDecomposer.cs @ 1539

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

Add Priority property to IDecomposer interface to allow specialized decomposers to be tried first. (#578)

File size: 2.6 KB
Line 
1using System;
2using HeuristicLab.Persistence.Core;
3using HeuristicLab.Persistence.Interfaces;
4using System.Collections.Generic;
5
6namespace HeuristicLab.Persistence.Default.Decomposers {
7   
8  public class ArrayDecomposer : IDecomposer {
9
10    public int Priority {
11      get { return 100; }
12    }
13
14    public bool CanDecompose(Type type) {
15      return type.IsArray || type == typeof(Array);
16    }
17
18    public IEnumerable<Tag> DeCompose(object array) {
19      Array a = (Array)array;     
20      yield return new Tag("rank", a.Rank);
21      int[] lengths = new int[a.Rank];
22      int[] lowerBounds = new int[a.Rank];
23      for (int i = 0; i < a.Rank; i++) {
24        lengths[i] = a.GetLength(i);
25        yield return new Tag("length_" + i, a.GetLength(i));
26      }
27      for (int i = 0; i < a.Rank; i++) {
28        lowerBounds[i] = a.GetLowerBound(i);
29        yield return new Tag("lowerBound_" + i, a.GetLowerBound(i));
30      }
31      int[] positions = (int[])lowerBounds.Clone();
32      while (positions[a.Rank - 1] < lengths[a.Rank - 1] + lowerBounds[a.Rank - 1]) {
33        yield return new Tag(a.GetValue(positions));
34        positions[0] += 1;
35        for (int i = 0; i < a.Rank - 1; i++) {
36          if (positions[i] >= lowerBounds[i] + lengths[i]) {
37            positions[i] = lowerBounds[i];
38            positions[i + 1] += 1;
39          } else {
40            break;
41          }
42        }
43      }
44    }
45
46    public object CreateInstance(Type t) {
47      return null;
48    }
49
50    public object Populate(object instance, IEnumerable<Tag> elements, Type t) {
51      IEnumerator<Tag> e = elements.GetEnumerator();
52      e.MoveNext();
53      int rank = (int)e.Current.Value;
54      int[] lengths = new int[rank];
55      for (int i = 0; i < rank; i++) {
56        e.MoveNext();
57        lengths[i] = (int)e.Current.Value;
58      }
59      int[] lowerBounds = new int[rank];
60      for (int i = 0; i < rank; i++) {
61        e.MoveNext();
62        lowerBounds[i] = (int)e.Current.Value;
63      }     
64      Array a = Array.CreateInstance(t.GetElementType(), lengths, lowerBounds);
65      int[] positions = (int[])lowerBounds.Clone();
66      while (e.MoveNext()) {
67        int[] currentPositions = positions;
68        e.Current.SafeSet(value => a.SetValue(value, currentPositions));       
69        positions[0] += 1;
70        for (int i = 0; i < rank-1; i++) {
71          if (positions[i] >= lengths[i]+lowerBounds[i]) {
72            positions[i] = lowerBounds[i];
73            positions[i + 1] += 1;
74          } else {
75            break;
76          }
77        }
78      }
79      return a;
80    }
81  }
82 
83}
Note: See TracBrowser for help on using the repository browser.