<commit_before>#include <QDebug>
#include <QSettings>
#include <QFileInfo>
#include <QDir>
#include <QThread>

#include <coreplugin/messagemanager.h>
#include <coreplugin/progressmanager/progressmanager.h>
#include <coreplugin/progressmanager/futureprogress.h>
#include <utils/macroexpander.h>

#include "CppcheckRunner.h"
#include "Constants.h"
#include "Settings.h"

using namespace QtcCppcheck::Internal;

namespace {
  enum ErrorField {
    ErrorFieldFile = 0, ErrorFieldLine, ErrorFieldSeverity, ErrorFieldId,
    ErrorFieldMessage
  };
}

CppcheckRunner::CppcheckRunner (Settings *settings, QObject *parent) :
  QObject (parent), settings_ (settings), showOutput_ (false), showId_ (false), futureInterface_ (NULL),
  maxArgumentsLength_ (0) {
#ifdef __linux__
  QProcess getConf;
  getConf.start (QLatin1String ("getconf ARG_MAX"));
  getConf.waitForFinished (2000);
  QByteArray argMax = getConf.readAllStandardOutput ().replace ("\n", "");
  maxArgumentsLength_ = std::max (argMax.toInt (), 32000);
#else
  maxArgumentsLength_ = 32767;
#endif
  Q_ASSERT (settings_ != NULL);

  connect (&process_, SIGNAL (readyReadStandardOutput ()),
           SLOT (readOutput ()));
  connect (&process_, SIGNAL (readyReadStandardError ()),
           SLOT (readError ()));
  connect (&process_, SIGNAL (started ()),
           SLOT (started ()));
  connect (&process_, SIGNAL (error (QProcess::ProcessError)),
           SLOT (error (QProcess::ProcessError)));
  connect (&process_, SIGNAL (finished (int,QProcess::ExitStatus)),
           SLOT (finished (int,QProcess::ExitStatus)));

  // Restart checking if got queue.
  connect (&process_, SIGNAL (finished (int,QProcess::ExitStatus)),
           SLOT (checkQueuedFiles ()));
}

CppcheckRunner::~CppcheckRunner () {
  if (process_.isOpen ()) {
    process_.kill ();
  }
  queueTimer_.stop ();
  settings_ = NULL;
  delete futureInterface_;
}

void CppcheckRunner::updateSettings () {
  Q_ASSERT (settings_ != NULL);
  showOutput_ = settings_->showBinaryOutput ();
  showId_ = settings_->showId ();
  runArguments_.clear ();
  QString enabled = QLatin1String ("--enable=warning,style,performance,"
                                   "portability,information,missingInclude");
  // Overwrite enable with user parameters if present
  for (int i = runArguments_.size () - 1; i >= 0; --i) {
    if (runArguments_.at (i).startsWith (QLatin1String ("--enable"))) {
      enabled = runArguments_.takeAt (i);
      break;
    }
  }
  if (settings_->checkUnused ()) {
    enabled += QLatin1String (",unusedFunction");
  }
  else{ //TODO always check with threads but rescan for unused after finish?
    runArguments_ << (QLatin1String ("-j ") +
                      QString::number (QThread::idealThreadCount ()));
  }
  runArguments_ << enabled;
  if (settings_->checkInconclusive ()) {
    runArguments_ << QLatin1String ("--inconclusive");
  }
  runArguments_ << QLatin1String ("--template={file},{line},{severity},{id},{message}");
}

void CppcheckRunner::setIncludePaths (const QStringList &paths) {
  includePaths_.clear ();
  includePaths_.reserve (paths.size ());
  for (const auto &i: paths) {
    includePaths_.append (QLatin1String ("-I") + i);
  }
}

void CppcheckRunner::checkFiles (const QStringList &fileNames) {
  Q_ASSERT (!fileNames.isEmpty ());
  fileCheckQueue_ += fileNames;
  fileCheckQueue_.removeDuplicates ();
  fileCheckQueue_.sort ();
  if (process_.isOpen ()) {
    if (fileCheckQueue_ == currentlyCheckingFiles_) {
      process_.kill ();
      // Rechecking will be restarted on finish signal.
    }
    return;
  }
  // Delay helps to avoid double checking same file on editor change.
  const int checkDelayInMs = 200;
  if (!queueTimer_.isActive ()) {
    queueTimer_.singleShot (checkDelayInMs, this, SLOT (checkQueuedFiles ()));
  }
}

void CppcheckRunner::stopChecking () {
  fileCheckQueue_.clear ();
  if (process_.isOpen ()) {
    process_.kill ();
  }
}

void CppcheckRunner::checkQueuedFiles () {
  if (fileCheckQueue_.isEmpty ()) {
    return;
  }
  QString binary = settings_->binaryFile ();
  if (binary.isEmpty ()) {
    return;
  }
  // Pass custom params BEFORE most of runner's to shadow if some repeat.
  auto expander = Utils::globalMacroExpander ();
  auto expanded = expander->expand (settings_->customParameters ());
  QStringList arguments (expanded.split (QLatin1Char (' '), QString::SkipEmptyParts));
  arguments += runArguments_;

  auto includes = !settings_->ignoreIncludePaths () ? includePaths_ : QStringList {};
  currentlyCheckingFiles_ = fileCheckQueue_;
  fileCheckQueue_.clear ();

  int argumentLength = arguments.join (QLatin1Literal (" ")).length ();
  int filesLength = currentlyCheckingFiles_.join (QLatin1Literal (" ")).length ();
  int includesLength = includes.join (QLatin1Literal (" ")).length ();
  if (argumentLength + includesLength + filesLength >= maxArgumentsLength_) {
    if (fileListFileContents_ != currentlyCheckingFiles_) {
      fileListFileContents_ = currentlyCheckingFiles_;
      fileListFile_.resize (0);
      includeListFile_.resize (0);

      if (fileListFile_.open () && includeListFile_.open ()) {
        QByteArray filesArg = fileListFileContents_.join (QLatin1String ("\n")).toLocal8Bit ();
        fileListFile_.write (filesArg);
        fileListFile_.close ();

        for (auto &i: includes) {
          i = i.mid (2);
        }
        QByteArray includesArg = includes.join (QLatin1String ("\n")).toLocal8Bit ();
        includeListFile_.write (includesArg);
        includeListFile_.close ();
      }
      else{
        Core::MessageManager::write (tr ("Failed to write cppcheck's argument files"),
                                     Core::MessageManager::Silent);
        return;
      }
    }
    arguments << QString (QLatin1String ("--file-list=%1")).arg (fileListFile_.fileName ());
    arguments << QString (QLatin1String ("--includes-file=%1")).arg (includeListFile_.fileName ());
  }
  else{
    arguments += currentlyCheckingFiles_;
    arguments += includes;
  }
  emit startedChecking (currentlyCheckingFiles_);
  if (showOutput_) {
    Core::MessageManager::write (QString ("Starting CppChecker with:%1, %2")
                                 .arg (binary,arguments.join (" ")), Core::MessageManager::WithFocus);
  }
  process_.start (binary, arguments);
}

void CppcheckRunner::readOutput () {
  if (!showOutput_) {
    return;
  }
  process_.setReadChannel (QProcess::StandardOutput);

  while (!process_.atEnd ()) {
    QByteArray rawLine = process_.readLine ();
    QString line = QString::fromUtf8 (rawLine).trimmed ();
    if (line.isEmpty ()) {
      continue;
    }
    const QString progressSample = QLatin1String ("% done");
    // check futureInterface because read can be triggered before started..
    if (line.endsWith (progressSample) && futureInterface_ != NULL) {
      int percentEndIndex = line.length () - progressSample.length ();
      int percentStartIndex = line.lastIndexOf (QLatin1String (" "), percentEndIndex);
      int done = line.mid (percentStartIndex, percentEndIndex - percentStartIndex).toInt ();
      futureInterface_->setProgressValue (done);
    }
    Core::MessageManager::write (line, Core::MessageManager::Silent);
  }
}

void CppcheckRunner::readError () {
  process_.setReadChannel (QProcess::StandardError);

  while (!process_.atEnd ()) {
    QByteArray rawLine = process_.readLine ();
    QString line = QString::fromUtf8 (rawLine).trimmed ();
    if (line.isEmpty ()) {
      continue;
    }
    if (showOutput_) {
      Core::MessageManager::write (line, Core::MessageManager::Silent);
    }
    QStringList details = line.split (QLatin1Char (','));
    if (details.size () <= ErrorFieldMessage) {
      continue;
    }
    QString file = QDir::fromNativeSeparators (details.at (ErrorFieldFile));
    int lineNumber = details.at (ErrorFieldLine).toInt ();
    char type = details.at (ErrorFieldSeverity).at (0).toLatin1 ();
    QString id = "";
    if (showId_) {
      id = details.at (ErrorFieldId);
    }
    QString description = line.mid (line.indexOf (details.at (ErrorFieldMessage)));
    emit newTask (type, id, description, file, lineNumber);
  }
}

void CppcheckRunner::started () {
  if (showOutput_) {
    Core::MessageManager::write (tr ("Cppcheck started"), Core::MessageManager::Silent);
  }

  using namespace Core;
  delete futureInterface_;
  futureInterface_ = new QFutureInterface<void>;
  FutureProgress *progress = ProgressManager::addTask (futureInterface_->future (),
                                                       tr ("Cppcheck"), Constants::TASK_CHECKING);
  connect (progress, SIGNAL (canceled ()), SLOT (stopChecking ()));
  futureInterface_->setProgressRange (0, 100); // %
  futureInterface_->reportStarted ();
}

void CppcheckRunner::error (QProcess::ProcessError error) {
  Q_UNUSED (error);
  if (showOutput_) {
    Core::MessageManager::write (tr ("Cppcheck error occured"), Core::MessageManager::Silent);
  }
  if (error == QProcess::FailedToStart) {
    finished (-1, QProcess::CrashExit);
  }
}

void CppcheckRunner::finished (int exitCode, QProcess::ExitStatus exitStatus) {
  Q_UNUSED (exitCode);
  Q_UNUSED (exitStatus);
  if (futureInterface_ != NULL) {
    futureInterface_->reportFinished ();
  }
  process_.close ();
  if (showOutput_) {
    Core::MessageManager::write (tr ("Cppcheck finished"), Core::MessageManager::Silent);
  }
}
<commit_msg>Fixed partial line reads.<commit_after>#include <QDebug>
#include <QSettings>
#include <QFileInfo>
#include <QDir>
#include <QThread>

#include <coreplugin/messagemanager.h>
#include <coreplugin/progressmanager/progressmanager.h>
#include <coreplugin/progressmanager/futureprogress.h>
#include <utils/macroexpander.h>

#include "CppcheckRunner.h"
#include "Constants.h"
#include "Settings.h"

using namespace QtcCppcheck::Internal;

namespace {
  enum ErrorField {
    ErrorFieldFile = 0, ErrorFieldLine, ErrorFieldSeverity, ErrorFieldId,
    ErrorFieldMessage
  };
}

CppcheckRunner::CppcheckRunner (Settings *settings, QObject *parent) :
  QObject (parent), settings_ (settings), showOutput_ (false), showId_ (false), futureInterface_ (NULL),
  maxArgumentsLength_ (0) {
#ifdef __linux__
  QProcess getConf;
  getConf.start (QLatin1String ("getconf ARG_MAX"));
  getConf.waitForFinished (2000);
  QByteArray argMax = getConf.readAllStandardOutput ().replace ("\n", "");
  maxArgumentsLength_ = std::max (argMax.toInt (), 32000);
#else
  maxArgumentsLength_ = 32767;
#endif
  Q_ASSERT (settings_ != NULL);

  connect (&process_, SIGNAL (readyReadStandardOutput ()),
           SLOT (readOutput ()));
  connect (&process_, SIGNAL (readyReadStandardError ()),
           SLOT (readError ()));
  connect (&process_, SIGNAL (started ()),
           SLOT (started ()));
  connect (&process_, SIGNAL (error (QProcess::ProcessError)),
           SLOT (error (QProcess::ProcessError)));
  connect (&process_, SIGNAL (finished (int,QProcess::ExitStatus)),
           SLOT (finished (int,QProcess::ExitStatus)));

  // Restart checking if got queue.
  connect (&process_, SIGNAL (finished (int,QProcess::ExitStatus)),
           SLOT (checkQueuedFiles ()));
}

