Free cookie consent management tool by TermsFeed Policy Generator

source: branches/PersistenceOverhaul/HeuristicLab.Persistence/4.0/Transformers/ArrayTransformer.cs @ 13326

Last change on this file since 13326 was 13326, checked in by swagner, 8 years ago

#2520: Created plugin for new persistence implementation

File size: 7.2 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2012 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.Linq;
24using HeuristicLab.Persistence.Data;
25
26namespace HeuristicLab.Persistence {
27  internal abstract class GenericArrayTransformer<TSource, TTarget> : TransformerBase {
28    public override bool CanTransformType(Type type) {
29      return type.IsArray && (type.GetElementType() == typeof(TSource));
30    }
31
32    public override PersistenceData ToData(object o, PersistenceMapper mapper) {
33      var arr = (Array)o;
34      var data = new ArrayData<TTarget>(Id);
35      mapper.Cache(o, data);
36      var elementType = arr.GetType().GetElementType();
37      data.ElementTypeId = mapper.GetTypeId(elementType);
38
39      if (arr.Rank == 1) {
40        data.Values = GetTargets((TSource[])o, mapper);
41        //data.Values = GetTargets(Array.ConvertAll(arr, x => (object)x), mapper);
42        //data.Values = GetTargets(arr.Cast<TSource>().ToArray(), mapper);
43        return data;
44      } else {
45        data.Lengths = new int[arr.Rank];
46        int[] positions = new int[arr.Rank];
47        for (int i = 0; i < arr.Rank; i++) {
48          data.Lengths[i] = arr.GetLength(i);
49          positions[i] = 0;
50        }
51
52        data.Values = new TTarget[arr.Length];
53        for (int i = 0; i < data.Values.Length; i++) {
54          data.Values[i] = GetTarget((TSource)arr.GetValue(positions), mapper);
55          positions[0] += 1;
56          for (int j = 0; j < arr.Rank - 1; j++) {
57            if (positions[j] >= data.Lengths[j]) {
58              positions[j] = 0;
59              positions[j + 1] += 1;
60            } else {
61              break;
62            }
63          }
64        }
65        return data;
66      }
67    }
68
69    public override object ToObject(PersistenceData data, PersistenceMapper mapper) {
70      var arrayData = (ArrayData<TTarget>)data;
71      var elementType = mapper.GetType(arrayData.ElementTypeId);
72      if (arrayData.Lengths.Length <= 1) {  // single dimensional
73        var o = GetSources(arrayData.Values, mapper);
74        mapper.Cache(data, o);
75        return o;
76      } else {
77        var o = Array.CreateInstance(elementType, arrayData.Lengths);
78        mapper.Cache(data, o);
79
80        int[] positions = new int[arrayData.Lengths.Length];
81        positions.Initialize();
82        for (int i = 0; i < arrayData.Values.Length; i++) {
83          o.SetValue(GetSource(arrayData.Values[i], mapper), positions);
84          positions[0] += 1;
85          for (int j = 0; j < o.Rank - 1; j++) {
86            if (positions[j] >= arrayData.Lengths[j]) {
87              positions[j] = 0;
88              positions[j + 1] += 1;
89            } else {
90              break;
91            }
92          }
93        }
94        return o;
95      }
96    }
97
98    protected abstract TTarget[] GetTargets(TSource[] sources, PersistenceMapper mapper);
99    protected abstract TSource[] GetSources(TTarget[] targets, PersistenceMapper mapper);
100    protected abstract TTarget GetTarget(TSource source, PersistenceMapper mapper);
101    protected abstract TSource GetSource(TTarget target, PersistenceMapper mapper);
102  }
103
104  internal abstract class PrimitiveArrayTransformer<T> : GenericArrayTransformer<T, T> {
105    protected override T[] GetTargets(T[] sources, PersistenceMapper mapper) {
106      return sources;
107    }
108    protected override T[] GetSources(T[] targets, PersistenceMapper mapper) {
109      return targets;
110    }
111    protected override T GetTarget(T source, PersistenceMapper mapper) {
112      return source;
113    }
114    protected override T GetSource(T target, PersistenceMapper mapper) {
115      return target;
116    }
117  }
118
119  [Transformer("F25A73B2-6B67-4493-BD59-B836AF4455D1", 300)]
120  internal sealed class BoolArrayTransformer : PrimitiveArrayTransformer<bool> { }
121
122  [Transformer("FF89F6D1-CDE3-498E-9166-F70AC6EB01F1", 301)]
123  internal sealed class ByteArrayTransformer : PrimitiveArrayTransformer<byte> { }
124
125  [Transformer("B49B3F2D-2E97-4BAB-8705-8D29DA707C6A", 302)]
126  internal sealed class SByteArrayTransformer : PrimitiveArrayTransformer<sbyte> { }
127
128  [Transformer("2811FDD4-6800-4CBA-86D7-9071ED5775ED", 303)]
129  internal sealed class ShortArrayTransformer : PrimitiveArrayTransformer<short> { }
130
131  [Transformer("1AAC2625-356C-40BC-8CB4-15CB3D047EB8", 304)]
132  internal sealed class UShortArrayTransformer : PrimitiveArrayTransformer<ushort> { }
133
134  [Transformer("12F19098-5D49-4C23-8897-69087F1C146D", 305)]
135  internal sealed class CharArrayTransformer : PrimitiveArrayTransformer<char> { }
136
137  [Transformer("5F6DC3BC-4433-4AE9-A636-4BD126F7DACD", 306)]
138  internal sealed class IntArrayTransformer : PrimitiveArrayTransformer<int> { }
139
140  [Transformer("3F10274F-D350-4C82-89EA-A5EB36D4EFCC", 307)]
141  internal sealed class UIntArrayTransformer : PrimitiveArrayTransformer<uint> { }
142
143  [Transformer("E9D550E2-57F7-47F3-803D-37A619DA1A5C", 308)]
144  internal sealed class LongArrayTransformer : PrimitiveArrayTransformer<long> { }
145
146  [Transformer("C02A205B-2176-4282-AC2B-ADEF96DDBE24", 309)]
147  internal sealed class ULongArrayTransformer : PrimitiveArrayTransformer<ulong> { }
148
149  [Transformer("3C4590D9-C76E-4AFB-98FD-E50D3D051648", 310)]
150  internal sealed class FloatArrayTransformer : PrimitiveArrayTransformer<float> { }
151
152  [Transformer("FB98C399-9323-4470-9A85-9186C2B2D5D4", 311)]
153  internal sealed class DoubleArrayTransformer : PrimitiveArrayTransformer<double> { }
154
155  [Transformer("9E68A52B-2EC8-447E-B45B-D382A16283D4", 312)]
156  internal sealed class DecimalArrayTransformer : PrimitiveArrayTransformer<decimal> { }
157
158  [Transformer("68332513-9CF1-47FA-A093-6DDB663186EC", 313)]
159  internal sealed class StringArrayTransformer : PrimitiveArrayTransformer<string> { }
160
161  [Transformer("C83F0B5A-68D8-4271-81F9-FF259FC6F126", 400)]
162  internal sealed class ArrayTransformer : GenericArrayTransformer<object, uint> {
163    public override bool CanTransformType(Type type) {
164      return type.IsArray;
165    }
166
167    protected override uint[] GetTargets(object[] sources, PersistenceMapper mapper) {
168      return sources.Select(x => mapper.GetDataId(x)).ToArray();
169    }
170    protected override object[] GetSources(uint[] targets, PersistenceMapper mapper) {
171      return targets.Select(x => mapper.GetObject(x)).ToArray();
172    }
173    protected override uint GetTarget(object source, PersistenceMapper mapper) {
174      return mapper.GetDataId(source);
175    }
176    protected override object GetSource(uint target, PersistenceMapper mapper) {
177      return mapper.GetObject(target);
178    }
179  }
180}
Note: See TracBrowser for help on using the repository browser.