<commit_before>/*******************************************************************************
**
** Filename   : newfolderdialog.cpp
** Created on : 30 January, 2005
** Copyright  : (c) 2005 Till Adam
** Email      : adam@kde.org
**
*******************************************************************************/

/*******************************************************************************
**
**   This program is free software; you can redistribute it and/or modify
**   it under the terms of the GNU General Public License as published by
**   the Free Software Foundation; either version 2 of the License, or
**   (at your option) any later version.
**
**   In addition, as a special exception, the copyright holders give
**   permission to link the code of this program with any edition of
**   the Qt library by Trolltech AS, Norway (or with modified versions
**   of Qt that use the same license as Qt), and distribute linked
**   combinations including the two.  You must obey the GNU General
**   Public License in all respects for all of the code used other than
**   Qt.  If you modify this file, you may extend this exception to
**   your version of the file, but you are not obligated to do so.  If
**   you do not wish to do so, delete this exception statement from
**   your version.
*******************************************************************************/

#include <qvariant.h>
#include <qpushbutton.h>
#include <qlabel.h>
#include <qlineedit.h>
#include <qcombobox.h>
#include <qlayout.h>
#include <qtooltip.h>
#include <qwhatsthis.h>
#include <qregexp.h>

#include <klocale.h>
#include <kdialogbase.h>
#include <kmessagebox.h>

#include "newfolderdialog.h"
#include "kmfolder.h"
#include "folderstorage.h"
#include "kmfolderimap.h"
#include "kmfoldercachedimap.h"
#include "kmfoldermgr.h"
#include "kmfolderdir.h"
#include "folderstorage.h"
#include "kmailicalifaceimpl.h"
#include "kmacctimap.h"
#include "kmacctcachedimap.h"

using namespace KMail;

NewFolderDialog::NewFolderDialog( QWidget* parent, KMFolder *folder )
    : KDialogBase( parent, "new_folder_dialog", false, i18n( "New Folder" ),
                   KDialogBase::Ok|KDialogBase::Cancel,
                   KDialogBase::Ok, true ),
      mFolder( folder )
{
  setWFlags( getWFlags() | WDestructiveClose );
  if ( folder ) {
    setCaption( i18n("New Subfolder of %1").arg( folder->prettyURL() ) );
  }
  QWidget* privateLayoutWidget = new QWidget( this, "mTopLevelLayout" );
  privateLayoutWidget->setGeometry( QRect( 10, 10, 260, 80 ) );
  setMainWidget( privateLayoutWidget );
  mTopLevelLayout = new QVBoxLayout( privateLayoutWidget, 0, spacingHint(),
                                     "mTopLevelLayout");

  mNameHBox = new QHBoxLayout( 0, 0, 6, "mNameHBox");

  mNameLabel = new QLabel( privateLayoutWidget, "mNameLabel" );
  mNameLabel->setText( i18n( "&Name:" ) );
  mNameHBox->addWidget( mNameLabel );

  mNameLineEdit = new QLineEdit( privateLayoutWidget, "mNameLineEdit" );
  mNameLabel->setBuddy( mNameLineEdit );
  QWhatsThis::add( mNameLineEdit, i18n( "Enter a name for the new folder." ) );
  mNameLineEdit->setFocus();
  mNameHBox->addWidget( mNameLineEdit );
  mTopLevelLayout->addLayout( mNameHBox );
  connect( mNameLineEdit, SIGNAL( textChanged ( const QString & ) ), this, SLOT( slotFolderNameChanged( const QString & ) ) );

  if ( !mFolder ||
      ( mFolder->folderType() != KMFolderTypeImap &&
        mFolder->folderType() != KMFolderTypeCachedImap ) ) {
    mFormatHBox = new QHBoxLayout( 0, 0, 6, "mFormatHBox");
    mMailboxFormatLabel = new QLabel( privateLayoutWidget, "mMailboxFormatLabel" );
    mMailboxFormatLabel->setText( i18n( "Mailbox &format:" ) );
    mFormatHBox->addWidget( mMailboxFormatLabel );

    mFormatComboBox = new QComboBox( FALSE, privateLayoutWidget, "mFormatComboBox" );
    mMailboxFormatLabel->setBuddy( mFormatComboBox );
    QWhatsThis::add( mFormatComboBox, i18n( "Select whether you want to store the messages in this folder as one file per  message (maildir) or as one big file (mbox). KMail uses maildir by default and this only needs to be changed in rare circumstances. If you are unsure, leave this option as-is." ) );

    mFormatComboBox->insertItem("mbox", 0);
    mFormatComboBox->insertItem("maildir", 1);
    // does the below make any sense?
    //  mFormatComboBox->insertItem("search", 2);
    {
      KConfig *config = KMKernel::config();
      KConfigGroupSaver saver(config, "General");
      int type = config->readNumEntry("default-mailbox-format", 1);
      if ( type < 0 || type > 1 ) type = 1;
      mFormatComboBox->setCurrentItem( type );
    }
    mFormatHBox->addWidget( mFormatComboBox );
    mTopLevelLayout->addLayout( mFormatHBox );
  }

  // --- contents -----
  if ( kmkernel->iCalIface().isEnabled() ) {
    mContentsHBox = new QHBoxLayout( 0, 0, 6, "mContentsHBox");

    mContentsLabel = new QLabel( privateLayoutWidget, "mContentsLabel" );
    mContentsLabel->setText( i18n( "Folder &contains:" ) );
    mContentsHBox->addWidget( mContentsLabel );

    mContentsComboBox = new QComboBox( FALSE, privateLayoutWidget, "mContentsComboBox" );
    mContentsLabel->setBuddy( mContentsComboBox );
    QWhatsThis::add( mContentsComboBox, i18n( "Select whether you want the new folder to be used for mail storage of for storage of groupware items such as tasks or notes. The default is mail. If you are unsure, leave this option as-is." ) );
    mContentsComboBox->insertItem( i18n( "Mail" ) );
    mContentsComboBox->insertItem( i18n( "Calendar" ) );
    mContentsComboBox->insertItem( i18n( "Contacts" ) );
    mContentsComboBox->insertItem( i18n( "Notes" ) );
    mContentsComboBox->insertItem( i18n( "Tasks" ) );
    mContentsComboBox->insertItem( i18n( "Journal" ) );
    if ( mFolder ) // inherit contents type from papa
      mContentsComboBox->setCurrentItem( mFolder->storage()->contentsType() );
    mContentsHBox->addWidget( mContentsComboBox );
    mTopLevelLayout->addLayout( mContentsHBox );
  }

  if ( mFolder &&
      ( mFolder->folderType() == KMFolderTypeImap ||
        mFolder->folderType() == KMFolderTypeCachedImap ) ) {
    bool rootFolder = false;
    QStringList namespaces;
    if ( mFolder->folderType() == KMFolderTypeImap ) {
      ImapAccountBase* ai = static_cast<KMFolderImap*>(mFolder->storage())->account();
      if ( mFolder->storage() == ai->rootFolder() ) {
        rootFolder = true;
        namespaces = ai->namespaces()[ImapAccountBase::PersonalNS];
      }
    }
    if ( mFolder->folderType() == KMFolderTypeCachedImap ) {
      ImapAccountBase* ai = static_cast<KMFolderCachedImap*>(mFolder->storage())->account();
      if ( mFolder->storage() == ai->rootFolder() ) {
        rootFolder = true;
        namespaces = ai->namespaces()[ImapAccountBase::PersonalNS];
      }
    }
    if ( rootFolder && namespaces.count() > 1 ) {
      mNamespacesHBox = new QHBoxLayout( 0, 0, 6, "mNamespaceHBox");

      mNamespacesLabel = new QLabel( privateLayoutWidget, "mNamespacesLabel" );
      mNamespacesLabel->setText( i18n( "Namespace for &folder:" ) );
      mNamespacesHBox->addWidget( mNamespacesLabel );

      mNamespacesComboBox = new QComboBox( FALSE, privateLayoutWidget, "mNamespacesComboBox" );
      mNamespacesLabel->setBuddy( mNamespacesComboBox );
      QWhatsThis::add( mNamespacesComboBox, i18n( "Select the personal namespace the folder should be created in." ) );
      mNamespacesComboBox->insertStringList( namespaces );
      mNamespacesHBox->addWidget( mNamespacesComboBox );
      mTopLevelLayout->addLayout( mNamespacesHBox );
    } else {
      mNamespacesComboBox = 0;
    }
  }

  resize( QSize(282, 108).expandedTo(minimumSizeHint()) );
  clearWState( WState_Polished );
  slotFolderNameChanged( mNameLineEdit->text());
}

void NewFolderDialog::slotFolderNameChanged( const QString & _text)
{
  enableButtonOK( !_text.isEmpty() );
}

void NewFolderDialog::slotOk()
{
  const QString &fldName = mNameLineEdit->text();
  if ( fldName.isEmpty() ) {
     KMessageBox::error( this, i18n("Please specify a name for the new folder."),
        i18n( "No Name Specified" ) );
     return;
  }
  if ( fldName.find( '/' ) != -1 &&
    ( !mFolder
      || mFolder->folderType() == KMFolderTypeImap
      || mFolder->folderType() == KMFolderTypeCachedImap ) ) {
    KMessageBox::error( this, i18n( "Folder names cannot contain the / (slash) character; please choose another folder name." ) );
    return;
  }

  if ( fldName.startsWith( "." ) ) {
    KMessageBox::error( this, i18n( "Folder names cannot start with a . (dot) character; please choose another folder name." ) );
    return;
  } else if ( mFolder &&
      ( mFolder->folderType() == KMFolderTypeImap ||
        mFolder->folderType() == KMFolderTypeCachedImap ) ) {
    QString delimiter;
    if ( mFolder->folderType() == KMFolderTypeImap ) {
      KMAcctImap* ai = static_cast<KMFolderImap*>( mFolder->storage() )->account();
      delimiter = ai->delimiterForFolder( mFolder->storage() );
    } else {
      KMAcctCachedImap* ai = static_cast<KMFolderCachedImap*>( mFolder->storage() )->account();
      delimiter = ai->delimiterForFolder( mFolder->storage() );
    }
    if ( !delimiter.isEmpty() && fldName.find( delimiter ) != -1 ) {
      KMessageBox::error( this, i18n( "Your IMAP server does not allow the character '%1'; please choose another folder name." ).arg( delimiter ) );
      return;
    }
  }

  // default parent is Top Level local folders
  KMFolderDir * selectedFolderDir = &(kmkernel->folderMgr()->dir());
  // we got a parent, let's use that
  if ( mFolder )
    selectedFolderDir = mFolder->createChildFolder();

  // check if the folder already exists
  if( selectedFolderDir->hasNamedFolder( fldName )
      && ( !( mFolder
          && ( selectedFolderDir == mFolder->parent() )
          && ( mFolder->storage()->name() == fldName ) ) ) )
  {
    const QString message = i18n( "<qt>Failed to create folder %1, folder already exists.</qt>" ).arg(fldName);
    KMessageBox::error( this, message );
    return;
  }

  /* Ok, obvious errors caught, let's try creating it for real. */
  const QString message = i18n( "<qt>Failed to create folder %1."
            "</qt> " ).arg(fldName);
  bool success = false;
  KMFolder *newFolder = 0;

   if ( mFolder && mFolder->folderType() == KMFolderTypeImap ) {
    KMFolderImap* selectedStorage = static_cast<KMFolderImap*>( mFolder->storage() );
    KMAcctImap *anAccount = selectedStorage->account();
    // check if a connection is available BEFORE creating the folder
    if (anAccount->makeConnection() == ImapAccountBase::Connected) {
      newFolder = kmkernel->imapFolderMgr()->createFolder( fldName, FALSE, KMFolderTypeImap, selectedFolderDir );
      if ( newFolder ) {
        QString imapPath, parent;
        if ( mNamespacesComboBox ) {
          // create folder with namespace
          parent = anAccount->addPathToNamespace( mNamespacesComboBox->currentText() );
          imapPath = anAccount->createImapPath( parent, fldName );
        }
        KMFolderImap* newStorage = static_cast<KMFolderImap*>( newFolder->storage() );
        selectedStorage->createFolder(fldName, parent); // create it on the server
        newStorage->initializeFrom( selectedStorage, imapPath, QString::null );
        static_cast<KMFolderImap*>(mFolder->storage())->setAccount( selectedStorage->account() );
        success = true;
      }
    }
  } else if ( mFolder && mFolder->folderType() == KMFolderTypeCachedImap ) {
    newFolder = kmkernel->dimapFolderMgr()->createFolder( fldName, FALSE, KMFolderTypeCachedImap, selectedFolderDir );
    if ( newFolder ) {
      KMFolderCachedImap* selectedStorage = static_cast<KMFolderCachedImap*>( mFolder->storage() );
      KMFolderCachedImap* newStorage = static_cast<KMFolderCachedImap*>( newFolder->storage() );
      newStorage->initializeFrom( selectedStorage );
      if ( mNamespacesComboBox ) {
        // create folder with namespace
        QString path = selectedStorage->account()->createImapPath(
            mNamespacesComboBox->currentText(), fldName );
        newStorage->setImapPathForCreation( path );
      }
      success = true;
    }
  } else {
    // local folder
    if (mFormatComboBox->currentItem() == 1)
      newFolder = kmkernel->folderMgr()->createFolder(fldName, FALSE, KMFolderTypeMaildir, selectedFolderDir );
    else
      newFolder = kmkernel->folderMgr()->createFolder(fldName, FALSE, KMFolderTypeMbox, selectedFolderDir );
    if ( newFolder )
      success = true;
  }
  if ( !success ) {
    KMessageBox::error( this, message );
    return;
  }

  // Set type field
  if ( kmkernel->iCalIface().isEnabled() && mContentsComboBox ) {
    KMail::FolderContentsType type =
      static_cast<KMail::FolderContentsType>( mContentsComboBox->currentItem() );
    newFolder->storage()->setContentsType( type );
    newFolder->storage()->writeConfig(); // connected slots will read it
  }
  KDialogBase::slotOk();
}