CppcheckRunner::~CppcheckRunner () {
  if (process_.isOpen ()) {
    process_.kill ();
  }
  queueTimer_.stop ();
  settings_ = NULL;
  delete futureInterface_;
}

void CppcheckRunner::updateSettings () {
  Q_ASSERT (settings_ != NULL);
  showOutput_ = settings_->showBinaryOutput ();
  showId_ = settings_->showId ();
  runArguments_.clear ();
  QString enabled = QLatin1String ("--enable=warning,style,performance,"
                                   "portability,information,missingInclude");
  // Overwrite enable with user parameters if present
  for (int i = runArguments_.size () - 1; i >= 0; --i) {
    if (runArguments_.at (i).startsWith (QLatin1String ("--enable"))) {
      enabled = runArguments_.takeAt (i);
      break;
    }
  }
  if (settings_->checkUnused ()) {
    enabled += QLatin1String (",unusedFunction");
  }
  else{ //TODO always check with threads but rescan for unused after finish?
    runArguments_ << (QLatin1String ("-j ") +
                      QString::number (QThread::idealThreadCount ()));
  }
  runArguments_ << enabled;
  if (settings_->checkInconclusive ()) {
    runArguments_ << QLatin1String ("--inconclusive");
  }
  runArguments_ << QLatin1String ("--template={file},{line},{severity},{id},{message}");
}

void CppcheckRunner::setIncludePaths (const QStringList &paths) {
  includePaths_.clear ();
  includePaths_.reserve (paths.size ());
  for (const auto &i: paths) {
    includePaths_.append (QLatin1String ("-I") + i);
  }
}

void CppcheckRunner::checkFiles (const QStringList &fileNames) {
  Q_ASSERT (!fileNames.isEmpty ());
  fileCheckQueue_ += fileNames;
  fileCheckQueue_.removeDuplicates ();
  fileCheckQueue_.sort ();
  if (process_.isOpen ()) {
    if (fileCheckQueue_ == currentlyCheckingFiles_) {
      process_.kill ();
      // Rechecking will be restarted on finish signal.
    }
    return;
  }
  // Delay helps to avoid double checking same file on editor change.
  const int checkDelayInMs = 200;
  if (!queueTimer_.isActive ()) {
    queueTimer_.singleShot (checkDelayInMs, this, SLOT (checkQueuedFiles ()));
  }
}

void CppcheckRunner::stopChecking () {
  fileCheckQueue_.clear ();
  if (process_.isOpen ()) {
    process_.kill ();
  }
}

void CppcheckRunner::checkQueuedFiles () {
  if (fileCheckQueue_.isEmpty ()) {
    return;
  }
  QString binary = settings_->binaryFile ();
  if (binary.isEmpty ()) {
    return;
  }
  // Pass custom params BEFORE most of runner's to shadow if some repeat.
  auto expander = Utils::globalMacroExpander ();
  auto expanded = expander->expand (settings_->customParameters ());
  QStringList arguments (expanded.split (QLatin1Char (' '), QString::SkipEmptyParts));
  arguments += runArguments_;

  auto includes = !settings_->ignoreIncludePaths () ? includePaths_ : QStringList {};
  currentlyCheckingFiles_ = fileCheckQueue_;
  fileCheckQueue_.clear ();

  int argumentLength = arguments.join (QLatin1Literal (" ")).length ();
  int filesLength = currentlyCheckingFiles_.join (QLatin1Literal (" ")).length ();
  int includesLength = includes.join (QLatin1Literal (" ")).length ();
  if (argumentLength + includesLength + filesLength >= maxArgumentsLength_) {
    if (fileListFileContents_ != currentlyCheckingFiles_) {
      fileListFileContents_ = currentlyCheckingFiles_;
      fileListFile_.resize (0);
      includeListFile_.resize (0);

      if (fileListFile_.open () && includeListFile_.open ()) {
        QByteArray filesArg = fileListFileContents_.join (QLatin1String ("\n")).toLocal8Bit ();
        fileListFile_.write (filesArg);
        fileListFile_.close ();

        for (auto &i: includes) {
          i = i.mid (2);
        }
        QByteArray includesArg = includes.join (QLatin1String ("\n")).toLocal8Bit ();
        includeListFile_.write (includesArg);
        includeListFile_.close ();
      }
      else{
        Core::MessageManager::write (tr ("Failed to write cppcheck's argument files"),
                                     Core::MessageManager::Silent);
        return;
      }
    }
    arguments << QString (QLatin1String ("--file-list=%1")).arg (fileListFile_.fileName ());
    arguments << QString (QLatin1String ("--includes-file=%1")).arg (includeListFile_.fileName ());
  }
  else{
    arguments += currentlyCheckingFiles_;
    arguments += includes;
  }
  emit startedChecking (currentlyCheckingFiles_);
  if (showOutput_) {
    Core::MessageManager::write (QString ("Starting CppChecker with:%1, %2")
                                 .arg (binary,arguments.join (" ")), Core::MessageManager::WithFocus);
  }
  process_.start (binary, arguments);
}

void CppcheckRunner::readOutput () {
  if (!showOutput_) {
    return;
  }
  process_.setReadChannel (QProcess::StandardOutput);

  while (!process_.atEnd () && process_.canReadLine ()) {
    QByteArray rawLine = process_.readLine ();
    QString line = QString::fromUtf8 (rawLine).trimmed ();
    if (line.isEmpty ()) {
      continue;
    }
    const QString progressSample = QLatin1String ("% done");
    // check futureInterface because read can be triggered before started..
    if (line.endsWith (progressSample) && futureInterface_ != NULL) {
      int percentEndIndex = line.length () - progressSample.length ();
      int percentStartIndex = line.lastIndexOf (QLatin1String (" "), percentEndIndex);
      int done = line.mid (percentStartIndex, percentEndIndex - percentStartIndex).toInt ();
      futureInterface_->setProgressValue (done);
    }
    Core::MessageManager::write (line, Core::MessageManager::Silent);
  }
}

void CppcheckRunner::readError () {
  process_.setReadChannel (QProcess::StandardError);

  while (!process_.atEnd () && process_.canReadLine ()) {
    QByteArray rawLine = process_.readLine ();
    QString line = QString::fromUtf8 (rawLine).trimmed ();
    if (line.isEmpty ()) {
      continue;
    }
    if (showOutput_) {
      Core::MessageManager::write (line, Core::MessageManager::Silent);
    }
    QStringList details = line.split (QLatin1Char (','));
    if (details.size () <= ErrorFieldMessage) {
      continue;
    }
    QString file = QDir::fromNativeSeparators (details.at (ErrorFieldFile));
    int lineNumber = details.at (ErrorFieldLine).toInt ();
    char type = details.at (ErrorFieldSeverity).at (0).toLatin1 ();
    QString id = "";
    if (showId_) {
      id = details.at (ErrorFieldId);
    }
    QString description = line.mid (line.indexOf (details.at (ErrorFieldMessage)));
    emit newTask (type, id, description, file, lineNumber);
  }
}

void CppcheckRunner::started () {
  if (showOutput_) {
    Core::MessageManager::write (tr ("Cppcheck started"), Core::MessageManager::Silent);
  }

  using namespace Core;
  delete futureInterface_;
  futureInterface_ = new QFutureInterface<void>;
  FutureProgress *progress = ProgressManager::addTask (futureInterface_->future (),
                                                       tr ("Cppcheck"), Constants::TASK_CHECKING);
  connect (progress, SIGNAL (canceled ()), SLOT (stopChecking ()));
  futureInterface_->setProgressRange (0, 100); // %
  futureInterface_->reportStarted ();
}

void CppcheckRunner::error (QProcess::ProcessError error) {
  Q_UNUSED (error);
  if (showOutput_) {
    Core::MessageManager::write (tr ("Cppcheck error occured"), Core::MessageManager::Silent);
  }
  if (error == QProcess::FailedToStart) {
    finished (-1, QProcess::CrashExit);
  }
}

