<commit_before>#include "request.h"

#include <boost/algorithm/string.hpp>

using namespace std;
namespace alg = boost::algorithm;
namespace sys = boost::system;

namespace wsgi_boost
{
	boost::system::error_code Request::parse_header()
	{
		string header;
		sys::error_code ec = m_connection.read_header(header);
		if (ec)
			return ec;
		istringstream iss{ header };
		string line;
		getline(iss, line);
		line.pop_back();
		vector<string> parts;
		alg::split(parts, line, alg::is_space(), alg::token_compress_on);
		if (parts.size() != 3)
			return sys::error_code(sys::errc::bad_message, sys::system_category());
		method = parts[0];
		path = parts[1];
		http_version = parts[2];
		while (true)
		{
			getline(iss, line);
			if (!iss.good())
				break;
			line.pop_back();
			size_t pos = line.find(':');
			if (pos != string::npos)
			{
				string header = alg::trim_copy(line.substr(0, pos));
				string value = alg::trim_copy(line.substr(pos + 1));
				if (headers.find(header) == headers.end())
				{
					headers.emplace(header, value);
				}
				else
				{
					headers[header] += "," + value;
				}
			}
		}
		if (method == "POST" || method == "PUT" || method == "PATCH")
		{
			try
			{
				long long cl = stoll(get_header("Content-Length"));
				m_connection.post_content_length(cl);
			}
			catch (const logic_error&)
			{
				return sys::error_code(sys::errc::invalid_argument, sys::system_category());
			}
		}
		else
		{
			m_connection.post_content_length(-1);
		}
		return sys::error_code(sys::errc::success, sys::system_category());
	}

	bool Request::check_header(const string& header, const string& value) const
	{
		auto it = headers.find(header);
		return (it != headers.end()) && boost::algorithm::icontains(it->second, value);
	}

	string Request::get_header(const string& header) const
	{
		auto it = headers.find(header);
		return it != headers.end() ? it->second : string();
	}

	bool Request::keep_alive() const
	{
		return http_version == "HTTP/1.1" && !check_header("Connection", "close");
	}

	Connection& Request::connection() const
	{
		return m_connection;
	}

	string Request::remote_address() const
	{
		return m_connection.socket()->remote_endpoint().address().to_string();
	}

	unsigned short Request::remote_port() const
	{
		return m_connection.socket()->remote_endpoint().port();
	}
}
<commit_msg>Fix Connection: keep-alive handling<commit_after>#include "request.h"

#include <boost/algorithm/string.hpp>

using namespace std;
namespace alg = boost::algorithm;
namespace sys = boost::system;

namespace wsgi_boost
{
	boost::system::error_code Request::parse_header()
	{
		string header;
		sys::error_code ec = m_connection.read_header(header);
		if (ec)
			return ec;
		istringstream iss{ header };
		string line;
		getline(iss, line);
		line.pop_back();
		vector<string> parts;
		alg::split(parts, line, alg::is_space(), alg::token_compress_on);
		if (parts.size() != 3)
			return sys::error_code(sys::errc::bad_message, sys::system_category());
		method = parts[0];
		path = parts[1];
		http_version = parts[2];
		while (true)
		{
			getline(iss, line);
			if (!iss.good())
				break;
			line.pop_back();
			size_t pos = line.find(':');
			if (pos != string::npos)
			{
				string header = alg::trim_copy(line.substr(0, pos));
				string value = alg::trim_copy(line.substr(pos + 1));
				if (headers.find(header) == headers.end())
				{
					headers.emplace(header, value);
				}
				else
				{
					headers[header] += "," + value;
				}
			}
		}
		if (method == "POST" || method == "PUT" || method == "PATCH")
		{
			try
			{
				long long cl = stoll(get_header("Content-Length"));
				m_connection.post_content_length(cl);
			}
			catch (const logic_error&)
			{
				return sys::error_code(sys::errc::invalid_argument, sys::system_category());
			}
		}
		else
		{
			m_connection.post_content_length(-1);
		}
		return sys::error_code(sys::errc::success, sys::system_category());
	}

	bool Request::check_header(const string& header, const string& value) const
	{
		auto it = headers.find(header);
		return (it != headers.end()) && boost::algorithm::icontains(it->second, value);
	}

	string Request::get_header(const string& header) const
	{
		auto it = headers.find(header);
		return it != headers.end() ? it->second : string();
	}

	bool Request::keep_alive() const
	{
		return check_header("Connection", "keep-alive") || (http_version == "HTTP/1.1" && !check_header("Connection", "close"));
	}

	Connection& Request::connection() const
	{
		return m_connection;
	}

	string Request::remote_address() const
	{
		return m_connection.socket()->remote_endpoint().address().to_string();
	}

	unsigned short Request::remote_port() const
	{
		return m_connection.socket()->remote_endpoint().port();
	}
}
<|endoftext|>


<commit_before>#ifndef PCL_TRACKING_IMPL_COHERENCE_H_
#define PCL_TRACKING_IMPL_COHERENCE_H_

namespace pcl
{
  namespace tracking
  {

    template <typename PointInT> double
    PointCoherence<PointInT>::compute (PointInT &source, PointInT &target)
    {
      return computeCoherence (source, target);
    }

    template <typename PointInT> double
    PointCloudCoherence<PointInT>::calcPointCoherence (PointInT &source, PointInT &target)
    {
      double val = 1.0;
      for (size_t i = 0; i < point_coherences_.size (); i++)\
      {
        PointCoherencePtr coherence = point_coherences_[i];
        val *= coherence->compute (source, target);
      }
      return val;
    }

    template <typename PointInT> bool
    PointCloudCoherence<PointInT>::initCompute ()
    {
      if (PCLBase<PointInT>::initCompute ())
      {
        PCL_ERROR ("[pcl::%s::initCompute] PCLBase::Init failed.\n", getClassName ().c_str ());
        deinitCompute ();
        return (false);
      }

      if (!target_input_ || target_input_->points.empty ())
      {
        PCL_ERROR ("[pcl::%s::compute] target_input_ is empty!\n", getClassName ().c_str ());
        deinitCompute ();
        return false;
      }

      return true;

    }

    template <typename PointInT> double
    PointCloudCoherence<PointInT>::compute ()
    {
      if (initCompute ())
      {
        PCL_ERROR ("[pcl::%s::compute] Init failed.\n", getClassName ().c_str ());
        return (false);
      }

      return computeCoherence ();
    }
  }
}

#endif
<commit_msg>fix boolean computation<commit_after>#ifndef PCL_TRACKING_IMPL_COHERENCE_H_
#define PCL_TRACKING_IMPL_COHERENCE_H_

namespace pcl
{
  namespace tracking
  {

    template <typename PointInT> double
    PointCoherence<PointInT>::compute (PointInT &source, PointInT &target)
    {
      return computeCoherence (source, target);
    }

    template <typename PointInT> double
    PointCloudCoherence<PointInT>::calcPointCoherence (PointInT &source, PointInT &target)
    {
      double val = 1.0;
      for (size_t i = 0; i < point_coherences_.size (); i++)\
      {
        PointCoherencePtr coherence = point_coherences_[i];
        val *= coherence->compute (source, target);
      }
      return val;
    }

    template <typename PointInT> bool
    PointCloudCoherence<PointInT>::initCompute ()
    {
      if (!PCLBase<PointInT>::initCompute ())
      {
        PCL_ERROR ("[pcl::%s::initCompute] PCLBase::Init failed.\n", getClassName ().c_str ());
        deinitCompute ();
        return (false);
      }

      if (!target_input_ || target_input_->points.empty ())
      {
        PCL_ERROR ("[pcl::%s::compute] target_input_ is empty!\n", getClassName ().c_str ());
        deinitCompute ();
        return false;
      }

      return true;

    }

    template <typename PointInT> double
    PointCloudCoherence<PointInT>::compute ()
    {
      if (!initCompute ())
      {
        PCL_ERROR ("[pcl::%s::compute] Init failed.\n", getClassName ().c_str ());
        return (false);
      }

      return computeCoherence ();
    }
  }
}

#endif
<|endoftext|>


<commit_before>#include "ARVersion.h"
#if !defined(__CINT__) || defined(__MAKECINT__)
#include "AliCDBManager.h"
#include "AliCDBStorage.h"
#include "AliCDBId.h"
#include "AliCDBMetaData.h"
#include "AliGeomManager.h"
#include "AliMC.h"
#include <TROOT.h>
#include "AliRun.h"
#include <TGeoManager.h>
#include <TString.h>
#include <TInterpreter.h>
#endif

void UpdateCDBIdealGeom(const char* cdbUri, const char* cfgFile){
  // Produce the ideal geometry and store it in the specified CDB
  // The second argument allows to specify the config file to be used
  // in particular for giving the choice to generate either a full or
  // a partial geometry.
  //

  AliCDBManager* cdb = AliCDBManager::Instance();
  // we set the default storage to the repository because some dets require
  // already at the time of geometry creation to find calibration objects in the cdb
  AliCDBStorage* storage = 0;
  if(!cdb->IsDefaultStorageSet()) cdb->SetDefaultStorage("local://$ALICE_ROOT/OCDB");
  storage = cdb->GetStorage(cdbUri);
  if(!storage)
  {
    Printf("unable to create valid storage from: %s", cdbUri);
    return;
  }
  cdb->SetRun(0);
  AliCDBId id("GRP/Geometry/Data",0,AliCDBRunRange::Infinity());
  AliCDBMetaData *md= new AliCDBMetaData();

  // Get root and AliRoot versions
  const char* rootv = gROOT->GetVersion();
  TString av(ALIROOT_SVN_BRANCH);
  Int_t revnum = ALIROOT_SVN_REVISION;

  Printf("root version: %s.  AliRoot %s, revision number %d",rootv,av.Data(),revnum);

  md->SetAliRootVersion(av.Data());
  md->SetComment(Form("Geometry produced with root version %s and AliRoot %s, revision number %d",rootv,av.Data(),revnum));

  gROOT->LoadMacro(cfgFile);
  gInterpreter->ProcessLine(gAlice->GetConfigFunction());
  gAlice->GetMCApp()->Init();

  if(!gGeoManager){
    Printf("Unable to produce a valid geometry to be put in the CDB!");
    return;
  }
  gGeoManager->DefaultColors(); // assign default colors according to Z of material
  // (many colors turned into dark gray nuances some time ago, when the root palette was changed)

  Printf("Storing in CDB geometry produced with root version %s and AliRoot version %s",rootv,av.Data());
  storage->Put(gGeoManager,id,md);
  // This is to allow macros lauched after this one in the same session to find the
  // newly produced geometry.
  storage->QueryCDB(cdb->GetRun());

}

<commit_msg>modified to upload an unlocked ideal geometry (thanks to Ruben)<commit_after>#include "ARVersion.h"
#if !defined(__CINT__) || defined(__MAKECINT__)
#include "AliCDBManager.h"
#include "AliCDBStorage.h"
#include "AliCDBId.h"
#include "AliCDBMetaData.h"
#include "AliGeomManager.h"
#include "AliMC.h"
#include <TROOT.h>
#include "AliRun.h"
#include <TGeoManager.h>
#include <TString.h>
#include <TInterpreter.h>
#endif