#include "newfolderdialog.moc"
<commit_msg>Set the imapPath also when no namespace combo was available<commit_after>/*******************************************************************************
**
** Filename   : newfolderdialog.cpp
** Created on : 30 January, 2005
** Copyright  : (c) 2005 Till Adam
** Email      : adam@kde.org
**
*******************************************************************************/

/*******************************************************************************
**
**   This program is free software; you can redistribute it and/or modify
**   it under the terms of the GNU General Public License as published by
**   the Free Software Foundation; either version 2 of the License, or
**   (at your option) any later version.
**
**   In addition, as a special exception, the copyright holders give
**   permission to link the code of this program with any edition of
**   the Qt library by Trolltech AS, Norway (or with modified versions
**   of Qt that use the same license as Qt), and distribute linked
**   combinations including the two.  You must obey the GNU General
**   Public License in all respects for all of the code used other than
**   Qt.  If you modify this file, you may extend this exception to
**   your version of the file, but you are not obligated to do so.  If
**   you do not wish to do so, delete this exception statement from
**   your version.
*******************************************************************************/

#include <qvariant.h>
#include <qpushbutton.h>
#include <qlabel.h>
#include <qlineedit.h>
#include <qcombobox.h>
#include <qlayout.h>
#include <qtooltip.h>
#include <qwhatsthis.h>
#include <qregexp.h>

#include <klocale.h>
#include <kdialogbase.h>
#include <kmessagebox.h>

#include "newfolderdialog.h"
#include "kmfolder.h"
#include "folderstorage.h"
#include "kmfolderimap.h"
#include "kmfoldercachedimap.h"
#include "kmfoldermgr.h"
#include "kmfolderdir.h"
#include "folderstorage.h"
#include "kmailicalifaceimpl.h"
#include "kmacctimap.h"
#include "kmacctcachedimap.h"

using namespace KMail;

NewFolderDialog::NewFolderDialog( QWidget* parent, KMFolder *folder )
    : KDialogBase( parent, "new_folder_dialog", false, i18n( "New Folder" ),
                   KDialogBase::Ok|KDialogBase::Cancel,
                   KDialogBase::Ok, true ),
      mFolder( folder )
{
  setWFlags( getWFlags() | WDestructiveClose );
  if ( folder ) {
    setCaption( i18n("New Subfolder of %1").arg( folder->prettyURL() ) );
  }
  QWidget* privateLayoutWidget = new QWidget( this, "mTopLevelLayout" );
  privateLayoutWidget->setGeometry( QRect( 10, 10, 260, 80 ) );
  setMainWidget( privateLayoutWidget );
  mTopLevelLayout = new QVBoxLayout( privateLayoutWidget, 0, spacingHint(),
                                     "mTopLevelLayout");

  mNameHBox = new QHBoxLayout( 0, 0, 6, "mNameHBox");

  mNameLabel = new QLabel( privateLayoutWidget, "mNameLabel" );
  mNameLabel->setText( i18n( "&Name:" ) );
  mNameHBox->addWidget( mNameLabel );

  mNameLineEdit = new QLineEdit( privateLayoutWidget, "mNameLineEdit" );
  mNameLabel->setBuddy( mNameLineEdit );
  QWhatsThis::add( mNameLineEdit, i18n( "Enter a name for the new folder." ) );
  mNameLineEdit->setFocus();
  mNameHBox->addWidget( mNameLineEdit );
  mTopLevelLayout->addLayout( mNameHBox );
  connect( mNameLineEdit, SIGNAL( textChanged ( const QString & ) ), this, SLOT( slotFolderNameChanged( const QString & ) ) );

  if ( !mFolder ||
      ( mFolder->folderType() != KMFolderTypeImap &&
        mFolder->folderType() != KMFolderTypeCachedImap ) ) {
    mFormatHBox = new QHBoxLayout( 0, 0, 6, "mFormatHBox");
    mMailboxFormatLabel = new QLabel( privateLayoutWidget, "mMailboxFormatLabel" );
    mMailboxFormatLabel->setText( i18n( "Mailbox &format:" ) );
    mFormatHBox->addWidget( mMailboxFormatLabel );

    mFormatComboBox = new QComboBox( FALSE, privateLayoutWidget, "mFormatComboBox" );
    mMailboxFormatLabel->setBuddy( mFormatComboBox );
    QWhatsThis::add( mFormatComboBox, i18n( "Select whether you want to store the messages in this folder as one file per  message (maildir) or as one big file (mbox). KMail uses maildir by default and this only needs to be changed in rare circumstances. If you are unsure, leave this option as-is." ) );

    mFormatComboBox->insertItem("mbox", 0);
    mFormatComboBox->insertItem("maildir", 1);
    // does the below make any sense?
    //  mFormatComboBox->insertItem("search", 2);
    {
      KConfig *config = KMKernel::config();
      KConfigGroupSaver saver(config, "General");
      int type = config->readNumEntry("default-mailbox-format", 1);
      if ( type < 0 || type > 1 ) type = 1;
      mFormatComboBox->setCurrentItem( type );
    }
    mFormatHBox->addWidget( mFormatComboBox );
    mTopLevelLayout->addLayout( mFormatHBox );
  }

  // --- contents -----
  if ( kmkernel->iCalIface().isEnabled() ) {
    mContentsHBox = new QHBoxLayout( 0, 0, 6, "mContentsHBox");

    mContentsLabel = new QLabel( privateLayoutWidget, "mContentsLabel" );
    mContentsLabel->setText( i18n( "Folder &contains:" ) );
    mContentsHBox->addWidget( mContentsLabel );

    mContentsComboBox = new QComboBox( FALSE, privateLayoutWidget, "mContentsComboBox" );
    mContentsLabel->setBuddy( mContentsComboBox );
    QWhatsThis::add( mContentsComboBox, i18n( "Select whether you want the new folder to be used for mail storage of for storage of groupware items such as tasks or notes. The default is mail. If you are unsure, leave this option as-is." ) );
    mContentsComboBox->insertItem( i18n( "Mail" ) );
    mContentsComboBox->insertItem( i18n( "Calendar" ) );
    mContentsComboBox->insertItem( i18n( "Contacts" ) );
    mContentsComboBox->insertItem( i18n( "Notes" ) );
    mContentsComboBox->insertItem( i18n( "Tasks" ) );
    mContentsComboBox->insertItem( i18n( "Journal" ) );
    if ( mFolder ) // inherit contents type from papa
      mContentsComboBox->setCurrentItem( mFolder->storage()->contentsType() );
    mContentsHBox->addWidget( mContentsComboBox );
    mTopLevelLayout->addLayout( mContentsHBox );
  }

  if ( mFolder &&
      ( mFolder->folderType() == KMFolderTypeImap ||
        mFolder->folderType() == KMFolderTypeCachedImap ) ) {
    bool rootFolder = false;
    QStringList namespaces;
    if ( mFolder->folderType() == KMFolderTypeImap ) {
      ImapAccountBase* ai = static_cast<KMFolderImap*>(mFolder->storage())->account();
      if ( mFolder->storage() == ai->rootFolder() ) {
        rootFolder = true;
        namespaces = ai->namespaces()[ImapAccountBase::PersonalNS];
      }
    }
    if ( mFolder->folderType() == KMFolderTypeCachedImap ) {
      ImapAccountBase* ai = static_cast<KMFolderCachedImap*>(mFolder->storage())->account();
      if ( mFolder->storage() == ai->rootFolder() ) {
        rootFolder = true;
        namespaces = ai->namespaces()[ImapAccountBase::PersonalNS];
      }
    }
    if ( rootFolder && namespaces.count() > 1 ) {
      mNamespacesHBox = new QHBoxLayout( 0, 0, 6, "mNamespaceHBox");

      mNamespacesLabel = new QLabel( privateLayoutWidget, "mNamespacesLabel" );
      mNamespacesLabel->setText( i18n( "Namespace for &folder:" ) );
      mNamespacesHBox->addWidget( mNamespacesLabel );

      mNamespacesComboBox = new QComboBox( FALSE, privateLayoutWidget, "mNamespacesComboBox" );
      mNamespacesLabel->setBuddy( mNamespacesComboBox );
      QWhatsThis::add( mNamespacesComboBox, i18n( "Select the personal namespace the folder should be created in." ) );
      mNamespacesComboBox->insertStringList( namespaces );
      mNamespacesHBox->addWidget( mNamespacesComboBox );
      mTopLevelLayout->addLayout( mNamespacesHBox );
    } else {
      mNamespacesComboBox = 0;
    }
  }

  resize( QSize(282, 108).expandedTo(minimumSizeHint()) );
  clearWState( WState_Polished );
  slotFolderNameChanged( mNameLineEdit->text());
}

void NewFolderDialog::slotFolderNameChanged( const QString & _text)
{
  enableButtonOK( !_text.isEmpty() );
}

