<commit_before>/*
 * Android File Transfer for Linux: MTP client for android devices
 * Copyright (C) 2015  Vladimir Menshakov

 * 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.

 * 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 General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */
#include "fileuploader.h"
#include "commandqueue.h"
#include "mtpobjectsmodel.h"
#include <QStringList>
#include <QFileInfo>
#include <QDir>
#include <QDirIterator>
#include <QDebug>

FileUploader::FileUploader(MtpObjectsModel * model, QObject *parent) :
	QObject(parent),
	_model(model)
{
	CommandQueue * worker = new CommandQueue(_model);
	worker->moveToThread(&_workerThread);

	connect(&_workerThread, SIGNAL(finished()), SLOT(deleteLater()));
	connect(this, SIGNAL(executeCommand(Command*)), worker, SLOT(execute(Command*)));
	connect(worker, SIGNAL(progress(qint64)), SLOT(onProgress(qint64)));
	connect(worker, SIGNAL(started(QString)), SLOT(onStarted(QString)));
	connect(worker, SIGNAL(finished()), SLOT(onFinished()));
	_workerThread.start();
}

FileUploader::~FileUploader()
{
	_workerThread.quit();
	_workerThread.wait();
}

void FileUploader::onProgress(qint64 current)
{
	//qDebug() << "progress " << current << " of " << _total;
	qint64 secs = _startedAt.secsTo(QDateTime::currentDateTime());
	if (secs)
		emit uploadSpeed(current / secs);
	emit uploadProgress(1.0 * current / _total);
}

void FileUploader::onStarted(const QString &file)
{
	emit uploadStarted(file);
}

void FileUploader::onFinished()
{
	qDebug() << "finished";
	emit finished();
}

void FileUploader::upload(QStringList files)
{
	_model->moveToThread(&_workerThread);
	_total = 0;
	QList<Command *> commands;
	while(!files.empty())
	{
		QString currentFile = files.front();
		files.pop_front();
		QFileInfo currentFileInfo(currentFile);
		if (currentFileInfo.isDir())
		{
			qDebug() << "adding subdirectory" << currentFile;
			commands.push_back(new MakeDirectory(currentFile, true));
			QDirIterator it(currentFile, QDirIterator::Subdirectories);
			while(it.hasNext())
			{
				QString next = it.next();
				QFileInfo fi(next);
				QString filename = fi.fileName();
				if (filename == "." || filename == "..")
					continue;

				if (fi.isFile())
				{
					commands.push_back(new UploadFile(next));
					_total += fi.size();
				}
				else if (fi.isDir())
				{
					commands.push_back(new MakeDirectory(next));
				}
			}
		}
		else if (currentFileInfo.isFile())
		{
			commands.push_back(new UploadFile(currentFile));
			_total += currentFileInfo.size();
		}
	}
	qDebug() << "uploading" << _total << "bytes";
	if (_total < 1)
		_total = 1;

	_startedAt = QDateTime::currentDateTime();

	for(auto command: commands)
	{
		emit executeCommand(command);
	}
	emit executeCommand(new FinishQueue());
}

void FileUploader::download(const QString &path, const QList<quint32> &objectIds)
{
	_model->moveToThread(&_workerThread);

	_total = 1;
	QVector<QPair<QString, mtp::u32> > files;
	for(quint32 id : objectIds)
	{
		MtpObjectsModel::ObjectInfo oi = _model->getInfo(id);
		_total += oi.Size;
		files.push_back(QPair<QString, mtp::u32>(oi.Filename, id));
	}
	qDebug() << "downloading " << files.size() << " file(s), " << _total << " bytes";
	_startedAt = QDateTime::currentDateTime();

	for(const auto & file : files)
	{
		emit executeCommand(new DownloadFile(path + "/" + file.first, file.second));
	}
	emit executeCommand(new FinishQueue());
}
<commit_msg>check object format, skip associations for now<commit_after>/*
 * Android File Transfer for Linux: MTP client for android devices
 * Copyright (C) 2015  Vladimir Menshakov

 * 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.

 * 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 General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */
#include "fileuploader.h"
#include "commandqueue.h"
#include "mtpobjectsmodel.h"
#include <QStringList>
#include <QFileInfo>
#include <QDir>
#include <QDirIterator>
#include <QDebug>

FileUploader::FileUploader(MtpObjectsModel * model, QObject *parent) :
	QObject(parent),
	_model(model)
{
	CommandQueue * worker = new CommandQueue(_model);
	worker->moveToThread(&_workerThread);

	connect(&_workerThread, SIGNAL(finished()), SLOT(deleteLater()));
	connect(this, SIGNAL(executeCommand(Command*)), worker, SLOT(execute(Command*)));
	connect(worker, SIGNAL(progress(qint64)), SLOT(onProgress(qint64)));
	connect(worker, SIGNAL(started(QString)), SLOT(onStarted(QString)));
	connect(worker, SIGNAL(finished()), SLOT(onFinished()));
	_workerThread.start();
}

FileUploader::~FileUploader()
{
	_workerThread.quit();
	_workerThread.wait();
}

void FileUploader::onProgress(qint64 current)
{
	//qDebug() << "progress " << current << " of " << _total;
	qint64 secs = _startedAt.secsTo(QDateTime::currentDateTime());
	if (secs)
		emit uploadSpeed(current / secs);
	emit uploadProgress(1.0 * current / _total);
}

void FileUploader::onStarted(const QString &file)
{
	emit uploadStarted(file);
}

void FileUploader::onFinished()
{
	qDebug() << "finished";
	emit finished();
}

void FileUploader::upload(QStringList files)
{
	_model->moveToThread(&_workerThread);
	_total = 0;
	QList<Command *> commands;
	while(!files.empty())
	{
		QString currentFile = files.front();
		files.pop_front();
		QFileInfo currentFileInfo(currentFile);
		if (currentFileInfo.isDir())
		{
			qDebug() << "adding subdirectory" << currentFile;
			commands.push_back(new MakeDirectory(currentFile, true));
			QDirIterator it(currentFile, QDirIterator::Subdirectories);
			while(it.hasNext())
			{
				QString next = it.next();
				QFileInfo fi(next);
				QString filename = fi.fileName();
				if (filename == "." || filename == "..")
					continue;

				if (fi.isFile())
				{
					commands.push_back(new UploadFile(next));
					_total += fi.size();
				}
				else if (fi.isDir())
				{
					commands.push_back(new MakeDirectory(next));
				}
			}
		}
		else if (currentFileInfo.isFile())
		{
			commands.push_back(new UploadFile(currentFile));
			_total += currentFileInfo.size();
		}
	}
	qDebug() << "uploading" << _total << "bytes";
	if (_total < 1)
		_total = 1;

	_startedAt = QDateTime::currentDateTime();

	for(auto command: commands)
	{
		emit executeCommand(command);
	}
	emit executeCommand(new FinishQueue());
}

void FileUploader::download(const QString &path, const QList<quint32> &objectIds)
{
	_model->moveToThread(&_workerThread);

	_total = 1;
	QVector<QPair<QString, mtp::u32> > files;
	for(quint32 id : objectIds)
	{
		MtpObjectsModel::ObjectInfo oi = _model->getInfo(id);
		if (oi.Format == mtp::ObjectFormat::Association)
		{
			//enumerate here
			qWarning() << "skipping directory " << oi.Filename;
		}
		else
		{
			_total += oi.Size;
			files.push_back(QPair<QString, mtp::u32>(oi.Filename, id));
		}
	}
	qDebug() << "downloading " << files.size() << " file(s), " << _total << " bytes";
	_startedAt = QDateTime::currentDateTime();

	for(const auto & file : files)
	{
		emit executeCommand(new DownloadFile(path + "/" + file.first, file.second));
	}
	emit executeCommand(new FinishQueue());
}
<|endoftext|>


<commit_before>
#include <sarah/cat_problem.h>

namespace sarah
{

  /**
   * Class constructor.
   */
  template <int dim>
  CatProblem<dim>::CatProblem (const std::string &prm)
    :
    mpi_communicator (MPI_COMM_WORLD),
    triangulation (mpi_communicator,
                   typename dealii::Triangulation<dim>::MeshSmoothing
                   (dealii::Triangulation<dim>::smoothing_on_refinement |
                    dealii::Triangulation<dim>::smoothing_on_coarsening)),
    dof_handler (triangulation),
    fe (dealii::FE_Q<dim> (1), 1),
    n_pairs (1),
    // ---
    pcout (std::cout, (dealii::Utilities::MPI::this_mpi_process (mpi_communicator) == 0)),
    timer (mpi_communicator, pcout,
	   dealii::TimerOutput::summary,
	   dealii::TimerOutput::wall_times)
  {
    parameters.declare_entry ("Global mesh refinement steps", "5",
                              dealii::Patterns::Integer (0, 20),
                              "The number of times the 1-cell coarse mesh should "
                              "be refined globally for our computations.");

    parameters.declare_entry ("Potential", "0",
                              dealii::Patterns::Anything (),
                              "A functional description of the potential.");

    parameters.declare_entry ("Number of eigenpairs", "5",
                              dealii::Patterns::Integer (0, 100),
                              "The number of eigenpairs to be computed.");

    parameters.declare_entry ("Number of eigenfunctions", "5",
                              dealii::Patterns::Integer (0, 100),
                              "The number of eigenfunctions "
                              "to be used for error indicators.");

    parameters.parse_input (prm);
  }

  /**
   * Class destructor.
   */
  template <int dim>
  CatProblem<dim>::~CatProblem ()
  {
    // Wipe DoF handlers.
    dof_handler.clear ();
  }

  /**
   * Make initial coarse grid.
   */
  template <int dim>
  void
  CatProblem<dim>::make_coarse_grid ()
  {
    dealii::TimerOutput::Scope time (timer, "make coarse grid");

    // Create a coarse grid according to the parameters given in the
    // input file.
    dealii::GridGenerator::hyper_cube (triangulation, -5, 5);

    triangulation.refine_global (parameters.get_integer ("Global mesh refinement steps"));
  }

  /**
   * Setup system matrices and vectors.
   */
  template <int dim>
  void CatProblem<dim>::setup_system ()
  {
    dealii::TimerOutput::Scope time (timer, "setup system");

    // Determine locally relevant DoFs.
    dof_handler.distribute_dofs (fe);
    locally_owned_dofs = dof_handler.locally_owned_dofs ();
    dealii::DoFTools::extract_locally_relevant_dofs (dof_handler, locally_relevant_dofs);

    // Initialise values.
    solution_value.resize (n_pairs, 0.);

    // Initialise distributed vectors.
    locally_relevant_solution.resize (n_pairs);
    for (unsigned int i=0; i<n_pairs; ++i)
      locally_relevant_solution[i].reinit (locally_owned_dofs, locally_relevant_dofs,
					   mpi_communicator);

    // Setup hanging node constraints.
    constraints.clear ();
    constraints.reinit (locally_relevant_dofs);
    dealii::DoFTools::make_hanging_node_constraints (dof_handler, constraints);
    dealii::DoFTools::make_zero_boundary_constraints (dof_handler, constraints);
    constraints.close ();

    // Finally, create a distributed sparsity pattern and initialise
    // the system- and mass-matrix from that.
    dealii::DynamicSparsityPattern dsp (locally_relevant_dofs);
    dealii::DoFTools::make_sparsity_pattern (dof_handler, dsp, constraints, false);
    dealii::SparsityTools::distribute_sparsity_pattern (dsp,
							dof_handler.n_locally_owned_dofs_per_processor (),
							mpi_communicator,
							locally_relevant_dofs);

    system_matrix.reinit (locally_owned_dofs, locally_owned_dofs, dsp,
			  mpi_communicator);

    mass_matrix.reinit (locally_owned_dofs, locally_owned_dofs,	dsp,
			mpi_communicator);
  }

