<commit_before>#include <miniMAT/util/PrintResult.hpp>

#include <iostream>
#include <iomanip>
#include <cmath>

namespace miniMAT {
    namespace util {
        void PrintResult(const std::string& varname, Matrix m, bool suppressed) {
            if (!suppressed) {
                using namespace std;

                int maxdigits = log10(m.maxCoeff()) + 1;    // Get number of digits of max element
                int precision = 4;
                int space = 1, dot = 1;

                // Print a row at a time (default precision is 4)
                cout << varname << " =" << endl << endl;
                for (int i = 0; i < m.rows(); i++) {
                    cout << "    ";
                    for (int j = 0; j < m.cols(); j++)
                        cout << right
                             << fixed
                             << showpoint
                             << setprecision(precision)
                             << setw(maxdigits + precision + dot + space)
                             << m(i,j);
                    cout << endl;
                }
                cout << endl;
            }
        }
    }
}<commit_msg>Adjust formatting in util::PrintResult for row vectors<commit_after>#include <miniMAT/util/PrintResult.hpp>

#include <iostream>
#include <iomanip>
#include <cmath>

namespace miniMAT {
    namespace util {
        void PrintResult(const std::string& varname, Matrix m, bool suppressed) {
            if (!suppressed) {
                using namespace std;

                int maxdigits = log10(m.maxCoeff()) + 1;    // Get number of digits of max element
                int precision = 4;
                int space = 1, dot = 1;

                cout << varname << " =" << endl << endl;
                if (m.rows() == 1) {
                    // Even spacing between elements in a single row
                    for (int j = 0; j < m.cols(); j++)
                        cout << right << fixed << showpoint << setprecision(precision) <<  "   " << m(0, j);
                    cout << endl;
                } else {
                    // More complex formatting for multiple rows
                    for (int i = 0; i < m.rows(); i++) {
                        cout << "    ";
                        for (int j = 0; j < m.cols(); j++)
                            cout << right
                                 << fixed
                                 << showpoint
                                 << setprecision(precision)
                                 << setw(maxdigits + precision + dot + space)
                                 << m(i,j);
                        cout << endl;
                    }
                    cout << endl;
                }
            }
        }
    }
}<|endoftext|>


<commit_before>//-----------------------------------------------------------------------bl-
//--------------------------------------------------------------------------
//
// GRINS - General Reacting Incompressible Navier-Stokes
//
// Copyright (C) 2014-2015 Paul T. Bauman, Roy H. Stogner
// Copyright (C) 2010-2013 The PECOS Development Team
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the Version 2.1 GNU Lesser General
// Public License as published by the Free Software Foundation.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc. 51 Franklin Street, Fifth Floor,
// Boston, MA  02110-1301  USA
//
//-----------------------------------------------------------------------el-

#include "grins_config.h"

// GRINS
#include "grins/mesh_builder.h"
#include "grins/simulation.h"
#include "grins/simulation_builder.h"
#include "grins/multiphysics_sys.h"

//libMesh
#include "libmesh/exact_solution.h"

void test_error_norm( libMesh::ExactSolution& exact_sol,
                      const std::string& system_name,
                      const std::string& var,
                      const std::string& norm,
                      const double tol,
                      int& return_flag );

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

  if( !command_line.search("--input") )
    {
      std::cerr << "ERROR: Must specify input file on command line with --input=<file>." << std::endl;
      exit(1);
    }

  if( !command_line.search("--soln-data") )
    {
      std::cerr << "ERROR: Must specify solution data on command line with --soln-data=<file>." << std::endl;
      exit(1);
    }

  if( !command_line.search("--vars") )
    {
      std::cerr << "ERROR: Must specify variables on command line with --vars='var1 var2'" << std::endl;
      exit(1);
    }

  if( !command_line.search("--norms") )
    {
      std::cerr << "ERROR: Must specify variables on command line with --norms='L2 H1'" << std::endl;
      exit(1);
    }

  // libMesh input file should be first argument
  std::string libMesh_input_filename = command_line("--input", "DIE!");

  // Create our GetPot object.
  GetPot libMesh_inputfile( libMesh_input_filename );

  // Initialize libMesh library.
  libMesh::LibMeshInit libmesh_init(argc, argv);

  GRINS::SimulationBuilder sim_builder;

  GRINS::Simulation grins( libMesh_inputfile,
			   sim_builder,
                           libmesh_init.comm() );

  // Do solve here
  grins.run();

  // Get equation systems to create ExactSolution object
  std::tr1::shared_ptr<libMesh::EquationSystems> es = grins.get_equation_system();

   // Create Exact solution object and attach exact solution quantities
  libMesh::ExactSolution exact_sol(*es);

  libMesh::EquationSystems es_ref( es->get_mesh() );

  // Filename of file where comparison solution is stashed
  std::string solution_file = command_line("--soln-data", "DIE!");
  es_ref.read( solution_file );

  exact_sol.attach_reference_solution( &es_ref );

  // Now grab the variables for which we want to compare
  unsigned int n_vars = command_line.vector_variable_size("--vars");
  std::vector<std::string> vars(n_vars);
  for( unsigned int v = 0; v < n_vars; v++ )
    {
      vars[v] = command_line("--vars", "DIE!", v);
    }

  // Now grab the norms to compute for each variable error
  unsigned int n_norms = command_line.vector_variable_size("--norms");
  std::vector<std::string> norms(n_vars);
  for( unsigned int n = 0; n < n_norms; n++ )
    {
      norms[n] = command_line("--norms", "DIE!", n);
      if( norms[n] != std::string("L2") &&
          norms[n] != std::string("H1") )
        {
          std::cerr << "ERROR: Invalid norm input " << norms[n] << std::endl
                    << "       Valid values are: L2" << std::endl
                    << "                         H1" << std::endl;
        }
    }

  const std::string& system_name = grins.get_multiphysics_system_name();

  // Now compute error for each variable
  for( unsigned int v = 0; v < n_vars; v++ )
    {
      exact_sol.compute_error(system_name, vars[v]);
    }

  int return_flag = 0;

  double tol = 1.0e-10;

  // Now test error for each variable, for each norm
  for( unsigned int v = 0; v < n_vars; v++ )
    {
      for( unsigned int n = 0; n < n_norms; n++ )
        {
          test_error_norm( exact_sol, system_name, vars[v], norms[n], tol, return_flag );
        }
    }

  return return_flag;
}

void test_error_norm( libMesh::ExactSolution& exact_sol,
                      const std::string& system_name,
                      const std::string& var,
                      const std::string& norm,
                      const double tol,
                      int& return_flag )
{
  // We don't set return_flag unless we are setting it 1
  // since this function gets called multiple times and we don't
  // want to overwrite a previous "fail" (return_flag = 1) with
  // a "pass" (return_flag = 0)

  double error = 0.0;

  if( norm == std::string("L2") )
    {
      error = exact_sol.l2_error(system_name, var);
    }
  else if( norm == std::string("H1") )
    {
      error = exact_sol.h1_error(system_name, var);
    }
  else
    {
      std::cerr << "ERROR: Invalid norm " << norm << std::endl;
      exit(1);
    }

  if( error > tol )
    {
      return_flag = 1;

      std::cerr << "Tolerance exceeded for generic regression test!" << std::endl
                << "tolerance     = " << tol << std::endl
                << "norm of error = " << error << std::endl
                << "norm type     = " << norm << std::endl
                << "var           = " << var << std::endl;
    }

  return;
}
<commit_msg>Resize array with correct size<commit_after>//-----------------------------------------------------------------------bl-
//--------------------------------------------------------------------------
//
// GRINS - General Reacting Incompressible Navier-Stokes
//
// Copyright (C) 2014-2015 Paul T. Bauman, Roy H. Stogner
// Copyright (C) 2010-2013 The PECOS Development Team
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the Version 2.1 GNU Lesser General
// Public License as published by the Free Software Foundation.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc. 51 Franklin Street, Fifth Floor,
// Boston, MA  02110-1301  USA
//
//-----------------------------------------------------------------------el-

#include "grins_config.h"

// GRINS
#include "grins/mesh_builder.h"
#include "grins/simulation.h"
#include "grins/simulation_builder.h"
#include "grins/multiphysics_sys.h"

//libMesh
#include "libmesh/exact_solution.h"

void test_error_norm( libMesh::ExactSolution& exact_sol,
                      const std::string& system_name,
                      const std::string& var,
                      const std::string& norm,
                      const double tol,
                      int& return_flag );

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

  if( !command_line.search("--input") )
    {
      std::cerr << "ERROR: Must specify input file on command line with --input=<file>." << std::endl;
      exit(1);
    }

  if( !command_line.search("--soln-data") )
    {
      std::cerr << "ERROR: Must specify solution data on command line with --soln-data=<file>." << std::endl;
      exit(1);
    }

  if( !command_line.search("--vars") )
    {
      std::cerr << "ERROR: Must specify variables on command line with --vars='var1 var2'" << std::endl;
      exit(1);
    }

  if( !command_line.search("--norms") )
    {
      std::cerr << "ERROR: Must specify variables on command line with --norms='L2 H1'" << std::endl;
      exit(1);
    }

  // libMesh input file should be first argument
  std::string libMesh_input_filename = command_line("--input", "DIE!");

  // Create our GetPot object.
  GetPot libMesh_inputfile( libMesh_input_filename );

  // Initialize libMesh library.
  libMesh::LibMeshInit libmesh_init(argc, argv);

  GRINS::SimulationBuilder sim_builder;

  GRINS::Simulation grins( libMesh_inputfile,
			   sim_builder,
                           libmesh_init.comm() );

  // Do solve here
  grins.run();

  // Get equation systems to create ExactSolution object
  std::tr1::shared_ptr<libMesh::EquationSystems> es = grins.get_equation_system();

   // Create Exact solution object and attach exact solution quantities
  libMesh::ExactSolution exact_sol(*es);

  libMesh::EquationSystems es_ref( es->get_mesh() );

  // Filename of file where comparison solution is stashed
  std::string solution_file = command_line("--soln-data", "DIE!");
  es_ref.read( solution_file );

  exact_sol.attach_reference_solution( &es_ref );

  // Now grab the variables for which we want to compare
  unsigned int n_vars = command_line.vector_variable_size("--vars");
  std::vector<std::string> vars(n_vars);
  for( unsigned int v = 0; v < n_vars; v++ )
    {
      vars[v] = command_line("--vars", "DIE!", v);
    }

  // Now grab the norms to compute for each variable error
  unsigned int n_norms = command_line.vector_variable_size("--norms");
  std::vector<std::string> norms(n_norms);
  for( unsigned int n = 0; n < n_norms; n++ )
    {
      norms[n] = command_line("--norms", "DIE!", n);
      if( norms[n] != std::string("L2") &&
          norms[n] != std::string("H1") )
        {
          std::cerr << "ERROR: Invalid norm input " << norms[n] << std::endl
                    << "       Valid values are: L2" << std::endl
                    << "                         H1" << std::endl;
        }
    }

  const std::string& system_name = grins.get_multiphysics_system_name();

  // Now compute error for each variable
  for( unsigned int v = 0; v < n_vars; v++ )
    {
      exact_sol.compute_error(system_name, vars[v]);
    }

  int return_flag = 0;

  double tol = 1.0e-10;

  // Now test error for each variable, for each norm
  for( unsigned int v = 0; v < n_vars; v++ )
    {
      for( unsigned int n = 0; n < n_norms; n++ )
        {
          test_error_norm( exact_sol, system_name, vars[v], norms[n], tol, return_flag );
        }
    }

  return return_flag;
}