void NewFolderDialog::slotOk()
{
  const QString &fldName = mNameLineEdit->text();
  if ( fldName.isEmpty() ) {
     KMessageBox::error( this, i18n("Please specify a name for the new folder."),
        i18n( "No Name Specified" ) );
     return;
  }
  if ( fldName.find( '/' ) != -1 &&
    ( !mFolder
      || mFolder->folderType() == KMFolderTypeImap
      || mFolder->folderType() == KMFolderTypeCachedImap ) ) {
    KMessageBox::error( this, i18n( "Folder names cannot contain the / (slash) character; please choose another folder name." ) );
    return;
  }

  if ( fldName.startsWith( "." ) ) {
    KMessageBox::error( this, i18n( "Folder names cannot start with a . (dot) character; please choose another folder name." ) );
    return;
  } else if ( mFolder &&
      ( mFolder->folderType() == KMFolderTypeImap ||
        mFolder->folderType() == KMFolderTypeCachedImap ) ) {
    QString delimiter;
    if ( mFolder->folderType() == KMFolderTypeImap ) {
      KMAcctImap* ai = static_cast<KMFolderImap*>( mFolder->storage() )->account();
      delimiter = ai->delimiterForFolder( mFolder->storage() );
    } else {
      KMAcctCachedImap* ai = static_cast<KMFolderCachedImap*>( mFolder->storage() )->account();
      delimiter = ai->delimiterForFolder( mFolder->storage() );
    }
    if ( !delimiter.isEmpty() && fldName.find( delimiter ) != -1 ) {
      KMessageBox::error( this, i18n( "Your IMAP server does not allow the character '%1'; please choose another folder name." ).arg( delimiter ) );
      return;
    }
  }

  // default parent is Top Level local folders
  KMFolderDir * selectedFolderDir = &(kmkernel->folderMgr()->dir());
  // we got a parent, let's use that
  if ( mFolder )
    selectedFolderDir = mFolder->createChildFolder();

  // check if the folder already exists
  if( selectedFolderDir->hasNamedFolder( fldName )
      && ( !( mFolder
          && ( selectedFolderDir == mFolder->parent() )
          && ( mFolder->storage()->name() == fldName ) ) ) )
  {
    const QString message = i18n( "<qt>Failed to create folder %1, folder already exists.</qt>" ).arg(fldName);
    KMessageBox::error( this, message );
    return;
  }

  /* Ok, obvious errors caught, let's try creating it for real. */
  const QString message = i18n( "<qt>Failed to create folder %1."
            "</qt> " ).arg(fldName);
  bool success = false;
  KMFolder *newFolder = 0;

   if ( mFolder && mFolder->folderType() == KMFolderTypeImap ) {
    KMFolderImap* selectedStorage = static_cast<KMFolderImap*>( mFolder->storage() );
    KMAcctImap *anAccount = selectedStorage->account();
    // check if a connection is available BEFORE creating the folder
    if (anAccount->makeConnection() == ImapAccountBase::Connected) {
      newFolder = kmkernel->imapFolderMgr()->createFolder( fldName, FALSE, KMFolderTypeImap, selectedFolderDir );
      if ( newFolder ) {
        QString imapPath, parent;
        if ( mNamespacesComboBox ) {
          // create folder with namespace
          parent = anAccount->addPathToNamespace( mNamespacesComboBox->currentText() );
          imapPath = anAccount->createImapPath( parent, fldName );
        } else {
          imapPath = anAccount->createImapPath( selectedStorage->imapPath(), fldName );
        }
        KMFolderImap* newStorage = static_cast<KMFolderImap*>( newFolder->storage() );
        selectedStorage->createFolder(fldName, parent); // create it on the server
        newStorage->initializeFrom( selectedStorage, imapPath, QString::null );
        static_cast<KMFolderImap*>(mFolder->storage())->setAccount( selectedStorage->account() );
        success = true;
      }
    }
  } else if ( mFolder && mFolder->folderType() == KMFolderTypeCachedImap ) {
    newFolder = kmkernel->dimapFolderMgr()->createFolder( fldName, FALSE, KMFolderTypeCachedImap, selectedFolderDir );
    if ( newFolder ) {
      KMFolderCachedImap* selectedStorage = static_cast<KMFolderCachedImap*>( mFolder->storage() );
      KMFolderCachedImap* newStorage = static_cast<KMFolderCachedImap*>( newFolder->storage() );
      newStorage->initializeFrom( selectedStorage );
      if ( mNamespacesComboBox ) {
        // create folder with namespace
        QString path = selectedStorage->account()->createImapPath(
            mNamespacesComboBox->currentText(), fldName );
        newStorage->setImapPathForCreation( path );
      }
      success = true;
    }
  } else {
    // local folder
    if (mFormatComboBox->currentItem() == 1)
      newFolder = kmkernel->folderMgr()->createFolder(fldName, FALSE, KMFolderTypeMaildir, selectedFolderDir );
    else
      newFolder = kmkernel->folderMgr()->createFolder(fldName, FALSE, KMFolderTypeMbox, selectedFolderDir );
    if ( newFolder )
      success = true;
  }
  if ( !success ) {
    KMessageBox::error( this, message );
    return;
  }

  // Set type field
  if ( kmkernel->iCalIface().isEnabled() && mContentsComboBox ) {
    KMail::FolderContentsType type =
      static_cast<KMail::FolderContentsType>( mContentsComboBox->currentItem() );
    newFolder->storage()->setContentsType( type );
    newFolder->storage()->writeConfig(); // connected slots will read it
  }
  KDialogBase::slotOk();
}

#include "newfolderdialog.moc"
<|endoftext|>


<commit_before>#ifndef LANEMAPPER_HPP_INCLUDED
#define LANEMAPPER_HPP_INCLUDED

#include <events/Event.hpp>
#include <sensors/DataStructures/StereoImageData.hpp>
#include <opencv2/opencv.hpp>

class LaneMapper
{
public:
    LaneMapper(Event<StereoImageData>* source)
        : LOnNewFrame(this)
    {
        if(source)
        {
            (*source) += &LOnNewFrame;
            _src = source;
        }
    }

    void ChangeSource(Event<StereoImageData> *newSource)
    {
        if(_src)
            (*_src) -= &LOnNewFrame;
        if(newSource)
        {
            _src = newSource;
            (*_src) += &LOnNewFrame;
        }
    }

    ~LaneMapper()
    {
        if(_src)
            (*_src) -= &LOnNewFrame;
    }

private:
    Event<StereoImageData> *_src;

    void OnNewFrame(StereoImageData image)
    {
        using namespace cv;
        Mat frame = image.left().mat();
        blur(frame, frame, Size(3, 3), Point(-1, -1) );

        Mat grassfiltered;
        {
            vector<Mat> channels;
            split(frame, channels);
            channels[0] = channels[0] - 0.5 * channels[1];
            merge(channels, grassfiltered);
        }

        cvtColor(grassfiltered, grassfiltered, CV_BGR2GRAY);

        threshold(grassfiltered, grassfiltered, 200, 255, CV_THRESH_BINARY);

        Mat obstacles(frame.rows, frame.cols, CV_8UC3);

        frame.copyTo(obstacles);

        {
            Mat HSV;
            cvtColor(obstacles, HSV, CV_BGR2HSV);
            vector<Mat> channels;
            split(HSV, channels);
            channels[2] = Mat(HSV.size(), CV_8UC1, Scalar(200));
            channels[1] *= 2.0;
            merge(channels, HSV);
            cvtColor(HSV, obstacles, CV_HSV2BGR);
        }

        {
            uchar *p;
            for(int r = 0; r < obstacles.rows; r++)
            {
                p = obstacles.ptr<uchar>(r);
                for(int c = 0; c < obstacles.cols * obstacles.channels(); c += 3)
                {
                    bool isNotGreenOrWhite = false;

                    if(p[c] < p[c+1] - 10 && p[c+2] < p[c+1] - 10)
                    {
                        isNotGreenOrWhite = true;
                    }

                    if(p[c] > 190 && p[c+1] > 190 && p[c+2] > 190)
                    {
                        isNotGreenOrWhite = true;
                    }

                    if(isNotGreenOrWhite)
                    {
                        p[c] = 0;
                        p[c+1] = 0;
                        p[c+2] = 0;
                    }
                }
            }
        }

        int erosion_size = 5;
        cv::Mat element = cv::getStructuringElement(cv::MORPH_CROSS,
                                                    cv::Size(2 * erosion_size + 1, 2 * erosion_size + 1),
                                                    cv::Point(erosion_size, erosion_size) );

        erode(obstacles, obstacles, element);
        dilate(obstacles, obstacles, element);

        Mat mask;
        {
            Mat frameT = frame.t();
            Mat obstT = obstacles.t();
            flip(frameT, frameT, 1);
            flip(obstT, obstT, 1);
            uchar *p;
            uchar* op;
            for(int r = 0; r < frameT.rows; r++)
            {
                bool blackout = false;
                p = frameT.ptr<uchar>(r);
                op = obstT.ptr<uchar>(r);
                for(int c = 0; c < frameT.cols * frameT.channels(); c += 3)
                {
                    if(blackout)
                    {
                        p[c] = 0;
                        p[c+1] = 0;
                        p[c+2] = 0;
                    }
                    else
                    {
                        if(op[c]+op[c+1]+op[c+2] > 0)
                        {
                            p[c] = 0;
                            p[c+1] = 0;
                            p[c+2] = 0;
                            blackout = true;
                        }
                        else
                        {
                            p[c] = 1;
                            p[c+1] = 1;
                            p[c+2] = 1;
                        }
                    }
                }
            }
            flip(frameT, frameT, 1);
            flip(obstT, obstT, 1);
            mask = frameT.t();
        }

        cvtColor(mask, mask, CV_BGR2GRAY);

        Mat lines = mask.mul(grassfiltered);

        {
            uchar* p;
            for(int r = 0; r < lines.rows; r++)
            {
                p = lines.ptr<uchar>(r);
                for(int c = 0; c < lines.cols; c++)
                {
                    if(p[c] == 255)
                    {
                        // Add to vector.

                    }
                }
            }
        }
    }
    LISTENER(LaneMapper, OnNewFrame, StereoImageData);
};

#endif // LANEMAPPER_HPP_INCLUDED
<commit_msg>Adds call to computeOffsets(...) to transform image coordinates into robot coordinates.<commit_after>#ifndef LANEMAPPER_HPP_INCLUDED
#define LANEMAPPER_HPP_INCLUDED

#include <events/Event.hpp>
#include <sensors/DataStructures/StereoImageData.hpp>
#include <opencv2/opencv.hpp>
#include <common/utils/ImageUtils.h>

class LaneMapper
{
public:
    Event<MatrixXd> onNewLanes;

    LaneMapper(Event<StereoImageData>* source)
        : LOnNewFrame(this)
    {
        if(source)
        {
            (*source) += &LOnNewFrame;
            _src = source;
        }
    }

    void ChangeSource(Event<StereoImageData> *newSource)
    {
        if(_src)
            (*_src) -= &LOnNewFrame;
        if(newSource)
        {
            _src = newSource;
            (*_src) += &LOnNewFrame;
        }
    }

    ~LaneMapper()
    {
        if(_src)
            (*_src) -= &LOnNewFrame;
    }

private:
    Event<StereoImageData> *_src;

    void OnNewFrame(StereoImageData image)
    {
        using namespace cv;
        Mat frame = image.left().mat();
        blur(frame, frame, Size(3, 3), Point(-1, -1) );

        Mat grassfiltered;
        {
            vector<Mat> channels;
            split(frame, channels);
            channels[0] = channels[0] - 0.5 * channels[1];
            merge(channels, grassfiltered);
        }

        cvtColor(grassfiltered, grassfiltered, CV_BGR2GRAY);

        threshold(grassfiltered, grassfiltered, 200, 255, CV_THRESH_BINARY);

        Mat obstacles(frame.rows, frame.cols, CV_8UC3);

        frame.copyTo(obstacles);

        {
            Mat HSV;
            cvtColor(obstacles, HSV, CV_BGR2HSV);
            vector<Mat> channels;
            split(HSV, channels);
            channels[2] = Mat(HSV.size(), CV_8UC1, Scalar(200));
            channels[1] *= 2.0;
            merge(channels, HSV);
            cvtColor(HSV, obstacles, CV_HSV2BGR);
        }

        {
            uchar *p;
            for(int r = 0; r < obstacles.rows; r++)
            {
                p = obstacles.ptr<uchar>(r);
                for(int c = 0; c < obstacles.cols * obstacles.channels(); c += 3)
                {
                    bool isNotGreenOrWhite = false;

                    if(p[c] < p[c+1] - 10 && p[c+2] < p[c+1] - 10)
                    {
                        isNotGreenOrWhite = true;
                    }

                    if(p[c] > 190 && p[c+1] > 190 && p[c+2] > 190)
                    {
                        isNotGreenOrWhite = true;
                    }

                    if(isNotGreenOrWhite)
                    {
                        p[c] = 0;
                        p[c+1] = 0;
                        p[c+2] = 0;
                    }
                }
            }
        }

        int erosion_size = 5;
        cv::Mat element = cv::getStructuringElement(cv::MORPH_CROSS,
                                                    cv::Size(2 * erosion_size + 1, 2 * erosion_size + 1),
                                                    cv::Point(erosion_size, erosion_size) );

        erode(obstacles, obstacles, element);
        dilate(obstacles, obstacles, element);

        Mat mask;
        {
            Mat frameT = frame.t();
            Mat obstT = obstacles.t();
            flip(frameT, frameT, 1);
            flip(obstT, obstT, 1);
            uchar *p;
            uchar* op;
            for(int r = 0; r < frameT.rows; r++)
            {
                bool blackout = false;
                p = frameT.ptr<uchar>(r);
                op = obstT.ptr<uchar>(r);
                for(int c = 0; c < frameT.cols * frameT.channels(); c += 3)
                {
                    if(blackout)
                    {
                        p[c] = 0;
                        p[c+1] = 0;
                        p[c+2] = 0;
                    }
                    else
                    {
                        if(op[c]+op[c+1]+op[c+2] > 0)
                        {
                            p[c] = 0;
                            p[c+1] = 0;
                            p[c+2] = 0;
                            blackout = true;
                        }
                        else
                        {
                            p[c] = 1;
                            p[c+1] = 1;
                            p[c+2] = 1;
                        }
                    }
                }
            }
            flip(frameT, frameT, 1);
            flip(obstT, obstT, 1);
            mask = frameT.t();
        }

        cvtColor(mask, mask, CV_BGR2GRAY);

        Mat lines = mask.mul(grassfiltered);

        vector<KeyPoint> keyPoints;

        {
            uchar* p;
            for(int r = 0; r < lines.rows; r++)
            {
                p = lines.ptr<uchar>(r);
                for(int c = 0; c < lines.cols; c++)
                {
                    if(p[c] == 255)
                    {
                        // Add to vector.
                        keyPoints.push_back(KeyPoint(r, c, 1));
                    }
                }
            }
        }

        MatrixXd pos;
        Robot robot = Robot::Misti();
        CameraInfo cameraInfo = CameraInfo::Bumblebee2_BB2_08S2C_38();
        computeOffsets(keyPoints, pos, robot, cameraInfo, lines.rows, lines.cols);

        onNewLanes(pos);
    }
    LISTENER(LaneMapper, OnNewFrame, StereoImageData);
};