  /**
   * Assemble system matrices and vectors.
   *
   * TODO Ideally, we would use a function like this:
   *
   * dealii::MatrixCreator::create_mass_matrix (dof_handler, quadrature_rule, system_matrix, 1, constraints);
   *
   * however no such thing currently exists in the deal.II library for
   * parallel matrices and vectors. Instead, the mass matrix and right
   * hand side vector are assembled by hand in functions defined in
   * the namepsaces, sarah::MatrixCreator and sarah::VectorCreator,
   * respectively.
   */
  template <int dim>
  void
  CatProblem<dim>::assemble_system ()
  {
    dealii::TimerOutput::Scope time (timer, "assemble system");

    // Define quadrature rule to be used.
    const dealii::QGauss<dim> quadrature_formula (3);

    sarah::MatrixCreator::create_mass_matrix<dim> (fe, dof_handler, quadrature_formula,
						   mass_matrix, constraints,
						   mpi_communicator);

    dealii::FEValues<dim> fe_values (fe, quadrature_formula,
				     dealii::update_values            |
				     dealii::update_gradients         |
				     dealii::update_quadrature_points |
				     dealii::update_JxW_values);

    const unsigned int dofs_per_cell = fe.dofs_per_cell;
    const unsigned int n_q_points    = quadrature_formula.size();

    dealii::FullMatrix<double> cell_system_matrix (dofs_per_cell, dofs_per_cell);

    std::vector<dealii::types::global_dof_index> local_dof_indices (dofs_per_cell);

    dealii::FunctionParser<dim> potential;
    potential.initialize (dealii::FunctionParser<dim>::default_variable_names (),
                          parameters.get ("Potential"),
                          typename dealii::FunctionParser<dim>::ConstMap ());

    std::vector<double> potential_values (n_q_points);

    typename dealii::DoFHandler<dim>::active_cell_iterator
      cell = dof_handler.begin_active (),
      endc = dof_handler.end ();

    for (; cell!=endc; ++cell)
      {
        fe_values.reinit (cell);
        cell_system_matrix = 0;

        potential.value_list (fe_values.get_quadrature_points (),
                              potential_values);

        for (unsigned int q_point=0; q_point<n_q_points; ++q_point)
          for (unsigned int i=0; i<dofs_per_cell; ++i)
            for (unsigned int j=0; j<dofs_per_cell; ++j)
              {
                cell_system_matrix (i, j)
		  += (0.5                               *
		      fe_values.shape_grad (i, q_point) *
		      fe_values.shape_grad (j, q_point)
		      +
		      potential_values[q_point]          *
		      fe_values.shape_value (i, q_point) *
		      fe_values.shape_value (j, q_point)
		      )
		  * fe_values.JxW (q_point);
              }

        cell->get_dof_indices (local_dof_indices);

        constraints
	  .distribute_local_to_global (cell_system_matrix,
				       local_dof_indices,
				       system_matrix);
      }

    system_matrix.compress (dealii::VectorOperation::add);

  }

  /**
   * Solve the linear algebra system.
   */
  template <int dim>
  unsigned int
  CatProblem<dim>::solve ()
  {
    dealii::TimerOutput::Scope time (timer, "solve");

    std::vector<dealii::PETScWrappers::MPI::Vector> completely_distributed_solution;
    completely_distributed_solution.resize (n_pairs);
    for (unsigned int i=0; i<n_pairs; ++i)
      completely_distributed_solution[i].reinit (locally_owned_dofs,
						 mpi_communicator);

    // Solve using KrylovSchur
    dealii::SolverControl solver_control (dof_handler.n_dofs (), 1e-06);
    dealii::SLEPcWrappers::SolverKrylovSchur solver (solver_control, mpi_communicator);

    solver.set_which_eigenpairs (EPS_SMALLEST_REAL);
    solver.set_problem_type (EPS_GHEP);

    solver.solve (system_matrix, mass_matrix, solution_value, completely_distributed_solution,
		  completely_distributed_solution.size ());

    // Ensure that all ghost elements are also copied as necessary.
    for (unsigned int i=0; i<n_pairs; ++i)
      constraints.distribute (completely_distributed_solution[i]);

    for (unsigned int i=0; i<n_pairs; ++i)
      locally_relevant_solution[i] = completely_distributed_solution[i];

    // Return the number of iterations (last step) of the solve.
    return solver_control.last_step ();
  }

  /**
   * Output results, ie., finite element functions and derived
   * quantitites for this cycle..
   */
  template <int dim>
  void
  CatProblem<dim>::output_results (const unsigned int cycle)
  {
    dealii::TimerOutput::Scope time (timer, "output_results");

    pcout << "   Values:"
	  << std::endl;
    for (unsigned int i=0; i<solution_value.size (); ++i)
      pcout << "      " << i << ": " << solution_value[i]
	    << std::endl;

    dealii::DataOut<dim> data_out;
    data_out.attach_dof_handler (dof_handler);
    data_out.add_data_vector (locally_relevant_solution[0], "wavefunction");

    dealii::Vector<double> projected_potential (dof_handler.n_dofs ());
    {
      dealii::FunctionParser<dim> potential;
      potential.initialize (dealii::FunctionParser<dim>::default_variable_names (),
                            parameters.get ("Potential"),
                            typename dealii::FunctionParser<dim>::ConstMap ());
      dealii::VectorTools::interpolate (dof_handler, potential, projected_potential);
    }
    data_out.add_data_vector (projected_potential, "interpolated_potential");

    dealii::Vector<float> subdomain (triangulation.n_active_cells ());
    for (unsigned int i=0; i<subdomain.size(); ++i)
      subdomain (i) = triangulation.locally_owned_subdomain ();
    data_out.add_data_vector (subdomain, "subdomain");

    data_out.build_patches ();

    const std::string filename = ("wavefunction-" +
                                  dealii::Utilities::int_to_string (cycle, 2) +
                                  "." +
                                  dealii::Utilities::int_to_string
                                  (triangulation.locally_owned_subdomain (), 4));

    std::ofstream output ((filename + ".vtu").c_str ());
    data_out.write_vtu (output);

    if (dealii::Utilities::MPI::this_mpi_process(mpi_communicator) == 1)
      {
	std::vector<std::string> filenames;

	for (unsigned int i=0;
	     i<dealii::Utilities::MPI::n_mpi_processes (mpi_communicator);
	     ++i)
	  filenames.push_back ("wavefunction-" +
			       dealii::Utilities::int_to_string (cycle, 2) +
			       "." +
			       dealii::Utilities::int_to_string (i, 4) +
			       ".vtu");
	std::ofstream master_output (("wavefunction-" +
				      dealii::Utilities::int_to_string (cycle, 2) +
				      ".pvtu").c_str ());

	data_out.write_pvtu_record (master_output, filenames);
      }

    {
      std::ostringstream filename;
      filename << "grid-" << cycle << ".gpl";
      std::ofstream output (filename.str ().c_str ());
      dealii::GridOut grid_out;
      grid_out.write_gnuplot (triangulation, output);
    }

  }

  /**
   * Refine grid based on Kelly's error estimator working on the
   * material id (solution vector).
   */
  template <int dim>
  void CatProblem<dim>::refine_grid ()
  {
    dealii::TimerOutput::Scope time (timer, "refine grid");

    dealii::Vector<double> estimated_error_per_cell (triangulation.n_active_cells ());

    // dealii::KellyErrorEstimator<dim>::estimate (dof_handler, dealii::QGauss<dim-1>(4),
    // 						typename dealii::FunctionMap<dim>::type (),
    // 						locally_relevant_solution[0],
    // 						estimated_error_per_cell);

    sarah::ErrorEstimator::estimate<dim> (fe, dof_handler, dealii::QGauss<dim>(4),
					  // typename dealii::FunctionMap<dim>::type (),
					  locally_relevant_solution[0],
					  estimated_error_per_cell,
					  mpi_communicator);

    pcout << "   Estimated error per cell: ";
    for (unsigned int i=0; i<estimated_error_per_cell.size (); ++i)
      pcout << estimated_error_per_cell(i) << " ";
    pcout << std::endl;

    dealii::parallel::distributed::GridRefinement::
      refine_and_coarsen_fixed_number (triangulation,
				       estimated_error_per_cell,
				       0.250, 0.025);

    triangulation.execute_coarsening_and_refinement ();
  }

  /**
   * Run the application in the order specified.
   */
  template <int dim>
  void
  CatProblem<dim>::run ()
  {
    const unsigned int n_cycles = 5;

    for (unsigned int cycle=0; cycle<n_cycles; ++cycle)
      {
        pcout << "CatProblem:: Cycle " << cycle << ':'
	      << std::endl;

	if (cycle==0)
	  make_coarse_grid ();

	else
	  refine_grid ();
	  // triangulation.refine_global ();

	pcout << "   Number of active cells:       "
	      << triangulation.n_global_active_cells ()
	      << std::endl;

	setup_system ();

	pcout << "   Number of degrees of freedom: "
	      << dof_handler.n_dofs ()
	      << std::endl;

	assemble_system ();

	const unsigned int n_iterations = solve ();

	pcout << "   Solved in " << n_iterations
	      << " iterations."
	      << std::endl;

	// Output results if the number of processes is less than or
	// equal to 32.
	if (dealii::Utilities::MPI::n_mpi_processes (mpi_communicator) <= 32)
	  output_results (cycle);

	// timer.print_summary ();
        pcout << std::endl;

      } // for cycle<n_cycles
  }

} // namespace sarah

template class sarah::CatProblem<2>;
<commit_msg>Improve refinement.<commit_after>
#include <sarah/cat_problem.h>

namespace sarah
{

  /**
   * Class constructor.
   */
  template <int dim>
  CatProblem<dim>::CatProblem (const std::string &prm)
    :
    mpi_communicator (MPI_COMM_WORLD),
    triangulation (mpi_communicator,
                   typename dealii::Triangulation<dim>::MeshSmoothing
                   (dealii::Triangulation<dim>::smoothing_on_refinement |
                    dealii::Triangulation<dim>::smoothing_on_coarsening)),
    dof_handler (triangulation),
    fe (dealii::FE_Q<dim> (2), 1),
    n_pairs (1),
    // ---
    pcout (std::cout, (dealii::Utilities::MPI::this_mpi_process (mpi_communicator) == 0)),
    timer (mpi_communicator, pcout,
	   dealii::TimerOutput::summary,
	   dealii::TimerOutput::wall_times)
  {
    parameters.declare_entry ("Global grid refinement steps", "5",
                              dealii::Patterns::Integer (0, 20),
                              "The number of times the 1-cell coarse mesh should "
                              "be refined globally for our computations.");

    parameters.declare_entry ("Adaptive grid refinement steps", "5",
                              dealii::Patterns::Integer (0, 20),
                              "The number of times the n-cell coarse mesh should "
                              "be refined adaptively for our computations.");

    parameters.declare_entry ("Potential", "0",
                              dealii::Patterns::Anything (),
                              "A functional description of the potential.");

    parameters.declare_entry ("Error function", "0",
                              dealii::Patterns::Anything (),
			      "A functional description of the error function.");

    parameters.declare_entry ("Number of eigenpairs", "5",
                              dealii::Patterns::Integer (0, 100),
                              "The number of eigenpairs to be computed.");

    parameters.declare_entry ("Number of eigenfunctions", "5",
                              dealii::Patterns::Integer (0, 100),
                              "The number of eigenfunctions "
                              "to be used for error indicators.");

    parameters.parse_input (prm);
  }

  /**
   * Class destructor.
   */
  template <int dim>
  CatProblem<dim>::~CatProblem ()
  {
    // Wipe DoF handlers.
    dof_handler.clear ();
  }