void test_error_norm( libMesh::ExactSolution& exact_sol,
                      const std::string& system_name,
                      const std::string& var,
                      const std::string& norm,
                      const double tol,
                      int& return_flag )
{
  // We don't set return_flag unless we are setting it 1
  // since this function gets called multiple times and we don't
  // want to overwrite a previous "fail" (return_flag = 1) with
  // a "pass" (return_flag = 0)

  double error = 0.0;

  if( norm == std::string("L2") )
    {
      error = exact_sol.l2_error(system_name, var);
    }
  else if( norm == std::string("H1") )
    {
      error = exact_sol.h1_error(system_name, var);
    }
  else
    {
      std::cerr << "ERROR: Invalid norm " << norm << std::endl;
      exit(1);
    }

  if( error > tol )
    {
      return_flag = 1;

      std::cerr << "Tolerance exceeded for generic regression test!" << std::endl
                << "tolerance     = " << tol << std::endl
                << "norm of error = " << error << std::endl
                << "norm type     = " << norm << std::endl
                << "var           = " << var << std::endl;
    }

  return;
}
<|endoftext|>


<commit_before>/*
 * SessionRequest.hpp
 *
 * Copyright (C) 2009-16 by RStudio, Inc.
 *
 * Unless you have received this program directly from RStudio pursuant
 * to the terms of a commercial license agreement with RStudio, then
 * this program is licensed to you under the terms of version 3 of the
 * GNU Affero General Public License. This program is distributed WITHOUT
 * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT,
 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the
 * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details.
 *
 */

#ifndef SESSION_REQUEST_HPP
#define SESSION_REQUEST_HPP

#include <core/Error.hpp>
#include <core/system/Environment.hpp>

#include <session/http/SessionRequest.hpp>

#if !defined(_WIN32)
#include <core/http/TcpIpBlockingClient.hpp>
#include <core/http/LocalStreamBlockingClient.hpp>
#else
#include <core/http/NamedPipeBlockingClient.hpp>
#endif

#if !defined(_WIN32)
#include <session/SessionLocalStreams.hpp>
#endif

#include <session/SessionConstants.hpp>

namespace rstudio {
namespace session {
namespace http {

// this function sends an request directly to the session; it's inlined so that
// it can be used both from the postback executable (which does not link with
// rsession) and the session itself
inline core::Error sendSessionRequest(const std::string& uri,
      const std::string& body, core::http::Response* pResponse)
{
   // build request
   core::http::Request request;
   request.setMethod("POST");
   request.setUri(uri);
   request.setHeader("Accept", "*/*");
   request.setHeader("Connection", "close");
   request.setBody(body);

#ifdef _WIN32
   // get local peer
   std::string pipeName = core::system::getenv("RS_LOCAL_PEER");
   pRequest->setHeader("X-Shared-Secret",
                       core::system::getenv("RS_SHARED_SECRET"));
   return core::http::sendRequest(pipeName,
                            *pRequest,
                            ConnectionRetryProfile(
                                  boost::posix_time::seconds(10),
                                  boost::posix_time::milliseconds(50)),
                            pResponse);
#else
   std::string tcpipPort = core::system::getenv(kRSessionStandalonePortNumber);
   if (!tcpipPort.empty())
   {
      return core::http::sendRequest("127.0.0.1", tcpipPort, request,
            pResponse);
   }
   else
   {
      // determine stream path
      std::string stream = core::system::getenv(kRStudioSessionStream);
      core::FilePath streamPath = session::local_streams::streamPath(stream);
      return core::http::sendRequest(streamPath, request, pResponse);
   }
#endif

   return core::Success();
}

} // namespace http
} // namespace session
} // namespace rstudio

#endif
<commit_msg>add support for desktop-mode authenticated session requests<commit_after>/*
 * SessionRequest.hpp
 *
 * Copyright (C) 2009-16 by RStudio, Inc.
 *
 * Unless you have received this program directly from RStudio pursuant
 * to the terms of a commercial license agreement with RStudio, then
 * this program is licensed to you under the terms of version 3 of the
 * GNU Affero General Public License. This program is distributed WITHOUT
 * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT,
 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the
 * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details.
 *
 */

#ifndef SESSION_REQUEST_HPP
#define SESSION_REQUEST_HPP

#include <core/Error.hpp>
#include <core/system/Environment.hpp>

#include <session/http/SessionRequest.hpp>

#if !defined(_WIN32)
#include <core/http/TcpIpBlockingClient.hpp>
#include <core/http/LocalStreamBlockingClient.hpp>
#else
#include <core/http/NamedPipeBlockingClient.hpp>
#endif

#if !defined(_WIN32)
#include <session/SessionLocalStreams.hpp>
#endif

#include <session/SessionConstants.hpp>

namespace rstudio {
namespace session {
namespace http {

// this function sends an request directly to the session; it's inlined so that
// it can be used both from the postback executable (which does not link with
// rsession) and the session itself
inline core::Error sendSessionRequest(const std::string& uri,
      const std::string& body, core::http::Response* pResponse)
{
   // build request
   core::http::Request request;
   request.setMethod("POST");
   request.setUri(uri);
   request.setHeader("Accept", "*/*");
   request.setHeader("Connection", "close");
   request.setBody(body);

#ifdef _WIN32
   // get local peer
   std::string pipeName = core::system::getenv("RS_LOCAL_PEER");
   request.setHeader("X-Shared-Secret",
                       core::system::getenv("RS_SHARED_SECRET"));
   return core::http::sendRequest(pipeName,
                            request,
                            ConnectionRetryProfile(
                                  boost::posix_time::seconds(10),
                                  boost::posix_time::milliseconds(50)),
                            pResponse);
#else
   std::string tcpipPort = core::system::getenv(kRSessionStandalonePortNumber);
   if (tcpipPort.empty())
   {
      // if no standalone port, make an authenticated session request
      tcpipPort = core::system::getenv(kRSessionPortNumber);
      request.setHeader("X-Shared-Secret",
                          core::system::getenv("RS_SHARED_SECRET"));
   }
   if (!tcpipPort.empty())
   {
      return core::http::sendRequest("127.0.0.1", tcpipPort, request,
            pResponse);
   }
   else
   {
      // determine stream path
      std::string stream = core::system::getenv(kRStudioSessionStream);
      core::FilePath streamPath = session::local_streams::streamPath(stream);
      return core::http::sendRequest(streamPath, request, pResponse);
   }
#endif

   return core::Success();
}

} // namespace http
} // namespace session
} // namespace rstudio

#endif
<|endoftext|>


<commit_before>
#include "Ubidots.h"

ubidots Ubidots("CCN8FrVulRYGulPTkbaiR9Myx8qN2o");