void UpdateCDBIdealGeom(const char* cdbUri, const char* cfgFile){
	// Produce the ideal geometry and store it in the specified CDB
	// The second argument allows to specify the config file to be used
	// in particular for giving the choice to generate either a full or
	// a partial geometry.
	//

	AliCDBManager* cdb = AliCDBManager::Instance();
	// we set the default storage to the repository because some dets require
	// already at the time of geometry creation to find calibration objects in the cdb
	AliCDBStorage* storage = 0;
	if(!cdb->IsDefaultStorageSet()) cdb->SetDefaultStorage("local://$ALICE_ROOT/OCDB");
	storage = cdb->GetStorage(cdbUri);
	if(!storage)
	{
		Printf("unable to create valid storage from: %s", cdbUri);
		return;
	}
	cdb->SetRun(0);
	AliCDBId id("GRP/Geometry/Data",0,AliCDBRunRange::Infinity());
	AliCDBMetaData *md= new AliCDBMetaData();

	// Get root and AliRoot versions
	const char* rootv = gROOT->GetVersion();
	TString av(ALIROOT_SVN_BRANCH);
	Int_t revnum = ALIROOT_SVN_REVISION;

	Printf("root version: %s.  AliRoot %s, revision number %d",rootv,av.Data(),revnum);

	md->SetAliRootVersion(av.Data());
	md->SetComment(Form("Geometry produced with root version %s and AliRoot %s, revision number %d",rootv,av.Data(),revnum));
	md->AddDateToComment();

	//gSystem->Exec("if [ -e geometry.root ]; then \necho deleting existing geometry.root \nrm -rf geometry.root \nfi");
	if(!gSystem->AccessPathName("geometry.root")){
		Printf("Deleting existing \"geometry.root\"");
		gSystem->Exec("rm -rf geometry.root");
	}

	gROOT->LoadMacro(cfgFile);
	gInterpreter->ProcessLine(gAlice->GetConfigFunction());

	gAlice->GetMCApp()->Init();

	if(!gGeoManager){
		Printf("Unable to produce a valid geometry to be put in the CDB!");
		return;
	}

	/*
	if (gSystem->Exec("if [ ! -e geometry.root ]; then \n return 1  \nfi")) {
		Printf("Did not find freshly written geometry.root file");
		return;
	} */
	if(gSystem->AccessPathName("geometry.root")){
		Printf("Did not find freshly written \"geometry.root\" file. Exiting ...");
		return;
	}

	Printf("Reloading freshly written geometry.root file");
	if (TGeoManager::IsLocked()) TGeoManager::UnlockGeometry();
	AliGeomManager::LoadGeometry("geometry.root");

	gGeoManager->DefaultColors(); // assign default colors according to Z of material
	// (many colors turned into dark gray nuances some time ago, when the root palette was changed)

	Printf("Storing in CDB geometry produced with root version %s and AliRoot version %s",rootv,av.Data());
	storage->Put(gGeoManager,id,md);
	// This is to allow macros lauched after this one in the same session to find the
	// newly produced geometry.
	storage->QueryCDB(cdb->GetRun());

}

<|endoftext|>


<commit_before>#pragma once

namespace But
{
namespace Threading
{
namespace detail
{

struct Command
{
  virtual ~Command() { }
  virtual void run() = 0;
};

template<typename F, typename Policy>
struct Task final: public Command
{
  explicit Task(F f): f_{ std::move(f) } { }

  virtual void run() noexcept
  {
    try
    {
      const auto tag = static_cast<value_type const*>(nullptr);
      runAndSetValue(tag);
    }
    catch(...)
    {
      promise_.set_exception( Policy::currentException() );
    }
  }

  void runAndSetValue(void const*)
  {
    f_();
    promise_.set_value();
  }

  template<typename Ignore>
    void runAndSetValue(Ignore const*)
    {
      promise_.set_value( f_() );
    }

  F f_;
  typename Policy::template promise_type<decltype(f_())> promise_;

  using value_type = typename std::decay<decltype(f_())>::type;
};

}
}
}
<commit_msg>indentation fix<commit_after>#pragma once

namespace But
{
namespace Threading
{
namespace detail
{

struct Command
{
  virtual ~Command() { }
  virtual void run() = 0;
};

template<typename F, typename Policy>
struct Task final: public Command
{
  explicit Task(F f): f_{ std::move(f) } { }

  virtual void run() noexcept
  {
    try
    {
      const auto tag = static_cast<value_type const*>(nullptr);
      runAndSetValue(tag);
    }
    catch(...)
    {
      promise_.set_exception( Policy::currentException() );
    }
  }

  void runAndSetValue(void const*)
  {
    f_();
    promise_.set_value();
  }

  template<typename Ignore>
  void runAndSetValue(Ignore const*)
  {
    promise_.set_value( f_() );
  }

  F f_;
  typename Policy::template promise_type<decltype(f_())> promise_;

  using value_type = typename std::decay<decltype(f_())>::type;
};

}
}
}
<|endoftext|>


<commit_before>/*********************************************************************
* PulseSensor library
* a class to control a pulse sensor connected to one of the pins
* attached to one of the external interrupt.
* version 0.3 BETA 19/09/2015
* Author: Jaime García  @peninquen
* Licence: Apache License Version 2.0.
*
**********************************************************************/
//------------------------------------------------------------------------------
// Poner PULSE_DEBUG a 1 para depuración.

#define PULSE_DEBUG  0

//------------------------------------------------------------------------------
// Debug directives

#if PULSE_DEBUG
#   define PULSE_DEBUG_PRINT(...)    Serial.print(__VA_ARGS__)
#   define PULSE_DEBUG_PRINTLN(...)  Serial.println(__VA_ARGS__)
#else
#   define PULSE_DEBUG_PRINT(...)
#   define PULSE_DEBUG_PRINTLN(...)
#endif

#include "PulseSensor.h"

volatile unsigned int _COUNTER;
volatile unsigned long _startTime;
volatile unsigned long _finishTime;

void detectPulseISR() {
  _COUNTER++;
  _startTime = _finishTime;
  _finishTime = micros();

}

/***************************************************************************/
/*constructor*/

PulseSensor::PulseSensor() {
}

/***************************************************************************/
/*Setup variables and initialize interrupts*/

void PulseSensor::begin(int pulsePin, unsigned int interval, float rateConversion, float acumConversion) {
  _interval = interval;
  _rateConversion = rateConversion;
  _acumConversion = acumConversion;
  _processTime = millis();       // start timer
  _flag = false;
  _acumCounter = 0;
  _counter = 0;                  // reset instance counter
  _COUNTER = 0;                  // reset global counter
  _startTime = 0;
  _finishTime = micros();

  PULSE_DEBUG_PRINT(F("Pulse Pin:")); PULSE_DEBUG_PRINT(pulsePin);
  PULSE_DEBUG_PRINT(F("  INT")); PULSE_DEBUG_PRINTLN(digitalPinToInterrupt(pulsePin));
  pinMode(pulsePin, INPUT_PULLUP); //
  attachInterrupt(digitalPinToInterrupt(pulsePin), detectPulseISR, RISING);
}

/***************************************************************************/
/*check interval and update data, include at least one time inside loop cycle*/
void PulseSensor::refreshData() {
  unsigned long nowTime = millis();
  if (nowTime - _processTime >= _interval) {
    byte oldSREG = SREG;
    noInterrupts();
    _counter = _COUNTER;
    _COUNTER = 0;
    _acumCounter += _counter;  // increase counter
    _processTime = nowTime;     //stamp process time
    _flag = true;
    SREG = oldSREG;            //enable last state interrupts register
  }
}

/***************************************************************************/
/*read sensor value[units per second]*/

float PulseSensor::read() {
  _flag = false;
  return (float)(_counter * 1000.0 / _rateConversion / _interval);
}

/***************************************************************************/
/*read instant value in defined unitsM; overflow errors after long inactivity time */
float PulseSensor::readInstant() {
  unsigned long period;
  byte oldSREG = SREG;
  noInterrupts();
  period = micros() - _finishTime;
  if (period < _finishTime - _startTime) period = _finishTime - _startTime;
  if (period> 0xF8000000){  //  > 61 minutes
    _finishtime += 0xF0000000); //increase
    _startTime += 0xC0000000);
  }
  SREG = oldSREG;            //enable last state interrupts register
  return (float)1000 / _rateConversion / period;
}

/***************************************************************************/
/*read acumulated value [units]*/

float PulseSensor::readAcum() {
  return (float)(_acumCounter / _acumConversion );
}

/***************************************************************************/
/*read instance partial pulse counter*/

unsigned int PulseSensor::readPulses() {
  _flag = false;
  return _counter;
}

/***************************************************************************/
/*read instance acumulated pulse counter*/

unsigned long PulseSensor::readAcumPulses() {
  return _acumCounter;
}

/***************************************************************************/
/*reset acumulated pulse counter */

void PulseSensor::resetAcum() {
  _acumCounter = 0;
}

/***************************************************************************/
/* Is new data available */

boolean PulseSensor::available() {
  refreshData();
  return _flag;
}
<commit_msg>fix bug in readInstant()<commit_after>/*********************************************************************
* PulseSensor library
* a class to control a pulse sensor connected to one of the pins
* attached to one of the external interrupt.
* version 0.3 BETA 19/09/2015
* Author: Jaime García  @peninquen
* Licence: Apache License Version 2.0.
*
**********************************************************************/
//------------------------------------------------------------------------------
// Poner PULSE_DEBUG a 1 para depuración.

#define PULSE_DEBUG  0

//------------------------------------------------------------------------------
// Debug directives

#if PULSE_DEBUG
#   define PULSE_DEBUG_PRINT(...)    Serial.print(__VA_ARGS__)
#   define PULSE_DEBUG_PRINTLN(...)  Serial.println(__VA_ARGS__)
#else
#   define PULSE_DEBUG_PRINT(...)
#   define PULSE_DEBUG_PRINTLN(...)
#endif

#include "PulseSensor.h"

volatile unsigned int _COUNTER;
volatile unsigned long _startTime;
volatile unsigned long _finishTime;

void detectPulseISR() {
  _COUNTER++;
  _startTime = _finishTime;
  _finishTime = micros();

}

/***************************************************************************/
/*constructor*/

PulseSensor::PulseSensor() {
}

/***************************************************************************/
/*Setup variables and initialize interrupts*/

void PulseSensor::begin(int pulsePin, unsigned int interval, float rateConversion, float acumConversion) {
  _interval = interval;
  _rateConversion = rateConversion;
  _acumConversion = acumConversion;
  _processTime = millis();       // start timer
  _flag = false;
  _acumCounter = 0;
  _counter = 0;                  // reset instance counter
  _COUNTER = 0;                  // reset global counter
  _startTime = 0;
  _finishTime = micros();

  PULSE_DEBUG_PRINT(F("Pulse Pin:")); PULSE_DEBUG_PRINT(pulsePin);
  PULSE_DEBUG_PRINT(F("  INT")); PULSE_DEBUG_PRINTLN(digitalPinToInterrupt(pulsePin));
  pinMode(pulsePin, INPUT_PULLUP); //
  attachInterrupt(digitalPinToInterrupt(pulsePin), detectPulseISR, RISING);
}

/***************************************************************************/
/*check interval and update data, include at least one time inside loop cycle*/
void PulseSensor::refreshData() {
  unsigned long nowTime = millis();
  if (nowTime - _processTime >= _interval) {
    byte oldSREG = SREG;
    noInterrupts();
    _counter = _COUNTER;
    _COUNTER = 0;
    _acumCounter += _counter;  // increase counter
    _processTime = nowTime;     //stamp process time
    _flag = true;
    SREG = oldSREG;            //enable last state interrupts register
  }
}

/***************************************************************************/
/*read sensor value[units per second]*/