  /**
   * Make initial coarse grid.
   */
  template <int dim>
  void
  CatProblem<dim>::make_coarse_grid ()
  {
    dealii::TimerOutput::Scope time (timer, "make coarse grid");

    // Create a coarse grid according to the parameters given in the
    // input file.
    dealii::GridGenerator::hyper_cube (triangulation, -5, 5);

    triangulation.refine_global (parameters.get_integer ("Global grid refinement steps"));
  }

  /**
   * Setup system matrices and vectors.
   */
  template <int dim>
  void CatProblem<dim>::setup_system ()
  {
    dealii::TimerOutput::Scope time (timer, "setup system");

    // Determine locally relevant DoFs.
    dof_handler.distribute_dofs (fe);
    locally_owned_dofs = dof_handler.locally_owned_dofs ();
    dealii::DoFTools::extract_locally_relevant_dofs (dof_handler, locally_relevant_dofs);

    // Initialise values.
    solution_value.resize (n_pairs, 0.);

    // Initialise distributed vectors.
    locally_relevant_solution.resize (n_pairs);
    for (unsigned int i=0; i<n_pairs; ++i)
      locally_relevant_solution[i].reinit (locally_owned_dofs, locally_relevant_dofs,
					   mpi_communicator);

    // Setup hanging node constraints.
    constraints.clear ();
    constraints.reinit (locally_relevant_dofs);
    dealii::DoFTools::make_hanging_node_constraints (dof_handler, constraints);
    dealii::DoFTools::make_zero_boundary_constraints (dof_handler, constraints);
    constraints.close ();

    // Finally, create a distributed sparsity pattern and initialise
    // the system- and mass-matrix from that.
    dealii::DynamicSparsityPattern dsp (locally_relevant_dofs);
    dealii::DoFTools::make_sparsity_pattern (dof_handler, dsp, constraints, false);
    dealii::SparsityTools::distribute_sparsity_pattern (dsp,
							dof_handler.n_locally_owned_dofs_per_processor (),
							mpi_communicator,
							locally_relevant_dofs);

    system_matrix.reinit (locally_owned_dofs, locally_owned_dofs, dsp,
			  mpi_communicator);

    mass_matrix.reinit (locally_owned_dofs, locally_owned_dofs,	dsp,
			mpi_communicator);
  }

  /**
   * Assemble system matrices and vectors.
   *
   * TODO Ideally, we would use a function like this:
   *
   * dealii::MatrixCreator::create_mass_matrix (dof_handler, quadrature_rule, system_matrix, 1, constraints);
   *
   * however no such thing currently exists in the deal.II library for
   * parallel matrices and vectors. Instead, the mass matrix and right
   * hand side vector are assembled by hand in functions defined in
   * the namepsaces, sarah::MatrixCreator and sarah::VectorCreator,
   * respectively.
   */
  template <int dim>
  void
  CatProblem<dim>::assemble_system ()
  {
    dealii::TimerOutput::Scope time (timer, "assemble system");

    // Define quadrature rule to be used.
    const dealii::QGauss<dim> quadrature_formula (3);

    sarah::MatrixCreator::create_mass_matrix<dim> (fe, dof_handler, quadrature_formula,
						   mass_matrix, constraints,
						   mpi_communicator);

    dealii::FEValues<dim> fe_values (fe, quadrature_formula,
				     dealii::update_values            |
				     dealii::update_gradients         |
				     dealii::update_quadrature_points |
				     dealii::update_JxW_values);

    const unsigned int dofs_per_cell = fe.dofs_per_cell;
    const unsigned int n_q_points    = quadrature_formula.size();

    dealii::FullMatrix<double> cell_system_matrix (dofs_per_cell, dofs_per_cell);

    std::vector<dealii::types::global_dof_index> local_dof_indices (dofs_per_cell);

    dealii::FunctionParser<dim> potential;
    potential.initialize (dealii::FunctionParser<dim>::default_variable_names (),
                          parameters.get ("Potential"),
                          typename dealii::FunctionParser<dim>::ConstMap ());

    std::vector<double> potential_values (n_q_points);

    typename dealii::DoFHandler<dim>::active_cell_iterator
      cell = dof_handler.begin_active (),
      endc = dof_handler.end ();

    for (; cell!=endc; ++cell)
      {
        fe_values.reinit (cell);
        cell_system_matrix = 0;

        potential.value_list (fe_values.get_quadrature_points (),
                              potential_values);

        for (unsigned int q_point=0; q_point<n_q_points; ++q_point)
          for (unsigned int i=0; i<dofs_per_cell; ++i)
            for (unsigned int j=0; j<dofs_per_cell; ++j)
              {
                cell_system_matrix (i, j)
		  += (0.5                               *
		      fe_values.shape_grad (i, q_point) *
		      fe_values.shape_grad (j, q_point)
		      +
		      potential_values[q_point]          *
		      fe_values.shape_value (i, q_point) *
		      fe_values.shape_value (j, q_point)
		      )
		  * fe_values.JxW (q_point);
              }

        cell->get_dof_indices (local_dof_indices);

        constraints
	  .distribute_local_to_global (cell_system_matrix,
				       local_dof_indices,
				       system_matrix);
      }

    system_matrix.compress (dealii::VectorOperation::add);

  }

  /**
   * Solve the linear algebra system.
   */
  template <int dim>
  unsigned int
  CatProblem<dim>::solve ()
  {
    dealii::TimerOutput::Scope time (timer, "solve");

    std::vector<dealii::PETScWrappers::MPI::Vector> completely_distributed_solution;
    completely_distributed_solution.resize (n_pairs);
    for (unsigned int i=0; i<n_pairs; ++i)
      completely_distributed_solution[i].reinit (locally_owned_dofs,
						 mpi_communicator);

    // Solve using KrylovSchur
    dealii::SolverControl solver_control (dof_handler.n_dofs (), 1e-06);
    dealii::SLEPcWrappers::SolverKrylovSchur solver (solver_control, mpi_communicator);

    solver.set_which_eigenpairs (EPS_SMALLEST_REAL);
    solver.set_problem_type (EPS_GHEP);

    solver.solve (system_matrix, mass_matrix, solution_value, completely_distributed_solution,
		  completely_distributed_solution.size ());

    // Ensure that all ghost elements are also copied as necessary.
    for (unsigned int i=0; i<n_pairs; ++i)
      constraints.distribute (completely_distributed_solution[i]);

    for (unsigned int i=0; i<n_pairs; ++i)
      locally_relevant_solution[i] = completely_distributed_solution[i];

    // Return the number of iterations (last step) of the solve.
    return solver_control.last_step ();
  }

  /**
   * Output results, ie., finite element functions and derived
   * quantitites for this cycle..
   */
  template <int dim>
  void
  CatProblem<dim>::output_results (const unsigned int cycle)
  {
    dealii::TimerOutput::Scope time (timer, "output_results");

    pcout << "   Values:"
	  << std::endl;
    for (unsigned int i=0; i<solution_value.size (); ++i)
      pcout << "      " << i << ": " << solution_value[i]
	    << " error " << std::fabs (solution_value[i]-i-1)
	    << std::endl;

    dealii::DataOut<dim> data_out;
    data_out.attach_dof_handler (dof_handler);
    data_out.add_data_vector (locally_relevant_solution[0], "wavefunction");

    dealii::Vector<double> projected_potential (dof_handler.n_dofs ());
    {
      dealii::FunctionParser<dim> potential;
      potential.initialize (dealii::FunctionParser<dim>::default_variable_names (),
                            parameters.get ("Potential"),
                            typename dealii::FunctionParser<dim>::ConstMap ());
      dealii::VectorTools::interpolate (dof_handler, potential, projected_potential);
    }
    data_out.add_data_vector (projected_potential, "interpolated_potential");

    dealii::Vector<float> subdomain (triangulation.n_active_cells ());
    for (unsigned int i=0; i<subdomain.size(); ++i)
      subdomain (i) = triangulation.locally_owned_subdomain ();
    data_out.add_data_vector (subdomain, "subdomain");

    data_out.build_patches ();

    const std::string filename = ("wavefunction-" +
                                  dealii::Utilities::int_to_string (cycle, 2) +
                                  "." +
                                  dealii::Utilities::int_to_string
                                  (triangulation.locally_owned_subdomain (), 4));

    std::ofstream output ((filename + ".vtu").c_str ());
    data_out.write_vtu (output);

    if (dealii::Utilities::MPI::this_mpi_process(mpi_communicator) == 1)
      {
	std::vector<std::string> filenames;

	for (unsigned int i=0;
	     i<dealii::Utilities::MPI::n_mpi_processes (mpi_communicator);
	     ++i)
	  filenames.push_back ("wavefunction-" +
			       dealii::Utilities::int_to_string (cycle, 2) +
			       "." +
			       dealii::Utilities::int_to_string (i, 4) +
			       ".vtu");
	std::ofstream master_output (("wavefunction-" +
				      dealii::Utilities::int_to_string (cycle, 2) +
				      ".pvtu").c_str ());

	data_out.write_pvtu_record (master_output, filenames);
      }

    {
      std::ostringstream filename;
      filename << "grid-" << cycle << ".gpl";
      std::ofstream output (filename.str ().c_str ());
      dealii::GridOut grid_out;
      grid_out.write_gnuplot (triangulation, output);
    }

  }

  /**
   * Refine grid based on Kelly's error estimator working on the
   * material id (solution vector).
   */
  template <int dim>
  void CatProblem<dim>::refine_grid ()
  {
    dealii::TimerOutput::Scope time (timer, "refine grid");

    dealii::Vector<double> estimated_error_per_cell (triangulation.n_active_cells ());

#undef  KELLY
#define VOLUME

#ifdef KELLY
    pcout << "Kelly: eigenfunction";

    // "Standard" Kelly error estimate applied to a super position of
    // the lowest k eigenfunctions.
    dealii::KellyErrorEstimator<dim>::estimate (dof_handler, dealii::QGauss<dim-1>(4),
     						typename dealii::FunctionMap<dim>::type (),
						locally_relevant_solution[0],
						estimated_error_per_cell);
#endif
#ifdef VOLUME
    pcout << "Physics-based: Volume";

    // This is a function description of the error - in short, it is
    // the "exp" projected potential.
    dealii::FunctionParser<dim> error_function;
    error_function.initialize (dealii::FunctionParser<dim>::default_variable_names (),
			       parameters.get ("Error function"),
			       typename dealii::FunctionParser<dim>::ConstMap ());

    sarah::ErrorEstimator::estimate<dim> (fe, dof_handler, dealii::QGauss<dim>(4),
					  error_function,
					  estimated_error_per_cell,
					  mpi_communicator);
#endif
    pcout << std::endl;

    // pcout << "   Estimated error per cell: ";
    // for (unsigned int i=0; i<estimated_error_per_cell.size (); ++i)
    //   pcout << estimated_error_per_cell(i) << " ";
    // pcout << std::endl;

    dealii::parallel::distributed::GridRefinement::
      refine_and_coarsen_fixed_number (triangulation,
				       estimated_error_per_cell,
				       0.250, 0.025);

    triangulation.execute_coarsening_and_refinement ();
  }

  /**
   * Run the application in the order specified.
   */
  template <int dim>
  void
  CatProblem<dim>::run ()
  {
    const unsigned int n_cycles = parameters.get_integer ("Adaptive grid refinement steps");;

    for (unsigned int cycle=0; cycle<n_cycles; ++cycle)
      {
        pcout << "CatProblem:: Cycle " << cycle << ':'
	      << std::endl;

	if (cycle==0)
	  make_coarse_grid ();

	else
	  refine_grid ();
	  // triangulation.refine_global ();

	pcout << "   Number of active cells:       "
	      << triangulation.n_global_active_cells ()
	      << std::endl;

	setup_system ();

	pcout << "   Number of degrees of freedom: "
	      << dof_handler.n_dofs ()
	      << std::endl;

	assemble_system ();

	const unsigned int n_iterations = solve ();

	pcout << "   Solved in " << n_iterations
	      << " iterations."
	      << std::endl;

	// Output results if the number of processes is less than or
	// equal to 32.
	if (dealii::Utilities::MPI::n_mpi_processes (mpi_communicator) <= 32)
	  output_results (cycle);

	// timer.print_summary ();
        pcout << std::endl;

      } // for cycle<n_cycles
  }

} // namespace sarah

