Changeset 2656


Ignore:
Timestamp:
Feb 11, 2011, 1:02:48 PM (11 years ago)
Author:
Matthäus Wander
Message:

Caesar:

  • Removed unnecessary private variables
  • Removed OnPropertyChanged calls on input parameters -> currently leads to non-updated quickviews, which is an Editor flaw (Editor should refresh quickview when passing parameters into plugin)
  • Updated code comments from Howto

Plugin Howto:

  • Updated code snippets from Caesar plugin
  • Removed full Caesar example in appendix (totally out-of-sync with actual source code, it's better to grab the current version online from trunk)
  • Removed obsolete x64 note
  • Removed self-adulation from abstract
  • Added wiki reference to abstract
  • Increased version to 0.7
Location:
trunk
Files:
2 deleted
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/CrypPlugins/Caesar/Caesar.cs

    r2529 r2656  
    3333    public class Caesar : IEncryption
    3434    {
    35         #region Private variables
     35        #region Private elements
    3636
    3737        private CaesarSettings settings;
    38         private string inputString;
    39         private string outputString;
     38        private bool isPlayMode = false;
     39
    4040        private enum CaesarMode { encrypt, decrypt };
    41         private bool isPlayMode = false;
     41
    4242        #endregion
    4343       
     
    5959        public ISettings Settings
    6060        {
    61             get { return (ISettings)this.settings; }
    62             set { this.settings = (CaesarSettings)value; }
     61            get { return this.settings; }
    6362        }
    6463
     
    6968            get
    7069            {
    71                 if (outputString != null)
     70                if (OutputString != null)
    7271                {                   
    73                     return new CStreamWriter(Encoding.Default.GetBytes(outputString));
     72                    return new CStreamWriter(Encoding.Default.GetBytes(OutputString));
    7473                }
    75                 else
    76                 {
    77                     return null;
    78                 }
    79             }
    80             set { }
    81         }
    82 
     74
     75                return null;
     76            }
     77        }
    8378
    8479        [PropertyInfo(Direction.InputData, "Text input", "Input a string to be processed by the Caesar cipher", "", true, false, QuickWatchFormat.Text, null)]
    8580        public string InputString
    8681        {
    87             get { return this.inputString; }
    88             set
    89             {
    90               if (value != inputString)
    91               {
    92                 this.inputString = value;
    93                 OnPropertyChanged("InputString");
    94               }
    95             }
     82            get;
     83            set;
    9684        }
    9785
     
    9987        public string OutputString
    10088        {
    101             get { return this.outputString; }
    102             set
    103             {
    104                 outputString = value;
    105                 OnPropertyChanged("OutputString");
    106             }
     89            get;
     90            set;
    10791        }
    10892
     
    11195        public string InputAlphabet
    11296        {
    113             get { return ((CaesarSettings)this.settings).AlphabetSymbols; }
     97            get { return this.settings.AlphabetSymbols; }
    11498            set
    11599            {
    116100              if (value != null && value != settings.AlphabetSymbols)
    117101              {
    118                 ((CaesarSettings)this.settings).AlphabetSymbols = value;
     102                this.settings.AlphabetSymbols = value;
    119103                OnPropertyChanged("InputAlphabet");
    120104              }
     
    128112          set
    129113          {
    130             if (value != settings.ShiftKey)
    131             {
    132114              settings.ShiftKey = value;
    133               // Execute();
    134             }
    135115          }
    136116        }
     
    163143        public void Dispose()
    164144        {
    165           }
     145        }
    166146
    167147        public bool HasChanges
     
    172152
    173153        /// <summary>
    174         /// Feuern, wenn sich sich eine Änderung des Fortschrittsbalkens ergibt
     154        /// Fires events to indicate progress bar changes.
    175155        /// </summary>
    176156        public event PluginProgressChangedEventHandler OnPluginProgressChanged;
    177 
    178         /// <summary>
    179         /// Feuern, wenn ein neuer Text im Statusbar angezeigt werden soll.
     157        private void ProgressChanged(double value, double max)
     158        {
     159            EventsHelper.ProgressChanged(OnPluginProgressChanged, this, new PluginProgressEventArgs(value, max));
     160        }
     161
     162        /// <summary>
     163        /// Fires events to indicate log messages.
    180164        /// </summary>
    181165        public event GuiLogNotificationEventHandler OnGuiLogNotificationOccured;
    182 
    183         /// <summary>
    184         /// Hier kommt das Darstellungs Control hin, Jungs!
     166        private void GuiLogMessage(string p, NotificationLevel notificationLevel)
     167        {
     168            EventsHelper.GuiLogMessage(OnGuiLogNotificationOccured, this, new GuiLogEventArgs(p, this, notificationLevel));
     169        }
     170
     171        /// <summary>
     172        /// Algorithm visualization (if any)
    185173        /// </summary>
    186174        public UserControl Presentation
     
    233221            string alphabet = cfg.AlphabetSymbols;
    234222
    235             // in case we want don't consider case in the alphabet, we use only capital letters, hence transform
    236             // the whole alphabet to uppercase
     223            // If we are working in case-insensitive mode, we will use only
     224            // capital letters, hence we must transform the whole alphabet
     225            // to uppercase.
    237226            if (!cfg.CaseSensitiveAlphabet)
    238227            {
     
    241230           
    242231
    243             if (inputString != null)
    244             {
    245                 for (int i = 0; i < inputString.Length; i++)
     232            if (!string.IsNullOrEmpty(InputString))
     233            {
     234                for (int i = 0; i < InputString.Length; i++)
    246235                {
    247                     // get plaintext char which is currently processed
    248                     char currentchar = inputString[i];
    249 
    250                     // remember if it is upper case (otherwise lowercase is assumed)
     236                    // Get the plaintext char currently being processed.
     237                    char currentchar = InputString[i];
     238
     239                    // Store whether it is upper case (otherwise lowercase is assumed).
    251240                    bool uppercase = char.IsUpper(currentchar);
    252241
    253                     // get the position of the plaintext character in the alphabet
     242                    // Get the position of the plaintext character in the alphabet.
    254243                    int ppos = 0;
    255244                    if (cfg.CaseSensitiveAlphabet)
     
    264253                    if (ppos >= 0)
    265254                    {
    266                         // we found the plaintext character in the alphabet, hence we do the shifting
     255                        // We found the plaintext character in the alphabet,
     256                        // hence we will commence shifting.
    267257                        int cpos = 0; ;
    268258                        switch (mode)
     
    276266                        }
    277267
    278                         // we have the position of the ciphertext character, hence just output it in the correct case
     268                        // We have the position of the ciphertext character,
     269                        // hence just output it in the correct case.
    279270                        if (cfg.CaseSensitiveAlphabet)
    280271                        {
     
    296287                    else
    297288                    {
    298                         // the plaintext character was not found in the alphabet, hence proceed with handling unknown characters
     289                        // The plaintext character was not found in the alphabet,
     290                        // hence proceed with handling unknown characters.
    299291                        switch ((CaesarSettings.UnknownSymbolHandlingMode)cfg.UnknownSymbolHandling)
    300292                        {
    301293                            case CaesarSettings.UnknownSymbolHandlingMode.Ignore:
    302                                 output.Append(inputString[i]);
     294                                output.Append(InputString[i]);
    303295                                break;
    304296                            case CaesarSettings.UnknownSymbolHandlingMode.Replace:
     
    309301                    }
    310302
    311                     //show the progress
    312                     if (OnPluginProgressChanged != null)
    313                     {
    314                       OnPluginProgressChanged(this, new PluginProgressEventArgs(i, inputString.Length - 1));
    315                     }
     303                    // Show the progress.
     304                    ProgressChanged(i, InputString.Length - 1);
    316305
    317306                }
    318                 outputString = output.ToString();
     307                OutputString = output.ToString();
    319308                OnPropertyChanged("OutputString");
    320309                OnPropertyChanged("OutputData");
    321                 OnPropertyChanged("InputString");
    322310            }
    323311        }
     
    329317        private void Caesar_LogMessage(string msg, NotificationLevel loglevel)
    330318        {
    331             EventsHelper.GuiLogMessage(OnGuiLogNotificationOccured, this, new GuiLogEventArgs(msg, this, loglevel));
    332             //if (OnGuiLogNotificationOccured != null)
    333             //{
    334             //    OnGuiLogNotificationOccured(this, new GuiLogEventArgs(msg, this, loglevel));
    335             //}
     319            GuiLogMessage(msg, loglevel);
    336320        }
    337321
     
    342326        {
    343327            if (isPlayMode)
    344                 Execute();
     328            {
     329                Execute();   
     330            }
    345331        }
    346332
  • trunk/Documentation/PluginHowTo/HowToDeveloper.tex

    r1636 r2656  
    124124\author{S.\ Przybylski, A.\ Wacker, M.\ Wander, F.\ Enkler and P.\ Vacek}
    125125\email{\{przybylski$|$wacker$|$wander$|$enkler$|$vacek\}@cryptool.org}
    126 \version{0.6}
     126\version{0.7}
    127127\date{\today}
    128128
     
    168168
    169169        \begin{abstract}
    170 CrypTool 2 is the modern successor of the well-known e-learning platform for cryptography and cryptanalysis \htmladdnormallink{CrypTool 1}{http://www.cryptool.org/}, which is used worldwide for educational purposes at schools and universities as well as in companies and agencies.
     170CrypTool~2 is the successor of the well-known e-learning platform for cryptography and cryptanalysis CrypTool\footnote{\url{http://www.cryptool.org/}}, which is used for educational purposes at schools and universities as well as in companies and agencies. As of January 2010, CrypTool~2 consists of over 7000 lines of C\# code in the core application and over 250,000 lines of C\# code in about 100 plugins.
    171171
    172 Since the first launch of CrypTool 1 in 1999 the art of software development has changed dramatically. The CrypTool 2 team began working in 2008 to develop a completely new e-learning application, embracing the newest trends in both didactics and software architecture to delight the end-user with an entirely new experience.\\
    173 
    174 To reach these goals, CrypTool 2 is built using the following:
     172CrypTool~2 is built using the following technologies and development tools:
    175173
    176174\begin{itemize}
    177175        \item .NET (a modern software framework from Microsoft with solutions to common programming problems)
    178176        \item C\# (a modern object-oriented programming language, comparable to Java)
    179     \item WPF (a modern purely vector-based graphical subsystem for rendering user interfaces in Windows-based applications)
    180     \item Visual Studio 2010 (a development environment)
     177  \item WPF (a modern vector-based graphical subsystem for rendering user interfaces in Windows-based applications)
     178  \item Visual Studio 2010 (a development environment)
    181179        \item Subversion (a source code and documentation version management system)
     180        \item trac (a lightweight web-based software project management system)
    182181\end{itemize}
    183182
    184 This document is intended for plugin developers who want to contribute new visual or mathematical functionality to CrypTool 2. As of January 2010, the program consists of over 7000 lines of C\# code in the core application and over 250,000 lines of C\# code in about 100 plugins.
    185 
    186 For further information, please visit the CrypTool 2 website at \htmladdnormallink{http://www.cryptool2.vs.uni-due.de}{http://www.cryptool2.vs.uni-due.de}.
     183This document is intended for plugin developers who want to contribute a new plugin to CrypTool~2 which implements a cryptographic algorithm or similar functionality. Please note that CrypTool~2 is an alive project in development. Certain information may be outdated or missing. If you want to stay up-to-date, we recommend checking out the CrypTool~2 development wiki\footnote{\url{https://www.cryptool.org/trac/CrypTool2/wiki}} and website\footnote{\url{http://cryptool2.vs.uni-due.de/}}.
    187184    \end{abstract}
    188185
     
    194191        \include{part1}
    195192        \include{part2}
    196        
    197         \begin{appendix}
    198         \include{appendix}
    199         \end{appendix}
    200193
    201194\end{document}
  • trunk/Documentation/PluginHowTo/frontpage.tex

    r1156 r2656  
    4040
    4141
    42 % Default values
    43 \date{\today}
    44 \author{}
    45 \title{}
    46 \subtitle{Paris}
    47 \version{}
    48 \email{no email address}
    49 
    50 
    51 
    5242\makeatother
  • trunk/Documentation/PluginHowTo/part1.tex

    r1636 r2656  
    160160\label{CompilingTheSourcesVS}
    161161
    162 By this point you should have checked out a copy of the entire CrypTool~2 repository. Compiling is pretty easy; just go to the \texttt{trunk\textbackslash} directory and open the \textbf{\textit{CrypTool 2.0.sln}} Visual Studio solution. The Visual Studio IDE should open with all the working plugin components nicely arranged. If you are now starting Visual Studio for the first time, you will have to choose your settings. Just select either \textit{most common} or \textit{C\#} --- you can change this at any time later. On the right side is the project explorer, where you can see all the subprojects included in the solution. Look for the project \textbf{\textit{CrypStartup}} there and make sure it is selected as startup project (right-click on it and select \textit{Set as StartUp Project} from the context menu). Next, go to the menu bar and make sure the target platform is set correctly (Figure~\ref{fig:vs_menubar_x86}). If your operating system is a 32 bit installation, you have to select \textbf{x86}. If you have a 64 bit operating system, you may use one of both, x64 or x86. If in doubt, select x86. Then click \textit{Build $\rightarrow$ Build Solution} in the menubar to start the build process.
    163 
    164 \begin{figure}[htbp]
    165         \centering
    166                 \includegraphics{figures/vs_menubar_x86.png}
    167         \caption{Selecting x86 as target platform.}
    168         \label{fig:vs_menubar_x86}
    169 \end{figure}
    170 \clearpage
     162By this point you should have checked out a copy of the entire CrypTool~2 repository. Compiling is pretty easy; just go to the \texttt{trunk\textbackslash} directory and open the \textbf{\textit{CrypTool 2.0.sln}} Visual Studio solution. The Visual Studio IDE should open with all the working plugin components nicely arranged. If you are now starting Visual Studio for the first time, you will have to choose your settings. Just select either \textit{most common} or \textit{C\#} --- you can change this at any time later. On the right side is the project explorer, where you can see all the subprojects included in the solution. Look for the project \textbf{\textit{CrypStartup}} there and make sure it is selected as startup project (right-click on it and select \textit{Set as StartUp Project} from the context menu). Then click \textit{Build $\rightarrow$ Build Solution} in the menubar to start the build process.
    171163
    172164You may have to wait a while for the program to compile. Once it is finished, select \textit{Debug $\rightarrow$ Start Debugging}. CrypTool 2 should now start for the first time with your own compiled code. Presumably you have not changed anything yet, but you now have your own build of all the components (with the exception of \textit{CrypWin} and \textit{AnotherEditor}, since they are available only as binaries). If the program does not compile or start correctly, please consult our \href{https://www.cryptool.org/trac/CrypTool2/wiki/FAQ}{FAQ} and let us know if you found a bug.
  • trunk/Documentation/PluginHowTo/part2.tex

    r2320 r2656  
    174174        \item \textit{Cryptool.PluginBase.Editor} --- contains interfaces for editors that can be implemented in CrypTool 2, such as the default editor.
    175175        \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}.
     176        \item \textit{Cryptool.PluginBase.IO} --- contains interfaces for input, output and the \textit{ICryptoolStream}.
    177177        \item \textit{Cryptool.PluginBase.Miscellaneous} --- contains assorted helper classes, including \textit{GuiLogMessage} and \textit{PropertyChanged}.
    178178        \item \textit{Cryptool.PluginBase.Resources} --- used only by CrypWin and the editor; not necessary for plugin development.
     
    186186        \item \textit{Cryptool.PluginBase} --- to implement \textit{ISettings} in the CaesarSettings class.
    187187        \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.
     188        \item \textit{Cryptool.PluginBase.IO} --- to use ICryptoolStream for data input and output.
    189189        \item \textit{Cryptool.PluginBase.Miscellaneous} --- to use the CrypTool event handler.
    190190\end{itemize}
     
    193193\label{sec:DefiningThePrivateVariablesOfTheSettingsInTheCaesarClass}
    194194
    195 The 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>();
     195The next step is to define some private class elements. In our example, this will look like the following:
     196
     197\begin{lstlisting}
     198        #region Private elements
     199        private CaesarSettings settings; // required to implement the IPlugin interface properly
     200        private enum CaesarMode { encrypt, decrypt }; // nested enum, used to select either encryption or decryption
    204201        #endregion
    205202\end{lstlisting}
    206203
    207 \ \\ % ugly but functional
    208 If 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 
    210 Our 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}
     204\ \\
     205If your algorithm deals with potentially large data amounts, it is recommended to use the \textit{ICryptoolStream} data type. More information about how to use the \textit{ICryptoolStream} can be found in the CrypTool 2 wiki: \url{https://www.cryptool.org/trac/CrypTool2/wiki/ICryptoolStreamUsage}. You will need to include the namespace \textit{Cryptool.PluginBase.IO} with a \texttt{using} statement as explained in Section \ref{sec:ImportingCrypPluginBaseNamespaces}.
    219206
    220207\subsection{Adding controls to the CaesarSettings class}
     
    331318public string InputString
    332319{
    333         get { return this.inputString; }
    334         set
    335   {
    336                 if (value != inputString)
    337                 {
    338                         this.inputString = value;
    339                         OnPropertyChanged("InputString");
    340                 }
    341         }
     320                get;
     321                set;
    342322}
    343323\end{lstlisting}
     
    353333public string OutputString
    354334{
    355         get { return this.outputString; }
    356         set
    357         {
    358                 outputString = value;
    359                 OnPropertyChanged("OutputString");
    360         }
     335                get;
     336                set;
    361337}
    362338\end{lstlisting}
     
    369345\begin{lstlisting}
    370346[PropertyInfo(Direction.OutputData, "CryptoolStream output", "The raw CryptoolStream data after processing with the Caesar cipher", "", false, false, QuickWatchFormat.Text, null)]
    371 public CryptoolStream OutputData
    372 {
    373         get
    374         {
    375                 if (outputString != null)
     347public ICryptoolStream OutputData
     348{
     349                get
    376350                {
    377                         CryptoolStream cs = new CryptoolStream();
    378                         listCryptoolStreamsOut.Add(cs);
    379                         cs.OpenRead(Encoding.Default.GetBytes(outputString.ToCharArray()));
    380                         return cs;
     351                                if (OutputString != null)
     352                                {                   
     353                                                return new CStreamWriter(Encoding.Default.GetBytes(OutputString));
     354                                }
     355
     356                                return null;
    381357                }
    382                 else
    383                 {
    384                         return null;
    385                 }
    386         }
    387         set { }
    388358}
    389359
     
    408378        set
    409379        {
    410                 if (value != settings.ShiftKey)
    411                 {
    412380                        settings.ShiftKey = value;
    413                 }
    414381        }
    415382}
     
    519486        {
    520487                case 0:
    521                         GuiLogMessage("Encrypting", NotificationLevel.Debug);
    522488                        ProcessCaesar(CaesarMode.encrypt);
    523489                        break;
    524490                case 1:
    525                         GuiLogMessage("Decrypting", NotificationLevel.Debug);
    526491                        ProcessCaesar(CaesarMode.decrypt);
    527492                        break;
     
    532497\end{lstlisting}
    533498
    534 It 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.
     499It is important to make sure that all changes to the output properties will be announced to the CrypTool 2 environment. Therefore we call \textit{OnPropertyChanged} on both changed output properties \textit{OutputString} and \textit{OutputData}.
    535500
    536501\subsection{Sending messages to the CrypTool 2 core}
    537502\label{sec:SendingMessagesToTheCrypTool2Core}
    538503
    539 The 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.
     504The 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 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.
    540505
    541506\begin{figure}[h]
     
    559524\end{itemize}
    560525
    561 \subsection{Performing a clean dispose}
    562 \label{sec:PerformingACleanDispose}
    563 
    564 Be 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}
    567 public void Dispose()
    568 {
    569         foreach(CryptoolStream stream in listCryptoolStreamsOut)
    570         {
    571                 stream.Close();
    572         }
    573         listCryptoolStreamsOut.Clear();
    574 }
    575 \end{lstlisting}
    576 
    577526\section{Drawing the workflow of your plugin}
    578527\label{DrawingTheWorkfloweOfYourPlugin}
Note: See TracChangeset for help on using the changeset viewer.