float PulseSensor::read() {
  _flag = false;
  return (float)(_counter * 1000.0 / _rateConversion / _interval);
}

/***************************************************************************/
/*read instant value in defined units */
float PulseSensor::readInstant() {
  unsigned long period;
  if ((_counter==0)&&(_COUNTER<2)) return 0.0; //we need 2 consecutive pulses to process
  byte oldSREG = SREG;
  noInterrupts();
  period = micros() - _finishTime;
  if (period < _finishTime - _startTime) period = _finishTime - _startTime;
  }
  SREG = oldSREG;            //enable last state interrupts register
  return (float)1000 / _rateConversion / period;
}

/***************************************************************************/
/*read acumulated value [units]*/

float PulseSensor::readAcum() {
  return (float)_acumCounter / _acumConversion;
}

/***************************************************************************/
/*read instance partial pulse counter*/

unsigned int PulseSensor::readPulses() {
  _flag = false;
  return _counter;
}

/***************************************************************************/
/*read instance acumulated pulse counter*/

unsigned long PulseSensor::readAcumPulses() {
  return _acumCounter;
}

/***************************************************************************/
/*reset acumulated pulse counter */

void PulseSensor::resetAcum() {
  _acumCounter = 0;
}

/***************************************************************************/
/* Is new data available */

boolean PulseSensor::available() {
  refreshData();
  return _flag;
}
<|endoftext|>


<commit_before>#ifndef HEADERLIB_HDR_LIST_HPP
#define HEADERLIB_HDR_LIST_HPP
/*
 * celists.hpp
 *
 *	Created on: 12.11.2015
 *			Author: Andreas Molzer
 */
#pragma once
#include <stdlib.h>
#include <stdio.h>
#include <typeinfo>
#include "hdr/core/std.hpp"

using namespace hdrstd;

namespace hdr::list{

	struct ListSentry;
	template<typename Head, typename Tail> struct List;

	template<typename> struct Head;
	template<typename> struct Tail;
	using head = TypeFunction<Head>;
	using tail = TypeFunction<Tail>;

	template<typename H, typename T>
	struct Head<List<H, T>> {
		using type = H;
	};
	template<typename H, typename T>
	struct Tail<List<H, T>> {
		using type = T;
	};

}

namespace hdrstd{
	template<typename... ob>
	struct Printer<_t_list<ob...>>{
		static void print(){
			printf("(");
			hdrlist::list_printer<hdrlist::separator, ob...>::print();
			printf(")");
		}
	};

	template<size_t... num>
	struct Printer<_c_list<num...>>{
		using print_list = typename hdrlist::c_to_t<_c_list<num...>>::result;
		static void print(){
			Printer<print_list>::print();
		}
	};
}
#endif //HEADERLIB_HDR_LIST_HPP
<commit_msg>Implement list<commit_after>#ifndef HEADERLIB_HDR_LIST_HPP
#define HEADERLIB_HDR_LIST_HPP
/*
 * celists.hpp
 *
 *	Created on: 12.11.2015
 *			Author: Andreas Molzer
 *			Coathor: Martin Molzer
 */
#include "hdr/core/std.hpp"

using namespace hdrstd;

namespace hdr::list {
	/** List a = Nil | Cons a (List a)
	*/
	struct Nil;

	template<typename head, typename tail>
	struct Cons;

	/** []
	*/
	using EmptyList = Nil;

	template<typename L>
	struct Head;
	using head = ::hdr::std::TypeFunction<Head>;
	template<typename L>
	struct Last;
	template<typename L>
	struct Tail;
	template<typename L>
	struct Init;

	// Head []
	template<>
	struct Head<EmptyList>; // exception?
	// Head (head:tail)
	template<typename head, typename tail>
	struct Head<Cons<head, tail>> { using type = head; };

	// Last []
	template<>
	struct Last<EmptyList>; // exception?
	// Last (head:[])
	template<typename head>
	struct Last<Cons<head, EmptyList>> { using type = head; };
	// Last (head:tail)
	template<typename head, typename tail>
	struct Last<Cons<head, tail>> { using type = Last<tail>; };

	// Tail []
	template<>
	struct Tail<EmptyList>; // exception?
	// Tail (head:tail)
	template<typename head, typename tail>
	struct Tail<Cons<head, tail>> { using type = tail; };

	// Init []
	template<>
	struct Init<EmptyList>; // exception?
	// Init (head:[])
	template<typename head>
	struct Init<Cons<head, EmptyList>> { using type = EmptyList; };
	// Last (head:tail)
	template<typename head, typename tail>
	struct Init<Cons<head, tail>> { using type = Cons<head, Init<tail>>; };

}

namespace hdrstd{
	template<typename Head, typename Tail>
	struct Printer<hdr::list::Cons<Head, Tail>>{
		static void print(){
			Printer<Head>::print();
			printf(", ");
			Printer<Tail>::print();
		}
	};
	template<typename Head>
	struct Printer<hdr::list::Cons<Head, hdr::list::Nil>>{
		static void print(){
			Printer<Head>::print();
		}
	};
	template<typename Head>
	struct Printer<hdr::list::Nil>{
		static void print(){
		}
	};
}
#endif //HEADERLIB_HDR_LIST_HPP
<|endoftext|>


<commit_before>/*
   For more information, please see: http://software.sci.utah.edu

   The MIT License

   Copyright (c) 2012 Scientific Computing and Imaging Institute,
   University of Utah.

   License for the specific language governing rights and limitations under
   Permission is hereby granted, free of charge, to any person obtaining a
   copy of this software and associated documentation files (the "Software"),
   to deal in the Software without restriction, including without limitation
   the rights to use, copy, modify, merge, publish, distribute, sublicense,
   and/or sell copies of the Software, and to permit persons to whom the
   Software is furnished to do so, subject to the following conditions:

   The above copyright notice and this permission notice shall be included
   in all copies or substantial portions of the Software.

   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
   THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
   DEALINGS IN THE SOFTWARE.
*/

#include <gtest/gtest.h>
#include <gmock/gmock.h>

#include <Core/Datatypes/DenseMatrix.h>
#include <Core/Datatypes/SparseRowMatrix.h>
#include <Core/Datatypes/MatrixIO.h>
#include <Core/Datatypes/MatrixComparison.h>

using namespace SCIRun::Core::Datatypes;
using namespace ::testing;

namespace
{
  SparseRowMatrix matrix1()
  {
    SparseRowMatrix m(4,5);
    m.insert(0,0) = 1;
    m.insert(1,2) = -2;
    m.insert(2,3) = 0.5;
    return m;
  }
  SparseRowMatrix Zero()
  {
    SparseRowMatrix m(4,5);
    m.setZero();
    return m;
  }
  SparseRowMatrix id3()
  {
    SparseRowMatrix m(3,3);
    m.insert(0,0) = 1;
    m.insert(1,1) = 1;
    m.insert(2,2) = 1;
    return m;
  }
  SparseRowMatrix matrixTdcsGood()
  {
    SparseRowMatrix m(5,5);
    m.insert(1,1) = 1;
    m.insert(2,3) = 0.5;
    return m;
  }
  SparseRowMatrix matrixTdcsBad1()
  {
    SparseRowMatrix m(5,5);
    m.insert(2,2) = 1;
    m.insert(2,1) = 0.5;
    return m;
  }
  SparseRowMatrix matrixTdcsBad2()
  {
    SparseRowMatrix m(5,5);
    m.insert(2,2) = 1;
    m.insert(1,2) = 0.5;
    return m;
  }
  SparseRowMatrix matrixTdcsBad3()
  {
    SparseRowMatrix m(5,5);
    m.insert(2,2) = 1.1;
    return m;
  }
}

#define PRINT_MATRIX(x) //std::cout << #x << " = \n" << (x) << std::endl
#define PRINT_MATRIX_BASE(x) //std::cout << #x << " = \n" << static_cast<const MatrixBase<double>&>((x)) << std::endl

TEST(SparseRowMatrixTest, CanCreateBasicMatrix)
{
  SparseRowMatrix m(matrix1());
  PRINT_MATRIX_BASE(m);
}

TEST(SparseRowMatrixTest, CanPrintInLegacyFormat)
{
  SparseRowMatrix m(matrix1());
  std::string legacy = matrix_to_string(0.5 * m);
  EXPECT_EQ("0.5 0 0 0 0 \n0 0 -1 0 0 \n0 0 0 0.25 0 \n0 0 0 0 0 \n", legacy);
}

TEST(SparseRowMatrixTest, CanDetermineSize)
{
  SparseRowMatrix m(matrix1());
  EXPECT_EQ(4, m.nrows());
  EXPECT_EQ(5, m.ncols());
}

TEST(SparseRowMatrixTest, CanCopyConstruct)
{
  SparseRowMatrix m(matrix1());
  SparseRowMatrix m2(m);
  EXPECT_EQ(m, m2);
  m.coeffRef(1,2) += 1;
  PRINT_MATRIX_BASE(m);
  PRINT_MATRIX_BASE(m2);
  EXPECT_NE(m, m2);
}

TEST(SparseRowMatrixTest, CanAssign)
{
  SparseRowMatrix m(matrix1());

  SparseRowMatrix m2;
  EXPECT_NE(m, m2);
  m2 = m;
  EXPECT_EQ(m, m2);
  m.coeffRef(1,2) += 1;
  EXPECT_NE(m, m2);
}

TEST(SparseRowMatrixUnaryOperationTests, CanNegate)
{
  SparseRowMatrix m(matrix1());

  PRINT_MATRIX_BASE(m);
  PRINT_MATRIX(-m);

  SparseRowMatrix n = - -m;
  EXPECT_EQ(m, n);
  SparseRowMatrix diff = m + (-m);
  EXPECT_EQ(diff, Zero());
}

TEST(SparseRowMatrixUnaryOperationTests, CanScalarMultiply)
{
  SparseRowMatrix m(matrix1());

  PRINT_MATRIX_BASE(m);
  PRINT_MATRIX(2*m);
  PRINT_MATRIX(m*2);
  SparseRowMatrix x = 2*m;
  SparseRowMatrix y = m*2;
  EXPECT_EQ(x,y);
}

TEST(SparseRowMatrixUnaryOperationTests, CanTranspose)
{
  SparseRowMatrix m(matrix1());

  PRINT_MATRIX_BASE(m);
  PRINT_MATRIX(m.transpose());

  SparseRowMatrix mtt = m.transpose().transpose();
  EXPECT_EQ(m,mtt);
}

TEST(SparseRowMatrixBinaryOperationTests, CanMultiply)
{
  SparseRowMatrix m(matrix1());

  PRINT_MATRIX_BASE(m);
  PRINT_MATRIX(m * m.transpose());
  SparseRowMatrix prod = Zero() * m;
  EXPECT_EQ(prod, Zero());
}

TEST(SparseRowMatrixBinaryOperationTests, CanAdd)
{
  SparseRowMatrix m(matrix1());

  PRINT_MATRIX_BASE(m);
  PRINT_MATRIX(m + m);
  SparseRowMatrix m2a = m + m;
  SparseRowMatrix m2b = 2*m;
  EXPECT_EQ(m2a, m2b);
}

TEST(SparseRowMatrixBinaryOperationTests, CanSubtract)
{
  SparseRowMatrix m(matrix1());

  PRINT_MATRIX_BASE(m);
  PRINT_MATRIX(m - m);
  SparseRowMatrix diff = m - m;
  EXPECT_EQ(diff, Zero());
}

