<commit_before>// $Id$

// The libMesh Finite Element Library.
// Copyright (C) 2002-2008 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner

// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.

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

// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

// C++ includes
#include <fstream>
#include <cstring>

// Local includes
#include "exodusII_io.h"
#include "boundary_info.h"
#include "mesh_base.h"
#include "enum_elem_type.h"
#include "elem.h"
#include "system.h"
#include "numeric_vector.h"
#include "exodusII_io_helper.h"

// ------------------------------------------------------------
// ExodusII_IO class members
ExodusII_IO::ExodusII_IO (MeshBase& mesh) :
  MeshInput<MeshBase> (mesh),
  MeshOutput<MeshBase> (mesh),
  _timestep(1),
  _verbose (false)
{
}

ExodusII_IO::~ExodusII_IO ()
{
#ifndef LIBMESH_HAVE_EXODUS_API

  std::cerr <<  "ERROR, ExodusII API is not defined.\n"
	    << std::endl;
  libmesh_error();

#else

  if(libMesh::processor_id() == 0)
    exio_helper.close();

#endif
}

void ExodusII_IO::verbose (bool set_verbosity)
{
  _verbose = set_verbosity;

#ifdef LIBMESH_HAVE_EXODUS_API
  // Set the verbose flag in the helper object
  // as well.
  exio_helper.verbose(_verbose);
#endif
}

void ExodusII_IO::read (const std::string& fname)
{
  // This is a serial-only process for now;
  // the Mesh should be read on processor 0 and
  // broadcast later
//  libmesh_assert(libMesh::processor_id() == 0);

#ifndef LIBMESH_HAVE_EXODUS_API

  std::cerr <<  "ERROR, ExodusII API is not defined.\n"
	    << "Input file " << fname << " cannot be read"
	    << std::endl;
  libmesh_error();

#else

  // Get a reference to the mesh we are reading
  MeshBase& mesh = MeshInput<MeshBase>::mesh();

  // Clear any existing mesh data
  mesh.clear();

  if (mesh.mesh_dimension() == 1) // No support for 1D ExodusII meshes
    libmesh_not_implemented();

#ifdef DEBUG
  this->verbose(true);
#endif

  ExodusII_IO_Helper::ElementMaps em;     // Instantiate the ElementMaps interface

  exio_helper.open(fname.c_str());       // Open the exodus file, if possible
  exio_helper.read_header();             // Get header information from exodus file
  exio_helper.print_header();            // Print header information

  //assertion fails due to inconsistent mesh dimension
//  libmesh_assert(static_cast<unsigned int>(exio_helper.get_num_dim()) == mesh.mesh_dimension()); // Be sure number of dimensions
                                                                                // is equal to the number of
                                                                                // dimensions in the mesh supplied.

  exio_helper.read_nodes();                        // Read nodes from the exodus file
  mesh.reserve_nodes(exio_helper.get_num_nodes()); // Reserve space for the nodes.

  // Loop over the nodes, create Nodes with local processor_id 0.
  for (int i=0; i<exio_helper.get_num_nodes(); i++)
    mesh.add_point (Point(exio_helper.get_x(i),
			  exio_helper.get_y(i),
			  exio_helper.get_z(i)), i);

  libmesh_assert (static_cast<unsigned int>(exio_helper.get_num_nodes()) == mesh.n_nodes());

  exio_helper.read_block_info();                 // Get information about all the blocks
  mesh.reserve_elem(exio_helper.get_num_elem()); // Reserve space for the elements

  // Read in the element connectivity for each block.
  int nelem_last_block = 0;

  std::map<int, unsigned int> exodus_id_to_mesh_id;

  // Loop over all the blocks
  for (int i=0; i<exio_helper.get_num_elem_blk(); i++)
    {
      // Read the information for block i
      exio_helper.read_elem_in_block (i);
      int subdomain_id = exio_helper.get_block_id(i);

      // Set any relevant node/edge maps for this element
      const std::string type_str (exio_helper.get_elem_type());
      const ExodusII_IO_Helper::Conversion conv = em.assign_conversion(type_str);
      //if (_verbose)
      //std::cout << "Reading a block of " << type_str << " elements." << std::endl;

      // Loop over all the faces in this block
      int jmax = nelem_last_block+exio_helper.get_num_elem_this_blk();
      for (int j=nelem_last_block; j<jmax; j++)
	{
	  Elem* elem = Elem::build (conv.get_canonical_type()).release();
	  libmesh_assert (elem);
          elem->subdomain_id() = static_cast<subdomain_id_type>(subdomain_id) ;
          //elem->set_id(j);// Don't try to second guess the Element ID setting scheme!
	  elem = mesh.add_elem (elem); // Catch the Elem pointer that the Mesh throws back

          exodus_id_to_mesh_id[j+1] = elem->id();

	  // Set all the nodes for this element
	  for (int k=0; k<exio_helper.get_num_nodes_per_elem(); k++)
	    {
	      int gi = (j-nelem_last_block)*exio_helper.get_num_nodes_per_elem() + conv.get_node_map(k); // global index
	      int node_number   = exio_helper.get_connect(gi);             // Global node number (1-based)
	      elem->set_node(k) = mesh.node_ptr((node_number-1)); // Set node number
	                                                          // Subtract 1 since
		                                                  // exodus is internally 1-based
	    }
	}

      // running sum of # of elements per block,
      // (should equal total number of elements in the end)
      nelem_last_block += exio_helper.get_num_elem_this_blk();
    }
  libmesh_assert (static_cast<unsigned int>(nelem_last_block) == mesh.n_elem());

  // Read in sideset information -- this is useful for applying boundary conditions
  {
    exio_helper.read_sideset_info(); // Get basic information about ALL sidesets
    int offset=0;
    for (int i=0; i<exio_helper.get_num_side_sets(); i++)
      {
	offset += (i > 0 ? exio_helper.get_num_sides_per_set(i-1) : 0); // Compute new offset
	exio_helper.read_sideset (i, offset);
      }

    const std::vector<int>& elem_list = exio_helper.get_elem_list();
    const std::vector<int>& side_list = exio_helper.get_side_list();
    const std::vector<int>& id_list   = exio_helper.get_id_list();

    for (unsigned int e=0; e<elem_list.size(); e++)
      {
	// Set any relevant node/edge maps for this element

        Elem * elem = mesh.elem(exodus_id_to_mesh_id[elem_list[e]]);

	const ExodusII_IO_Helper::Conversion conv =
	  em.assign_conversion(elem->type());

	mesh.boundary_info->add_side (exodus_id_to_mesh_id[elem_list[e]],
				      conv.get_side_map(side_list[e]-1),
				      id_list[e]);
      }
  }

  // Read nodeset info
  {
    exio_helper.read_nodeset_info();

    for (int nodeset=0; nodeset<exio_helper.get_num_node_sets(); nodeset++)
      {
        int nodeset_id = exio_helper.get_nodeset_id(nodeset);

        exio_helper.read_nodeset(nodeset);

        const std::vector<int>& node_list = exio_helper.get_node_list();

        for(unsigned int node=0; node<node_list.size(); node++)
          mesh.boundary_info->add_node(node_list[node], nodeset_id);
      }
  }

#endif
}

#ifndef LIBMESH_HAVE_EXODUS_API

void ExodusII_IO::copy_nodal_solution(System& , std::string, unsigned int)
{

  std::cerr <<  "ERROR, ExodusII API is not defined.\n"
	    << std::endl;
  libmesh_error();
}

#else

void ExodusII_IO::copy_nodal_solution(System& system, std::string nodal_var_name, unsigned int timestep)
{
  // FIXME: Do we need to call get_time_steps() at all?
  /*const std::vector<double>& time_steps = */
  exio_helper.get_time_steps();

  const std::vector<double> & nodal_values = exio_helper.get_nodal_var_values(nodal_var_name,timestep);

  //const DofMap & dof_map = system.get_dof_map();

  const unsigned int var_num = system.variable_number(nodal_var_name);

  for (unsigned int i=0; i<nodal_values.size(); ++i)
    {
      const unsigned int dof_index = MeshInput<MeshBase>::mesh().node_ptr(i)->dof_number(system.number(),var_num,0);

      // If the dof_index is local to this processor, set the value
      if ((dof_index >= system.solution->first_local_index()) && (dof_index <  system.solution->last_local_index()))
	system.solution->set (dof_index, nodal_values[i]);
    }

  system.update();
}

#endif

#ifndef LIBMESH_HAVE_EXODUS_API

void ExodusII_IO::write_nodal_data (const std::string& ,
				    const std::vector<Number>& ,
				    const std::vector<std::string>& )
{

  std::cerr <<  "ERROR, ExodusII API is not defined.\n"
	    << std::endl;
  libmesh_error();
}

#else

void ExodusII_IO::write_nodal_data (const std::string& fname,
				    const std::vector<Number>& soln,
				    const std::vector<std::string>& names)
{
  if (libMesh::processor_id() == 0)
    {
      const MeshBase & mesh = MeshOutput<MeshBase>::mesh();

      int num_vars = names.size();
      int num_nodes = mesh.n_nodes();

      // FIXME: Will we ever _not_ need to do this?
      // DRG: Yes... when writing multiple timesteps to the same file.
      if (!exio_helper.created())
	{
	  exio_helper.create(fname);
	  exio_helper.initialize(fname,mesh);
	  exio_helper.write_nodal_coordinates(mesh);
	  exio_helper.write_elements(mesh);
          exio_helper.write_sidesets(mesh);
          exio_helper.write_nodesets(mesh);
	  exio_helper.initialize_nodal_variables(names);
	}

      for (int c=0; c<num_vars; c++)
	{
	  std::vector<Number> cur_soln(num_nodes);

	  //Copy out this variable's solution
	  for(int i=0; i<num_nodes; i++)
	    cur_soln[i] = soln[i*num_vars + c];//c*num_nodes+i];

	  exio_helper.write_nodal_values(c+1,cur_soln,_timestep);
	}
    }
}

#endif

#ifndef LIBMESH_HAVE_EXODUS_API

void ExodusII_IO::write_timestep (const std::string& ,
				  const EquationSystems& ,
				  const int ,
				  const double )
{

  std::cerr <<  "ERROR, ExodusII API is not defined.\n"
	    << std::endl;
  libmesh_error();
}

#else

void ExodusII_IO::write_timestep (const std::string& fname,
				  const EquationSystems& es,
				  const int timestep,
				  const double time)
{
  _timestep=timestep;
  write_equation_systems(fname,es);

  if (libMesh::processor_id() == 0)
    exio_helper.write_timestep(timestep, time);
}

#endif

#ifndef LIBMESH_HAVE_EXODUS_API

void ExodusII_IO::write (const std::string& )
{
  std::cerr <<  "ERROR, ExodusII API is not defined.\n"
	    << std::endl;
  libmesh_error();
}

#else

void ExodusII_IO::write (const std::string& fname)
{
  if (libMesh::processor_id() == 0)
    {
      const MeshBase & mesh = MeshOutput<MeshBase>::mesh();

      libmesh_assert( !exio_helper.created() );

      exio_helper.create(fname);
      exio_helper.initialize(fname,mesh);
      exio_helper.write_nodal_coordinates(mesh);
      exio_helper.write_elements(mesh);
      exio_helper.write_sidesets(mesh);
      exio_helper.write_nodesets(mesh);

      // Note: the file is closed automatically by the ExodusII_IO destructor.
    }
}