#endif // LANEMAPPER_HPP_INCLUDED
<|endoftext|>


<commit_before>#include "mutator.hpp"

#include <iostream>
#include <fstream>

namespace mtt
{

    Mutator::Mutator()
    {
        std::random_device rd;
        gen = std::mt19937(rd());

        letter = std::uniform_int_distribution<>{1, 1000000000};

        for (std::size_t i = 0; i < probabilities.size(); ++i)
            for (std::size_t j = 0; j < probabilities.size(); ++j)
                for (std::size_t k = 0; k < probabilities.size(); ++k)
                    for (std::size_t l = 0; l < probabilities.size(); ++l)
                        probabilities[i][j][k][l] = letter(gen)/1000000000.0;
    }

    Mutator::Mutator(const std::string & filename) : probabilities{}
    {
        _setProbas(filename);
    }

    void Mutator::addText(const std::string & filename)
    {
        _setProbas(filename);
    }

    std::vector<char> Mutator::createText(const std::size_t n)
    {
        std::vector<char> text;

        int prev,prevprev,prevprevprev;

        // First char
        float currLetter = letter(gen)/1000000000.0;
        std::array<float,27> cumuledProbabilities{0};
        for (std::size_t i = 0; i < probabilities.size(); i++)
        {
            float proba = 0;
            for (std::size_t j = 0; j < probabilities.size(); j++)
            {
                for (std::size_t k = 0; k < probabilities.size(); k++)
                {
                    for (std::size_t l = 0; l < probabilities.size(); l++)
                        proba += probabilities[i][j][k][l];
                }
            }
            cumuledProbabilities[i] = proba;
        }
        for (std::size_t i = 1; i < cumuledProbabilities.size(); i++)
        {
            cumuledProbabilities[i] += cumuledProbabilities[i-1];
        }
        for (std::size_t i = 0; i < cumuledProbabilities.size(); i++)
            cumuledProbabilities[i] /= cumuledProbabilities.at(cumuledProbabilities.size()-1);
        for (std::size_t i = 0; i < cumuledProbabilities.size(); i++)
        {
            if (cumuledProbabilities[i] > currLetter)
            {
                text.push_back(i);
                prev = i;
                break;
            }
        }

        // Second char
        currLetter = letter(gen)/1000000000.0;
        cumuledProbabilities = {0};
        for (std::size_t i = 0; i < probabilities.size(); i++)
        {
            float proba = 0;
            for (std::size_t j = 0; j < probabilities.size(); j++)
            {
                for (std::size_t k = 0; k < probabilities.size(); k++)
                {
                    proba += probabilities[prev][i][j][k];
                }
            }
            cumuledProbabilities[i] = proba;
        }
        for (std::size_t i = 1; i < cumuledProbabilities.size(); i++)
            cumuledProbabilities[i] += cumuledProbabilities[i-1];
        for (std::size_t i = 0; i < cumuledProbabilities.size(); i++)
            cumuledProbabilities[i] /= cumuledProbabilities.at(cumuledProbabilities.size()-1);
        for (std::size_t i = 0; i < cumuledProbabilities.size(); i++)
        {
            if (cumuledProbabilities[i] > currLetter)
            {
                text.push_back(i);
                prevprev = i;
                break;
            }
        }

        // Third char
        currLetter = letter(gen)/1000000000.0;
        cumuledProbabilities = {0};
        for (std::size_t j = 0; j < probabilities.size(); j++)
        {
            float proba = 0;
            for (std::size_t k = 0; k < probabilities.size(); k++)
            {
                proba += probabilities[prev][prevprev][j][k];
            }
            cumuledProbabilities[j] = proba;
        }
        for (std::size_t i = 1; i < cumuledProbabilities.size(); i++)
            cumuledProbabilities[i] += cumuledProbabilities[i-1];
        for (std::size_t i = 0; i < cumuledProbabilities.size(); i++)
            cumuledProbabilities[i] /= cumuledProbabilities.at(cumuledProbabilities.size()-1);
        for (std::size_t i = 0; i < cumuledProbabilities.size(); i++)
        {
            if (cumuledProbabilities[i] > currLetter)
            {
                text.push_back(i);
                prevprevprev = i;
                break;
            }
        }

        // Next chars
        while(text.size() < 10000)
        {
            int prevprevprevprev = 0;
            std::array<float,27> cumuledProbabilities{0};
            currLetter = letter(gen)/1000000000.0;
            cumuledProbabilities[0] = probabilities[prevprevprev][prevprev][prev][0];
            for (std::size_t i = 1; i < probabilities.size(); i++)
                cumuledProbabilities[i] = cumuledProbabilities[i-1] + probabilities[prevprevprev][prevprev][prev][i];
            if (cumuledProbabilities.at(cumuledProbabilities.size()-1) == 0)
            {
                text.pop_back();
                prev = prevprev;
                prevprev = prevprevprev;
                prevprevprev = prevprevprevprev;
                continue;
            }
            for (std::size_t i = 0; i < probabilities.size(); i++)
                cumuledProbabilities[i] /=cumuledProbabilities.at(cumuledProbabilities.size()-1);
            for (std::size_t i = 0; i < cumuledProbabilities.size(); i++)
            {
                if (cumuledProbabilities[i] >= currLetter && (i != 26 || prev != 26))
                {
                    text.push_back(i);
                    prevprevprevprev = prevprevprev;
                    prevprevprev = prevprev;
                    prevprev = prev;
                    prev = i;
                    break;
                }
            }
        }

        return text;
    }

    void Mutator::_setProbas(const std::string & filename)
    {
        std::ifstream ifile(filename);

        probabilities = {0};

        std::size_t count = 3;
        char c = ifile.get();
        auto prevprevprevindex = c == ' ' ? 26 : static_cast<int>(c) - 97;
        c = ifile.get();
        auto prevprevindex = c == ' ' ? 26 : static_cast<int>(c) - 97;
        c = ifile.get();
        auto previndex = c == ' ' ? 26 : static_cast<int>(c) - 97;

        while (ifile.get(c)) {
            count++;
            auto index = c == ' ' ? 26 : static_cast<int>(c) - 97;
            probabilities[prevprevprevindex][prevprevindex][previndex][index]++;
            prevprevprevindex = prevprevindex;
            prevprevindex = previndex;
            previndex = index;
        }

        for (std::size_t i = 0; i < probabilities.size(); ++i)
            for (std::size_t j = 0; j < probabilities.size(); ++j)
                for (std::size_t k = 0; k < probabilities.size(); ++k)
                    for (std::size_t l = 0; l < probabilities.size(); ++l)
                    {
                        probabilities[i][j][k][l] /= count;
                    }

    }

}

std::ostream& operator<<(std::ostream& os, const std::vector<char>& text)
{
    for (std::size_t n = 0; n < text.size(); ++n)
    {
        if (text.at(n) == 26)
        {
            os <<  " ";
        }
        else
        {
            os << (char) (text.at(n) + 97) ;
        }
    }

    return os;
}

<commit_msg>Corrected a minor bug in mutator.createText(...)<commit_after>#include "mutator.hpp"

#include <iostream>
#include <fstream>

namespace mtt
{

    Mutator::Mutator()
    {
        std::random_device rd;
        gen = std::mt19937(rd());

        letter = std::uniform_int_distribution<>{1, 1000000000};

        for (std::size_t i = 0; i < probabilities.size(); ++i)
            for (std::size_t j = 0; j < probabilities.size(); ++j)
                for (std::size_t k = 0; k < probabilities.size(); ++k)
                    for (std::size_t l = 0; l < probabilities.size(); ++l)
                        probabilities[i][j][k][l] = letter(gen)/1000000000.0;
    }

    Mutator::Mutator(const std::string & filename) : probabilities{}
    {
        _setProbas(filename);
    }

    void Mutator::addText(const std::string & filename)
    {
        _setProbas(filename);
    }

    std::vector<char> Mutator::createText(const std::size_t n)
    {
        std::vector<char> text;

        int prev,prevprev,prevprevprev;

        // First char
        float currLetter = letter(gen)/1000000000.0;
        std::array<float,27> cumuledProbabilities{0};
        for (std::size_t i = 0; i < probabilities.size(); i++)
        {
            float proba = 0;
            for (std::size_t j = 0; j < probabilities.size(); j++)
            {
                for (std::size_t k = 0; k < probabilities.size(); k++)
                {
                    for (std::size_t l = 0; l < probabilities.size(); l++)
                        proba += probabilities[i][j][k][l];
                }
            }
            cumuledProbabilities[i] = proba;
        }
        for (std::size_t i = 1; i < cumuledProbabilities.size(); i++)
        {
            cumuledProbabilities[i] += cumuledProbabilities[i-1];
        }
        for (std::size_t i = 0; i < cumuledProbabilities.size(); i++)
            cumuledProbabilities[i] /= cumuledProbabilities.at(cumuledProbabilities.size()-1);
        for (std::size_t i = 0; i < cumuledProbabilities.size(); i++)
        {
            if (cumuledProbabilities[i] > currLetter)
            {
                text.push_back(i);
                prev = i;
                break;
            }
        }

        // Second char
        currLetter = letter(gen)/1000000000.0;
        cumuledProbabilities = {0};
        for (std::size_t i = 0; i < probabilities.size(); i++)
        {
            float proba = 0;
            for (std::size_t j = 0; j < probabilities.size(); j++)
            {
                for (std::size_t k = 0; k < probabilities.size(); k++)
                {
                    proba += probabilities[prev][i][j][k];
                }
            }
            cumuledProbabilities[i] = proba;
        }
        for (std::size_t i = 1; i < cumuledProbabilities.size(); i++)
            cumuledProbabilities[i] += cumuledProbabilities[i-1];
        for (std::size_t i = 0; i < cumuledProbabilities.size(); i++)
            cumuledProbabilities[i] /= cumuledProbabilities.at(cumuledProbabilities.size()-1);
        for (std::size_t i = 0; i < cumuledProbabilities.size(); i++)
        {
            if (cumuledProbabilities[i] > currLetter)
            {
                text.push_back(i);
                prevprev = i;
                break;
            }
        }

        // Third char
        currLetter = letter(gen)/1000000000.0;
        cumuledProbabilities = {0};
        for (std::size_t j = 0; j < probabilities.size(); j++)
        {
            float proba = 0;
            for (std::size_t k = 0; k < probabilities.size(); k++)
            {
                proba += probabilities[prev][prevprev][j][k];
            }
            cumuledProbabilities[j] = proba;
        }
        for (std::size_t i = 1; i < cumuledProbabilities.size(); i++)
            cumuledProbabilities[i] += cumuledProbabilities[i-1];
        for (std::size_t i = 0; i < cumuledProbabilities.size(); i++)
            cumuledProbabilities[i] /= cumuledProbabilities.at(cumuledProbabilities.size()-1);
        for (std::size_t i = 0; i < cumuledProbabilities.size(); i++)
        {
            if (cumuledProbabilities[i] > currLetter)
            {
                text.push_back(i);
                prevprevprev = i;
                break;
            }
        }

        // Next chars
        while(text.size() < n)
        {
            int prevprevprevprev = 0;
            std::array<float,27> cumuledProbabilities{0};
            currLetter = letter(gen)/1000000000.0;
            cumuledProbabilities[0] = probabilities[prevprevprev][prevprev][prev][0];
            for (std::size_t i = 1; i < probabilities.size(); i++)
                cumuledProbabilities[i] = cumuledProbabilities[i-1] + probabilities[prevprevprev][prevprev][prev][i];
            if (cumuledProbabilities.at(cumuledProbabilities.size()-1) == 0)
            {
                text.pop_back();
                prev = prevprev;
                prevprev = prevprevprev;
                prevprevprev = prevprevprevprev;
                continue;
            }
            for (std::size_t i = 0; i < probabilities.size(); i++)
                cumuledProbabilities[i] /=cumuledProbabilities.at(cumuledProbabilities.size()-1);
            for (std::size_t i = 0; i < cumuledProbabilities.size(); i++)
            {
                if (cumuledProbabilities[i] >= currLetter && (i != 26 || prev != 26))
                {
                    text.push_back(i);
                    prevprevprevprev = prevprevprev;
                    prevprevprev = prevprev;
                    prevprev = prev;
                    prev = i;
                    break;
                }
            }
        }

        return text;
    }