template class sarah::CatProblem<2>;
<|endoftext|>


<commit_before>/*
 * Copyright 2007 Stephen Liu
 * For license terms, see the file COPYING along with this library.
 */

#include <string.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>

#include "spbuffer.hpp"

#include "config.h"
#include "event.h"

SP_Buffer :: SP_Buffer()
{
	mBuffer = evbuffer_new();
}

SP_Buffer :: ~SP_Buffer()
{
	evbuffer_free( mBuffer );
	mBuffer = NULL;
}

int SP_Buffer :: append( const void * buffer, int len )
{
	len = len <= 0 ? strlen( (char*)buffer ) : len;

	return evbuffer_add( mBuffer, (void*)buffer, len );
}

int SP_Buffer :: append( const SP_Buffer * buffer )
{
	if( buffer->getSize() > 0 ) {
		return append( buffer->getBuffer(), buffer->getSize() );
	} else {
		return 0;
	}
}

void SP_Buffer :: erase( int len )
{
	evbuffer_drain( mBuffer, len );
}

void SP_Buffer :: reset()
{
	erase( getSize() );
}

const void * SP_Buffer :: getBuffer() const
{
	if( NULL != EVBUFFER_DATA( mBuffer ) ) {
		((char*)(EVBUFFER_DATA( mBuffer )))[ getSize() ] = '\0';
		return EVBUFFER_DATA( mBuffer );
	} else {
		return "";
	}
}

size_t SP_Buffer :: getSize() const
{
	return EVBUFFER_LENGTH( mBuffer );
}

char * SP_Buffer :: getLine()
{
	return evbuffer_readline( mBuffer );
}

int SP_Buffer :: take( char * buffer, int len )
{
	len = evbuffer_remove( mBuffer, buffer, len - 1);
	buffer[ len ] = '\0';

	return len;
}

SP_Buffer * SP_Buffer :: take()
{
	SP_Buffer * ret = new SP_Buffer();

	struct evbuffer * tmp = ret->mBuffer;
	ret->mBuffer = mBuffer;
	mBuffer = tmp;

	return ret;
}

const void * SP_Buffer :: find( const void * key, size_t len )
{
	//return (void*)evbuffer_find( mBuffer, (u_char*)key, len );

	struct evbuffer * buffer = mBuffer;
	u_char * what = (u_char*)key;

	size_t remain = buffer->off;
	u_char *search = buffer->buffer;
	u_char *p;

	while (remain >= len) {
		if ((p = (u_char*)memchr(search, *what, (remain - len) + 1)) == NULL)
			break;

		if (memcmp(p, what, len) == 0)
			return (p);

		search = p + 1;
		remain = buffer->off - (size_t)(search - buffer->buffer);
	}

	return (NULL);
}

<commit_msg>fix write outside of an allocated buffer, thanks for Jurgen Van Ham ( jurgen.vanham@vasco.com) 's patch<commit_after>/*
 * Copyright 2007 Stephen Liu
 * For license terms, see the file COPYING along with this library.
 */

#include <string.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>

#include "spbuffer.hpp"

#include "config.h"
#include "event.h"

SP_Buffer :: SP_Buffer()
{
	mBuffer = evbuffer_new();
}

SP_Buffer :: ~SP_Buffer()
{
	evbuffer_free( mBuffer );
	mBuffer = NULL;
}

int SP_Buffer :: append( const void * buffer, int len )
{
	len = len <= 0 ? strlen( (char*)buffer ) : len;

	return evbuffer_add( mBuffer, (void*)buffer, len );
}

int SP_Buffer :: append( const SP_Buffer * buffer )
{
	if( buffer->getSize() > 0 ) {
		return append( buffer->getBuffer(), buffer->getSize() );
	} else {
		return 0;
	}
}

void SP_Buffer :: erase( int len )
{
	evbuffer_drain( mBuffer, len );
}

void SP_Buffer :: reset()
{
	erase( getSize() );
}

const void * SP_Buffer :: getBuffer() const
{
	if( NULL != EVBUFFER_DATA( mBuffer ) ) {
		evbuffer_expand( mBuffer, 1 );
		((char*)(EVBUFFER_DATA( mBuffer )))[ getSize() ] = '\0';
		return EVBUFFER_DATA( mBuffer );
	} else {
		return "";
	}
}

size_t SP_Buffer :: getSize() const
{
	return EVBUFFER_LENGTH( mBuffer );
}

char * SP_Buffer :: getLine()
{
	return evbuffer_readline( mBuffer );
}

int SP_Buffer :: take( char * buffer, int len )
{
	len = evbuffer_remove( mBuffer, buffer, len - 1);
	buffer[ len ] = '\0';

	return len;
}

SP_Buffer * SP_Buffer :: take()
{
	SP_Buffer * ret = new SP_Buffer();

	struct evbuffer * tmp = ret->mBuffer;
	ret->mBuffer = mBuffer;
	mBuffer = tmp;

	return ret;
}

const void * SP_Buffer :: find( const void * key, size_t len )
{
	//return (void*)evbuffer_find( mBuffer, (u_char*)key, len );

	struct evbuffer * buffer = mBuffer;
	u_char * what = (u_char*)key;

	size_t remain = buffer->off;
	u_char *search = buffer->buffer;
	u_char *p;

	while (remain >= len) {
		if ((p = (u_char*)memchr(search, *what, (remain - len) + 1)) == NULL)
			break;

		if (memcmp(p, what, len) == 0)
			return (p);

		search = p + 1;
		remain = buffer->off - (size_t)(search - buffer->buffer);
	}

	return (NULL);
}

<|endoftext|>


<commit_before>/**
 * Node.cc
 *
 * Copyright(c) 2001 Thiago Maia, Andre Senna
 * All rights reserved.
 */
#include <stdio.h>
#include "Node.h"
#include "ClassServer.h"
//#include "exceptions.h"
#include "Link.h"
#include "TLB.h"
#include "utils.h"
#include "AtomSpaceDefinitions.h"

Node::Node(Type type, const std::string& name, const TruthValue& tv) throw (InvalidParamException, AssertionException) : Atom(type, std::vector<Handle>(), tv) {

    if (!ClassServer::isAssignableFrom(NODE, type)) {
        throw InvalidParamException(TRACE_INFO, "Node - Invalid node type '%d'.", type);
    }

    cassert(TRACE_INFO, &name, "Node - name parameter should not be NULL.");

    // If name is empty let it unitialized for saving memory...
    if (!name.empty()) {
        this->name = name;
    }
}

Node::~Node() throw () {
//    fprintf(stdout, "Deleting Node:\n%s\n", this->toString().c_str());
//    fflush(stdout);
}

const std::string& Node::getName() const{
    return name;
}

void Node::setName(const std::string& name) throw (RuntimeException) {

    if (atomTable != NULL){
        throw RuntimeException(TRACE_INFO,
              "Node - Cannot change the name of a node already inserted into an AtomTable.");
    }

    if (!name.empty()) {
        this->name = name;
    } else if (!(this->name.empty())) {
        this->name = name;
    }
}

void Node::merge(Atom* atom) throw (InconsistenceException) {

    if (!equals(atom)){
        throw InconsistenceException(TRACE_INFO, "Node - Different nodes cannot be merged");
    }

    Atom::merge(atom);
}

std::string Node::toShortString() {
    char buf[1024];
    sprintf(buf, "node[%d:%s%s]", type, name.c_str(), (getFlag(HYPOTETHICAL_FLAG)?":h":""));
    return buf;
}

std::string Node::toString() {
    char buf[1024];
    sprintf(buf, "node[%d:%s] (%d,%f)", type, name.c_str(), (int)getAttentionValue().getSTI(), 0.0); //activation here at 0: can be replace with LTI
    return buf;
}

bool Node::equals(Atom *other){
    bool result = false;
    if (other != NULL && (type == other->getType())){
        Node *otherNode = (Node *) other;
        result = !strcmp(name.c_str(), otherNode->getName().c_str());
    }
    return(result);
}

int Node::hashCode(){
    int result = Atom::hashCode();
    result += Util::hash<const char*>()(name.c_str());
    return result;
}

<commit_msg>cleanup several buffer overflows, plus some bizarre conceptions about string allocation.<commit_after>/**
 * Node.cc
 *
 * Copyright(c) 2001 Thiago Maia, Andre Senna
 * All rights reserved.
 */
#include <stdio.h>
#include "Node.h"
#include "ClassServer.h"
//#include "exceptions.h"
#include "Link.h"
#include "TLB.h"
#include "utils.h"
#include "AtomSpaceDefinitions.h"

Node::Node(Type type,
           const std::string& cname,
           const TruthValue& tv)
throw (InvalidParamException, AssertionException)
    : Atom(type, std::vector<Handle>(), tv)
{
    if (!ClassServer::isAssignableFrom(NODE, type)) {
        throw InvalidParamException(TRACE_INFO, "Node - Invalid node type '%d'.", type);
    }

    cassert(TRACE_INFO, &name, "Node - name parameter should not be NULL.");
    name = cname;
}

Node::~Node() throw ()
{
//    fprintf(stdout, "Deleting Node:\n%s\n", toString().c_str());
//    fflush(stdout);
}

const std::string& Node::getName() const
{
    return name;
}

void Node::setName(const std::string& cname) throw (RuntimeException)
{

    if (atomTable != NULL){
        throw RuntimeException(TRACE_INFO,
              "Node - Cannot change the name of a node already inserted into an AtomTable.");
    }
    name = cname;
}

void Node::merge(Atom* atom) throw (InconsistenceException)
{
    if (!equals(atom)) {
        throw InconsistenceException(TRACE_INFO, "Node - Different nodes cannot be merged");
    }

    Atom::merge(atom);
}

std::string Node::toShortString()
{
#define BUFSZ 1024
    char buf[BUFSZ];
    snprintf(buf, BUFSZ, "node[%d:%s%s]",
        type, name.c_str(), (getFlag(HYPOTETHICAL_FLAG)?":h":""));
    return buf;
}

std::string Node::toString()
{
    char buf[BUFSZ];
    //activation here at 0: can be replace with LTI
    snprintf(buf, BUFSZ, "node[%d:%s] (%d,%f)",
        type, name.c_str(), (int)getAttentionValue().getSTI(), 0.0);
    return buf;
}

bool Node::equals(Atom *other)
{
    bool result = false;
    if (other != NULL && (type == other->getType())){
        Node *otherNode = (Node *) other;
        result = !strcmp(name.c_str(), otherNode->getName().c_str());
    }
    return(result);
}

int Node::hashCode()
{
    int result = Atom::hashCode();
    result += Util::hash<const char*>()(name.c_str());
    return result;
}

<|endoftext|>


<commit_before>#ifndef SLICE_HPP
#define SLICE_HPP

#include "iterbase.hpp"

#include <iterator>
#include <type_traits>
#include <initializer_list>

namespace iter {

    //Forward declarations of Slice and slice
    //template <typename Container, typename DifferenceType>
    //class Slice;

    //template <typename T>
    //Slice<std::initializer_list<T>> slice( std::initializer_list<T> &&);

    //template <typename Container, typename DifferenceType>
    //Slice<Container> slice(Container &&);
    template <typename T>
    class has_size
    {
        typedef char one;
        typedef long two;

        template <typename C> static one test( decltype(&C::size) ) ;
        template <typename C> static two test(...);