#endif
<commit_msg>fix one-off bug<commit_after>// $Id$

// The libMesh Finite Element Library.
// Copyright (C) 2002-2008 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner

// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.

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

// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

// C++ includes
#include <fstream>
#include <cstring>

// Local includes
#include "exodusII_io.h"
#include "boundary_info.h"
#include "mesh_base.h"
#include "enum_elem_type.h"
#include "elem.h"
#include "system.h"
#include "numeric_vector.h"
#include "exodusII_io_helper.h"

// ------------------------------------------------------------
// ExodusII_IO class members
ExodusII_IO::ExodusII_IO (MeshBase& mesh) :
  MeshInput<MeshBase> (mesh),
  MeshOutput<MeshBase> (mesh),
  _timestep(1),
  _verbose (false)
{
}

ExodusII_IO::~ExodusII_IO ()
{
#ifndef LIBMESH_HAVE_EXODUS_API

  std::cerr <<  "ERROR, ExodusII API is not defined.\n"
	    << std::endl;
  libmesh_error();

#else

  if(libMesh::processor_id() == 0)
    exio_helper.close();

#endif
}

void ExodusII_IO::verbose (bool set_verbosity)
{
  _verbose = set_verbosity;

#ifdef LIBMESH_HAVE_EXODUS_API
  // Set the verbose flag in the helper object
  // as well.
  exio_helper.verbose(_verbose);
#endif
}

void ExodusII_IO::read (const std::string& fname)
{
  // This is a serial-only process for now;
  // the Mesh should be read on processor 0 and
  // broadcast later
//  libmesh_assert(libMesh::processor_id() == 0);

#ifndef LIBMESH_HAVE_EXODUS_API

  std::cerr <<  "ERROR, ExodusII API is not defined.\n"
	    << "Input file " << fname << " cannot be read"
	    << std::endl;
  libmesh_error();

#else

  // Get a reference to the mesh we are reading
  MeshBase& mesh = MeshInput<MeshBase>::mesh();

  // Clear any existing mesh data
  mesh.clear();

  if (mesh.mesh_dimension() == 1) // No support for 1D ExodusII meshes
    libmesh_not_implemented();

#ifdef DEBUG
  this->verbose(true);
#endif

  ExodusII_IO_Helper::ElementMaps em;     // Instantiate the ElementMaps interface

  exio_helper.open(fname.c_str());       // Open the exodus file, if possible
  exio_helper.read_header();             // Get header information from exodus file
  exio_helper.print_header();            // Print header information

  //assertion fails due to inconsistent mesh dimension
//  libmesh_assert(static_cast<unsigned int>(exio_helper.get_num_dim()) == mesh.mesh_dimension()); // Be sure number of dimensions
                                                                                // is equal to the number of
                                                                                // dimensions in the mesh supplied.

  exio_helper.read_nodes();                        // Read nodes from the exodus file
  mesh.reserve_nodes(exio_helper.get_num_nodes()); // Reserve space for the nodes.

  // Loop over the nodes, create Nodes with local processor_id 0.
  for (int i=0; i<exio_helper.get_num_nodes(); i++)
    mesh.add_point (Point(exio_helper.get_x(i),
			  exio_helper.get_y(i),
			  exio_helper.get_z(i)), i);

  libmesh_assert (static_cast<unsigned int>(exio_helper.get_num_nodes()) == mesh.n_nodes());

  exio_helper.read_block_info();                 // Get information about all the blocks
  mesh.reserve_elem(exio_helper.get_num_elem()); // Reserve space for the elements

  // Read in the element connectivity for each block.
  int nelem_last_block = 0;

  std::map<int, unsigned int> exodus_id_to_mesh_id;

  // Loop over all the blocks
  for (int i=0; i<exio_helper.get_num_elem_blk(); i++)
    {
      // Read the information for block i
      exio_helper.read_elem_in_block (i);
      int subdomain_id = exio_helper.get_block_id(i);

      // Set any relevant node/edge maps for this element
      const std::string type_str (exio_helper.get_elem_type());
      const ExodusII_IO_Helper::Conversion conv = em.assign_conversion(type_str);
      //if (_verbose)
      //std::cout << "Reading a block of " << type_str << " elements." << std::endl;

      // Loop over all the faces in this block
      int jmax = nelem_last_block+exio_helper.get_num_elem_this_blk();
      for (int j=nelem_last_block; j<jmax; j++)
	{
	  Elem* elem = Elem::build (conv.get_canonical_type()).release();
	  libmesh_assert (elem);
          elem->subdomain_id() = static_cast<subdomain_id_type>(subdomain_id) ;
          //elem->set_id(j);// Don't try to second guess the Element ID setting scheme!
	  elem = mesh.add_elem (elem); // Catch the Elem pointer that the Mesh throws back

          exodus_id_to_mesh_id[j+1] = elem->id();

	  // Set all the nodes for this element
	  for (int k=0; k<exio_helper.get_num_nodes_per_elem(); k++)
	    {
	      int gi = (j-nelem_last_block)*exio_helper.get_num_nodes_per_elem() + conv.get_node_map(k); // global index
	      int node_number   = exio_helper.get_connect(gi);             // Global node number (1-based)
	      elem->set_node(k) = mesh.node_ptr((node_number-1)); // Set node number
	                                                          // Subtract 1 since
		                                                  // exodus is internally 1-based
	    }
	}

      // running sum of # of elements per block,
      // (should equal total number of elements in the end)
      nelem_last_block += exio_helper.get_num_elem_this_blk();
    }
  libmesh_assert (static_cast<unsigned int>(nelem_last_block) == mesh.n_elem());

  // Read in sideset information -- this is useful for applying boundary conditions
  {
    exio_helper.read_sideset_info(); // Get basic information about ALL sidesets
    int offset=0;
    for (int i=0; i<exio_helper.get_num_side_sets(); i++)
      {
	offset += (i > 0 ? exio_helper.get_num_sides_per_set(i-1) : 0); // Compute new offset
	exio_helper.read_sideset (i, offset);
      }

    const std::vector<int>& elem_list = exio_helper.get_elem_list();
    const std::vector<int>& side_list = exio_helper.get_side_list();
    const std::vector<int>& id_list   = exio_helper.get_id_list();

    for (unsigned int e=0; e<elem_list.size(); e++)
      {
	// Set any relevant node/edge maps for this element

        Elem * elem = mesh.elem(exodus_id_to_mesh_id[elem_list[e]]);

	const ExodusII_IO_Helper::Conversion conv =
	  em.assign_conversion(elem->type());

	mesh.boundary_info->add_side (exodus_id_to_mesh_id[elem_list[e]],
				      conv.get_side_map(side_list[e]-1),
				      id_list[e]);
      }
  }

  // Read nodeset info
  {
    exio_helper.read_nodeset_info();

    for (int nodeset=0; nodeset<exio_helper.get_num_node_sets(); nodeset++)
      {
        int nodeset_id = exio_helper.get_nodeset_id(nodeset);

        exio_helper.read_nodeset(nodeset);

        const std::vector<int>& node_list = exio_helper.get_node_list();

        for(unsigned int node=0; node<node_list.size(); node++)
          mesh.boundary_info->add_node(node_list[node]-1, nodeset_id);
      }
  }

#endif
}

#ifndef LIBMESH_HAVE_EXODUS_API

void ExodusII_IO::copy_nodal_solution(System& , std::string, unsigned int)
{

  std::cerr <<  "ERROR, ExodusII API is not defined.\n"
	    << std::endl;
  libmesh_error();
}

#else

void ExodusII_IO::copy_nodal_solution(System& system, std::string nodal_var_name, unsigned int timestep)
{
  // FIXME: Do we need to call get_time_steps() at all?
  /*const std::vector<double>& time_steps = */
  exio_helper.get_time_steps();

  const std::vector<double> & nodal_values = exio_helper.get_nodal_var_values(nodal_var_name,timestep);

  //const DofMap & dof_map = system.get_dof_map();

  const unsigned int var_num = system.variable_number(nodal_var_name);

  for (unsigned int i=0; i<nodal_values.size(); ++i)
    {
      const unsigned int dof_index = MeshInput<MeshBase>::mesh().node_ptr(i)->dof_number(system.number(),var_num,0);

      // If the dof_index is local to this processor, set the value
      if ((dof_index >= system.solution->first_local_index()) && (dof_index <  system.solution->last_local_index()))
	system.solution->set (dof_index, nodal_values[i]);
    }

  system.update();
}

#endif

#ifndef LIBMESH_HAVE_EXODUS_API

void ExodusII_IO::write_nodal_data (const std::string& ,
				    const std::vector<Number>& ,
				    const std::vector<std::string>& )
{

  std::cerr <<  "ERROR, ExodusII API is not defined.\n"
	    << std::endl;
  libmesh_error();
}

#else

void ExodusII_IO::write_nodal_data (const std::string& fname,
				    const std::vector<Number>& soln,
				    const std::vector<std::string>& names)
{
  if (libMesh::processor_id() == 0)
    {
      const MeshBase & mesh = MeshOutput<MeshBase>::mesh();

      int num_vars = names.size();
      int num_nodes = mesh.n_nodes();

      // FIXME: Will we ever _not_ need to do this?
      // DRG: Yes... when writing multiple timesteps to the same file.
      if (!exio_helper.created())
	{
	  exio_helper.create(fname);
	  exio_helper.initialize(fname,mesh);
	  exio_helper.write_nodal_coordinates(mesh);
	  exio_helper.write_elements(mesh);
          exio_helper.write_sidesets(mesh);
          exio_helper.write_nodesets(mesh);
	  exio_helper.initialize_nodal_variables(names);
	}

      for (int c=0; c<num_vars; c++)
	{
	  std::vector<Number> cur_soln(num_nodes);

	  //Copy out this variable's solution
	  for(int i=0; i<num_nodes; i++)
	    cur_soln[i] = soln[i*num_vars + c];//c*num_nodes+i];

	  exio_helper.write_nodal_values(c+1,cur_soln,_timestep);
	}
    }
}

#endif

#ifndef LIBMESH_HAVE_EXODUS_API

void ExodusII_IO::write_timestep (const std::string& ,
				  const EquationSystems& ,
				  const int ,
				  const double )
{

  std::cerr <<  "ERROR, ExodusII API is not defined.\n"
	    << std::endl;
  libmesh_error();
}

#else

void ExodusII_IO::write_timestep (const std::string& fname,
				  const EquationSystems& es,
				  const int timestep,
				  const double time)
{
  _timestep=timestep;
  write_equation_systems(fname,es);

  if (libMesh::processor_id() == 0)
    exio_helper.write_timestep(timestep, time);
}

#endif

#ifndef LIBMESH_HAVE_EXODUS_API

void ExodusII_IO::write (const std::string& )
{
  std::cerr <<  "ERROR, ExodusII API is not defined.\n"
	    << std::endl;
  libmesh_error();
}

#else