    void Mutator::_setProbas(const std::string & filename)
    {
        std::ifstream ifile(filename);

        probabilities = {0};

        std::size_t count = 3;
        char c = ifile.get();
        auto prevprevprevindex = c == ' ' ? 26 : static_cast<int>(c) - 97;
        c = ifile.get();
        auto prevprevindex = c == ' ' ? 26 : static_cast<int>(c) - 97;
        c = ifile.get();
        auto previndex = c == ' ' ? 26 : static_cast<int>(c) - 97;

        while (ifile.get(c)) {
            count++;
            auto index = c == ' ' ? 26 : static_cast<int>(c) - 97;
            probabilities[prevprevprevindex][prevprevindex][previndex][index]++;
            prevprevprevindex = prevprevindex;
            prevprevindex = previndex;
            previndex = index;
        }

        for (std::size_t i = 0; i < probabilities.size(); ++i)
            for (std::size_t j = 0; j < probabilities.size(); ++j)
                for (std::size_t k = 0; k < probabilities.size(); ++k)
                    for (std::size_t l = 0; l < probabilities.size(); ++l)
                    {
                        probabilities[i][j][k][l] /= count;
                    }

    }

}

std::ostream& operator<<(std::ostream& os, const std::vector<char>& text)
{
    for (std::size_t n = 0; n < text.size(); ++n)
    {
        if (text.at(n) == 26)
        {
            os <<  " ";
        }
        else
        {
            os << (char) (text.at(n) + 97) ;
        }
    }

    return os;
}

<|endoftext|>


<commit_before>/*=========================================================================

   Copyright 2011 Patrick IMBO
   Contributed to ORFEO Toolbox under license Apache 2

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.

=========================================================================*/

#include "otbImage.h"
#include "otbImageFileReader.h"
#include "otbStreamingImageFileWriter.h"
#include "otbImageFileWriter.h"
#include "itkComplexToModulusImageFilter.h"
#include "itkComplexToPhaseImageFilter.h"
#include "itkMinimumMaximumImageCalculator.h"
#include "otbUnaryFunctorWithIndexImageFilter.h"
#include "itkFFTRealToComplexConjugateImageFilter.h"
#include "itkRescaleIntensityImageFilter.h"

// Command line:

// ./JustFlatEarthRemovalInterferogramComputation interf.tif phase.tif remove_earth_interf.tif cleanphase.tif

/** Functor to compute the remove earth phase */
namespace Functor
{
template< class TInput, class TOutput>
    class EarthRemovePhaseInterferogramCalculator
{
  public:
  // The constructor and destructor.
    EarthRemovePhaseInterferogramCalculator()  {};
    ~EarthRemovePhaseInterferogramCalculator() {};

	typedef itk::Index<2> IndexType;

	inline TOutput operator ()(const TInput& inPix, IndexType index)
    {
 	  TOutput result = static_cast<TOutput>( inPix);
	  for(unsigned int i = 0 ; i<2 ; ++i)
	  {
		double tmp_phase;
		tmp_phase= otb::CONST_2PI*m_IndexFrequencyMax[0]*index[0];
		TOutput phase(cos(tmp_phase), -sin(tmp_phase));
	    result *= phase;
	}
      return result;
    }

  void SetIndexFrequencyMax(IndexType value)
  {
    m_IndexFrequencyMax = value;
  }

  private:
	  IndexType m_IndexFrequencyMax;
};
}

  typedef double                           ScalarPixelType;
  typedef std::complex<ScalarPixelType>    PixelType;
  typedef otb::Image<PixelType,2>          ImageType;
  typedef ImageType::IndexType             IndexType;
  typedef otb::Image<ScalarPixelType,2>    ScalarImageType;

  typedef itk::ComplexToPhaseImageFilter<ImageType,ScalarImageType> PhaseFilterType;
  typedef itk::FFTRealToComplexConjugateImageFilter< ScalarPixelType, ImageType::ImageDimension >  RealFFTType;
  typedef itk::ComplexToModulusImageFilter<RealFFTType::OutputImageType,ScalarImageType>      ModulusFilterType;
  typedef itk::MinimumMaximumImageCalculator<ModulusFilterType::OutputImageType>  MinMaxCalculatorType;

  typedef Functor::EarthRemovePhaseInterferogramCalculator<PixelType, PixelType> InterferogramCalculatorType;
  typedef otb::UnaryFunctorWithIndexImageFilter<ImageType,ImageType,InterferogramCalculatorType> EarthRemovePhaseInterferogramFilterType;

  /* Reading images */
  typedef otb::ImageFileReader<ImageType> ReaderType;
  typedef otb::StreamingImageFileWriter<ImageType> WriterType;
  typedef otb::StreamingImageFileWriter<ScalarImageType> ScalarWriterType;

  typedef unsigned char                     OutputPixelType;
  typedef otb ::Image<OutputPixelType, 2>   OutputImageType;
  typedef itk::RescaleIntensityImageFilter<ScalarImageType , OutputImageType > RescalerType;
  typedef otb::StreamingImageFileWriter<OutputImageType > RescaleWriterType ;

int main(int argc, char* argv[])
{

  if (argc != 5)
    {
    std::cerr << "Usage: " << argv[0] << " interferogram Phase flatEarthRemoveInterferogram cleanedPhase" << std::endl;
    return EXIT_FAILURE;
    }

  ReaderType::Pointer interferogram = ReaderType::New();
  interferogram->SetFileName(argv[1]);

  PhaseFilterType::Pointer phaseFilter = PhaseFilterType::New();
  phaseFilter->SetInput(interferogram->GetOutput());
  phaseFilter->Update();

  RescalerType::Pointer rescalePhase = RescalerType::New();
  rescalePhase->SetOutputMinimum(0);
  rescalePhase->SetOutputMaximum(255);
  rescalePhase->SetInput(phaseFilter->GetOutput());

  RescaleWriterType::Pointer rescalePhaseWriter = RescaleWriterType::New();
  rescalePhaseWriter->SetFileName(argv[2]);
  rescalePhaseWriter->SetInput(rescalePhase->GetOutput());
  rescalePhaseWriter->Update();

  RealFFTType::Pointer phaseFFT = RealFFTType::New();
  phaseFFT->SetInput(phaseFilter->GetOutput());
  phaseFFT->Update();

  ModulusFilterType::Pointer modulusPhaseFFT = ModulusFilterType::New();
  modulusPhaseFFT->SetInput( phaseFFT->GetOutput() );
  modulusPhaseFFT->Update();

  MinMaxCalculatorType::Pointer minMax = MinMaxCalculatorType::New();
  minMax->SetImage(modulusPhaseFFT->GetOutput());
  minMax->ComputeMaximum();

  IndexType index;
  index = minMax->GetIndexOfMaximum();

  std::cout << "Frequency max evaluation : " << index[0]<< " with " << modulusPhaseFFT->GetOutput()->GetLargestPossibleRegion().GetSize()[0]
	        << " , "                         << index[0]/(modulusPhaseFFT->GetOutput()->GetLargestPossibleRegion().GetSize()[0]*1.0) << std::endl;

  EarthRemovePhaseInterferogramFilterType::Pointer earthRemovePhaseInterferogram = EarthRemovePhaseInterferogramFilterType::New();
  earthRemovePhaseInterferogram->SetInput(interferogram->GetOutput());
  earthRemovePhaseInterferogram->GetFunctor().SetIndexFrequencyMax( index);
  earthRemovePhaseInterferogram->Update();

  WriterType::Pointer flatEarthRemoveWriterInterferogram = WriterType::New();
  flatEarthRemoveWriterInterferogram->SetFileName(argv[3]);
  flatEarthRemoveWriterInterferogram->SetInput(earthRemovePhaseInterferogram->GetOutput());
  flatEarthRemoveWriterInterferogram->Update();

  PhaseFilterType::Pointer cleanPhaseFilter = PhaseFilterType::New();
  cleanPhaseFilter->SetInput(earthRemovePhaseInterferogram->GetOutput());
  cleanPhaseFilter->Update();

  RescalerType::Pointer rescaleCleanPhase = RescalerType::New();
  rescaleCleanPhase->SetOutputMinimum(0);
  rescaleCleanPhase->SetOutputMaximum(255);
  rescaleCleanPhase->SetInput(cleanPhaseFilter->GetOutput());

  RescaleWriterType::Pointer rescaleCleanPhaseWriter = RescaleWriterType::New();
  rescaleCleanPhaseWriter->SetFileName(argv[4]);
  rescaleCleanPhaseWriter->SetInput(rescaleCleanPhase->GetOutput());
  rescaleCleanPhaseWriter->Update();

  return EXIT_SUCCESS;
}
<commit_msg>ENH: normalize interferogram and process cleaning fringe<commit_after>/*=========================================================================

   Copyright 2011 Patrick IMBO
   Contributed to ORFEO Toolbox under license Apache 2

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.

=========================================================================*/

#include "otbImage.h"
#include "otbImageFileReader.h"
#include "otbStreamingImageFileWriter.h"
#include "otbImageFileWriter.h"
#include "itkComplexToModulusImageFilter.h"
#include "itkComplexToPhaseImageFilter.h"
#include "itkMinimumMaximumImageCalculator.h"
#include "otbUnaryFunctorWithIndexImageFilter.h"
#include "itkFFTRealToComplexConjugateImageFilter.h"
#include "itkRescaleIntensityImageFilter.h"
#include "itkUnaryFunctorImageFilter.h"
#include "itkFFTComplexToComplexImageFilter.h"

// Command line:

// ./JustFlatEarthRemovalInterferogramComputation interf.tif phase.tif remove_earth_interf.tif cleanphase.tif

  typedef double                           ScalarPixelType;
  typedef std::complex<ScalarPixelType>    PixelType;
  typedef otb::Image<PixelType,2>          ImageType;
  typedef ImageType::IndexType             IndexType;
  typedef ImageType::SizeType              SizeType;
  typedef otb::Image<ScalarPixelType,2>    ScalarImageType;

/** Functor to compute the remove earth phase */
namespace Functor
{
template< class TInput, class TOutput>
    class EarthRemovePhaseInterferogramCalculator
{
  public:
  // The constructor and destructor.
    EarthRemovePhaseInterferogramCalculator()  {};
    ~EarthRemovePhaseInterferogramCalculator() {};

	typedef itk::Index<2> IndexType;

	inline TOutput operator ()(const TInput& inPix, IndexType index)
    {
 	  TOutput result = static_cast<TOutput>( inPix);
	  for(unsigned int i = 0 ; i<2 ; i++)
	  {
		double tmp_phase;
		tmp_phase= otb::CONST_2PI*m_IndexFrequencyMax[i] / m_ImageSize[i] *index[i] ;
		TOutput phase(0.0, tmp_phase);
	    result *= exp(phase);
	}
// 	  std::cout << "phase : " << static_cast<TOutput>( inPix) << " -> "<<  result << std::endl;
	  return result;
    }