void setup() {
    Serial.begin(115200);
}
void loop() {
    #include "application.h"
#include "Ubidots.h"

#define TOKEN "YOUR_TOKEN_OF_UBIDOTS_HERE"

#define ID "YOUR_ID_HERE"

Ubidots ubidots(TOKEN);

void setup() {
    Serial.begin(115200);

}
void loop() {

    float value1 = analogRead(A0);
    float value2 = analogRead(A1);
    float value3 = analogRead(A2);
    ubidots.send_ubidots( value1, "Temperatura", ram,"Servomotor", value2, "Humedad", value3 );
    float n = ubidots.get_ubidots(ID);
    Serial.println(n);
    delay(300);
}
<commit_msg>Update Ubidots_example.cpp<commit_after>
#include "Ubidots.h"

ubidots Ubidots("CCN8FrVulRYGulPTkbaiR9Myx8qN2o");

void setup() {
    Serial.begin(115200);
}
void loop() {
    #include "application.h"
#include "Ubidots.h"

#define TOKEN "YOUR_TOKEN_OF_UBIDOTS_HERE"

#define ID "YOUR_ID_HERE"

Ubidots ubidots(TOKEN);

void setup() {
    Serial.begin(115200);

}
void loop() {
    int quantityOfVariables
    float value1 = analogRead(A0);
    float value2 = analogRead(A1);
    float value3 = analogRead(A2);
    // First arg is to send the quantity of variables, and the next arg is the name of the first
    // variable between first variable value
    ubidots.send_ubidots( quantityOfVariables, "Temperatura", value1,"Servomotor", value2, "Humedad", value3 );
    float n = ubidots.get_ubidots(ID);
    Serial.println(n);
    delay(300);
}
<|endoftext|>


<commit_before>/* RTcmix  - Copyright (C) 2005  The RTcmix Development Team
   See ``AUTHORS'' for a list of contributors. See ``LICENSE'' for
   the license to this software and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <rtcmix_types.h>
#include <PField.h>
#include <DisplayPField.h>
#include <RTcmixDisplay.h>
#include <ugens.h>		// for warn, die
#include <utils.h>		// for createPFieldHandle

// ------------------------------------------------------------- makedisplay ---
//
//    display = makedisplay(handle, [prefix[, units,]] [precision])
//
//    First argument is a PField handle, such as that returned by a call
//    to makeconnection("midi", ...). Other arguments, which are optional:
//
//    <prefix>       label to display in window [string]
//    <units>        units (e.g., "Hz") to display in window [string]
//    <precision>    digits after decimal point to display in window [number]
//
//    If <prefix> is missing or an empty string, then no label printed in
//    window.
//                                                               JGG, 2/8/05

static PFieldWrapper *
_makedisplay_usage()
{
	die("makedisplay",
		"Usage: makedisplay(handle, [prefix[, units,]] [precision])");
	return NULL;
}

static PFieldWrapper *
create_pfield(const Arg args[], const int nargs)
{
	if (nargs < 1)
		return _makedisplay_usage();

	if (!args[0].isType(HandleType)) {
		die("makedisplay", "First argument must be a valid pfield handle.");
		return NULL;
	}
	PField *pfield = (PField *) args[0];

	const char *prefix = NULL, *units = NULL;
	int precision = 3;

	// Handle the optional arguments.
	// <prefix> and <units> strings must appear in that order.  <precision>
	// follows either or both of the strings, or replaces both.  (I.e., it
	// appears after of a list of 0, 1, or 2 strings.)
	if (nargs > 1) {
		if (args[1].isType(StringType)) {
			prefix = args[1];
			if (nargs > 2) {
				if (args[2].isType(StringType)) {
					units = args[2];
					if (nargs > 3) {
						if (args[3].isType(DoubleType))
							precision = (int) args[3];
						else
							return _makedisplay_usage();
					}
				}
				else
					precision = (int) args[2];
			}
		}
		else
			precision = (int) args[1];
	}

	static RTcmixDisplay *displaywin = NULL;
	if (displaywin == NULL)					// first time, so make window
		displaywin = createDisplayWindow();
	if (displaywin == NULL) {
		die("makedisplay", "Failed to create display window");
		return NULL;
	}

	return new DisplayPField(pfield, displaywin, prefix, units, precision);
}

// The following functions are the publicly-visible ones called by the
// system.

extern "C" {
	Handle create_handle(const Arg args[], const int nargs);
	int register_dso();
};

Handle
create_handle(const Arg args[], const int nargs)
{
	PField *pField = create_pfield(args, nargs);
	Handle handle = NULL;
	if (pField != NULL) {
		handle = createPFieldHandle(pField);
	}
	return handle;
}

int register_dso()
{
	 return 0;
}

<commit_msg>Some name changes in preparation for move to makemonitor.<commit_after>/* RTcmix  - Copyright (C) 2005  The RTcmix Development Team
   See ``AUTHORS'' for a list of contributors. See ``LICENSE'' for
   the license to this software and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <rtcmix_types.h>
#include <PField.h>
#include <DisplayPField.h>
#include <RTcmixDisplay.h>
#include <ugens.h>		// for warn, die
#include <utils.h>		// for createPFieldHandle

// -----------------------------------------------------------------------------
//
//    display = makemonitor(handle, "display", [prefix[, units,]] [precision])
//
//    First argument is a PField handle, such as that returned by a call
//    to makeconnection("midi", ...). Other arguments, which are optional:
//
//    <prefix>       label to display in window [string]
//    <units>        units (e.g., "Hz") to display in window [string]
//    <precision>    digits after decimal point to display in window [number]
//
//    If <prefix> is missing or an empty string, then no label printed in
//    window.
//                                                               JGG, 2/8/05

static PFieldWrapper *
_display_usage()
{
	die("makemonitor",
		"Usage: makemonitor(handle, \"display\", [prefix[, units,]] [precision])");
	return NULL;
}

static PFieldWrapper *
create_pfield(const Arg args[], const int nargs)
{
	if (nargs < 1)
		return _display_usage();

	if (!args[0].isType(HandleType)) {
		die("makemonitor (display)", "First argument must be a valid pfield handle.");
		return NULL;
	}
	PField *pfield = (PField *) args[0];

	const char *prefix = NULL, *units = NULL;
	int precision = 3;

	// Handle the optional arguments.
	// <prefix> and <units> strings must appear in that order.  <precision>
	// follows either or both of the strings, or replaces both.  (I.e., it
	// appears after of a list of 0, 1, or 2 strings.)
	if (nargs > 1) {
		if (args[1].isType(StringType)) {
			prefix = args[1];
			if (nargs > 2) {
				if (args[2].isType(StringType)) {
					units = args[2];
					if (nargs > 3) {
						if (args[3].isType(DoubleType))
							precision = (int) args[3];
						else
							return _display_usage();
					}
				}
				else
					precision = (int) args[2];
			}
		}
		else
			precision = (int) args[1];
	}

	static RTcmixDisplay *displaywin = NULL;
	if (displaywin == NULL)					// first time, so make window
		displaywin = createDisplayWindow();
	if (displaywin == NULL) {
		die("makemonitor (display)", "Failed to create display window");
		return NULL;
	}

	return new DisplayPField(pfield, displaywin, prefix, units, precision);
}

// The following functions are the publicly-visible ones called by the
// system.

extern "C" {
	Handle create_handle(const Arg args[], const int nargs);
	int register_dso();
};

Handle
create_handle(const Arg args[], const int nargs)
{
	PField *pField = create_pfield(args, nargs);
	Handle handle = NULL;
	if (pField != NULL) {
		handle = createPFieldHandle(pField);
	}
	return handle;
}

int register_dso()
{
	 return 0;
}

<|endoftext|>


<commit_before>////////////////////////////////////////////////////////////////////////////////
//
// Author: Artur Szostak
// Email:  artur@alice.phy.uct.ac.za | artursz@iafrica.com
//
////////////////////////////////////////////////////////////////////////////////

/* Sample macro indicating how to run the micro dHLT version.
 */

void RunMicrodHLT(Bool_t rundebug = kFALSE)
{
	if (rundebug)
		gSystem->Load("../lib/Linux-debug/libMUONHLT.so");
	else
		gSystem->Load("../lib/Linux/libMUONHLT.so");

	cout << "dHLT Version: " << AliMUONHLT::Version() << endl;

	AliMUONDataInterface data;
	data.SetFile();

	// Load the trigger data.
	AliMUONHLT::TriggerSource ts;
	ts.DataToUse(AliMUONHLT::TriggerSource::FromHits);
	ts.FillFrom(&data);

	// Load the cluster data.
	AliMUONHLT::ClusterSource cs;
	cs.DataToUse(AliMUONHLT::ClusterSource::FromHits);
	cs.FillFrom(&data);

	// Create a Track output object.
	AliMUONHLT::TrackSink trackout;

	// Create the dHLT process object and connect it to input and output.
	AliMUONHLT::MicrodHLT dhlt;
	dhlt.SetTriggerSource(&ts);
	dhlt.SetClusterSource(&cs);
	dhlt.SetTrackSink(&trackout);

	// run the dHLT
	cout << "running..." << endl;
	dhlt.Run();

	// Display the output:
	if ( ! trackout.GetFirstEvent())
		cout << "No tracks found." << endl;

	while (trackout.MoreEvents())
	{
		cout << "================= Event: " << trackout.CurrentEvent() << " =================" << endl;
		Int_t blocknum = 0;

		if ( ! trackout.GetFirstBlock() )
			cout << "No track blocks found." << endl;

		while (trackout.MoreBlocks())
		{
			cout << "Block: " << blocknum++ << endl;
			cout << "\tReal\tReal\tHLT\tHLT\tHLT\tL0\tL0" << endl;
			cout << "\tP\tPt\tSign\tP\tPt\tSign\tPt" << endl;

			if ( trackout.GetFirstTrack() == NULL )
				cout << "\tNo tracks found." << endl;

			while (trackout.MoreTracks())
			{
				AliMUONHLT::Track* track = trackout.GetTrack();

				// Find the corresponding trigger record.
				AliMUONHLT::TriggerRecord* trigrec = NULL;
				ts.GetEvent(trackout.CurrentEvent());

				if (ts.GetFirstBlock())
				{
					do
					{
						trigrec = ts.GetTrigger( track->TriggerID() );
						if (trigrec != NULL) break;
					} while (ts.GetNextBlock());
				};
				if (trigrec == NULL)
				{
					cerr << "Error: could not find corresponding trigger record!" << endl;
					continue;
				};

				// Find the corresponding particle in Kine.
				// Note: track->fTriggerID happens to be the TreeH track number when
				// filling from Hit objects.
				data.GetEvent(trackout.CurrentEvent());
				AliMUONHit* hit = data.Hit(track->TriggerID(), 0);
				if (hit == NULL)
				{
					cerr << "Warning: Could not find hit 0 for track number = "
					<< track->TriggerID() << endl;
					continue;
				};

				// Need to decode the particle index.
				Int_t num_primaries = data.NumberOfTracks();
				Int_t num_tracks = data.NumberOfParticles();
				Int_t particleindex;
				if (hit->Track() < num_primaries)
					particleindex = hit->Track() + num_tracks - num_primaries;
				else
					particleindex =  hit->Track()- num_primaries;

				TParticle* p = data.Particle(particleindex);

				// All data found, now write output:
				cout << "\t" << p->P()
					<< "\t" << p->Pt()
					<< "\t" << track->ParticleSign()
					<< "\t" << track->P()
					<< "\t" << track->Pt()
					<< "\t" << trigrec->ParticleSign()
					<< "\t" << trigrec->Pt()
					<< endl;

				trackout.GetNextTrack();
			};
			trackout.GetNextBlock();
		};
		trackout.GetNextEvent();
	};
};
<commit_msg>This is deprecated and is being removed.<commit_after><|endoftext|>


<commit_before>/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 1999 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xalan" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */
#if !defined(FUNCTIONROUND_HEADER_GUARD_1357924680)
#define FUNCTIONROUND_HEADER_GUARD_1357924680

// Base header file.  Must be first.
#include <XPath/XPathDefinitions.hpp>

#include <vector>

// Base class header file...
// Base class header file...
#include <XPath/Function.hpp>

#include <XPath/XObject.hpp>
#include <XPath/XObjectFactory.hpp>
#include <XPath/XPathExecutionContext.hpp>

/**
 * XPath implementation of "round" function.
 */
//
// These are all inline, even though
// there are virtual functions, because we expect that they will only be
// needed by the XPath class.
class XALAN_XPATH_EXPORT FunctionRound : public Function
{
public:

	// These methods are inherited from Function ...

	virtual XObject*
	execute(
			XPathExecutionContext&			executionContext,
			XalanNode*						context,
			int								/* opPos */,
			const XObjectArgVectorType&		args)
	{
		if (args.size() != 1)
		{
			executionContext.error("The round() function takes one argument!",
								   context);
		}

		const double	theValue = args[0]->num();

		// $$$ ToDo: This is not really correct, but will do for now...
		const long	theRoundedValue = static_cast<long>(theValue < 0 ? theValue - 0.5 : theValue + 0.5);

		return executionContext.getXObjectFactory().createNumber(theRoundedValue);
	}

#if defined(XALAN_NO_COVARIANT_RETURN_TYPE)
	virtual Function*
#else
	virtual FunctionRound*
#endif
	clone() const
	{
		return new FunctionRound(*this);
	}

private:

	// Not implemented...
	FunctionRound&
	operator=(const FunctionRound&);

	bool
	operator==(const FunctionRound&) const;
};

#endif	// FUNCTIONROUND_HEADER_GUARD_1357924680
<commit_msg>Handle special values (NaN, etc.), and some other special cases correctly.<commit_after>/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 1999 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xalan" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */
#if !defined(FUNCTIONROUND_HEADER_GUARD_1357924680)
#define FUNCTIONROUND_HEADER_GUARD_1357924680

// Base header file.  Must be first.
#include <XPath/XPathDefinitions.hpp>

#include <cmath>
#include <vector>

// Base class header file...
#include <XPath/Function.hpp>

#include <PlatformSupport/DoubleSupport.hpp>

#include <XPath/XObject.hpp>
#include <XPath/XObjectFactory.hpp>
#include <XPath/XPathExecutionContext.hpp>

/**
 * XPath implementation of "round" function.
 */
//
// These are all inline, even though
// there are virtual functions, because we expect that they will only be
// needed by the XPath class.
class XALAN_XPATH_EXPORT FunctionRound : public Function
{
public:

	// These methods are inherited from Function ...

	virtual XObject*
	execute(
			XPathExecutionContext&			executionContext,
			XalanNode*						context,
			int								/* opPos */,
			const XObjectArgVectorType&		args)
	{
		if (args.size() != 1)
		{
			executionContext.error("The round() function takes one argument!",
								   context);
		}

		const double	theValue = args[0]->num();

		return executionContext.getXObjectFactory().createNumber(getRoundedValue(theValue));
	}

#if defined(XALAN_NO_COVARIANT_RETURN_TYPE)
	virtual Function*
#else
	virtual FunctionRound*
#endif
	clone() const
	{
		return new FunctionRound(*this);
	}

	static double
	getRoundedValue(double	theValue)
	{
		if (DoubleSupport::isNaN(theValue))
		{
			return DoubleSupport::getNaN();
		}
		else if (DoubleSupport::isPositiveInfinity(theValue))
		{
			return DoubleSupport::getPositiveInfinity();
		}
		if (DoubleSupport::isNegativeInfinity(theValue))
		{
			return DoubleSupport::getNegativeInfinity();
		}
		else if (theValue == 0)
		{
			return 0.0;
		}
		else if (theValue > 0)
		{
			return static_cast<long>(theValue + 0.5);
		}
		else
		{
			// Negative numbers are a special case.  Any time we
			// have -0.5 as the fractional part, we have to
			// round up (toward 0), rather than down.
			double			intPart = 0;

			const double	fracPart = modf(theValue, &intPart);

			if (fracPart == -0.5)
			{
				// special case -- we have have to round toward 0...
				return static_cast<long>(theValue + 0.5);
			}
			else
			{
				return static_cast<long>(theValue - 0.5);
			}
		}
	}

private:

	// Not implemented...
	FunctionRound&
	operator=(const FunctionRound&);

	bool
	operator==(const FunctionRound&) const;
};

#endif	// FUNCTIONROUND_HEADER_GUARD_1357924680
<|endoftext|>


<commit_before>#include "SearchA2DMatrixII.hpp"

bool SearchA2DMatrixII::searchMatrix(vector<vector<int>> &matrix, int target) {
    int r = matrix.size();
    int c = matrix[0].size();
    int i = 0;
    int j = c - 1;

    while (i < r && j >= 0) {
        int p = matrix[i][j];

        if (p == target)
            return true;
        else if (p < target)
            i++;
        else
            j--;
    }

    return false;
}<commit_msg>Refine Problem 240. Search a 2D Matrix II<commit_after>#include "SearchA2DMatrixII.hpp"

bool SearchA2DMatrixII::searchMatrix(vector<vector<int>> &matrix, int target) {
    int m = matrix.size();
    if (m == 0) return false;
    int n = matrix[0].size();
    if (n == 0) return false;

    int i = 0;
    int j = n - 1;

    // from top right to bottom left
    while (i < m && j >= 0) {
        int p = matrix[i][j];

        if (p == target)
            return true;
        else if (p < target)
            i++;
        else
            j--;
    }

    return false;
}<|endoftext|>


<commit_before>#ifndef _STATISTICS_TOOLS_HPP_
#define _STATISTICS_TOOLS_HPP_

#include <cmath>
#include <glog/logging.h>

inline double inc_avg(double curr_avg, uint64_t count, double val) {
	return curr_avg + (val-curr_avg)/(count);
}

inline uint64_t max2(uint64_t a, uint64_t b) {
  return (a>b) ? a : b;
}

class RunningStandardDeviation {
  private:
    double s0;
    double s1;
    double s2;

  public:
    RunningStandardDeviation() {
      reset();
    }

    void reset() {
        s0 = 0.0;
        s1 = 0.0;
        s2 = 0.0;
    }

    void addSample( uint64_t value ) {
        s0 += 1;
        s1 += value;
        s2 += pow(value, 2);
    }

    double value() {
      double sq = s0*s2 - pow(s1, 2);
      if (sq > 0 && s0 > 0) {
        LOG(INFO) << "CHECKSDEV" << sq << " " << s0;
        return sqrt(sq) / s0;
      } else {
        LOG(INFO) << "CHECKSDEV" << sq << " " << s0;
        return 0;
      }
    }

    void merge( RunningStandardDeviation other ) {
      s0 += other.s0;
      s1 += other.s1;
      s2 += other.s2;
    }
};

#endif // STATISTICS_TOOLS_HPP_
<commit_msg>remove a debug printout (I think)<commit_after>#ifndef _STATISTICS_TOOLS_HPP_
#define _STATISTICS_TOOLS_HPP_

#include <cmath>
#include <glog/logging.h>

inline double inc_avg(double curr_avg, uint64_t count, double val) {
	return curr_avg + (val-curr_avg)/(count);
}

inline uint64_t max2(uint64_t a, uint64_t b) {
  return (a>b) ? a : b;
}

class RunningStandardDeviation {
  private:
    double s0;
    double s1;
    double s2;

  public:
    RunningStandardDeviation() {
      reset();
    }

    void reset() {
        s0 = 0.0;
        s1 = 0.0;
        s2 = 0.0;
    }

    void addSample( uint64_t value ) {
        s0 += 1;
        s1 += value;
        s2 += pow(value, 2);
    }

    double value() {
      double sq = s0*s2 - pow(s1, 2);
      if (sq > 0 && s0 > 0) {
        return sqrt(sq) / s0;
      } else {
        return 0;
      }
    }

    void merge( RunningStandardDeviation other ) {
      s0 += other.s0;
      s1 += other.s1;
      s2 += other.s2;
    }
};

#endif // STATISTICS_TOOLS_HPP_
<|endoftext|>


<commit_before>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/automation/extension_port_container.h"

#include "base/logging.h"
#include "base/json/json_reader.h"
#include "base/json/json_writer.h"
#include "base/values.h"
#include "chrome/browser/automation/automation_provider.h"
#include "chrome/browser/automation/extension_automation_constants.h"
#include "chrome/browser/browser_thread.h"
#include "chrome/browser/extensions/extension_message_service.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/renderer_host/render_process_host.h"
#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/render_messages.h"
#include "chrome/test/automation/automation_messages.h"

// TODO(siggi): Find a more structured way to read and write JSON messages.

namespace ext = extension_automation_constants;

ExtensionPortContainer::ExtensionPortContainer(AutomationProvider* automation,
                                               int tab_handle) :
    automation_(automation), service_(NULL), port_id_(-1),
    tab_handle_(tab_handle) {
  service_ = automation_->profile()->GetExtensionMessageService();
  DCHECK(service_);
}

ExtensionPortContainer::~ExtensionPortContainer() {
  DCHECK_EQ(MessageLoop::current()->type(), MessageLoop::TYPE_UI);

  if (port_id_ != -1)
    service_->CloseChannel(port_id_);
}

bool ExtensionPortContainer::PostResponseToExternalPort(
    const std::string& message) {
  return automation_->Send(
      new AutomationMsg_ForwardMessageToExternalHost(
          0, tab_handle_, message, ext::kAutomationOrigin,
          ext::kAutomationPortResponseTarget));
}

bool ExtensionPortContainer::PostMessageToExternalPort(
    const std::string& message) {
  return automation_->Send(
      new AutomationMsg_ForwardMessageToExternalHost(
          0, tab_handle_, message,
          ext::kAutomationOrigin,
          ext::kAutomationPortRequestTarget));
}

void ExtensionPortContainer::PostMessageFromExternalPort(
    const std::string &message) {
  service_->PostMessageFromRenderer(port_id_, message);
}

bool ExtensionPortContainer::Connect(const std::string &extension_id,
                                     int process_id,
                                     int routing_id,
                                     int connection_id,
                                     const std::string& channel_name,
                                     const std::string& tab_json) {
  DCHECK_EQ(MessageLoop::current()->type(), MessageLoop::TYPE_UI);

  port_id_ = service_->OpenSpecialChannelToExtension(
      extension_id, channel_name, tab_json, this);
  if (port_id_ == -1) {
    // In this case a disconnect message has been dispatched.
    return false;
  }

  SendConnectionResponse(connection_id, port_id_);
  return true;
}

void ExtensionPortContainer::SendConnectionResponse(int connection_id,
                                                    int port_id) {
  // Compose the reply message.
  scoped_ptr<DictionaryValue> msg_dict(new DictionaryValue());
  msg_dict->SetInteger(ext::kAutomationRequestIdKey, ext::CHANNEL_OPENED);
  msg_dict->SetInteger(ext::kAutomationConnectionIdKey, connection_id);
  msg_dict->SetInteger(ext::kAutomationPortIdKey, port_id);

  std::string msg_json;
  base::JSONWriter::Write(msg_dict.get(), false, &msg_json);

  PostResponseToExternalPort(msg_json);
}

bool ExtensionPortContainer::Send(IPC::Message *message) {
  DCHECK_EQ(MessageLoop::current()->type(), MessageLoop::TYPE_UI);

  IPC_BEGIN_MESSAGE_MAP(ExtensionPortContainer, *message)
    IPC_MESSAGE_HANDLER(ViewMsg_ExtensionMessageInvoke,
                        OnExtensionMessageInvoke)
    IPC_MESSAGE_UNHANDLED_ERROR()
  IPC_END_MESSAGE_MAP()

  delete message;
  return true;
}

void ExtensionPortContainer::OnExtensionMessageInvoke(
    const std::string& extension_id,
    const std::string& function_name,
    const ListValue& args,
    const GURL& event_url) {
  if (function_name == ExtensionMessageService::kDispatchOnMessage) {
    DCHECK_EQ(args.GetSize(), 2u);

    std::string message;
    int source_port_id;
    if (args.GetString(0, &message) && args.GetInteger(1, &source_port_id))
      OnExtensionHandleMessage(message, source_port_id);
  } else if (function_name == ExtensionMessageService::kDispatchOnDisconnect) {
    DCHECK_EQ(args.GetSize(), 1u);
    int port_id;
    if (args.GetInteger(0, &port_id))
      OnExtensionPortDisconnected(port_id);
  } else if (function_name == ExtensionMessageService::kDispatchOnConnect) {
    // Do nothing.
    // TODO(siggi): implement
  } else {
    NOTREACHED() << function_name << " shouldn't be called.";
  }
}

void ExtensionPortContainer::OnExtensionHandleMessage(
    const std::string& message, int source_port_id) {
  // Compose the reply message and fire it away.
  DictionaryValue msg_dict;
  msg_dict.SetInteger(ext::kAutomationRequestIdKey, ext::POST_MESSAGE);
  msg_dict.SetInteger(ext::kAutomationPortIdKey, port_id_);
  msg_dict.SetString(ext::kAutomationMessageDataKey, message);

  std::string msg_json;
  base::JSONWriter::Write(&msg_dict, false, &msg_json);

  PostMessageToExternalPort(msg_json);
}

void ExtensionPortContainer::OnExtensionPortDisconnected(int source_port_id) {
  // Compose the disconnect message and fire it away.
  DictionaryValue msg_dict;
  msg_dict.SetInteger(ext::kAutomationRequestIdKey, ext::CHANNEL_CLOSED);
  msg_dict.SetInteger(ext::kAutomationPortIdKey, port_id_);

  std::string msg_json;
  base::JSONWriter::Write(&msg_dict, false, &msg_json);

  PostMessageToExternalPort(msg_json);
}

bool ExtensionPortContainer::InterceptMessageFromExternalHost(
    const std::string& message, const std::string& origin,
    const std::string& target, AutomationProvider* automation,
    RenderViewHost *view_host, int tab_handle) {
  if (target != ext::kAutomationPortRequestTarget)
    return false;

  if (origin != ext::kAutomationOrigin) {
    // TODO(siggi): Should we block the message on wrong origin?
    LOG(WARNING) << "Wrong origin on automation port message " << origin;
  }

  scoped_ptr<Value> message_value(base::JSONReader::Read(message, false));
  DCHECK(message_value->IsType(Value::TYPE_DICTIONARY));
  if (!message_value->IsType(Value::TYPE_DICTIONARY))
    return true;

  DictionaryValue* message_dict =
      reinterpret_cast<DictionaryValue*>(message_value.get());

  int command = -1;
  bool got_value = message_dict->GetInteger(ext::kAutomationRequestIdKey,
                                            &command);
  DCHECK(got_value);
  if (!got_value)
    return true;

  if (command == ext::OPEN_CHANNEL) {
    // Extract the "extension_id" and "connection_id" parameters.
    std::string extension_id;
    got_value = message_dict->GetString(ext::kAutomationExtensionIdKey,
                                        &extension_id);
    DCHECK(got_value);
    if (!got_value)
      return true;

    int connection_id;
    got_value = message_dict->GetInteger(ext::kAutomationConnectionIdKey,
                                         &connection_id);
    DCHECK(got_value);
    if (!got_value)
      return true;

    std::string channel_name;
    // Channel name is optional.
    message_dict->GetString(ext::kAutomationChannelNameKey, &channel_name);

    // Tab information is optional, try to retrieve it
    // and re-flatten it to a string.
    std::string tab_json("null");
    DictionaryValue* tab = NULL;
    if (message_dict->GetDictionary(ext::kAutomationTabJsonKey, &tab))
      base::JSONWriter::Write(tab, false, &tab_json);

    int routing_id = view_host->routing_id();
    // Create the extension port and connect it.
    scoped_ptr<ExtensionPortContainer> port(
        new ExtensionPortContainer(automation, tab_handle));

    int process_id = view_host->process()->id();
    if (port->Connect(extension_id, process_id, routing_id, connection_id,
                      channel_name, tab_json)) {
      // We have a successful connection.
      automation->AddPortContainer(port.release());
    }
  } else if (command == ext::POST_MESSAGE) {
    int port_id = -1;
    got_value = message_dict->GetInteger(ext::kAutomationPortIdKey, &port_id);
    DCHECK(got_value);
    if (!got_value)
      return true;

    std::string data;
    got_value = message_dict->GetString(ext::kAutomationMessageDataKey, &data);
    DCHECK(got_value);
    if (!got_value)
      return true;

    ExtensionPortContainer* port = automation->GetPortContainer(port_id);
    DCHECK(port);
    if (port)
      port->PostMessageFromExternalPort(data);
  } else if (command == ext::CHANNEL_CLOSED) {
    int port_id = -1;
    got_value = message_dict->GetInteger(ext::kAutomationPortIdKey, &port_id);
    DCHECK(got_value);
    if (!got_value)
      return true;

    ExtensionPortContainer* port = automation->GetPortContainer(port_id);
    DCHECK(port);
    if (port) {
      // This will delete the port and notify the other end of the disconnect.
      automation->RemovePortContainer(port);
    }
  } else {
    // We don't expect other messages here.
    NOTREACHED();
  }

  return true;
}
<commit_msg>A recent change (r64277) added an extra argument to Port.dispatchOnDisconnect() causing this DCHECK to trigger because it was still checking for the old number of arguments.  Changed the DCHECK condition to test for the correct number.<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/automation/extension_port_container.h"

#include "base/logging.h"
#include "base/json/json_reader.h"
#include "base/json/json_writer.h"
#include "base/values.h"
#include "chrome/browser/automation/automation_provider.h"
#include "chrome/browser/automation/extension_automation_constants.h"
#include "chrome/browser/browser_thread.h"
#include "chrome/browser/extensions/extension_message_service.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/renderer_host/render_process_host.h"
#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/render_messages.h"
#include "chrome/test/automation/automation_messages.h"

// TODO(siggi): Find a more structured way to read and write JSON messages.

namespace ext = extension_automation_constants;

ExtensionPortContainer::ExtensionPortContainer(AutomationProvider* automation,
                                               int tab_handle) :
    automation_(automation), service_(NULL), port_id_(-1),
    tab_handle_(tab_handle) {
  service_ = automation_->profile()->GetExtensionMessageService();
  DCHECK(service_);
}

ExtensionPortContainer::~ExtensionPortContainer() {
  DCHECK_EQ(MessageLoop::current()->type(), MessageLoop::TYPE_UI);

  if (port_id_ != -1)
    service_->CloseChannel(port_id_);
}

bool ExtensionPortContainer::PostResponseToExternalPort(
    const std::string& message) {
  return automation_->Send(
      new AutomationMsg_ForwardMessageToExternalHost(
          0, tab_handle_, message, ext::kAutomationOrigin,
          ext::kAutomationPortResponseTarget));
}

bool ExtensionPortContainer::PostMessageToExternalPort(
    const std::string& message) {
  return automation_->Send(
      new AutomationMsg_ForwardMessageToExternalHost(
          0, tab_handle_, message,
          ext::kAutomationOrigin,
          ext::kAutomationPortRequestTarget));
}

void ExtensionPortContainer::PostMessageFromExternalPort(
    const std::string &message) {
  service_->PostMessageFromRenderer(port_id_, message);
}

bool ExtensionPortContainer::Connect(const std::string &extension_id,
                                     int process_id,
                                     int routing_id,
                                     int connection_id,
                                     const std::string& channel_name,
                                     const std::string& tab_json) {
  DCHECK_EQ(MessageLoop::current()->type(), MessageLoop::TYPE_UI);

  port_id_ = service_->OpenSpecialChannelToExtension(
      extension_id, channel_name, tab_json, this);
  if (port_id_ == -1) {
    // In this case a disconnect message has been dispatched.
    return false;
  }

  SendConnectionResponse(connection_id, port_id_);
  return true;
}

void ExtensionPortContainer::SendConnectionResponse(int connection_id,
                                                    int port_id) {
  // Compose the reply message.
  scoped_ptr<DictionaryValue> msg_dict(new DictionaryValue());
  msg_dict->SetInteger(ext::kAutomationRequestIdKey, ext::CHANNEL_OPENED);
  msg_dict->SetInteger(ext::kAutomationConnectionIdKey, connection_id);
  msg_dict->SetInteger(ext::kAutomationPortIdKey, port_id);

  std::string msg_json;
  base::JSONWriter::Write(msg_dict.get(), false, &msg_json);

  PostResponseToExternalPort(msg_json);
}

bool ExtensionPortContainer::Send(IPC::Message *message) {
  DCHECK_EQ(MessageLoop::current()->type(), MessageLoop::TYPE_UI);

  IPC_BEGIN_MESSAGE_MAP(ExtensionPortContainer, *message)
    IPC_MESSAGE_HANDLER(ViewMsg_ExtensionMessageInvoke,
                        OnExtensionMessageInvoke)
    IPC_MESSAGE_UNHANDLED_ERROR()
  IPC_END_MESSAGE_MAP()

  delete message;
  return true;
}

void ExtensionPortContainer::OnExtensionMessageInvoke(
    const std::string& extension_id,
    const std::string& function_name,
    const ListValue& args,
    const GURL& event_url) {
  if (function_name == ExtensionMessageService::kDispatchOnMessage) {
    DCHECK_EQ(args.GetSize(), 2u);

    std::string message;
    int source_port_id;
    if (args.GetString(0, &message) && args.GetInteger(1, &source_port_id))
      OnExtensionHandleMessage(message, source_port_id);
  } else if (function_name == ExtensionMessageService::kDispatchOnDisconnect) {
    DCHECK_EQ(args.GetSize(), 2u);
    int port_id;
    if (args.GetInteger(0, &port_id))
      OnExtensionPortDisconnected(port_id);
  } else if (function_name == ExtensionMessageService::kDispatchOnConnect) {
    // Do nothing.
    // TODO(siggi): implement
  } else {
    NOTREACHED() << function_name << " shouldn't be called.";
  }
}

void ExtensionPortContainer::OnExtensionHandleMessage(
    const std::string& message, int source_port_id) {
  // Compose the reply message and fire it away.
  DictionaryValue msg_dict;
  msg_dict.SetInteger(ext::kAutomationRequestIdKey, ext::POST_MESSAGE);
  msg_dict.SetInteger(ext::kAutomationPortIdKey, port_id_);
  msg_dict.SetString(ext::kAutomationMessageDataKey, message);

  std::string msg_json;
  base::JSONWriter::Write(&msg_dict, false, &msg_json);

  PostMessageToExternalPort(msg_json);
}

void ExtensionPortContainer::OnExtensionPortDisconnected(int source_port_id) {
  // Compose the disconnect message and fire it away.
  DictionaryValue msg_dict;
  msg_dict.SetInteger(ext::kAutomationRequestIdKey, ext::CHANNEL_CLOSED);
  msg_dict.SetInteger(ext::kAutomationPortIdKey, port_id_);

  std::string msg_json;
  base::JSONWriter::Write(&msg_dict, false, &msg_json);

  PostMessageToExternalPort(msg_json);
}

bool ExtensionPortContainer::InterceptMessageFromExternalHost(
    const std::string& message, const std::string& origin,
    const std::string& target, AutomationProvider* automation,
    RenderViewHost *view_host, int tab_handle) {
  if (target != ext::kAutomationPortRequestTarget)
    return false;

  if (origin != ext::kAutomationOrigin) {
    // TODO(siggi): Should we block the message on wrong origin?
    LOG(WARNING) << "Wrong origin on automation port message " << origin;
  }

  scoped_ptr<Value> message_value(base::JSONReader::Read(message, false));
  DCHECK(message_value->IsType(Value::TYPE_DICTIONARY));
  if (!message_value->IsType(Value::TYPE_DICTIONARY))
    return true;

  DictionaryValue* message_dict =
      reinterpret_cast<DictionaryValue*>(message_value.get());

  int command = -1;
  bool got_value = message_dict->GetInteger(ext::kAutomationRequestIdKey,
                                            &command);
  DCHECK(got_value);
  if (!got_value)
    return true;

  if (command == ext::OPEN_CHANNEL) {
    // Extract the "extension_id" and "connection_id" parameters.
    std::string extension_id;
    got_value = message_dict->GetString(ext::kAutomationExtensionIdKey,
                                        &extension_id);
    DCHECK(got_value);
    if (!got_value)
      return true;

    int connection_id;
    got_value = message_dict->GetInteger(ext::kAutomationConnectionIdKey,
                                         &connection_id);
    DCHECK(got_value);
    if (!got_value)
      return true;

    std::string channel_name;
    // Channel name is optional.
    message_dict->GetString(ext::kAutomationChannelNameKey, &channel_name);

    // Tab information is optional, try to retrieve it
    // and re-flatten it to a string.
    std::string tab_json("null");
    DictionaryValue* tab = NULL;
    if (message_dict->GetDictionary(ext::kAutomationTabJsonKey, &tab))
      base::JSONWriter::Write(tab, false, &tab_json);

    int routing_id = view_host->routing_id();
    // Create the extension port and connect it.
    scoped_ptr<ExtensionPortContainer> port(
        new ExtensionPortContainer(automation, tab_handle));

    int process_id = view_host->process()->id();
    if (port->Connect(extension_id, process_id, routing_id, connection_id,
                      channel_name, tab_json)) {
      // We have a successful connection.
      automation->AddPortContainer(port.release());
    }
  } else if (command == ext::POST_MESSAGE) {
    int port_id = -1;
    got_value = message_dict->GetInteger(ext::kAutomationPortIdKey, &port_id);
    DCHECK(got_value);
    if (!got_value)
      return true;

    std::string data;
    got_value = message_dict->GetString(ext::kAutomationMessageDataKey, &data);
    DCHECK(got_value);
    if (!got_value)
      return true;

    ExtensionPortContainer* port = automation->GetPortContainer(port_id);
    DCHECK(port);
    if (port)
      port->PostMessageFromExternalPort(data);
  } else if (command == ext::CHANNEL_CLOSED) {
    int port_id = -1;
    got_value = message_dict->GetInteger(ext::kAutomationPortIdKey, &port_id);
    DCHECK(got_value);
    if (!got_value)
      return true;

    ExtensionPortContainer* port = automation->GetPortContainer(port_id);
    DCHECK(port);
    if (port) {
      // This will delete the port and notify the other end of the disconnect.
      automation->RemovePortContainer(port);
    }
  } else {
    // We don't expect other messages here.
    NOTREACHED();
  }

  return true;
}
<|endoftext|>


<commit_before>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/profiles/avatar_menu_model.h"

#include "base/string16.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/profiles/avatar_menu_model_observer.h"
#include "chrome/browser/profiles/profile_info_cache.h"
#include "chrome/test/base/testing_browser_process.h"
#include "chrome/test/base/testing_profile_manager.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace {

class MockObserver : public AvatarMenuModelObserver {
 public:
  MockObserver() : count_(0) {}
  virtual ~MockObserver() {}

  virtual void OnAvatarMenuModelChanged(
      AvatarMenuModel* avatar_menu_model) OVERRIDE{
    ++count_;
  }

  int change_count() { return count_; }

 private:
  int count_;
};

class AvatarMenuModelTest : public testing::Test {
 public:
  AvatarMenuModelTest()
      : manager_(static_cast<TestingBrowserProcess*>(g_browser_process)) {
  }

  virtual void SetUp() {
    ASSERT_TRUE(manager_.SetUp());
#if defined(OS_CHROMEOS)
    // AvatarMenu and multiple profiles works after user logged in.
    manager_.SetLoggedIn(true);
#endif
  }

  Browser* browser() { return NULL; }

  TestingProfileManager* manager() { return &manager_; }

 private:
  TestingProfileManager manager_;
};

TEST_F(AvatarMenuModelTest, InitialCreation) {
  string16 name1(ASCIIToUTF16("Test 1"));
  string16 name2(ASCIIToUTF16("Test 2"));

  manager()->CreateTestingProfile("p1", name1, 0);
  manager()->CreateTestingProfile("p2", name2, 0);

  MockObserver observer;
  EXPECT_EQ(0, observer.change_count());

  AvatarMenuModel model(manager()->profile_info_cache(), &observer, browser());
  EXPECT_EQ(0, observer.change_count());

  ASSERT_EQ(2U, model.GetNumberOfItems());

  const AvatarMenuModel::Item& item1 = model.GetItemAt(0);
  EXPECT_EQ(0U, item1.model_index);
  EXPECT_EQ(name1, item1.name);

  const AvatarMenuModel::Item& item2 = model.GetItemAt(1);
  EXPECT_EQ(1U, item2.model_index);
  EXPECT_EQ(name2, item2.name);
}

TEST_F(AvatarMenuModelTest, ActiveItem) {
  string16 name1(ASCIIToUTF16("Test 1"));
  string16 name2(ASCIIToUTF16("Test 2"));

  manager()->CreateTestingProfile("p1", name1, 0);
  manager()->CreateTestingProfile("p2", name2, 0);

  MockObserver observer;
  AvatarMenuModel model(manager()->profile_info_cache(), &observer, browser());
  ASSERT_EQ(2U, model.GetNumberOfItems());
  // TODO(jeremy): Expand test to verify active profile index other than 0
  // crbug.com/100871
  ASSERT_EQ(0U, model.GetActiveProfileIndex());
}

TEST_F(AvatarMenuModelTest, ModifyingNameResortsCorrectly) {
  string16 name1(ASCIIToUTF16("Alpha"));
  string16 name2(ASCIIToUTF16("Beta"));
  string16 newname1(ASCIIToUTF16("Gamma"));

  manager()->CreateTestingProfile("p1", name1, 0);
  manager()->CreateTestingProfile("p2", name2, 0);

  MockObserver observer;
  AvatarMenuModel model(manager()->profile_info_cache(), &observer, browser());
  EXPECT_EQ(0, observer.change_count());

  ASSERT_EQ(2U, model.GetNumberOfItems());

  const AvatarMenuModel::Item& item1 = model.GetItemAt(0);
  EXPECT_EQ(0U, item1.model_index);
  EXPECT_EQ(name1, item1.name);

  const AvatarMenuModel::Item& item2 = model.GetItemAt(1);
  EXPECT_EQ(1U, item2.model_index);
  EXPECT_EQ(name2, item2.name);

  // Change name of the first profile, to trigger resorting of the profiles:
  // now the first model should be named "beta", and the second be "gamma".
  manager()->profile_info_cache()->SetNameOfProfileAtIndex(0, newname1);
  const AvatarMenuModel::Item& item1next = model.GetItemAt(0);
  EXPECT_GT(observer.change_count(), 1);
  EXPECT_EQ(0U, item1next.model_index);
  EXPECT_EQ(name2, item1next.name);

  const AvatarMenuModel::Item& item2next = model.GetItemAt(1);
  EXPECT_EQ(1U, item2next.model_index);
  EXPECT_EQ(newname1, item2next.name);
}

TEST_F(AvatarMenuModelTest, ChangeOnNotify) {
  string16 name1(ASCIIToUTF16("Test 1"));
  string16 name2(ASCIIToUTF16("Test 2"));

  manager()->CreateTestingProfile("p1", name1, 0);
  manager()->CreateTestingProfile("p2", name2, 0);

  MockObserver observer;
  EXPECT_EQ(0, observer.change_count());

  AvatarMenuModel model(manager()->profile_info_cache(), &observer, browser());
  EXPECT_EQ(0, observer.change_count());
  EXPECT_EQ(2U, model.GetNumberOfItems());

  string16 name3(ASCIIToUTF16("Test 3"));
  manager()->CreateTestingProfile("p3", name3, 0);

  // Four changes happened via the call to CreateTestingProfile: adding the
  // profile to the cache, setting the user name, rebuilding the list of
  // profiles after the name change, and changing the avatar.
  // On Windows, an extra change happens to set the shortcut name for the
  // profile.
  EXPECT_GE(4, observer.change_count());
  ASSERT_EQ(3U, model.GetNumberOfItems());

  const AvatarMenuModel::Item& item1 = model.GetItemAt(0);
  EXPECT_EQ(0U, item1.model_index);
  EXPECT_EQ(name1, item1.name);

  const AvatarMenuModel::Item& item2 = model.GetItemAt(1);
  EXPECT_EQ(1U, item2.model_index);
  EXPECT_EQ(name2, item2.name);

  const AvatarMenuModel::Item& item3 = model.GetItemAt(2);
  EXPECT_EQ(2U, item3.model_index);
  EXPECT_EQ(name3, item3.name);
}

}  // namespace
<commit_msg>Fix reversed condition check in AvatarMenuModelTest.<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/profiles/avatar_menu_model.h"

#include "base/string16.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/profiles/avatar_menu_model_observer.h"
#include "chrome/browser/profiles/profile_info_cache.h"
#include "chrome/test/base/testing_browser_process.h"
#include "chrome/test/base/testing_profile_manager.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace {

class MockObserver : public AvatarMenuModelObserver {
 public:
  MockObserver() : count_(0) {}
  virtual ~MockObserver() {}

  virtual void OnAvatarMenuModelChanged(
      AvatarMenuModel* avatar_menu_model) OVERRIDE{
    ++count_;
  }

  int change_count() { return count_; }

 private:
  int count_;
};

class AvatarMenuModelTest : public testing::Test {
 public:
  AvatarMenuModelTest()
      : manager_(static_cast<TestingBrowserProcess*>(g_browser_process)) {
  }

  virtual void SetUp() {
    ASSERT_TRUE(manager_.SetUp());
#if defined(OS_CHROMEOS)
    // AvatarMenu and multiple profiles works after user logged in.
    manager_.SetLoggedIn(true);
#endif
  }

  Browser* browser() { return NULL; }

  TestingProfileManager* manager() { return &manager_; }

 private:
  TestingProfileManager manager_;
};

TEST_F(AvatarMenuModelTest, InitialCreation) {
  string16 name1(ASCIIToUTF16("Test 1"));
  string16 name2(ASCIIToUTF16("Test 2"));

  manager()->CreateTestingProfile("p1", name1, 0);
  manager()->CreateTestingProfile("p2", name2, 0);

  MockObserver observer;
  EXPECT_EQ(0, observer.change_count());

  AvatarMenuModel model(manager()->profile_info_cache(), &observer, browser());
  EXPECT_EQ(0, observer.change_count());

  ASSERT_EQ(2U, model.GetNumberOfItems());

  const AvatarMenuModel::Item& item1 = model.GetItemAt(0);
  EXPECT_EQ(0U, item1.model_index);
  EXPECT_EQ(name1, item1.name);

  const AvatarMenuModel::Item& item2 = model.GetItemAt(1);
  EXPECT_EQ(1U, item2.model_index);
  EXPECT_EQ(name2, item2.name);
}

TEST_F(AvatarMenuModelTest, ActiveItem) {
  string16 name1(ASCIIToUTF16("Test 1"));
  string16 name2(ASCIIToUTF16("Test 2"));

  manager()->CreateTestingProfile("p1", name1, 0);
  manager()->CreateTestingProfile("p2", name2, 0);

  MockObserver observer;
  AvatarMenuModel model(manager()->profile_info_cache(), &observer, browser());
  ASSERT_EQ(2U, model.GetNumberOfItems());
  // TODO(jeremy): Expand test to verify active profile index other than 0
  // crbug.com/100871
  ASSERT_EQ(0U, model.GetActiveProfileIndex());
}

TEST_F(AvatarMenuModelTest, ModifyingNameResortsCorrectly) {
  string16 name1(ASCIIToUTF16("Alpha"));
  string16 name2(ASCIIToUTF16("Beta"));
  string16 newname1(ASCIIToUTF16("Gamma"));

  manager()->CreateTestingProfile("p1", name1, 0);
  manager()->CreateTestingProfile("p2", name2, 0);

  MockObserver observer;
  AvatarMenuModel model(manager()->profile_info_cache(), &observer, browser());
  EXPECT_EQ(0, observer.change_count());

  ASSERT_EQ(2U, model.GetNumberOfItems());

  const AvatarMenuModel::Item& item1 = model.GetItemAt(0);
  EXPECT_EQ(0U, item1.model_index);
  EXPECT_EQ(name1, item1.name);

  const AvatarMenuModel::Item& item2 = model.GetItemAt(1);
  EXPECT_EQ(1U, item2.model_index);
  EXPECT_EQ(name2, item2.name);

  // Change name of the first profile, to trigger resorting of the profiles:
  // now the first model should be named "beta", and the second be "gamma".
  manager()->profile_info_cache()->SetNameOfProfileAtIndex(0, newname1);
  const AvatarMenuModel::Item& item1next = model.GetItemAt(0);
  EXPECT_GT(observer.change_count(), 1);
  EXPECT_EQ(0U, item1next.model_index);
  EXPECT_EQ(name2, item1next.name);

  const AvatarMenuModel::Item& item2next = model.GetItemAt(1);
  EXPECT_EQ(1U, item2next.model_index);
  EXPECT_EQ(newname1, item2next.name);
}

TEST_F(AvatarMenuModelTest, ChangeOnNotify) {
  string16 name1(ASCIIToUTF16("Test 1"));
  string16 name2(ASCIIToUTF16("Test 2"));

  manager()->CreateTestingProfile("p1", name1, 0);
  manager()->CreateTestingProfile("p2", name2, 0);

  MockObserver observer;
  EXPECT_EQ(0, observer.change_count());

  AvatarMenuModel model(manager()->profile_info_cache(), &observer, browser());
  EXPECT_EQ(0, observer.change_count());
  EXPECT_EQ(2U, model.GetNumberOfItems());

  string16 name3(ASCIIToUTF16("Test 3"));
  manager()->CreateTestingProfile("p3", name3, 0);

  // Four changes happened via the call to CreateTestingProfile: adding the
  // profile to the cache, setting the user name, rebuilding the list of
  // profiles after the name change, and changing the avatar.
  // On Windows, an extra change happens to set the shortcut name for the
  // profile.
  EXPECT_GE(observer.change_count(), 4);
  ASSERT_EQ(3U, model.GetNumberOfItems());

  const AvatarMenuModel::Item& item1 = model.GetItemAt(0);
  EXPECT_EQ(0U, item1.model_index);
  EXPECT_EQ(name1, item1.name);

  const AvatarMenuModel::Item& item2 = model.GetItemAt(1);
  EXPECT_EQ(1U, item2.model_index);
  EXPECT_EQ(name2, item2.name);

  const AvatarMenuModel::Item& item3 = model.GetItemAt(2);
  EXPECT_EQ(2U, item3.model_index);
  EXPECT_EQ(name3, item3.name);
}

}  // namespace
<|endoftext|>