void ExodusII_IO::write (const std::string& fname)
{
  if (libMesh::processor_id() == 0)
    {
      const MeshBase & mesh = MeshOutput<MeshBase>::mesh();

      libmesh_assert( !exio_helper.created() );

      exio_helper.create(fname);
      exio_helper.initialize(fname,mesh);
      exio_helper.write_nodal_coordinates(mesh);
      exio_helper.write_elements(mesh);
      exio_helper.write_sidesets(mesh);
      exio_helper.write_nodesets(mesh);

      // Note: the file is closed automatically by the ExodusII_IO destructor.
    }
}

#endif
<|endoftext|>


<commit_before>/**
 * The MIT License (MIT)
 *
 * Copyright (c) 2013-2020 Winlin
 *
 * 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.
 */

#ifndef SRS_CORE_VERSION4_HPP
#define SRS_CORE_VERSION4_HPP

#define SRS_VERSION4_REVISION 73

#endif
<commit_msg>Refine code. 4.0.74<commit_after>/**
 * The MIT License (MIT)
 *
 * Copyright (c) 2013-2020 Winlin
 *
 * 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.
 */

#ifndef SRS_CORE_VERSION4_HPP
#define SRS_CORE_VERSION4_HPP

#define SRS_VERSION4_REVISION 74

#endif
<|endoftext|>


<commit_before>/*****************************************************************************
 * Project: RooFit                                                           *
 * Package: RooFitModels                                                     *
 * @(#)root/roofit:$Id$
 * Authors:                                                                  *
 *   GR, Gerhard Raven,   UC San Diego, Gerhard.Raven@slac.stanford.edu
 *                                                                           *
 * Copyright (c) 2000-2005, Regents of the University of California          *
 *                          and Stanford University. All rights reserved.    *
 *                                                                           *
 * Redistribution and use in source and binary forms,                        *
 * with or without modification, are permitted according to the terms        *
 * listed in LICENSE (http://roofit.sourceforge.net/license.txt)             *
 *****************************************************************************/

//////////////////////////////////////////////////////////////////////////////
//
// BEGIN_HTML
// Chebychev polynomial p.d.f. of the first kind
// END_HTML
//

#include <cmath>
#include <iostream>

#include "RooFit.h"

#include "Riostream.h"

#include "RooChebychev.h"
#include "RooAbsReal.h"
#include "RooRealVar.h"
#include "RooArgList.h"

#if defined(__my_func__)
#undef __my_func__
#endif
#if defined(WIN32)
#define __my_func__ __FUNCTION__
#else
#define __my_func__ __func__
#endif

ClassImp(RooChebychev)
;

//_____________________________________________________________________________
RooChebychev::RooChebychev()
{
}

//_____________________________________________________________________________
RooChebychev::RooChebychev(const char* name, const char* title,
                           RooAbsReal& x, const RooArgList& coefList):
  RooAbsPdf(name, title),
  _x("x", "Dependent", this, x),
  _coefList("coefficients","List of coefficients",this)
{
  // Constructor
  TIterator* coefIter = coefList.createIterator() ;
  RooAbsArg* coef ;
  while((coef = (RooAbsArg*)coefIter->Next())) {
    if (!dynamic_cast<RooAbsReal*>(coef)) {
	std::cerr << "RooChebychev::ctor(" << GetName() <<
	    ") ERROR: coefficient " << coef->GetName() <<
	    " is not of type RooAbsReal" << std::endl ;
      assert(0) ;
    }
    _coefList.add(*coef) ;
  }
  delete coefIter ;
}

//_____________________________________________________________________________
RooChebychev::RooChebychev(const RooChebychev& other, const char* name) :
  RooAbsPdf(other, name),
  _x("x", this, other._x),
  _coefList("coefList",this,other._coefList)
{
}

//inline static double p0(double ,double a) { return a; }
inline static double p1(double t,double a,double b) { return a*t+b; }
inline static double p2(double t,double a,double b,double c) { return p1(t,p1(t,a,b),c); }
inline static double p3(double t,double a,double b,double c,double d) { return p2(t,p1(t,a,b),c,d); }
//inline static double p4(double t,double a,double b,double c,double d,double e) { return p3(t,p1(t,a,b),c,d,e); }

//_____________________________________________________________________________
Double_t RooChebychev::evaluate() const
{

  Double_t xmin = _x.min(); Double_t xmax = _x.max();
  Double_t x(-1+2*(_x-xmin)/(xmax-xmin));
  Double_t x2(x*x);
  Double_t sum(0) ;
  switch (_coefList.getSize()) {
  case  7: sum+=((RooAbsReal&)_coefList[6]).getVal()*x*p3(x2,64,-112,56,-7);
  case  6: sum+=((RooAbsReal&)_coefList[5]).getVal()*p3(x2,32,-48,18,-1);
  case  5: sum+=((RooAbsReal&)_coefList[4]).getVal()*x*p2(x2,16,-20,5);
  case  4: sum+=((RooAbsReal&)_coefList[3]).getVal()*p2(x2,8,-8,1);
  case  3: sum+=((RooAbsReal&)_coefList[2]).getVal()*x*p1(x2,4,-3);
  case  2: sum+=((RooAbsReal&)_coefList[1]).getVal()*p1(x2,2,-1);
  case  1: sum+=((RooAbsReal&)_coefList[0]).getVal()*x;
  case  0: sum+=1; break;
  default: std::cerr << "In " << __my_func__ << " (" << __FILE__ << ", line " <<
	       __LINE__ << "): Higher order Chebychev polynomials currently "
	       "unimplemented." << std::endl;
	   assert(false);
  }
  return sum;
}

//_____________________________________________________________________________
Int_t RooChebychev::getAnalyticalIntegral(RooArgSet& allVars, RooArgSet& analVars, const char* /* rangeName */) const
{
  if (matchArgs(allVars, analVars, _x)) return 1;
  return 0;
}

//_____________________________________________________________________________
Double_t RooChebychev::analyticalIntegral(Int_t code, const char* rangeName) const
{
  (void)code;
  assert(1 == code);

  // the full range of the function is mapped to the normalised [-1, 1] range
  const Double_t xminfull(_x.min()), xmaxfull(_x.max());
  const Double_t fullRange = xmaxfull - xminfull;

  // define limits of the integration range on a normalised scale
  Double_t minScaled = -1., maxScaled = +1.;

  // check to see if integral of a subrange is requested
  if (rangeName && 0 != rangeName[0]) {
    assert(xminfull <= _x.min(rangeName) && _x.min(rangeName) <= xmaxfull);
    assert(xminfull <= _x.max(rangeName) && _x.max(rangeName) <= xmaxfull);
    minScaled = -1. + 2. * (_x.min(rangeName) - xminfull) / fullRange;
    maxScaled = +1. - 2. * (xmaxfull - _x.max(rangeName)) / fullRange;
  }

  // return half of the range since the normalised range runs from -1 to 1
  // which has a range of two
  return 0.5 * fullRange * (evalAnaInt(maxScaled) - evalAnaInt(minScaled));
}

Double_t RooChebychev::evalAnaInt(const Double_t x) const
{
  const Double_t x2 = x * x;
  Double_t sum = 0.;
  switch (_coefList.getSize()) {
    case  7: sum+=((RooAbsReal&)_coefList[6]).getVal()*x2*p3(x2,8.,-112./6.,14.,-7./2.);
    case  6: sum+=((RooAbsReal&)_coefList[5]).getVal()*x*p3(x2,32./7.,-48./5.,6.,-1.);
    case  5: sum+=((RooAbsReal&)_coefList[4]).getVal()*x2*p2(x2,16./6.,-5.,2.5);
    case  4: sum+=((RooAbsReal&)_coefList[3]).getVal()*x*p2(x2,8./5.,-8./3.,1.);
    case  3: sum+=((RooAbsReal&)_coefList[2]).getVal()*x2*p1(x2,1.,-3./2.);
    case  2: sum+=((RooAbsReal&)_coefList[1]).getVal()*x*p1(x2,2./3.,-1.);
    case  1: sum+=((RooAbsReal&)_coefList[0]).getVal()*x2*.5;
    case  0: sum+=x; break;

    default: std::cerr << "In " << __my_func__ << " (" << __FILE__ << ", line " <<
	     __LINE__ << "): Higher order Chebychev polynomials currently "
		 "unimplemented." << std::endl;
	     assert(false);
  }
  return sum;
}

#undef __my_func__
<commit_msg>Copy from master fix for ROOT-6664<commit_after>/*****************************************************************************
 * Project: RooFit                                                           *
 * Package: RooFitModels                                                     *
 * @(#)root/roofit:$Id$
 * Authors:                                                                  *
 *   GR, Gerhard Raven,   UC San Diego, Gerhard.Raven@slac.stanford.edu
 *                                                                           *
 * Copyright (c) 2000-2005, Regents of the University of California          *
 *                          and Stanford University. All rights reserved.    *
 *                                                                           *
 * Redistribution and use in source and binary forms,                        *
 * with or without modification, are permitted according to the terms        *
 * listed in LICENSE (http://roofit.sourceforge.net/license.txt)             *
 *****************************************************************************/

//////////////////////////////////////////////////////////////////////////////
//
// BEGIN_HTML
// Chebychev polynomial p.d.f. of the first kind
// END_HTML
//

#include <cmath>
#include <iostream>

#include "RooFit.h"

#include "Riostream.h"

#include "RooChebychev.h"
#include "RooAbsReal.h"
#include "RooRealVar.h"
#include "RooArgList.h"

#if defined(__my_func__)
#undef __my_func__
#endif
#if defined(WIN32)
#define __my_func__ __FUNCTION__
#else
#define __my_func__ __func__
#endif

ClassImp(RooChebychev)
;

//_____________________________________________________________________________
RooChebychev::RooChebychev()
{
}

//_____________________________________________________________________________
RooChebychev::RooChebychev(const char* name, const char* title,
                           RooAbsReal& x, const RooArgList& coefList):
  RooAbsPdf(name, title),
  _x("x", "Dependent", this, x),
  _coefList("coefficients","List of coefficients",this)
{
  // Constructor
  TIterator* coefIter = coefList.createIterator() ;
  RooAbsArg* coef ;
  while((coef = (RooAbsArg*)coefIter->Next())) {
    if (!dynamic_cast<RooAbsReal*>(coef)) {
	std::cerr << "RooChebychev::ctor(" << GetName() <<
	    ") ERROR: coefficient " << coef->GetName() <<
	    " is not of type RooAbsReal" << std::endl ;
      assert(0) ;
    }
    _coefList.add(*coef) ;
  }
  delete coefIter ;
}

//_____________________________________________________________________________
RooChebychev::RooChebychev(const RooChebychev& other, const char* name) :
  RooAbsPdf(other, name),
  _x("x", this, other._x),
  _coefList("coefList",this,other._coefList)
{
}

//inline static double p0(double ,double a) { return a; }
inline static double p1(double t,double a,double b) { return a*t+b; }
inline static double p2(double t,double a,double b,double c) { return p1(t,p1(t,a,b),c); }
inline static double p3(double t,double a,double b,double c,double d) { return p2(t,p1(t,a,b),c,d); }
//inline static double p4(double t,double a,double b,double c,double d,double e) { return p3(t,p1(t,a,b),c,d,e); }