//TODO: compare to v4.
//TEST(SparseRowMatrixBinaryOperationTests, WhatHappensWhenYouAddDifferentSizes)
//{
//  SparseRowMatrix sum = matrix1() + matrix1();
//  std::cout << sum.rows() << std::endl;
//  std::cout << sum.cols() << std::endl;
//  PRINT_MATRIX(sum);
//}

template <typename T>
void printArray(const T* ts, size_t size)
{
  std::copy(ts, ts + size, std::ostream_iterator<T>(std::cout, " "));
  std::cout << std::endl;
}

TEST(SparseRowMatrixTest, CheckingInternalArrays)
{
  auto mat = matrix1();

  mat.makeCompressed();
  EXPECT_EQ(0, mat.innerNonZeroPtr());
  EXPECT_EQ(3, mat.nonZeros());
  EXPECT_NE(mat.rows(), mat.cols());
  EXPECT_EQ(mat.outerSize(), mat.rows());
  EXPECT_EQ(mat.innerSize(), mat.cols());

  std::vector<double> values(mat.valuePtr(), mat.valuePtr() + mat.nonZeros());
  EXPECT_THAT(values, ElementsAre(1, -2, 0.5));
  std::vector<double> columns(mat.innerIndexPtr(), mat.innerIndexPtr() + mat.nonZeros());
  EXPECT_THAT(columns, ElementsAre(0,2,3));
  std::vector<double> rows(mat.outerIndexPtr(), mat.outerIndexPtr() + mat.outerSize());
  EXPECT_THAT(rows, ElementsAre(0,1,2,3));
}

TEST(SparseRowMatrixTest, CheckingInternalArrays2)
{
  SparseRowMatrix mat(id3());

  mat.makeCompressed();
  EXPECT_EQ(0, mat.innerNonZeroPtr());
  EXPECT_EQ(3, mat.nonZeros());
  EXPECT_EQ(mat.rows(), mat.cols());
  EXPECT_EQ(mat.outerSize(), mat.rows());
  EXPECT_EQ(mat.innerSize(), mat.cols());

  std::vector<double> values(mat.valuePtr(), mat.valuePtr() + mat.nonZeros());
  EXPECT_THAT(values, ElementsAre(1, 1, 1));
  std::vector<double> columns(mat.innerIndexPtr(), mat.innerIndexPtr() + mat.nonZeros());
  EXPECT_THAT(columns, ElementsAre(0,1,2));
  std::vector<double> rows(mat.outerIndexPtr(), mat.outerIndexPtr() + mat.outerSize());
  EXPECT_THAT(rows, ElementsAre(0,1,2));
}

bool passesTdcsTest(const SparseRowMatrix& matrix)
{
  for (int k=0; k < matrix.outerSize(); ++k)
  {
    for (SparseMatrix<double>::InnerIterator it(mat,k); it; ++it)
    {
      //if (it.value() == 1

      it.value();
      it.row();   // row index
      it.col();   // col index (here it is equal to k)

    }
  }
  return false;
}

TEST(SparseRowMatrixTest, SearchingForSingleNonzeroInRowAndColumnOnTheDiagonal)
{
  EXPECT_TRUE(passesTdcsTest(id3()));
  EXPECT_TRUE(passesTdcsTest(matrixTdcsGood()));

  EXPECT_FALSE(passesTdcsTest(Zero()));

  EXPECT_FALSE(passesTdcsTest(matrixTdcsBad1()));
  EXPECT_FALSE(passesTdcsTest(matrixTdcsBad2()));
  EXPECT_FALSE(passesTdcsTest(matrixTdcsBad3()));

}<commit_msg>Partially working TDCS sparse matrix check code<commit_after>/*
   For more information, please see: http://software.sci.utah.edu

   The MIT License

   Copyright (c) 2012 Scientific Computing and Imaging Institute,
   University of Utah.

   License for the specific language governing rights and limitations under
   Permission is hereby granted, free of charge, to any person obtaining a
   copy of this software and associated documentation files (the "Software"),
   to deal in the Software without restriction, including without limitation
   the rights to use, copy, modify, merge, publish, distribute, sublicense,
   and/or sell copies of the Software, and to permit persons to whom the
   Software is furnished to do so, subject to the following conditions:

   The above copyright notice and this permission notice shall be included
   in all copies or substantial portions of the Software.

   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
   THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
   DEALINGS IN THE SOFTWARE.
*/

#include <gtest/gtest.h>
#include <gmock/gmock.h>

#include <Core/Datatypes/DenseMatrix.h>
#include <Core/Datatypes/SparseRowMatrix.h>
#include <Core/Datatypes/MatrixIO.h>
#include <Core/Datatypes/MatrixComparison.h>

using namespace SCIRun::Core::Datatypes;
using namespace ::testing;

namespace
{
  SparseRowMatrix matrix1()
  {
    SparseRowMatrix m(4,5);
    m.insert(0,0) = 1;
    m.insert(1,2) = -2;
    m.insert(2,3) = 0.5;
    return m;
  }
  SparseRowMatrix Zero()
  {
    SparseRowMatrix m(4,5);
    m.setZero();
    return m;
  }
  SparseRowMatrix id3()
  {
    SparseRowMatrix m(3,3);
    m.insert(0,0) = 1;
    m.insert(1,1) = 1;
    m.insert(2,2) = 1;
    return m;
  }
  SparseRowMatrix matrixTdcsGood()
  {
    SparseRowMatrix m(5,5);
    m.insert(1,1) = 1;
    m.insert(2,3) = 0.5;
    return m;
  }
  SparseRowMatrix matrixTdcsBad1()
  {
    SparseRowMatrix m(5,5);
    m.insert(2,2) = 1;
    m.insert(2,1) = 0.5;
    return m;
  }
  SparseRowMatrix matrixTdcsBad2()
  {
    SparseRowMatrix m(5,5);
    m.insert(2,2) = 1;
    m.insert(1,2) = 0.5;
    return m;
  }
  SparseRowMatrix matrixTdcsBad3()
  {
    SparseRowMatrix m(5,5);
    m.insert(2,2) = 1.1;
    return m;
  }
}

#define PRINT_MATRIX(x) //std::cout << #x << " = \n" << (x) << std::endl
#define PRINT_MATRIX_BASE(x) //std::cout << #x << " = \n" << static_cast<const MatrixBase<double>&>((x)) << std::endl

TEST(SparseRowMatrixTest, CanCreateBasicMatrix)
{
  SparseRowMatrix m(matrix1());
  PRINT_MATRIX_BASE(m);
}

TEST(SparseRowMatrixTest, CanPrintInLegacyFormat)
{
  SparseRowMatrix m(matrix1());
  std::string legacy = matrix_to_string(0.5 * m);
  EXPECT_EQ("0.5 0 0 0 0 \n0 0 -1 0 0 \n0 0 0 0.25 0 \n0 0 0 0 0 \n", legacy);
}

TEST(SparseRowMatrixTest, CanDetermineSize)
{
  SparseRowMatrix m(matrix1());
  EXPECT_EQ(4, m.nrows());
  EXPECT_EQ(5, m.ncols());
}

TEST(SparseRowMatrixTest, CanCopyConstruct)
{
  SparseRowMatrix m(matrix1());
  SparseRowMatrix m2(m);
  EXPECT_EQ(m, m2);
  m.coeffRef(1,2) += 1;
  PRINT_MATRIX_BASE(m);
  PRINT_MATRIX_BASE(m2);
  EXPECT_NE(m, m2);
}

TEST(SparseRowMatrixTest, CanAssign)
{
  SparseRowMatrix m(matrix1());

  SparseRowMatrix m2;
  EXPECT_NE(m, m2);
  m2 = m;
  EXPECT_EQ(m, m2);
  m.coeffRef(1,2) += 1;
  EXPECT_NE(m, m2);
}

TEST(SparseRowMatrixUnaryOperationTests, CanNegate)
{
  SparseRowMatrix m(matrix1());

  PRINT_MATRIX_BASE(m);
  PRINT_MATRIX(-m);

  SparseRowMatrix n = - -m;
  EXPECT_EQ(m, n);
  SparseRowMatrix diff = m + (-m);
  EXPECT_EQ(diff, Zero());
}

TEST(SparseRowMatrixUnaryOperationTests, CanScalarMultiply)
{
  SparseRowMatrix m(matrix1());

  PRINT_MATRIX_BASE(m);
  PRINT_MATRIX(2*m);
  PRINT_MATRIX(m*2);
  SparseRowMatrix x = 2*m;
  SparseRowMatrix y = m*2;
  EXPECT_EQ(x,y);
}

TEST(SparseRowMatrixUnaryOperationTests, CanTranspose)
{
  SparseRowMatrix m(matrix1());

  PRINT_MATRIX_BASE(m);
  PRINT_MATRIX(m.transpose());

  SparseRowMatrix mtt = m.transpose().transpose();
  EXPECT_EQ(m,mtt);
}

TEST(SparseRowMatrixBinaryOperationTests, CanMultiply)
{
  SparseRowMatrix m(matrix1());

  PRINT_MATRIX_BASE(m);
  PRINT_MATRIX(m * m.transpose());
  SparseRowMatrix prod = Zero() * m;
  EXPECT_EQ(prod, Zero());
}

TEST(SparseRowMatrixBinaryOperationTests, CanAdd)
{
  SparseRowMatrix m(matrix1());

  PRINT_MATRIX_BASE(m);
  PRINT_MATRIX(m + m);
  SparseRowMatrix m2a = m + m;
  SparseRowMatrix m2b = 2*m;
  EXPECT_EQ(m2a, m2b);
}

TEST(SparseRowMatrixBinaryOperationTests, CanSubtract)
{
  SparseRowMatrix m(matrix1());

  PRINT_MATRIX_BASE(m);
  PRINT_MATRIX(m - m);
  SparseRowMatrix diff = m - m;
  EXPECT_EQ(diff, Zero());
}

//TODO: compare to v4.
//TEST(SparseRowMatrixBinaryOperationTests, WhatHappensWhenYouAddDifferentSizes)
//{
//  SparseRowMatrix sum = matrix1() + matrix1();
//  std::cout << sum.rows() << std::endl;
//  std::cout << sum.cols() << std::endl;
//  PRINT_MATRIX(sum);
//}

template <typename T>
void printArray(const T* ts, size_t size)
{
  std::copy(ts, ts + size, std::ostream_iterator<T>(std::cout, " "));
  std::cout << std::endl;
}

TEST(SparseRowMatrixTest, CheckingInternalArrays)
{
  auto mat = matrix1();

  mat.makeCompressed();
  EXPECT_EQ(0, mat.innerNonZeroPtr());
  EXPECT_EQ(3, mat.nonZeros());
  EXPECT_NE(mat.rows(), mat.cols());
  EXPECT_EQ(mat.outerSize(), mat.rows());
  EXPECT_EQ(mat.innerSize(), mat.cols());

  std::vector<double> values(mat.valuePtr(), mat.valuePtr() + mat.nonZeros());
  EXPECT_THAT(values, ElementsAre(1, -2, 0.5));
  std::vector<long long> columns(mat.innerIndexPtr(), mat.innerIndexPtr() + mat.nonZeros());
  EXPECT_THAT(columns, ElementsAre(0,2,3));
  std::vector<long long> rows(mat.outerIndexPtr(), mat.outerIndexPtr() + mat.outerSize());
  EXPECT_THAT(rows, ElementsAre(0,1,2,3));
}