  void SetIndexFrequencyMax(IndexType value)
  {
    m_IndexFrequencyMax = value;
  }
  void SetImageSize(SizeType size)
  {
    m_ImageSize = size;
	std::cout << "Image Size : " << m_ImageSize << std::endl;
  }

  private:
	  IndexType m_IndexFrequencyMax;
	  SizeType  m_ImageSize;
};
}

template<class TInput, class TOutput>
class PhaseToComplexFunctor
{
public:
  inline PixelType operator()(const TInput & inPix) const
  {
 	TOutput result = static_cast<TOutput>( inPix);
	TOutput phase(0.0,inPix);
    return static_cast<TOutput>( exp(phase) );
  }
};

  typedef PhaseToComplexFunctor<ScalarPixelType,PixelType> PhaseToComplexFunctorType;
  typedef itk::UnaryFunctorImageFilter<ScalarImageType,ImageType,PhaseToComplexFunctorType> PhaseToComplexFilterType;

  typedef itk::ComplexToPhaseImageFilter<ImageType,ScalarImageType> PhaseFilterType;
  typedef itk::FFTRealToComplexConjugateImageFilter< ScalarPixelType, ImageType::ImageDimension >  RealFFTType;
  typedef itk::ComplexToModulusImageFilter<RealFFTType::OutputImageType,ScalarImageType>      ModulusFilterType;
  typedef itk::MinimumMaximumImageCalculator<ModulusFilterType::OutputImageType>  MinMaxCalculatorType;

  typedef Functor::EarthRemovePhaseInterferogramCalculator<PixelType, PixelType> InterferogramCalculatorType;
  typedef otb::UnaryFunctorWithIndexImageFilter<ImageType,ImageType,InterferogramCalculatorType> EarthRemovePhaseInterferogramFilterType;

  typedef itk::FFTComplexToComplexImageFilter< PixelType::value_type,
                                           ImageType::ImageDimension > FFTType;
  typedef FFTType::OutputImageType                                       FFTOutputImageType;
  typedef FFTType::TransformDirectionType                                FFTDirectionType;

  /* Reading images */
  typedef otb::ImageFileReader<ImageType> ReaderType;
  typedef otb::StreamingImageFileWriter<ImageType> WriterType;
  typedef otb::StreamingImageFileWriter<ScalarImageType> ScalarWriterType;

  typedef unsigned char                     OutputPixelType;
  typedef otb ::Image<OutputPixelType, 2>   OutputImageType;
  typedef itk::RescaleIntensityImageFilter<ScalarImageType , OutputImageType > RescalerType;
  typedef otb::StreamingImageFileWriter<OutputImageType > RescaleWriterType ;

int main(int argc, char* argv[])
{

  if (argc != 5)
    {
    std::cerr << "Usage: " << argv[0] << " interferogram Phase flatEarthRemoveInterferogram cleanedPhase" << std::endl;
    return EXIT_FAILURE;
    }

  ReaderType::Pointer interferogram = ReaderType::New();
  interferogram->SetFileName(argv[1]);
  interferogram->UpdateOutputInformation();

  PhaseFilterType::Pointer phaseFilter = PhaseFilterType::New();
  phaseFilter->SetInput(interferogram->GetOutput());
  phaseFilter->Update();

  RescalerType::Pointer rescalePhase = RescalerType::New();
  rescalePhase->SetOutputMinimum(0);
  rescalePhase->SetOutputMaximum(255);
  rescalePhase->SetInput(phaseFilter->GetOutput());

  RescaleWriterType::Pointer rescalePhaseWriter = RescaleWriterType::New();
  rescalePhaseWriter->SetFileName(argv[2]);
  rescalePhaseWriter->SetInput(rescalePhase->GetOutput());
  rescalePhaseWriter->Update();

  PhaseToComplexFilterType::Pointer complexPhase = PhaseToComplexFilterType::New();
  complexPhase->SetInput(phaseFilter->GetOutput());
  complexPhase->Update();

  FFTType::Pointer phaseFFT = FFTType::New();
  phaseFFT->SetInput(complexPhase->GetOutput());
  phaseFFT->Update();

  ModulusFilterType::Pointer modulusPhaseFFT = ModulusFilterType::New();
  modulusPhaseFFT->SetInput( phaseFFT->GetOutput() );
  modulusPhaseFFT->Update();

  MinMaxCalculatorType::Pointer minMax = MinMaxCalculatorType::New();
  minMax->SetImage(modulusPhaseFFT->GetOutput());
  minMax->ComputeMaximum();

  IndexType index;
  index = minMax->GetIndexOfMaximum();

  std::cout << "Frequency max evaluation : " << index[0]<< " with " << modulusPhaseFFT->GetOutput()->GetLargestPossibleRegion().GetSize()[0]
	        << " , "                         << index[0]/(modulusPhaseFFT->GetOutput()->GetLargestPossibleRegion().GetSize()[0]*1.0) << std::endl;

  EarthRemovePhaseInterferogramFilterType::Pointer earthRemovePhaseInterferogram = EarthRemovePhaseInterferogramFilterType::New();
  earthRemovePhaseInterferogram->SetInput(interferogram->GetOutput());
  earthRemovePhaseInterferogram->GetFunctor().SetIndexFrequencyMax( index);
  earthRemovePhaseInterferogram->GetFunctor().SetImageSize(modulusPhaseFFT->GetOutput()->GetLargestPossibleRegion().GetSize());
  earthRemovePhaseInterferogram->Update();

  WriterType::Pointer flatEarthRemoveWriterInterferogram = WriterType::New();
  flatEarthRemoveWriterInterferogram->SetFileName(argv[3]);
  flatEarthRemoveWriterInterferogram->SetInput(earthRemovePhaseInterferogram->GetOutput());
  flatEarthRemoveWriterInterferogram->Update();

  PhaseFilterType::Pointer cleanPhaseFilter = PhaseFilterType::New();
  cleanPhaseFilter->SetInput(earthRemovePhaseInterferogram->GetOutput());
  cleanPhaseFilter->Update();

  RescalerType::Pointer rescaleCleanPhase = RescalerType::New();
  rescaleCleanPhase->SetOutputMinimum(0);
  rescaleCleanPhase->SetOutputMaximum(255);
  rescaleCleanPhase->SetInput(cleanPhaseFilter->GetOutput());

  RescaleWriterType::Pointer rescaleCleanPhaseWriter = RescaleWriterType::New();
  rescaleCleanPhaseWriter->SetFileName(argv[4]);
  rescaleCleanPhaseWriter->SetInput(rescaleCleanPhase->GetOutput());
  rescaleCleanPhaseWriter->Update();

  return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>/*
* DSA Parameter Generation
* (C) 1999-2007 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/

#include <botan/numthry.h>
#include <botan/hash.h>
#include <botan/parsing.h>
#include <algorithm>

namespace Botan {

namespace {

/*
* Check if this size is allowed by FIPS 186-3
*/
bool fips186_3_valid_size(size_t pbits, size_t qbits)
   {
   if(qbits == 160)
      return (pbits == 1024);

   if(qbits == 224)
      return (pbits == 2048);

   if(qbits == 256)
      return (pbits == 2048 || pbits == 3072);

   return false;
   }

}

/*
* Attempt DSA prime generation with given seed
*/
bool generate_dsa_primes(RandomNumberGenerator& rng,
                         BigInt& p, BigInt& q,
                         size_t pbits, size_t qbits,
                         const std::vector<uint8_t>& seed_c,
                         size_t offset)
   {
   if(!fips186_3_valid_size(pbits, qbits))
      throw Invalid_Argument(
         "FIPS 186-3 does not allow DSA domain parameters of " +
         std::to_string(pbits) + "/" + std::to_string(qbits) + " bits long");

   if(seed_c.size() * 8 < qbits)
      throw Invalid_Argument(
         "Generating a DSA parameter set with a " + std::to_string(qbits) +
         "long q requires a seed at least as many bits long");

   const std::string hash_name = "SHA-" + std::to_string(qbits);
   std::unique_ptr<HashFunction> hash(HashFunction::create_or_throw(hash_name));

   const size_t HASH_SIZE = hash->output_length();

   class Seed
      {
      public:
         explicit Seed(const std::vector<uint8_t>& s) : m_seed(s) {}

         operator std::vector<uint8_t>& () { return m_seed; }

         Seed& operator++()
            {
            for(size_t j = m_seed.size(); j > 0; --j)
               if(++m_seed[j-1])
                  break;
            return (*this);
            }
      private:
         std::vector<uint8_t> m_seed;
      };

   Seed seed(seed_c);

   q.binary_decode(hash->process(seed));
   q.set_bit(qbits-1);
   q.set_bit(0);

   if(!is_prime(q, rng))
      return false;

   const size_t n = (pbits-1) / (HASH_SIZE * 8),
                b = (pbits-1) % (HASH_SIZE * 8);

   BigInt X;
   std::vector<uint8_t> V(HASH_SIZE * (n+1));

   for(size_t j = 0; j != 4*pbits; ++j)
      {
      for(size_t k = 0; k <= n; ++k)
         {
         ++seed;
         hash->update(seed);
         hash->final(&V[HASH_SIZE * (n-k)]);
         }

      if(j >= offset)
         {
         X.binary_decode(&V[HASH_SIZE - 1 - b/8],
                         V.size() - (HASH_SIZE - 1 - b/8));
         X.set_bit(pbits-1);

         p = X - (X % (2*q) - 1);

         if(p.bits() == pbits && is_prime(p, rng))
            return true;
         }
      }
   return false;
   }

/*
* Generate DSA Primes
*/
std::vector<uint8_t> generate_dsa_primes(RandomNumberGenerator& rng,
                                      BigInt& p, BigInt& q,
                                      size_t pbits, size_t qbits)
   {
   while(true)
      {
      std::vector<uint8_t> seed(qbits / 8);
      rng.randomize(seed.data(), seed.size());

      if(generate_dsa_primes(rng, p, q, pbits, qbits, seed))
         return seed;
      }
   }

}
<commit_msg>increase miller-rabin iterations for dsa primes (FIPS-186-4)<commit_after>/*
* DSA Parameter Generation
* (C) 1999-2007 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/

#include <botan/numthry.h>
#include <botan/hash.h>
#include <botan/parsing.h>
#include <algorithm>

namespace Botan {

namespace {

/*
* Check if this size is allowed by FIPS 186-3
*/
bool fips186_3_valid_size(size_t pbits, size_t qbits)
   {
   if(qbits == 160)
      return (pbits == 1024);

   if(qbits == 224)
      return (pbits == 2048);

   if(qbits == 256)
      return (pbits == 2048 || pbits == 3072);

   return false;
   }

}

/*
* Attempt DSA prime generation with given seed
*/
bool generate_dsa_primes(RandomNumberGenerator& rng,
                         BigInt& p, BigInt& q,
                         size_t pbits, size_t qbits,
                         const std::vector<uint8_t>& seed_c,
                         size_t offset)
   {
   if(!fips186_3_valid_size(pbits, qbits))
      throw Invalid_Argument(
         "FIPS 186-3 does not allow DSA domain parameters of " +
         std::to_string(pbits) + "/" + std::to_string(qbits) + " bits long");

   if(seed_c.size() * 8 < qbits)
      throw Invalid_Argument(
         "Generating a DSA parameter set with a " + std::to_string(qbits) +
         "long q requires a seed at least as many bits long");

   const std::string hash_name = "SHA-" + std::to_string(qbits);
   std::unique_ptr<HashFunction> hash(HashFunction::create_or_throw(hash_name));

   const size_t HASH_SIZE = hash->output_length();

   class Seed
      {
      public:
         explicit Seed(const std::vector<uint8_t>& s) : m_seed(s) {}

         operator std::vector<uint8_t>& () { return m_seed; }

         Seed& operator++()
            {
            for(size_t j = m_seed.size(); j > 0; --j)
               if(++m_seed[j-1])
                  break;
            return (*this);
            }
      private:
         std::vector<uint8_t> m_seed;
      };

   Seed seed(seed_c);

   q.binary_decode(hash->process(seed));
   q.set_bit(qbits-1);
   q.set_bit(0);

   if(!is_prime(q, rng, 126))
      return false;

   const size_t n = (pbits-1) / (HASH_SIZE * 8),
                b = (pbits-1) % (HASH_SIZE * 8);

   BigInt X;
   std::vector<uint8_t> V(HASH_SIZE * (n+1));

   for(size_t j = 0; j != 4*pbits; ++j)
      {
      for(size_t k = 0; k <= n; ++k)
         {
         ++seed;
         hash->update(seed);
         hash->final(&V[HASH_SIZE * (n-k)]);
         }

      if(j >= offset)
         {
         X.binary_decode(&V[HASH_SIZE - 1 - b/8],
                         V.size() - (HASH_SIZE - 1 - b/8));
         X.set_bit(pbits-1);

         p = X - (X % (2*q) - 1);

         if(p.bits() == pbits && is_prime(p, rng, 126))
            return true;
         }
      }
   return false;
   }