//_____________________________________________________________________________
Double_t RooChebychev::evaluate() const
{

  Double_t xmin = _x.min(); Double_t xmax = _x.max();
  Double_t x(-1+2*(_x-xmin)/(xmax-xmin));
  Double_t x2(x*x);
  Double_t sum(0) ;
  switch (_coefList.getSize()) {
  case  7: sum+=((RooAbsReal&)_coefList[6]).getVal()*x*p3(x2,64,-112,56,-7);
  case  6: sum+=((RooAbsReal&)_coefList[5]).getVal()*p3(x2,32,-48,18,-1);
  case  5: sum+=((RooAbsReal&)_coefList[4]).getVal()*x*p2(x2,16,-20,5);
  case  4: sum+=((RooAbsReal&)_coefList[3]).getVal()*p2(x2,8,-8,1);
  case  3: sum+=((RooAbsReal&)_coefList[2]).getVal()*x*p1(x2,4,-3);
  case  2: sum+=((RooAbsReal&)_coefList[1]).getVal()*p1(x2,2,-1);
  case  1: sum+=((RooAbsReal&)_coefList[0]).getVal()*x;
  case  0: sum+=1; break;
  default: std::cerr << "In " << __my_func__ << " (" << __FILE__ << ", line " <<
	       __LINE__ << "): Higher order Chebychev polynomials currently "
	       "unimplemented." << std::endl;
	   assert(false);
  }
  return sum;
}

//_____________________________________________________________________________
Int_t RooChebychev::getAnalyticalIntegral(RooArgSet& allVars, RooArgSet& analVars, const char* /* rangeName */) const
{
  if (matchArgs(allVars, analVars, _x)) return 1;
  return 0;
}

//_____________________________________________________________________________
Double_t RooChebychev::analyticalIntegral(Int_t code, const char* rangeName) const
{
  (void)code;
  assert(1 == code);

  // the full range of the function is mapped to the normalised [-1, 1] range
  const Double_t xminfull(_x.min()), xmaxfull(_x.max());
  const Double_t fullRange = xmaxfull - xminfull;

  // define limits of the integration range on a normalised scale
  Double_t minScaled = -1., maxScaled = +1.;

  // check to see if integral of a subrange is requested
  if (rangeName && 0 != rangeName[0]) {
    // LM: no reason to assrt there (see ROOT-6664)
    //assert(xminfull <= _x.min(rangeName) && _x.min(rangeName) <= xmaxfull);
    //assert(xminfull <= _x.max(rangeName) && _x.max(rangeName) <= xmaxfull);
    minScaled = -1. + 2. * (_x.min(rangeName) - xminfull) / fullRange;
    maxScaled = +1. - 2. * (xmaxfull - _x.max(rangeName)) / fullRange;
  }

  // return half of the range since the normalised range runs from -1 to 1
  // which has a range of two
  return 0.5 * fullRange * (evalAnaInt(maxScaled) - evalAnaInt(minScaled));
}

Double_t RooChebychev::evalAnaInt(const Double_t x) const
{
  const Double_t x2 = x * x;
  Double_t sum = 0.;
  switch (_coefList.getSize()) {
    case  7: sum+=((RooAbsReal&)_coefList[6]).getVal()*x2*p3(x2,8.,-112./6.,14.,-7./2.);
    case  6: sum+=((RooAbsReal&)_coefList[5]).getVal()*x*p3(x2,32./7.,-48./5.,6.,-1.);
    case  5: sum+=((RooAbsReal&)_coefList[4]).getVal()*x2*p2(x2,16./6.,-5.,2.5);
    case  4: sum+=((RooAbsReal&)_coefList[3]).getVal()*x*p2(x2,8./5.,-8./3.,1.);
    case  3: sum+=((RooAbsReal&)_coefList[2]).getVal()*x2*p1(x2,1.,-3./2.);
    case  2: sum+=((RooAbsReal&)_coefList[1]).getVal()*x*p1(x2,2./3.,-1.);
    case  1: sum+=((RooAbsReal&)_coefList[0]).getVal()*x2*.5;
    case  0: sum+=x; break;

    default: std::cerr << "In " << __my_func__ << " (" << __FILE__ << ", line " <<
	     __LINE__ << "): Higher order Chebychev polynomials currently "
		 "unimplemented." << std::endl;
	     assert(false);
  }
  return sum;
}

#undef __my_func__
<|endoftext|>


<commit_before>#include <iostream>
#include <sstream>
#include <string>

#include <unistd.h>
#include <vector>
#include <algorithm>
#include <list>
#include <map>

#include <cstdlib>
#include <cstring>

#include "segment.h"
#include "message.h"
#include "register_success_message.h"
#include "register_failure_message.h"
#include "register_request_message.h"
#include "loc_success_message.h"
#include "loc_failure_message.h"
#include "loc_request_message.h"
#include "terminate_message.h"

#include "constants.h"
#include "network.h"
#include "helper_functions.h"

using namespace std;

//TODO:
//MANAGE CLIENT CONNECTION
//MANAGE SERVER CONNECTION
//DATABASE
//ROUND ROBIN

static map<procedure_signature, list<server_info *>, ps_compare> procLocDict;
static list<server_function_info *> roundRobinList;
static list<server_info *> serverList;

static bool onSwitch = true;

/*
TODO:
ADD FUNCTION TO MAP
ADD FUNCTION TO ROUND ROBIN
IF FUNCTION EXISTS IN ROUND ROBIN DELETE OLD REPLACE WITH NEW (where)
*/

void mapPrint(){
  cout << "procLocDict size: "<<procLocDict.size() << endl;
  cout << "Map Print: ";
  for(map<procedure_signature, list<server_info *>, ps_compare> ::const_iterator it = procLocDict.begin();
   it != procLocDict.end(); it++){

    cout << it->first.name << ", " ;
  }

  cout << endl;
}

void roundRobinPrint(){
  cout << "roundRobin Print: ";
  for(list<server_function_info *> ::const_iterator it = roundRobinList.begin(); it != roundRobinList.end(); it++){
    cout << (*it)->ps->name << endl;
  }
}

void serverListPrint(){
  cout << "serverList Print: " << endl;
  for(list<server_info *> ::const_iterator it = serverList.begin(); it != serverList.end(); it++){
    cout << (*it)->server_identifier << ", " <<  (*it)->port << ", " <<  (*it)->socket<< endl;
  }
}

void registration_request_handler(RegisterRequestMessage * message, int sock){
  const char * name = message->getName().c_str();
  int * argTypes = message->getArgTypes();
  string server_identifier = message->getServerIdentifier();
  int port = message->getPort();

  cout << "We are trying to register: " << name  << ", " << server_identifier << ", " << port << endl;

  procedure_signature key(name, argTypes);

  int status = 0;

  //if 'key' dosnt exist in map, add it to the map and round robin
	if (procLocDict.find(key) == procLocDict.end()) {
    //The purpose of this function is so we can have copy of the argTypes that not the original
    int *memArgTypes = copyArgTypes(argTypes);

    key = procedure_signature(name, memArgTypes);
    procLocDict[key] = list<server_info *>();

    //This is bad we shouldn't need a newKey and we should be able to use the key above
    //due to &* reasones I made a variable newKey for the 'info' object
    procedure_signature * newKey = new procedure_signature(name, memArgTypes);
    server_info * entry = new server_info(server_identifier, port, sock);
    server_function_info * info = new server_function_info(entry, newKey);

    //Adding to roundRobinList if server is not found
    roundRobinList.push_back(info);

    //Adding to serverList if server is not found
    bool serverExist = false;
    for (list<server_info *>::iterator it = serverList.begin(); it != serverList.end(); it++) {

      if( (*it)->server_identifier == entry->server_identifier && (*it)->port == entry->port &&  (*it)->socket == entry->socket){
          serverExist = true;
          break;
        }
    }

    cout << "entry->server_identifier: " <<entry->server_identifier << endl;
    cout << "entry->port: " <<entry->port << endl;
    cout << "entry->socket: " << entry->socket << endl;

    if(!serverExist){
      serverList.push_back(entry);
    }

  } else {
    bool sameLoc = false;
    list<server_info *> hostList = procLocDict[key];

    for (list<server_info *>::iterator it = hostList.begin(); it != hostList.end(); it++) {
      if((*it)->socket == sock){
        //If they have the same socket, then must be same server_address/port
        //The same procedure signature already exists on the same location
        //TODO: Move to end of round robin or something, maybe we should keep
        sameLoc = true;
      }
    }

  	if(!sameLoc){ //same procedure different socket
       server_info * new_msg_loc = new server_info(server_identifier, port, sock);
       hostList.push_back(new_msg_loc);
    }
  }

  //mapPrint();
  //roundRobinPrint();
  serverListPrint();

  RegisterSuccessMessage regSuccessMsg = RegisterSuccessMessage(status);
  Segment regSuccessSeg = Segment(regSuccessMsg.getLength(), MSG_TYPE_REGISTER_SUCCESS, &regSuccessMsg);
  regSuccessSeg.send(sock);

}

/*
TODO:
USE ROUND ROBIN TO ACCESS THE CORRECT SERVER/FUNCTION FOR THE CLIENT
*/
void location_request_handler(LocRequestMessage * message, int sock){

  bool exist = false;
  string serverIdToPushBack;
  int portToPushBack;
  int socketToPushBack;

  //cout << "Hunted name names: " << message->getName() << endl;

	for (list<server_function_info *>::iterator it = roundRobinList.begin(); it != roundRobinList.end(); it++){
    //If the name are the same and argTypes
    //cout << "Iterator names: " << (*it)->ps->name << endl;

    if((*it)->ps->name == message->getName() && compareArr((*it)->ps->argTypes, message->getArgTypes() )){
      exist = true;

      //cout << "Attempt to send locSuccessMsg" << endl;
      //cout << "server_identifier: "<< (*it)->si->server_identifier << endl;
      //cout << "port: " << (*it)->si->port<< endl;

      serverIdToPushBack = (*it)->si->server_identifier;
      portToPushBack = (*it)->si->port;
      socketToPushBack = (*it)->si->socket;

      LocSuccessMessage locSuccessMsg = LocSuccessMessage((*it)->si->server_identifier.c_str(), (*it)->si->port);
      Segment locSuccessSeg = Segment(locSuccessMsg.getLength(), MSG_TYPE_LOC_SUCCESS, &locSuccessMsg);
      locSuccessSeg.send(sock);

      //When we have identified the correct procedure_signature use splice and move that service to the end
      roundRobinList.splice(roundRobinList.end(), roundRobinList, it);
      break;
 		}
	}

  if(exist){
    for (list<server_function_info *>::iterator it = roundRobinList.begin(); it != roundRobinList.end(); it++){

       if((*it)->si->server_identifier == serverIdToPushBack && (*it)->si->port == portToPushBack && (*it)->si->socket == socketToPushBack){
          roundRobinList.splice(roundRobinList.end(), roundRobinList, it);
       }
    }
  }else {
    int reasoncode = -5; // Need actual reasoncode
    LocFailureMessage locFailMsg = LocFailureMessage(reasoncode);
    Segment locFailSeg = Segment(locFailMsg.getLength(), MSG_TYPE_LOC_FAILURE, &locFailMsg);
    locFailSeg.send(sock);
  }
}

void binder_terminate_handler() {
  cout << "Binder set to execute" << endl;

  for (list<server_info *>::const_iterator it = serverList.begin(); it != serverList.end(); it++) {
    cout << "Terminating server: " << (*it)->server_identifier << ", " <<  (*it)->port << ", " <<  (*it)->socket<< endl;
    TerminateMessage termMsg = TerminateMessage();
    Segment termSeg = Segment(termMsg.getLength(), MSG_TYPE_TERMINATE, &termMsg);
    termSeg.send((*it)->socket);
  }

  onSwitch = false;

}