void CppcheckRunner::finished (int exitCode, QProcess::ExitStatus exitStatus) {
  Q_UNUSED (exitCode);
  Q_UNUSED (exitStatus);
  if (futureInterface_ != NULL) {
    futureInterface_->reportFinished ();
  }
  process_.close ();
  if (showOutput_) {
    Core::MessageManager::write (tr ("Cppcheck finished"), Core::MessageManager::Silent);
  }
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: CurrentMasterPagesSelector.hxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: ihi $ $Date: 2006-08-01 09:22:20 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef SD_TOOLPANEL_CONTROLS_CURRENT_MASTER_PAGES_SELECTOR_HXX
#define SD_TOOLPANEL_CONTROLS_CURRENT_MASTER_PAGES_SELECTOR_HXX

#include "MasterPagesSelector.hxx"
#ifndef _COM_SUN_STAR_LANG_XCOMPONENT_HPP_
#include <com/sun/star/lang/XComponent.hpp>
#endif

namespace sd { namespace tools { class EventMultiplexerEvent; } }

namespace sd { namespace toolpanel { namespace controls {

/** Show the master pages currently used by a SdDrawDocument.
*/
class CurrentMasterPagesSelector
    : public MasterPagesSelector
{
public:
    CurrentMasterPagesSelector (
        TreeNode* pParent,
        SdDrawDocument& rDocument,
        ViewShellBase& rBase,
        const ::boost::shared_ptr<MasterPageContainer>& rpContainer);
    virtual ~CurrentMasterPagesSelector (void);

    virtual void LateInit (void);

    /** Set the selection so that the master page is selected that is
        used by the currently selected page of the document in the
        center pane.
    */
    virtual void UpdateSelection (void);

    /** Copy all master pages that are to be shown into the given list.
    */
    virtual void Fill (ItemList& rItemList);

protected:
    /** Return the master page whose preview is currently selected in the
        value set control.
        @return
            The returned page belongs to the main document, not to the local
            document of the MasterPageContainer.
    */
    virtual SdPage* GetSelectedMasterPage (void);

private:
    ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent>
        mxListener;

    DECL_LINK(EventMultiplexerListener,sd::tools::EventMultiplexerEvent*);
};

} } } // end of namespace ::sd::toolpanel::controls

#endif
<commit_msg>INTEGRATION: CWS sdwarningsbegone (1.6.76); FILE MERGED 2006/11/27 13:48:13 cl 1.6.76.1: #i69285# warning free code changes for sd project<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: CurrentMasterPagesSelector.hxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: kz $ $Date: 2006-12-12 18:46:56 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef SD_TOOLPANEL_CONTROLS_CURRENT_MASTER_PAGES_SELECTOR_HXX
#define SD_TOOLPANEL_CONTROLS_CURRENT_MASTER_PAGES_SELECTOR_HXX

#include "MasterPagesSelector.hxx"
#ifndef _COM_SUN_STAR_LANG_XCOMPONENT_HPP_
#include <com/sun/star/lang/XComponent.hpp>
#endif

namespace sd { namespace tools { class EventMultiplexerEvent; } }

namespace sd { namespace toolpanel { namespace controls {

/** Show the master pages currently used by a SdDrawDocument.
*/
class CurrentMasterPagesSelector
    : public MasterPagesSelector
{
public:
    CurrentMasterPagesSelector (
        TreeNode* pParent,
        SdDrawDocument& rDocument,
        ViewShellBase& rBase,
        const ::boost::shared_ptr<MasterPageContainer>& rpContainer);
    virtual ~CurrentMasterPagesSelector (void);

    virtual void LateInit (void);

    /** Set the selection so that the master page is selected that is
        used by the currently selected page of the document in the
        center pane.
    */
    virtual void UpdateSelection (void);

    /** Copy all master pages that are to be shown into the given list.
    */
    virtual void Fill (ItemList& rItemList);

    using sd::toolpanel::controls::MasterPagesSelector::Fill;

protected:
    /** Return the master page whose preview is currently selected in the
        value set control.
        @return
            The returned page belongs to the main document, not to the local
            document of the MasterPageContainer.
    */
    virtual SdPage* GetSelectedMasterPage (void);

private:
    ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent>
        mxListener;

    DECL_LINK(EventMultiplexerListener,sd::tools::EventMultiplexerEvent*);
};

} } } // end of namespace ::sd::toolpanel::controls

#endif
<|endoftext|>


<commit_before>//// License: Apache 2.0. See LICENSE file in root directory.
//// Copyright(c) 2020 Intel Corporation. All Rights Reserved.

#include "depth-to-rgb-calibration.h"
#include <librealsense2/rs.hpp>
#include "core/streaming.h"
#include "context.h"
#include <direct.h>

#define AC_LOG_PREFIX "AC1: "
#define AC_LOG(TYPE,MSG) LOG_##TYPE( AC_LOG_PREFIX << MSG )
//#define AC_LOG(TYPE,MSG) LOG_ERROR( AC_LOG_PREFIX << MSG )
//#define AC_LOG(TYPE,MSG) std::cout << (std::string)( to_string() << "-" << #TYPE [0] << "- " << MSG ) << std::endl

using namespace librealsense;
namespace impl = librealsense::algo::depth_to_rgb_calibration;

depth_to_rgb_calibration::depth_to_rgb_calibration(
    rs2::frame depth,
    rs2::frame ir,
    rs2::frame yuy,
    rs2::frame prev_yuy
)
    : _intr( yuy.get_profile().as< rs2::video_stream_profile >().get_intrinsics() )
    , _extr( depth.get_profile().get_extrinsics_to( yuy.get_profile()))
    , _depth_units(depth.as< rs2::depth_frame >().get_units())
    , _from( depth.get_profile().get()->profile )
    , _to( yuy.get_profile().get()->profile )
{
    debug_calibration( "old" );

    AC_LOG( DEBUG, "... setting yuy data" );
    auto color_profile = yuy.get_profile().as< rs2::video_stream_profile >();
    auto yuy_data = (impl::yuy_t const *) yuy.get_data();
    auto prev_yuy_data = (impl::yuy_t const *) prev_yuy.get_data();
    impl::calib calibration( _intr, _extr );
    _algo.set_yuy_data(
        std::vector< impl::yuy_t >( yuy_data, yuy_data + yuy.get_data_size() / sizeof( impl::yuy_t )),
        std::vector< impl::yuy_t >( prev_yuy_data, prev_yuy_data + yuy.get_data_size() / sizeof( impl::yuy_t ) ),
        calibration
    );

    AC_LOG( DEBUG, "... setting ir data" );
    auto ir_profile = ir.get_profile().as< rs2::video_stream_profile >();
    auto ir_data = (impl::ir_t const *) ir.get_data();
    _algo.set_ir_data(
        std::vector< impl::ir_t >( ir_data, ir_data + ir.get_data_size() / sizeof( impl::ir_t )),
        ir_profile.width(), ir_profile.height()
    );

    AC_LOG( DEBUG, "... setting z data" );
    auto z_profile = depth.get_profile().as< rs2::video_stream_profile >();
    auto z_data = (impl::z_t const *) depth.get_data();
    _algo.set_z_data(
        std::vector< impl::z_t >( z_data, z_data + depth.get_data_size() / sizeof( impl::z_t ) ),
        z_profile.get_intrinsics(),
        depth.as< rs2::depth_frame >().get_units()
    );

    std::string dir = "C:\\work\\autocal\\data\\";
    dir += to_string() << depth.get_frame_number();
    if( _mkdir( dir.c_str() ) == 0 )
        _algo.write_data_to( dir );
    else
        AC_LOG( WARNING, "Failed to write AC frame data to: " << dir );
}

rs2_calibration_status depth_to_rgb_calibration::optimize()
{
    try
    {
        AC_LOG( DEBUG, "... checking scene validity" );
        if( !_algo.is_scene_valid() )
        {
            AC_LOG( ERROR, "Calibration scene was found invalid!" );
            //return RS2_CALIBRATION_SCENE_INVALID;
        }

        AC_LOG( DEBUG, "... optimizing" );
        auto n_iterations = _algo.optimize();
        if( !n_iterations )
        {
            //AC_LOG( INFO, "Calibration not necessary; nothing done" );
            return RS2_CALIBRATION_NOT_NEEDED;
        }

        AC_LOG( DEBUG, "... checking result validity" );
        if( !_algo.is_valid_results() )
            ; // return RS2_CALIBRATION_BAD_RESULT;

        //AC_LOG( INFO, "Calibration finished; original cost= " << original_cost << "  optimized cost= " << params_curr.cost );

        _intr = _algo.get_calibration().get_intrinsics();
        _extr = _algo.get_calibration().get_extrinsics();
        debug_calibration( "new" );

        return RS2_CALIBRATION_SUCCESSFUL;
    }
    catch( std::exception const & e )
    {
        AC_LOG( ERROR, "Calibration failed: " << e.what() );
        return RS2_CALIBRATION_FAILED;
    }
}

void depth_to_rgb_calibration::debug_calibration( char const * prefix )
{
    AC_LOG( DEBUG, prefix << " intr"
        << ": width: " << _intr.width
        << ", height: " << _intr.height
        << ", ppx: " << _intr.ppx
        << ", ppy: " << _intr.ppy
        << ", fx: " << _intr.fx
        << ", fy: " << _intr.fy
        << ", model: " << int( _intr.model)
        << ", coeffs: ["
        << _intr.coeffs[0] << ", " << _intr.coeffs[1] << ", " << _intr.coeffs[2] << ", " << _intr.coeffs[3] << ", " << _intr.coeffs[4]
        << "]" );
    AC_LOG( DEBUG, prefix << " extr:"
        << " rotation: ["
        << _extr.rotation[0] << ", " << _extr.rotation[1] << ", " << _extr.rotation[2] << ", " << _extr.rotation[3] << ", " << _extr.rotation[4] << ", "
        << _extr.rotation[5] << ", " << _extr.rotation[6] << ", " << _extr.rotation[7] << ", " << _extr.rotation[8]
        << "]  translation: ["
        << _extr.translation[0] << ", " << _extr.translation[1] << ", " << _extr.translation[2]
        << "]" );
}

<commit_msg>nope... try with sys/stat.h...<commit_after>//// License: Apache 2.0. See LICENSE file in root directory.
//// Copyright(c) 2020 Intel Corporation. All Rights Reserved.

#include "depth-to-rgb-calibration.h"
#include <librealsense2/rs.hpp>
#include "core/streaming.h"
#include "context.h"
#include <sys/stat.h>  // mkdir

#define AC_LOG_PREFIX "AC1: "
#define AC_LOG(TYPE,MSG) LOG_##TYPE( AC_LOG_PREFIX << MSG )
//#define AC_LOG(TYPE,MSG) LOG_ERROR( AC_LOG_PREFIX << MSG )
//#define AC_LOG(TYPE,MSG) std::cout << (std::string)( to_string() << "-" << #TYPE [0] << "- " << MSG ) << std::endl

using namespace librealsense;
namespace impl = librealsense::algo::depth_to_rgb_calibration;

depth_to_rgb_calibration::depth_to_rgb_calibration(
    rs2::frame depth,
    rs2::frame ir,
    rs2::frame yuy,
    rs2::frame prev_yuy
)
    : _intr( yuy.get_profile().as< rs2::video_stream_profile >().get_intrinsics() )
    , _extr( depth.get_profile().get_extrinsics_to( yuy.get_profile()))
    , _depth_units(depth.as< rs2::depth_frame >().get_units())
    , _from( depth.get_profile().get()->profile )
    , _to( yuy.get_profile().get()->profile )
{
    debug_calibration( "old" );

    AC_LOG( DEBUG, "... setting yuy data" );
    auto color_profile = yuy.get_profile().as< rs2::video_stream_profile >();
    auto yuy_data = (impl::yuy_t const *) yuy.get_data();
    auto prev_yuy_data = (impl::yuy_t const *) prev_yuy.get_data();
    impl::calib calibration( _intr, _extr );
    _algo.set_yuy_data(
        std::vector< impl::yuy_t >( yuy_data, yuy_data + yuy.get_data_size() / sizeof( impl::yuy_t )),
        std::vector< impl::yuy_t >( prev_yuy_data, prev_yuy_data + yuy.get_data_size() / sizeof( impl::yuy_t ) ),
        calibration
    );

    AC_LOG( DEBUG, "... setting ir data" );
    auto ir_profile = ir.get_profile().as< rs2::video_stream_profile >();
    auto ir_data = (impl::ir_t const *) ir.get_data();
    _algo.set_ir_data(
        std::vector< impl::ir_t >( ir_data, ir_data + ir.get_data_size() / sizeof( impl::ir_t )),
        ir_profile.width(), ir_profile.height()
    );

    AC_LOG( DEBUG, "... setting z data" );
    auto z_profile = depth.get_profile().as< rs2::video_stream_profile >();
    auto z_data = (impl::z_t const *) depth.get_data();
    _algo.set_z_data(
        std::vector< impl::z_t >( z_data, z_data + depth.get_data_size() / sizeof( impl::z_t ) ),
        z_profile.get_intrinsics(),
        depth.as< rs2::depth_frame >().get_units()
    );

    std::string dir = "C:\\work\\autocal\\data\\";
    dir += to_string() << depth.get_frame_number();
    if( mkdir( dir.c_str() ) == 0 )
        _algo.write_data_to( dir );
    else
        AC_LOG( WARNING, "Failed to write AC frame data to: " << dir );
}

rs2_calibration_status depth_to_rgb_calibration::optimize()
{
    try
    {
        AC_LOG( DEBUG, "... checking scene validity" );
        if( !_algo.is_scene_valid() )
        {
            AC_LOG( ERROR, "Calibration scene was found invalid!" );
            //return RS2_CALIBRATION_SCENE_INVALID;
        }

        AC_LOG( DEBUG, "... optimizing" );
        auto n_iterations = _algo.optimize();
        if( !n_iterations )
        {
            //AC_LOG( INFO, "Calibration not necessary; nothing done" );
            return RS2_CALIBRATION_NOT_NEEDED;
        }

        AC_LOG( DEBUG, "... checking result validity" );
        if( !_algo.is_valid_results() )
            ; // return RS2_CALIBRATION_BAD_RESULT;

        //AC_LOG( INFO, "Calibration finished; original cost= " << original_cost << "  optimized cost= " << params_curr.cost );

        _intr = _algo.get_calibration().get_intrinsics();
        _extr = _algo.get_calibration().get_extrinsics();
        debug_calibration( "new" );

        return RS2_CALIBRATION_SUCCESSFUL;
    }
    catch( std::exception const & e )
    {
        AC_LOG( ERROR, "Calibration failed: " << e.what() );
        return RS2_CALIBRATION_FAILED;
    }
}

void depth_to_rgb_calibration::debug_calibration( char const * prefix )
{
    AC_LOG( DEBUG, prefix << " intr"
        << ": width: " << _intr.width
        << ", height: " << _intr.height
        << ", ppx: " << _intr.ppx
        << ", ppy: " << _intr.ppy
        << ", fx: " << _intr.fx
        << ", fy: " << _intr.fy
        << ", model: " << int( _intr.model)
        << ", coeffs: ["
        << _intr.coeffs[0] << ", " << _intr.coeffs[1] << ", " << _intr.coeffs[2] << ", " << _intr.coeffs[3] << ", " << _intr.coeffs[4]
        << "]" );
    AC_LOG( DEBUG, prefix << " extr:"
        << " rotation: ["
        << _extr.rotation[0] << ", " << _extr.rotation[1] << ", " << _extr.rotation[2] << ", " << _extr.rotation[3] << ", " << _extr.rotation[4] << ", "
        << _extr.rotation[5] << ", " << _extr.rotation[6] << ", " << _extr.rotation[7] << ", " << _extr.rotation[8]
        << "]  translation: ["
        << _extr.translation[0] << ", " << _extr.translation[1] << ", " << _extr.translation[2]
        << "]" );
}

<|endoftext|>


<commit_before>#include "devicedetectionprocessor.h"
#include "config/configuration.h"
#include "events/events.h"
#include "sysex/devicedetectionquery.h"
#include "sysex/midi.h"

#include <QApplication>
#include <QDebug>
#include <QSettings>
#include <iomanip>
#include <unistd.h>

DeviceDetectionProcessor::DeviceDetectionProcessor(QWidget *gui) : gui(gui) {
	std::cout << "create DeviceDetectionProcessor" << std::endl;
}

DeviceDetectionProcessor::~DeviceDetectionProcessor() {
  if (Configuration::getInstance().getUsbDeviceDetection())
    libusb_exit(NULL);
  if (Configuration::getInstance().getMidiDeviceDetection()) {
    midiin = NULL;
    midiout = NULL;
  }
}

int DeviceDetectionProcessor::getMidiInPortCount() {
  if (midiin)
    return midiin->getPortCount();
  return 0;
}

int DeviceDetectionProcessor::getMddiOutPortCount() {
  if (midiout)
    return midiout->getPortCount();
  return 0;
}

/* MIDI-methods */

void DeviceDetectionProcessor::startDeviceDetection() {
  if (Configuration::getInstance().getMidiDeviceDetection()) {
    setupMidiPorts();
    detectDevices();
  }
  if (Configuration::getInstance().getUsbDeviceDetection()) {
    setupUSB();
  }
}

bool DeviceDetectionProcessor::isIconnectivityDevice(
    std::vector<unsigned char> *message) {
  int nMessageSize = message->size();
  return ((nMessageSize >= 16) && (message->at(0) == SYSEX_START) &&
          (message->at(1) == Device::MANUFACTURER_SYSEX_ID[0]) &&
          (message->at(2) == Device::MANUFACTURER_SYSEX_ID[1]) &&
          (message->at(3) == Device::MANUFACTURER_SYSEX_ID[2]) &&
          (message->at(15) == 0x02));
}

void DeviceDetectionProcessor::setupMidiPorts() {
  createMidiIn();
  createMidiOut();
}

void DeviceDetectionProcessor::sendProgressEvent(int progress) {
  ProgressEvent *e = new ProgressEvent();
  e->setValue(progress);
  QApplication::sendEvent(gui, e);
}

int DeviceDetectionProcessor::detectDevices() {

  int defaultDeviceSerialNumber =
      Configuration::getInstance().getDefaultDevice();
  int nOutPortCount = midiout->getPortCount();
  int nInPortCount = midiin->getPortCount();
#ifdef __MIO_DEBUG__
  std::cout << "Out ports: " << std::dec << nOutPortCount
            << ", in ports: " << nInPortCount
            << " - combinations to probe:  " << nOutPortCount * nInPortCount
            << std::endl;
#endif //__MIO_DEBUG__
  DeviceDetectionQuery *q = new DeviceDetectionQuery();
  long serialNumber;
  BYTE_VECTOR *qMessage = q->getMIDISysExMessage();
  std::map<long, Device *> *devices = Configuration::getInstance().getDevices();
  // for each output signal
  for (int i = 0; i < nOutPortCount; i++) {
    midiout->openPort(i);
    // and each input signal
    for (int j = 0; j < nInPortCount; j++) {
      int progress = (i * nInPortCount) + j + 1;
      sendProgressEvent(progress);
			midiin->openPort(j);
			midiout->sendMessage(qMessage);
      // pause a little
			usleep(100000);
			BYTE_VECTOR *message = new BYTE_VECTOR;
      midiin->getMessage(message);
      unsigned int nMessageSize = message->size();
      if (nMessageSize > 0) {
#ifdef __MIO_DEBUG__
        MIDI::printMessage(message);
#endif //__MIO_DEBUG__
        // test for iConnectivity device
        if (isIconnectivityDevice(message)) {
          serialNumber =
              MIDI::byteJoin(message, (unsigned int)7, (unsigned int)5);
					std::cout << "device with serial number " << serialNumber
										<< " detected... (" << midiout->getPortName(i) << "- "
										<< midiin->getPortName(j) << ") ";
          midiin->closePort();
					midiout->closePort();
          if (devices->find(serialNumber) == devices->end()) {
            int productId = MIDI::byteJoin(message, 5, 2);
            Device *device = new Device(j, i, serialNumber, productId);
            devices->insert(std::pair<long, Device *>(serialNumber, device));
						std::cout << "... and added to list of devices" << std::endl;
          } else {
						std::cout << "... but it's already recognized" << std::endl;
          }
          break;
        }
#ifdef __MIO_DEBUG__
        else {
          std::cout << "there is an answer from a device but no iConnectivity: "
                    << midiout->getPortName(i) << " - "
                    << midiin->getPortName(j) << std::endl;
        }
#endif // __MIO_DEBUG__
      }
#ifdef __MIO_DEBUG__
      else {
        std::cout << "no answer from any device: " << midiout->getPortName(i)
                  << " - " << midiin->getPortName(j) << std::endl;
      }
#endif //__MIO_DEBUG__
			midiin->closePort();
    }
		if (midiout->isPortOpen())
			midiout->closePort();
    ProgressEvent *e = new ProgressEvent();
    e->setValue(getMidiInPortCount() * getMddiOutPortCount());
    QApplication::sendEvent(gui, e);
  }
#ifdef __MIO_SIMULATE__
  // if simulation is enabled, send some events to progress bar...
  int base = midiin->getPortCount() * midiout->getPortCount();
  for (int i = 0; i <= 27; i++) {
    sendProgressEvent(base + i);
    usleep(10000);
  }
  //... and create two devices
  Device *ds = new Device(1, 1, 0x11, 0x0101, "mio10", "Device 1");
  devices->insert(std::pair<long, Device *>(0x11, ds));
  ds = new Device(2, 2, 0x12, 0x0201, "mio2", "Device 2");
  devices->insert(std::pair<long, Device *>(0x12, ds));
#endif //__MIO_SIMULATE__
  Device *d = 0;
  try {
    d = devices->at(defaultDeviceSerialNumber);
    d->setDefault(true);
  } catch (std::out_of_range) {
    d = devices->begin()->second;
    d->setDefault(true);
    defaultDeviceSerialNumber = d->getSerialNumber()->getLongValue();
    Configuration::getInstance().setDefaultDevice(defaultDeviceSerialNumber);
  }

	for (Devices::iterator it = devices->begin(); it != devices->end(); ++it) {
    d = it->second;
    d->queryDeviceInfo();
  }
  Configuration::getInstance().setDevices(devices);
  return devices->size();
}

double DeviceDetectionProcessor::getMessage(BYTE_VECTOR *message) {
  double deltatime = midiin->getMessage(message);
  return deltatime;
}

void DeviceDetectionProcessor::createMidiIn() {
  midiin = MIDI::createMidiIn();
#ifdef __MIO_DEBUG__
  unsigned int nPorts = midiin->getPortCount();
  std::cout << "\nThere are " << nPorts << " MIDI input sources available.\n";
  std::string portName;
  for (unsigned int i = 0; i < nPorts; i++) {
    try {
      portName = midiin->getPortName(i);
    } catch (RtMidiError &error) {
      error.printMessage();
    }
    std::cout << "  Input Port #" << i + 1 << ": " << portName.c_str() << "\n";
  }
#endif //__MIO_DEBUG_
}

void DeviceDetectionProcessor::createMidiOut() {
  // RtMidiOut constructor
  midiout = MIDI::createMidiOut();
// Check outputs.
#ifdef __MIO_DEBUG__
  unsigned int nPorts = midiout->getPortCount();
  std::cout << "\nThere are " << nPorts << " MIDI output ports available.\n";
  std::string portName;
  for (unsigned int i = 0; i < nPorts; i++) {
    try {
      portName = midiout->getPortName(i);
    } catch (RtMidiError &error) {
      error.printMessage();
    }
    std::cout << "  Output Port #" << i + 1 << ": " << portName.c_str() << "\n";
  }
#endif //__MIO_DEBUG__
}

/* USB methods - currently not used */
bool DeviceDetectionProcessor::setupUSB() {
  int r;

  r = libusb_init(NULL);
  if (r < 0)
    return false;

  return true;
}

void DeviceDetectionProcessor::printUSBDevs() {
  ssize_t cnt;
  libusb_device **devs;
  libusb_device *dev;
  int i = 0, j = 0;
  uint8_t path[8];

  cnt = libusb_get_device_list(NULL, &devs);
  if (cnt < 0)
    return;

  while ((dev = devs[i++]) != NULL) {
    struct libusb_device_descriptor desc;
    int r = libusb_get_device_descriptor(dev, &desc);
    if (r < 0) {
      fprintf(stderr, "failed to get device descriptor");
      return;
    }

    printf("%04x:%04x (bus %d, device %d)", desc.idVendor, desc.idProduct,
           libusb_get_bus_number(dev), libusb_get_device_address(dev));
    if (desc.idVendor == Device::MANUFACTURER_USB_ID) {
      std::cout << "Found iConnectivity Device";
    }
    r = libusb_get_port_numbers(dev, path, sizeof(path));
    if (r > 0) {
      printf(" path: %d", path[0]);
      for (j = 1; j < r; j++)
        printf(".%d", path[j]);
    }
    printf("\n");
  }

  libusb_free_device_list(devs, 1);
}
<commit_msg>use macro for device dependend wait times correction for calculating the progress steps of device detection<commit_after>#include "devicedetectionprocessor.h"
#include "config/configuration.h"
#include "events/events.h"
#include "sysex/devicedetectionquery.h"
#include "sysex/midi.h"

#include <QApplication>
#include <QDebug>
#include <QSettings>
#include <iomanip>
#include <unistd.h>

DeviceDetectionProcessor::DeviceDetectionProcessor(QWidget *gui) : gui(gui) {
	if (Configuration::getInstance().getMidiDeviceDetection()) {
		setupMidiPorts();
	}
	if (Configuration::getInstance().getUsbDeviceDetection()) {
		setupUSB();
	}
}

DeviceDetectionProcessor::~DeviceDetectionProcessor() {
  if (Configuration::getInstance().getUsbDeviceDetection())
    libusb_exit(NULL);
  if (Configuration::getInstance().getMidiDeviceDetection()) {
    midiin = NULL;
    midiout = NULL;
  }
}

int DeviceDetectionProcessor::getMidiInPortCount() {
  if (midiin)
    return midiin->getPortCount();
  return 0;
}

int DeviceDetectionProcessor::getMddiOutPortCount() {
  if (midiout)
    return midiout->getPortCount();
  return 0;
}

/* MIDI-methods */

void DeviceDetectionProcessor::startDeviceDetection() {
  if (Configuration::getInstance().getMidiDeviceDetection()) {
    detectDevices();
  }
}

bool DeviceDetectionProcessor::isIconnectivityDevice(
    std::vector<unsigned char> *message) {
  int nMessageSize = message->size();
  return ((nMessageSize >= 16) && (message->at(0) == SYSEX_START) &&
          (message->at(1) == Device::MANUFACTURER_SYSEX_ID[0]) &&
          (message->at(2) == Device::MANUFACTURER_SYSEX_ID[1]) &&
          (message->at(3) == Device::MANUFACTURER_SYSEX_ID[2]) &&
          (message->at(15) == 0x02));
}

void DeviceDetectionProcessor::setupMidiPorts() {
  createMidiIn();
  createMidiOut();
}

void DeviceDetectionProcessor::sendProgressEvent(int progress) {
  ProgressEvent *e = new ProgressEvent();
  e->setValue(progress);
  QApplication::sendEvent(gui, e);
}

int DeviceDetectionProcessor::detectDevices() {

  int defaultDeviceSerialNumber =
      Configuration::getInstance().getDefaultDevice();
  int nOutPortCount = midiout->getPortCount();
  int nInPortCount = midiin->getPortCount();
#ifdef __MIO_DEBUG__
  std::cout << "Out ports: " << std::dec << nOutPortCount
            << ", in ports: " << nInPortCount
            << " - combinations to probe:  " << nOutPortCount * nInPortCount
            << std::endl;
#endif //__MIO_DEBUG__
  DeviceDetectionQuery *q = new DeviceDetectionQuery();
  long serialNumber;
  BYTE_VECTOR *qMessage = q->getMIDISysExMessage();
  std::map<long, Device *> *devices = Configuration::getInstance().getDevices();
  // for each output signal
  for (int i = 0; i < nOutPortCount; i++) {
    midiout->openPort(i);
    // and each input signal
    for (int j = 0; j < nInPortCount; j++) {
      int progress = (i * nInPortCount) + j + 1;
      sendProgressEvent(progress);
			midiin->openPort(j);
			midiout->sendMessage(qMessage);
      // pause a little
			SLEEP(100);
			BYTE_VECTOR *message = new BYTE_VECTOR;
      midiin->getMessage(message);
      unsigned int nMessageSize = message->size();
      if (nMessageSize > 0) {
#ifdef __MIO_DEBUG__
        MIDI::printMessage(message);
#endif //__MIO_DEBUG__
        // test for iConnectivity device
        if (isIconnectivityDevice(message)) {
          serialNumber =
              MIDI::byteJoin(message, (unsigned int)7, (unsigned int)5);
					std::cout << "device with serial number " << serialNumber
										<< " detected... (" << midiout->getPortName(i) << "- "
										<< midiin->getPortName(j) << ") ";
          midiin->closePort();
					midiout->closePort();
          if (devices->find(serialNumber) == devices->end()) {
            int productId = MIDI::byteJoin(message, 5, 2);
            Device *device = new Device(j, i, serialNumber, productId);
            devices->insert(std::pair<long, Device *>(serialNumber, device));
						std::cout << "... and added to list of devices" << std::endl;
          } else {
						std::cout << "... but it's already recognized" << std::endl;
          }
          break;
        }
#ifdef __MIO_DEBUG__
        else {
          std::cout << "there is an answer from a device but no iConnectivity: "
                    << midiout->getPortName(i) << " - "
                    << midiin->getPortName(j) << std::endl;
        }
#endif // __MIO_DEBUG__
      }
#ifdef __MIO_DEBUG__
      else {
        std::cout << "no answer from any device: " << midiout->getPortName(i)
                  << " - " << midiin->getPortName(j) << std::endl;
      }
#endif //__MIO_DEBUG__
			midiin->closePort();
    }
		if (midiout->isPortOpen())
			midiout->closePort();
	}
	sendProgressEvent(getMidiInPortCount() * getMddiOutPortCount());

#ifdef __MIO_SIMULATE__
  // if simulation is enabled, send some events to progress bar...
  int base = midiin->getPortCount() * midiout->getPortCount();
  for (int i = 0; i <= 27; i++) {
    sendProgressEvent(base + i);
		SLEEP(10);
  }
  //... and create two devices
  Device *ds = new Device(1, 1, 0x11, 0x0101, "mio10", "Device 1");
  devices->insert(std::pair<long, Device *>(0x11, ds));
  ds = new Device(2, 2, 0x12, 0x0201, "mio2", "Device 2");
  devices->insert(std::pair<long, Device *>(0x12, ds));
#endif //__MIO_SIMULATE__
  Device *d = 0;
  try {
    d = devices->at(defaultDeviceSerialNumber);
    d->setDefault(true);
  } catch (std::out_of_range) {
    d = devices->begin()->second;
    d->setDefault(true);
    defaultDeviceSerialNumber = d->getSerialNumber()->getLongValue();
    Configuration::getInstance().setDefaultDevice(defaultDeviceSerialNumber);
  }

	for (Devices::iterator it = devices->begin(); it != devices->end(); ++it) {
    d = it->second;
    d->queryDeviceInfo();
  }
  Configuration::getInstance().setDevices(devices);
  return devices->size();
}

double DeviceDetectionProcessor::getMessage(BYTE_VECTOR *message) {
  double deltatime = midiin->getMessage(message);
  return deltatime;
}

void DeviceDetectionProcessor::createMidiIn() {
  midiin = MIDI::createMidiIn();
#ifdef __MIO_DEBUG__
  unsigned int nPorts = midiin->getPortCount();
  std::cout << "\nThere are " << nPorts << " MIDI input sources available.\n";
  std::string portName;
  for (unsigned int i = 0; i < nPorts; i++) {
    try {
      portName = midiin->getPortName(i);
    } catch (RtMidiError &error) {
      error.printMessage();
    }
    std::cout << "  Input Port #" << i + 1 << ": " << portName.c_str() << "\n";
  }
#endif //__MIO_DEBUG_
}

void DeviceDetectionProcessor::createMidiOut() {
  // RtMidiOut constructor
  midiout = MIDI::createMidiOut();
// Check outputs.
#ifdef __MIO_DEBUG__
  unsigned int nPorts = midiout->getPortCount();
  std::cout << "\nThere are " << nPorts << " MIDI output ports available.\n";
  std::string portName;
  for (unsigned int i = 0; i < nPorts; i++) {
    try {
      portName = midiout->getPortName(i);
    } catch (RtMidiError &error) {
      error.printMessage();
    }
    std::cout << "  Output Port #" << i + 1 << ": " << portName.c_str() << "\n";
  }
#endif //__MIO_DEBUG__
}

/* USB methods - currently not used */
bool DeviceDetectionProcessor::setupUSB() {
  int r;

  r = libusb_init(NULL);
  if (r < 0)
    return false;

  return true;
}

void DeviceDetectionProcessor::printUSBDevs() {
  ssize_t cnt;
  libusb_device **devs;
  libusb_device *dev;
  int i = 0, j = 0;
  uint8_t path[8];

  cnt = libusb_get_device_list(NULL, &devs);
  if (cnt < 0)
    return;

  while ((dev = devs[i++]) != NULL) {
    struct libusb_device_descriptor desc;
    int r = libusb_get_device_descriptor(dev, &desc);
    if (r < 0) {
      fprintf(stderr, "failed to get device descriptor");
      return;
    }

    printf("%04x:%04x (bus %d, device %d)", desc.idVendor, desc.idProduct,
           libusb_get_bus_number(dev), libusb_get_device_address(dev));
    if (desc.idVendor == Device::MANUFACTURER_USB_ID) {
      std::cout << "Found iConnectivity Device";
    }
    r = libusb_get_port_numbers(dev, path, sizeof(path));
    if (r > 0) {
      printf(" path: %d", path[0]);
      for (j = 1; j < r; j++)
        printf(".%d", path[j]);
    }
    printf("\n");
  }

  libusb_free_device_list(devs, 1);
}
<|endoftext|>


<commit_before>/*
    open source routing machine
    Copyright (C) Dennis Luxen, others 2010

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
or see http://www.gnu.org/licenses/agpl.txt.
 */
#ifdef STXXL_VERBOSE_LEVEL
#undef STXXL_VERBOSE_LEVEL
#endif
#define STXXL_VERBOSE_LEVEL -1000

#include <algorithm>
#include <cassert>
#include <climits>
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>

#include <libxml/xmlreader.h>
#include <google/sparse_hash_map>
#include <unistd.h>
#include <stxxl.h>

#include "typedefs.h"
#include "DataStructures/InputReaderFactory.h"
#include "DataStructures/ExtractorCallBacks.h"
#include "DataStructures/ExtractorStructs.h"
#include "DataStructures/PBFParser.h"
#include "DataStructures/XMLParser.h"
#include "Util/BaseConfiguration.h"
#include "Util/InputFileUtil.h"

typedef BaseConfiguration ExtractorConfiguration;

unsigned globalRelationCounter = 0;
ExtractorCallbacks * extractCallBacks;

bool nodeFunction(_Node n);
bool adressFunction(_Node n, HashTable<std::string, std::string> keyVals);
bool relationFunction(_Relation r);
bool wayFunction(_Way w);

template<class ClassT>
bool removeIfUnused(ClassT n) { return (false == n.used); }

int main (int argc, char *argv[]) {
    if(argc <= 1) {
        std::cerr << "usage: " << endl << argv[0] << " <file.osm>" << std::endl;
        exit(-1);
    }

    std::cout << "[extractor] extracting data from input file " << argv[1] << std::endl;
    bool isPBF = false;
    std::string outputFileName(argv[1]);
    std::string::size_type pos = outputFileName.find(".osm.bz2");
    if(pos==string::npos) {
        pos = outputFileName.find(".osm.pbf");
        if(pos!=string::npos) {
            isPBF = true;
        }
    }
    if(pos!=string::npos) {
        outputFileName.replace(pos, 8, ".osrm");
    } else {
        pos=outputFileName.find(".osm");
        if(pos!=string::npos) {
            outputFileName.replace(pos, 5, ".osrm");
        } else {
            outputFileName.append(".osrm");
        }
    }
    std::string adressFileName(outputFileName);

    unsigned amountOfRAM = 1;
    unsigned installedRAM = (sysconf(_SC_PHYS_PAGES) * sysconf(_SC_PAGESIZE));
    if(installedRAM < 2097422336) {
        std::cout << "[Warning] Machine has less than 2GB RAM." << std::endl;
    }
    if(testDataFile("extractor.ini")) {
        ExtractorConfiguration extractorConfig("extractor.ini");
        unsigned memoryAmountFromFile = atoi(extractorConfig.GetParameter("Memory").c_str());
        if( memoryAmountFromFile != 0 && memoryAmountFromFile <= installedRAM/(1024*1024*1024))
            amountOfRAM = memoryAmountFromFile;
        std::cout << "[extractor] using " << amountOfRAM << " GB of RAM for buffers" << std::endl;
    }

    STXXLNodeIDVector usedNodeIDs;
    STXXLNodeVector   allNodes;
    STXXLEdgeVector   allEdges;
    STXXLAddressVector adressVector;
    STXXLStringVector  nameVector;
    unsigned usedNodeCounter = 0;
    unsigned usedEdgeCounter = 0;

    StringMap * stringMap = new StringMap();
    Settings settings;
    settings.speedProfile.names.insert(settings.speedProfile.names.begin(), names, names+14);
    settings.speedProfile.speed.insert(settings.speedProfile.speed.begin(), speeds, speeds+14);

    double time = get_timestamp();

    stringMap->set_empty_key(GetRandomString());
    stringMap->insert(std::make_pair("", 0));
    extractCallBacks = new ExtractorCallbacks(&allNodes, &usedNodeIDs, &allEdges,  &nameVector, &adressVector, settings, stringMap);

    BaseParser<_Node, _Relation, _Way> * parser;
    if(isPBF) {
        parser = new PBFParser(argv[1]);
    } else {
        parser = new XMLParser(argv[1]);
    }
    parser->RegisterCallbacks(&nodeFunction, &relationFunction, &wayFunction, &adressFunction);
    if(parser->Init()) {
        parser->Parse();
    } else {
        std::cerr << "[error] parser not initialized!" << std::endl;
        exit(-1);
    }
    delete parser;

    try {
        //        std::cout << "[info] raw no. of names:     " << nameVector.size()    << std::endl;
        //        std::cout << "[info] raw no. of nodes:     " << allNodes.size()      << std::endl;
        //        std::cout << "[info] no. of used nodes:    " << usedNodeIDs.size()     << std::endl;
        //        std::cout << "[info] raw no. of edges:     " << allEdges.size()      << std::endl;
        //        std::cout << "[info] raw no. of relations: " << globalRelationCounter << std::endl;
        //        std::cout << "[info] raw no. of addresses: " << adressVector.size()  << std::endl;

        std::cout << "[extractor] parsing finished after " << get_timestamp() - time << "seconds" << std::endl;
        time = get_timestamp();
        unsigned memory_to_use = amountOfRAM * 1024 * 1024 * 1024;

        std::cout << "[extractor] Sorting used nodes        ... " << std::flush;
        stxxl::sort(usedNodeIDs.begin(), usedNodeIDs.end(), Cmp(), memory_to_use);
        std::cout << "ok, after " << get_timestamp() - time << "s" << std::endl;

        time = get_timestamp();
        std::cout << "[extractor] Erasing duplicate nodes   ... " << std::flush;
        stxxl::vector<NodeID>::iterator NewEnd = unique ( usedNodeIDs.begin(),usedNodeIDs.end() ) ;
        usedNodeIDs.resize ( NewEnd - usedNodeIDs.begin() );
        cout << "ok, after " << get_timestamp() - time << "s" << endl;
        time = get_timestamp();

        std::cout << "[extractor] Sorting all nodes         ... " << std::flush;
        stxxl::sort(allNodes.begin(), allNodes.end(), CmpNodeByID(), memory_to_use);
        std::cout << "ok, after " << get_timestamp() - time << "s" << std::endl;
        time = get_timestamp();

        std::ofstream fout;
        fout.open(outputFileName.c_str(), std::ios::binary);
        fout.write((char*)&usedNodeCounter, sizeof(unsigned));

        std::cout << "[extractor] Confirming used nodes     ... " << std::flush;
        STXXLNodeVector::iterator nodesIT = allNodes.begin();
        STXXLNodeIDVector::iterator usedNodeIDsIT = usedNodeIDs.begin();
        while(usedNodeIDsIT != usedNodeIDs.end() && nodesIT != allNodes.end()) {
            if(*usedNodeIDsIT < nodesIT->id){
                usedNodeIDsIT++;
                continue;
            }
            if(*usedNodeIDsIT > nodesIT->id) {
                nodesIT++;
                continue;
            }
            if(*usedNodeIDsIT == nodesIT->id) {
                fout.write((char*)&(nodesIT->id), sizeof(unsigned));
                fout.write((char*)&(nodesIT->lon), sizeof(int));
                fout.write((char*)&(nodesIT->lat), sizeof(int));
                usedNodeCounter++;
                usedNodeIDsIT++;
                nodesIT++;
            }
        }
        std::cout << "ok, after " << get_timestamp() - time << "s" << std::endl;
        time = get_timestamp();

        std::cout << "[extractor] setting number of nodes   ... " << std::flush;
        std::ios::pos_type positionInFile = fout.tellp();
        fout.seekp(std::ios::beg);
        fout.write((char*)&usedNodeCounter, sizeof(unsigned));
        fout.seekp(positionInFile);

        std::cout << "ok" << std::endl;
        time = get_timestamp();

        // Sort edges by start.
        std::cout << "[extractor] Sorting edges by start    ... " << std::flush;
        stxxl::sort(allEdges.begin(), allEdges.end(), CmpEdgeByStartID(), memory_to_use);
        std::cout << "ok, after " << get_timestamp() - time << "s" << std::endl;
        time = get_timestamp();

        std::cout << "[extractor] Setting start coords      ... " << std::flush;
        fout.write((char*)&usedEdgeCounter, sizeof(unsigned));
        // Traverse list of edges and nodes in parallel and set start coord
        nodesIT = allNodes.begin();
        STXXLEdgeVector::iterator edgeIT = allEdges.begin();
        while(edgeIT != allEdges.end() && nodesIT != allNodes.end()) {
            if(edgeIT->start < nodesIT->id){
                edgeIT++;
                continue;
            }
            if(edgeIT->start > nodesIT->id) {
                nodesIT++;
                continue;
            }
            if(edgeIT->start == nodesIT->id) {
                edgeIT->startCoord.lat = nodesIT->lat;
                edgeIT->startCoord.lon = nodesIT->lon;
                edgeIT++;
            }
        }
        std::cout << "ok, after " << get_timestamp() - time << "s" << std::endl;
        time = get_timestamp();

        // Sort Edges by target
        std::cout << "[extractor] Sorting edges by target   ... " << std::flush;
        stxxl::sort(allEdges.begin(), allEdges.end(), CmpEdgeByTargetID(), memory_to_use);
        std::cout << "ok, after " << get_timestamp() - time << "s" << std::endl;
        time = get_timestamp();

        std::cout << "[extractor] Setting target coords     ... " << std::flush;
        // Traverse list of edges and nodes in parallel and set target coord
        nodesIT = allNodes.begin();
        edgeIT = allEdges.begin();
        while(edgeIT != allEdges.end() && nodesIT != allNodes.end()) {
            if(edgeIT->target < nodesIT->id){
                edgeIT++;
                continue;
            }
            if(edgeIT->target > nodesIT->id) {
                nodesIT++;
                continue;
            }
            if(edgeIT->startCoord.lat != INT_MIN && edgeIT->target == nodesIT->id) {
                edgeIT->targetCoord.lat = nodesIT->lat;
                edgeIT->targetCoord.lon = nodesIT->lon;

                double distance = ApproximateDistance(edgeIT->startCoord.lat, edgeIT->startCoord.lon, nodesIT->lat, nodesIT->lon);
                if(edgeIT->speed == -1)
                    edgeIT->speed = settings.speedProfile.speed[edgeIT->type];
                double weight = ( distance * 10. ) / (edgeIT->speed / 3.6);
                int intWeight = max(1, (int) weight);
                int intDist = max(1, (int)distance);
                int ferryIndex = settings.indexInAccessListOf("ferry");
                assert(ferryIndex != -1);
                short zero = 0;
                short one = 1;

                fout.write((char*)&edgeIT->start, sizeof(unsigned));
                fout.write((char*)&edgeIT->target, sizeof(unsigned));
                fout.write((char*)&intDist, sizeof(int));
                switch(edgeIT->direction) {
                case _Way::notSure:
                    fout.write((char*)&zero, sizeof(short));
                    break;
                case _Way::oneway:
                    fout.write((char*)&one, sizeof(short));
                    break;
                case _Way::bidirectional:
                    fout.write((char*)&zero, sizeof(short));

                    break;
                case _Way::opposite:
                    fout.write((char*)&one, sizeof(short));
                    break;
                default:
                    std::cerr << "[error] edge with no direction: " << edgeIT->direction << std::endl;
                    assert(false);
                    break;
                }
                fout.write((char*)&intWeight, sizeof(int));
                short edgeType = edgeIT->type;
                fout.write((char*)&edgeType, sizeof(short));
                fout.write((char*)&edgeIT->nameID, sizeof(unsigned));

                usedEdgeCounter++;
                edgeIT++;
            }
        }
        std::cout << "ok, after " << get_timestamp() - time << "s" << std::endl;
        time = get_timestamp();

        std::cout << "[extractor] setting number of edges   ... " << std::flush;
        fout.seekp(positionInFile);
        fout.write((char*)&usedEdgeCounter, sizeof(unsigned));
        fout.close();
        std::cout << "ok" << std::endl;
        time = get_timestamp();

        std::cout << "[extractor] writing street name index ... " << std::flush;
        std::vector<unsigned> * nameIndex = new std::vector<unsigned>(nameVector.size()+1, 0);
        outputFileName.append(".names");
        std::ofstream nameOutFile(outputFileName.c_str(), std::ios::binary);
        unsigned sizeOfNameIndex = nameIndex->size();
        nameOutFile.write((char *)&(sizeOfNameIndex), sizeof(unsigned));

        for(STXXLStringVector::iterator it = nameVector.begin(); it != nameVector.end(); it++) {
            unsigned lengthOfRawString = strlen(it->c_str());
            nameOutFile.write((char *)&(lengthOfRawString), sizeof(unsigned));
            nameOutFile.write(it->c_str(), lengthOfRawString);
        }

        nameOutFile.close();
        delete nameIndex;
        std::cout << "ok, after " << get_timestamp() - time << "s" << std::endl;

        //        time = get_timestamp();
        //        std::cout << "[extractor] writing address list      ... " << std::flush;
        //
        //        adressFileName.append(".address");
        //        std::ofstream addressOutFile(adressFileName.c_str());
        //        for(STXXLAddressVector::iterator it = adressVector.begin(); it != adressVector.end(); it++) {
        //            addressOutFile << it->node.id << "|" << it->node.lat << "|" << it->node.lon << "|" << it->city << "|" << it->street << "|" << it->housenumber << "|" << it->state << "|" << it->country << "\n";
        //        }
        //        addressOutFile.close();
        //        std::cout << "ok, after " << get_timestamp() - time << "s" << std::endl;

    } catch ( const std::exception& e ) {
        std::cerr <<  "Caught Execption:" << e.what() << std::endl;
        return false;
    }

    delete extractCallBacks;
    std::cout << "[extractor] finished." << std::endl;
    return 0;
}

bool nodeFunction(_Node n) {
    extractCallBacks->nodeFunction(n);
    return true;
}

bool adressFunction(_Node n, HashTable<std::string, std::string> keyVals){
    extractCallBacks->adressFunction(n, keyVals);
    return true;
}

bool relationFunction(_Relation r) {
    globalRelationCounter++;
    return true;
}
bool wayFunction(_Way w) {
    extractCallBacks->wayFunction(w);
    return true;
}

<commit_msg>fixing a silly endless loop that occurred when an edge had a starting node that was not present in node data (Thanks Frederik)<commit_after>/*
    open source routing machine
    Copyright (C) Dennis Luxen, others 2010

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
or see http://www.gnu.org/licenses/agpl.txt.
 */
#ifdef STXXL_VERBOSE_LEVEL
#undef STXXL_VERBOSE_LEVEL
#endif
#define STXXL_VERBOSE_LEVEL -1000

#include <algorithm>
#include <cassert>
#include <climits>
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>

#include <libxml/xmlreader.h>
#include <google/sparse_hash_map>
#include <unistd.h>
#include <stxxl.h>

#include "typedefs.h"
#include "DataStructures/InputReaderFactory.h"
#include "DataStructures/ExtractorCallBacks.h"
#include "DataStructures/ExtractorStructs.h"
#include "DataStructures/PBFParser.h"
#include "DataStructures/XMLParser.h"
#include "Util/BaseConfiguration.h"
#include "Util/InputFileUtil.h"

typedef BaseConfiguration ExtractorConfiguration;

unsigned globalRelationCounter = 0;
ExtractorCallbacks * extractCallBacks;

bool nodeFunction(_Node n);
bool adressFunction(_Node n, HashTable<std::string, std::string> keyVals);
bool relationFunction(_Relation r);
bool wayFunction(_Way w);

template<class ClassT>
bool removeIfUnused(ClassT n) { return (false == n.used); }

int main (int argc, char *argv[]) {
    if(argc <= 1) {
        std::cerr << "usage: " << endl << argv[0] << " <file.osm>" << std::endl;
        exit(-1);
    }

    std::cout << "[extractor] extracting data from input file " << argv[1] << std::endl;
    bool isPBF = false;
    std::string outputFileName(argv[1]);
    std::string::size_type pos = outputFileName.find(".osm.bz2");
    if(pos==string::npos) {
        pos = outputFileName.find(".osm.pbf");
        if(pos!=string::npos) {
            isPBF = true;
        }
    }
    if(pos!=string::npos) {
        outputFileName.replace(pos, 8, ".osrm");
    } else {
        pos=outputFileName.find(".osm");
        if(pos!=string::npos) {
            outputFileName.replace(pos, 5, ".osrm");
        } else {
            outputFileName.append(".osrm");
        }
    }
    std::string adressFileName(outputFileName);

    unsigned amountOfRAM = 1;
    unsigned installedRAM = (sysconf(_SC_PHYS_PAGES) * sysconf(_SC_PAGESIZE));
    if(installedRAM < 2097422336) {
        std::cout << "[Warning] Machine has less than 2GB RAM." << std::endl;
    }
    if(testDataFile("extractor.ini")) {
        ExtractorConfiguration extractorConfig("extractor.ini");
        unsigned memoryAmountFromFile = atoi(extractorConfig.GetParameter("Memory").c_str());
        if( memoryAmountFromFile != 0 && memoryAmountFromFile <= installedRAM/(1024*1024*1024))
            amountOfRAM = memoryAmountFromFile;
        std::cout << "[extractor] using " << amountOfRAM << " GB of RAM for buffers" << std::endl;
    }

    STXXLNodeIDVector usedNodeIDs;
    STXXLNodeVector   allNodes;
    STXXLEdgeVector   allEdges;
    STXXLAddressVector adressVector;
    STXXLStringVector  nameVector;
    unsigned usedNodeCounter = 0;
    unsigned usedEdgeCounter = 0;

    StringMap * stringMap = new StringMap();
    Settings settings;
    settings.speedProfile.names.insert(settings.speedProfile.names.begin(), names, names+14);
    settings.speedProfile.speed.insert(settings.speedProfile.speed.begin(), speeds, speeds+14);

    double time = get_timestamp();

    stringMap->set_empty_key(GetRandomString());
    stringMap->insert(std::make_pair("", 0));
    extractCallBacks = new ExtractorCallbacks(&allNodes, &usedNodeIDs, &allEdges,  &nameVector, &adressVector, settings, stringMap);

    BaseParser<_Node, _Relation, _Way> * parser;
    if(isPBF) {
        parser = new PBFParser(argv[1]);
    } else {
        parser = new XMLParser(argv[1]);
    }
    parser->RegisterCallbacks(&nodeFunction, &relationFunction, &wayFunction, &adressFunction);
    if(parser->Init()) {
        parser->Parse();
    } else {
        std::cerr << "[error] parser not initialized!" << std::endl;
        exit(-1);
    }
    delete parser;

    try {
        //        std::cout << "[info] raw no. of names:     " << nameVector.size()    << std::endl;
        //        std::cout << "[info] raw no. of nodes:     " << allNodes.size()      << std::endl;
        //        std::cout << "[info] no. of used nodes:    " << usedNodeIDs.size()     << std::endl;
        //        std::cout << "[info] raw no. of edges:     " << allEdges.size()      << std::endl;
        //        std::cout << "[info] raw no. of relations: " << globalRelationCounter << std::endl;
        //        std::cout << "[info] raw no. of addresses: " << adressVector.size()  << std::endl;

        std::cout << "[extractor] parsing finished after " << get_timestamp() - time << "seconds" << std::endl;
        time = get_timestamp();
        unsigned memory_to_use = amountOfRAM * 1024 * 1024 * 1024;

        std::cout << "[extractor] Sorting used nodes        ... " << std::flush;
        stxxl::sort(usedNodeIDs.begin(), usedNodeIDs.end(), Cmp(), memory_to_use);
        std::cout << "ok, after " << get_timestamp() - time << "s" << std::endl;

        time = get_timestamp();
        std::cout << "[extractor] Erasing duplicate nodes   ... " << std::flush;
        stxxl::vector<NodeID>::iterator NewEnd = unique ( usedNodeIDs.begin(),usedNodeIDs.end() ) ;
        usedNodeIDs.resize ( NewEnd - usedNodeIDs.begin() );
        cout << "ok, after " << get_timestamp() - time << "s" << endl;
        time = get_timestamp();

        std::cout << "[extractor] Sorting all nodes         ... " << std::flush;
        stxxl::sort(allNodes.begin(), allNodes.end(), CmpNodeByID(), memory_to_use);
        std::cout << "ok, after " << get_timestamp() - time << "s" << std::endl;
        time = get_timestamp();

        std::ofstream fout;
        fout.open(outputFileName.c_str(), std::ios::binary);
        fout.write((char*)&usedNodeCounter, sizeof(unsigned));

        std::cout << "[extractor] Confirming used nodes     ... " << std::flush;
        STXXLNodeVector::iterator nodesIT = allNodes.begin();
        STXXLNodeIDVector::iterator usedNodeIDsIT = usedNodeIDs.begin();
        while(usedNodeIDsIT != usedNodeIDs.end() && nodesIT != allNodes.end()) {
            if(*usedNodeIDsIT < nodesIT->id){
                usedNodeIDsIT++;
                continue;
            }
            if(*usedNodeIDsIT > nodesIT->id) {
                nodesIT++;
                continue;
            }
            if(*usedNodeIDsIT == nodesIT->id) {
                fout.write((char*)&(nodesIT->id), sizeof(unsigned));
                fout.write((char*)&(nodesIT->lon), sizeof(int));
                fout.write((char*)&(nodesIT->lat), sizeof(int));
                usedNodeCounter++;
                usedNodeIDsIT++;
                nodesIT++;
            }
        }
        std::cout << "ok, after " << get_timestamp() - time << "s" << std::endl;
        time = get_timestamp();

        std::cout << "[extractor] setting number of nodes   ... " << std::flush;
        std::ios::pos_type positionInFile = fout.tellp();
        fout.seekp(std::ios::beg);
        fout.write((char*)&usedNodeCounter, sizeof(unsigned));
        fout.seekp(positionInFile);

        std::cout << "ok" << std::endl;
        time = get_timestamp();

        // Sort edges by start.
        std::cout << "[extractor] Sorting edges by start    ... " << std::flush;
        stxxl::sort(allEdges.begin(), allEdges.end(), CmpEdgeByStartID(), memory_to_use);
        std::cout << "ok, after " << get_timestamp() - time << "s" << std::endl;
        time = get_timestamp();

        std::cout << "[extractor] Setting start coords      ... " << std::flush;
        fout.write((char*)&usedEdgeCounter, sizeof(unsigned));
        // Traverse list of edges and nodes in parallel and set start coord
        nodesIT = allNodes.begin();
        STXXLEdgeVector::iterator edgeIT = allEdges.begin();
        while(edgeIT != allEdges.end() && nodesIT != allNodes.end()) {
            if(edgeIT->start < nodesIT->id){
                edgeIT++;
                continue;
            }
            if(edgeIT->start > nodesIT->id) {
                nodesIT++;
                continue;
            }
            if(edgeIT->start == nodesIT->id) {
                edgeIT->startCoord.lat = nodesIT->lat;
                edgeIT->startCoord.lon = nodesIT->lon;
                edgeIT++;
            }
        }
        std::cout << "ok, after " << get_timestamp() - time << "s" << std::endl;
        time = get_timestamp();

        // Sort Edges by target
        std::cout << "[extractor] Sorting edges by target   ... " << std::flush;
        stxxl::sort(allEdges.begin(), allEdges.end(), CmpEdgeByTargetID(), memory_to_use);
        std::cout << "ok, after " << get_timestamp() - time << "s" << std::endl;
        time = get_timestamp();

        std::cout << "[extractor] Setting target coords     ... " << std::flush;
        // Traverse list of edges and nodes in parallel and set target coord
        nodesIT = allNodes.begin();
        edgeIT = allEdges.begin();
        while(edgeIT != allEdges.end() && nodesIT != allNodes.end()) {
            if(edgeIT->target < nodesIT->id){
                edgeIT++;
                continue;
            }
            if(edgeIT->target > nodesIT->id) {
                nodesIT++;
                continue;
            }
            if(edgeIT->target == nodesIT->id) {
                if(edgeIT->startCoord.lat != INT_MIN) {
                    edgeIT->targetCoord.lat = nodesIT->lat;
                    edgeIT->targetCoord.lon = nodesIT->lon;

                    double distance = ApproximateDistance(edgeIT->startCoord.lat, edgeIT->startCoord.lon, nodesIT->lat, nodesIT->lon);
                    if(edgeIT->speed == -1)
                        edgeIT->speed = settings.speedProfile.speed[edgeIT->type];
                    double weight = ( distance * 10. ) / (edgeIT->speed / 3.6);
                    int intWeight = max(1, (int) weight);
                    int intDist = max(1, (int)distance);
                    int ferryIndex = settings.indexInAccessListOf("ferry");
                    assert(ferryIndex != -1);
                    short zero = 0;
                    short one = 1;

                    fout.write((char*)&edgeIT->start, sizeof(unsigned));
                    fout.write((char*)&edgeIT->target, sizeof(unsigned));
                    fout.write((char*)&intDist, sizeof(int));
                    switch(edgeIT->direction) {
                    case _Way::notSure:
                        fout.write((char*)&zero, sizeof(short));
                        break;
                    case _Way::oneway:
                        fout.write((char*)&one, sizeof(short));
                        break;
                    case _Way::bidirectional:
                        fout.write((char*)&zero, sizeof(short));

                        break;
                    case _Way::opposite:
                        fout.write((char*)&one, sizeof(short));
                        break;
                    default:
                        std::cerr << "[error] edge with no direction: " << edgeIT->direction << std::endl;
                        assert(false);
                        break;
                    }
                    fout.write((char*)&intWeight, sizeof(int));
                    short edgeType = edgeIT->type;
                    fout.write((char*)&edgeType, sizeof(short));
                    fout.write((char*)&edgeIT->nameID, sizeof(unsigned));
                }
                usedEdgeCounter++;
                edgeIT++;
            }
        }
        std::cout << "ok, after " << get_timestamp() - time << "s" << std::endl;
        time = get_timestamp();

        std::cout << "[extractor] setting number of edges   ... " << std::flush;
        fout.seekp(positionInFile);
        fout.write((char*)&usedEdgeCounter, sizeof(unsigned));
        fout.close();
        std::cout << "ok" << std::endl;
        time = get_timestamp();

        std::cout << "[extractor] writing street name index ... " << std::flush;
        std::vector<unsigned> * nameIndex = new std::vector<unsigned>(nameVector.size()+1, 0);
        outputFileName.append(".names");
        std::ofstream nameOutFile(outputFileName.c_str(), std::ios::binary);
        unsigned sizeOfNameIndex = nameIndex->size();
        nameOutFile.write((char *)&(sizeOfNameIndex), sizeof(unsigned));

        for(STXXLStringVector::iterator it = nameVector.begin(); it != nameVector.end(); it++) {
            unsigned lengthOfRawString = strlen(it->c_str());
            nameOutFile.write((char *)&(lengthOfRawString), sizeof(unsigned));
            nameOutFile.write(it->c_str(), lengthOfRawString);
        }

        nameOutFile.close();
        delete nameIndex;
        std::cout << "ok, after " << get_timestamp() - time << "s" << std::endl;

        //        time = get_timestamp();
        //        std::cout << "[extractor] writing address list      ... " << std::flush;
        //
        //        adressFileName.append(".address");
        //        std::ofstream addressOutFile(adressFileName.c_str());
        //        for(STXXLAddressVector::iterator it = adressVector.begin(); it != adressVector.end(); it++) {
        //            addressOutFile << it->node.id << "|" << it->node.lat << "|" << it->node.lon << "|" << it->city << "|" << it->street << "|" << it->housenumber << "|" << it->state << "|" << it->country << "\n";
        //        }
        //        addressOutFile.close();
        //        std::cout << "ok, after " << get_timestamp() - time << "s" << std::endl;

    } catch ( const std::exception& e ) {
        std::cerr <<  "Caught Execption:" << e.what() << std::endl;
        return false;
    }

    delete extractCallBacks;
    std::cout << "[extractor] finished." << std::endl;
    return 0;
}

bool nodeFunction(_Node n) {
    extractCallBacks->nodeFunction(n);
    return true;
}

bool adressFunction(_Node n, HashTable<std::string, std::string> keyVals){
    extractCallBacks->adressFunction(n, keyVals);
    return true;
}

bool relationFunction(_Relation r) {
    globalRelationCounter++;
    return true;
}
bool wayFunction(_Way w) {
    extractCallBacks->wayFunction(w);
    return true;
}

<|endoftext|>


<commit_before>/*
 * ply2json
 *
 * The program is a ply file format to json file format converter for use
 * with three.js. The program uses the C++ libraries from the VTK toolkit
 * in order to read in a ply file and convert it into the json file format
 * which can be recongnized by three.js for rendering in the browsing.
 *
 * @Author Migara Liyanamage
 * @Date 19 June 2014
 * @Version 1.0
 *
 */

// Import for VTK Libraries
#include <vtkPLYReader.h>
#include <vtkSmartPointer.h>
#include <vtkCellArray.h>
#include <vtkDecimatePro.h>

// Import for standard C++ libraries
#include <iostream>
#include <fstream>

// Import for program header
#include "ply2json.h"

using namespace std;

// stores the filename of the input file
static string inputFilename;

// store the filename of the output file
static string outputFilename;

// set amount to decimate by, if set to 1 no decimation occurs
static double decAmount;

/*
 * Main Method
 *
 * This method reads in the file which is to be converted from the command line
 * and calls the appropriate methods to begin the conversion.
 *
 */
int main( int argc, char ** argv )
{
    if (argc  < 3)
    {
        // Print Usage Message
        cout << "Usage: " << argv[0] << " filename.ply outputName [decimate amount 0.0 .. 1.0]" << endl;
        return EXIT_FAILURE;
    }

    if (argc == 4)
    {
        decAmount = atof(argv[3]);
    }
    else
    {
        decAmount = 1.0;
    }

    // Assign appropriate file names for the program
    inputFilename = argv[1];
    outputFilename = argv[2];

    // begin generation
    generateJSON();

    return EXIT_SUCCESS;
}

/*
 * Generate JSON Method
 *
 * This method calls the appropriate methods in the vtk toolkit and outputs the
 * JSON file to the output file name specified
 *
 */
void generateJSON()
{
    // File stream for output file
    std::ofstream outputFile;
    outputFile.open(outputFilename.c_str());

    // begin the json file
    outputFile << "{\n";

    // Reader to read in PLY File
    vtkSmartPointer<vtkPLYReader> reader =
        vtkSmartPointer<vtkPLYReader>::New();

    // Specify filename
    reader->SetFileName ( inputFilename.c_str() );

    // Call vtk pipeline to read in the file
    reader->Update();

    vtkDataSet * data;
    vtkIdType vert;
    vtkPolyData * pdata;
    vtkCellArray * faces;

    if (decAmount >= 1.0)
    {
         // Get the outpuyt for vertices
        data = reader->GetOutput();
        vert = data->GetNumberOfPoints();

        // Get the output for polygons
        pdata = reader->GetOutput();
        faces = pdata->GetPolys();

    }
    else if (decAmount < 0.0)
    {
        cout << "Invalid Decimate Amount, Program will now exit" << endl;
        exit(EXIT_FAILURE);
    } else
    {
        // create decimator
        vtkSmartPointer<vtkDecimatePro> decimate = vtkSmartPointer<vtkDecimatePro>::New();

        // set decimator to the selected file
        decimate->SetInputData(reader->GetOutput());

        // set target to reduce to, and set topology to be preserved
        decimate->PreserveTopologyOn();
        decimate->SetTargetReduction(decAmount);i

        // start decimation
        decimate->Update();

    }

    vtkIdType numCells = faces->GetNumberOfCells();
    vtkIdType cellLocation = 0;

    // Write the standard format header for the json file
    outputFile << "\"metadata\":{\"formatVersion\":3,\"vertices\":" << vert << ",\"faces\":" << numCells << ",\"materials\":1},\n";
    outputFile << "\"scale\":1.0,\n\"materials\":[{\"DbgColor\":15658734,\"DbgIndex\":0,\"DbgName\":\"default\",\"vertexColors\": false}],\n";

    // Begin writing vertices
    outputFile << "\"vertices\":[";

    // Iterate over all the points and print them to the file
    for(vtkIdType i = 0; i < vert; i++)
    {
        double p[3];
        data->GetPoint(i, p);
        outputFile << p[0] << "," << p[1] << "," << p[2];
        if (i != vert - 1) outputFile << ","; // Avoid putting comma before end bracket
    }

    // End the vertices section
    outputFile << "],\n";

    // Begin writing faces
    outputFile << "\"faces\":[";

    // Iterate over the faces and print them to file
    for (vtkIdType i = 0; i < numCells; i++)
    {
        vtkIdType numIDs;
        vtkIdType * pointIds;

        faces->GetCell(cellLocation, numIDs, pointIds);
        cellLocation += 1 + numIDs; // increment to include already printed faces

        for (vtkIdType j = 0; j < numIDs; j++)
        {
            // print to the file
            // printing the zero is for the bit mask signifying face type
            if (j == 0) outputFile << 0 << ",";
            outputFile << pointIds[j];
            if (i != numCells - 1)
            {
                outputFile << ",";
            }
            else
            {
                if(j != numIDs - 1) outputFile << ","; // avoid additional comma at end
            }
        }
    }

    // end faces section
    outputFile << "]\n";

    // end the json file
    outputFile << "}\n";

    // close file stream
    outputFile.close();
}
<commit_msg>finished decimate pro, now can decimate to output file<commit_after>/*
 * ply2json
 *
 * The program is a ply file format to json file format converter for use
 * with three.js. The program uses the C++ libraries from the VTK toolkit
 * in order to read in a ply file and convert it into the json file format
 * which can be recongnized by three.js for rendering in the browsing.
 *
 * @Author Migara Liyanamage
 * @Date 19 June 2014
 * @Version 1.0
 *
 */

// Import for VTK Libraries
#include <vtkPLYReader.h>
#include <vtkSmartPointer.h>
#include <vtkCellArray.h>
#include <vtkDecimatePro.h>

// Import for standard C++ libraries
#include <iostream>
#include <fstream>

// Import for program header
#include "ply2json.h"

using namespace std;

// stores the filename of the input file
static string inputFilename;

// store the filename of the output file
static string outputFilename;

// set amount to decimate by, if set to 1 no decimation occurs
static double decAmount;

/*
 * Main Method
 *
 * This method reads in the file which is to be converted from the command line
 * and calls the appropriate methods to begin the conversion.
 *
 */
int main( int argc, char ** argv )
{
    if (argc  < 3)
    {
        // Print Usage Message
        cout << "Usage: " << argv[0] << " filename.ply outputName [decimate amount 0.0 .. 1.0]" << endl;
        return EXIT_FAILURE;
    }

    if (argc == 4)
    {
        decAmount = atof(argv[3]);
    }
    else
    {
        decAmount = 1.0;
    }

    // Assign appropriate file names for the program
    inputFilename = argv[1];
    outputFilename = argv[2];

    // begin generation
    generateJSON();

    return EXIT_SUCCESS;
}

/*
 * Generate JSON Method
 *
 * This method calls the appropriate methods in the vtk toolkit and outputs the
 * JSON file to the output file name specified
 *
 */
void generateJSON()
{
    // File stream for output file
    std::ofstream outputFile;
    outputFile.open(outputFilename.c_str());

    // begin the json file
    outputFile << "{\n";

    // Reader to read in PLY File
    vtkSmartPointer<vtkPLYReader> reader =
        vtkSmartPointer<vtkPLYReader>::New();

    // Specify filename
    reader->SetFileName ( inputFilename.c_str() );

    // Call vtk pipeline to read in the file
    reader->Update();

    vtkDataSet * data;
    vtkIdType vert;
    vtkPolyData * pdata;
    vtkCellArray * faces;

    if (decAmount >= 1.0)
    {
         // Get the outpuyt for vertices
        data = reader->GetOutput();
        vert = data->GetNumberOfPoints();

        // Get the output for polygons
        pdata = reader->GetOutput();
        faces = pdata->GetPolys();

    }
    else if (decAmount < 0.0)
    {
        cout << "Invalid Decimate Amount, Program will now exit" << endl;
        exit(EXIT_FAILURE);
    } else
    {
        // create decimator
        vtkSmartPointer<vtkDecimatePro> decimate = vtkSmartPointer<vtkDecimatePro>::New();

        // set decimator to the selected file
        decimate->SetInputData(reader->GetOutput());

        // set target to reduce to, and set topology to be preserved
        decimate->PreserveTopologyOn();
        decimate->SetTargetReduction(decAmount);

        // start decimation
        decimate->Update();

        // Get the outpuyt for vertices
        data = decimate->GetOutput();
        vert = data->GetNumberOfPoints();

        // Get the output for polygons
        pdata = decimate->GetOutput();
        faces = pdata->GetPolys();
    }

    vtkIdType numCells = faces->GetNumberOfCells();
    vtkIdType cellLocation = 0;

    // Write the standard format header for the json file
    outputFile << "\"metadata\":{\"formatVersion\":3,\"vertices\":" << vert << ",\"faces\":" << numCells << ",\"materials\":1},\n";
    outputFile << "\"scale\":1.0,\n\"materials\":[{\"DbgColor\":15658734,\"DbgIndex\":0,\"DbgName\":\"default\",\"vertexColors\": false}],\n";

    // Begin writing vertices
    outputFile << "\"vertices\":[";

    // Iterate over all the points and print them to the file
    for(vtkIdType i = 0; i < vert; i++)
    {
        double p[3];
        data->GetPoint(i, p);
        outputFile << p[0] << "," << p[1] << "," << p[2];
        if (i != vert - 1) outputFile << ","; // Avoid putting comma before end bracket
    }

    // End the vertices section
    outputFile << "],\n";

    // Begin writing faces
    outputFile << "\"faces\":[";

    // Iterate over the faces and print them to file
    for (vtkIdType i = 0; i < numCells; i++)
    {
        vtkIdType numIDs;
        vtkIdType * pointIds;

        faces->GetCell(cellLocation, numIDs, pointIds);
        cellLocation += 1 + numIDs; // increment to include already printed faces

        for (vtkIdType j = 0; j < numIDs; j++)
        {
            // print to the file
            // printing the zero is for the bit mask signifying face type
            if (j == 0) outputFile << 0 << ",";
            outputFile << pointIds[j];
            if (i != numCells - 1)
            {
                outputFile << ",";
            }
            else
            {
                if(j != numIDs - 1) outputFile << ","; // avoid additional comma at end
            }
        }
    }

    // end faces section
    outputFile << "]\n";

    // end the json file
    outputFile << "}\n";

    // close file stream
    outputFile.close();
}
<|endoftext|>