TEST(SparseRowMatrixTest, CheckingInternalArrays2)
{
  SparseRowMatrix mat(id3());

  mat.makeCompressed();
  EXPECT_EQ(0, mat.innerNonZeroPtr());
  EXPECT_EQ(3, mat.nonZeros());
  EXPECT_EQ(mat.rows(), mat.cols());
  EXPECT_EQ(mat.outerSize(), mat.rows());
  EXPECT_EQ(mat.innerSize(), mat.cols());

  std::vector<double> values(mat.valuePtr(), mat.valuePtr() + mat.nonZeros());
  EXPECT_THAT(values, ElementsAre(1, 1, 1));
  std::vector<long long> columns(mat.innerIndexPtr(), mat.innerIndexPtr() + mat.nonZeros());
  EXPECT_THAT(columns, ElementsAre(0,1,2));
  std::vector<long long> rows(mat.outerIndexPtr(), mat.outerIndexPtr() + mat.outerSize());
  EXPECT_THAT(rows, ElementsAre(0,1,2));
}

bool hasNElements(const SparseRowMatrix::InnerIterator& it, int n)
{
  SparseRowMatrix::InnerIterator copy(it);
  for (int i = 0; i < n && copy; ++i)
    ++copy;
  return !copy;
}

bool passesTdcsTest(const SparseRowMatrix& matrix)
{
  for (int k=0; k < matrix.outerSize(); ++k)
  {
    for (SparseRowMatrix::InnerIterator it(matrix,k); it; ++it)
    {
      //std::cout << "value: " << it.value() << std::endl;
      //std::cout << "row: " << it.row() << std::endl;
      //std::cout << "col: " << it.col() << std::endl;

      if (hasNElements(it, 1))
      {
        //std::cout << "has 1 element" << std::endl;
        //std::cout << "value = " << it.value() << std::endl;
        if (it.value() == 1)
        {
          //std::cout << "found a 1 " << std::endl;
          return true;
        }
      }
      //if (it.value() == 1

      //it.value();
      //it.row();   // row index
      //it.col();   // col index (here it is equal to k)

    }
  }
  return false;
}

TEST(SparseRowMatrixTest, SearchingForSingleNonzeroInRowAndColumnOnTheDiagonal)
{
  EXPECT_TRUE(passesTdcsTest(id3()));
  EXPECT_TRUE(passesTdcsTest(matrixTdcsGood()));

  EXPECT_FALSE(passesTdcsTest(Zero()));

  EXPECT_FALSE(passesTdcsTest(matrixTdcsBad1()));
  EXPECT_FALSE(passesTdcsTest(matrixTdcsBad2()));
  EXPECT_FALSE(passesTdcsTest(matrixTdcsBad3()));

}<|endoftext|>


<commit_before>#include "x_client_chooser.hpp"

#include <algorithm>
#include <X11/keysym.h>

x_client_chooser::x_client_chooser(x_connection & c,
                                   chooser_t * chooser,
                                   xcb_keysym_t action_keysym,
                                   xcb_mod_mask_t action_modmask)
  : _c(c), _chooser(chooser)
  , _action_modmask(action_modmask)
{
  _c.register_handler(XCB_KEY_PRESS, this);
  _c.register_handler(XCB_KEY_RELEASE, this);
  _c.grab_key(_action_modmask, action_keysym);
  _action_keycode = _c.keysym_to_keycode(action_keysym);
  _modifier_map = _c.modifier_mapping();
}

bool
x_client_chooser::handle(xcb_generic_event_t * ge)
{
  bool result = false;

  if (XCB_KEY_PRESS == (ge->response_type & ~0x80)) {
    result = true;
    xcb_key_press_event_t * e = (xcb_key_press_event_t *)ge;

    if (e->detail == _action_keycode
        && (e->state == _action_modmask
          || e->state == (_action_modmask | XCB_MOD_MASK_SHIFT))) {
      if (_active) {
        if (e->state == _action_modmask) {
          _chooser->next();
        } else {
          _chooser->prev();
        }

      } else {
        _active = true;
        _c.grab_keyboard();
        _chooser->show();
        _chooser->next();
      }
    }

  } else if (XCB_KEY_RELEASE == (ge->response_type & ~0x80)) {
    result = true;
    xcb_key_release_event_t * e = (xcb_key_release_event_t *)ge;
    for (auto & keycode : _modifier_map[_action_modmask]) {
      if (e->detail == keycode) {
        _active = false;
        _c.ungrab_keyboard();
        _chooser->hide();
        _chooser->select();
      }
      break;
    }
  }

  return result;
}
<commit_msg>Directly select window when clicked on it<commit_after>#include "x_client_chooser.hpp"

#include <algorithm>
#include <X11/keysym.h>

x_client_chooser::x_client_chooser(x_connection & c,
                                   chooser_t * chooser,
                                   xcb_keysym_t action_keysym,
                                   xcb_mod_mask_t action_modmask)
  : _c(c), _chooser(chooser)
  , _action_modmask(action_modmask)
{
  _c.register_handler(XCB_KEY_PRESS, this);
  _c.register_handler(XCB_KEY_RELEASE, this);
  _c.register_handler(XCB_BUTTON_PRESS, this);
  _c.grab_key(_action_modmask, action_keysym);
  _action_keycode = _c.keysym_to_keycode(action_keysym);
  _modifier_map = _c.modifier_mapping();
}

bool
x_client_chooser::handle(xcb_generic_event_t * ge)
{
  bool result = false;

  if (XCB_KEY_PRESS == (ge->response_type & ~0x80)) {
    result = true;
    xcb_key_press_event_t * e = (xcb_key_press_event_t *)ge;

    if (e->detail == _action_keycode
        && (e->state == _action_modmask
          || e->state == (_action_modmask | XCB_MOD_MASK_SHIFT))) {
      if (_active) {
        if (e->state == _action_modmask) {
          _chooser->next();
        } else {
          _chooser->prev();
        }

      } else {
        _active = true;
        _c.grab_keyboard();
        _chooser->show();
        _chooser->next();
      }
    }

  } else if (XCB_KEY_RELEASE == (ge->response_type & ~0x80)) {
    result = true;
    xcb_key_release_event_t * e = (xcb_key_release_event_t *)ge;
    for (auto & keycode : _modifier_map[_action_modmask]) {
      if (e->detail == keycode) {
        _active = false;
        _c.ungrab_keyboard();
        _chooser->hide();
        _chooser->select();
      }
      break;
    }

  } else if (XCB_BUTTON_PRESS == (ge->response_type & ~0x80)) {
    result = true;
    xcb_button_press_event_t * e = (xcb_button_press_event_t *)ge;
    _active = false;
    _c.ungrab_keyboard();
    _chooser->hide();
    _chooser->select(e->event);

  }

  return result;
}
<|endoftext|>


<commit_before><commit_msg>fix date from string constructor allocation errors<commit_after><|endoftext|>


<commit_before>#include <mimosa/stream/string-stream.hh>
#include <mimosa/stream/base16-decoder.hh>
#include <mimosa/tpl/dict.hh>
#include <mimosa/tpl/include.hh>
#include <mimosa/tpl/list.hh>
#include <mimosa/tpl/template.hh>
#include <mimosa/tpl/value.hh>

#include "peers-handler.hh"
#include "torrent-db.hh"
#include "hefur.hh"
#include "template-factory.hh"

namespace hefur
{
  bool
  PeersHandler::handle(mimosa::http::RequestReader &  request,
                       mimosa::http::ResponseWriter & response) const
  {
    std::string info_hash = request.queryGet("info_hash");

    mimosa::stream::StringStream::Ptr ss = new mimosa::stream::StringStream;
    mimosa::stream::Base16Decoder::Ptr dec = new mimosa::stream::Base16Decoder(ss);
    dec->write(info_hash.data(), info_hash.size());

    info_hash = ss->str();

    if (info_hash.size() != 20)
      return false;

    auto tpl = TemplateFactory::instance().create("page.html");
    if (!tpl)
      return false;

    auto tpl_body = TemplateFactory::instance().create("peers.html");
    if (!tpl_body)
      return false;

    mimosa::tpl::Dict dict;
    HttpServer::commonDict(dict);
    dict.append("body", tpl_body);
    dict.append("title", "Torrent peers");

    auto peers = new mimosa::tpl::List("peers");
    dict.append(peers);

    {
      TorrentDb & tdb = Hefur::instance().torrentDb();
      mimosa::SharedMutex::ReadLocker locker(tdb.torrents_lock_);
      auto torrent = tdb.torrents_.find(info_hash);
      if (!torrent)
      {
        response.status_ = mimosa::http::kStatusNotFound;
        return true;
      }

      for (auto it = torrent->timeouts_.begin(); it != torrent->timeouts_.end(); ++it)
      {
        auto ip = it->addr_.ipStr();
        auto peer = new mimosa::tpl::Dict("peer");
        peers->append(peer);
        peer->append("ip", ip);
        peer->append("port", it->addr_.port());
        peer->append("peerid", mimosa::StringRef((const char *)it->peerid_, 20));
        peer->append("downloaded", it->downloaded_);
        peer->append("uploaded", it->uploaded_);
        peer->append("left", it->left_);
      }
    }

    tpl->execute(&response, dict);
    return true;
  }
}
<commit_msg>PeersHandler: prettify byte size<commit_after>#include <mimosa/format/print.hh>
#include <mimosa/stream/string-stream.hh>
#include <mimosa/stream/base16-decoder.hh>
#include <mimosa/tpl/dict.hh>
#include <mimosa/tpl/include.hh>
#include <mimosa/tpl/list.hh>
#include <mimosa/tpl/template.hh>
#include <mimosa/tpl/value.hh>

#include "peers-handler.hh"
#include "torrent-db.hh"
#include "hefur.hh"
#include "template-factory.hh"

namespace hefur
{
  bool
  PeersHandler::handle(mimosa::http::RequestReader &  request,
                       mimosa::http::ResponseWriter & response) const
  {
    std::string info_hash = request.queryGet("info_hash");

    mimosa::stream::StringStream::Ptr ss = new mimosa::stream::StringStream;
    mimosa::stream::Base16Decoder::Ptr dec = new mimosa::stream::Base16Decoder(ss);
    dec->write(info_hash.data(), info_hash.size());

    info_hash = ss->str();

    if (info_hash.size() != 20)
      return false;

    auto tpl = TemplateFactory::instance().create("page.html");
    if (!tpl)
      return false;

    auto tpl_body = TemplateFactory::instance().create("peers.html");
    if (!tpl_body)
      return false;

    mimosa::tpl::Dict dict;
    HttpServer::commonDict(dict);
    dict.append("body", tpl_body);
    dict.append("title", "Torrent peers");

    auto peers = new mimosa::tpl::List("peers");
    dict.append(peers);

    {
      TorrentDb & tdb = Hefur::instance().torrentDb();
      mimosa::SharedMutex::ReadLocker locker(tdb.torrents_lock_);
      auto torrent = tdb.torrents_.find(info_hash);
      if (!torrent)
      {
        response.status_ = mimosa::http::kStatusNotFound;
        return true;
      }

      for (auto it = torrent->timeouts_.begin(); it != torrent->timeouts_.end(); ++it)
      {
        auto ip = it->addr_.ipStr();
        auto peer = new mimosa::tpl::Dict("peer");
        peers->append(peer);
        peer->append("ip", ip);
        peer->append("port", it->addr_.port());
        peer->append("peerid", mimosa::StringRef((const char *)it->peerid_, 20));

        mimosa::stream::StringStream ss;
        mimosa::format::printByteSize(ss, it->downloaded_);
        dict.append("downloaded", ss.str());

        ss.setStr("");
        mimosa::format::printByteSize(ss, it->uploaded_);
        dict.append("uploaded", ss.str());

        ss.setStr("");
        mimosa::format::printByteSize(ss, it->left_);
        dict.append("left", ss.str());
      }
    }

    tpl->execute(&response, dict);
    return true;
  }
}
<|endoftext|>