<commit_before>// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// For information about interceptions as a whole see
// http://wiki/Main/ChromeSandboxInterceptionDesign

#include "sandbox/src/interception_agent.h"

#include "sandbox/src/interception_internal.h"
#include "sandbox/src/eat_resolver.h"
#include "sandbox/src/sidestep_resolver.h"
#include "sandbox/src/sandbox_nt_util.h"

namespace {

// Returns true if target lies between base and base + range.
bool IsWithinRange(const void* base, size_t range, const void* target) {
  const char* end = reinterpret_cast<const char*>(base) + range;
  return reinterpret_cast<const char*>(target) < end;
}

}  // namespace

namespace sandbox {

// This is the list of all imported symbols from ntdll.dll.
SANDBOX_INTERCEPT NtExports g_nt;

// Memory buffer mapped from the parent, with the list of interceptions.
SANDBOX_INTERCEPT SharedMemory* g_interceptions = NULL;

InterceptionAgent* InterceptionAgent::GetInterceptionAgent() {
  static InterceptionAgent* s_singleton = NULL;
  if (!s_singleton) {
    if (!g_interceptions)
      return NULL;

    size_t array_bytes = g_interceptions->num_intercepted_dlls * sizeof(void*);
    s_singleton = reinterpret_cast<InterceptionAgent*>(
        new(NT_ALLOC) char[array_bytes + sizeof(InterceptionAgent)]);

    bool success = s_singleton->Init(g_interceptions);
    if (!success) {
      operator delete(s_singleton, NT_ALLOC);
      s_singleton = NULL;
    }
  }
  return s_singleton;
}

bool InterceptionAgent::Init(SharedMemory* shared_memory) {
  interceptions_ = shared_memory;
  for (int i = 0 ; i < shared_memory->num_intercepted_dlls; i++)
    dlls_[i] = NULL;
  return true;
}

bool InterceptionAgent::DllMatch(const UNICODE_STRING* full_path,
                                 const UNICODE_STRING* name,
                                 const DllPatchInfo* dll_info) {
  UNICODE_STRING current_name;
  current_name.Length = static_cast<USHORT>(g_nt.wcslen(dll_info->dll_name) *
                                            sizeof(wchar_t));
  current_name.MaximumLength = current_name.Length;
  current_name.Buffer = const_cast<wchar_t*>(dll_info->dll_name);

  BOOLEAN case_insensitive = TRUE;
  if (full_path &&
      !g_nt.RtlCompareUnicodeString(&current_name, full_path, case_insensitive))
    return true;

  if (!g_nt.RtlCompareUnicodeString(&current_name, name, case_insensitive))
    return true;

  return false;
}

bool InterceptionAgent::OnDllLoad(const UNICODE_STRING* full_path,
                                  const UNICODE_STRING* name,
                                  void* base_address) {
  DllPatchInfo* dll_info = interceptions_->dll_list;
  int i = 0;
  for (; i < interceptions_->num_intercepted_dlls; i++) {
    if (DllMatch(full_path, name, dll_info))
      break;

    dll_info = reinterpret_cast<DllPatchInfo*>(
                   reinterpret_cast<char*>(dll_info) + dll_info->record_bytes);
  }

  // Return now if the dll is not in our list of interest.
  if (i == interceptions_->num_intercepted_dlls)
    return true;

  // The dll must be unloaded.
  if (dll_info->unload_module)
    return false;

  // Purify causes this condition to trigger.
  if (dlls_[i])
    return true;

  size_t buffer_bytes = offsetof(DllInterceptionData, thunks) +
                        dll_info->num_functions * sizeof(ThunkData);
  dlls_[i] = reinterpret_cast<DllInterceptionData*>(
                 new(NT_PAGE) char[buffer_bytes]);

  DCHECK_NT(dlls_[i]);
  if (!dlls_[i])
    return true;

  dlls_[i]->data_bytes = buffer_bytes;
  dlls_[i]->num_thunks = 0;
  dlls_[i]->base = base_address;
  dlls_[i]->used_bytes = offsetof(DllInterceptionData, thunks);

  VERIFY(PatchDll(dll_info, dlls_[i]));

  ULONG old_protect;
  SIZE_T real_size = buffer_bytes;
  void* to_protect = dlls_[i];
  VERIFY_SUCCESS(g_nt.ProtectVirtualMemory(NtCurrentProcess, &to_protect,
                                           &real_size, PAGE_EXECUTE_READ,
                                           &old_protect));
  return true;
}

void InterceptionAgent::OnDllUnload(void* base_address) {
  for (int i = 0; i < interceptions_->num_intercepted_dlls; i++) {
    if (dlls_[i] && dlls_[i]->base == base_address) {
      operator delete(dlls_[i], NT_PAGE);
      dlls_[i] = NULL;
      break;
    }
  }
}

// TODO(rvargas): We have to deal with prebinded dlls. I see two options: change
// the timestamp of the patched dll, or modify the info on the prebinded dll.
// the first approach messes matching of debug symbols, the second one is more
// complicated.
bool InterceptionAgent::PatchDll(const DllPatchInfo* dll_info,
                                 DllInterceptionData* thunks) {
  DCHECK_NT(NULL != thunks);
  DCHECK_NT(NULL != dll_info);

  const FunctionInfo* function = reinterpret_cast<const FunctionInfo*>(
      reinterpret_cast<const char*>(dll_info) + dll_info->offset_to_functions);

  for (int i = 0; i < dll_info->num_functions; i++) {
    if (!IsWithinRange(dll_info, dll_info->record_bytes, function->function)) {
      NOTREACHED_NT();
      return false;
    }

    ResolverThunk* resolver = GetResolver(function->type);
    if (!resolver)
      return false;

    const char* interceptor = function->function +
                              g_nt.strlen(function->function) + 1;

    if (!IsWithinRange(function, function->record_bytes, interceptor) ||
        !IsWithinRange(dll_info, dll_info->record_bytes, interceptor)) {
      NOTREACHED_NT();
      return false;
    }

    NTSTATUS ret = resolver->Setup(thunks->base,
                                   interceptions_->interceptor_base,
                                   function->function,
                                   interceptor,
                                   function->interceptor_address,
                                   &thunks->thunks[i],
                                   sizeof(ThunkData),
                                   NULL);
    if (!NT_SUCCESS(ret)) {
      NOTREACHED_NT();
      return false;
    }

    thunks->num_thunks++;
    thunks->used_bytes += sizeof(ThunkData);

    function = reinterpret_cast<const FunctionInfo*>(
        reinterpret_cast<const char*>(function) + function->record_bytes);
  }

  return true;
}

// This method is called from within the loader lock
ResolverThunk* InterceptionAgent::GetResolver(InterceptionType type) {
  static EatResolverThunk* eat_resolver = NULL;
  static SidestepResolverThunk* sidestep_resolver = NULL;
  static SmartSidestepResolverThunk* smart_sidestep_resolver = NULL;

  if (!eat_resolver)
    eat_resolver = new(NT_ALLOC) EatResolverThunk;

  if (!sidestep_resolver)
    sidestep_resolver = new(NT_ALLOC) SidestepResolverThunk;

  if (!smart_sidestep_resolver)
    smart_sidestep_resolver = new(NT_ALLOC) SmartSidestepResolverThunk;

  switch (type) {
    case INTERCEPTION_EAT:
      return eat_resolver;
    case INTERCEPTION_SIDESTEP:
      return sidestep_resolver;
    case INTERCEPTION_SMART_SIDESTEP:
      return smart_sidestep_resolver;
    default:
      NOTREACHED_NT();
  }

  return NULL;
}

}  // namespace sandbox