int request_handler(Segment * segment, int sock){
  int retval = 0;
  if(segment->getType() == MSG_TYPE_REGISTER_REQUEST){
    Message * cast1 = segment->getMessage();
    RegisterRequestMessage * rrm = dynamic_cast<RegisterRequestMessage*>(cast1);

    registration_request_handler(rrm, sock);

  }else if (segment->getType() == MSG_TYPE_LOC_REQUEST){

    cout << "Loc Request" << endl;

    Message * cast2 = segment->getMessage();
    LocRequestMessage * lqm = dynamic_cast<LocRequestMessage*>(cast2);

    location_request_handler(lqm, sock);

  }else if (segment->getType() == MSG_TYPE_TERMINATE){

    cout << "Terminate Request" <<endl;

    binder_terminate_handler();
  }

	return retval;
}

//TODO:
//Create helper functions that can be used for rpcServer.cc
int main() {
// Code refactoring

  fd_set allSockets;
  fd_set readSockets;

  // Clears all entries from the all sockets set and the read
  // sockets set
  FD_ZERO(&allSockets);
  FD_ZERO(&readSockets);

  // Creates the welcome socket, adds it to the all sockets set and
  // sets it as the maximum socket so far
  int welcomeSocket = createSocket();
  int status = setUpToListen(welcomeSocket);
  FD_SET(welcomeSocket, &allSockets);
  int maxSocket = welcomeSocket;

  // Prints the binder address and the binder port on the binder's
  // standard output
  cout << "BINDER_ADDRESS " << getHostAddress() << endl;
  cout << "BINDER_PORT " << getSocketPort(welcomeSocket) << endl;

  while (onSwitch) {
    readSockets = allSockets;

    // Checks if some of the sockets are ready to be read from
    int result = select(maxSocket + 1, &readSockets, 0, 0, 0);
    if (result < 0) {
      continue;
    }

    for (int i = 0; i <= maxSocket; i++) {
      if (!FD_ISSET(i, &readSockets)) {
        continue;
      }

      if (i == welcomeSocket) {

        // Creates the connection socket when a connection is made
        // to the welcome socket
        int connectionSocket = acceptConnection(i);
        if (connectionSocket < 0) {
          continue;
        }

        // Adds the connection socket to the all sockets set
        FD_SET(connectionSocket, &allSockets);

        // Sets the connection socket as the maximum socket so far
        // if necessary
        if (connectionSocket > maxSocket) {
          maxSocket = connectionSocket;
        }

      } else {

        // Creates a segment to receive data from the client/server and
        // reads into it from the connection socket
        Segment *segment = 0;
        result = 0;
        result = Segment::receive(i, segment);
        if (result <= 0) {
          // Closes the connection socket and removes it from the
          // all sockets set
          destroySocket(i);
          FD_CLR(i, &allSockets);
          continue;
        }

        request_handler(segment, i);
      }
    }
  }

  // Destroys the welcome socket
  destroySocket(welcomeSocket);
}<commit_msg>changes<commit_after>#include <iostream>
#include <sstream>
#include <string>

#include <unistd.h>
#include <vector>
#include <algorithm>
#include <list>
#include <map>

#include <cstdlib>
#include <cstring>

#include "segment.h"
#include "message.h"
#include "register_success_message.h"
#include "register_failure_message.h"
#include "register_request_message.h"
#include "loc_success_message.h"
#include "loc_failure_message.h"
#include "loc_request_message.h"
#include "terminate_message.h"

#include "constants.h"
#include "network.h"
#include "helper_functions.h"

using namespace std;

//TODO:
//MANAGE CLIENT CONNECTION
//MANAGE SERVER CONNECTION
//DATABASE
//ROUND ROBIN

static map<procedure_signature, list<server_info *>, ps_compare> procLocDict;
static list<server_function_info *> roundRobinList;
static list<server_info *> serverList;

static bool onSwitch = true;

/*
TODO:
ADD FUNCTION TO MAP
ADD FUNCTION TO ROUND ROBIN
IF FUNCTION EXISTS IN ROUND ROBIN DELETE OLD REPLACE WITH NEW (where)
*/

void mapPrint(){
  cout << "procLocDict size: "<<procLocDict.size() << endl;
  cout << "Map Print: ";
  for(map<procedure_signature, list<server_info *>, ps_compare> ::const_iterator it = procLocDict.begin();
   it != procLocDict.end(); it++){

    cout << it->first.name << ", " ;
  }

  cout << endl;
}

void roundRobinPrint(){
  cout << "roundRobin Print: ";
  for(list<server_function_info *> ::const_iterator it = roundRobinList.begin(); it != roundRobinList.end(); it++){
    cout << (*it)->ps->name << endl;
  }
}

void serverListPrint(){
  cout << "serverList Print: " << endl;
  for(list<server_info *> ::const_iterator it = serverList.begin(); it != serverList.end(); it++){
    cout << (*it)->server_identifier << ", " <<  (*it)->port << ", " <<  (*it)->socket<< endl;
  }
}

void registration_request_handler(RegisterRequestMessage * message, int sock){
  const char * name = message->getName().c_str();
  int * argTypes = message->getArgTypes();
  string server_identifier = message->getServerIdentifier();
  int port = message->getPort();

  cout << "We are trying to register: " << name  << ", " << server_identifier << ", " << port << endl;

  procedure_signature key(name, argTypes);

  int status = 0;

  //if 'key' dosnt exist in map, add it to the map and round robin
	if (procLocDict.find(key) == procLocDict.end()) {
    //The purpose of this function is so we can have copy of the argTypes that not the original
    int *memArgTypes = copyArgTypes(argTypes);

    key = procedure_signature(name, memArgTypes);
    procLocDict[key] = list<server_info *>();

    //This is bad we shouldn't need a newKey and we should be able to use the key above
    //due to &* reasones I made a variable newKey for the 'info' object
    procedure_signature * newKey = new procedure_signature(name, memArgTypes);
    server_info * entry = new server_info(server_identifier, port, sock);
    server_function_info * info = new server_function_info(entry, newKey);

    //Adding to roundRobinList if server is not found
    roundRobinList.push_back(info);

    //Adding to serverList if server is not found
    bool serverExist = false;
    for (list<server_info *>::iterator it = serverList.begin(); it != serverList.end(); it++) {

      if( (*it)->server_identifier == entry->server_identifier && (*it)->port == entry->port &&  (*it)->socket == entry->socket){
          serverExist = true;
          break;
        }
    }

    cout << "entry->server_identifier: " <<entry->server_identifier << endl;
    cout << "entry->port: " <<entry->port << endl;
    cout << "entry->socket: " << entry->socket << endl;

    if(!serverExist){
      serverList.push_back(entry);
    }

  } else {
    bool sameLoc = false;
    list<server_info *> hostList = procLocDict[key];

    for (list<server_info *>::iterator it = hostList.begin(); it != hostList.end(); it++) {
      if((*it)->socket == sock){
        //If they have the same socket, then must be same server_address/port
        //The same procedure signature already exists on the same location
        //TODO: Move to end of round robin or something, maybe we should keep
        sameLoc = true;
      }
    }

  	if(!sameLoc){ //same procedure different socket
       server_info * new_msg_loc = new server_info(server_identifier, port, sock);
       hostList.push_back(new_msg_loc);
    }
  }

  //mapPrint();
  //roundRobinPrint();
  serverListPrint();

  RegisterSuccessMessage regSuccessMsg = RegisterSuccessMessage(status);
  Segment regSuccessSeg = Segment(regSuccessMsg.getLength(), MSG_TYPE_REGISTER_SUCCESS, &regSuccessMsg);
  regSuccessSeg.send(sock);

}

/*
TODO:
USE ROUND ROBIN TO ACCESS THE CORRECT SERVER/FUNCTION FOR THE CLIENT
*/
void location_request_handler(LocRequestMessage * message, int sock){

  bool exist = false;
  string serverIdToPushBack;
  int portToPushBack;
  int socketToPushBack;

  //cout << "Hunted name names: " << message->getName() << endl;

	for (list<server_function_info *>::iterator it = roundRobinList.begin(); it != roundRobinList.end(); it++){
    //If the name are the same and argTypes
    //cout << "Iterator names: " << (*it)->ps->name << endl;

    if((*it)->ps->name == message->getName() && compareArr((*it)->ps->argTypes, message->getArgTypes() )){
      exist = true;

      //cout << "Attempt to send locSuccessMsg" << endl;
      //cout << "server_identifier: "<< (*it)->si->server_identifier << endl;
      //cout << "port: " << (*it)->si->port<< endl;

      serverIdToPushBack = (*it)->si->server_identifier;
      portToPushBack = (*it)->si->port;
      socketToPushBack = (*it)->si->socket;

      LocSuccessMessage locSuccessMsg = LocSuccessMessage((*it)->si->server_identifier.c_str(), (*it)->si->port);
      Segment locSuccessSeg = Segment(locSuccessMsg.getLength(), MSG_TYPE_LOC_SUCCESS, &locSuccessMsg);
      locSuccessSeg.send(sock);

      //When we have identified the correct procedure_signature use splice and move that service to the end
      roundRobinList.splice(roundRobinList.end(), roundRobinList, it);
      break;
 		}
	}

  if(exist){
    for (list<server_function_info *>::iterator it = roundRobinList.begin(); it != roundRobinList.end(); it++){

       if((*it)->si->server_identifier == serverIdToPushBack && (*it)->si->port == portToPushBack && (*it)->si->socket == socketToPushBack){
          roundRobinList.splice(roundRobinList.end(), roundRobinList, it);
       }
    }
  }else {
    int reasoncode = -5; // Need actual reasoncode
    LocFailureMessage locFailMsg = LocFailureMessage(reasoncode);
    Segment locFailSeg = Segment(locFailMsg.getLength(), MSG_TYPE_LOC_FAILURE, &locFailMsg);
    locFailSeg.send(sock);
  }
}

void binder_terminate_handler() {
  cout << "Binder set to execute" << endl;

  for (list<server_info *>::const_iterator it = serverList.begin(); it != serverList.end(); it++) {
    cout << "Terminating server: " << (*it)->server_identifier << ", " <<  (*it)->port << ", " <<  (*it)->socket<< endl;
    TerminateMessage termMsg = TerminateMessage();
    Segment termSeg = Segment(termMsg.getLength(), MSG_TYPE_TERMINATE, &termMsg);
    termSeg.send((*it)->socket);
  }

  onSwitch = false;

}

int request_handler(Segment * segment, int sock){
  int retval = 0;
  if(segment->getType() == MSG_TYPE_REGISTER_REQUEST){
    Message * cast1 = segment->getMessage();
    RegisterRequestMessage * rrm = dynamic_cast<RegisterRequestMessage*>(cast1);

    registration_request_handler(rrm, sock);

  }else if (segment->getType() == MSG_TYPE_LOC_REQUEST){

    cout << "Loc Request" << endl;

    Message * cast2 = segment->getMessage();
    LocRequestMessage * lqm = dynamic_cast<LocRequestMessage*>(cast2);

    location_request_handler(lqm, sock);

  }else if (segment->getType() == MSG_TYPE_TERMINATE){

    cout << "Terminate Request" <<endl;

    binder_terminate_handler();
  }

	return retval;
}