<commit_before>#include "wallet/test/wallet_test_fixture.h"

#include "rpc/server.h"
#include "wallet/db.h"
#include "wallet/wallet.h"

WalletTestingSetup::WalletTestingSetup(const std::string& chainName):
    TestingSetup(chainName)
{
    bitdb.MakeMock();

    bool fFirstRun;
    pwalletMain = new CWallet("wallet.dat");
    pwalletMain->LoadWallet(fFirstRun);
    RegisterValidationInterface(pwalletMain);

    RegisterWalletRPCCommands(tableRPC);
}

WalletTestingSetup::~WalletTestingSetup()
{
    UnregisterValidationInterface(pwalletMain);
    delete pwalletMain;
    pwalletMain = NULL;

    bitdb.Flush(true);
    bitdb.Reset();
}
<commit_msg>test: Rename wallet.dat to wallet_test.dat<commit_after>#include "wallet/test/wallet_test_fixture.h"

#include "rpc/server.h"
#include "wallet/db.h"
#include "wallet/wallet.h"

WalletTestingSetup::WalletTestingSetup(const std::string& chainName):
    TestingSetup(chainName)
{
    bitdb.MakeMock();

    bool fFirstRun;
    pwalletMain = new CWallet("wallet_test.dat");
    pwalletMain->LoadWallet(fFirstRun);
    RegisterValidationInterface(pwalletMain);

    RegisterWalletRPCCommands(tableRPC);
}

WalletTestingSetup::~WalletTestingSetup()
{
    UnregisterValidationInterface(pwalletMain);
    delete pwalletMain;
    pwalletMain = NULL;

    bitdb.Flush(true);
    bitdb.Reset();
}
<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (directui@nokia.com)
**
** This file is part of meegotouch-controlpanelapplets.
**
** If you have questions regarding the use of this file, please contact
** Nokia at directui@nokia.com.
**
** 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
** and appearing in the file LICENSE.LGPL included in the packaging
** of this file.
**
****************************************************************************/

#include "wallpaperwidget.h"
#include "wallpaperlist.h"

#include <QGraphicsLinearLayout>
#include <MLayout>
#include <MLinearLayoutPolicy>
#include <MContainer>
#include <QTimer>
#include <MContentItem>
#include <MAction>
#include <QDebug>
#include <QtTracker/Tracker>

#define DEBUG
#define WARNING
#include "../debug.h"

static const int MaxColumns = 2;

static const char *oviCommand = "webwidgetrunner /usr/share/webwidgets/applications/d34177b1c241ea44cb132005b63ee6527c9f6040-wrt-widget.desktop -widgetparameter graphics &";

WallpaperWidget::WallpaperWidget (
        WallpaperBusinessLogic *wallpaperBusinessLogic,
        QGraphicsWidget        *parent) :
    DcpWidget (parent),
    m_WallpaperBusinessLogic (wallpaperBusinessLogic)
{
    /*
     * Unfortunatelly the content has to be created late, otherwise the list
     * only shows one row.
     * FIXME: I'm n ot sure how late should this be done, I thing we should use
     * the void MApplicationPage::createContent(), but I don't know how to do
     * that.
     */
    //createContent ();
    QTimer::singleShot(100, this, SLOT(createContent()));

    connect (this, SIGNAL(layoutChanged()),
            this, SLOT(haveParent ()));
}

WallpaperWidget::~WallpaperWidget ()
{
}

void
WallpaperWidget::createContent ()
{
    QGraphicsLinearLayout *mainLayout;

    mainLayout = new QGraphicsLinearLayout (Qt::Vertical);
    mainLayout->setContentsMargins (0, 0, 0, 0);
    setLayout (mainLayout);

    /*
     * The list of the available images.
     */
    m_ImageList = new WallpaperList (m_WallpaperBusinessLogic, this);
    m_ImageList->setObjectName("WallpaperImageList");
    connect (m_ImageList, SIGNAL(imageActivated(WallpaperDescriptor *)),
            this, SLOT(slotImageActivated(WallpaperDescriptor *)));

    m_ImageList->setDataSourceType (WallpaperList::DataSourceLocal);

    /*
     * Adding all widgets into the layout.
     */
    mainLayout->addItem (m_ImageList);
    mainLayout->setStretchFactor (m_ImageList, 1);

    connect (m_WallpaperBusinessLogic, SIGNAL(imageEditRequested()),
            this, SLOT(slotImageActivated()));
}

/*
 * This slot is called when the user activates an image in the list. The
 * WallpaperList has a signal for that.
 */
void
WallpaperWidget::slotImageActivated (
        WallpaperDescriptor *desc)
{
    SYS_DEBUG ("*** desc = %s", SYS_STR(desc->basename()));
    m_WallpaperBusinessLogic->startEdit (desc);
}

/*
 * When this slot is activated the image has to be already loaded, so that the
 * editor widget can be shown without delay.
 */
void
WallpaperWidget::slotImageActivated ()
{
    SYS_DEBUG ("");

    emit changeWidget (1);
}

void
WallpaperWidget::oviActivated ()
{
    SYS_DEBUG ("Executing %s", oviCommand);
    system (oviCommand);
}

void
WallpaperWidget::haveParent ()
{
    QGraphicsWidget  *parent;
    MApplicationPage *page = 0;
    MAction          *action;

    /*
     * We need to find the MApplicationPage among our parents.
     */
    parent = parentWidget();
    while (parent) {
        page = qobject_cast <MApplicationPage *>(parent);
        if (page)
            break;
        parent = parent->parentWidget();
    }

    if (!page)
        return;

    /*
     * Adding the gallery action.
     */
    #ifdef HAVE_CONTENT_MANAGER
    action = new MAction("icon-m-content-gallery", "", this);
    action->setLocation(MAction::ToolBarLocation);
    page->addAction(action);
    connect(action, SIGNAL(triggered()), this, SLOT(galleryActivated()));
    #endif

    /*
     * Adding the ovi action.
     */
    action = new MAction("icon-m-common-ovi", "", this);
    action->setLocation(MAction::ToolBarLocation);
    page->addAction(action);
    connect(action, SIGNAL(triggered()), this, SLOT(oviActivated()));
}

#ifdef HAVE_CONTENT_MANAGER
/*!
 * Slot that is activated when the user clicked on the gallery item, the widget
 * that activates the ContentManager page. We support this only when the
 * ContentManager library is available.
 */
void
WallpaperWidget::galleryActivated ()
{
    /*
     * Please note that the m_ImageBrowser is a QPointer object that will reset
     * itself to NULL when the widget is destroyed. It will also initialize
     * itself to NULL when it is created.
     */
    if (!m_ImageBrowser) {
        m_ImageBrowser = new SelectSingleContentItemPage (
                QString(),
                QStringList() << "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#Image",
                QString());

        m_ImageBrowser->setObjectName (
                "SelectSingleContentItemPage_imageBrowser");

        connect (m_ImageBrowser, SIGNAL(backButtonClicked()),
                m_ImageBrowser, SLOT(dismiss()));
        connect (m_ImageBrowser, SIGNAL(contentItemSelected(const QString &)),
                this, SLOT(galleryImageSelected(const QString &)));
    }

    m_ImageBrowser->appear (MSceneWindow::DestroyWhenDismissed);
}
#endif

#ifdef HAVE_CONTENT_MANAGER
/*!
 * Slot that activated when the user picks an image from the content manager
 * page. We only need this slot when the ContentManager library is activated.
 */
void
WallpaperWidget::galleryImageSelected (
        const QString &uri)
{
    m_WallpaperBusinessLogic->addImageFromGallery (uri);
}
#endif
<commit_msg>Fixes: a compilation error<commit_after>/****************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (directui@nokia.com)
**
** This file is part of meegotouch-controlpanelapplets.
**
** If you have questions regarding the use of this file, please contact
** Nokia at directui@nokia.com.
**
** 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
** and appearing in the file LICENSE.LGPL included in the packaging
** of this file.
**
****************************************************************************/

#include "wallpaperwidget.h"
#include "wallpaperlist.h"

#include <MApplicationPage>
#include <QGraphicsLinearLayout>
#include <MLayout>
#include <MLinearLayoutPolicy>
#include <MContainer>
#include <QTimer>
#include <MContentItem>
#include <MAction>
#include <QDebug>
#include <QtTracker/Tracker>

#define DEBUG
#define WARNING
#include "../debug.h"

static const int MaxColumns = 2;

static const char *oviCommand = "webwidgetrunner /usr/share/webwidgets/applications/d34177b1c241ea44cb132005b63ee6527c9f6040-wrt-widget.desktop -widgetparameter graphics &";

WallpaperWidget::WallpaperWidget (
        WallpaperBusinessLogic *wallpaperBusinessLogic,
        QGraphicsWidget        *parent) :
    DcpWidget (parent),
    m_WallpaperBusinessLogic (wallpaperBusinessLogic)
{
    /*
     * Unfortunatelly the content has to be created late, otherwise the list
     * only shows one row.
     * FIXME: I'm n ot sure how late should this be done, I thing we should use
     * the void MApplicationPage::createContent(), but I don't know how to do
     * that.
     */
    //createContent ();
    QTimer::singleShot(100, this, SLOT(createContent()));

    connect (this, SIGNAL(layoutChanged()),
            this, SLOT(haveParent ()));
}

WallpaperWidget::~WallpaperWidget ()
{
}

void
WallpaperWidget::createContent ()
{
    QGraphicsLinearLayout *mainLayout;

    mainLayout = new QGraphicsLinearLayout (Qt::Vertical);
    mainLayout->setContentsMargins (0, 0, 0, 0);
    setLayout (mainLayout);

    /*
     * The list of the available images.
     */
    m_ImageList = new WallpaperList (m_WallpaperBusinessLogic, this);
    m_ImageList->setObjectName("WallpaperImageList");
    connect (m_ImageList, SIGNAL(imageActivated(WallpaperDescriptor *)),
            this, SLOT(slotImageActivated(WallpaperDescriptor *)));

    m_ImageList->setDataSourceType (WallpaperList::DataSourceLocal);

    /*
     * Adding all widgets into the layout.
     */
    mainLayout->addItem (m_ImageList);
    mainLayout->setStretchFactor (m_ImageList, 1);

    connect (m_WallpaperBusinessLogic, SIGNAL(imageEditRequested()),
            this, SLOT(slotImageActivated()));
}

/*
 * This slot is called when the user activates an image in the list. The
 * WallpaperList has a signal for that.
 */
void
WallpaperWidget::slotImageActivated (
        WallpaperDescriptor *desc)
{
    SYS_DEBUG ("*** desc = %s", SYS_STR(desc->basename()));
    m_WallpaperBusinessLogic->startEdit (desc);
}

/*
 * When this slot is activated the image has to be already loaded, so that the
 * editor widget can be shown without delay.
 */
void
WallpaperWidget::slotImageActivated ()
{
    SYS_DEBUG ("");

    emit changeWidget (1);
}

void
WallpaperWidget::oviActivated ()
{
    SYS_DEBUG ("Executing %s", oviCommand);
    system (oviCommand);
}