/*
* Generate DSA Primes
*/
std::vector<uint8_t> generate_dsa_primes(RandomNumberGenerator& rng,
                                      BigInt& p, BigInt& q,
                                      size_t pbits, size_t qbits)
   {
   while(true)
      {
      std::vector<uint8_t> seed(qbits / 8);
      rng.randomize(seed.data(), seed.size());

      if(generate_dsa_primes(rng, p, q, pbits, qbits, seed))
         return seed;
      }
   }

}
<|endoftext|>


<commit_before>// -*- Mode:C++ -*-

/**************************************************************************************************/
/*                                                                                */
/* Copyright (C) 2016 University of Hull                                                          */
/*                                                                                */
/**************************************************************************************************/
/*                                                                                */
/*  module     :  hugh/platform/application/base.cpp                                              */
/*  project    :                                                                                */
/*  description:                                                                                */
/*                                                                                */
/**************************************************************************************************/

// include i/f header

#include "hugh/platform/application/base.hpp"

// includes, system

#include <boost/filesystem.hpp> // boost::filesystem::path
#include <cstdlib>              // EXIT_SUCCESS
#include <ostream>              // std::ostream
#include <stdexcept>            // std::exception
#include <system_error>         // std::system_error

// includes, project

//#include <>

#define HUGH_USE_TRACE
#undef HUGH_USE_TRACE
#include <hugh/support/trace.hpp>

// internal unnamed namespace

namespace {

  // types, internal (class, enum, struct, union, typedef)

  // variables, internal

  // functions, internal

} // namespace {

namespace hugh {

  namespace platform {

    namespace application {

      // variables, exported

      /* static */ bool base::terminate(false);

      // functions, exported

      /* virtual */ signed
      base::run()
      {
        TRACE("hugh::platform::application::base::run");

        throw std::logic_error("pure virtual function"
                               "'hugh::platform::application::base::run' called");

        return EXIT_FAILURE;
      }

      /* virtual */ void
      base::process_command_line()
      {
        bool   print_help(false);
        signed exit_value(EXIT_SUCCESS);

        try {
          command_line_.process();
        }

        catch (std::exception const& ex) {
          std::cerr << '\n' << "command-line problem: " << ex.what() << std::endl;

          print_help = true;
          exit_value = EXIT_FAILURE;
        }

        if (command_line_.options.count("help") || print_help) {
          std::string const base_name(boost::filesystem::path(command_line_.argv0)
                                      .filename().string());

          std::cerr << "\nusage: " << base_name << " [OPTIONS] [POSITIONALS ...]\n"
                    << command_line_.descriptions
                    << std::endl;

          // std::exit(exit_value);
          throw std::system_error(ECANCELED, std::generic_category(),
                                  "exit value:" + std::to_string(exit_value));
        }
      }

      /* virtual */ void
      base::print_on(std::ostream& os) const
      {
        TRACE_NEVER("hugh::platform::application::base::print_on");

        os << '['
           << "@0x"      << this << ','
           << "verbose:" << verbose_level_
           << ']';
      }

      /* explicit */
      base::base(command_line const& a)
        : boost::noncopyable(),
          support::printable(),
          command_line_     (a),
          verbose_level_    (0)
      {
        TRACE("hugh::platform::application::base::application");

        namespace bpo = boost::program_options;

        bpo::options_description global("Global Options",
                                        command_line::line_length,
                                        command_line::text_length);

        global.add_options()
          ("help,h", "display command-line help and exit");

        global.add_options()
          ("verbose,v",
           bpo::value<unsigned>(&verbose_level_)
           ->implicit_value(verbose_level_ + 1)
           ->default_value (verbose_level_),
           "verbosity level");

        command_line_.descriptions.add(global);
      }

      /* virtual */
      base::~base()
      {
        TRACE("hugh::platform::application::base::~application");
      }

    } // namespace application {

  } // namespace platform {

} // namespace hugh {
<commit_msg>white space<commit_after>// -*- Mode:C++ -*-

/**************************************************************************************************/
/*                                                                                */
/* Copyright (C) 2016 University of Hull                                                          */
/*                                                                                */
/**************************************************************************************************/
/*                                                                                */
/*  module     :  hugh/platform/application/base.cpp                                              */
/*  project    :                                                                                */
/*  description:                                                                                */
/*                                                                                */
/**************************************************************************************************/

// include i/f header

#include "hugh/platform/application/base.hpp"

// includes, system

#include <boost/filesystem.hpp> // boost::filesystem::path
#include <cstdlib>              // EXIT_SUCCESS
#include <ostream>              // std::ostream
#include <stdexcept>            // std::exception
#include <system_error>         // std::system_error

// includes, project

//#include <>

#define HUGH_USE_TRACE
#undef HUGH_USE_TRACE
#include <hugh/support/trace.hpp>

// internal unnamed namespace

namespace {

  // types, internal (class, enum, struct, union, typedef)

  // variables, internal

  // functions, internal

} // namespace {

namespace hugh {

  namespace platform {

    namespace application {

      // variables, exported

      /* static */ bool base::terminate(false);

      // functions, exported

      /* virtual */ signed
      base::run()
      {
        TRACE("hugh::platform::application::base::run");

        throw std::logic_error("pure virtual function"
                               "'hugh::platform::application::base::run' called");

        return EXIT_FAILURE;
      }

      /* virtual */ void
      base::process_command_line()
      {
        bool   print_help(false);
        signed exit_value(EXIT_SUCCESS);

        try {
          command_line_.process();
        }

        catch (std::exception const& ex) {
          std::cerr << '\n' << "command-line problem: " << ex.what() << std::endl;

          print_help = true;
          exit_value = EXIT_FAILURE;
        }

        if (command_line_.options.count("help") || print_help) {
          std::string const base_name(boost::filesystem::path(command_line_.argv0)
                                      .filename().string());

          std::cerr << "\nusage: " << base_name << " [OPTIONS] [POSITIONALS ...]\n"
                    << command_line_.descriptions
                    << std::endl;

          // std::exit(exit_value);
          throw std::system_error(ECANCELED, std::generic_category(),
                                  "exit value:" + std::to_string(exit_value));
        }
      }

      /* virtual */ void
      base::print_on(std::ostream& os) const
      {
        TRACE_NEVER("hugh::platform::application::base::print_on");

        os << '['
           << "@0x"      << this << ','
           << "verbose:" << verbose_level_
           << ']';
      }

      /* explicit */
      base::base(command_line const& a)
        : boost::noncopyable(),
          support::printable(),
          command_line_     (a),
          verbose_level_    (0)
      {
        TRACE("hugh::platform::application::base::application");

        namespace bpo = boost::program_options;

        bpo::options_description global("Global Options",
                                        command_line::line_length,
                                        command_line::text_length);

        global.add_options()
          ("help,h", "display command-line help and exit");

        global.add_options()
          ("verbose,v",
           bpo::value<unsigned>(&verbose_level_)
           ->implicit_value(verbose_level_ + 1)
           ->default_value (verbose_level_),
           "verbosity level");

        command_line_.descriptions.add(global);
      }

      /* virtual */
      base::~base()
      {
        TRACE("hugh::platform::application::base::~application");
      }

    } // namespace application {

  } // namespace platform {

} // namespace hugh {
<|endoftext|>


<commit_before>/*
* System RNG
* (C) 2014,2015,2017,2018 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/

#include <botan/system_rng.h>

#if defined(BOTAN_TARGET_OS_HAS_RTLGENRANDOM)
  #include <botan/dyn_load.h>
  #define NOMINMAX 1
  #define _WINSOCKAPI_ // stop windows.h including winsock.h
  #include <windows.h>

#elif defined(BOTAN_TARGET_OS_HAS_CRYPTO_NG)
   #include <bcrypt.h>

#elif defined(BOTAN_TARGET_OS_HAS_ARC4RANDOM)
   #include <stdlib.h>

#elif defined(BOTAN_TARGET_OS_HAS_GETRANDOM)
   #include <sys/random.h>
   #include <errno.h>

#elif defined(BOTAN_TARGET_OS_HAS_DEV_RANDOM)
   #include <sys/types.h>
   #include <sys/stat.h>
   #include <fcntl.h>
   #include <unistd.h>
   #include <errno.h>
#endif

namespace Botan {

namespace {

#if defined(BOTAN_TARGET_OS_HAS_RTLGENRANDOM)

class System_RNG_Impl final : public RandomNumberGenerator
   {
   public:
      System_RNG_Impl() : m_advapi("advapi32.dll")
         {
         // This throws if the function is not found
         m_rtlgenrandom = m_advapi.resolve<RtlGenRandom_fptr>("SystemFunction036");
         }

      void randomize(uint8_t buf[], size_t len) override
         {
         bool success = m_rtlgenrandom(buf, ULONG(len)) == TRUE;
         if(!success)
            throw System_Error("RtlGenRandom failed");
         }

      void add_entropy(const uint8_t[], size_t) override { /* ignored */ }
      bool is_seeded() const override { return true; }
      bool accepts_input() const override { return false; }
      void clear() override { /* not possible */ }
      std::string name() const override { return "RtlGenRandom"; }
   private:
      // Use type BYTE instead of BOOLEAN because of a naming conflict
      // https://msdn.microsoft.com/en-us/library/windows/desktop/aa387694(v=vs.85).aspx
      // https://msdn.microsoft.com/en-us/library/windows/desktop/aa383751(v=vs.85).aspx
      using RtlGenRandom_fptr = BYTE (NTAPI *)(PVOID, ULONG);

      Dynamically_Loaded_Library m_advapi;
      RtlGenRandom_fptr m_rtlgenrandom;
   };

#elif defined(BOTAN_TARGET_OS_HAS_CRYPTO_NG)

class System_RNG_Impl final : public RandomNumberGenerator
   {
   public:
      System_RNG_Impl()
         {
         NTSTATUS ret = ::BCryptOpenAlgorithmProvider(&m_prov,
                                                      BCRYPT_RNG_ALGORITHM,
                                                      MS_PRIMITIVE_PROVIDER, 0);
         if(ret != STATUS_SUCCESS)
            throw System_Error("System_RNG failed to acquire crypto provider", ret);
         }

      ~System_RNG_Impl()
         {
         ::BCryptCloseAlgorithmProvider(m_prov, 0);
         }

      void randomize(uint8_t buf[], size_t len) override
         {
         NTSTATUS ret = ::BCryptGenRandom(m_prov, static_cast<PUCHAR>(buf), static_cast<ULONG>(len), 0);
         if(ret != STATUS_SUCCESS)
            throw System_Error("System_RNG call to BCryptGenRandom failed", ret);
         }

      void add_entropy(const uint8_t in[], size_t length) override
         {
         /*
         There is a flag BCRYPT_RNG_USE_ENTROPY_IN_BUFFER to provide
         entropy inputs, but it is ignored in Windows 8 and later.
         */
         }

      bool is_seeded() const override { return true; }
      bool accepts_input() const override { return false; }
      void clear() override { /* not possible */ }
      std::string name() const override { return "crypto_ng"; }
   private:
      BCRYPT_ALG_HANDLE m_handle;
   };

#elif defined(BOTAN_TARGET_OS_HAS_ARC4RANDOM)

class System_RNG_Impl final : public RandomNumberGenerator
   {
   public:
      // No constructor or destructor needed as no userland state maintained

      void randomize(uint8_t buf[], size_t len) override
         {
         ::arc4random_buf(buf, len);
         }

      bool accepts_input() const override { return false; }
      void add_entropy(const uint8_t[], size_t) override { /* ignored */ }
      bool is_seeded() const override { return true; }
      void clear() override { /* not possible */ }
      std::string name() const override { return "arc4random"; }
   };