        public:
        enum { value = sizeof(test<T>(0)) == sizeof(char) };
    };
    template <typename Container>
    typename std::enable_if<has_size<Container>::value,size_t>::type
    size(Container & container) {
        return container.size();
    }

    template <typename Container>
    typename std::enable_if<!has_size<Container>::value,size_t>::type
    size(Container & container) {
        return std::distance(std::begin(container), std::end(container));
    }

    template <typename T, size_t N>
    size_t size(T (&)[N]) {
        return N;
    }

    template <typename Container, typename DifferenceType>
    class Slice {
        private:
            Container & container;
            DifferenceType start;
            DifferenceType stop;
            DifferenceType step;

            // The only thing allowed to directly instantiate an Slice is
            // the slice function
            //friend Slice slice<Container, DifferenceType>(Container &&);
            //template <typename T>
            //friend Slice<std::initializer_list<T>> slice(std::initializer_list<T> &&);

        public:
            Slice(Container & container, DifferenceType start,
                  DifferenceType stop, DifferenceType step) :
                container(container),
                start(start),
                stop(stop),
                step(step)
            {
                // sets stop = start if the range is empty
                if ((start < stop && step <=0) ||
                        (start > stop && step >=0)){
                    this->stop = start;
                }
                if (this->stop > static_cast<DifferenceType>(size(container))) {
                    this->stop = static_cast<DifferenceType>(size(container));
                }
                if (this->start < 0) {
                    this->start = 0;
                }
            }

            Slice () = delete;
            Slice & operator=(const Slice &) = delete;

            Slice(const Slice &) = default;

            class Iterator {
                private:
                    iterator_type<Container> sub_iter;
                    DifferenceType current;
                    const DifferenceType stop;
                    const DifferenceType step;

                public:
                    Iterator (iterator_type<Container> si, DifferenceType start,
                            DifferenceType stop, DifferenceType step) :
                        sub_iter(si),
                        current(start),
                        stop(stop),
                        step(step)
                    { }

                    iterator_deref<Container> operator*() const {
                        return *this->sub_iter;
                    }

                    Iterator & operator++() {
                        std::advance(this->sub_iter, this->step);
                        this->current += this->step;
                        return *this;
                    }

                    bool operator!=(const Iterator &) const {
                        return (this->step > 0 && this->current < this->stop)||
                            (this->step < 0 && this->current > this->stop);
                    }
            };

            Iterator begin() const {
                return Iterator(
                        std::next(std::begin(this->container), this->start),
                        this->start, this->stop, this->step);
            }

            Iterator end() const {
                return Iterator(
                        std::next(std::begin(this->container), this->stop),
                        this->stop, this->stop, this->step);
            }

    };

    // Helper function to instantiate a Slice
    template <typename Container, typename DifferenceType>
    Slice<Container, DifferenceType> slice(
            Container && container, DifferenceType start,
            DifferenceType stop, DifferenceType step=1) {
        return Slice<Container, DifferenceType>(
                std::forward<Container>(container), start, stop, step);
    }

    //only give the end as an arg and assume step  is 1 and begin is 0
    template <typename Container, typename DifferenceType>
    Slice<Container, DifferenceType> slice(
            Container && container, DifferenceType stop) {
        return Slice<Container, DifferenceType>(
                std::forward<Container>(container), 0, stop, 1);
    }

    template <typename T, typename DifferenceType>
    Slice<std::initializer_list<T>, DifferenceType> slice(
            std::initializer_list<T> && il, DifferenceType start,
            DifferenceType stop, DifferenceType step=1) {
        return Slice<std::initializer_list<T>, DifferenceType>(
                il, start, stop, step);
    }

    template <typename T, typename DifferenceType>
    Slice<std::initializer_list<T>, DifferenceType> slice(
            std::initializer_list<T> && il, DifferenceType stop) {
        return Slice<std::initializer_list<T>, DifferenceType>(il, 0, stop, 1);
    }
}

#endif //SLICE_HPP
<commit_msg>uniform initialization updates<commit_after>#ifndef SLICE_HPP
#define SLICE_HPP

#include "iterbase.hpp"

#include <iterator>
#include <type_traits>
#include <initializer_list>

namespace iter {

    //Forward declarations of Slice and slice
    //template <typename Container, typename DifferenceType>
    //class Slice;

    //template <typename T>
    //Slice<std::initializer_list<T>> slice( std::initializer_list<T> &&);

    //template <typename Container, typename DifferenceType>
    //Slice<Container> slice(Container &&);
    template <typename T>
    class has_size
    {
        typedef char one;
        typedef long two;

        template <typename C> static one test( decltype(&C::size) ) ;
        template <typename C> static two test(...);

        public:
        enum { value = sizeof(test<T>(0)) == sizeof(char) };
    };
    template <typename Container>
    typename std::enable_if<has_size<Container>::value,size_t>::type
    size(Container & container) {
        return container.size();
    }

    template <typename Container>
    typename std::enable_if<!has_size<Container>::value,size_t>::type
    size(Container & container) {
        return std::distance(std::begin(container), std::end(container));
    }

    template <typename T, size_t N>
    size_t size(T (&)[N]) {
        return N;
    }

    template <typename Container, typename DifferenceType>
    class Slice {
        private:
            Container & container;
            DifferenceType start;
            DifferenceType stop;
            DifferenceType step;

            // The only thing allowed to directly instantiate an Slice is
            // the slice function
            //friend Slice slice<Container, DifferenceType>(Container &&);
            //template <typename T>
            //friend Slice<std::initializer_list<T>> slice(std::initializer_list<T> &&);

        public:
            Slice(Container & container, DifferenceType start,
                  DifferenceType stop, DifferenceType step)
                : container{container},
                start{start},
                stop{stop},
                step{step}
            {
                // sets stop = start if the range is empty
                if ((start < stop && step <=0) ||
                        (start > stop && step >=0)){
                    this->stop = start;
                }
                if (this->stop > static_cast<DifferenceType>(size(container))) {
                    this->stop = static_cast<DifferenceType>(size(container));
                }
                if (this->start < 0) {
                    this->start = 0;
                }
            }

            Slice () = delete;
            Slice & operator=(const Slice &) = delete;

            Slice(const Slice &) = default;

            class Iterator {
                private:
                    iterator_type<Container> sub_iter;
                    DifferenceType current;
                    const DifferenceType stop;
                    const DifferenceType step;

                public:
                    Iterator (iterator_type<Container> si, DifferenceType start,
                            DifferenceType stop, DifferenceType step)
                        : sub_iter{si},
                        current{start},
                        stop{stop},
                        step{step}
                    { }

                    iterator_deref<Container> operator*() const {
                        return *this->sub_iter;
                    }

                    Iterator & operator++() {
                        std::advance(this->sub_iter, this->step);
                        this->current += this->step;
                        return *this;
                    }

                    bool operator!=(const Iterator &) const {
                        return (this->step > 0 && this->current < this->stop)||
                            (this->step < 0 && this->current > this->stop);
                    }
            };

            Iterator begin() const {
                return {std::next(std::begin(this->container), this->start),
                        this->start, this->stop, this->step};
            }

            Iterator end() const {
                return {std::next(std::begin(this->container), this->stop),
                        this->stop, this->stop, this->step};
            }

    };

    // Helper function to instantiate a Slice
    template <typename Container, typename DifferenceType>
    Slice<Container, DifferenceType> slice(
            Container && container, DifferenceType start,
            DifferenceType stop, DifferenceType step=1) {
        return {std::forward<Container>(container), start, stop, step};
    }

    //only give the end as an arg and assume step  is 1 and begin is 0
    template <typename Container, typename DifferenceType>
    Slice<Container, DifferenceType> slice(
            Container && container, DifferenceType stop) {
        return {std::forward<Container>(container), 0, stop, 1};
    }

    template <typename T, typename DifferenceType>
    Slice<std::initializer_list<T>, DifferenceType> slice(
            std::initializer_list<T> && il, DifferenceType start,
            DifferenceType stop, DifferenceType step=1) {
        return {il, start, stop, step};
    }

    template <typename T, typename DifferenceType>
    Slice<std::initializer_list<T>, DifferenceType> slice(
            std::initializer_list<T> && il, DifferenceType stop) {
        return {il, 0, stop, 1};
    }
}

#endif //SLICE_HPP
<|endoftext|>


<commit_before>#include <string>

static const std::string base64_chars =
             "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
             "abcdefghijklmnopqrstuvwxyz"
             "0123456789+/";

std::string hexToByteString(const std::string hexString)
{
    std::string bytes;
    for(unsigned int i = 0; i < hexString.length(); i += 2)
    {
        std::string byteString = hexString.substr(i, 2);
        char byte = (char) strtol(byteString.c_str(), NULL, 16);
        bytes.push_back(byte);
    }
    return bytes;
}

std::string base64Encode(const std::string byteString)
{
    std::string result;
    unsigned int neededPadding = 0;
    for(unsigned int i = 0; i < byteString.size(); i += 3)
    {
        auto chunk = byteString.substr(i, 3);
        if(chunk.size() != 3)
        {
            neededPadding = 3 - chunk.size();
            chunk += std::string("\0", neededPadding) ;
        }
        result += base64_chars[(chunk[0] & 0xFC) >> 2];
        result += base64_chars[((chunk[0] & 0x03) << 4) + ((chunk[1] & 0xF0) >> 4)];
        result += base64_chars[((chunk[1] & 0x0F) << 2) + ((chunk[2] & 0xC0) >> 6)];
        result += base64_chars[chunk[2] & 0x3F];
    }

    if(byteString.size() % 3)
    {
        for(unsigned int i = 0; i < neededPadding; ++i)
        {
            result[result.size()-1-i] = '=';
        }
    }

    return result;
}
<commit_msg>Added missing references<commit_after>#include <string>

static const std::string base64_chars =
             "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
             "abcdefghijklmnopqrstuvwxyz"
             "0123456789+/";

std::string hexToByteString(const std::string& hexString)
{
    std::string bytes;
    for(unsigned int i = 0; i < hexString.length(); i += 2)
    {
        std::string byteString = hexString.substr(i, 2);
        char byte = (char) strtol(byteString.c_str(), NULL, 16);
        bytes.push_back(byte);
    }
    return bytes;
}

std::string base64Encode(const std::string& byteString)
{
    std::string result;
    unsigned int neededPadding = 0;
    for(unsigned int i = 0; i < byteString.size(); i += 3)
    {
        auto chunk = byteString.substr(i, 3);
        if(chunk.size() != 3)
        {
            neededPadding = 3 - chunk.size();
            chunk += std::string("\0", neededPadding) ;
        }
        result += base64_chars[(chunk[0] & 0xFC) >> 2];
        result += base64_chars[((chunk[0] & 0x03) << 4) + ((chunk[1] & 0xF0) >> 4)];
        result += base64_chars[((chunk[1] & 0x0F) << 2) + ((chunk[2] & 0xC0) >> 6)];
        result += base64_chars[chunk[2] & 0x3F];
    }

    if(byteString.size() % 3)
    {
        for(unsigned int i = 0; i < neededPadding; ++i)
        {
            result[result.size()-1-i] = '=';
        }
    }

    return result;
}
<|endoftext|>


<commit_before>#include <qpdf/Pl_AES_PDF.hh>
#include <qpdf/QUtil.hh>
#include <qpdf/MD5.hh>
#include <cstring>
#include <assert.h>
#include <stdexcept>
#include <qpdf/rijndael.h>
#include <string>
#include <stdlib.h>
#include <qpdf/qpdf-config.h>
#ifndef HAVE_RANDOM
# define random rand
# define srandom srand
#endif