void
WallpaperWidget::haveParent ()
{
    QGraphicsWidget  *parent;
    MApplicationPage *page = 0;
    MAction          *action;

    /*
     * We need to find the MApplicationPage among our parents.
     */
    parent = parentWidget();
    while (parent) {
        page = qobject_cast <MApplicationPage *>(parent);
        if (page)
            break;
        parent = parent->parentWidget();
    }

    if (!page)
        return;

    /*
     * Adding the gallery action.
     */
    #ifdef HAVE_CONTENT_MANAGER
    action = new MAction("icon-m-content-gallery", "", this);
    action->setLocation(MAction::ToolBarLocation);
    page->addAction(action);
    connect(action, SIGNAL(triggered()), this, SLOT(galleryActivated()));
    #endif

    /*
     * Adding the ovi action.
     */
    action = new MAction("icon-m-common-ovi", "", this);
    action->setLocation(MAction::ToolBarLocation);
    page->addAction(action);
    connect(action, SIGNAL(triggered()), this, SLOT(oviActivated()));
}

#ifdef HAVE_CONTENT_MANAGER
/*!
 * Slot that is activated when the user clicked on the gallery item, the widget
 * that activates the ContentManager page. We support this only when the
 * ContentManager library is available.
 */
void
WallpaperWidget::galleryActivated ()
{
    /*
     * Please note that the m_ImageBrowser is a QPointer object that will reset
     * itself to NULL when the widget is destroyed. It will also initialize
     * itself to NULL when it is created.
     */
    if (!m_ImageBrowser) {
        m_ImageBrowser = new SelectSingleContentItemPage (
                QString(),
                QStringList() << "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#Image",
                QString());

        m_ImageBrowser->setObjectName (
                "SelectSingleContentItemPage_imageBrowser");

        connect (m_ImageBrowser, SIGNAL(backButtonClicked()),
                m_ImageBrowser, SLOT(dismiss()));
        connect (m_ImageBrowser, SIGNAL(contentItemSelected(const QString &)),
                this, SLOT(galleryImageSelected(const QString &)));
    }

    m_ImageBrowser->appear (MSceneWindow::DestroyWhenDismissed);
}
#endif

#ifdef HAVE_CONTENT_MANAGER
/*!
 * Slot that activated when the user picks an image from the content manager
 * page. We only need this slot when the ContentManager library is activated.
 */
void
WallpaperWidget::galleryImageSelected (
        const QString &uri)
{
    m_WallpaperBusinessLogic->addImageFromGallery (uri);
}
#endif
<|endoftext|>


<commit_before>/*
 * Copyright 2011 Google Inc.
 *
 * 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.
 */

// Author: pulkitg@google.com (Pulkit Goyal)
//
// Contains implementation of DelayImagesFilter, which delays all the high
// quality images whose low quality inlined data url are available within their
// respective image tag.

#include "net/instaweb/rewriter/public/delay_images_filter.h"

#include <map>
#include <utility>

#include "base/logging.h"
#include "net/instaweb/htmlparse/public/html_element.h"
#include "net/instaweb/htmlparse/public/html_name.h"
#include "net/instaweb/http/public/log_record.h"
#include "net/instaweb/http/public/semantic_type.h"
#include "net/instaweb/rewriter/public/critical_images_finder.h"
#include "net/instaweb/rewriter/public/server_context.h"
#include "net/instaweb/rewriter/public/request_properties.h"
#include "net/instaweb/rewriter/public/resource_tag_scanner.h"
#include "net/instaweb/rewriter/public/rewrite_driver.h"
#include "net/instaweb/rewriter/public/rewrite_options.h"
#include "net/instaweb/rewriter/public/static_asset_manager.h"
#include "net/instaweb/util/enums.pb.h"
#include "net/instaweb/util/public/string.h"

namespace net_instaweb {

const char DelayImagesFilter::kDelayImagesSuffix[] =
    "\npagespeed.delayImagesInit();";

const char DelayImagesFilter::kDelayImagesInlineSuffix[] =
    "\npagespeed.delayImagesInlineInit();";

const char DelayImagesFilter::kOnloadFunction[] =
    "var elem=this;"
    "setTimeout(function(){elem.onload = null;"
    "elem.src=elem.getAttribute('pagespeed_high_res_src');}, 0);";

DelayImagesFilter::DelayImagesFilter(RewriteDriver* driver)
    : driver_(driver),
      static_asset_manager_(
          driver->server_context()->static_asset_manager()),
      num_low_res_inlined_images_(0),
      insert_low_res_images_inplace_(false),
      lazyload_highres_images_(false),
      is_script_inserted_(false) {
}

DelayImagesFilter::~DelayImagesFilter() {}

void DelayImagesFilter::StartDocument() {
  num_low_res_inlined_images_ = 0;
  // Low res images will be placed inside the respective image tag if the user
  // agent is not a mobile, or if mobile aggressive rewriters are turned off.
  // Otherwise, the low res images are inserted at the end of the flush window.
  insert_low_res_images_inplace_ = ShouldRewriteInplace();
  lazyload_highres_images_ = driver_->options()->lazyload_highres_images() &&
      driver_->request_properties()->IsMobile();
  is_script_inserted_ = false;
}

void DelayImagesFilter::EndDocument() {
  low_res_data_map_.clear();
}

void DelayImagesFilter::EndElement(HtmlElement* element) {
  if (element->keyword() == HtmlName::kBody) {
    InsertLowResImagesAndJs(element, /* insert_after_element */ false);
    InsertHighResJs(element);
  } else if (driver_->IsRewritable(element) &&
             (element->keyword() == HtmlName::kImg ||
              element->keyword() == HtmlName::kInput)) {
    // We only handle img and input tag images.  Note that delay_images.js and
    // delay_images_inline.js must be modified to handle other possible tags.
    // We should probably specifically *not* include low res images for link
    // tags of various sorts (favicons, mobile desktop icons, etc.). Use of low
    // res for explicit background images is a more interesting case, but the
    // current DOM walk in the above js files would need to be modified to
    // handle the large number of tags that we can identify in
    // resource_tag_scanner::ScanElement.
    semantic_type::Category category;
    HtmlElement::Attribute* src = resource_tag_scanner::ScanElement(
        element, driver_, &category);

    if (src == NULL || src->DecodedValueOrNull() == NULL ||
        category != semantic_type::kImage) {
      return;
    }
    HtmlElement::Attribute* low_res_src =
        element->FindAttribute(HtmlName::kPagespeedLowResSrc);
    if (low_res_src == NULL || low_res_src->DecodedValueOrNull() == NULL) {
      return;
    }
    ++num_low_res_inlined_images_;
    if (element->FindAttribute(HtmlName::kOnload) == NULL) {
      driver_->log_record()->SetRewriterLoggingStatus(
          RewriteOptions::FilterId(RewriteOptions::kDelayImages),
          RewriterApplication::APPLIED_OK);
      // High res src is added and original img src attribute is removed
      // from img tag.
      driver_->SetAttributeName(src, HtmlName::kPagespeedHighResSrc);
      if (insert_low_res_images_inplace_) {
        // Set the src as the low resolution image.
        driver_->AddAttribute(element, HtmlName::kSrc,
                              low_res_src->DecodedValueOrNull());
        // Add an onload function to set the high resolution image.
        driver_->AddEscapedAttribute(
            element, HtmlName::kOnload, kOnloadFunction);
      } else {
        // Low res image data is collected in low_res_data_map_ map. This
        // low_res_src will be moved just after last low res image in the flush
        // window.
        // It is better to move inlined low resolution data later in the DOM,
        // otherwise they will block further parsing and rendering of the html
        // page.
        // Note that the high resolution images are loaded at end of body.
        const GoogleString& src_content = src->DecodedValueOrNull();
        low_res_data_map_[src_content] = low_res_src->DecodedValueOrNull();
      }
    }
    if (num_low_res_inlined_images_ == driver_->num_inline_preview_images()) {
      if (!insert_low_res_images_inplace_) {
        InsertLowResImagesAndJs(element, /* insert_after_element */ true);
      }
    }
  }
  element->DeleteAttribute(HtmlName::kPagespeedLowResSrc);
}

void DelayImagesFilter::InsertLowResImagesAndJs(HtmlElement* element,
                                                bool insert_after_element) {
  if (low_res_data_map_.empty()) {
    return;
  }
  GoogleString inline_script;
  HtmlElement* current_element = element;
  // Check script for changing src to low res data url is inserted once.
  if (!is_script_inserted_) {
    inline_script = StrCat(
        static_asset_manager_->GetAsset(
            StaticAssetManager::kDelayImagesInlineJs,
            driver_->options()),
        kDelayImagesInlineSuffix,
        static_asset_manager_->GetAsset(
            StaticAssetManager::kDelayImagesJs,
            driver_->options()),
        kDelayImagesSuffix);
    HtmlElement* script_element =
        driver_->NewElement(element, HtmlName::kScript);
    driver_->AddAttribute(script_element, HtmlName::kPagespeedNoDefer, "");
    if (insert_after_element) {
      DCHECK(element->keyword() == HtmlName::kImg ||
             element->keyword() == HtmlName::kInput);
      driver_->InsertNodeAfterNode(current_element, script_element);
      current_element = script_element;
    } else {
      DCHECK(element->keyword() == HtmlName::kBody);
      driver_->AppendChild(element, script_element);
    }
    static_asset_manager_->AddJsToElement(
        inline_script, script_element, driver_);
    is_script_inserted_ = true;
  }

  // Generate javascript map for inline data urls where key is url and
  // base64 encoded data url as its value. This map is added to the
  // html at the end of last low res image.
  GoogleString inline_data_script;
  for (StringStringMap::iterator it = low_res_data_map_.begin();
       it != low_res_data_map_.end(); ++it) {
    inline_data_script = StrCat(
        "\npagespeed.delayImagesInline.addLowResImages('",
        it->first, "', '", it->second, "');");
    StrAppend(&inline_data_script,
              "\npagespeed.delayImagesInline.replaceWithLowRes();\n");
    HtmlElement* low_res_element =
        driver_->NewElement(current_element, HtmlName::kScript);
    driver_->AddAttribute(low_res_element, HtmlName::kPagespeedNoDefer, "");
    if (insert_after_element) {
      driver_->InsertNodeAfterNode(current_element, low_res_element);
      current_element = low_res_element;
    } else {
      driver_->AppendChild(element, low_res_element);
    }
    static_asset_manager_->AddJsToElement(
        inline_data_script, low_res_element, driver_);
  }
  low_res_data_map_.clear();
}

void DelayImagesFilter::InsertHighResJs(HtmlElement* body_element) {
  if (insert_low_res_images_inplace_ || !is_script_inserted_) {
    return;
  }
  GoogleString js;
  if (lazyload_highres_images_) {
    StrAppend(&js,
              "\npagespeed.delayImages.registerLazyLoadHighRes();\n");
  } else {
    StrAppend(&js,
              "\npagespeed.delayImages.replaceWithHighRes();\n");
  }
  HtmlElement* script = driver_->NewElement(body_element, HtmlName::kScript);
  driver_->AddAttribute(script, HtmlName::kPagespeedNoDefer, "");
  driver_->AppendChild(body_element, script);
  static_asset_manager_->AddJsToElement(js, script, driver_);
}

bool DelayImagesFilter::ShouldRewriteInplace() const {
  const RewriteOptions* options = driver_->options();
  return (options->use_blank_image_for_inline_preview() ||
          !(options->enable_aggressive_rewriters_for_mobile() &&
            driver_->request_properties()->IsMobile()));
}

void DelayImagesFilter::DetermineEnabled() {
  AbstractLogRecord* log_record = driver_->log_record();
  if (!driver_->request_properties()->SupportsImageInlining()) {
    log_record->LogRewriterHtmlStatus(
        RewriteOptions::FilterId(RewriteOptions::kDelayImages),
        RewriterHtmlApplication::USER_AGENT_NOT_SUPPORTED);
    set_is_enabled(false);
    return;
  }
  CriticalImagesFinder* finder =
      driver_->server_context()->critical_images_finder();
  if (finder->IsMeaningful(driver_) && !finder->IsSetFromPcache(driver_)) {
    log_record->LogRewriterHtmlStatus(
        RewriteOptions::FilterId(RewriteOptions::kDelayImages),
        RewriterHtmlApplication::PROPERTY_CACHE_MISS);
    set_is_enabled(false);
    return;
  }
  log_record->LogRewriterHtmlStatus(
      RewriteOptions::FilterId(RewriteOptions::kDelayImages),
      RewriterHtmlApplication::ACTIVE);
  set_is_enabled(true);
}

}  // namespace net_instaweb
<commit_msg>delay_images should remain active if split_html_helper is enabled - since it will fill up the critical image info.<commit_after>/*
 * Copyright 2011 Google Inc.
 *
 * 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.
 */

