source: trunk/Documentation/Developer/PluginHowTo/part2.tex @ 1626

Last change on this file since 1626 was 1626, checked in by Matthäus Wander, 11 years ago

HowTo:

  • reworked part 2
  • removed no longer needed stuff (the plugin template saves a lot of manual work)
  • moved very long settings example to appendix
File size: 32.6 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 assume, you have retrieved the CrypTool 2 source code from the SVN repository, have set up Visual Studio 2010 or Visual C\# 2010 Express to build CrypTool 2, and you have placed the template at 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 did not to download the entire CrypTool 2 source code as described in Section \ref{CheckingOutTheSources}, you can still get a copy of 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 opening up, 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 location for your project (Figure~\ref{fig:vs_create_new_project}).
17
18\begin{figure}
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 set up in the template correctly, you should now be able to compile the new plugin. First of all, rename the two files in the solution explorer to some more meaningful filenames, for example \texttt{Caesar.cs} and \texttt{CaesarSettings.cs}.
26
27\begin{figure}
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, what you should change in order to adapt the plugin skeleton to your custom implementation. Most \texttt{HOWTO} hints are self-explanatory and we won't discuss all of them 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
60\subsection{The \protect\textit{[Author]} attribute}
61\label{sec:TheAuthorAttribute}
62
63The \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.
64
65\begin{figure}[h!]
66        \centering
67                \includegraphics[width=.90\textwidth]{figures/attribute_author.jpg}
68        \caption{The defintion for the \textit{[Author]} attribute.}
69        \label{fig:attribute_author}
70\end{figure}
71
72As can be seen above, the author attribute takes four elements of type string. These elements are:
73
74\begin{itemize}
75        \item \textit{Author} --- the name of the plugin developer.
76        \item \textit{Email} --- the email address of the plugin developer, should he or she wish to be available for contact.
77        \item \textit{Institute} --- the organization, company or university with which the developer is affiliated.
78        \item \textit{URL} --- the website of the developer or of his or her institution.
79\end{itemize}
80
81All 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.
82
83\subsection{The \protect\textit{[PluginInfo]} attribute}
84\label{sec:ThePluginInfoAttribute}
85
86The 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:
87
88\begin{figure}[h]
89        \centering
90                \includegraphics[width=1.00\textwidth]{figures/attribute_plugininfo.jpg}
91        \caption{The defintion for the \textit{[PluginInfo]} attribute.}
92        \label{fig:attribute_plugininfo}
93\end{figure}
94
95\noindent This attribute has the following parameters:
96
97\begin{itemize}
98        \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.
99        \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.
100        \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.
101        \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.
102        \item \textit{DescriptionURL} --- the local path of the description file (e.g.\ XAML file). This element is optional.
103        \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.
104\end{itemize}
105
106\noindent Unused elements should be set to \texttt{null} or an empty string.
107
108There 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.
109
110In 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.
111
112The second parameter, \textit{startable}, should be set to \texttt{false}, because our encryption algorithm is not an input generator.
113
114The 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.)
115
116The \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:
117
118\begin{figure}[h!]
119        \centering
120                \includegraphics[width=.30\textwidth]{figures/detailed_description.jpg}
121        \caption{The folder structure as seen in the Solution Explorer.}
122        \label{fig:attribute_plugininfo_icon_path}
123\end{figure}
124
125Once 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} (Figure~\ref{fig:xaml_description}).
126
127\begin{figure}
128        \centering
129                \includegraphics[width=1.00\textwidth]{figures/xaml_description.jpg}
130        \caption{A detailed description provided through an XAML file.}
131        \label{fig:xaml_description}
132\end{figure}
133
134The 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$>$}.
135
136The 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}.
137
138If 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.)
139
140\subsection{Algorithm category and the \protect\textit{[EncryptionType]} attribute}
141
142In the CrypTool 2 user interface plugins are grouped by their algorithm category, for example hash algorithm, encryption algorithm 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 choice of a subcategory, which is entered as attribute\footnote{The current category system is unhandy and will be changed in future, see trac ticket \#50.}. In our example, Caesar inherits from \textit{IEncryption} and needs the attribute \textit{[EncryptionType]}.
143
144\begin{lstlisting}
145    [EncryptionType(EncryptionType.Classic)]
146    public class Caesar : IEncryption
147                {
148\end{lstlisting}
149
150The possible values of the \textit{[EncryptionType]} attribute are as follows:
151
152\begin{itemize}
153        \item \textit{Asymmetric} --- for asymmetrical encryption algorithms, such as RSA.
154        \item \textit{SymmetricBlock} --- for block cipher algorithms, such as DES, AES and Twofish.
155        \item \textit{SymmetricStream} --- for stream cipher algorithms, such as RC4, Rabbit and SEAL.
156        \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.
157        \item \textit{Classic} --- for classical encryption or hash algorithms, such as Caesar or MD5.
158\end{itemize}
159
160\subsection{Importing CrypPluginBase namespaces}
161\label{sec:ImportingCrypPluginBaseNamespaces}
162
163Depending 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:
164
165\begin{itemize}
166        \item \textit{Cryptool.PluginBase} --- contains interfaces such as \textit{IPlugin}, \textit{IHash}, and \textit{ISettings}, as well as attributes, enumerations, delegates and extensions.
167        \item \textit{Cryptool.PluginBase.Analysis} --- contains interfaces for cryptanalysis plugins (such as \textit{Stream Comparator}).
168        \item \textit{Cryptool.PluginBase.Control} --- contains global interfaces for the \textit{IControl} feature for defining custom controls.
169        \item \textit{Cryptool.PluginBase.Cryptography} --- contains interfaces for encryption and hash algorithms such as AES, DES and MD5.
170        \item \textit{Cryptool.PluginBase.Editor} --- contains interfaces for editors that can be implemented in CrypTool 2, such as the default editor.
171        \item \textit{Cryptool.PluginBase.Generator} --- contains interfaces for generators, including the random input generator.
172        \item \textit{Cryptool.PluginBase.IO} --- contains interfaces for input, output and the \textit{CryptoolStream}.
173        \item \textit{Cryptool.PluginBase.Miscellaneous} --- contains assorted helper classes, including \textit{GuiLogMessage} and \textit{PropertyChanged}.
174        \item \textit{Cryptool.PluginBase.Resources} --- used only by CrypWin and the editor; not necessary for plugin development.
175        \item \textit{Cryptool.PluginBase.Tool} --- contains an interface for standalone tools in CrypTool~2 that are not run in a workspace editor.
176        \item \textit{Cryptool.PluginBase.Validation} --- contains interfaces for validation methods, including regular expressions.
177\end{itemize}
178
179\noindent In our example, the Caesar algorithm necessitates the inclusion of the following namespaces:
180
181\begin{itemize}
182        \item \textit{Cryptool.PluginBase} --- to implement \textit{ISettings} in the CaesarSettings class.
183        \item \textit{Cryptool.PluginBase.Cryptography} --- to implement \textit{IEncryption} in the Caesar class.
184        \item \textit{Cryptool.PluginBase.IO} --- to use CryptoolStream for data input and output.
185        \item \textit{Cryptool.PluginBase.Miscellaneous} --- to use the CrypTool event handler.
186\end{itemize}
187
188\section{Defining the private variables of the settings in the Caesar class}
189\label{sec:DefiningThePrivateVariablesOfTheSettingsInTheCaesarClass}
190
191The 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:
192
193\begin{lstlisting}
194        #region Private variables
195        private CaesarSettings settings;
196        private string inputString;
197        private string outputString;
198        private enum CaesarMode { encrypt, decrypt };
199        private List<CryptoolStream> listCryptoolStreamsOut = new List<CryptoolStream>();
200        #endregion
201\end{lstlisting}
202
203\ \\ % ugly but functional
204If 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}.
205
206Our example makes use of the following private variables:
207
208\begin{itemize}
209        \item \texttt{CaesarSettings settings} --- required to implement the IPlugin interface properly.
210        \item \texttt{string inputString} --- string from which to read the input data.
211        \item \texttt{string outputString} --- string to which to save the output data.
212        \item \texttt{enum CaesarMode} --- used to select either encryption or decryption.
213        \item \texttt{List$<$CryptoolStream$>$ listCryptoolStreamsOut} --- a list of all streams created by the plugin, which helps to perform a clean dispose.
214\end{itemize}
215
216\subsection{Adding controls to the CaesarSettings class}
217\label{sec:AddingControlsToTheCaesarSettingsClass}
218
219The settings class contains the necessary information about controls, captions, descriptions and default parameters (e.g.\ for key settings, alphabets, key length and type of action) 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. Thus we will need to 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 (i.e.\ 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.
220
221\section{Adding an icon to the Caesar class}
222\label{sec:AddingAnIconToTheCaesarClass}
223
224Before we go back to the code of the Caesar class, we add a custom icon to our project, which will 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 a custom own.
225
226The 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, we created 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}.
227
228\begin{figure}[h!]
229        \centering
230                \includegraphics{figures/add_existing_item.jpg}
231        \caption{Adding an existing item.}
232        \label{fig:add_existing_item}
233\end{figure}
234\clearpage
235
236A new window will then appear. Select \textit{Image Files} as the file type and select your newly-created icon for your plugin.
237
238\begin{figure}[h!]
239        \centering
240                \includegraphics{figures/choose_icon.jpg}
241        \caption{Selecting the image file.}
242        \label{fig:choose_icon}
243\end{figure}
244\clearpage
245
246Finally, 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.
247
248\begin{figure}[h!]
249        \centering
250                \includegraphics{figures/icon_properties.jpg}
251        \caption{Selecting the image properties.}
252        \label{fig:icon_properties}
253\end{figure}
254
255In the \textit{Properties} panel, set the \textit{Build Action} to \textit{Resource}.
256
257\begin{figure}[h!]
258        \centering
259                \includegraphics{figures/icon_build_action.jpg}
260        \caption{Selecting the icon's build action.}
261        \label{fig:icon_build_action}
262\end{figure}
263\clearpage
264
265\section{Input and output dockpoints}
266
267\subsection{The input/output attributes}
268\label{sec:TheInputOutputAttributes}
269
270Next 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.
271
272The attribute that we will use for each proprerty is called \textit{[PropertyInfo]} and it consists of the following elements:
273
274\begin{itemize}
275        \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:
276        \begin{itemize}
277                \item \texttt{Direction.Input}
278                \item \texttt{Direction.Output}
279        \end{itemize}
280        \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:
281       
282\begin{figure}[h!]
283        \centering
284                \includegraphics[width=.55\textwidth]{figures/property_caption.jpg}
285        \caption{A possible property caption and toolTip.}
286        \label{fig:property_caption}
287\end{figure}
288
289        \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.
290        \item \textit{descriptionUrl} --- currently not used; fill it with \texttt{null} or an empty string.
291        \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.
292        \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.
293        \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:
294       
295        \begin{itemize}
296                \item \texttt{DisplayLevel.Beginner}
297                \item \texttt{DisplayLevel.Experienced}
298                \item \texttt{DisplayLevel.Expert}
299                \item \texttt{DisplayLevel.Professional}
300        \end{itemize}
301       
302        \item \textit{quickWatchFormat} --- determines how the content of the property will be shown in the quickwatch perspective. CrypTool 2 accepts the following quickwatch formats:
303       
304        \begin{itemize}
305                \item \texttt{QuickWatchFormat.Base64}
306                \item \texttt{QuickWatchFormat.Hex}
307                \item \texttt{QuickWatchFormat.None}
308                \item \texttt{QuickWatchFormat.Text}
309        \end{itemize}
310
311\begin{figure}[h]
312        \centering
313                \includegraphics{figures/quick_watch.jpg}
314        \caption{A quickwatch display in hexadecimal.}
315        \label{fig:quick_watch}
316\end{figure}
317       
318        \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:
319
320\begin{lstlisting}
321object YourMethodName(string PropertyNameToConvert)
322\end{lstlisting}
323
324\end{itemize}
325
326\subsection{Defining the input/output properties}
327\label{sec:DefiningTheInputOutputProperties}
328
329The 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:
330
331\begin{lstlisting}
332[PropertyInfo(Direction.InputData, "Text input", "Input a string to be processed by the Caesar cipher", "", true, false, DisplayLevel.Beginner, QuickWatchFormat.Text, null)]
333public string InputString
334{
335        get { return this.inputString; }
336        set
337  {
338                if (value != inputString)
339                {
340                        this.inputString = value;
341                        OnPropertyChanged("InputString");
342                }
343        }
344}
345\end{lstlisting}
346
347\ \\
348In 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:
349
350%\textit{\small Note 1: It is currently not possible to read directly from the input data stream without creating an intermediate CryptoolStream.\\\\
351%\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.\\\\}
352
353\begin{lstlisting}
354[PropertyInfo(Direction.OutputData, "Text output", "The string after processing with the Caesar cipher", "", false, false, DisplayLevel.Beginner, QuickWatchFormat.Text, null)]
355public string OutputString
356{
357        get { return this.outputString; }
358        set
359        {
360                outputString = value;
361                OnPropertyChanged("OutputString");
362        }
363}
364\end{lstlisting}
365
366\ \\
367\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.
368
369You 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:
370
371\begin{lstlisting}
372[PropertyInfo(Direction.OutputData, "CryptoolStream output", "The raw CryptoolStream data after processing with the Caesar cipher", "", false, false, DisplayLevel.Beginner, QuickWatchFormat.Text, null)]
373public CryptoolStream OutputData
374{
375        get
376        {
377                if (outputString != null)
378                {
379                        CryptoolStream cs = new CryptoolStream();
380                        listCryptoolStreamsOut.Add(cs);
381                        cs.OpenRead(Encoding.Default.GetBytes(outputString.ToCharArray()));
382                        return cs;
383                }
384                else
385                {
386                        return null;
387                }
388        }
389        set { }
390}
391
392[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)]
393public string InputAlphabet
394{
395        get { return ((CaesarSettings)this.settings).AlphabetSymbols; }
396        set
397        {
398                if (value != null && value != settings.AlphabetSymbols)
399                {
400                        ((CaesarSettings)this.settings).AlphabetSymbols = value;
401                        OnPropertyChanged("InputAlphabet");
402                }
403        }
404}
405
406[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)]
407public int ShiftKey
408{
409        get { return settings.ShiftKey; }
410        set
411        {
412                if (value != settings.ShiftKey)
413                {
414                        settings.ShiftKey = value;
415                }
416        }
417}
418\end{lstlisting}
419
420\section{Implementing the actual algorithm}
421
422Algorithmic 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:
423
424\begin{lstlisting}
425private void ProcessCaesar(CaesarMode mode)
426{
427        CaesarSettings cfg = (CaesarSettings)this.settings;
428        StringBuilder output = new StringBuilder("");
429        string alphabet = cfg.AlphabetSymbols;
430
431        // If we are working in case-insensitive mode, we will use only
432        // capital letters, hence we must transform the whole alphabet
433        // to uppercase.
434        if (!cfg.CaseSensitiveAlphabet)
435        {
436                alphabet = cfg.AlphabetSymbols.ToUpper();
437        }
438
439        if (inputString != null)
440        {
441                for (int i = 0; i < inputString.Length; i++)
442                {
443                        // Get the plaintext char currently being processed.
444                        char currentchar = inputString[i];
445
446                        // Store whether it is upper case (otherwise lowercase is assumed).
447                        bool uppercase = char.IsUpper(currentchar);
448
449                        // Get the position of the plaintext character in the alphabet.
450                        int ppos = 0;
451                        if (cfg.CaseSensitiveAlphabet)
452                        {
453                                ppos = alphabet.IndexOf(currentchar);
454                        }
455                        else
456                        {
457                                ppos = alphabet.IndexOf(char.ToUpper(currentchar));
458                        }
459
460                        if (ppos >= 0)
461                        {
462                                // We found the plaintext character in the alphabet,
463                                // hence we will commence shifting.
464                                int cpos = 0;
465                                switch (mode)
466                                {
467                                        case CaesarMode.encrypt:
468                                                cpos = (ppos + cfg.ShiftKey) % alphabet.Length;
469                                                break;
470                                        case CaesarMode.decrypt:
471                                                cpos = (ppos - cfg.ShiftKey + alphabet.Length) % alphabet.Length;
472                                                break;
473                                }
474
475                                // We have the position of the ciphertext character,
476                                // hence just output it in the correct case.
477                                if (cfg.CaseSensitiveAlphabet)
478                                {
479                                        output.Append(alphabet[cpos]);
480                                }
481                                else
482                                {
483                                        if (uppercase)
484                                        {
485                                                output.Append(char.ToUpper(alphabet[cpos]));
486                                        }
487                                        else
488                                        {
489                                                output.Append(char.ToLower(alphabet[cpos]));
490                                        }
491                                }
492                        }
493                        else
494                        {
495                                // The plaintext character was not found in the alphabet,
496                                // hence proceed with handling unknown characters.
497                                switch ((CaesarSettings.UnknownSymbolHandlingMode)cfg.UnknownSymbolHandling)
498                                {
499                                        case CaesarSettings.UnknownSymbolHandlingMode.Ignore:
500                                                output.Append(inputString[i]);
501                                                break;
502                                        case CaesarSettings.UnknownSymbolHandlingMode.Replace:
503                                                output.Append('?');
504                                                break;
505                                }
506                        }
507
508                        // Show the progress.
509                        ProgressChanged(i, inputString.Length - 1);
510                }
511                outputString = output.ToString();
512                OnPropertyChanged("OutputString");
513                OnPropertyChanged("OutputData");
514        }
515}
516
517public void Execute()
518{
519        switch (settings.Action)
520        {
521                case 0:
522                        GuiLogMessage("Encrypting", NotificationLevel.Debug);
523                        ProcessCaesar(CaesarMode.encrypt);
524                        break;
525                case 1:
526                        GuiLogMessage("Decrypting", NotificationLevel.Debug);
527                        ProcessCaesar(CaesarMode.decrypt);
528                        break;
529                default:
530        break;
531        }
532}
533\end{lstlisting}
534
535It 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.
536
537\subsection{Sending messages to the CrypTool 2 core}
538\label{sec:SendingMessagesToTheCrypTool2Core}
539
540The 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.
541
542\begin{figure}[h]
543        \centering
544                \includegraphics[width=1.00\textwidth]{figures/status_bar.jpg}
545        \caption{An example status bar.}
546        \label{fig:status_bar}
547\end{figure}
548
549The \textit{GuiLogMessage} method takes two parameters:
550
551\begin{itemize}
552        \item \textit{Message} --- the text to be shown in the status bar.
553        \item \textit{NotificationLevel} --- the type of message, that is, its alert level:
554        \begin{itemize}
555                \item \texttt{NotificationLevel.Error}
556                \item \texttt{NotificationLevel.Warning}
557                \item \texttt{NotificationLevel.Info}
558                \item \texttt{NotificationLevel.Debug}
559        \end{itemize}
560\end{itemize}
561
562\subsection{Performing a clean dispose}
563
564Be 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.
565
566\begin{lstlisting}
567public void Dispose()
568{
569        foreach(CryptoolStream stream in listCryptoolStreamsOut)
570        {
571                stream.Close();
572        }
573        listCryptoolStreamsOut.Clear();
574}
575\end{lstlisting}
576
577\section{Drawing the workflow of your plugin}
578\label{DrawingTheWorkfloweOfYourPlugin}
579
580Each 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:
581
582\begin{figure}[h]
583        \centering
584                \includegraphics{figures/sample.jpg}
585        \caption{A sample workflow diagram for the Caesar algorithm.}
586        \label{fig:sample}
587\end{figure}
588
589As your last step of development, once your plugin runs smoothly, you should also create one of these sample workflow files for 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.