Pl_AES_PDF::Pl_AES_PDF(char const* identifier, Pipeline* next,
		       bool encrypt, unsigned char const key[key_size]) :
    Pipeline(identifier, next),
    encrypt(encrypt),
    cbc_mode(true),
    first(true),
    offset(0),
    nrounds(0)
{
    static int const keybits = 128;
    assert(key_size == KEYLENGTH(keybits));
    assert(sizeof(this->rk) / sizeof(uint32_t) == RKLENGTH(keybits));
    std::memcpy(this->key, key, key_size);
    std::memset(this->rk, 0, sizeof(this->rk));
    std::memset(this->inbuf, 0, this->buf_size);
    std::memset(this->outbuf, 0, this->buf_size);
    std::memset(this->cbc_block, 0, this->buf_size);
    if (encrypt)
    {
	this->nrounds = rijndaelSetupEncrypt(this->rk, this->key, keybits);
    }
    else
    {
	this->nrounds = rijndaelSetupDecrypt(this->rk, this->key, keybits);
    }
    assert(this->nrounds == NROUNDS(keybits));
}

Pl_AES_PDF::~Pl_AES_PDF()
{
    // nothing needed
}

void
Pl_AES_PDF::disableCBC()
{
    this->cbc_mode = false;
}

void
Pl_AES_PDF::write(unsigned char* data, int len)
{
    unsigned int bytes_left = len;
    unsigned char* p = data;

    while (bytes_left > 0)
    {
	if (this->offset == this->buf_size)
	{
	    flush(false);
	}

	unsigned int available = this->buf_size - this->offset;
	int bytes = (bytes_left < available ? bytes_left : available);
	bytes_left -= bytes;
	std::memcpy(this->inbuf + this->offset, p, bytes);
	this->offset += bytes;
	p += bytes;
    }
}

void
Pl_AES_PDF::finish()
{
    if (this->encrypt)
    {
	if (this->offset == this->buf_size)
	{
	    flush(false);
	}
	// Pad as described in section 3.5.1 of version 1.7 of the PDF
	// specification, including providing an entire block of padding
	// if the input was a multiple of 16 bytes.
	unsigned char pad = this->buf_size - this->offset;
	memset(this->inbuf + this->offset, pad, pad);
	this->offset = this->buf_size;
	flush(false);
    }
    else
    {
	if (this->offset != this->buf_size)
	{
	    throw std::runtime_error(
		"aes encrypted stream length was not a multiple of " +
		QUtil::int_to_string(this->buf_size) + " bytes (offset = " +
		QUtil::int_to_string(this->offset) + ")");
	}
	flush(true);
    }
    getNext()->finish();
}

void
Pl_AES_PDF::initializeVector()
{
    std::string seed_str;
    seed_str += QUtil::int_to_string((int)QUtil::get_current_time());
    seed_str += " QPDF aes random";
    MD5 m;
    m.encodeString(seed_str.c_str());
    MD5::Digest digest;
    m.digest(digest);
    assert(sizeof(digest) >= sizeof(unsigned int));
    unsigned int seed;
    memcpy((void*)(&seed), digest, sizeof(unsigned int));
    srandom(seed);
    for (unsigned int i = 0; i < this->buf_size; ++i)
    {
	this->cbc_block[i] = (unsigned char)(random() & 0xff);
    }
}

void
Pl_AES_PDF::flush(bool strip_padding)
{
    assert(this->offset == this->buf_size);

    if (first)
    {
	first = false;
	if (this->cbc_mode)
	{
	    if (encrypt)
	    {
		// Set cbc_block to a random initialization vector and
		// write it to the output stream
		initializeVector();
		getNext()->write(this->cbc_block, this->buf_size);
	    }
	    else
	    {
		// Take the first block of input as the initialization
		// vector.  There's nothing to write at this time.
		memcpy(this->cbc_block, this->inbuf, this->buf_size);
		this->offset = 0;
		return;
	    }
	}
    }

    if (this->encrypt)
    {
	if (this->cbc_mode)
	{
	    for (unsigned int i = 0; i < this->buf_size; ++i)
	    {
		this->inbuf[i] ^= this->cbc_block[i];
	    }
	}
	rijndaelEncrypt(this->rk, this->nrounds, this->inbuf, this->outbuf);
	if (this->cbc_mode)
	{
	    memcpy(this->cbc_block, this->outbuf, this->buf_size);
	}
    }
    else
    {
	rijndaelDecrypt(this->rk, this->nrounds, this->inbuf, this->outbuf);
	if (this->cbc_mode)
	{
	    for (unsigned int i = 0; i < this->buf_size; ++i)
	    {
		this->outbuf[i] ^= this->cbc_block[i];
	    }
	    memcpy(this->cbc_block, this->inbuf, this->buf_size);
	}
    }
    unsigned int bytes = this->buf_size;
    if (strip_padding)
    {
	unsigned char last = this->outbuf[this->buf_size - 1];
	if (last <= this->buf_size)
	{
	    bool strip = true;
	    for (unsigned int i = 1; i <= last; ++i)
	    {
		if (this->outbuf[this->buf_size - i] != last)
		{
		    strip = false;
		    break;
		}
	    }
	    if (strip)
	    {
		bytes -= last;
	    }
	}
    }
    getNext()->write(this->outbuf, bytes);
    this->offset = 0;
}
<commit_msg>avoid low order bits of random just in case it's rand<commit_after>#include <qpdf/Pl_AES_PDF.hh>
#include <qpdf/QUtil.hh>
#include <qpdf/MD5.hh>
#include <cstring>
#include <assert.h>
#include <stdexcept>
#include <qpdf/rijndael.h>
#include <string>
#include <stdlib.h>
#include <qpdf/qpdf-config.h>
#ifndef HAVE_RANDOM
# define random rand
# define srandom srand
#endif

Pl_AES_PDF::Pl_AES_PDF(char const* identifier, Pipeline* next,
		       bool encrypt, unsigned char const key[key_size]) :
    Pipeline(identifier, next),
    encrypt(encrypt),
    cbc_mode(true),
    first(true),
    offset(0),
    nrounds(0)
{
    static int const keybits = 128;
    assert(key_size == KEYLENGTH(keybits));
    assert(sizeof(this->rk) / sizeof(uint32_t) == RKLENGTH(keybits));
    std::memcpy(this->key, key, key_size);
    std::memset(this->rk, 0, sizeof(this->rk));
    std::memset(this->inbuf, 0, this->buf_size);
    std::memset(this->outbuf, 0, this->buf_size);
    std::memset(this->cbc_block, 0, this->buf_size);
    if (encrypt)
    {
	this->nrounds = rijndaelSetupEncrypt(this->rk, this->key, keybits);
    }
    else
    {
	this->nrounds = rijndaelSetupDecrypt(this->rk, this->key, keybits);
    }
    assert(this->nrounds == NROUNDS(keybits));
}

Pl_AES_PDF::~Pl_AES_PDF()
{
    // nothing needed
}

void
Pl_AES_PDF::disableCBC()
{
    this->cbc_mode = false;
}

void
Pl_AES_PDF::write(unsigned char* data, int len)
{
    unsigned int bytes_left = len;
    unsigned char* p = data;

    while (bytes_left > 0)
    {
	if (this->offset == this->buf_size)
	{
	    flush(false);
	}

	unsigned int available = this->buf_size - this->offset;
	int bytes = (bytes_left < available ? bytes_left : available);
	bytes_left -= bytes;
	std::memcpy(this->inbuf + this->offset, p, bytes);
	this->offset += bytes;
	p += bytes;
    }
}

void
Pl_AES_PDF::finish()
{
    if (this->encrypt)
    {
	if (this->offset == this->buf_size)
	{
	    flush(false);
	}
	// Pad as described in section 3.5.1 of version 1.7 of the PDF
	// specification, including providing an entire block of padding
	// if the input was a multiple of 16 bytes.
	unsigned char pad = this->buf_size - this->offset;
	memset(this->inbuf + this->offset, pad, pad);
	this->offset = this->buf_size;
	flush(false);
    }
    else
    {
	if (this->offset != this->buf_size)
	{
	    throw std::runtime_error(
		"aes encrypted stream length was not a multiple of " +
		QUtil::int_to_string(this->buf_size) + " bytes (offset = " +
		QUtil::int_to_string(this->offset) + ")");
	}
	flush(true);
    }
    getNext()->finish();
}

void
Pl_AES_PDF::initializeVector()
{
    std::string seed_str;
    seed_str += QUtil::int_to_string((int)QUtil::get_current_time());
    seed_str += " QPDF aes random";
    MD5 m;
    m.encodeString(seed_str.c_str());
    MD5::Digest digest;
    m.digest(digest);
    assert(sizeof(digest) >= sizeof(unsigned int));
    unsigned int seed;
    memcpy((void*)(&seed), digest, sizeof(unsigned int));
    srandom(seed);
    for (unsigned int i = 0; i < this->buf_size; ++i)
    {
	this->cbc_block[i] = (unsigned char)((random() & 0xff0) >> 4);
    }
}

void
Pl_AES_PDF::flush(bool strip_padding)
{
    assert(this->offset == this->buf_size);

    if (first)
    {
	first = false;
	if (this->cbc_mode)
	{
	    if (encrypt)
	    {
		// Set cbc_block to a random initialization vector and
		// write it to the output stream
		initializeVector();
		getNext()->write(this->cbc_block, this->buf_size);
	    }
	    else
	    {
		// Take the first block of input as the initialization
		// vector.  There's nothing to write at this time.
		memcpy(this->cbc_block, this->inbuf, this->buf_size);
		this->offset = 0;
		return;
	    }
	}
    }

    if (this->encrypt)
    {
	if (this->cbc_mode)
	{
	    for (unsigned int i = 0; i < this->buf_size; ++i)
	    {
		this->inbuf[i] ^= this->cbc_block[i];
	    }
	}
	rijndaelEncrypt(this->rk, this->nrounds, this->inbuf, this->outbuf);
	if (this->cbc_mode)
	{
	    memcpy(this->cbc_block, this->outbuf, this->buf_size);
	}
    }
    else
    {
	rijndaelDecrypt(this->rk, this->nrounds, this->inbuf, this->outbuf);
	if (this->cbc_mode)
	{
	    for (unsigned int i = 0; i < this->buf_size; ++i)
	    {
		this->outbuf[i] ^= this->cbc_block[i];
	    }
	    memcpy(this->cbc_block, this->inbuf, this->buf_size);
	}
    }
    unsigned int bytes = this->buf_size;
    if (strip_padding)
    {
	unsigned char last = this->outbuf[this->buf_size - 1];
	if (last <= this->buf_size)
	{
	    bool strip = true;
	    for (unsigned int i = 1; i <= last; ++i)
	    {
		if (this->outbuf[this->buf_size - i] != last)
		{
		    strip = false;
		    break;
		}
	    }
	    if (strip)
	    {
		bytes -= last;
	    }
	}
    }
    getNext()->write(this->outbuf, bytes);
    this->offset = 0;
}
<|endoftext|>


<commit_before>#include "application.h"
#include "DHT.h"

DHT::DHT(uint8_t pin, uint8_t type) {
    _pin = pin;
    _type = type;
    _count = 6;
    firstreading = true;
}

void DHT::begin(void) {
    // set up the pins!
    pinMode(_pin, INPUT);
    digitalWrite(_pin, HIGH);
    _lastreadtime = 0;
}

//boolean S == Scale.  True == Farenheit; False == Celcius
float DHT::readTemperature(bool S) {
    float _f;

    if (read()) {
        switch (_type) {
            case DHT11:
                _f = data[2];

                if(S)
                    _f = convertCtoF(_f);

                return _f;

            case DHT22:
            case DHT21:
                _f = data[2] & 0x7F;
                _f *= 256;
                _f += data[3];
                _f /= 10;

                if (data[2] & 0x80)
                    _f *= -1;

                if(S)
                    _f = convertCtoF(_f);

                return _f;
        }
    }

    return NAN;
}

float DHT::convertCtoF(float c) {
    return c * 9 / 5 + 32;
}