<commit_msg>Use of null string on DLLMatch happens on the bots - Not in my machine unless I incredibuild. - But change makes sense.<commit_after>// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// For information about interceptions as a whole see
// http://wiki/Main/ChromeSandboxInterceptionDesign

#include "sandbox/src/interception_agent.h"

#include "sandbox/src/interception_internal.h"
#include "sandbox/src/eat_resolver.h"
#include "sandbox/src/sidestep_resolver.h"
#include "sandbox/src/sandbox_nt_util.h"

namespace {

// Returns true if target lies between base and base + range.
bool IsWithinRange(const void* base, size_t range, const void* target) {
  const char* end = reinterpret_cast<const char*>(base) + range;
  return reinterpret_cast<const char*>(target) < end;
}

}  // namespace

namespace sandbox {

// This is the list of all imported symbols from ntdll.dll.
SANDBOX_INTERCEPT NtExports g_nt;

// Memory buffer mapped from the parent, with the list of interceptions.
SANDBOX_INTERCEPT SharedMemory* g_interceptions = NULL;

InterceptionAgent* InterceptionAgent::GetInterceptionAgent() {
  static InterceptionAgent* s_singleton = NULL;
  if (!s_singleton) {
    if (!g_interceptions)
      return NULL;

    size_t array_bytes = g_interceptions->num_intercepted_dlls * sizeof(void*);
    s_singleton = reinterpret_cast<InterceptionAgent*>(
        new(NT_ALLOC) char[array_bytes + sizeof(InterceptionAgent)]);

    bool success = s_singleton->Init(g_interceptions);
    if (!success) {
      operator delete(s_singleton, NT_ALLOC);
      s_singleton = NULL;
    }
  }
  return s_singleton;
}

bool InterceptionAgent::Init(SharedMemory* shared_memory) {
  interceptions_ = shared_memory;
  for (int i = 0 ; i < shared_memory->num_intercepted_dlls; i++)
    dlls_[i] = NULL;
  return true;
}

bool InterceptionAgent::DllMatch(const UNICODE_STRING* full_path,
                                 const UNICODE_STRING* name,
                                 const DllPatchInfo* dll_info) {
  UNICODE_STRING current_name;
  current_name.Length = static_cast<USHORT>(g_nt.wcslen(dll_info->dll_name) *
                                            sizeof(wchar_t));
  current_name.MaximumLength = current_name.Length;
  current_name.Buffer = const_cast<wchar_t*>(dll_info->dll_name);

  BOOLEAN case_insensitive = TRUE;
  if (full_path &&
      !g_nt.RtlCompareUnicodeString(&current_name, full_path, case_insensitive))
    return true;

  if (name &&
      !g_nt.RtlCompareUnicodeString(&current_name, name, case_insensitive))
    return true;

  return false;
}

bool InterceptionAgent::OnDllLoad(const UNICODE_STRING* full_path,
                                  const UNICODE_STRING* name,
                                  void* base_address) {
  DllPatchInfo* dll_info = interceptions_->dll_list;
  int i = 0;
  for (; i < interceptions_->num_intercepted_dlls; i++) {
    if (DllMatch(full_path, name, dll_info))
      break;

    dll_info = reinterpret_cast<DllPatchInfo*>(
                   reinterpret_cast<char*>(dll_info) + dll_info->record_bytes);
  }

  // Return now if the dll is not in our list of interest.
  if (i == interceptions_->num_intercepted_dlls)
    return true;

  // The dll must be unloaded.
  if (dll_info->unload_module)
    return false;

  // Purify causes this condition to trigger.
  if (dlls_[i])
    return true;

  size_t buffer_bytes = offsetof(DllInterceptionData, thunks) +
                        dll_info->num_functions * sizeof(ThunkData);
  dlls_[i] = reinterpret_cast<DllInterceptionData*>(
                 new(NT_PAGE) char[buffer_bytes]);

  DCHECK_NT(dlls_[i]);
  if (!dlls_[i])
    return true;

  dlls_[i]->data_bytes = buffer_bytes;
  dlls_[i]->num_thunks = 0;
  dlls_[i]->base = base_address;
  dlls_[i]->used_bytes = offsetof(DllInterceptionData, thunks);

  VERIFY(PatchDll(dll_info, dlls_[i]));

  ULONG old_protect;
  SIZE_T real_size = buffer_bytes;
  void* to_protect = dlls_[i];
  VERIFY_SUCCESS(g_nt.ProtectVirtualMemory(NtCurrentProcess, &to_protect,
                                           &real_size, PAGE_EXECUTE_READ,
                                           &old_protect));
  return true;
}

void InterceptionAgent::OnDllUnload(void* base_address) {
  for (int i = 0; i < interceptions_->num_intercepted_dlls; i++) {
    if (dlls_[i] && dlls_[i]->base == base_address) {
      operator delete(dlls_[i], NT_PAGE);
      dlls_[i] = NULL;
      break;
    }
  }
}

// TODO(rvargas): We have to deal with prebinded dlls. I see two options: change
// the timestamp of the patched dll, or modify the info on the prebinded dll.
// the first approach messes matching of debug symbols, the second one is more
// complicated.
bool InterceptionAgent::PatchDll(const DllPatchInfo* dll_info,
                                 DllInterceptionData* thunks) {
  DCHECK_NT(NULL != thunks);
  DCHECK_NT(NULL != dll_info);

  const FunctionInfo* function = reinterpret_cast<const FunctionInfo*>(
      reinterpret_cast<const char*>(dll_info) + dll_info->offset_to_functions);

  for (int i = 0; i < dll_info->num_functions; i++) {
    if (!IsWithinRange(dll_info, dll_info->record_bytes, function->function)) {
      NOTREACHED_NT();
      return false;
    }

    ResolverThunk* resolver = GetResolver(function->type);
    if (!resolver)
      return false;

    const char* interceptor = function->function +
                              g_nt.strlen(function->function) + 1;

    if (!IsWithinRange(function, function->record_bytes, interceptor) ||
        !IsWithinRange(dll_info, dll_info->record_bytes, interceptor)) {
      NOTREACHED_NT();
      return false;
    }

    NTSTATUS ret = resolver->Setup(thunks->base,
                                   interceptions_->interceptor_base,
                                   function->function,
                                   interceptor,
                                   function->interceptor_address,
                                   &thunks->thunks[i],
                                   sizeof(ThunkData),
                                   NULL);
    if (!NT_SUCCESS(ret)) {
      NOTREACHED_NT();
      return false;
    }

    thunks->num_thunks++;
    thunks->used_bytes += sizeof(ThunkData);

    function = reinterpret_cast<const FunctionInfo*>(
        reinterpret_cast<const char*>(function) + function->record_bytes);
  }

  return true;
}

// This method is called from within the loader lock
ResolverThunk* InterceptionAgent::GetResolver(InterceptionType type) {
  static EatResolverThunk* eat_resolver = NULL;
  static SidestepResolverThunk* sidestep_resolver = NULL;
  static SmartSidestepResolverThunk* smart_sidestep_resolver = NULL;

  if (!eat_resolver)
    eat_resolver = new(NT_ALLOC) EatResolverThunk;

  if (!sidestep_resolver)
    sidestep_resolver = new(NT_ALLOC) SidestepResolverThunk;

  if (!smart_sidestep_resolver)
    smart_sidestep_resolver = new(NT_ALLOC) SmartSidestepResolverThunk;

  switch (type) {
    case INTERCEPTION_EAT:
      return eat_resolver;
    case INTERCEPTION_SIDESTEP:
      return sidestep_resolver;
    case INTERCEPTION_SMART_SIDESTEP:
      return smart_sidestep_resolver;
    default:
      NOTREACHED_NT();
  }

  return NULL;
}

}  // namespace sandbox

<|endoftext|>