source: trunk/CrypPlugins/Concatenate/Concatenate.cs @ 1785

Last change on this file since 1785 was 1259, checked in by Matthäus Wander, 12 years ago

shortened license text to boilerplate notice in all source files

File size: 12.9 KB
Line 
1/*
2   Copyright 2008 Thomas Schmid, University of Siegen
3
4   Licensed under the Apache License, Version 2.0 (the "License");
5   you may not use this file except in compliance with the License.
6   You may obtain a copy of the License at
7
8       http://www.apache.org/licenses/LICENSE-2.0
9
10   Unless required by applicable law or agreed to in writing, software
11   distributed under the License is distributed on an "AS IS" BASIS,
12   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   See the License for the specific language governing permissions and
14   limitations under the License.
15*/
16
17using System;
18using System.Collections.Generic;
19using System.Linq;
20using System.Text;
21using Cryptool.PluginBase.IO;
22using Cryptool.PluginBase.Miscellaneous;
23using System.ComponentModel;
24using System.Windows.Controls;
25using Cryptool.PluginBase;
26using System.Runtime.CompilerServices;
27
28namespace Concatenate
29{
30  [Author("Thomas Schmid", "thomas.schmid@cryptool.org", "Uni Siegen", "http://www.uni-siegen.de")]
31  [PluginInfo(false, "Concatenate", "Concatenates two input values. Fires output if second value arrives (The other value can be overwritten in the meantime).", null, "Concatenate/icon.png")]
32  public class Concatenate : IThroughput
33  {
34    # region Fields
35    private List<CryptoolStream> listCryptoolStreamsOut = new List<CryptoolStream>();
36    private readonly string inputOne = "InputOne";
37    private readonly string inputTwo = "InputTwo";
38    private readonly string outputOne = "OutputOne";
39    private ConcatenateSettings settings;
40    # endregion Fields
41
42    public event DynamicPropertiesChanged OnDynamicPropertiesChanged;
43
44    public Concatenate()
45    {
46      settings = new ConcatenateSettings(this);
47      settings.OnGuiLogNotificationOccured += settings_OnGuiLogNotificationOccured;
48      CanChangeDynamicProperty = true;
49      CreateInputOutput(false);
50    }
51
52    public void CreateInputOutput(bool announcePropertyChange)
53    {
54      DicDynamicProperties.Clear();
55      AddInput(inputOne, "Input one");
56      AddInput(inputTwo, "Input two");
57      AddOutput(outputOne);
58      if (announcePropertyChange) DynamicPropertiesChanged();
59    }
60
61    private void DynamicPropertiesChanged()
62    {
63      if (OnDynamicPropertiesChanged != null) OnDynamicPropertiesChanged(this);
64    }
65
66    void settings_OnGuiLogNotificationOccured(IPlugin sender, GuiLogEventArgs args)
67    {
68      EventsHelper.GuiLogMessage(OnGuiLogNotificationOccured, this, new GuiLogEventArgs(args.Message, this, args.NotificationLevel));
69    }
70
71    # region DynamicProperties
72
73    public Dictionary<string, DynamicProperty> dicDynamicProperties = new Dictionary<string, DynamicProperty>();
74
75    [DynamicPropertyInfo("methodGetValue", "methodSetValue", "CanChangeDynamicProperty", "OnDynamicPropertiesChanged", "CanSendPropertiesChangedEvent")]
76    public Dictionary<string, DynamicProperty> DicDynamicProperties
77    {
78      get { return dicDynamicProperties; }
79      set { dicDynamicProperties = value; }
80    }
81
82    private bool canSendPropertiesChangedEvent = true;
83    public bool CanSendPropertiesChangedEvent
84    {
85      get { return canSendPropertiesChangedEvent; }
86      set { canSendPropertiesChangedEvent = value; }
87    }
88
89    public bool CanChangeDynamicProperty
90    {
91      get { return settings.CanChangeProperty; }
92      set { settings.CanChangeProperty = value; }
93    }
94
95    private Type getCurrentType()
96    {
97      switch (settings.CurrentDataType)
98      {
99        case ConcatenateSettings.DataTypes.CryptoolStream:
100          return typeof(CryptoolStream);
101        case ConcatenateSettings.DataTypes.String:
102          return typeof(string);
103        case ConcatenateSettings.DataTypes.ByteArray:
104          return typeof(byte[]);
105        case ConcatenateSettings.DataTypes.Boolean:
106          return typeof(bool);
107        case ConcatenateSettings.DataTypes.Integer:
108          return typeof(int);
109        default:
110          return null;
111      }
112    }
113
114    private QuickWatchFormat getQuickWatchFormat()
115    {
116      Type type = getCurrentType();
117      if (type == typeof(CryptoolStream))
118        return QuickWatchFormat.Hex;
119      else if (type == typeof(string))
120        return QuickWatchFormat.Text;
121      else if (type == typeof(byte[]))
122        return QuickWatchFormat.Hex;
123      else if (type == typeof(bool))
124        return QuickWatchFormat.Text;
125      else if (type == typeof(int))
126        return QuickWatchFormat.Text;
127      else
128        return QuickWatchFormat.None;
129    }
130
131    private void AddInput(string name, string toolTip)
132    {
133      DicDynamicProperties.Add(name,
134        new DynamicProperty(name, getCurrentType(),
135          new PropertyInfoAttribute(Direction.InputData, name, toolTip, "", false, true, DisplayLevel.Beginner, getQuickWatchFormat(), null)));
136    }
137
138    private void AddOutput(string name)
139    {
140      DicDynamicProperties.Add(name,
141        new DynamicProperty(name, getCurrentType(),
142          new PropertyInfoAttribute(Direction.OutputData, name, "", "", false, false, DisplayLevel.Beginner, getQuickWatchFormat(), null)));
143    }
144
145    [MethodImpl(MethodImplOptions.Synchronized)]
146    public void methodSetValue(string propertyKey, object value)
147    {
148      try
149      {
150        if (DicDynamicProperties.ContainsKey(propertyKey))
151        {
152          DicDynamicProperties[propertyKey].Value = value;
153          if (value is CryptoolStream) listCryptoolStreamsOut.Add((CryptoolStream)value);
154          OnPropertyChanged(propertyKey);
155        }
156        // Fire output on value Pair.
157        if (DicDynamicProperties[inputOne].Value != null && DicDynamicProperties[inputTwo].Value != null)
158        {
159          object val1 = DicDynamicProperties[inputOne].Value;
160          //DicDynamicProperties[inputOne].Value = null;
161          object val2 = DicDynamicProperties[inputTwo].Value;
162          //DicDynamicProperties[inputTwo].Value = null;
163
164          switch (settings.CurrentDataType)
165          {
166            #region CryptoolStream
167            case ConcatenateSettings.DataTypes.CryptoolStream:
168              CryptoolStream stream1 = val1 as CryptoolStream;
169              CryptoolStream stream2 = val2 as CryptoolStream;
170              CryptoolStream returnStream = new CryptoolStream();
171              returnStream.OpenWrite();
172              byte[] byteValues = new byte[1024];
173              int byteRead;
174              int position = 0;
175              long total = stream1.Length + stream2.Length;
176              // first stream
177              while ((byteRead = stream1.Read(byteValues, 0, byteValues.Length)) != 0)
178              {
179                returnStream.Write(byteValues, 0, byteRead);
180                if (OnPluginProgressChanged != null && stream1.Length > 0 &&
181                    (int)(stream1.Position * 100 / total) > position)
182                {
183                  position = (int)(stream1.Position * 100 / total);
184                  Progress(stream1.Position, total);
185                }
186              }
187              // second stream
188              while ((byteRead = stream2.Read(byteValues, 0, byteValues.Length)) != 0)
189              {
190                returnStream.Write(byteValues, 0, byteRead);
191                if (OnPluginProgressChanged != null && stream2.Length > 0 &&
192                    (int)((stream2.Position + stream1.Length) * 100 / total) > position)
193                {
194                  position = (int)((stream2.Position + stream1.Length) * 100 / total);
195                  Progress((stream2.Position + stream1.Length), total);
196                }
197              }
198              returnStream.Close();
199              stream1.Position = 0;
200              stream2.Position = 0;
201              setOutputInternal(outputOne, returnStream);
202              break;
203            #endregion
204            #region String
205            case ConcatenateSettings.DataTypes.String:
206              setOutputInternal(outputOne, (val1 as string) + (val2 as string));
207              break;
208            #endregion
209            #region ByteArray
210            case ConcatenateSettings.DataTypes.ByteArray:
211              byte[] arrReturn = new byte[(val1 as byte[]).Length + (val2 as byte[]).Length];
212              System.Buffer.BlockCopy((val1 as byte[]), 0, arrReturn, 0, (val1 as byte[]).Length);
213              System.Buffer.BlockCopy((val2 as byte[]), 0, arrReturn, (val1 as byte[]).Length, (val2 as byte[]).Length);
214              setOutputInternal(outputOne, arrReturn);
215              break;
216            #endregion
217            #region Boolean
218            case ConcatenateSettings.DataTypes.Boolean:
219              Nullable<bool> boolValue = ((bool)val1) && ((bool)val2);
220              setOutputInternal(outputOne, boolValue);
221              break;
222            #endregion
223            #region Integer
224            case ConcatenateSettings.DataTypes.Integer:
225              int? intValue = ((int)val1) + ((int)val2);
226              setOutputInternal(outputOne, intValue);
227              break;
228            #endregion
229            default:
230              break;
231          }
232          Progress(100, 100);
233        }
234      }
235      catch (Exception exception)
236      {
237        GuiLogMessage(exception.Message, NotificationLevel.Error);
238      }
239    }
240
241    /// <summary>
242    /// Used to avoid loop in methodSetValue (setting values to null there destroys quickWatch updates)
243    /// </summary>
244    /// <param name="propertyKey">The property key.</param>
245    /// <param name="value">The value.</param>
246    private void setOutputInternal(string propertyKey, object value)
247    {
248      try
249      {
250        if (DicDynamicProperties.ContainsKey(propertyKey))
251        {
252          DicDynamicProperties[propertyKey].Value = value;
253          if (value is CryptoolStream) 
254            listCryptoolStreamsOut.Add((CryptoolStream)value);
255          OnPropertyChanged(propertyKey);
256        }
257      }
258      catch (Exception exception)
259      {
260        GuiLogMessage(exception.Message, NotificationLevel.Error);
261      }
262    }
263
264    [MethodImpl(MethodImplOptions.Synchronized)]
265    public object methodGetValue(string propertyKey)
266    {
267      try
268      {
269        if (DicDynamicProperties.ContainsKey(propertyKey))
270        {
271          if (DicDynamicProperties[propertyKey].Value is CryptoolStream)
272          {
273            CryptoolStream cryptoolStream = new CryptoolStream();
274            cryptoolStream.OpenRead((DicDynamicProperties[propertyKey].Value as CryptoolStream).FileName);
275            listCryptoolStreamsOut.Add(cryptoolStream);
276            return cryptoolStream;
277          }
278          return DicDynamicProperties[propertyKey].Value;
279        }
280      }
281      catch (Exception exception)
282      {
283        GuiLogMessage(exception.Message, NotificationLevel.Error);
284      }
285      return null;
286    }
287
288    # endregion DynamicProperties
289
290    #region IPlugin Members
291
292    public event StatusChangedEventHandler OnPluginStatusChanged;
293
294    public event GuiLogNotificationEventHandler OnGuiLogNotificationOccured;
295    private void GuiLogMessage(string message, NotificationLevel logLevel)
296    {
297      EventsHelper.GuiLogMessage(OnGuiLogNotificationOccured, this, new GuiLogEventArgs(message, this, logLevel));
298    }
299
300    public event PluginProgressChangedEventHandler OnPluginProgressChanged;
301    private void Progress(double value, double max)
302    {
303      EventsHelper.ProgressChanged(OnPluginProgressChanged, this, new PluginProgressEventArgs(value, max));
304    }
305
306    public ISettings Settings
307    {
308      get { return settings; }
309    }
310
311    public UserControl Presentation
312    {
313      get { return null; }
314    }
315
316    public UserControl QuickWatchPresentation
317    {
318      get { return null; }
319    }
320
321    public void PreExecution()
322    {
323      Dispose();
324    }
325
326    public void Execute()
327    {
328    }
329
330    public void PostExecution()
331    {
332      Dispose();
333    }
334
335    public void Pause()
336    {
337    }
338
339    public void Stop()
340    {
341    }
342
343    public void Initialize()
344    {
345    }
346
347    public void Dispose()
348    {
349      foreach (CryptoolStream cryptoolStream in listCryptoolStreamsOut)
350      {
351        cryptoolStream.Close();
352      }
353      listCryptoolStreamsOut.Clear();
354      // This values have to be set to null here because it might be CryptoolStreams.
355      // The files will be deleted before each run. So the quickWatch calls on PreExec
356      // will produce an exception, because MethodGetValue tries to access the old files if not
357      // set to null here.
358      DicDynamicProperties[inputOne].Value = null;
359      DicDynamicProperties[inputTwo].Value = null;
360      DicDynamicProperties[outputOne].Value = null;
361    }
362
363    #endregion
364
365    #region INotifyPropertyChanged Members
366
367    public event PropertyChangedEventHandler PropertyChanged;
368
369    protected void OnPropertyChanged(string name)
370    {
371      EventsHelper.PropertyChanged(PropertyChanged, this, new PropertyChangedEventArgs(name));
372    }
373
374    #endregion
375  }
376}
Note: See TracBrowser for help on using the repository browser.