float DHT::readHumidity(void) {
    float _f;
    if (read()) {
        switch (_type) {
            case DHT11:
                _f = data[0];
                return _f;

            case DHT22:
            case DHT21:
                _f = data[0];
                _f *= 256;
                _f += data[1];
                _f /= 10;
                return _f;
        }
    }

    return NAN;
}

bool DHT::read(void) {
    uint8_t laststate = HIGH;
    uint8_t counter = 0;
    uint8_t j = 0, i;
    unsigned long currenttime;

    currenttime = millis();
    if (currenttime < _lastreadtime) {
        // ie there was a rollover
        _lastreadtime = 0;
    }

    if (!firstreading && ((currenttime - _lastreadtime) < 2000)) {
        //delay(2000 - (currenttime - _lastreadtime));
        return true; // return last correct measurement
    }

    // pull the pin high and wait 250 milliseconds
    digitalWrite(_pin, HIGH);
    delay(250);

    firstreading = false;
    Serial.print("Currtime: "); Serial.println(currenttime);
    Serial.print(" Lasttime: "); Serial.println(_lastreadtime);
    _lastreadtime = millis();

    data[0] = data[1] = data[2] = data[3] = data[4] = 0;

    // now pull it low for ~20 milliseconds
    pinMode(_pin, OUTPUT);
    digitalWrite(_pin, LOW);
    delay(20);
    cli();
    digitalWrite(_pin, HIGH);
    delayMicroseconds(40);
    pinMode(_pin, INPUT);

    // read in timings
    for ( i=0; i< MAXTIMINGS; i++) {
        counter = 0;

        while (digitalRead(_pin) == laststate) {
            counter++;
            delayMicroseconds(1);

            if (counter == 255)
                break;
        }

        laststate = digitalRead(_pin);

        if (counter == 255)
            break;

        // ignore first 3 transitions
        if ((i >= 4) && (i%2 == 0)) {
            // shove each bit into the storage bytes
            data[j/8] <<= 1;

            if (counter > _count)
                data[j/8] |= 1;

            j++;
        }
    }

    sei();

    // check we read 40 bits and that the checksum matches
    if ((j >= 40) &&  (data[4] == ((data[0] + data[1] + data[2] + data[3]) & 0xFF)))
        return true;

    return false;
}
<commit_msg>fix for NAN values<commit_after>#include "application.h"
#include "DHT.h"

DHT::DHT(uint8_t pin, uint8_t type) {
    _pin = pin;
    _type = type;
    _count = 6;
    firstreading = true;
}

void DHT::begin(void) {
    // set up the pins!
    pinMode(_pin, INPUT);
    digitalWrite(_pin, HIGH);
    _lastreadtime = 0;
}

//boolean S == Scale.  True == Farenheit; False == Celcius
float DHT::readTemperature(bool S) {
    float _f;

    if (read()) {
        switch (_type) {
            case DHT11:
                _f = data[2];

                if(S)
                    _f = convertCtoF(_f);

                return _f;

            case DHT22:
            case DHT21:
                _f = data[2] & 0x7F;
                _f *= 256;
                _f += data[3];
                _f /= 10;

                if (data[2] & 0x80)
                    _f *= -1;

                if(S)
                    _f = convertCtoF(_f);

                return _f;
        }
    }

    return false;
}

float DHT::convertCtoF(float c) {
    return c * 9 / 5 + 32;
}

float DHT::readHumidity(void) {
    float _f;
    if (read()) {
        switch (_type) {
            case DHT11:
                _f = data[0];
                return _f;

            case DHT22:
            case DHT21:
                _f = data[0];
                _f *= 256;
                _f += data[1];
                _f /= 10;
                return _f;
        }
    }

    return false;
}

bool DHT::read(void) {
    uint8_t laststate = HIGH;
    uint8_t counter = 0;
    uint8_t j = 0, i;
    unsigned long currenttime;

    currenttime = millis();
    if (currenttime < _lastreadtime) {
        // ie there was a rollover
        _lastreadtime = 0;
    }

    if (!firstreading && ((currenttime - _lastreadtime) < 2000)) {
        //delay(2000 - (currenttime - _lastreadtime));
        return true; // return last correct measurement
    }

    // pull the pin high and wait 250 milliseconds
    digitalWrite(_pin, HIGH);
    delay(250);

    firstreading = false;
    Serial.print("Currtime: "); Serial.println(currenttime);
    Serial.print(" Lasttime: "); Serial.println(_lastreadtime);
    _lastreadtime = millis();

    data[0] = data[1] = data[2] = data[3] = data[4] = 0;

    // now pull it low for ~20 milliseconds
    pinMode(_pin, OUTPUT);
    digitalWrite(_pin, LOW);
    delay(20);
    cli();
    digitalWrite(_pin, HIGH);
    delayMicroseconds(40);
    pinMode(_pin, INPUT);

    // read in timings
    for ( i=0; i< MAXTIMINGS; i++) {
        counter = 0;

        while (digitalRead(_pin) == laststate) {
            counter++;
            delayMicroseconds(1);

            if (counter == 255)
                break;
        }

        laststate = digitalRead(_pin);

        if (counter == 255)
            break;

        // ignore first 3 transitions
        if ((i >= 4) && (i%2 == 0)) {
            // shove each bit into the storage bytes
            data[j/8] <<= 1;

            if (counter > _count)
                data[j/8] |= 1;

            j++;
        }
    }

    sei();

    // check we read 40 bits and that the checksum matches
    if ((j >= 40) &&  (data[4] == ((data[0] + data[1] + data[2] + data[3]) & 0xFF)))
        return true;

    return false;
}
<|endoftext|>


<commit_before>#ifdef _WIN32
#define BACKTRACE_WINDOWS
#define _CRT_SECURE_NO_WARNINGS
#define WIN32_LEAN_AND_MEAN
#define NOMINMAX
#define USE_DEBUGBREAK_TRAP
#else
// We assume we're on a posix platform if not windows
#define USE_SIGNAL_TRAP
#include <signal.h>
#endif

#include "library/backtrace.h"
#include "library/strings_format.h"

#include <mutex>
#ifdef BACKTRACE_LIBUNWIND
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <dlfcn.h>
#define UNW_LOCAL_ONLY
#include <libunwind.h>
#elif defined(BACKTRACE_WINDOWS)
#include <windows.h>
// windows.h must be included before DbgHelp.h
#include <DbgHelp.h>
#endif

#define MAX_SYMBOL_LENGTH 1000

namespace OpenApoc
{

#ifdef USE_DEBUGBREAK_TRAP
void debug_trap() { DebugBreak(); }
#endif

#ifdef USE_SIGNAL_TRAP
void debug_trap() { raise(SIGTRAP); }
#endif

#if defined(BACKTRACE_LIBUNWIND)

class libunwind_backtrace : public backtrace
{
  public:
	std::vector<unw_cursor_t> frames;

	static UString symbolicate(unw_cursor_t ip);

	~libunwind_backtrace() override = default;
};

up<backtrace> new_backtrace()
{

	unw_context_t ctx;
	unw_cursor_t cursor;
	unw_getcontext(&ctx);
	unw_init_local(&cursor, &ctx);
	auto bt = mkup<libunwind_backtrace>();
	while (unw_step(&cursor) > 0)
	{
		bt->frames.push_back(cursor);
	}
	return bt;
}

UString libunwind_backtrace::symbolicate(unw_cursor_t frame)
{
	Dl_info info;
	unw_word_t ip;
	unw_get_reg(&frame, UNW_REG_IP, &ip);
	if (ip == 0)
		return "  (null ip)";
	dladdr(reinterpret_cast<void *>(ip), &info);
	if (info.dli_sname)
	{
		return format("  0x%zx %s+0x%zx (%s)\n", static_cast<uintptr_t>(ip), info.dli_sname,
		              static_cast<uintptr_t>(ip) - reinterpret_cast<uintptr_t>(info.dli_saddr),
		              info.dli_fname);
	}
	// If dladdr() failed, try libunwind
	unw_word_t offsetInFn;
	char fnName[MAX_SYMBOL_LENGTH];
	if (!unw_get_proc_name(&frame, fnName, MAX_SYMBOL_LENGTH, &offsetInFn))
	{
		return format("  0x%zx %s+0x%zx (%s)\n", static_cast<uintptr_t>(ip), fnName, offsetInFn,
		              info.dli_fname);
	}
	else
		return format("  0x%zx\n", static_cast<uintptr_t>(ip));
}

std::ostream &operator<<(std::ostream &lhs, const backtrace &bt)
{
	const auto *unwind_backtrace = dynamic_cast<const libunwind_backtrace *>(&bt);
	if (!unwind_backtrace)
	{
		lhs << "invalid backtrace object";
		return lhs;
	}

	for (const auto &frame : unwind_backtrace->frames)
	{
		lhs << unwind_backtrace->symbolicate(frame) << "\n";
	}
	return lhs;
}

#elif defined(BACKTRACE_WINDOWS)
#define MAX_STACK_FRAMES 100

class win32_backtrace : public backtrace
{
  public:
	std::vector<void *> ip;
	~win32_backtrace() override = default;
	static UString symbolicate(const void *ip);
};

static bool process_initialised = false;
static HANDLE process;

static void init_process()
{
	if (process_initialised)
		return;

	process = GetCurrentProcess();
	SymInitialize(process, NULL, true);
	process_initialised = true;
}

up<backtrace> new_backtrace()
{
	unsigned int frames;
	void *ip[MAX_STACK_FRAMES];

	auto backtrace_object = mkup<win32_backtrace>();

	init_process();

	if (!process)
	{
		return backtrace_object;
	}

	/* Skip 1 frame (the get_backtrace function itself) */
	frames = CaptureStackBackTrace(1, MAX_STACK_FRAMES, ip, NULL);

	for (unsigned int frame = 0; frame < frames; frame++)
	{
		backtrace_object->ip.push_back(ip[frame]);
	}

	return backtrace_object;
}

UString win32_backtrace::symbolicate(const void *ip)
{
	SYMBOL_INFO *sym;
	UString str;

	sym = (SYMBOL_INFO *)calloc(sizeof(SYMBOL_INFO) + MAX_SYMBOL_LENGTH * (sizeof(char)), 1);
	if (!sym)
	{
		return "";
	}
	sym->MaxNameLen = MAX_SYMBOL_LENGTH;
	sym->SizeOfStruct = sizeof(SYMBOL_INFO);

	SymFromAddr(process, (DWORD64)(ip), 0, sym);
	str = format("  0x%p %s+0x%Ix\n", ip, sym->Name, (uintptr_t)ip - (uintptr_t)sym->Address);

	free(sym);
	return str;
}

std::ostream &operator<<(std::ostream &lhs, const backtrace &bt)
{
	const auto *backtrace_object = dynamic_cast<const win32_backtrace *>(&bt);
	if (!backtrace_object)
	{
		lhs << "invalid backtrace object";
		return lhs;
	}

	for (const auto &frame : backtrace_object->ip)
	{
		lhs << backtrace_object->symbolicate(frame) << "\n";
	}
	return lhs;
}
#else
#warning no backtrace enabled for this platform
class null_backtrace : public backtrace
{
  public:
	~null_backtrace() override = default;
};

up<backtrace> new_backtrace()
{
	// TODO: Other platform backtrace?
	return mkup<null_backtrace>();
}

std::ostream &operator<<(std::ostream &lhs, const backtrace &bt)
{
	const auto *backtrace_object = dynamic_cast<const null_backtrace *>(&bt);
	if (!backtrace_object)
	{
		lhs << "invalid backtrace object";
		return lhs;
	}

	lhs << "backtrace disabled";
	return lhs;
}

#endif

} // namespace OpenApoc
<commit_msg>Fixup windows backtrace formatting<commit_after>#ifdef _WIN32
#define BACKTRACE_WINDOWS
#define _CRT_SECURE_NO_WARNINGS
#define WIN32_LEAN_AND_MEAN
#define NOMINMAX
#define USE_DEBUGBREAK_TRAP
#else
// We assume we're on a posix platform if not windows
#define USE_SIGNAL_TRAP
#include <signal.h>
#endif