#elif defined(BOTAN_TARGET_OS_HAS_GETRANDOM)

class System_RNG_Impl final : public RandomNumberGenerator
   {
   public:
      // No constructor or destructor needed as no userland state maintained

      void randomize(uint8_t buf[], size_t len) override
         {
         const unsigned int flags = 0;

         while(len > 0)
            {
            const ssize_t got = ::getrandom(buf, len, flags);

            if(got < 0)
               {
               if(errno == EINTR)
                  continue;
               throw System_Error("System_RNG getrandom failed", errno);
               }

            buf += got;
            len -= got;
            }
         }

      bool accepts_input() const override { return false; }
      void add_entropy(const uint8_t[], size_t) override { /* ignored */ }
      bool is_seeded() const override { return true; }
      void clear() override { /* not possible */ }
      std::string name() const override { return "getrandom"; }
   };

#elif defined(BOTAN_TARGET_OS_HAS_DEV_RANDOM)

// Read a random device

class System_RNG_Impl final : public RandomNumberGenerator
   {
   public:
      System_RNG_Impl()
         {
         #ifndef O_NOCTTY
            #define O_NOCTTY 0
         #endif

         m_fd = ::open(BOTAN_SYSTEM_RNG_DEVICE, O_RDWR | O_NOCTTY);

         if(m_fd >= 0)
            {
            m_writable = true;
            }
         else
            {
            /*
            Cannot open in read-write mode. Fall back to read-only,
            calls to add_entropy will fail, but randomize will work
            */
            m_fd = ::open(BOTAN_SYSTEM_RNG_DEVICE, O_RDONLY | O_NOCTTY);
            m_writable = false;
            }

         if(m_fd < 0)
            throw System_Error("System_RNG failed to open RNG device", errno);
         }

      ~System_RNG_Impl()
         {
         ::close(m_fd);
         m_fd = -1;
         }

      void randomize(uint8_t buf[], size_t len) override;
      void add_entropy(const uint8_t in[], size_t length) override;
      bool is_seeded() const override { return true; }
      bool accepts_input() const override { return m_writable; }
      void clear() override { /* not possible */ }
      std::string name() const override { return BOTAN_SYSTEM_RNG_DEVICE; }
   private:
      int m_fd;
      bool m_writable;
   };

void System_RNG_Impl::randomize(uint8_t buf[], size_t len)
   {
   while(len)
      {
      ssize_t got = ::read(m_fd, buf, len);

      if(got < 0)
         {
         if(errno == EINTR)
            continue;
         throw System_Error("System_RNG read failed", errno);
         }
      if(got == 0)
         throw System_Error("System_RNG EOF on device"); // ?!?

      buf += got;
      len -= got;
      }
   }

void System_RNG_Impl::add_entropy(const uint8_t input[], size_t len)
   {
   if(!m_writable)
      return;

   while(len)
      {
      ssize_t got = ::write(m_fd, input, len);

      if(got < 0)
         {
         if(errno == EINTR)
            continue;

         /*
         * This is seen on OS X CI, despite the fact that the man page
         * for Darwin urandom explicitly states that writing to it is
         * supported, and write(2) does not document EPERM at all.
         * But in any case EPERM seems indicative of a policy decision
         * by the OS or sysadmin that additional entropy is not wanted
         * in the system pool, so we accept that and return here,
         * since there is no corrective action possible.
	 *
	 * In Linux EBADF or EPERM is returned if m_fd is not opened for
	 * writing.
         */
         if(errno == EPERM || errno == EBADF)
            return;

         // maybe just ignore any failure here and return?
         throw System_Error("System_RNG write failed", errno);
         }

      input += got;
      len -= got;
      }
   }

#endif

}

RandomNumberGenerator& system_rng()
   {
   static System_RNG_Impl g_system_rng;
   return g_system_rng;
   }

}
<commit_msg>Renamed m_handle to m_prov as this is the variable name used elsewhere.<commit_after>/*
* System RNG
* (C) 2014,2015,2017,2018 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/

#include <botan/system_rng.h>

#if defined(BOTAN_TARGET_OS_HAS_RTLGENRANDOM)
  #include <botan/dyn_load.h>
  #define NOMINMAX 1
  #define _WINSOCKAPI_ // stop windows.h including winsock.h
  #include <windows.h>

#elif defined(BOTAN_TARGET_OS_HAS_CRYPTO_NG)
   #include <bcrypt.h>

#elif defined(BOTAN_TARGET_OS_HAS_ARC4RANDOM)
   #include <stdlib.h>

#elif defined(BOTAN_TARGET_OS_HAS_GETRANDOM)
   #include <sys/random.h>
   #include <errno.h>

#elif defined(BOTAN_TARGET_OS_HAS_DEV_RANDOM)
   #include <sys/types.h>
   #include <sys/stat.h>
   #include <fcntl.h>
   #include <unistd.h>
   #include <errno.h>
#endif

namespace Botan {

namespace {

#if defined(BOTAN_TARGET_OS_HAS_RTLGENRANDOM)

class System_RNG_Impl final : public RandomNumberGenerator
   {
   public:
      System_RNG_Impl() : m_advapi("advapi32.dll")
         {
         // This throws if the function is not found
         m_rtlgenrandom = m_advapi.resolve<RtlGenRandom_fptr>("SystemFunction036");
         }

      void randomize(uint8_t buf[], size_t len) override
         {
         bool success = m_rtlgenrandom(buf, ULONG(len)) == TRUE;
         if(!success)
            throw System_Error("RtlGenRandom failed");
         }

      void add_entropy(const uint8_t[], size_t) override { /* ignored */ }
      bool is_seeded() const override { return true; }
      bool accepts_input() const override { return false; }
      void clear() override { /* not possible */ }
      std::string name() const override { return "RtlGenRandom"; }
   private:
      // Use type BYTE instead of BOOLEAN because of a naming conflict
      // https://msdn.microsoft.com/en-us/library/windows/desktop/aa387694(v=vs.85).aspx
      // https://msdn.microsoft.com/en-us/library/windows/desktop/aa383751(v=vs.85).aspx
      using RtlGenRandom_fptr = BYTE (NTAPI *)(PVOID, ULONG);

      Dynamically_Loaded_Library m_advapi;
      RtlGenRandom_fptr m_rtlgenrandom;
   };

#elif defined(BOTAN_TARGET_OS_HAS_CRYPTO_NG)

class System_RNG_Impl final : public RandomNumberGenerator
   {
   public:
      System_RNG_Impl()
         {
         NTSTATUS ret = ::BCryptOpenAlgorithmProvider(&m_prov,
                                                      BCRYPT_RNG_ALGORITHM,
                                                      MS_PRIMITIVE_PROVIDER, 0);
         if(ret != STATUS_SUCCESS)
            throw System_Error("System_RNG failed to acquire crypto provider", ret);
         }

      ~System_RNG_Impl()
         {
         ::BCryptCloseAlgorithmProvider(m_prov, 0);
         }

      void randomize(uint8_t buf[], size_t len) override
         {
         NTSTATUS ret = ::BCryptGenRandom(m_prov, static_cast<PUCHAR>(buf), static_cast<ULONG>(len), 0);
         if(ret != STATUS_SUCCESS)
            throw System_Error("System_RNG call to BCryptGenRandom failed", ret);
         }

      void add_entropy(const uint8_t in[], size_t length) override
         {
         /*
         There is a flag BCRYPT_RNG_USE_ENTROPY_IN_BUFFER to provide
         entropy inputs, but it is ignored in Windows 8 and later.
         */
         }

      bool is_seeded() const override { return true; }
      bool accepts_input() const override { return false; }
      void clear() override { /* not possible */ }
      std::string name() const override { return "crypto_ng"; }
   private:
      BCRYPT_ALG_HANDLE m_prov;
   };

#elif defined(BOTAN_TARGET_OS_HAS_ARC4RANDOM)

class System_RNG_Impl final : public RandomNumberGenerator
   {
   public:
      // No constructor or destructor needed as no userland state maintained

      void randomize(uint8_t buf[], size_t len) override
         {
         ::arc4random_buf(buf, len);
         }

      bool accepts_input() const override { return false; }
      void add_entropy(const uint8_t[], size_t) override { /* ignored */ }
      bool is_seeded() const override { return true; }
      void clear() override { /* not possible */ }
      std::string name() const override { return "arc4random"; }
   };

#elif defined(BOTAN_TARGET_OS_HAS_GETRANDOM)

class System_RNG_Impl final : public RandomNumberGenerator
   {
   public:
      // No constructor or destructor needed as no userland state maintained

      void randomize(uint8_t buf[], size_t len) override
         {
         const unsigned int flags = 0;

         while(len > 0)
            {
            const ssize_t got = ::getrandom(buf, len, flags);

            if(got < 0)
               {
               if(errno == EINTR)
                  continue;
               throw System_Error("System_RNG getrandom failed", errno);
               }

            buf += got;
            len -= got;
            }
         }

      bool accepts_input() const override { return false; }
      void add_entropy(const uint8_t[], size_t) override { /* ignored */ }
      bool is_seeded() const override { return true; }
      void clear() override { /* not possible */ }
      std::string name() const override { return "getrandom"; }
   };

#elif defined(BOTAN_TARGET_OS_HAS_DEV_RANDOM)

// Read a random device

class System_RNG_Impl final : public RandomNumberGenerator
   {
   public:
      System_RNG_Impl()
         {
         #ifndef O_NOCTTY
            #define O_NOCTTY 0
         #endif

         m_fd = ::open(BOTAN_SYSTEM_RNG_DEVICE, O_RDWR | O_NOCTTY);

         if(m_fd >= 0)
            {
            m_writable = true;
            }
         else
            {
            /*
            Cannot open in read-write mode. Fall back to read-only,
            calls to add_entropy will fail, but randomize will work
            */
            m_fd = ::open(BOTAN_SYSTEM_RNG_DEVICE, O_RDONLY | O_NOCTTY);
            m_writable = false;
            }

         if(m_fd < 0)
            throw System_Error("System_RNG failed to open RNG device", errno);
         }

      ~System_RNG_Impl()
         {
         ::close(m_fd);
         m_fd = -1;
         }

      void randomize(uint8_t buf[], size_t len) override;
      void add_entropy(const uint8_t in[], size_t length) override;
      bool is_seeded() const override { return true; }
      bool accepts_input() const override { return m_writable; }
      void clear() override { /* not possible */ }
      std::string name() const override { return BOTAN_SYSTEM_RNG_DEVICE; }
   private:
      int m_fd;
      bool m_writable;
   };

void System_RNG_Impl::randomize(uint8_t buf[], size_t len)
   {
   while(len)
      {
      ssize_t got = ::read(m_fd, buf, len);

      if(got < 0)
         {
         if(errno == EINTR)
            continue;
         throw System_Error("System_RNG read failed", errno);
         }
      if(got == 0)
         throw System_Error("System_RNG EOF on device"); // ?!?

      buf += got;
      len -= got;
      }
   }

void System_RNG_Impl::add_entropy(const uint8_t input[], size_t len)
   {
   if(!m_writable)
      return;

   while(len)
      {
      ssize_t got = ::write(m_fd, input, len);

      if(got < 0)
         {
         if(errno == EINTR)
            continue;

         /*
         * This is seen on OS X CI, despite the fact that the man page
         * for Darwin urandom explicitly states that writing to it is
         * supported, and write(2) does not document EPERM at all.
         * But in any case EPERM seems indicative of a policy decision
         * by the OS or sysadmin that additional entropy is not wanted
         * in the system pool, so we accept that and return here,
         * since there is no corrective action possible.
	 *
	 * In Linux EBADF or EPERM is returned if m_fd is not opened for
	 * writing.
         */
         if(errno == EPERM || errno == EBADF)
            return;

         // maybe just ignore any failure here and return?
         throw System_Error("System_RNG write failed", errno);
         }

      input += got;
      len -= got;
      }
   }

#endif

}

RandomNumberGenerator& system_rng()
   {
   static System_RNG_Impl g_system_rng;
   return g_system_rng;
   }

}
<|endoftext|>