//TODO:
//Create helper functions that can be used for rpcServer.cc
int main() {
// Code refactoring

  fd_set allSockets;
  fd_set readSockets;

  // Clears all entries from the all sockets set and the read
  // sockets set
  FD_ZERO(&allSockets);
  FD_ZERO(&readSockets);

  // Creates the welcome socket, adds it to the all sockets set and
  // sets it as the maximum socket so far
  int welcomeSocket = createSocket();
  int status = setUpToListen(welcomeSocket);
  FD_SET(welcomeSocket, &allSockets);
  int maxSocket = welcomeSocket;

  // Prints the binder address and the binder port on the binder's
  // standard output
  cout << "BINDER_ADDRESS " << getHostAddress() << endl;
  cout << "BINDER_PORT " << getSocketPort(welcomeSocket) << endl;

  while (onSwitch) {
    readSockets = allSockets;

    // Checks if some of the sockets are ready to be read from
    int result = select(maxSocket + 1, &readSockets, 0, 0, 0);
    if (result < 0) {
      continue;
    }

    for (int i = 0; i <= maxSocket; i++) {
      if (!FD_ISSET(i, &readSockets)) {
        continue;
      }

      if (i == welcomeSocket) {

        // Creates the connection socket when a connection is made
        // to the welcome socket
        int connectionSocket = acceptConnection(i);
        if (connectionSocket < 0) {
          continue;
        }

        // Adds the connection socket to the all sockets set
        FD_SET(connectionSocket, &allSockets);

        // Sets the connection socket as the maximum socket so far
        // if necessary
        if (connectionSocket > maxSocket) {
          maxSocket = connectionSocket;
        }

      } else {

        // Creates a segment to receive data from the client/server and
        // reads into it from the connection socket
        Segment *segment = 0;
        result = 0;
        result = Segment::receive(i, segment);
        if (result < 0) {
          // Closes the connection socket and removes it from the
          // all sockets set
          destroySocket(i);
          FD_CLR(i, &allSockets);
          continue;
        }

        request_handler(segment, i);
      }
    }
  }

  // Destroys the welcome socket
  destroySocket(welcomeSocket);
}<|endoftext|>