#include "library/backtrace.h"
#include "library/strings_format.h"

#include <mutex>
#ifdef BACKTRACE_LIBUNWIND
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <dlfcn.h>
#define UNW_LOCAL_ONLY
#include <libunwind.h>
#elif defined(BACKTRACE_WINDOWS)
#include <windows.h>
// windows.h must be included before DbgHelp.h
#include <DbgHelp.h>
#endif

#define MAX_SYMBOL_LENGTH 1000

namespace OpenApoc
{

#ifdef USE_DEBUGBREAK_TRAP
void debug_trap() { DebugBreak(); }
#endif

#ifdef USE_SIGNAL_TRAP
void debug_trap() { raise(SIGTRAP); }
#endif

#if defined(BACKTRACE_LIBUNWIND)

class libunwind_backtrace : public backtrace
{
  public:
	std::vector<unw_cursor_t> frames;

	static UString symbolicate(unw_cursor_t ip);

	~libunwind_backtrace() override = default;
};

up<backtrace> new_backtrace()
{

	unw_context_t ctx;
	unw_cursor_t cursor;
	unw_getcontext(&ctx);
	unw_init_local(&cursor, &ctx);
	auto bt = mkup<libunwind_backtrace>();
	while (unw_step(&cursor) > 0)
	{
		bt->frames.push_back(cursor);
	}
	return bt;
}

UString libunwind_backtrace::symbolicate(unw_cursor_t frame)
{
	Dl_info info;
	unw_word_t ip;
	unw_get_reg(&frame, UNW_REG_IP, &ip);
	if (ip == 0)
		return "  (null ip)";
	dladdr(reinterpret_cast<void *>(ip), &info);
	if (info.dli_sname)
	{
		return format("  0x%zx %s+0x%zx (%s)\n", static_cast<uintptr_t>(ip), info.dli_sname,
		              static_cast<uintptr_t>(ip) - reinterpret_cast<uintptr_t>(info.dli_saddr),
		              info.dli_fname);
	}
	// If dladdr() failed, try libunwind
	unw_word_t offsetInFn;
	char fnName[MAX_SYMBOL_LENGTH];
	if (!unw_get_proc_name(&frame, fnName, MAX_SYMBOL_LENGTH, &offsetInFn))
	{
		return format("  0x%zx %s+0x%zx (%s)\n", static_cast<uintptr_t>(ip), fnName, offsetInFn,
		              info.dli_fname);
	}
	else
		return format("  0x%zx\n", static_cast<uintptr_t>(ip));
}

std::ostream &operator<<(std::ostream &lhs, const backtrace &bt)
{
	const auto *unwind_backtrace = dynamic_cast<const libunwind_backtrace *>(&bt);
	if (!unwind_backtrace)
	{
		lhs << "invalid backtrace object";
		return lhs;
	}

	for (const auto &frame : unwind_backtrace->frames)
	{
		lhs << unwind_backtrace->symbolicate(frame) << "\n";
	}
	return lhs;
}

#elif defined(BACKTRACE_WINDOWS)
#define MAX_STACK_FRAMES 100

class win32_backtrace : public backtrace
{
  public:
	std::vector<void *> ip;
	~win32_backtrace() override = default;
	static UString symbolicate(const void *ip);
};

static bool process_initialised = false;
static HANDLE process;

static void init_process()
{
	if (process_initialised)
		return;

	process = GetCurrentProcess();
	SymInitialize(process, NULL, true);
	process_initialised = true;
}

up<backtrace> new_backtrace()
{
	unsigned int frames;
	void *ip[MAX_STACK_FRAMES];

	auto backtrace_object = mkup<win32_backtrace>();

	init_process();

	if (!process)
	{
		return backtrace_object;
	}

	/* Skip 1 frame (the get_backtrace function itself) */
	frames = CaptureStackBackTrace(1, MAX_STACK_FRAMES, ip, NULL);

	for (unsigned int frame = 0; frame < frames; frame++)
	{
		backtrace_object->ip.push_back(ip[frame]);
	}

	return backtrace_object;
}

UString win32_backtrace::symbolicate(const void *ip)
{
	SYMBOL_INFO *sym;
	UString str;

	sym = (SYMBOL_INFO *)calloc(sizeof(SYMBOL_INFO) + MAX_SYMBOL_LENGTH * (sizeof(char)), 1);
	if (!sym)
	{
		return "";
	}
	sym->MaxNameLen = MAX_SYMBOL_LENGTH;
	sym->SizeOfStruct = sizeof(SYMBOL_INFO);

	SymFromAddr(process, (DWORD64)(ip), 0, sym);
	str = format("  0x%p %s+0x%x\n", ip, sym->Name, (uintptr_t)ip - (uintptr_t)sym->Address);

	free(sym);
	return str;
}

std::ostream &operator<<(std::ostream &lhs, const backtrace &bt)
{
	const auto *backtrace_object = dynamic_cast<const win32_backtrace *>(&bt);
	if (!backtrace_object)
	{
		lhs << "invalid backtrace object";
		return lhs;
	}

	for (const auto &frame : backtrace_object->ip)
	{
		lhs << backtrace_object->symbolicate(frame) << "\n";
	}
	return lhs;
}
#else
#warning no backtrace enabled for this platform
class null_backtrace : public backtrace
{
  public:
	~null_backtrace() override = default;
};

up<backtrace> new_backtrace()
{
	// TODO: Other platform backtrace?
	return mkup<null_backtrace>();
}

std::ostream &operator<<(std::ostream &lhs, const backtrace &bt)
{
	const auto *backtrace_object = dynamic_cast<const null_backtrace *>(&bt);
	if (!backtrace_object)
	{
		lhs << "invalid backtrace object";
		return lhs;
	}

	lhs << "backtrace disabled";
	return lhs;
}

#endif

} // namespace OpenApoc
<|endoftext|>


<commit_before>/*
 * Copyright 2013 Gustaf Räntilä
 *
 * 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 <q/thread.hpp>
#include <q/pp.hpp>

#ifdef LIBQ_ON_WINDOWS
  // todo
#elif defined( LIBQ_ON_OSX )
#	include <sys/types.h>
#	include <sys/sysctl.h>
#elif defined( LIBQ_ON_POSIX )
#	include <pthread.h>
#endif

#define AT_LEAST_ONE( n ) \
	std::min< std::size_t >( static_cast< std::size_t >( n ), 1 )

namespace q {

std::size_t fallback_cores( )
{
	return AT_LEAST_ONE( std::thread::hardware_concurrency( ) );
}

// TODO: Move and change implementation. This is a decent default, nothing else
std::size_t hard_cores( )
{
#if defined( LIBQ_ON_OSX )
	int count;
	size_t count_len = sizeof( count );
	::sysctlbyname( "hw.physicalcpu_max", &count, &count_len, NULL, 0 );
	return AT_LEAST_ONE( count );
#else
	return fallback_cores( );
#endif
}

std::size_t soft_cores( )
{
#if defined( LIBQ_ON_OSX )
	int count;
	size_t count_len = sizeof( count );
	::sysctlbyname( "hw.logicalcpu_max", &count, &count_len, NULL, 0 );
	return AT_LEAST_ONE( count );
#else
	return fallback_cores( );
#endif
}

namespace detail {

void set_thread_name( const std::string& name )
{
#ifdef LIBQ_ON_POSIX

#ifndef LIBQ_ON_OSX
	auto tid = pthread_self( );
#endif // LIBQ_ON_OSX

#if defined( LIBQ_ON_OSX )
	pthread_setname_np( name.c_str( ) );
#elif defined( LIBQ_ON_BSD )
	pthread_set_name_np( tid, name.c_str( ) );
#else
	pthread_setname_np( tid, name.c_str( ) );
#endif

#endif // LIBQ_ON_POSIX
}

std::string get_thread_name( )
{
#ifdef LIBQ_ON_POSIX

	auto tid = pthread_self( );
	char namebuf[ NAME_MAX ];

#if defined( LIBQ_ON_OSX )
	pthread_getname_np( tid, namebuf, NAME_MAX );
	return namebuf;
#elif defined( LIBQ_ON_BSD )
	pthread_get_name_np( tid, namebuf, NAME_MAX );
	return namebuf;
#else
	pthread_getname_np( tid, namebuf, NAME_MAX );
	return namebuf;
#endif

#endif // LIBQ_ON_POSIX
}

} // namespace detail

/*
thread* thread::current( )
{
	// TODO: TLS Lookup, or nullptr
	return nullptr;
}
*/

} // namespace q
<commit_msg>Thread name compilation fix for linux<commit_after>/*
 * Copyright 2013 Gustaf Räntilä
 *
 * 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 <q/thread.hpp>
#include <q/pp.hpp>

#ifdef LIBQ_ON_WINDOWS
  // todo
#elif defined( LIBQ_ON_OSX )
#	include <sys/types.h>
#	include <sys/sysctl.h>
#elif defined( LIBQ_ON_POSIX )
#	include <pthread.h>
#endif

#define AT_LEAST_ONE( n ) \
	std::min< std::size_t >( static_cast< std::size_t >( n ), 1 )

namespace q {

std::size_t fallback_cores( )
{
	return AT_LEAST_ONE( std::thread::hardware_concurrency( ) );
}

// TODO: Move and change implementation. This is a decent default, nothing else
std::size_t hard_cores( )
{
#if defined( LIBQ_ON_OSX )
	int count;
	size_t count_len = sizeof( count );
	::sysctlbyname( "hw.physicalcpu_max", &count, &count_len, NULL, 0 );
	return AT_LEAST_ONE( count );
#else
	return fallback_cores( );
#endif
}

std::size_t soft_cores( )
{
#if defined( LIBQ_ON_OSX )
	int count;
	size_t count_len = sizeof( count );
	::sysctlbyname( "hw.logicalcpu_max", &count, &count_len, NULL, 0 );
	return AT_LEAST_ONE( count );
#else
	return fallback_cores( );
#endif
}

namespace detail {

void set_thread_name( const std::string& name )
{
#ifdef LIBQ_ON_POSIX

#ifndef LIBQ_ON_OSX
	auto tid = pthread_self( );
#endif // LIBQ_ON_OSX

#if defined( LIBQ_ON_OSX )
	pthread_setname_np( name.c_str( ) );
#elif defined( LIBQ_ON_BSD )
	pthread_set_name_np( tid, name.c_str( ) );
#else
	pthread_setname_np( tid, name.c_str( ) );
#endif

#endif // LIBQ_ON_POSIX
}

std::string get_thread_name( )
{
#ifdef LIBQ_ON_POSIX

#	ifdef LIBQ_ON_LINUX
#		define PTHREAD_NAME_MAX 16
#	else
#		define PTHREAD_NAME_MAX NAME_MAX
#	endif

	auto tid = pthread_self( );
	char namebuf[ PTHREAD_NAME_MAX ];

#if defined( LIBQ_ON_OSX )
	pthread_getname_np( tid, namebuf, PTHREAD_NAME_MAX );
	return namebuf;
#elif defined( LIBQ_ON_BSD )
	pthread_get_name_np( tid, namebuf, PTHREAD_NAME_MAX );
	return namebuf;
#else
	pthread_getname_np( tid, namebuf, PTHREAD_NAME_MAX );
	return namebuf;
#endif

#endif // LIBQ_ON_POSIX
}

} // namespace detail

/*
thread* thread::current( )
{
	// TODO: TLS Lookup, or nullptr
	return nullptr;
}
*/

} // namespace q
<|endoftext|>