// Author: pulkitg@google.com (Pulkit Goyal)
//
// Contains implementation of DelayImagesFilter, which delays all the high
// quality images whose low quality inlined data url are available within their
// respective image tag.

#include "net/instaweb/rewriter/public/delay_images_filter.h"

#include <map>
#include <utility>

#include "base/logging.h"
#include "net/instaweb/htmlparse/public/html_element.h"
#include "net/instaweb/htmlparse/public/html_name.h"
#include "net/instaweb/http/public/log_record.h"
#include "net/instaweb/http/public/semantic_type.h"
#include "net/instaweb/rewriter/public/critical_images_finder.h"
#include "net/instaweb/rewriter/public/server_context.h"
#include "net/instaweb/rewriter/public/request_properties.h"
#include "net/instaweb/rewriter/public/resource_tag_scanner.h"
#include "net/instaweb/rewriter/public/rewrite_driver.h"
#include "net/instaweb/rewriter/public/rewrite_options.h"
#include "net/instaweb/rewriter/public/static_asset_manager.h"
#include "net/instaweb/util/enums.pb.h"
#include "net/instaweb/util/public/string.h"

namespace net_instaweb {

const char DelayImagesFilter::kDelayImagesSuffix[] =
    "\npagespeed.delayImagesInit();";

const char DelayImagesFilter::kDelayImagesInlineSuffix[] =
    "\npagespeed.delayImagesInlineInit();";

const char DelayImagesFilter::kOnloadFunction[] =
    "var elem=this;"
    "setTimeout(function(){elem.onload = null;"
    "elem.src=elem.getAttribute('pagespeed_high_res_src');}, 0);";

DelayImagesFilter::DelayImagesFilter(RewriteDriver* driver)
    : driver_(driver),
      static_asset_manager_(
          driver->server_context()->static_asset_manager()),
      num_low_res_inlined_images_(0),
      insert_low_res_images_inplace_(false),
      lazyload_highres_images_(false),
      is_script_inserted_(false) {
}

DelayImagesFilter::~DelayImagesFilter() {}

void DelayImagesFilter::StartDocument() {
  num_low_res_inlined_images_ = 0;
  // Low res images will be placed inside the respective image tag if the user
  // agent is not a mobile, or if mobile aggressive rewriters are turned off.
  // Otherwise, the low res images are inserted at the end of the flush window.
  insert_low_res_images_inplace_ = ShouldRewriteInplace();
  lazyload_highres_images_ = driver_->options()->lazyload_highres_images() &&
      driver_->request_properties()->IsMobile();
  is_script_inserted_ = false;
}

void DelayImagesFilter::EndDocument() {
  low_res_data_map_.clear();
}

void DelayImagesFilter::EndElement(HtmlElement* element) {
  if (element->keyword() == HtmlName::kBody) {
    InsertLowResImagesAndJs(element, /* insert_after_element */ false);
    InsertHighResJs(element);
  } else if (driver_->IsRewritable(element) &&
             (element->keyword() == HtmlName::kImg ||
              element->keyword() == HtmlName::kInput)) {
    // We only handle img and input tag images.  Note that delay_images.js and
    // delay_images_inline.js must be modified to handle other possible tags.
    // We should probably specifically *not* include low res images for link
    // tags of various sorts (favicons, mobile desktop icons, etc.). Use of low
    // res for explicit background images is a more interesting case, but the
    // current DOM walk in the above js files would need to be modified to
    // handle the large number of tags that we can identify in
    // resource_tag_scanner::ScanElement.
    semantic_type::Category category;
    HtmlElement::Attribute* src = resource_tag_scanner::ScanElement(
        element, driver_, &category);

    if (src == NULL || src->DecodedValueOrNull() == NULL ||
        category != semantic_type::kImage) {
      return;
    }
    HtmlElement::Attribute* low_res_src =
        element->FindAttribute(HtmlName::kPagespeedLowResSrc);
    if (low_res_src == NULL || low_res_src->DecodedValueOrNull() == NULL) {
      return;
    }
    ++num_low_res_inlined_images_;
    if (element->FindAttribute(HtmlName::kOnload) == NULL) {
      driver_->log_record()->SetRewriterLoggingStatus(
          RewriteOptions::FilterId(RewriteOptions::kDelayImages),
          RewriterApplication::APPLIED_OK);
      // High res src is added and original img src attribute is removed
      // from img tag.
      driver_->SetAttributeName(src, HtmlName::kPagespeedHighResSrc);
      if (insert_low_res_images_inplace_) {
        // Set the src as the low resolution image.
        driver_->AddAttribute(element, HtmlName::kSrc,
                              low_res_src->DecodedValueOrNull());
        // Add an onload function to set the high resolution image.
        driver_->AddEscapedAttribute(
            element, HtmlName::kOnload, kOnloadFunction);
      } else {
        // Low res image data is collected in low_res_data_map_ map. This
        // low_res_src will be moved just after last low res image in the flush
        // window.
        // It is better to move inlined low resolution data later in the DOM,
        // otherwise they will block further parsing and rendering of the html
        // page.
        // Note that the high resolution images are loaded at end of body.
        const GoogleString& src_content = src->DecodedValueOrNull();
        low_res_data_map_[src_content] = low_res_src->DecodedValueOrNull();
      }
    }
    if (num_low_res_inlined_images_ == driver_->num_inline_preview_images()) {
      if (!insert_low_res_images_inplace_) {
        InsertLowResImagesAndJs(element, /* insert_after_element */ true);
      }
    }
  }
  element->DeleteAttribute(HtmlName::kPagespeedLowResSrc);
}

void DelayImagesFilter::InsertLowResImagesAndJs(HtmlElement* element,
                                                bool insert_after_element) {
  if (low_res_data_map_.empty()) {
    return;
  }
  GoogleString inline_script;
  HtmlElement* current_element = element;
  // Check script for changing src to low res data url is inserted once.
  if (!is_script_inserted_) {
    inline_script = StrCat(
        static_asset_manager_->GetAsset(
            StaticAssetManager::kDelayImagesInlineJs,
            driver_->options()),
        kDelayImagesInlineSuffix,
        static_asset_manager_->GetAsset(
            StaticAssetManager::kDelayImagesJs,
            driver_->options()),
        kDelayImagesSuffix);
    HtmlElement* script_element =
        driver_->NewElement(element, HtmlName::kScript);
    driver_->AddAttribute(script_element, HtmlName::kPagespeedNoDefer, "");
    if (insert_after_element) {
      DCHECK(element->keyword() == HtmlName::kImg ||
             element->keyword() == HtmlName::kInput);
      driver_->InsertNodeAfterNode(current_element, script_element);
      current_element = script_element;
    } else {
      DCHECK(element->keyword() == HtmlName::kBody);
      driver_->AppendChild(element, script_element);
    }
    static_asset_manager_->AddJsToElement(
        inline_script, script_element, driver_);
    is_script_inserted_ = true;
  }

  // Generate javascript map for inline data urls where key is url and
  // base64 encoded data url as its value. This map is added to the
  // html at the end of last low res image.
  GoogleString inline_data_script;
  for (StringStringMap::iterator it = low_res_data_map_.begin();
       it != low_res_data_map_.end(); ++it) {
    inline_data_script = StrCat(
        "\npagespeed.delayImagesInline.addLowResImages('",
        it->first, "', '", it->second, "');");
    StrAppend(&inline_data_script,
              "\npagespeed.delayImagesInline.replaceWithLowRes();\n");
    HtmlElement* low_res_element =
        driver_->NewElement(current_element, HtmlName::kScript);
    driver_->AddAttribute(low_res_element, HtmlName::kPagespeedNoDefer, "");
    if (insert_after_element) {
      driver_->InsertNodeAfterNode(current_element, low_res_element);
      current_element = low_res_element;
    } else {
      driver_->AppendChild(element, low_res_element);
    }
    static_asset_manager_->AddJsToElement(
        inline_data_script, low_res_element, driver_);
  }
  low_res_data_map_.clear();
}

void DelayImagesFilter::InsertHighResJs(HtmlElement* body_element) {
  if (insert_low_res_images_inplace_ || !is_script_inserted_) {
    return;
  }
  GoogleString js;
  if (lazyload_highres_images_) {
    StrAppend(&js,
              "\npagespeed.delayImages.registerLazyLoadHighRes();\n");
  } else {
    StrAppend(&js,
              "\npagespeed.delayImages.replaceWithHighRes();\n");
  }
  HtmlElement* script = driver_->NewElement(body_element, HtmlName::kScript);
  driver_->AddAttribute(script, HtmlName::kPagespeedNoDefer, "");
  driver_->AppendChild(body_element, script);
  static_asset_manager_->AddJsToElement(js, script, driver_);
}

bool DelayImagesFilter::ShouldRewriteInplace() const {
  const RewriteOptions* options = driver_->options();
  return (options->use_blank_image_for_inline_preview() ||
          !(options->enable_aggressive_rewriters_for_mobile() &&
            driver_->request_properties()->IsMobile()));
}

void DelayImagesFilter::DetermineEnabled() {
  AbstractLogRecord* log_record = driver_->log_record();
  if (!driver_->request_properties()->SupportsImageInlining()) {
    log_record->LogRewriterHtmlStatus(
        RewriteOptions::FilterId(RewriteOptions::kDelayImages),
        RewriterHtmlApplication::USER_AGENT_NOT_SUPPORTED);
    set_is_enabled(false);
    return;
  }
  CriticalImagesFinder* finder =
      driver_->server_context()->critical_images_finder();
  if (finder->IsMeaningful(driver_) &&
      !finder->IsSetFromPcache(driver_) &&
      !driver_->options()->Enabled(RewriteOptions::kSplitHtmlHelper)) {
    log_record->LogRewriterHtmlStatus(
        RewriteOptions::FilterId(RewriteOptions::kDelayImages),
        RewriterHtmlApplication::PROPERTY_CACHE_MISS);
    set_is_enabled(false);
    return;
  }
  log_record->LogRewriterHtmlStatus(
      RewriteOptions::FilterId(RewriteOptions::kDelayImages),
      RewriterHtmlApplication::ACTIVE);
  set_is_enabled(true);
}

}  // namespace net_instaweb
<|endoftext|>