<commit_before>/***********************************************************************
	filename: 	CEGUIDefaultResourceProvider.cpp
	created:	8/7/2004
	author:		James '_mental_' O'Sullivan

	purpose:	Implements the Resource Manager common functionality
*************************************************************************/
/***************************************************************************
 *   Copyright (C) 2004 - 2006 Paul D Turner & The CEGUI Development Team
 *
 *   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 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 "CEGUIDefaultResourceProvider.h"
#include "CEGUIExceptions.h"

#include <fstream>

// Start of CEGUI namespace section
namespace CEGUI
{

    void DefaultResourceProvider::loadRawDataContainer(const String& filename, RawDataContainer& output, const String& resourceGroup)
    {
        if (filename.empty())
        {
            throw InvalidRequestException(
                "DefaultResourceProvider::load - Filename supplied for data loading must be valid");
        }

        String final_filename(getFinalFilename(filename, resourceGroup));

        std::ifstream dataFile(final_filename.c_str(), std::ios::binary|std::ios::ate);
        if( dataFile.fail())
        {
            throw InvalidRequestException(
                "DefaultResourceProvider::load - " + filename + " does not exist");
        }
        std::streampos size = dataFile.tellg();
        dataFile.seekg (0, std::ios::beg);

        unsigned char* buffer = new unsigned char [size];

        try {
            dataFile.read(reinterpret_cast<char*>(buffer), size);
        }
        catch(std::ifstream::failure e) {
            delete [] buffer;
            throw GenericException(
                "DefaultResourceProvider::loadRawDataContainer - Problem reading " + filename);
        }

        dataFile.close();

        output.setData(buffer);
        output.setSize(size);
    }

    void DefaultResourceProvider::unloadRawDataContainer(RawDataContainer& data)
    {
        uint8* ptr = data.getDataPtr();
        delete [] ptr;
        data.setData(0);
        data.setSize(0);
    }

    void DefaultResourceProvider::setResourceGroupDirectory(const String& resourceGroup, const String& directory)
    {
        d_resourceGroups[resourceGroup] = directory;
    }

    const String& DefaultResourceProvider::getResourceGroupDirectory(const String& resourceGroup)
    {
        return d_resourceGroups[resourceGroup];
    }

    void DefaultResourceProvider::clearResourceGroupDirectory(const String& resourceGroup)
    {
        ResourceGroupMap::iterator iter = d_resourceGroups.find(resourceGroup);

        if (iter != d_resourceGroups.end())
            d_resourceGroups.erase(iter);
    }

    String DefaultResourceProvider::getFinalFilename(const String& filename, const String& resourceGroup) const
    {
        String final_filename;

        // look up resource group directory
        ResourceGroupMap::const_iterator iter = d_resourceGroups.find(resourceGroup);

        // if there was an entry for this group, use it's directory as the
        // first part of the filename
        if (iter != d_resourceGroups.end())
            final_filename = (*iter).second;

        // append the filename part that we were passed
        final_filename += filename;

        // return result
        return final_filename;
    }

} // End of  CEGUI namespace section
<commit_msg>Bug fix: Global default resource group was not being used by DefaultResourceProvider.<commit_after>/***********************************************************************
	filename: 	CEGUIDefaultResourceProvider.cpp
	created:	8/7/2004
	author:		James '_mental_' O'Sullivan

	purpose:	Implements the Resource Manager common functionality
*************************************************************************/
/***************************************************************************
 *   Copyright (C) 2004 - 2006 Paul D Turner & The CEGUI Development Team
 *
 *   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 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 "CEGUIDefaultResourceProvider.h"
#include "CEGUIExceptions.h"

#include <fstream>

// Start of CEGUI namespace section
namespace CEGUI
{

    void DefaultResourceProvider::loadRawDataContainer(const String& filename, RawDataContainer& output, const String& resourceGroup)
    {
        if (filename.empty())
        {
            throw InvalidRequestException(
                "DefaultResourceProvider::load - Filename supplied for data loading must be valid");
        }

        String final_filename(getFinalFilename(filename, resourceGroup));

        std::ifstream dataFile(final_filename.c_str(), std::ios::binary|std::ios::ate);
        if( dataFile.fail())
        {
            throw InvalidRequestException(
                "DefaultResourceProvider::load - " + filename + " does not exist");
        }
        std::streampos size = dataFile.tellg();
        dataFile.seekg (0, std::ios::beg);

        unsigned char* buffer = new unsigned char [size];

        try {
            dataFile.read(reinterpret_cast<char*>(buffer), size);
        }
        catch(std::ifstream::failure e) {
            delete [] buffer;
            throw GenericException(
                "DefaultResourceProvider::loadRawDataContainer - Problem reading " + filename);
        }

        dataFile.close();

        output.setData(buffer);
        output.setSize(size);
    }

    void DefaultResourceProvider::unloadRawDataContainer(RawDataContainer& data)
    {
        uint8* ptr = data.getDataPtr();
        delete [] ptr;
        data.setData(0);
        data.setSize(0);
    }

    void DefaultResourceProvider::setResourceGroupDirectory(const String& resourceGroup, const String& directory)
    {
        d_resourceGroups[resourceGroup] = directory;
    }

    const String& DefaultResourceProvider::getResourceGroupDirectory(const String& resourceGroup)
    {
        return d_resourceGroups[resourceGroup];
    }

    void DefaultResourceProvider::clearResourceGroupDirectory(const String& resourceGroup)
    {
        ResourceGroupMap::iterator iter = d_resourceGroups.find(resourceGroup);

        if (iter != d_resourceGroups.end())
            d_resourceGroups.erase(iter);
    }

    String DefaultResourceProvider::getFinalFilename(const String& filename, const String& resourceGroup) const
    {
        String final_filename;

        // look up resource group directory
        ResourceGroupMap::const_iterator iter =
            d_resourceGroups.find(resourceGroup.empty() ? d_defaultResourceGroup : resourceGroup);

        // if there was an entry for this group, use it's directory as the
        // first part of the filename
        if (iter != d_resourceGroups.end())
            final_filename = (*iter).second;

        // append the filename part that we were passed
        final_filename += filename;

        // return result
        return final_filename;
    }

} // End of  CEGUI namespace section
<|endoftext|>


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

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_configmgr.hxx"

#include <stdio.h>
#include "confproviderimpl2.hxx"

#ifndef CONFIGMGR_ROOTTREE_HXX_
#include "roottree.hxx"
#endif
#ifndef CONFIGMGR_CONFIGNODE_HXX_
#include "noderef.hxx"
#endif
#ifndef CONFIGMGR_API_TREEACCESS_HXX_
#include "apitreeaccess.hxx"
#endif
#ifndef CONFIGMGR_API_OBJECTREGISTRY_HXX_
#include "objectregistry.hxx"
#endif
#ifndef CONFIGMGR_CONFIGEXCEPT_HXX_
#include "configexcept.hxx"
#endif
#ifndef CONFIGMGR_API_PROVIDER2_HXX_
#include "confprovider2.hxx"
#endif
#ifndef CONFIGMGR_TREEPROVIDER_HXX
#include "treeprovider.hxx"
#endif

#ifndef _CONFIGMGR_TRACER_HXX_
#include "tracer.hxx"
#endif

#ifndef _COM_SUN_STAR_BEANS_PROPERTYVALUE_HPP_
#include <com/sun/star/beans/PropertyValue.hpp>
#endif

namespace configmgr
{
    namespace css   = ::com::sun::star;
    namespace uno   = css::uno;
    namespace beans = css::beans;

    using ::rtl::OUString;

    using configapi::NodeElement;
    using configuration::RootTree;

    //=============================================================================
    //= OConfigurationProviderImpl
    //=============================================================================
    //-----------------------------------------------------------------------------------
    OConfigurationProviderImpl::OConfigurationProviderImpl(OConfigurationProvider* _pProvider, CreationContext const & xContext)
                               :OProviderImpl(_pProvider, xContext)
    {
    }
    //--------------------------------------------------------------------------
    uno::Reference<uno::XInterface>  OConfigurationProviderImpl::createReadAccess( uno::Sequence<uno::Any> const& aArgs)
        CFG_UNO_THROW_ALL(  )
    {
        CFG_TRACE_INFO("config provider: going to create a read access instance");

        // extract the args
        OUString sPath;
        sal_Int32 nLevels;

        RequestOptions aOptions = getDefaultOptions();

        OProviderImpl::FactoryArguments::extractArgs(aArgs, sPath, nLevels, aOptions);

        CFG_TRACE_INFO_NI("config provider: node accessor extracted from the args is %s", OUSTRING2ASCII(sPath));
        CFG_TRACE_INFO_NI("config provider: level depth extracted from the args is %i", nLevels);

        // create the access object
        uno::Reference< uno::XInterface > xReturn;

        NodeElement* pElement = buildReadAccess(sPath, aOptions, nLevels);
        if (pElement != 0)
        {
            xReturn = pElement->getUnoInstance();
            if (xReturn.is())
                // acquired once by buildReadAccess
                xReturn->release();
        }

        return xReturn;
    }

    //-----------------------------------------------------------------------------------
    uno::Reference<uno::XInterface> OConfigurationProviderImpl::createUpdateAccess( uno::Sequence<uno::Any> const& aArgs)
        CFG_UNO_THROW_ALL(  )
    {
        CFG_TRACE_INFO("config provider: going to create an update access instance");

        // extract the args
        OUString sPath;
        sal_Int32 nLevels;

        RequestOptions aOptions = getDefaultOptions();

        OProviderImpl::FactoryArguments::extractArgs(aArgs, sPath, nLevels, aOptions);

        CFG_TRACE_INFO_NI("config provider: node accessor extracted from the args is %s", OUSTRING2ASCII(sPath));
        CFG_TRACE_INFO_NI("config provider: level depth extracted from the args is %i", nLevels);

        // create the access object
        uno::Reference< uno::XInterface > xReturn;

        NodeElement* pElement = buildUpdateAccess(sPath, aOptions, nLevels);
        if (pElement != 0)
        {
            xReturn = pElement->getUnoInstance();
            if (xReturn.is())
                // acquired once by buildReadAccess
                xReturn->release();
        }

        return xReturn;
    }
} // namespace configmgr

<commit_msg>INTEGRATION: CWS changefileheader (1.32.72); FILE MERGED 2008/04/01 12:27:11 thb 1.32.72.2: #i85898# Stripping all external header guards 2008/03/31 12:22:37 rt 1.32.72.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: confproviderimpl2.cxx,v $
 * $Revision: 1.33 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_configmgr.hxx"

#include <stdio.h>
#include "confproviderimpl2.hxx"
#include "roottree.hxx"
#include "noderef.hxx"
#include "apitreeaccess.hxx"
#include "objectregistry.hxx"
#include "configexcept.hxx"
#ifndef CONFIGMGR_API_PROVIDER2_HXX_
#include "confprovider2.hxx"
#endif
#include "treeprovider.hxx"
#include "tracer.hxx"
#include <com/sun/star/beans/PropertyValue.hpp>

namespace configmgr
{
    namespace css   = ::com::sun::star;
    namespace uno   = css::uno;
    namespace beans = css::beans;

    using ::rtl::OUString;

    using configapi::NodeElement;
    using configuration::RootTree;

    //=============================================================================
    //= OConfigurationProviderImpl
    //=============================================================================
    //-----------------------------------------------------------------------------------
    OConfigurationProviderImpl::OConfigurationProviderImpl(OConfigurationProvider* _pProvider, CreationContext const & xContext)
                               :OProviderImpl(_pProvider, xContext)
    {
    }
    //--------------------------------------------------------------------------
    uno::Reference<uno::XInterface>  OConfigurationProviderImpl::createReadAccess( uno::Sequence<uno::Any> const& aArgs)
        CFG_UNO_THROW_ALL(  )
    {
        CFG_TRACE_INFO("config provider: going to create a read access instance");

        // extract the args
        OUString sPath;
        sal_Int32 nLevels;

        RequestOptions aOptions = getDefaultOptions();

        OProviderImpl::FactoryArguments::extractArgs(aArgs, sPath, nLevels, aOptions);

        CFG_TRACE_INFO_NI("config provider: node accessor extracted from the args is %s", OUSTRING2ASCII(sPath));
        CFG_TRACE_INFO_NI("config provider: level depth extracted from the args is %i", nLevels);

        // create the access object
        uno::Reference< uno::XInterface > xReturn;

        NodeElement* pElement = buildReadAccess(sPath, aOptions, nLevels);
        if (pElement != 0)
        {
            xReturn = pElement->getUnoInstance();
            if (xReturn.is())
                // acquired once by buildReadAccess
                xReturn->release();
        }

        return xReturn;
    }

    //-----------------------------------------------------------------------------------
    uno::Reference<uno::XInterface> OConfigurationProviderImpl::createUpdateAccess( uno::Sequence<uno::Any> const& aArgs)
        CFG_UNO_THROW_ALL(  )
    {
        CFG_TRACE_INFO("config provider: going to create an update access instance");

        // extract the args
        OUString sPath;
        sal_Int32 nLevels;

        RequestOptions aOptions = getDefaultOptions();

        OProviderImpl::FactoryArguments::extractArgs(aArgs, sPath, nLevels, aOptions);

        CFG_TRACE_INFO_NI("config provider: node accessor extracted from the args is %s", OUSTRING2ASCII(sPath));
        CFG_TRACE_INFO_NI("config provider: level depth extracted from the args is %i", nLevels);

        // create the access object
        uno::Reference< uno::XInterface > xReturn;

        NodeElement* pElement = buildUpdateAccess(sPath, aOptions, nLevels);
        if (pElement != 0)
        {
            xReturn = pElement->getUnoInstance();
            if (xReturn.is())
                // acquired once by buildReadAccess
                xReturn->release();
        }

        return xReturn;
    }
} // namespace configmgr

<|endoftext|>


<commit_before>#include <bits/stdc++.h>
using namespace std;

const int INF = 0x3f3f3f3f;

typedef long double ld;
const double EPS = 1e-9, PI = acos(-1.);

// Change long double to long long if using integers
typedef long double type;

bool ge(type x, type y) { return x + EPS > y; }
bool le(type x, type y) { return x - EPS < y; }
bool eq(type x, type y) { return ge(x, y) and le(x, y); }

struct point {
  type x, y;

  point() : x(0), y(0) {}
  point(type x, type y) : x(x), y(y) {}

  point operator -() { return point(-x, -y); }
  point operator +(point p) { return point(x+p.x, y+p.y); }
  point operator -(point p) { return point(x-p.x, y-p.y); }

  point operator *(type k) { return point(k*x, k*y); }
  point operator /(type k) { return point(x/k, y/k); }

  type operator *(point p) { return x*p.x + y*p.y; }
  type operator %(point p) { return x*p.y - y*p.x; }

  // o is the origin, p is another point
  // dir == +1 => p is clockwise from this
  // dir ==  0 => p is colinear with this
  // dir == -1 => p is counterclockwise from this
  int dir(point o, point p) {
    type x = (*this - o) % (p - o);
    return ge(x,0) - le(x,0);
  }

  bool on_seg(point p, point q) {
    if (this->dir(p, q)) return 0;
    return ge(x, min(p.x, q.x)) and le(x, max(p.x, q.x)) and
           ge(y, min(p.y, q.y)) and le(y, max(p.y, q.y));
  }

  ld abs() { return sqrt(x*x + y*y); }
  type abs2() { return x*x + y*y; }
  ld dist(point x) { return (*this - x).abs(); }
  type dist2(point x) { return (*this - x).abs2(); }

  ld arg() { return atan2l(y, x); }

  // Project point on vector y
  point project(point y) { return y * ((*this * y) / (y * y)); }

  // Project point on line generated by points x and y
  point project(point x, point y) { return x + (*this - x).project(y-x); }

  ld dist_line(point x, point y) { return dist(project(x, y)); }

  ld dist_seg(point x, point y) {
    return project(x, y).on_seg(x, y) ? dist_line(x, y) :  min(dist(x), dist(y));
  }

  point rotate(ld sin, ld cos) { return point(cos*x-sin*y, sin*x+cos*y); }
  point rotate(ld a) { return rotate(sin(a), cos(a)); }
  // rotate around the argument of vector p
  point rotate(point p) { return rotate(p.x / p.abs(), p.y / p.abs()); }
};

int direction(point o, point p, point q) { return p.dir(o, q); }

bool segments_intersect(point p, point q, point a, point b) {
  int d1, d2, d3, d4;
  d1 = direction(p, q, a);
  d2 = direction(p, q, b);
  d3 = direction(a, b, p);
  d4 = direction(a, b, q);
  if (d1*d2 < 0 and d3*d4 < 0) return 1;
  return p.on_seg(a, b) or q.on_seg(a, b) or
         a.on_seg(p, q) or b.on_seg(p, q);
}

point lines_intersect(point p, point q, point a, point b) {
  point r = q-p, s = b-a, c(p%q, a%b);
  if (eq(r%s,0)) return point(INF, INF);
  return point(point(r.x, s.x) % c, point(r.y, s.y) % c) / (r%s);
}

// Sorting points in counterclockwise order.
// If the angle is the same, closer points to the origin come first.
point origin;
bool radial(point p, point q) {
  int dir = p.dir(origin, q);
  return dir > 0 or (!dir and p.on_seg(origin, q));
}

// Graham Scan
vector<point> convex_hull(vector<point> pts) {
  vector<point> ch(pts.size());
  point mn = pts[0];

  for(point p : pts) if (p.y < mn.y or (p.y == mn.y and p.x < p.y)) mn = p;

  origin = mn;
  sort(pts.begin(), pts.end(), radial);

  int n = 0;

  // IF: Convex hull without collinear points
  for(point p : pts) {
    while (n > 1 and ch[n-1].dir(ch[n-2], p) < 1) n--;
    ch[n++] = p;
  }

  /* ELSE IF: Convex hull with collinear points
  for(point p : pts) {
    while (n > 1 and ch[n-1].dir(ch[n-2], p) < 0) n--;
    ch[n++] = p;
  }

  for(int i=pts.size()-1; i >=1; --i)
    if (pts[i] != ch[n-1] and !pts[i].dir(pts[0], ch[n-1]))
      ch[n++] = pts[i];
  // END IF */

  ch.resize(n);
  return ch;
}

// Double of the triangle area
ld double_of_triangle_area(point p1, point p2, point p3) {
  return abs((p2-p1) % (p3-p1));
}

bool point_inside_triangle(point p, point p1, point p2, point p3) {
  ld a1, a2, a3, a;
  a =  double_of_triangle_area(p1, p2, p3);
  a1 = double_of_triangle_area(p, p2, p3);
  a2 = double_of_triangle_area(p, p1, p3);
  a3 = double_of_triangle_area(p, p1, p2);
  return eq(a, a1 + a2 + a3);
}

bool point_inside_convex_poly(int l, int r, vector<point> v, point p) {
  while(l+1 != r) {
    int m = (l+r)/2;
    if (p.dir(v[0], v[m])) r = m;
    else l = m;
  }
  return point_inside_triangle(p, v[0], v[l], v[r]);
}

vector<point> circle_circle_intersection(point p1, ld r1, point p2, ld r2) {
  vector<point> ret;

  ld d = p1.dist(p2);
  if (d > r1 + r2 or d + min(r1, r2) < max(r1, r2)) return ret;

  ld x = (r1*r1 - r2*r2 + d*d) / (2*d);
  ld y = sqrt(r1*r1 - x*x);

  point v = (p2 - p1)/d;

  ret.push_back(p1 + v * x + v.rotate(PI/2) * y);
  if (y > 0)
    ret.push_back(p1 + v * x - v.rotate(PI/2) * y);

  return ret;
}
<commit_msg>Added centroid functino to geometry basics. The function is not yet tested.<commit_after>#include <bits/stdc++.h>
using namespace std;

const int INF = 0x3f3f3f3f;

typedef long double ld;
const double EPS = 1e-9, PI = acos(-1.);

// Change long double to long long if using integers
typedef long double type;

bool ge(type x, type y) { return x + EPS > y; }
bool le(type x, type y) { return x - EPS < y; }
bool eq(type x, type y) { return ge(x, y) and le(x, y); }

