source: trunk/Documentation/PluginHowTo/part2.tex @ 2253

Last change on this file since 2253 was 1636, checked in by Patrick Vacek, 11 years ago

HowTo: general improvement of language.

File size: 32.9 KB
Line 
1\chapter{Plugin Implementation}
2\label{sec:PluginImplementation}
3In this chapter we provide step-by-step instructions for implementing your own CrypTool 2 plugin. We shall assume that you have already retrieved the CrypTool 2 source code from the SVN repository, set up Visual Studio 2010 or Visual C\# 2010 Express to build CrypTool 2, and you have placed the plugin template in the right place.
4
5\section{Downloading the example}
6\label{sec:DownloadingTheExample}
7
8We will use the \textbf{Caesar cipher} (also known as the \textbf{shift cipher}) as an example throughout this chapter. If you have not downloaded the entire CrypTool 2 source code as described in Section \ref{CheckingOutTheSources}, you can also get a copy of just the source code for the Caesar algorithm referenced throughout this guide from the following location:\\\\
9\textit{username: anonymous\\
10password:} (not required)\\
11\url{https://www.cryptool.org/svn/CrypTool2/trunk/CrypPlugins/Caesar/}
12
13\section{Creating a new project}
14\label{sec:CreatingANewProject}
15
16Open the CrypTool 2 solution, right click in the solution explorer on \textit{CrypPlugins} (or on the top solution item, if you're using Visual C\# Express) and select \textit{Add~$\rightarrow$ New Project}. In the dialog window, select \textit{Visual C\# $\rightarrow$ CrypTool 2.0 Plugin} as project template and enter a unique name for your new plugin project (such as \textit{Caesar} in our case). The \textbf{next step is crucial} to ensure that your plugin will compile and run correctly: select the subdirectory \texttt{CrypPlugins\textbackslash} as the location of your project (Figure~\ref{fig:vs_create_new_project}).
17
18\begin{figure}[h!]
19        \centering
20                \includegraphics{figures/vs_create_new_project.png}
21        \caption{Creating a new CrypTool 2 plugin project.}
22        \label{fig:vs_create_new_project}
23\end{figure}
24
25As the project basics are already correctly set up in the template, you should now be able to compile the new plugin. First of all, rename the two files in the solution explorer to something more meaningful, for example \texttt{Caesar.cs} and \texttt{CaesarSettings.cs}.
26
27\begin{figure}[h!]
28        \centering
29                \includegraphics{figures/caesar_project.png}
30        \caption{Items of a new plugin project.}
31        \label{fig:caesar_project}
32\end{figure}
33
34\section{Adapting the plugin skeleton}
35\label{AdaptingThePluginSkeleton}
36
37If you look into the two C\# source files (Figure~\ref{fig:caesar_project}), you will notice a lot of comments marked with the keyword \texttt{HOWTO}. These are hints as to what you should change in order to adapt the plugin skeleton to your custom implementation. Most \texttt{HOWTO} hints are self-explanatory and thus we won't discuss them all in detail. For example, at the top of both source files, there is a hint to enter your name and affiliation in the license boilerplate:
38
39\begin{lstlisting}
40/* HOWTO: Change year, author name and organization.
41   Copyright 2010 Your Name, University of Duckburg
42
43\end{lstlisting}
44
45After you have done this, remove the \texttt{HOWTO} hint:
46
47\begin{lstlisting}
48/*
49   Copyright 2010 John Doe, University of Duisburg-Essen
50
51\end{lstlisting}
52
53\section{Defining the attributes of the Caesar class}
54\label{sec:DefiningTheAttributesOfTheCaesarClass}
55
56The next thing we will do in our example \textit{Caesar.cs} is define the attributes of our class. These attributes are used to provide necessary information for the CrypTool 2 environment. If they are not properly defined, your plugin won't show up in the application user interface, even if everything else is implemented correctly.
57
58Attributes are used for declarative programming and provide metadata that can be added to the existing .NET metadata. CrypTool 2 provides a set of custom attributes that are used to mark the different parts of your plugin. These attributes should be defined right before the class declaration.
59\clearpage
60
61\subsection{The \protect\textit{[Author]} attribute}
62\label{sec:TheAuthorAttribute}
63
64The \textit{[Author]} attribute is optional, meaning that we are not required to define it. The attribute can be used to provide additional information about the plugin developer (or developers, as the case may be). This information will appear in the TaskPane, as for example in Appendix \ref{app:CaesarSettings}. We will define the attribute to demonstrate how it should look in case you want to use it in your plugin.
65
66\begin{figure}[h!]
67        \centering
68                \includegraphics[width=.90\textwidth]{figures/attribute_author.jpg}
69        \caption{The defintion for the \textit{[Author]} attribute.}
70        \label{fig:attribute_author}
71\end{figure}
72
73As can be seen above, the author attribute takes four elements of type string. These elements are:
74
75\begin{itemize}
76        \item \textit{Author} --- the name of the plugin developer.
77        \item \textit{Email} --- the email address of the plugin developer, should he or she wish to be available for contact.
78        \item \textit{Institute} --- the organization, company or university with which the developer is affiliated.
79        \item \textit{URL} --- the website of the developer or of his or her institution.
80\end{itemize}
81
82All of these elements are optional; the developer can choose what information will be published. Unused elements should be set to \texttt{null} or an empty string.
83
84\subsection{The \protect\textit{[PluginInfo]} attribute}
85\label{sec:ThePluginInfoAttribute}
86
87The second attribute, \textit{[PluginInfo]}, provides necessary information about the plugin, and is therefore mandatory. The information defined in this attribute appears in the caption and tool tip window. The attribute is defined as follows:
88
89\begin{figure}[h]
90        \centering
91                \includegraphics[width=1.00\textwidth]{figures/attribute_plugininfo.jpg}
92        \caption{The defintion for the \textit{[PluginInfo]} attribute.}
93        \label{fig:attribute_plugininfo}
94\end{figure}
95
96\noindent This attribute has the following parameters:
97
98\begin{itemize}
99        \item \textit{Resource File} --- the relative path of the associated resource file (if the plugin makes use of one). These files are used primarily to provide multilingual support for the plugin, although this is currently a work in progress. This element is optional.
100        \item \textit{Startable} --- a flag that should be set to \texttt{true} only if the plugin is an input generator (i.e.\ if your plugin only has outputs and no inputs). In all other cases this should be set to \texttt{false}. This flag is important --- setting it incorrectly will result in unpredictable results. This element is mandatory.
101        \item \textit{Caption} --- the name of the plugin, or, if using a resource file, the name of the field in the file with the caption data. This element is mandatory.
102        \item \textit{ToolTip} --- a description of the plugin, or, if using a resource file, the name of the field in the resource file with the toolTip data. This element is optional.
103        \item \textit{DescriptionURL} --- the local path of the description file (e.g.\ XAML file). This element is optional.
104        \item \textit{Icons} --- an array of strings to define all the paths of the icons used in the plugin (i.e.\ the plugin icon described in Section \ref{sec:AddingAnIconToTheCaesarClass}). This element is mandatory.
105\end{itemize}
106
107\noindent Unused elements should be set to \texttt{null} or an empty string.
108
109There are a few limitations and bugs that still exist in the \textit{[PluginInfo]} attribute that will be resolved in a future version. First, it is possible to use the plugin without setting a caption, although this is not recommended, and future versions of the plugin will fail to load without a caption. Second, a zero-length toolTip string currently causes the toolTip to appear as an empty box in the application. Third, the toolTip and description do not currently support internationalization and localization. Since the precise formulation and functionality of this attribute is still being developed, it is recommended to view other plugins for examples.
110
111In our example, the \textit{resourceFile} parameter is set to \textit{Cryptool.Caesar.Resource.res}. This file will be used to store the label and caption text to support multilingualism.
112
113The second parameter, \textit{startable}, should be set to \texttt{false}, because our encryption algorithm is not an input generator.
114
115The next two parameters are necessary to define the plugin's name and description. Since we are using a resource file, we should place here the names of the resource fields that contain the caption and toolTip. (We could also just write simple text strings instead of using outsourced references.)
116
117The \textit{DescriptionURL} element defines the location path of the description file. The parameter is composed in the format \textit{$<$assembly name$>$/$<$file name$>$} or, if you want to store your description files in a separate folder (as in our case), \textit{$<$assembly name$>$/$<$path$>$/$<$file name$>$}. The description file must be an XAML file. In our case, we shall create a folder named \textit{DetailedDescription} in which to store our XAML file with any necessary images. Our folder structure now looks as follows:
118
119\begin{figure}[h!]
120        \centering
121                \includegraphics[width=.30\textwidth]{figures/detailed_description.jpg}
122        \caption{The folder structure as seen in the Solution Explorer.}
123        \label{fig:attribute_plugininfo_icon_path}
124\end{figure}
125\clearpage
126
127Once a detailed description has been written in the XAML file, it can be accessed in the CrypTool~2 application by right-clicking on the plugin icon in the workspace and selecting \textit{Show description} \mbox{(Figure \ref{fig:xaml_description})}.
128
129\begin{figure}[h!]
130        \centering
131                \includegraphics[width=1.00\textwidth]{figures/xaml_description.jpg}
132        \caption{A detailed description provided through an XAML file.}
133        \label{fig:xaml_description}
134\end{figure}
135
136The last parameter tells CrypTool 2 the names of the provided icons. This parameter is an array composed of strings in the format \textit{$<$assembly name$>$/$<$file name$>$} or \textit{$<$assembly name$>$/$<$path$>$/\linebreak $<$file~name$>$}.
137
138The first and most important icon is the plugin icon, which will be shown in CrypTool 2 in the ribbon bar and navigation pane. Once the icon has been added to the project as described in Section~\ref{sec:AddingAnIconToTheCaesarClass}, we must accordingly tell CrypTool 2 where to find the icon. This can be seen above in Figure \ref{fig:attribute_plugininfo}.
139
140If your plugin will use additional icons, you should define the paths to each of them by adding the path strings to the \textit{[PluginInfo]} attribute parameter list, each separated by a comma. We have added two further icons for the context menu in the CrypTool 2 workspace. (If you choose to add more icons, don't forget to add the icons to your solution.)
141
142\subsection{Algorithm category and the \protect\textit{[EncryptionType]} attribute}
143\label{sec:AlgorithmCategoryAndTheEncryptionTypeAttribute}
144
145In the CrypTool 2 user interface plugins are grouped by their algorithm category, for example hash, encryption, and so on. To set the category, your plugin must inherit from a specific interface, like \textit{IHash} or \textit{IEncryption}. Some categories require the specification of a subcategory, which is entered as an attribute\footnote{The current category system is less than ideal and will be changed in future; see trac ticket \#50.}. In our example, Caesar inherits from \textit{IEncryption}.
146
147\begin{lstlisting}
148    [EncryptionType(EncryptionType.Classic)]
149    public class Caesar : IEncryption
150                {
151\end{lstlisting}
152\clearpage
153
154The possible values of the \textit{[EncryptionType]} attribute are as follows:
155
156\begin{itemize}
157        \item \textit{Asymmetric} --- for asymmetrical encryption algorithms, such as RSA.
158        \item \textit{SymmetricBlock} --- for block cipher algorithms, such as DES, AES and Twofish.
159        \item \textit{SymmetricStream} --- for stream cipher algorithms, such as RC4, Rabbit and SEAL.
160        \item \textit{Hybrid} --- for algorithms which are actually a combination of several algorithms, such as algorithms in which the data is encrypted symmetrically and the encryption key asymmetrically.
161        \item \textit{Classic} --- for classical encryption or hash algorithms, such as Caesar or MD5.
162\end{itemize}
163
164\subsection{Importing CrypPluginBase namespaces}
165\label{sec:ImportingCrypPluginBaseNamespaces}
166
167Depending on which algorithm category you choose, you will need to import the corresponding namespace of \textit{CrypPluginBase}. To include the necessary namespaces in the class header, use the \texttt{using} statement followed by the name of the desired namespace. \textit{CrypPluginBase} provides the following namespaces:
168
169\begin{itemize}
170        \item \textit{Cryptool.PluginBase} --- contains interfaces such as \textit{IPlugin}, \textit{IHash}, and \textit{ISettings}, as well as attributes, enumerations, delegates and extensions.
171        \item \textit{Cryptool.PluginBase.Analysis} --- contains interfaces for cryptanalysis plugins (such as \textit{Stream Comparator}).
172        \item \textit{Cryptool.PluginBase.Control} --- contains global interfaces for the \textit{IControl} feature for defining custom controls.
173        \item \textit{Cryptool.PluginBase.Cryptography} --- contains interfaces for encryption and hash algorithms such as AES, DES and MD5.
174        \item \textit{Cryptool.PluginBase.Editor} --- contains interfaces for editors that can be implemented in CrypTool 2, such as the default editor.
175        \item \textit{Cryptool.PluginBase.Generator} --- contains interfaces for generators, including the random input generator.
176        \item \textit{Cryptool.PluginBase.IO} --- contains interfaces for input, output and the \textit{CryptoolStream}.
177        \item \textit{Cryptool.PluginBase.Miscellaneous} --- contains assorted helper classes, including \textit{GuiLogMessage} and \textit{PropertyChanged}.
178        \item \textit{Cryptool.PluginBase.Resources} --- used only by CrypWin and the editor; not necessary for plugin development.
179        \item \textit{Cryptool.PluginBase.Tool} --- contains an interface for standalone tools in CrypTool~2 that are not run in a workspace editor.
180        \item \textit{Cryptool.PluginBase.Validation} --- contains interfaces for validation methods, including regular expressions.
181\end{itemize}
182
183\noindent In our example, the Caesar algorithm necessitates the inclusion of the following namespaces:
184
185\begin{itemize}
186        \item \textit{Cryptool.PluginBase} --- to implement \textit{ISettings} in the CaesarSettings class.
187        \item \textit{Cryptool.PluginBase.Cryptography} --- to implement \textit{IEncryption} in the Caesar class.
188        \item \textit{Cryptool.PluginBase.IO} --- to use CryptoolStream for data input and output.
189        \item \textit{Cryptool.PluginBase.Miscellaneous} --- to use the CrypTool event handler.
190\end{itemize}
191
192\section{Defining the private variables of the settings in the Caesar class}
193\label{sec:DefiningThePrivateVariablesOfTheSettingsInTheCaesarClass}
194
195The next step is to define some private variables that are needed for the settings, input, and output data. In our example, this will look like the following:
196
197\begin{lstlisting}
198        #region Private variables
199        private CaesarSettings settings;
200        private string inputString;
201        private string outputString;
202        private enum CaesarMode { encrypt, decrypt };
203        private List<CryptoolStream> listCryptoolStreamsOut = new List<CryptoolStream>();
204        #endregion
205\end{lstlisting}
206
207\ \\ % ugly but functional
208If your algorithm deals with long strings of code, it is recommended to use the \textit{CryptoolStream} data type. This was designed for input and output between plugins and to handle large amounts of data. To use the native CrypTool stream type, include the namespace \textit{Cryptool.PluginBase.IO} with a \texttt{using} statement as explained in Section \ref{sec:ImportingCrypPluginBaseNamespaces}.
209
210Our example makes use of the following private variables:
211
212\begin{itemize}
213        \item \texttt{CaesarSettings settings} --- required to implement the IPlugin interface properly.
214        \item \texttt{string inputString} --- string from which to read the input data.
215        \item \texttt{string outputString} --- string to which to save the output data.
216        \item \texttt{enum CaesarMode} --- used to select either encryption or decryption.
217        \item \texttt{List$<$CryptoolStream$>$ listCryptoolStreamsOut} --- a list of all streams created by the plugin, which helps to perform a clean dispose.
218\end{itemize}
219
220\subsection{Adding controls to the CaesarSettings class}
221\label{sec:AddingControlsToTheCaesarSettingsClass}
222
223The settings class contains the necessary information about controls, captions, descriptions, and default parameters (for key settings, alphabets, key length, type of action, etc.) to build the settings \textbf{TaskPane} in the CrypTool application. The settings class is used to populate the TaskPane in the CrypTool 2 application so that the user can modify the plugin settings at will. Therefore, we must implement some controls, such as buttons and text boxes, to allow for the necessary interaction. If you will be implementing an algorithm that does not have any user-defined settings (such as a hash function), then this class can be left mostly empty. In Appendix \ref{app:CaesarSettings} there is a full example of what a completed TaskPane and the corresponding source code for the existing Caesar plugin in CrypTool 2 looks like. You can also look at the source code of other CrypTool 2 plugins for examples of how to create the TaskPane backend.
224\clearpage
225
226\section{Adding an icon to the Caesar class}
227\label{sec:AddingAnIconToTheCaesarClass}
228
229Before we go back to the code of the Caesar class, we need to add a custom icon to our project to be shown in the CrypTool 2 \textbf{ribbon bar} and \textbf{navigation pane}. The template has a default icon set, so you don't need to create your own custom set.
230
231The proper image size is 40x40 pixels, but since the image will be rescaled if necessary, any size is technically acceptable. Once you have saved your icon, you should add it directly to the project or to a subdirectory with it. In the project solution, create a new folder named \textit{Images}. This can be done by right-clicking on the project item (\textit{Caesar} in our example) and selecting \textit{Add $\rightarrow$ New Folder}. The icon can be added to this folder (or to the project directly, or to any other subdirectory) by right-clicking on the folder and selecting \textit{Add $\rightarrow$ Existing Item}.
232
233\begin{figure}[h!]
234        \centering
235                \includegraphics{figures/add_existing_item.jpg}
236        \caption{Adding an existing item.}
237        \label{fig:add_existing_item}
238\end{figure}
239\clearpage
240
241A new window will then appear. Select \textit{Image Files} as the file type and select your newly-created icon for your plugin.
242
243\begin{figure}[h!]
244        \centering
245                \includegraphics{figures/choose_icon.jpg}
246        \caption{Selecting the image file.}
247        \label{fig:choose_icon}
248\end{figure}
249\clearpage
250
251Finally, we must set the icon as a \textit{Resource} to avoid including the icon as a separate file. Right-click on the icon and select \textit{Properties} as seen below.
252
253\begin{figure}[h!]
254        \centering
255                \includegraphics{figures/icon_properties.jpg}
256        \caption{Selecting the image properties.}
257        \label{fig:icon_properties}
258\end{figure}
259
260In the \textit{Properties} panel, set the \textit{Build Action} to \textit{Resource}.
261
262\begin{figure}[h!]
263        \centering
264                \includegraphics{figures/icon_build_action.jpg}
265        \caption{Selecting the icon's build action.}
266        \label{fig:icon_build_action}
267\end{figure}
268\clearpage
269
270\section{Input and output dockpoints}
271\label{sec:InputAndOutputDockpoints}
272
273\subsection{The input/output attributes}
274\label{sec:TheInputOutputAttributes}
275
276Next we will define five properties, each with an appropriate attribute, to be used for input and output. Th attributes are necessary to tell CrypTool 2 whether the properties are used for input or output and to provide the plugin with external data.
277
278The attribute that we will use for each proprerty is called \textit{[PropertyInfo]} and it consists of the following elements:
279
280\begin{itemize}
281        \item \textit{direction} --- defines whether this property is an input or output property, e.g.\ whether it reads input data or writes output data. The possible values are:
282        \begin{itemize}
283                \item \texttt{Direction.Input}
284                \item \texttt{Direction.Output}
285        \end{itemize}
286        \item \textit{caption} --- the caption for the property displayed over the input or output arrow of the icon after it has been placed in the editor; ``Input stream'' in the example below:
287       
288\begin{figure}[h!]
289        \centering
290                \includegraphics[width=.55\textwidth]{figures/property_caption.jpg}
291        \caption{A possible property caption and toolTip.}
292        \label{fig:property_caption}
293\end{figure}
294
295        \item \textit{toolTip} --- the toolTip for the property displayed over the input or output arrow of the icon after it has been placed in the editor; ``Input data to be hashed'' in the example above.
296        \item \textit{descriptionUrl} --- currently not used; fill it with \texttt{null} or an empty string.
297        \item \textit{mandatory} --- this flag determines whether an input must be attached by the user to use the plugin. If set to \texttt{true}, an input connection will be required or else the plugin will not be executed in the workflow chain. If set to \texttt{false}, connecting an input is optional. As this only applies to input properties, if the direction has been set to \texttt{Direction.Output}, this flag will be ignored.
298        \item \textit{hasDefaultValue} --- if this flag is set to \texttt{true}, CrypTool 2 will assume that the property has a default input value that does not require user input.
299        \item \textit{displayLevel} --- determines in which display levels your property will be shown in CrypTool~2. These are used to hide more advanced item from less-experienced users; a beginner using the corresponding display level will not see the properties marked as any other level, but a professional using the appropriate display level will have access to everything. These levels are as follows:
300       
301        \begin{itemize}
302                \item \texttt{DisplayLevel.Beginner}
303                \item \texttt{DisplayLevel.Experienced}
304                \item \texttt{DisplayLevel.Expert}
305                \item \texttt{DisplayLevel.Professional}
306        \end{itemize}
307       
308        \item \textit{quickWatchFormat} --- determines how the content of the property will be shown in the quickwatch perspective. CrypTool 2 accepts the following quickwatch formats:
309       
310        \begin{itemize}
311                \item \texttt{QuickWatchFormat.Base64}
312                \item \texttt{QuickWatchFormat.Hex}
313                \item \texttt{QuickWatchFormat.None}
314                \item \texttt{QuickWatchFormat.Text}
315        \end{itemize}
316
317\begin{figure}[h]
318        \centering
319                \includegraphics{figures/quick_watch.jpg}
320        \caption{A quickwatch display in hexadecimal.}
321        \label{fig:quick_watch}
322\end{figure}
323       
324        \item \textit{quickWatchConversionMethod} --- this is used to indicate a conversion method; most plugins do not ned to convert their data and thus should use a \texttt{null} value here. The quickwatch function uses the default system encoding to display data, so if your data is in another format, such as UTF-16 or Windows-1250, you should provide here the name of a conversion method as string. The header for such a method should look something like the following:
325
326\begin{lstlisting}
327object YourMethodName(string PropertyNameToConvert)
328\end{lstlisting}
329
330\end{itemize}
331
332\subsection{Defining the input/output properties}
333\label{sec:DefiningTheInputOutputProperties}
334
335The first of the five properties that we will define is \textit{InputString}. This is used to provide our plugin with the data to be encrypted or decrypted:
336
337\begin{lstlisting}
338[PropertyInfo(Direction.InputData, "Text input", "Input a string to be processed by the Caesar cipher", "", true, false, DisplayLevel.Beginner, QuickWatchFormat.Text, null)]
339public string InputString
340{
341        get { return this.inputString; }
342        set
343  {
344                if (value != inputString)
345                {
346                        this.inputString = value;
347                        OnPropertyChanged("InputString");
348                }
349        }
350}
351\end{lstlisting}
352
353\ \\
354In the get method we simply return the value of the input data. The set method checks if the input value has changed, and, if so, sets the new input data and announces the change to the CrypTool 2 environment by calling the function \textit{OnPropertyChanged(\textit{$<$Property name$>$})}. This step is necessary for input properties to update the quickwatch view. The output data property (which handles the input data after it has been encrypted or decrypted) will in our example look as follows:
355
356%\textit{\small Note 1: It is currently not possible to read directly from the input data stream without creating an intermediate CryptoolStream.\\\\
357%\small Note 2: The naming may be confusing. The new CryptoolStream is not an output stream, but it is added to the list of output streams to enable a clean dispose afterwards. See chapter 9 below.\\\\}
358
359\begin{lstlisting}
360[PropertyInfo(Direction.OutputData, "Text output", "The string after processing with the Caesar cipher", "", false, false, DisplayLevel.Beginner, QuickWatchFormat.Text, null)]
361public string OutputString
362{
363        get { return this.outputString; }
364        set
365        {
366                outputString = value;
367                OnPropertyChanged("OutputString");
368        }
369}
370\end{lstlisting}
371
372\ \\
373\indent CrypTool 2 does not require implementing set methods for output properties, as they will never be called from outside the plugin. Nevertheless, in our example the plugin itself accesses the property, and therefore we have chosen to implement the set method.
374
375You can provide additional output data types if you so desire. In our example, we will also offer output data of type \textit{CryptoolStream}, input data for external alphabets, and input data for the shift value of our Caesar algorithm. Note that for the first of these, the set method is not implemented since it will never be called. We shall define these properties as follows:
376
377\begin{lstlisting}
378[PropertyInfo(Direction.OutputData, "CryptoolStream output", "The raw CryptoolStream data after processing with the Caesar cipher", "", false, false, DisplayLevel.Beginner, QuickWatchFormat.Text, null)]
379public CryptoolStream OutputData
380{
381        get
382        {
383                if (outputString != null)
384                {
385                        CryptoolStream cs = new CryptoolStream();
386                        listCryptoolStreamsOut.Add(cs);
387                        cs.OpenRead(Encoding.Default.GetBytes(outputString.ToCharArray()));
388                        return cs;
389                }
390                else
391                {
392                        return null;
393                }
394        }
395        set { }
396}
397
398[PropertyInfo(Direction.InputData, "External alphabet input", "Input a string containing the alphabet to be used by Caesar.\nIf no alphabet is provided for this input, the internal default alphabet will be used.", "", false, false, DisplayLevel.Expert, QuickWatchFormat.Text, null)]
399public string InputAlphabet
400{
401        get { return ((CaesarSettings)this.settings).AlphabetSymbols; }
402        set
403        {
404                if (value != null && value != settings.AlphabetSymbols)
405                {
406                        ((CaesarSettings)this.settings).AlphabetSymbols = value;
407                        OnPropertyChanged("InputAlphabet");
408                }
409        }
410}
411
412[PropertyInfo(Direction.InputData, "Shift value (integer)", "This is the same setting as the shift value in the Settings pane but as dynamic input.", "", false, false, DisplayLevel.Expert, QuickWatchFormat.Text, null)]
413public int ShiftKey
414{
415        get { return settings.ShiftKey; }
416        set
417        {
418                if (value != settings.ShiftKey)
419                {
420                        settings.ShiftKey = value;
421                }
422        }
423}
424\end{lstlisting}
425
426\section{Implementing the actual algorithm}
427\label{sec:ImplementingTheActualAlgorithm}
428
429Algorithmic processing should be done in the \textit{Execute()} function. The actual functionality of your algorithm, as well as the structure thereof, is up to you. Below is our implementation of the Caesar algorithmic processing and the \textit{Execute()} function:
430
431\begin{lstlisting}
432private void ProcessCaesar(CaesarMode mode)
433{
434        CaesarSettings cfg = (CaesarSettings)this.settings;
435        StringBuilder output = new StringBuilder("");
436        string alphabet = cfg.AlphabetSymbols;
437
438        // If we are working in case-insensitive mode, we will use only
439        // capital letters, hence we must transform the whole alphabet
440        // to uppercase.
441        if (!cfg.CaseSensitiveAlphabet)
442        {
443                alphabet = cfg.AlphabetSymbols.ToUpper();
444        }
445
446        if (inputString != null)
447        {
448                for (int i = 0; i < inputString.Length; i++)
449                {
450                        // Get the plaintext char currently being processed.
451                        char currentchar = inputString[i];
452
453                        // Store whether it is upper case (otherwise lowercase is assumed).
454                        bool uppercase = char.IsUpper(currentchar);
455
456                        // Get the position of the plaintext character in the alphabet.
457                        int ppos = 0;
458                        if (cfg.CaseSensitiveAlphabet)
459                        {
460                                ppos = alphabet.IndexOf(currentchar);
461                        }
462                        else
463                        {
464                                ppos = alphabet.IndexOf(char.ToUpper(currentchar));
465                        }
466
467                        if (ppos >= 0)
468                        {
469                                // We found the plaintext character in the alphabet,
470                                // hence we will commence shifting.
471                                int cpos = 0;
472                                switch (mode)
473                                {
474                                        case CaesarMode.encrypt:
475                                                cpos = (ppos + cfg.ShiftKey) % alphabet.Length;
476                                                break;
477                                        case CaesarMode.decrypt:
478                                                cpos = (ppos - cfg.ShiftKey + alphabet.Length) % alphabet.Length;
479                                                break;
480                                }
481
482                                // We have the position of the ciphertext character,
483                                // hence just output it in the correct case.
484                                if (cfg.CaseSensitiveAlphabet)
485                                {
486                                        output.Append(alphabet[cpos]);
487                                }
488                                else
489                                {
490                                        if (uppercase)
491                                        {
492                                                output.Append(char.ToUpper(alphabet[cpos]));
493                                        }
494                                        else
495                                        {
496                                                output.Append(char.ToLower(alphabet[cpos]));
497                                        }
498                                }
499                        }
500                        else
501                        {
502                                // The plaintext character was not found in the alphabet,
503                                // hence proceed with handling unknown characters.
504                                switch ((CaesarSettings.UnknownSymbolHandlingMode)cfg.UnknownSymbolHandling)
505                                {
506                                        case CaesarSettings.UnknownSymbolHandlingMode.Ignore:
507                                                output.Append(inputString[i]);
508                                                break;
509                                        case CaesarSettings.UnknownSymbolHandlingMode.Replace:
510                                                output.Append('?');
511                                                break;
512                                }
513                        }
514
515                        // Show the progress.
516                        ProgressChanged(i, inputString.Length - 1);
517                }
518                outputString = output.ToString();
519                OnPropertyChanged("OutputString");
520                OnPropertyChanged("OutputData");
521        }
522}
523
524public void Execute()
525{
526        switch (settings.Action)
527        {
528                case 0:
529                        GuiLogMessage("Encrypting", NotificationLevel.Debug);
530                        ProcessCaesar(CaesarMode.encrypt);
531                        break;
532                case 1:
533                        GuiLogMessage("Decrypting", NotificationLevel.Debug);
534                        ProcessCaesar(CaesarMode.decrypt);
535                        break;
536                default:
537        break;
538        }
539}
540\end{lstlisting}
541
542It is important to make sure that all changes to the output properties will be announced to the CrypTool 2 environment. In our example this happens by calling the set method of \textit{OutputData}, which in turn calls \textit{OnPropertyChanged} to indicate that both output properties \textit{OutputData} and \textit{OutputDataStream} have changed. Instead of calling the property's set method you could instead call \textit{OnPropertyChanged} directly within the \textit{Execute()} method.
543
544\subsection{Sending messages to the CrypTool 2 core}
545\label{sec:SendingMessagesToTheCrypTool2Core}
546
547The CrypTool 2 API provides three methods to send messages from the plugin to the CrypTool 2 core. \textit{GuiLogMessage} is used to send messages to the CrypTool 2 status bar. This method is a nice mechanism to inform the user as to what your plugin is currently doing. \textit{OnPropertyChanged} is used to inform the core application of changes to any data output properties. This is necessary for a correct plugin execution. \textit{ProgressChanged} is used to visualize the progress of the algorithm as a bar.
548
549\begin{figure}[h]
550        \centering
551                \includegraphics[width=1.00\textwidth]{figures/status_bar.jpg}
552        \caption{An example status bar.}
553        \label{fig:status_bar}
554\end{figure}
555
556The \textit{GuiLogMessage} method takes two parameters:
557
558\begin{itemize}
559        \item \textit{Message} --- the text to be shown in the status bar.
560        \item \textit{NotificationLevel} --- the type of message, that is, its alert level:
561        \begin{itemize}
562                \item \texttt{NotificationLevel.Error}
563                \item \texttt{NotificationLevel.Warning}
564                \item \texttt{NotificationLevel.Info}
565                \item \texttt{NotificationLevel.Debug}
566        \end{itemize}
567\end{itemize}
568
569\subsection{Performing a clean dispose}
570\label{sec:PerformingACleanDispose}
571
572Be sure you have closed and cleaned all your streams after execution before CrypTool 2 decides to dispose the plugin instance. There has been some misunderstanding about the meaning of \textit{Dispose()}. Dispose will be called ultimately before object destruction. After disposal, the object will be in an undefined state.
573
574\begin{lstlisting}
575public void Dispose()
576{
577        foreach(CryptoolStream stream in listCryptoolStreamsOut)
578        {
579                stream.Close();
580        }
581        listCryptoolStreamsOut.Clear();
582}
583\end{lstlisting}
584
585\section{Drawing the workflow of your plugin}
586\label{DrawingTheWorkfloweOfYourPlugin}
587
588Each plugin should have an associated workflow file to show the algorithm in action in CrypTool 2. These workflow files are saved with the special \textit{.cte} file extension. You can view the example files from other plugins by opening any of the files in the \texttt{ProjectSamples\textbackslash} folder with CrypTool 2. Below is a sample workflow for our Caesar example:
589
590\begin{figure}[h]
591        \centering
592                \includegraphics{figures/sample.jpg}
593        \caption{A sample workflow diagram for the Caesar algorithm.}
594        \label{fig:sample}
595\end{figure}
596
597As your last step of development, once your plugin runs smoothly, you should also create one of these sample workflow files for your plugin. Such a file can be automatically created by simply saving a CrypTool 2 workspace project featuring your plugin. You should store the workflow file in the \texttt{ProjectSamples\textbackslash} folder and make sure to commit the file to the SVN repository (see Section \ref{CommitingYourChanges}).
Note: See TracBrowser for help on using the repository browser.