struct point {
  type x, y;

  point() : x(0), y(0) {}
  point(type x, type y) : x(x), y(y) {}

  point operator -() { return point(-x, -y); }
  point operator +(point p) { return point(x+p.x, y+p.y); }
  point operator -(point p) { return point(x-p.x, y-p.y); }

  point operator *(type k) { return point(k*x, k*y); }
  point operator /(type k) { return point(x/k, y/k); }

  type operator *(point p) { return x*p.x + y*p.y; }
  type operator %(point p) { return x*p.y - y*p.x; }

  // o is the origin, p is another point
  // dir == +1 => p is clockwise from this
  // dir ==  0 => p is colinear with this
  // dir == -1 => p is counterclockwise from this
  int dir(point o, point p) {
    type x = (*this - o) % (p - o);
    return ge(x,0) - le(x,0);
  }

  bool on_seg(point p, point q) {
    if (this->dir(p, q)) return 0;
    return ge(x, min(p.x, q.x)) and le(x, max(p.x, q.x)) and
           ge(y, min(p.y, q.y)) and le(y, max(p.y, q.y));
  }

  ld abs() { return sqrt(x*x + y*y); }
  type abs2() { return x*x + y*y; }
  ld dist(point x) { return (*this - x).abs(); }
  type dist2(point x) { return (*this - x).abs2(); }

  ld arg() { return atan2l(y, x); }

  // Project point on vector y
  point project(point y) { return y * ((*this * y) / (y * y)); }

  // Project point on line generated by points x and y
  point project(point x, point y) { return x + (*this - x).project(y-x); }

  ld dist_line(point x, point y) { return dist(project(x, y)); }

  ld dist_seg(point x, point y) {
    return project(x, y).on_seg(x, y) ? dist_line(x, y) :  min(dist(x), dist(y));
  }

  point rotate(ld sin, ld cos) { return point(cos*x-sin*y, sin*x+cos*y); }
  point rotate(ld a) { return rotate(sin(a), cos(a)); }
  // rotate around the argument of vector p
  point rotate(point p) { return rotate(p.x / p.abs(), p.y / p.abs()); }
};

int direction(point o, point p, point q) { return p.dir(o, q); }

bool segments_intersect(point p, point q, point a, point b) {
  int d1, d2, d3, d4;
  d1 = direction(p, q, a);
  d2 = direction(p, q, b);
  d3 = direction(a, b, p);
  d4 = direction(a, b, q);
  if (d1*d2 < 0 and d3*d4 < 0) return 1;
  return p.on_seg(a, b) or q.on_seg(a, b) or
         a.on_seg(p, q) or b.on_seg(p, q);
}

point lines_intersect(point p, point q, point a, point b) {
  point r = q-p, s = b-a, c(p%q, a%b);
  if (eq(r%s,0)) return point(INF, INF);
  return point(point(r.x, s.x) % c, point(r.y, s.y) % c) / (r%s);
}

// Sorting points in counterclockwise order.
// If the angle is the same, closer points to the origin come first.
point origin;
bool radial(point p, point q) {
  int dir = p.dir(origin, q);
  return dir > 0 or (!dir and p.on_seg(origin, q));
}

// Graham Scan
vector<point> convex_hull(vector<point> pts) {
  vector<point> ch(pts.size());
  point mn = pts[0];

  for(point p : pts) if (p.y < mn.y or (p.y == mn.y and p.x < p.y)) mn = p;

  origin = mn;
  sort(pts.begin(), pts.end(), radial);

  int n = 0;

  // IF: Convex hull without collinear points
  for(point p : pts) {
    while (n > 1 and ch[n-1].dir(ch[n-2], p) < 1) n--;
    ch[n++] = p;
  }

  /* ELSE IF: Convex hull with collinear points
  for(point p : pts) {
    while (n > 1 and ch[n-1].dir(ch[n-2], p) < 0) n--;
    ch[n++] = p;
  }

  for(int i=pts.size()-1; i >=1; --i)
    if (pts[i] != ch[n-1] and !pts[i].dir(pts[0], ch[n-1]))
      ch[n++] = pts[i];
  // END IF */

  ch.resize(n);
  return ch;
}

// Double of the triangle area
ld double_of_triangle_area(point p1, point p2, point p3) {
  return abs((p2-p1) % (p3-p1));
}

// TODO: test this code. This code has not been tested, please do it before proper use.
// http://codeforces.com/problemset/problem/975/E is a good problem for testing.
point centroid(vector<point> &v) {
  int n = v.size();
  type da = 0;
  point m, c;

  for(point p : v) m = m + p;
  m = m / n;

  for(int i=0; i<n; ++i) {
    point p = v[i] - m, q = v[(i+1)%n] - m;
    type x = p % q;
    c = c + (p + q) * x;
    da += x;
  }

  return c / (3 * da);
}

bool point_inside_triangle(point p, point p1, point p2, point p3) {
  ld a1, a2, a3, a;
  a =  double_of_triangle_area(p1, p2, p3);
  a1 = double_of_triangle_area(p, p2, p3);
  a2 = double_of_triangle_area(p, p1, p3);
  a3 = double_of_triangle_area(p, p1, p2);
  return eq(a, a1 + a2 + a3);
}

bool point_inside_convex_poly(int l, int r, vector<point> v, point p) {
  while(l+1 != r) {
    int m = (l+r)/2;
    if (p.dir(v[0], v[m])) r = m;
    else l = m;
  }
  return point_inside_triangle(p, v[0], v[l], v[r]);
}

vector<point> circle_circle_intersection(point p1, ld r1, point p2, ld r2) {
  vector<point> ret;

  ld d = p1.dist(p2);
  if (d > r1 + r2 or d + min(r1, r2) < max(r1, r2)) return ret;

  ld x = (r1*r1 - r2*r2 + d*d) / (2*d);
  ld y = sqrt(r1*r1 - x*x);

  point v = (p2 - p1)/d;

  ret.push_back(p1 + v * x + v.rotate(PI/2) * y);
  if (y > 0)
    ret.push_back(p1 + v * x - v.rotate(PI/2) * y);

  return ret;
}
<|endoftext|>


<commit_before>/* This file is part of Ingen.
 * Copyright 2007-2011 David Robillard <http://drobilla.net>
 *
 * Ingen is free software; you can redistribute it and/or modify it under the
 * terms of the GNU General Public License as published by the Free Software
 * Foundation; either version 2 of the License, or (at your option) any later
 * version.
 *
 * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 */

#ifndef INGEN_ENGINE_BUFFER_HPP
#define INGEN_ENGINE_BUFFER_HPP

#include <cstddef>
#include <cassert>
#include <boost/utility.hpp>
#include <boost/intrusive_ptr.hpp>
#include "raul/Deletable.hpp"
#include "raul/SharedPtr.hpp"
#include "ingen/PortType.hpp"
#include "types.hpp"
#include "BufferFactory.hpp"

namespace Ingen {
namespace Server {

class Context;
class Engine;
class BufferFactory;

class Buffer : public boost::noncopyable, public Raul::Deletable
{
public:
	Buffer(BufferFactory& bufs, PortType type, size_t size)
		: _factory(bufs)
		, _type(type)
		, _size(size)
		, _next(NULL)
		, _refs(0)
	{}

	/** Clear contents and reset state */
	virtual void clear() = 0;

	virtual void resize(size_t size) { _size = size; }

	virtual void*       port_data(PortType port_type, SampleCount offset=0) = 0;
	virtual const void* port_data(PortType port_type, SampleCount offset=0) const = 0;

	/** Rewind (ie reset read pointer), but leave contents unchanged */
	virtual void rewind() const {}

	virtual void copy(Context& context, const Buffer* src) = 0;

	virtual void prepare_read(Context& context) {}
	virtual void prepare_write(Context& context) {}

	PortType type() const { return _type; }
	size_t           size() const { return _size; }

	inline void ref() { ++_refs; }

	inline void deref() {
		assert(_refs > 0);
		if ((--_refs) == 0)
			_factory.recycle(this);
	}

protected:
	BufferFactory& _factory;
	PortType       _type;
	size_t         _size;

	friend class BufferFactory;
	virtual ~Buffer() {}

private:
	Buffer* _next; ///< Intrusive linked list for BufferFactory
	size_t  _refs; ///< Intrusive reference count for intrusive_ptr
};

} // namespace Server
} // namespace Ingen

namespace boost {
inline void intrusive_ptr_add_ref(Ingen::Server::Buffer* b) { b->ref(); }
inline void intrusive_ptr_release(Ingen::Server::Buffer* b) { b->deref(); }
}

#endif // INGEN_ENGINE_BUFFER_HPP
<commit_msg>Upate for new Raul API<commit_after>/* This file is part of Ingen.
 * Copyright 2007-2011 David Robillard <http://drobilla.net>
 *
 * Ingen is free software; you can redistribute it and/or modify it under the
 * terms of the GNU General Public License as published by the Free Software
 * Foundation; either version 2 of the License, or (at your option) any later
 * version.
 *
 * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 */

#ifndef INGEN_ENGINE_BUFFER_HPP
#define INGEN_ENGINE_BUFFER_HPP

#include <cstddef>
#include <cassert>
#include <boost/utility.hpp>
#include <boost/intrusive_ptr.hpp>
#include "raul/Deletable.hpp"
#include "raul/SharedPtr.hpp"
#include "ingen/PortType.hpp"
#include "types.hpp"
#include "BufferFactory.hpp"

#define IntrusivePtr boost::intrusive_ptr

namespace Ingen {
namespace Server {

class Context;
class Engine;
class BufferFactory;

class Buffer : public boost::noncopyable, public Raul::Deletable
{
public:
	Buffer(BufferFactory& bufs, PortType type, size_t size)
		: _factory(bufs)
		, _type(type)
		, _size(size)
		, _next(NULL)
		, _refs(0)
	{}

	/** Clear contents and reset state */
	virtual void clear() = 0;

	virtual void resize(size_t size) { _size = size; }

	virtual void*       port_data(PortType port_type, SampleCount offset=0) = 0;
	virtual const void* port_data(PortType port_type, SampleCount offset=0) const = 0;

	/** Rewind (ie reset read pointer), but leave contents unchanged */
	virtual void rewind() const {}

	virtual void copy(Context& context, const Buffer* src) = 0;

	virtual void prepare_read(Context& context) {}
	virtual void prepare_write(Context& context) {}

	PortType type() const { return _type; }
	size_t           size() const { return _size; }

	inline void ref() { ++_refs; }

	inline void deref() {
		assert(_refs > 0);
		if ((--_refs) == 0)
			_factory.recycle(this);
	}

protected:
	BufferFactory& _factory;
	PortType       _type;
	size_t         _size;

	friend class BufferFactory;
	virtual ~Buffer() {}

private:
	Buffer* _next; ///< Intrusive linked list for BufferFactory
	size_t  _refs; ///< Intrusive reference count for intrusive_ptr
};

} // namespace Server
} // namespace Ingen

namespace boost {
inline void intrusive_ptr_add_ref(Ingen::Server::Buffer* b) { b->ref(); }
inline void intrusive_ptr_release(Ingen::Server::Buffer* b) { b->deref(); }
}

#endif // INGEN_ENGINE_BUFFER_HPP
<|endoftext|>