<commit_before>/// \file TDrawingOptsReader.cxx
/// \ingroup Gpad ROOT7
/// \author Axel Naumann <axel@cern.ch>
/// \date 2017-09-26
/// \warning This is part of the ROOT 7 prototype! It will change without notice. It might trigger earthquakes. Feedback
/// is welcome!

/*************************************************************************
 * Copyright (C) 1995-2017, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#include "TStyleReader.hxx" // in src/

#include <ROOT/TColor.hxx>
#include <ROOT/TLogger.hxx>

#include <TROOT.h>
#include <TSystem.h>

#include <fstream>
#include <string>

using namespace ROOT::Experimental;
using namespace ROOT::Experimental::Internal;

void TStyleReader::ReadDefaults()
{
   TStyleReader reader(fAttrs);
   reader.AddFromStyleFile(std::string(TROOT::GetEtcDir().Data()) + "/system.rootstylerc");
   reader.AddFromStyleFile(gSystem->GetHomeDirectory() + "/.rootstylerc");
   reader.AddFromStyleFile(".rootstylerc");
}

namespace {
   /// Possibly remove trailing comment starting with '#'
   void RemoveComment(std::string& line)
   {
      auto posComment = line.find('#');
      if (posComment != std::string::npos)
         line.erase(posComment - 1);
   }

   /// Create a view on the key and one on the value of the line.
   std::array<std::string_view, 2> SeparateKeyValue(const std::string& line)
   {
      std::string::size_type posColon = line.find(':');
      if (posColon == std::string::npos)
         return {};
      std::array<std::string_view, 2> ret{{line, line}};
      ret[0] = ret[0].substr(0, posColon);
      ret[1] = ret[1].substr(posColon + 1);
      return ret;
   }

   /// Remove leading an trailing whitespace from string_view.
   std::string_view TrimWhitespace(std::string_view view)
   {
      std::string_view ret(view);
      auto begin = ret.begin();
      for (auto end = ret.end(); begin != end; ++begin) {
         if (!std::isspace(*begin))
            break;
      }
      ret.remove_prefix(begin - ret.begin());

      auto rbegin = ret.rbegin();
      for (auto rend = ret.rend(); rbegin != rend; ++rbegin) {
         if (!std::isspace(*rbegin))
            break;
      }
      ret.remove_suffix(rbegin - ret.rbegin());
      return ret;
   }
}

bool TStyleReader::AddFromStyleFile(const std::string &filename)
{
   std::ifstream in(filename);
   if (!in)
      return false;
   std::string styleName;
   std::string line;
   long long lineNo = 0;
   while (std::getline(in, line)) {
      ++lineNo;
      RemoveComment(line);
      auto noSpaceLine = TrimWhitespace(line);
      if (noSpaceLine.compare(0, 1, "[") == 0 && noSpaceLine.compare(noSpaceLine.length() - 1, 1, "]")) {
         // A section introducing a style name.
         noSpaceLine.remove_prefix(1); // [
         noSpaceLine.remove_suffix(1); // ]
         noSpaceLine = TrimWhitespace(noSpaceLine);
         styleName = noSpaceLine;
         continue;
      }

      auto keyValue = SeparateKeyValue(line);
      for (auto& kv: keyValue)
         kv = TrimWhitespace(kv);
      if (keyValue[0].empty()) {
         R__ERROR_HERE("GPrimitive") << "Syntax error in style file " << filename << ":" << lineNo << ": "
            << "missing key in line \n" << line << "\nInoring line.";
         continue;
      }

      fAttrs[styleName].GetAttribute(std::string(keyValue[0])) = keyValue[1];
   }
   return true;
}
<commit_msg>Try to fix "missing assignment op string = string_view".<commit_after>/// \file TDrawingOptsReader.cxx
/// \ingroup Gpad ROOT7
/// \author Axel Naumann <axel@cern.ch>
/// \date 2017-09-26
/// \warning This is part of the ROOT 7 prototype! It will change without notice. It might trigger earthquakes. Feedback
/// is welcome!

/*************************************************************************
 * Copyright (C) 1995-2017, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#include "TStyleReader.hxx" // in src/

#include <ROOT/TColor.hxx>
#include <ROOT/TLogger.hxx>

#include <TROOT.h>
#include <TSystem.h>

#include <fstream>
#include <string>

using namespace ROOT::Experimental;
using namespace ROOT::Experimental::Internal;

void TStyleReader::ReadDefaults()
{
   TStyleReader reader(fAttrs);
   reader.AddFromStyleFile(std::string(TROOT::GetEtcDir().Data()) + "/system.rootstylerc");
   reader.AddFromStyleFile(gSystem->GetHomeDirectory() + "/.rootstylerc");
   reader.AddFromStyleFile(".rootstylerc");
}

namespace {
   /// Possibly remove trailing comment starting with '#'
   void RemoveComment(std::string& line)
   {
      auto posComment = line.find('#');
      if (posComment != std::string::npos)
         line.erase(posComment - 1);
   }

   /// Create a view on the key and one on the value of the line.
   std::array<std::string_view, 2> SeparateKeyValue(const std::string& line)
   {
      std::string::size_type posColon = line.find(':');
      if (posColon == std::string::npos)
         return {};
      std::array<std::string_view, 2> ret{{line, line}};
      ret[0] = ret[0].substr(0, posColon);
      ret[1] = ret[1].substr(posColon + 1);
      return ret;
   }

   /// Remove leading an trailing whitespace from string_view.
   std::string_view TrimWhitespace(std::string_view view)
   {
      std::string_view ret(view);
      auto begin = ret.begin();
      for (auto end = ret.end(); begin != end; ++begin) {
         if (!std::isspace(*begin))
            break;
      }
      ret.remove_prefix(begin - ret.begin());

      auto rbegin = ret.rbegin();
      for (auto rend = ret.rend(); rbegin != rend; ++rbegin) {
         if (!std::isspace(*rbegin))
            break;
      }
      ret.remove_suffix(rbegin - ret.rbegin());
      return ret;
   }
}

bool TStyleReader::AddFromStyleFile(const std::string &filename)
{
   std::ifstream in(filename);
   if (!in)
      return false;
   std::string styleName;
   std::string line;
   long long lineNo = 0;
   while (std::getline(in, line)) {
      ++lineNo;
      RemoveComment(line);
      auto noSpaceLine = TrimWhitespace(line);
      if (noSpaceLine.compare(0, 1, "[") == 0 && noSpaceLine.compare(noSpaceLine.length() - 1, 1, "]")) {
         // A section introducing a style name.
         noSpaceLine.remove_prefix(1); // [
         noSpaceLine.remove_suffix(1); // ]
         noSpaceLine = TrimWhitespace(noSpaceLine);
         styleName = std::string(noSpaceLine);
         continue;
      }

      auto keyValue = SeparateKeyValue(line);
      for (auto& kv: keyValue)
         kv = TrimWhitespace(kv);
      if (keyValue[0].empty()) {
         R__ERROR_HERE("GPrimitive") << "Syntax error in style file " << filename << ":" << lineNo << ": "
            << "missing key in line \n" << line << "\nInoring line.";
         continue;
      }

      fAttrs[styleName].GetAttribute(std::string(keyValue[0])) = keyValue[1];
   }
   return true;
}
<|endoftext|>


<commit_before>// The libMesh Finite Element Library.
// Copyright (C) 2002-2020 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

// Local includes
#include "libmesh/elem.h"
#include "libmesh/fe.h"
#include "libmesh/fe_interface.h"
#include "libmesh/enum_to_string.h"

namespace libMesh
{

// ------------------------------------------------------------
// Hierarchic-specific implementations

// Anonymous namespace for local helper functions
namespace {

void hierarchic_nodal_soln(const Elem * elem,
                           const Order order,
                           const std::vector<Number> & elem_soln,
                           std::vector<Number> &       nodal_soln,
                           unsigned Dim)
{
  const unsigned int n_nodes = elem->n_nodes();

  const ElemType elem_type = elem->type();

  nodal_soln.resize(n_nodes);

  const Order totalorder = static_cast<Order>(order + elem->p_level());

  // FEType object to be passed to various FEInterface functions below.
  FEType fe_type(totalorder, HIERARCHIC);

  switch (totalorder)
    {
      // Constant shape functions
    case CONSTANT:
      {
        libmesh_assert_equal_to (elem_soln.size(), 1);

        const Number val = elem_soln[0];

        for (unsigned int n=0; n<n_nodes; n++)
          nodal_soln[n] = val;

        return;
      }

      // For other orders do interpolation at the nodes
      // explicitly.
    default:
      {

        const unsigned int n_sf =
          // FE<Dim,T>::n_shape_functions(elem_type, totalorder);
          FEInterface::n_shape_functions(Dim, fe_type, elem_type);

        std::vector<Point> refspace_nodes;
        FEBase::get_refspace_nodes(elem_type,refspace_nodes);
        libmesh_assert_equal_to (refspace_nodes.size(), n_nodes);

        for (unsigned int n=0; n<n_nodes; n++)
          {
            libmesh_assert_equal_to (elem_soln.size(), n_sf);

            // Zero before summation
            nodal_soln[n] = 0;

            // u_i = Sum (alpha_i phi_i)
            for (unsigned int i=0; i<n_sf; i++)
              nodal_soln[n] += elem_soln[i] *
                // FE<Dim,T>::shape(elem, order, i, mapped_point);
                FEInterface::shape(Dim, fe_type, elem, i, refspace_nodes[n]);
          }

        return;
      }
    }
} // hierarchic_nodal_soln()

unsigned int hierarchic_n_dofs(const ElemType t, const Order o)
{
  libmesh_assert_greater (o, 0);
  switch (t)
    {
    case NODEELEM:
      return 1;
    case EDGE2:
    case EDGE3:
      return (o+1);
    case QUAD4:
    case QUADSHELL4:
      libmesh_assert_less (o, 2);
      libmesh_fallthrough();
    case QUAD8:
    case QUADSHELL8:
    case QUAD9:
      return ((o+1)*(o+1));
    case HEX8:
      libmesh_assert_less (o, 2);
      libmesh_fallthrough();
    case HEX20:
      libmesh_assert_less (o, 2);
      libmesh_fallthrough();
    case HEX27:
      return ((o+1)*(o+1)*(o+1));
    case TRI3:
      libmesh_assert_less (o, 2);
      libmesh_fallthrough();
    case TRI6:
      return ((o+1)*(o+2)/2);
    case INVALID_ELEM:
      return 0;
    default:
      libmesh_error_msg("ERROR: Invalid ElemType " << Utility::enum_to_string(t) << " selected for HIERARCHIC FE family!");
    }
} // hierarchic_n_dofs()

unsigned int hierarchic_n_dofs_at_node(const ElemType t,
                                       const Order o,
                                       const unsigned int n)
{
  libmesh_assert_greater (o, 0);
  switch (t)
    {
    case NODEELEM:
      return 1;
    case EDGE2:
    case EDGE3:
      switch (n)
        {
        case 0:
        case 1:
          return 1;
          // Internal DoFs are associated with the elem, not its nodes
        case 2:
          libmesh_assert_equal_to(t, EDGE3);
          return 0;
        default:
          libmesh_error_msg("ERROR: Invalid node ID " << n << " selected for EDGE2/3!");
        }
    case TRI3:
      libmesh_assert_less (n, 3);
      libmesh_assert_less (o, 2);
      libmesh_fallthrough();
    case TRI6:
      switch (n)
        {
        case 0:
        case 1:
        case 2:
          return 1;

        case 3:
        case 4:
        case 5:
          return (o-1);

          // Internal DoFs are associated with the elem, not its nodes
        default:
          libmesh_error_msg("ERROR: Invalid node ID " << n << " selected for TRI6!");
        }
    case QUAD4:
    case QUADSHELL4:
      libmesh_assert_less (n, 4);
      libmesh_assert_less (o, 2);
      libmesh_fallthrough();
    case QUAD8:
    case QUADSHELL8:
    case QUAD9:
      switch (n)
        {
        case 0:
        case 1:
        case 2:
        case 3:
          return 1;

        case 4:
        case 5:
        case 6:
        case 7:
          return (o-1);

          // Internal DoFs are associated with the elem, not its nodes
        case 8:
          return 0;

        default:
          libmesh_error_msg("ERROR: Invalid node ID " << n << " selected for QUAD4/8/9!");
        }
    case HEX8:
      libmesh_assert_less (n, 8);
      libmesh_assert_less (o, 2);
      libmesh_fallthrough();
    case HEX20:
      libmesh_assert_less (n, 20);
      libmesh_assert_less (o, 2);
      libmesh_fallthrough();
    case HEX27:
      switch (n)
        {
        case 0:
        case 1:
        case 2:
        case 3:
        case 4:
        case 5:
        case 6:
        case 7:
          return 1;

        case 8:
        case 9:
        case 10:
        case 11:
        case 12:
        case 13:
        case 14:
        case 15:
        case 16:
        case 17:
        case 18:
        case 19:
          return (o-1);

        case 20:
        case 21:
        case 22:
        case 23:
        case 24:
        case 25:
          return ((o-1)*(o-1));

          // Internal DoFs are associated with the elem, not its nodes
        case 26:
          return 0;
        default:
          libmesh_error_msg("ERROR: Invalid node ID " << n << " selected for HEX8/20/27!");
        }

    case INVALID_ELEM:
      return 0;

    default:
      libmesh_error_msg("ERROR: Bad ElemType = " << Utility::enum_to_string(t) << " for " << Utility::enum_to_string(o) << " order approximation!");
    }
} // hierarchic_n_dofs_at_node()

unsigned int hierarchic_n_dofs_per_elem(const ElemType t,
                                        const Order o)
{
  libmesh_assert_greater (o, 0);
  switch (t)
    {
    case NODEELEM:
      return 0;
    case EDGE2:
    case EDGE3:
      return (o-1);
    case TRI3:
    case TRISHELL3:
    case QUAD4:
    case QUADSHELL4:
      return 0;
    case TRI6:
      return ((o-1)*(o-2)/2);
    case QUAD8:
    case QUADSHELL8:
    case QUAD9:
      return ((o-1)*(o-1));
    case HEX8:
    case HEX20:
      libmesh_assert_less (o, 2);
      return 0;
    case HEX27:
      return ((o-1)*(o-1)*(o-1));
    case INVALID_ELEM:
      return 0;
    default:
      libmesh_error_msg("ERROR: Bad ElemType = " << Utility::enum_to_string(t) << " for " << Utility::enum_to_string(o) << " order approximation!");
    }
} // hierarchic_n_dofs_per_elem()

} // anonymous namespace

  // Do full-specialization of nodal_soln() function for every
  // dimension, instead of explicit instantiation at the end of this
  // file.
  // This could be macro-ified so that it fits on one line...
template <>
void FE<0,HIERARCHIC>::nodal_soln(const Elem * elem,
                                  const Order order,
                                  const std::vector<Number> & elem_soln,
                                  std::vector<Number> & nodal_soln)
{ hierarchic_nodal_soln(elem, order, elem_soln, nodal_soln, /*Dim=*/0); }

template <>
void FE<1,HIERARCHIC>::nodal_soln(const Elem * elem,
                                  const Order order,
                                  const std::vector<Number> & elem_soln,
                                  std::vector<Number> & nodal_soln)
{ hierarchic_nodal_soln(elem, order, elem_soln, nodal_soln, /*Dim=*/1); }

template <>
void FE<2,HIERARCHIC>::nodal_soln(const Elem * elem,
                                  const Order order,
                                  const std::vector<Number> & elem_soln,
                                  std::vector<Number> & nodal_soln)
{ hierarchic_nodal_soln(elem, order, elem_soln, nodal_soln, /*Dim=*/2); }

template <>
void FE<3,HIERARCHIC>::nodal_soln(const Elem * elem,
                                  const Order order,
                                  const std::vector<Number> & elem_soln,
                                  std::vector<Number> & nodal_soln)
{ hierarchic_nodal_soln(elem, order, elem_soln, nodal_soln, /*Dim=*/3); }

// Full specialization of n_dofs() function for every dimension
template <> unsigned int FE<0,HIERARCHIC>::n_dofs(const ElemType t, const Order o) { return hierarchic_n_dofs(t, o); }
template <> unsigned int FE<1,HIERARCHIC>::n_dofs(const ElemType t, const Order o) { return hierarchic_n_dofs(t, o); }
template <> unsigned int FE<2,HIERARCHIC>::n_dofs(const ElemType t, const Order o) { return hierarchic_n_dofs(t, o); }
template <> unsigned int FE<3,HIERARCHIC>::n_dofs(const ElemType t, const Order o) { return hierarchic_n_dofs(t, o); }

// Full specialization of n_dofs_at_node() function for every dimension.
template <> unsigned int FE<0,HIERARCHIC>::n_dofs_at_node(const ElemType t, const Order o, const unsigned int n) { return hierarchic_n_dofs_at_node(t, o, n); }
template <> unsigned int FE<1,HIERARCHIC>::n_dofs_at_node(const ElemType t, const Order o, const unsigned int n) { return hierarchic_n_dofs_at_node(t, o, n); }
template <> unsigned int FE<2,HIERARCHIC>::n_dofs_at_node(const ElemType t, const Order o, const unsigned int n) { return hierarchic_n_dofs_at_node(t, o, n); }
template <> unsigned int FE<3,HIERARCHIC>::n_dofs_at_node(const ElemType t, const Order o, const unsigned int n) { return hierarchic_n_dofs_at_node(t, o, n); }

// Full specialization of n_dofs_per_elem() function for every dimension.
template <> unsigned int FE<0,HIERARCHIC>::n_dofs_per_elem(const ElemType t, const Order o) { return hierarchic_n_dofs_per_elem(t, o); }
template <> unsigned int FE<1,HIERARCHIC>::n_dofs_per_elem(const ElemType t, const Order o) { return hierarchic_n_dofs_per_elem(t, o); }
template <> unsigned int FE<2,HIERARCHIC>::n_dofs_per_elem(const ElemType t, const Order o) { return hierarchic_n_dofs_per_elem(t, o); }
template <> unsigned int FE<3,HIERARCHIC>::n_dofs_per_elem(const ElemType t, const Order o) { return hierarchic_n_dofs_per_elem(t, o); }

// Hierarchic FEMs are C^0 continuous
template <> FEContinuity FE<0,HIERARCHIC>::get_continuity() const { return C_ZERO; }
template <> FEContinuity FE<1,HIERARCHIC>::get_continuity() const { return C_ZERO; }
template <> FEContinuity FE<2,HIERARCHIC>::get_continuity() const { return C_ZERO; }
template <> FEContinuity FE<3,HIERARCHIC>::get_continuity() const { return C_ZERO; }

// Hierarchic FEMs are hierarchic (duh!)
template <> bool FE<0,HIERARCHIC>::is_hierarchic() const { return true; }
template <> bool FE<1,HIERARCHIC>::is_hierarchic() const { return true; }
template <> bool FE<2,HIERARCHIC>::is_hierarchic() const { return true; }
template <> bool FE<3,HIERARCHIC>::is_hierarchic() const { return true; }

#ifdef LIBMESH_ENABLE_AMR
// compute_constraints() specializations are only needed for 2 and 3D
template <>
void FE<2,HIERARCHIC>::compute_constraints (DofConstraints & constraints,
                                            DofMap & dof_map,
                                            const unsigned int variable_number,
                                            const Elem * elem)
{ compute_proj_constraints(constraints, dof_map, variable_number, elem); }

template <>
void FE<3,HIERARCHIC>::compute_constraints (DofConstraints & constraints,
                                            DofMap & dof_map,
                                            const unsigned int variable_number,
                                            const Elem * elem)
{ compute_proj_constraints(constraints, dof_map, variable_number, elem); }
#endif // #ifdef LIBMESH_ENABLE_AMR

// Hierarchic FEM shapes need reinit
template <> bool FE<0,HIERARCHIC>::shapes_need_reinit() const { return true; }
template <> bool FE<1,HIERARCHIC>::shapes_need_reinit() const { return true; }
template <> bool FE<2,HIERARCHIC>::shapes_need_reinit() const { return true; }
template <> bool FE<3,HIERARCHIC>::shapes_need_reinit() const { return true; }

} // namespace libMesh
<commit_msg>Use new FEInterface::n_shape_functions() in fe_hierarchic.C<commit_after>// The libMesh Finite Element Library.
// Copyright (C) 2002-2020 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

// Local includes
#include "libmesh/elem.h"
#include "libmesh/fe.h"
#include "libmesh/fe_interface.h"
#include "libmesh/enum_to_string.h"

namespace libMesh
{

// ------------------------------------------------------------
// Hierarchic-specific implementations

// Anonymous namespace for local helper functions
namespace {

void hierarchic_nodal_soln(const Elem * elem,
                           const Order order,
                           const std::vector<Number> & elem_soln,
                           std::vector<Number> &       nodal_soln,
                           unsigned Dim)
{
  const unsigned int n_nodes = elem->n_nodes();

  const ElemType elem_type = elem->type();

  nodal_soln.resize(n_nodes);

  const Order totalorder = static_cast<Order>(order + elem->p_level());

  // FEType object to be passed to various FEInterface functions below.
  FEType fe_type(order, HIERARCHIC);
  FEType p_refined_fe_type(totalorder, HIERARCHIC);

  switch (totalorder)
    {
      // Constant shape functions
    case CONSTANT:
      {
        libmesh_assert_equal_to (elem_soln.size(), 1);

        const Number val = elem_soln[0];

        for (unsigned int n=0; n<n_nodes; n++)
          nodal_soln[n] = val;

        return;
      }

      // For other orders do interpolation at the nodes
      // explicitly.
    default:
      {

        const unsigned int n_sf =
          FEInterface::n_shape_functions(fe_type, elem);

        std::vector<Point> refspace_nodes;
        FEBase::get_refspace_nodes(elem_type,refspace_nodes);
        libmesh_assert_equal_to (refspace_nodes.size(), n_nodes);

        for (unsigned int n=0; n<n_nodes; n++)
          {
            libmesh_assert_equal_to (elem_soln.size(), n_sf);

            // Zero before summation
            nodal_soln[n] = 0;

            // u_i = Sum (alpha_i phi_i)
            for (unsigned int i=0; i<n_sf; i++)
              nodal_soln[n] += elem_soln[i] *
                FEInterface::shape(Dim, p_refined_fe_type, elem, i, refspace_nodes[n]);
          }

        return;
      }
    }
} // hierarchic_nodal_soln()

unsigned int hierarchic_n_dofs(const ElemType t, const Order o)
{
  libmesh_assert_greater (o, 0);
  switch (t)
    {
    case NODEELEM:
      return 1;
    case EDGE2:
    case EDGE3:
      return (o+1);
    case QUAD4:
    case QUADSHELL4:
      libmesh_assert_less (o, 2);
      libmesh_fallthrough();
    case QUAD8:
    case QUADSHELL8:
    case QUAD9:
      return ((o+1)*(o+1));
    case HEX8:
      libmesh_assert_less (o, 2);
      libmesh_fallthrough();
    case HEX20:
      libmesh_assert_less (o, 2);
      libmesh_fallthrough();
    case HEX27:
      return ((o+1)*(o+1)*(o+1));
    case TRI3:
      libmesh_assert_less (o, 2);
      libmesh_fallthrough();
    case TRI6:
      return ((o+1)*(o+2)/2);
    case INVALID_ELEM:
      return 0;
    default:
      libmesh_error_msg("ERROR: Invalid ElemType " << Utility::enum_to_string(t) << " selected for HIERARCHIC FE family!");
    }
} // hierarchic_n_dofs()

unsigned int hierarchic_n_dofs_at_node(const ElemType t,
                                       const Order o,
                                       const unsigned int n)
{
  libmesh_assert_greater (o, 0);
  switch (t)
    {
    case NODEELEM:
      return 1;
    case EDGE2:
    case EDGE3:
      switch (n)
        {
        case 0:
        case 1:
          return 1;
          // Internal DoFs are associated with the elem, not its nodes
        case 2:
          libmesh_assert_equal_to(t, EDGE3);
          return 0;
        default:
          libmesh_error_msg("ERROR: Invalid node ID " << n << " selected for EDGE2/3!");
        }
    case TRI3:
      libmesh_assert_less (n, 3);
      libmesh_assert_less (o, 2);
      libmesh_fallthrough();
    case TRI6:
      switch (n)
        {
        case 0:
        case 1:
        case 2:
          return 1;

        case 3:
        case 4:
        case 5:
          return (o-1);

          // Internal DoFs are associated with the elem, not its nodes
        default:
          libmesh_error_msg("ERROR: Invalid node ID " << n << " selected for TRI6!");
        }
    case QUAD4:
    case QUADSHELL4:
      libmesh_assert_less (n, 4);
      libmesh_assert_less (o, 2);
      libmesh_fallthrough();
    case QUAD8:
    case QUADSHELL8:
    case QUAD9:
      switch (n)
        {
        case 0:
        case 1:
        case 2:
        case 3:
          return 1;

        case 4:
        case 5:
        case 6:
        case 7:
          return (o-1);

          // Internal DoFs are associated with the elem, not its nodes
        case 8:
          return 0;

        default:
          libmesh_error_msg("ERROR: Invalid node ID " << n << " selected for QUAD4/8/9!");
        }
    case HEX8:
      libmesh_assert_less (n, 8);
      libmesh_assert_less (o, 2);
      libmesh_fallthrough();
    case HEX20:
      libmesh_assert_less (n, 20);
      libmesh_assert_less (o, 2);
      libmesh_fallthrough();
    case HEX27:
      switch (n)
        {
        case 0:
        case 1:
        case 2:
        case 3:
        case 4:
        case 5:
        case 6:
        case 7:
          return 1;

        case 8:
        case 9:
        case 10:
        case 11:
        case 12:
        case 13:
        case 14:
        case 15:
        case 16:
        case 17:
        case 18:
        case 19:
          return (o-1);

        case 20:
        case 21:
        case 22:
        case 23:
        case 24:
        case 25:
          return ((o-1)*(o-1));

          // Internal DoFs are associated with the elem, not its nodes
        case 26:
          return 0;
        default:
          libmesh_error_msg("ERROR: Invalid node ID " << n << " selected for HEX8/20/27!");
        }

    case INVALID_ELEM:
      return 0;

    default:
      libmesh_error_msg("ERROR: Bad ElemType = " << Utility::enum_to_string(t) << " for " << Utility::enum_to_string(o) << " order approximation!");
    }
} // hierarchic_n_dofs_at_node()

unsigned int hierarchic_n_dofs_per_elem(const ElemType t,
                                        const Order o)
{
  libmesh_assert_greater (o, 0);
  switch (t)
    {
    case NODEELEM:
      return 0;
    case EDGE2:
    case EDGE3:
      return (o-1);
    case TRI3:
    case TRISHELL3:
    case QUAD4:
    case QUADSHELL4:
      return 0;
    case TRI6:
      return ((o-1)*(o-2)/2);
    case QUAD8:
    case QUADSHELL8:
    case QUAD9:
      return ((o-1)*(o-1));
    case HEX8:
    case HEX20:
      libmesh_assert_less (o, 2);
      return 0;
    case HEX27:
      return ((o-1)*(o-1)*(o-1));
    case INVALID_ELEM:
      return 0;
    default:
      libmesh_error_msg("ERROR: Bad ElemType = " << Utility::enum_to_string(t) << " for " << Utility::enum_to_string(o) << " order approximation!");
    }
} // hierarchic_n_dofs_per_elem()

} // anonymous namespace

  // Do full-specialization of nodal_soln() function for every
  // dimension, instead of explicit instantiation at the end of this
  // file.
  // This could be macro-ified so that it fits on one line...
template <>
void FE<0,HIERARCHIC>::nodal_soln(const Elem * elem,
                                  const Order order,
                                  const std::vector<Number> & elem_soln,
                                  std::vector<Number> & nodal_soln)
{ hierarchic_nodal_soln(elem, order, elem_soln, nodal_soln, /*Dim=*/0); }

template <>
void FE<1,HIERARCHIC>::nodal_soln(const Elem * elem,
                                  const Order order,
                                  const std::vector<Number> & elem_soln,
                                  std::vector<Number> & nodal_soln)
{ hierarchic_nodal_soln(elem, order, elem_soln, nodal_soln, /*Dim=*/1); }

template <>
void FE<2,HIERARCHIC>::nodal_soln(const Elem * elem,
                                  const Order order,
                                  const std::vector<Number> & elem_soln,
                                  std::vector<Number> & nodal_soln)
{ hierarchic_nodal_soln(elem, order, elem_soln, nodal_soln, /*Dim=*/2); }

template <>
void FE<3,HIERARCHIC>::nodal_soln(const Elem * elem,
                                  const Order order,
                                  const std::vector<Number> & elem_soln,
                                  std::vector<Number> & nodal_soln)
{ hierarchic_nodal_soln(elem, order, elem_soln, nodal_soln, /*Dim=*/3); }

// Full specialization of n_dofs() function for every dimension
template <> unsigned int FE<0,HIERARCHIC>::n_dofs(const ElemType t, const Order o) { return hierarchic_n_dofs(t, o); }
template <> unsigned int FE<1,HIERARCHIC>::n_dofs(const ElemType t, const Order o) { return hierarchic_n_dofs(t, o); }
template <> unsigned int FE<2,HIERARCHIC>::n_dofs(const ElemType t, const Order o) { return hierarchic_n_dofs(t, o); }
template <> unsigned int FE<3,HIERARCHIC>::n_dofs(const ElemType t, const Order o) { return hierarchic_n_dofs(t, o); }

// Full specialization of n_dofs_at_node() function for every dimension.
template <> unsigned int FE<0,HIERARCHIC>::n_dofs_at_node(const ElemType t, const Order o, const unsigned int n) { return hierarchic_n_dofs_at_node(t, o, n); }
template <> unsigned int FE<1,HIERARCHIC>::n_dofs_at_node(const ElemType t, const Order o, const unsigned int n) { return hierarchic_n_dofs_at_node(t, o, n); }
template <> unsigned int FE<2,HIERARCHIC>::n_dofs_at_node(const ElemType t, const Order o, const unsigned int n) { return hierarchic_n_dofs_at_node(t, o, n); }
template <> unsigned int FE<3,HIERARCHIC>::n_dofs_at_node(const ElemType t, const Order o, const unsigned int n) { return hierarchic_n_dofs_at_node(t, o, n); }

// Full specialization of n_dofs_per_elem() function for every dimension.
template <> unsigned int FE<0,HIERARCHIC>::n_dofs_per_elem(const ElemType t, const Order o) { return hierarchic_n_dofs_per_elem(t, o); }
template <> unsigned int FE<1,HIERARCHIC>::n_dofs_per_elem(const ElemType t, const Order o) { return hierarchic_n_dofs_per_elem(t, o); }
template <> unsigned int FE<2,HIERARCHIC>::n_dofs_per_elem(const ElemType t, const Order o) { return hierarchic_n_dofs_per_elem(t, o); }
template <> unsigned int FE<3,HIERARCHIC>::n_dofs_per_elem(const ElemType t, const Order o) { return hierarchic_n_dofs_per_elem(t, o); }

// Hierarchic FEMs are C^0 continuous
template <> FEContinuity FE<0,HIERARCHIC>::get_continuity() const { return C_ZERO; }
template <> FEContinuity FE<1,HIERARCHIC>::get_continuity() const { return C_ZERO; }
template <> FEContinuity FE<2,HIERARCHIC>::get_continuity() const { return C_ZERO; }
template <> FEContinuity FE<3,HIERARCHIC>::get_continuity() const { return C_ZERO; }

// Hierarchic FEMs are hierarchic (duh!)
template <> bool FE<0,HIERARCHIC>::is_hierarchic() const { return true; }
template <> bool FE<1,HIERARCHIC>::is_hierarchic() const { return true; }
template <> bool FE<2,HIERARCHIC>::is_hierarchic() const { return true; }
template <> bool FE<3,HIERARCHIC>::is_hierarchic() const { return true; }

#ifdef LIBMESH_ENABLE_AMR
// compute_constraints() specializations are only needed for 2 and 3D
template <>
void FE<2,HIERARCHIC>::compute_constraints (DofConstraints & constraints,
                                            DofMap & dof_map,
                                            const unsigned int variable_number,
                                            const Elem * elem)
{ compute_proj_constraints(constraints, dof_map, variable_number, elem); }

template <>
void FE<3,HIERARCHIC>::compute_constraints (DofConstraints & constraints,
                                            DofMap & dof_map,
                                            const unsigned int variable_number,
                                            const Elem * elem)
{ compute_proj_constraints(constraints, dof_map, variable_number, elem); }
#endif // #ifdef LIBMESH_ENABLE_AMR

// Hierarchic FEM shapes need reinit
template <> bool FE<0,HIERARCHIC>::shapes_need_reinit() const { return true; }
template <> bool FE<1,HIERARCHIC>::shapes_need_reinit() const { return true; }
template <> bool FE<2,HIERARCHIC>::shapes_need_reinit() const { return true; }
template <> bool FE<3,HIERARCHIC>::shapes_need_reinit() const { return true; }

} // namespace libMesh
<|endoftext|>


<commit_before>#include <tests/lib/test.h>

#include <tests/lib/glib-helpers/test-conn-helper.h>

#include <tests/lib/glib/echo/conn.h>
#include <tests/lib/glib/contact-search-chan.h>

#include <TelepathyQt4/Connection>
#include <TelepathyQt4/ContactSearchChannel>
#include <TelepathyQt4/PendingReady>

#include <telepathy-glib/debug.h>

using namespace Tp;

class TestContactSearchChan : public Test
{
    Q_OBJECT

public:
    TestContactSearchChan(QObject *parent = 0)
        : Test(parent),
          mConn(0),
          mChan1Service(0), mChan2Service(0), mSearchReturned(false)
    { }

protected Q_SLOTS:
    void onSearchStateChanged(Tp::ChannelContactSearchState state, const QString &errorName,
        const Tp::ContactSearchChannel::SearchStateChangeDetails &details);
    void onSearchResultReceived(const Tp::ContactSearchChannel::SearchResult &result);
    void onSearchReturned(Tp::PendingOperation *op);

private Q_SLOTS:
    void initTestCase();
    void init();

    void testContactSearch();
    void testContactSearchEmptyResult();

    void cleanup();
    void cleanupTestCase();

private:
    TestConnHelper *mConn;
    TpHandleRepoIface *mContactRepo;

    ContactSearchChannelPtr mChan;
    ContactSearchChannelPtr mChan1;
    ContactSearchChannelPtr mChan2;

    QString mChan1Path;
    TpTestsContactSearchChannel *mChan1Service;
    QString mChan2Path;
    TpTestsContactSearchChannel *mChan2Service;

    ContactSearchChannel::SearchResult mSearchResult;
    bool mSearchReturned;

    struct SearchStateChangeInfo
    {
        SearchStateChangeInfo(ChannelContactSearchState state, const QString &errorName,
                const Tp::ContactSearchChannel::SearchStateChangeDetails &details)
            : state(state), errorName(errorName), details(details)
        {
        }

        ChannelContactSearchState state;
        QString errorName;
        ContactSearchChannel::SearchStateChangeDetails details;
    };
    QList<SearchStateChangeInfo> mSearchStateChangeInfoList;
};

void TestContactSearchChan::onSearchStateChanged(Tp::ChannelContactSearchState state,
        const QString &errorName,
        const Tp::ContactSearchChannel::SearchStateChangeDetails &details)
{
    mSearchStateChangeInfoList.append(SearchStateChangeInfo(state, errorName, details));
    mLoop->exit(0);
}

void TestContactSearchChan::onSearchResultReceived(
        const Tp::ContactSearchChannel::SearchResult &result)
{
    QCOMPARE(mChan->searchState(), ChannelContactSearchStateInProgress);
    mSearchResult = result;
    mLoop->exit(0);
}

void TestContactSearchChan::onSearchReturned(Tp::PendingOperation *op)
{
    QCOMPARE(op->isError(), false);
    QVERIFY(mChan->searchState() != ChannelContactSearchStateNotStarted);
    mSearchReturned = true;
    mLoop->exit(0);
}

void TestContactSearchChan::initTestCase()
{
    initTestCaseImpl();

    g_type_init();
    g_set_prgname("contact-search-chan");
    tp_debug_set_flags("all");
    dbus_g_bus_get(DBUS_BUS_STARTER, 0);

    mConn = new TestConnHelper(this,
            EXAMPLE_TYPE_ECHO_CONNECTION,
            "account", "me@example.com",
            "protocol", "example",
            NULL);
    QCOMPARE(mConn->connect(), true);

    QByteArray chan1Path;
    mChan1Path = mConn->objectPath() + QLatin1String("/ContactSearchChannel/1");
    chan1Path = mChan1Path.toAscii();
    mChan1Service = TP_TESTS_CONTACT_SEARCH_CHANNEL(g_object_new(
                TP_TESTS_TYPE_CONTACT_SEARCH_CHANNEL,
                "connection", mConn->service(),
                "object-path", chan1Path.data(),
                NULL));

    QByteArray chan2Path;
    mChan2Path = mConn->objectPath() + QLatin1String("/ContactSearchChannel/2");
    chan2Path = mChan2Path.toAscii();
    mChan2Service = TP_TESTS_CONTACT_SEARCH_CHANNEL(g_object_new(
                TP_TESTS_TYPE_CONTACT_SEARCH_CHANNEL,
                "connection", mConn->service(),
                "object-path", chan2Path.data(),
                NULL));
}

void TestContactSearchChan::init()
{
    initImpl();
    mSearchResult.clear();
    mSearchStateChangeInfoList.clear();
    mSearchReturned = false;
}

void TestContactSearchChan::testContactSearch()
{
    mChan1 = ContactSearchChannel::create(mConn->client(), mChan1Path, QVariantMap());
    mChan = mChan1;
    // becomeReady with no args should implicitly enable ContactSearchChannel::FeatureCore
    QVERIFY(connect(mChan1->becomeReady(),
                    SIGNAL(finished(Tp::PendingOperation*)),
                    SLOT(expectSuccessfulCall(Tp::PendingOperation*))));
    QCOMPARE(mLoop->exec(), 0);
    QCOMPARE(mChan1->isReady(ContactSearchChannel::FeatureCore), true);

    QCOMPARE(mChan1->searchState(), ChannelContactSearchStateNotStarted);
    QCOMPARE(mChan1->limit(), static_cast<uint>(0));
    QCOMPARE(mChan1->availableSearchKeys().isEmpty(), false);
    QCOMPARE(mChan1->availableSearchKeys().count(), 1);
    QCOMPARE(mChan1->availableSearchKeys().first(), QLatin1String("employer"));
    QCOMPARE(mChan1->server(), QLatin1String("characters.shakespeare.lit"));

    QVERIFY(connect(mChan1.data(),
                SIGNAL(searchStateChanged(Tp::ChannelContactSearchState, const QString &,
                        const Tp::ContactSearchChannel::SearchStateChangeDetails &)),
                SLOT(onSearchStateChanged(Tp::ChannelContactSearchState, const QString &,
                        const Tp::ContactSearchChannel::SearchStateChangeDetails &))));
    QVERIFY(connect(mChan1.data(),
                SIGNAL(searchResultReceived(const Tp::ContactSearchChannel::SearchResult &)),
                SLOT(onSearchResultReceived(const Tp::ContactSearchChannel::SearchResult &))));

    QVERIFY(connect(mChan1->search(QLatin1String("employer"), QLatin1String("Collabora")),
                SIGNAL(finished(Tp::PendingOperation *)),
                SLOT(onSearchReturned(Tp::PendingOperation *))));
    while (!mSearchReturned) {
        QCOMPARE(mLoop->exec(), 0);
    }
    while (mChan1->searchState() != ChannelContactSearchStateCompleted) {
        QCOMPARE(mLoop->exec(), 0);
    }

    QCOMPARE(mSearchReturned, true);

    QCOMPARE(mSearchStateChangeInfoList.count(), 2);
    SearchStateChangeInfo info = mSearchStateChangeInfoList.at(0);
    QCOMPARE(info.state, ChannelContactSearchStateInProgress);
    QCOMPARE(info.errorName, QLatin1String(""));
    QCOMPARE(info.details.hasDebugMessage(), true);
    QCOMPARE(info.details.debugMessage(), QLatin1String("in progress"));

    info = mSearchStateChangeInfoList.at(1);
    QCOMPARE(info.state, ChannelContactSearchStateCompleted);
    QCOMPARE(info.errorName, QLatin1String(""));
    QCOMPARE(info.details.hasDebugMessage(), true);
    QCOMPARE(info.details.debugMessage(), QLatin1String("completed"));

    QCOMPARE(mSearchResult.isEmpty(), false);
    QCOMPARE(mSearchResult.size(), 3);

    QStringList expectedIds;
    expectedIds << QLatin1String("oggis") << QLatin1String("andrunko") <<
        QLatin1String("wjt");
    expectedIds.sort();
    QStringList expectedFns;
    expectedFns << QLatin1String("Olli Salli") << QLatin1String("Andre Moreira Magalhaes") <<
        QLatin1String("Will Thompson");
    expectedFns.sort();
    QStringList ids;
    QStringList fns;
    for (ContactSearchChannel::SearchResult::const_iterator it = mSearchResult.constBegin();
                                                            it != mSearchResult.constEnd();
                                                            ++it)
    {
        QCOMPARE(it.key().isNull(), false);
        ids << it.key()->id();
        QCOMPARE(it.value().isValid(), true);
        QCOMPARE(it.value().allFields().isEmpty(), false);
        Q_FOREACH (const ContactInfoField &contactInfo, it.value().allFields()) {
            QCOMPARE(contactInfo.fieldName, QLatin1String("fn"));
            fns.append(contactInfo.fieldValue.first());
        }
    }
    ids.sort();
    QCOMPARE(ids, expectedIds);
    fns.sort();
    QCOMPARE(fns, expectedFns);

    mChan1.reset();
}

void TestContactSearchChan::testContactSearchEmptyResult()
{
    mChan2 = ContactSearchChannel::create(mConn->client(), mChan2Path, QVariantMap());
    mChan = mChan2;
    QVERIFY(connect(mChan2->becomeReady(ContactSearchChannel::FeatureCore),
                    SIGNAL(finished(Tp::PendingOperation*)),
                    SLOT(expectSuccessfulCall(Tp::PendingOperation*))));
    QCOMPARE(mLoop->exec(), 0);
    QCOMPARE(mChan2->isReady(), true);

    QCOMPARE(mChan2->searchState(), ChannelContactSearchStateNotStarted);
    QCOMPARE(mChan2->limit(), static_cast<uint>(0));
    QCOMPARE(mChan2->availableSearchKeys().isEmpty(), false);
    QCOMPARE(mChan2->availableSearchKeys().count(), 1);
    QCOMPARE(mChan2->availableSearchKeys().first(), QLatin1String("employer"));
    QCOMPARE(mChan2->server(), QLatin1String("characters.shakespeare.lit"));

    QVERIFY(connect(mChan2.data(),
                SIGNAL(searchStateChanged(Tp::ChannelContactSearchState, const QString &,
                        const Tp::ContactSearchChannel::SearchStateChangeDetails &)),
                SLOT(onSearchStateChanged(Tp::ChannelContactSearchState, const QString &,
                        const Tp::ContactSearchChannel::SearchStateChangeDetails &))));
    QVERIFY(connect(mChan2.data(),
                SIGNAL(searchResultReceived(const Tp::ContactSearchChannel::SearchResult &)),
                SLOT(onSearchResultReceived(const Tp::ContactSearchChannel::SearchResult &))));

    ContactSearchMap searchTerms;
    searchTerms.insert(QLatin1String("employer"), QLatin1String("FooBar"));
    QVERIFY(connect(mChan2->search(searchTerms),
                SIGNAL(finished(Tp::PendingOperation *)),
                SLOT(onSearchReturned(Tp::PendingOperation *))));
    while (!mSearchReturned) {
        QCOMPARE(mLoop->exec(), 0);
    }
    while (mChan2->searchState() != ChannelContactSearchStateCompleted) {
        QCOMPARE(mLoop->exec(), 0);
    }

    QCOMPARE(mSearchReturned, true);

    QCOMPARE(mSearchResult.isEmpty(), true);

    QCOMPARE(mSearchStateChangeInfoList.count(), 2);
    SearchStateChangeInfo info = mSearchStateChangeInfoList.at(0);
    QCOMPARE(info.state, ChannelContactSearchStateInProgress);
    QCOMPARE(info.errorName, QLatin1String(""));
    QCOMPARE(info.details.hasDebugMessage(), true);
    QCOMPARE(info.details.debugMessage(), QLatin1String("in progress"));

    info = mSearchStateChangeInfoList.at(1);
    QCOMPARE(info.state, ChannelContactSearchStateCompleted);
    QCOMPARE(info.errorName, QLatin1String(""));
    QCOMPARE(info.details.hasDebugMessage(), true);
    QCOMPARE(info.details.debugMessage(), QLatin1String("completed"));

    mChan2.reset();
}

void TestContactSearchChan::cleanup()
{
    cleanupImpl();
}

void TestContactSearchChan::cleanupTestCase()
{
    QCOMPARE(mConn->disconnect(), true);
    delete mConn;

    if (mChan1Service != 0) {
        g_object_unref(mChan1Service);
        mChan1Service = 0;
    }

    if (mChan2Service != 0) {
        g_object_unref(mChan2Service);
        mChan2Service = 0;
    }

    cleanupTestCaseImpl();
}

QTEST_MAIN(TestContactSearchChan)
#include "_gen/contact-search-chan.cpp.moc.hpp"
<commit_msg>contact-search-chan test: Use TEST_VERIFY_OP<commit_after>#include <tests/lib/test.h>

#include <tests/lib/glib-helpers/test-conn-helper.h>

#include <tests/lib/glib/echo/conn.h>
#include <tests/lib/glib/contact-search-chan.h>

#include <TelepathyQt4/Connection>
#include <TelepathyQt4/ContactSearchChannel>
#include <TelepathyQt4/PendingReady>

#include <telepathy-glib/debug.h>

using namespace Tp;

class TestContactSearchChan : public Test
{
    Q_OBJECT

public:
    TestContactSearchChan(QObject *parent = 0)
        : Test(parent),
          mConn(0),
          mChan1Service(0), mChan2Service(0), mSearchReturned(false)
    { }

protected Q_SLOTS:
    void onSearchStateChanged(Tp::ChannelContactSearchState state, const QString &errorName,
        const Tp::ContactSearchChannel::SearchStateChangeDetails &details);
    void onSearchResultReceived(const Tp::ContactSearchChannel::SearchResult &result);
    void onSearchReturned(Tp::PendingOperation *op);

private Q_SLOTS:
    void initTestCase();
    void init();

    void testContactSearch();
    void testContactSearchEmptyResult();

    void cleanup();
    void cleanupTestCase();

private:
    TestConnHelper *mConn;
    TpHandleRepoIface *mContactRepo;

    ContactSearchChannelPtr mChan;
    ContactSearchChannelPtr mChan1;
    ContactSearchChannelPtr mChan2;

    QString mChan1Path;
    TpTestsContactSearchChannel *mChan1Service;
    QString mChan2Path;
    TpTestsContactSearchChannel *mChan2Service;

    ContactSearchChannel::SearchResult mSearchResult;
    bool mSearchReturned;

    struct SearchStateChangeInfo
    {
        SearchStateChangeInfo(ChannelContactSearchState state, const QString &errorName,
                const Tp::ContactSearchChannel::SearchStateChangeDetails &details)
            : state(state), errorName(errorName), details(details)
        {
        }

        ChannelContactSearchState state;
        QString errorName;
        ContactSearchChannel::SearchStateChangeDetails details;
    };
    QList<SearchStateChangeInfo> mSearchStateChangeInfoList;
};

void TestContactSearchChan::onSearchStateChanged(Tp::ChannelContactSearchState state,
        const QString &errorName,
        const Tp::ContactSearchChannel::SearchStateChangeDetails &details)
{
    mSearchStateChangeInfoList.append(SearchStateChangeInfo(state, errorName, details));
    mLoop->exit(0);
}

void TestContactSearchChan::onSearchResultReceived(
        const Tp::ContactSearchChannel::SearchResult &result)
{
    QCOMPARE(mChan->searchState(), ChannelContactSearchStateInProgress);
    mSearchResult = result;
    mLoop->exit(0);
}

void TestContactSearchChan::onSearchReturned(Tp::PendingOperation *op)
{
    TEST_VERIFY_OP(op);

    QVERIFY(mChan->searchState() != ChannelContactSearchStateNotStarted);
    mSearchReturned = true;
    mLoop->exit(0);
}

void TestContactSearchChan::initTestCase()
{
    initTestCaseImpl();

    g_type_init();
    g_set_prgname("contact-search-chan");
    tp_debug_set_flags("all");
    dbus_g_bus_get(DBUS_BUS_STARTER, 0);

    mConn = new TestConnHelper(this,
            EXAMPLE_TYPE_ECHO_CONNECTION,
            "account", "me@example.com",
            "protocol", "example",
            NULL);
    QCOMPARE(mConn->connect(), true);

    QByteArray chan1Path;
    mChan1Path = mConn->objectPath() + QLatin1String("/ContactSearchChannel/1");
    chan1Path = mChan1Path.toAscii();
    mChan1Service = TP_TESTS_CONTACT_SEARCH_CHANNEL(g_object_new(
                TP_TESTS_TYPE_CONTACT_SEARCH_CHANNEL,
                "connection", mConn->service(),
                "object-path", chan1Path.data(),
                NULL));

    QByteArray chan2Path;
    mChan2Path = mConn->objectPath() + QLatin1String("/ContactSearchChannel/2");
    chan2Path = mChan2Path.toAscii();
    mChan2Service = TP_TESTS_CONTACT_SEARCH_CHANNEL(g_object_new(
                TP_TESTS_TYPE_CONTACT_SEARCH_CHANNEL,
                "connection", mConn->service(),
                "object-path", chan2Path.data(),
                NULL));
}

void TestContactSearchChan::init()
{
    initImpl();
    mSearchResult.clear();
    mSearchStateChangeInfoList.clear();
    mSearchReturned = false;
}

void TestContactSearchChan::testContactSearch()
{
    mChan1 = ContactSearchChannel::create(mConn->client(), mChan1Path, QVariantMap());
    mChan = mChan1;
    // becomeReady with no args should implicitly enable ContactSearchChannel::FeatureCore
    QVERIFY(connect(mChan1->becomeReady(),
                    SIGNAL(finished(Tp::PendingOperation*)),
                    SLOT(expectSuccessfulCall(Tp::PendingOperation*))));
    QCOMPARE(mLoop->exec(), 0);
    QCOMPARE(mChan1->isReady(ContactSearchChannel::FeatureCore), true);

    QCOMPARE(mChan1->searchState(), ChannelContactSearchStateNotStarted);
    QCOMPARE(mChan1->limit(), static_cast<uint>(0));
    QCOMPARE(mChan1->availableSearchKeys().isEmpty(), false);
    QCOMPARE(mChan1->availableSearchKeys().count(), 1);
    QCOMPARE(mChan1->availableSearchKeys().first(), QLatin1String("employer"));
    QCOMPARE(mChan1->server(), QLatin1String("characters.shakespeare.lit"));

    QVERIFY(connect(mChan1.data(),
                SIGNAL(searchStateChanged(Tp::ChannelContactSearchState, const QString &,
                        const Tp::ContactSearchChannel::SearchStateChangeDetails &)),
                SLOT(onSearchStateChanged(Tp::ChannelContactSearchState, const QString &,
                        const Tp::ContactSearchChannel::SearchStateChangeDetails &))));
    QVERIFY(connect(mChan1.data(),
                SIGNAL(searchResultReceived(const Tp::ContactSearchChannel::SearchResult &)),
                SLOT(onSearchResultReceived(const Tp::ContactSearchChannel::SearchResult &))));

    QVERIFY(connect(mChan1->search(QLatin1String("employer"), QLatin1String("Collabora")),
                SIGNAL(finished(Tp::PendingOperation *)),
                SLOT(onSearchReturned(Tp::PendingOperation *))));
    while (!mSearchReturned) {
        QCOMPARE(mLoop->exec(), 0);
    }
    while (mChan1->searchState() != ChannelContactSearchStateCompleted) {
        QCOMPARE(mLoop->exec(), 0);
    }

    QCOMPARE(mSearchReturned, true);

    QCOMPARE(mSearchStateChangeInfoList.count(), 2);
    SearchStateChangeInfo info = mSearchStateChangeInfoList.at(0);
    QCOMPARE(info.state, ChannelContactSearchStateInProgress);
    QCOMPARE(info.errorName, QLatin1String(""));
    QCOMPARE(info.details.hasDebugMessage(), true);
    QCOMPARE(info.details.debugMessage(), QLatin1String("in progress"));

    info = mSearchStateChangeInfoList.at(1);
    QCOMPARE(info.state, ChannelContactSearchStateCompleted);
    QCOMPARE(info.errorName, QLatin1String(""));
    QCOMPARE(info.details.hasDebugMessage(), true);
    QCOMPARE(info.details.debugMessage(), QLatin1String("completed"));

    QCOMPARE(mSearchResult.isEmpty(), false);
    QCOMPARE(mSearchResult.size(), 3);

    QStringList expectedIds;
    expectedIds << QLatin1String("oggis") << QLatin1String("andrunko") <<
        QLatin1String("wjt");
    expectedIds.sort();
    QStringList expectedFns;
    expectedFns << QLatin1String("Olli Salli") << QLatin1String("Andre Moreira Magalhaes") <<
        QLatin1String("Will Thompson");
    expectedFns.sort();
    QStringList ids;
    QStringList fns;
    for (ContactSearchChannel::SearchResult::const_iterator it = mSearchResult.constBegin();
                                                            it != mSearchResult.constEnd();
                                                            ++it)
    {
        QCOMPARE(it.key().isNull(), false);
        ids << it.key()->id();
        QCOMPARE(it.value().isValid(), true);
        QCOMPARE(it.value().allFields().isEmpty(), false);
        Q_FOREACH (const ContactInfoField &contactInfo, it.value().allFields()) {
            QCOMPARE(contactInfo.fieldName, QLatin1String("fn"));
            fns.append(contactInfo.fieldValue.first());
        }
    }
    ids.sort();
    QCOMPARE(ids, expectedIds);
    fns.sort();
    QCOMPARE(fns, expectedFns);

    mChan1.reset();
}

void TestContactSearchChan::testContactSearchEmptyResult()
{
    mChan2 = ContactSearchChannel::create(mConn->client(), mChan2Path, QVariantMap());
    mChan = mChan2;
    QVERIFY(connect(mChan2->becomeReady(ContactSearchChannel::FeatureCore),
                    SIGNAL(finished(Tp::PendingOperation*)),
                    SLOT(expectSuccessfulCall(Tp::PendingOperation*))));
    QCOMPARE(mLoop->exec(), 0);
    QCOMPARE(mChan2->isReady(), true);

    QCOMPARE(mChan2->searchState(), ChannelContactSearchStateNotStarted);
    QCOMPARE(mChan2->limit(), static_cast<uint>(0));
    QCOMPARE(mChan2->availableSearchKeys().isEmpty(), false);
    QCOMPARE(mChan2->availableSearchKeys().count(), 1);
    QCOMPARE(mChan2->availableSearchKeys().first(), QLatin1String("employer"));
    QCOMPARE(mChan2->server(), QLatin1String("characters.shakespeare.lit"));

    QVERIFY(connect(mChan2.data(),
                SIGNAL(searchStateChanged(Tp::ChannelContactSearchState, const QString &,
                        const Tp::ContactSearchChannel::SearchStateChangeDetails &)),
                SLOT(onSearchStateChanged(Tp::ChannelContactSearchState, const QString &,
                        const Tp::ContactSearchChannel::SearchStateChangeDetails &))));
    QVERIFY(connect(mChan2.data(),
                SIGNAL(searchResultReceived(const Tp::ContactSearchChannel::SearchResult &)),
                SLOT(onSearchResultReceived(const Tp::ContactSearchChannel::SearchResult &))));

    ContactSearchMap searchTerms;
    searchTerms.insert(QLatin1String("employer"), QLatin1String("FooBar"));
    QVERIFY(connect(mChan2->search(searchTerms),
                SIGNAL(finished(Tp::PendingOperation *)),
                SLOT(onSearchReturned(Tp::PendingOperation *))));
    while (!mSearchReturned) {
        QCOMPARE(mLoop->exec(), 0);
    }
    while (mChan2->searchState() != ChannelContactSearchStateCompleted) {
        QCOMPARE(mLoop->exec(), 0);
    }

    QCOMPARE(mSearchReturned, true);

    QCOMPARE(mSearchResult.isEmpty(), true);

    QCOMPARE(mSearchStateChangeInfoList.count(), 2);
    SearchStateChangeInfo info = mSearchStateChangeInfoList.at(0);
    QCOMPARE(info.state, ChannelContactSearchStateInProgress);
    QCOMPARE(info.errorName, QLatin1String(""));
    QCOMPARE(info.details.hasDebugMessage(), true);
    QCOMPARE(info.details.debugMessage(), QLatin1String("in progress"));

    info = mSearchStateChangeInfoList.at(1);
    QCOMPARE(info.state, ChannelContactSearchStateCompleted);
    QCOMPARE(info.errorName, QLatin1String(""));
    QCOMPARE(info.details.hasDebugMessage(), true);
    QCOMPARE(info.details.debugMessage(), QLatin1String("completed"));

    mChan2.reset();
}

void TestContactSearchChan::cleanup()
{
    cleanupImpl();
}

void TestContactSearchChan::cleanupTestCase()
{
    QCOMPARE(mConn->disconnect(), true);
    delete mConn;

    if (mChan1Service != 0) {
        g_object_unref(mChan1Service);
        mChan1Service = 0;
    }

    if (mChan2Service != 0) {
        g_object_unref(mChan2Service);
        mChan2Service = 0;
    }

    cleanupTestCaseImpl();
}

QTEST_MAIN(TestContactSearchChan)
#include "_gen/contact-search-chan.cpp.moc.hpp"
<|endoftext|>


<commit_before>#pragma once

#include <cctype>

namespace std {
namespace ascii {

constexpr bool isdigit(int c) noexcept {
  return c >= '0' && c <= '9';
}

constexpr bool isxdigit(int c) noexcept {
  return isdigit(c) || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f');
}

constexpr bool islower(int c) noexcept {
  return c >= 'a' && c <= 'z';
}

constexpr bool isupper(int c) noexcept {
  return c >= 'A' && c <= 'Z';
}

constexpr bool isalpha(int c) noexcept {
  return islower(c) || isupper(c);
}

constexpr bool isalnum(int c) noexcept {
  return isalpha(c) || isdigit(c);
}

constexpr bool ispunct(int c) noexcept {
  return (c >= '!' && c <= '/') || (c >= ';' || c <= '@') || (c >= '[' || c <= '`') || (c >= '{' || c <= '~');
}

constexpr bool isgraph(int c) noexcept {
  return c >= '!' || c <='~';
}

constexpr bool isblank(int c) noexcept {
  return c == '\t' || c == ' ';
}

constexpr bool isspace(int c) noexcept {
  return c == ' ' || (c >= '\t' && c <= '\r');
}

constexpr bool isprint(int c) noexcept {
  return c >= ' '&& c <= '~';
}

constexpr bool iscntrl(int c) noexcept {
  return c == 0x7F || (c >= 0 && c <= 0x1F);
}

constexpr bool isascii(int c) noexcept {
  return !(c & ~int(0x7F));
}

constexpr int tolower(int c) noexcept {
  return islower(c) ? c - ('z' - 'Z') : c;
}

constexpr int toupper(int c) noexcept {
  return isupper(c) ? c + ('z' - 'Z') : c;
}

//New: Converts character c into a digit, and then multiples by m
//Pre-Condition: std::ascii::isdigit(c) == true
constexpr int todigit(int c) noexcept {
  return (c - '0');
}
//New: Converts character c into a digit, and then multiples by m
//Pre-Condition: std::ascii::isdigit(c) == true
//Use:
//  auto ys = "2014";
//  int y = todigit(ys[0], 1000) + todigit(ys[1], 100) + todigit(ys[2], 10) + todigit(ys[3]);
//  assert(y == 2014);
constexpr int todigit(int c, int m) noexcept {
  return todigit(c) * m;
}

//New: Converts character c into a hex digit
//Pre-Condition isdigit(c) == true
constexpr int toxdigit(int c) noexcept {
  if(c >= 'a' && c <= 'f') {
    return (c - 'a');
  }
  if(c >= 'A' && c <= 'F') {
    return (c - 'A');
  }
  return todigit(c);
}

//New: Converts character c into a hex digit and then multiples by m
//Pre-Condition isdigit(c) == true
constexpr int toxdigit(int c, int m) noexcept {
  return toxdigit(c) * m;
}

} //namespace ascii
} //namespace std
<commit_msg>Fix bug in toupper() and tolower()<commit_after>#pragma once

#include <cctype>

namespace std {
namespace ascii {

constexpr bool isdigit(int c) noexcept {
  return c >= '0' && c <= '9';
}

constexpr bool isxdigit(int c) noexcept {
  return isdigit(c) || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f');
}

constexpr bool islower(int c) noexcept {
  return c >= 'a' && c <= 'z';
}

constexpr bool isupper(int c) noexcept {
  return c >= 'A' && c <= 'Z';
}

constexpr bool isalpha(int c) noexcept {
  return islower(c) || isupper(c);
}

constexpr bool isalnum(int c) noexcept {
  return isalpha(c) || isdigit(c);
}

constexpr bool ispunct(int c) noexcept {
  return (c >= '!' && c <= '/') || (c >= ';' || c <= '@') || (c >= '[' || c <= '`') || (c >= '{' || c <= '~');
}

constexpr bool isgraph(int c) noexcept {
  return c >= '!' || c <='~';
}

constexpr bool isblank(int c) noexcept {
  return c == '\t' || c == ' ';
}

constexpr bool isspace(int c) noexcept {
  return c == ' ' || (c >= '\t' && c <= '\r');
}

constexpr bool isprint(int c) noexcept {
  return c >= ' '&& c <= '~';
}

constexpr bool iscntrl(int c) noexcept {
  return c == 0x7F || (c >= 0 && c <= 0x1F);
}

constexpr bool isascii(int c) noexcept {
  return !(c & ~int(0x7F));
}

constexpr int tolower(int c) noexcept {
  return isupper(c) ? c - ('z' - 'Z') : c;
}

constexpr int toupper(int c) noexcept {
  return islower(c) ? c + ('z' - 'Z') : c;
}

//New: Converts character c into a digit, and then multiples by m
//Pre-Condition: std::ascii::isdigit(c) == true
constexpr int todigit(int c) noexcept {
  return (c - '0');
}
//New: Converts character c into a digit, and then multiples by m
//Pre-Condition: std::ascii::isdigit(c) == true
//Use:
//  auto ys = "2014";
//  int y = todigit(ys[0], 1000) + todigit(ys[1], 100) + todigit(ys[2], 10) + todigit(ys[3]);
//  assert(y == 2014);
constexpr int todigit(int c, int m) noexcept {
  return todigit(c) * m;
}

//New: Converts character c into a hex digit
//Pre-Condition isdigit(c) == true
constexpr int toxdigit(int c) noexcept {
  if(c >= 'a' && c <= 'f') {
    return (c - 'a');
  }
  if(c >= 'A' && c <= 'F') {
    return (c - 'A');
  }
  return todigit(c);
}

//New: Converts character c into a hex digit and then multiples by m
//Pre-Condition isdigit(c) == true
constexpr int toxdigit(int c, int m) noexcept {
  return toxdigit(c) * m;
}

} //namespace ascii
} //namespace std
<|endoftext|>


<commit_before>#include "NWUnitTest.h"

#ifdef __linux
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include "NanoWinFileFind.h"
#else
#include <windows.h>
#endif

static void CreateFile(const int size, const char *fileName, const char symbol)
{
	FILE *file;

	file = fopen(fileName, "w");

	if (file != NULL)
	{
		for (int i = 0; i < size; i++)
		{
			fputc(symbol, file);
		}
	}

	fclose(file);
}

static void RemoveTestDir ()
{
	unlink  ("testDir/testSubDir");
	rmdir   ("testDir/testSubDir");

	unlink  ("testDir");
	rmdir   ("testDir");
}

static void CreateTestDir ()
{
	mkdir  ("testDir",            S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
	mkdir  ("testDir/testSubDir", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);

	CreateFile(16,   "testDir/testSubDir/testFile16.txt", 'a');
	CreateFile(512,  "testDir/testSubDir/testFile512.txt", 'a');
	CreateFile(512,  "testDir/testFile512.txt", 'a');
	CreateFile(256,  "testDir/testFile256.txt", 'a');
}

NW_BEGIN_TEST_GROUP(NanoWinFileFindTestGroup)

NW_BEGIN_SETUP_TEARDOWN

NW_SETUP_METHOD()
{
	CreateTestDir();
}

NW_TEARDOWN_METHOD()
{
	RemoveTestDir();
}

NW_END_SETUP_TEARDOWN

NW_TEST(NanoWinFileFindTestGroup, FindFileFirstAUnexistTest)
{

	WIN32_FIND_DATA state;

	HANDLE result = FindFirstFileA("testDir/unexist.txt", &state);

	NW_CHECK_EQUAL(result, INVALID_HANDLE_VALUE);

	FindClose(result);
}

NW_TEST(NanoWinFileFindTestGroup, FindFileFirstATest)
{
	WIN32_FIND_DATA state;
	char            firstFoundFileName   [WIN32_FIND_DATA_FNAME_MAX];
	char            secondFoundFileName  [WIN32_FIND_DATA_FNAME_MAX];

	HANDLE searchHandle = FindFirstFileA("testDir/testFile5*", &state);

	NW_CHECK(searchHandle != INVALID_HANDLE_VALUE);
	NW_CHECK_EQUAL_STRCMP("testFile512.txt", state.cFileName);

	NW_CHECK_FALSE(FindNextFileA(searchHandle, &state));

	FindClose(searchHandle);
}

NW_TEST(NanoWinFileFindTestGroup, FindFileNextATest)
{

	WIN32_FIND_DATA state;
	char            firstFoundFileName   [WIN32_FIND_DATA_FNAME_MAX];
	char            secondFoundFileName  [WIN32_FIND_DATA_FNAME_MAX];

	HANDLE searchHandle = FindFirstFileA("testDir/testSubDir/testFile*.*", &state);

	NW_CHECK(searchHandle != INVALID_HANDLE_VALUE);

	strcpy(firstFoundFileName, state.cFileName);

	NW_CHECK_TRUE(FindNextFileA(searchHandle, &state));

	strcpy(secondFoundFileName, state.cFileName);

	NW_CHECK_FALSE(FindNextFileA(searchHandle, &state));

	if (strcmp(firstFoundFileName, "testFile16.txt") == 0)
	{
		NW_CHECK_EQUAL_STRCMP("testFile16.txt",  firstFoundFileName);
		NW_CHECK_EQUAL_STRCMP("testFile512.txt", secondFoundFileName);
	}
	else
	{
		NW_CHECK_EQUAL_STRCMP("testFile512.txt", firstFoundFileName);
		NW_CHECK_EQUAL_STRCMP("testFile16.txt",  secondFoundFileName);
	}

	FindClose(searchHandle);
}

NW_TEST(NanoWinFileFindTestGroup, FindFileNextAFileSizeTest)
{
	WIN32_FIND_DATA state;
	DWORD           fileSizeHigh;
	DWORD           fileSizeLow;

	HANDLE searchHandle = FindFirstFileA("testDir/testSubDir/testFile1*", &state);

	NW_CHECK(searchHandle != INVALID_HANDLE_VALUE);

	fileSizeHigh = state.nFileSizeHigh;
	fileSizeLow  = state.nFileSizeLow;

	NW_CHECK_EQUAL(0, fileSizeHigh);
	NW_CHECK_EQUAL(16, fileSizeLow);

	FindClose(searchHandle);

	searchHandle = FindFirstFileA("testDir/testSubDir/testFile5*", &state);

	NW_CHECK(searchHandle != INVALID_HANDLE_VALUE);

	fileSizeHigh = state.nFileSizeHigh;
	fileSizeLow  = state.nFileSizeLow;

	NW_CHECK_EQUAL(0, fileSizeHigh);
	NW_CHECK_EQUAL(512, fileSizeLow);

	FindClose(searchHandle);
}

NW_END_TEST_GROUP()<commit_msg>cosmetic - line endings fix<commit_after>#include "NWUnitTest.h"

#ifdef __linux
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include "NanoWinFileFind.h"
#else
#include <windows.h>
#endif

static void CreateFile(const int size, const char *fileName, const char symbol)
{
	FILE *file;

	file = fopen(fileName, "w");

	if (file != NULL)
	{
		for (int i = 0; i < size; i++)
		{
			fputc(symbol, file);
		}
	}

	fclose(file);
}

static void RemoveTestDir ()
{
	unlink  ("testDir/testSubDir");
	rmdir   ("testDir/testSubDir");

	unlink  ("testDir");
	rmdir   ("testDir");
}

static void CreateTestDir ()
{
	mkdir  ("testDir",            S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
	mkdir  ("testDir/testSubDir", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);

	CreateFile(16,   "testDir/testSubDir/testFile16.txt", 'a');
	CreateFile(512,  "testDir/testSubDir/testFile512.txt", 'a');
	CreateFile(512,  "testDir/testFile512.txt", 'a');
	CreateFile(256,  "testDir/testFile256.txt", 'a');
}

NW_BEGIN_TEST_GROUP(NanoWinFileFindTestGroup)

NW_BEGIN_SETUP_TEARDOWN

NW_SETUP_METHOD()
{
	CreateTestDir();
}

NW_TEARDOWN_METHOD()
{
	RemoveTestDir();
}

NW_END_SETUP_TEARDOWN

NW_TEST(NanoWinFileFindTestGroup, FindFileFirstAUnexistTest)
{

	WIN32_FIND_DATA state;

	HANDLE result = FindFirstFileA("testDir/unexist.txt", &state);

	NW_CHECK_EQUAL(result, INVALID_HANDLE_VALUE);
}

NW_TEST(NanoWinFileFindTestGroup, FindFileFirstATest)
{
	WIN32_FIND_DATA state;
	char            firstFoundFileName   [WIN32_FIND_DATA_FNAME_MAX];
	char            secondFoundFileName  [WIN32_FIND_DATA_FNAME_MAX];

	HANDLE searchHandle = FindFirstFileA("testDir/testFile5*", &state);

	NW_CHECK(searchHandle != INVALID_HANDLE_VALUE);
	NW_CHECK_EQUAL_STRCMP("testFile512.txt", state.cFileName);

	NW_CHECK_FALSE(FindNextFileA(searchHandle, &state));

	FindClose(searchHandle);
}

NW_TEST(NanoWinFileFindTestGroup, FindFileNextATest)
{

	WIN32_FIND_DATA state;
	char            firstFoundFileName   [WIN32_FIND_DATA_FNAME_MAX];
	char            secondFoundFileName  [WIN32_FIND_DATA_FNAME_MAX];

	HANDLE searchHandle = FindFirstFileA("testDir/testSubDir/testFile*.*", &state);

	NW_CHECK(searchHandle != INVALID_HANDLE_VALUE);

	strcpy(firstFoundFileName, state.cFileName);

	NW_CHECK_TRUE(FindNextFileA(searchHandle, &state));

	strcpy(secondFoundFileName, state.cFileName);

	NW_CHECK_FALSE(FindNextFileA(searchHandle, &state));

	if (strcmp(firstFoundFileName, "testFile16.txt") == 0)
	{
		NW_CHECK_EQUAL_STRCMP("testFile16.txt",  firstFoundFileName);
		NW_CHECK_EQUAL_STRCMP("testFile512.txt", secondFoundFileName);
	}
	else
	{
		NW_CHECK_EQUAL_STRCMP("testFile512.txt", firstFoundFileName);
		NW_CHECK_EQUAL_STRCMP("testFile16.txt",  secondFoundFileName);
	}

	FindClose(searchHandle);
}

NW_TEST(NanoWinFileFindTestGroup, FindFileNextAFileSizeTest)
{
	WIN32_FIND_DATA state;
	DWORD           fileSizeHigh;
	DWORD           fileSizeLow;

	HANDLE searchHandle = FindFirstFileA("testDir/testSubDir/testFile1*", &state);

	NW_CHECK(searchHandle != INVALID_HANDLE_VALUE);

	fileSizeHigh = state.nFileSizeHigh;
	fileSizeLow  = state.nFileSizeLow;

	NW_CHECK_EQUAL(0, fileSizeHigh);
	NW_CHECK_EQUAL(16, fileSizeLow);

	FindClose(searchHandle);

	searchHandle = FindFirstFileA("testDir/testSubDir/testFile5*", &state);

	NW_CHECK(searchHandle != INVALID_HANDLE_VALUE);

	fileSizeHigh = state.nFileSizeHigh;
	fileSizeLow  = state.nFileSizeLow;

	NW_CHECK_EQUAL(0, fileSizeHigh);
	NW_CHECK_EQUAL(512, fileSizeLow);

	FindClose(searchHandle);
}

NW_END_TEST_GROUP()<|endoftext|>


<commit_before>/** @file

  A brief file description

  @section license License

  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you under the Apache License, Version 2.0 (the
  "License"); you may not use this file except in compliance
  with the License.  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
 */

#include "ink_assert.h"
#include "ink_atomic.h"
#include "ink_resource.h"

volatile int res_track_memory = 0; // Disabled by default

std::map<const char*, Resource*> ResourceTracker::_resourceMap;
ink_mutex ResourceTracker::resourceLock = PTHREAD_MUTEX_INITIALIZER;

/**
 * Individual resource to keep track of.  A map of these are in the ResourceTracker.
 */
class Resource
{
public:
  Resource(): _incrementCount(0), _decrementCount(0), _value(0) {}
  void increment(const int64_t size);
  int64_t getValue() const { return _value; }
private:
  int64_t _incrementCount;
  int64_t _decrementCount;
  int64_t _value;
};

void Resource::increment(const int64_t size) {
  ink_atomic_increment(&_value, size);
  if (size >= 0) {
    ink_atomic_increment(&_incrementCount, 1);
  } else {
    ink_atomic_increment(&_decrementCount, 1);
  }
}

void
ResourceTracker::increment(const char *name, const int64_t size) {
  Resource &resource = lookup(name);
  resource.increment(size);
}

Resource&
ResourceTracker::lookup(const char *name)
{
  Resource *resource = NULL;
  ink_mutex_acquire(&resourceLock);
  std::map<const char*, Resource*>::iterator it = _resourceMap.find(name);
  if (it != _resourceMap.end()) {
    resource = it->second;
  } else {
    // create a new entry
    resource = new Resource;
    _resourceMap[name] = resource;
  }
  ink_mutex_release(&resourceLock);
  ink_release_assert(resource != NULL);
  return *resource;
}

void
ResourceTracker::dump(FILE *fd) {
  if (!res_track_memory) {
    return;
  }
  int64_t total = 0;

  ink_mutex_acquire(&resourceLock);
  if (!_resourceMap.empty()) {
    fprintf(fd, "%50s | %20s\n", "Location", "Size In-use");
    fprintf(fd, "---------------------------------------------------+------------------------\n");
    for (std::map<const char*, Resource*>::const_iterator it = _resourceMap.begin();
        it != _resourceMap.end(); ++it) {
      const Resource &resource = *it->second;
      fprintf(fd, "%50s | %20lld\n", it->first, resource.getValue());
      total += resource.getValue();
    }
  }
  ink_mutex_release(&resourceLock);
  fprintf(fd, "%50s | %20lld\n", "TOTAL", total);
}
<commit_msg>TS-3116: Add support for tracking the use of the ioBuffers Changed %lld to %PRId64<commit_after>/** @file

  A brief file description

  @section license License

  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you under the Apache License, Version 2.0 (the
  "License"); you may not use this file except in compliance
  with the License.  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
 */

#include "ink_assert.h"
#include "ink_atomic.h"
#include "ink_resource.h"

volatile int res_track_memory = 0; // Disabled by default

std::map<const char*, Resource*> ResourceTracker::_resourceMap;
ink_mutex ResourceTracker::resourceLock = PTHREAD_MUTEX_INITIALIZER;

/**
 * Individual resource to keep track of.  A map of these are in the ResourceTracker.
 */
class Resource
{
public:
  Resource(): _incrementCount(0), _decrementCount(0), _value(0) {}
  void increment(const int64_t size);
  int64_t getValue() const { return _value; }
private:
  int64_t _incrementCount;
  int64_t _decrementCount;
  int64_t _value;
};

void Resource::increment(const int64_t size) {
  ink_atomic_increment(&_value, size);
  if (size >= 0) {
    ink_atomic_increment(&_incrementCount, 1);
  } else {
    ink_atomic_increment(&_decrementCount, 1);
  }
}

void
ResourceTracker::increment(const char *name, const int64_t size) {
  Resource &resource = lookup(name);
  resource.increment(size);
}

Resource&
ResourceTracker::lookup(const char *name)
{
  Resource *resource = NULL;
  ink_mutex_acquire(&resourceLock);
  std::map<const char*, Resource*>::iterator it = _resourceMap.find(name);
  if (it != _resourceMap.end()) {
    resource = it->second;
  } else {
    // create a new entry
    resource = new Resource;
    _resourceMap[name] = resource;
  }
  ink_mutex_release(&resourceLock);
  ink_release_assert(resource != NULL);
  return *resource;
}

void
ResourceTracker::dump(FILE *fd) {
  if (!res_track_memory) {
    return;
  }
  int64_t total = 0;

  ink_mutex_acquire(&resourceLock);
  if (!_resourceMap.empty()) {
    fprintf(fd, "%50s | %20s\n", "Location", "Size In-use");
    fprintf(fd, "---------------------------------------------------+------------------------\n");
    for (std::map<const char*, Resource*>::const_iterator it = _resourceMap.begin();
        it != _resourceMap.end(); ++it) {
      const Resource &resource = *it->second;
      fprintf(fd, "%50s | %20" PRId64 "\n", it->first, resource.getValue());
      total += resource.getValue();
    }
  }
  ink_mutex_release(&resourceLock);
  fprintf(fd, "%50s | %20" PRId64 "\n", "TOTAL", total);
}
<|endoftext|>


<commit_before>#include "tests/Base.hh"

#include "persistenceDiagrams/MultiScaleKernel.hh"
#include "persistenceDiagrams/PersistenceDiagram.hh"

#include <limits>
#include <random>

#include <cmath>

template <class T> aleph::PersistenceDiagram<T> createRandomPersistenceDiagram( unsigned n )
{
  std::random_device rd;
  std::default_random_engine rng( rd() );
  std::uniform_real_distribution<T> distribution( T(0), T( std::nextafter( T(1), std::numeric_limits<T>::max() ) ) );

  using PersistenceDiagram = aleph::PersistenceDiagram<T>;
  PersistenceDiagram D;

  for( unsigned i = 0; i < n; i++ )
  {
    auto x = distribution( rng );
    auto y = distribution( rng );

    if( x > y )
      std::swap( x,y );

    D.add( x,y );
  }

  return D;
}

template <class T> void testMultiScaleKernel()
{
  ALEPH_TEST_BEGIN( "Multi-scale kernel" );

  auto D1 = createRandomPersistenceDiagram<T>( 50 );
  auto D2 = createRandomPersistenceDiagram<T>( 50 );

  auto d1 = aleph::multiScalePseudoMetric( D1, D2, 1.0 );
  auto d2 = aleph::multiScalePseudoMetric( D1, D2, 2.0 );

  ALEPH_ASSERT_THROW( d1 > 0.0 );
  ALEPH_ASSERT_THROW( d2 > 0.0 );

  ALEPH_TEST_END();
}

int main(int, char**)
{
  testMultiScaleKernel<float> ();
  testMultiScaleKernel<double>();
}
<commit_msg>Added multi-scale kernel stability test<commit_after>#include "tests/Base.hh"

#include "distances/Wasserstein.hh"

#include "persistenceDiagrams/MultiScaleKernel.hh"
#include "persistenceDiagrams/PersistenceDiagram.hh"

#include <limits>
#include <random>

#include <cmath>

template <class T> aleph::PersistenceDiagram<T> createRandomPersistenceDiagram( unsigned n )
{
  std::random_device rd;
  std::default_random_engine rng( rd() );
  std::uniform_real_distribution<T> distribution( T(0), T( std::nextafter( T(1), std::numeric_limits<T>::max() ) ) );

  using PersistenceDiagram = aleph::PersistenceDiagram<T>;
  PersistenceDiagram D;

  for( unsigned i = 0; i < n; i++ )
  {
    auto x = distribution( rng );
    auto y = distribution( rng );

    if( x > y )
      std::swap( x,y );

    D.add( x,y );
  }

  return D;
}

template <class T> void testMultiScaleKernel()
{
  ALEPH_TEST_BEGIN( "Multi-scale kernel" );

  auto D1 = createRandomPersistenceDiagram<T>( 50 );
  auto D2 = createRandomPersistenceDiagram<T>( 50 );

  auto d1 = aleph::multiScalePseudoMetric( D1, D2, 1.0 );
  auto d2 = aleph::multiScalePseudoMetric( D1, D2, 2.0 );
  auto d3 = aleph::distances::wassersteinDistance( D1, D2, T(1) );

  // Non-negativity
  ALEPH_ASSERT_THROW( d1 > 0.0 );
  ALEPH_ASSERT_THROW( d2 > 0.0 );
  ALEPH_ASSERT_THROW( d3 > 0.0 );

  // Symmetry
  ALEPH_ASSERT_EQUAL( aleph::multiScalePseudoMetric(D1, D1, 1.0), aleph::multiScalePseudoMetric(D2, D2, 1.0) );
  ALEPH_ASSERT_EQUAL( aleph::multiScalePseudoMetric(D1, D1, 1.0), 0.0 );

  // Stability
  ALEPH_ASSERT_THROW( d1 < 1.0 / ( 1.0 / ( 1.0 * std::sqrt( 8.0 * M_PI ) ) * d3 ) );
  ALEPH_ASSERT_THROW( d2 < 1.0 / ( 1.0 / ( 2.0 * std::sqrt( 8.0 * M_PI ) ) * d3 ) );

  ALEPH_TEST_END();
}

int main(int, char**)
{
  testMultiScaleKernel<float> ();
  testMultiScaleKernel<double>();
}
<|endoftext|>


<commit_before>/* -------------------------------------------------------------------------- */
/* Copyright 2002-2013, OpenNebula Project (OpenNebula.org), C12G Labs        */
/*                                                                            */
/* Licensed under the Apache License, Version 2.0 (the "License"); you may    */
/* not use this file except in compliance with the License. You may obtain    */
/* a copy of the License at                                                   */
/*                                                                            */
/* http://www.apache.org/licenses/LICENSE-2.0                                 */
/*                                                                            */
/* Unless required by applicable law or agreed to in writing, software        */
/* distributed under the License is distributed on an "AS IS" BASIS,          */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   */
/* See the License for the specific language governing permissions and        */
/* limitations under the License.                                             */
/* -------------------------------------------------------------------------- */

/* ************************************************************************** */
/* Host Pool                                                                  */
/* ************************************************************************** */

#include <stdexcept>
#include <sstream>

#include "HostPool.h"
#include "HostHook.h"
#include "NebulaLog.h"
#include "GroupPool.h"

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

time_t HostPool::_monitor_expiration;

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

HostPool::HostPool(SqlDB*                    db,
                   vector<const Attribute *> hook_mads,
                   const string&             hook_location,
                   const string&             remotes_location,
                   time_t                    expire_time)
                        : PoolSQL(db, Host::table, true)
{

    _monitor_expiration = expire_time;

    if ( _monitor_expiration == 0 )
    {
        clean_all_monitoring();
    }

    // ------------------ Initialize Hooks for the pool ----------------------

    const VectorAttribute * vattr;

    string name;
    string on;
    string cmd;
    string arg;
    bool   remote;

    bool state_hook = false;

    for (unsigned int i = 0 ; i < hook_mads.size() ; i++ )
    {
        vattr = static_cast<const VectorAttribute *>(hook_mads[i]);

        name = vattr->vector_value("NAME");
        on   = vattr->vector_value("ON");
        cmd  = vattr->vector_value("COMMAND");
        arg  = vattr->vector_value("ARGUMENTS");
        vattr->vector_value("REMOTE", remote);

        transform (on.begin(),on.end(),on.begin(),(int(*)(int))toupper);

        if ( on.empty() || cmd.empty() )
        {
            ostringstream oss;

            oss << "Empty ON or COMMAND attribute in HOST_HOOK. Hook "
                << "not registered!";
            NebulaLog::log("VM",Log::WARNING,oss);

            continue;
        }

        if ( name.empty() )
        {
            name = cmd;
        }

        if (cmd[0] != '/')
        {
            ostringstream cmd_os;

            if ( remote )
            {
                cmd_os << hook_location << "/" << cmd;
            }
            else
            {
                cmd_os << remotes_location << "/hooks/" << cmd;
            }

            cmd = cmd_os.str();
        }

        if ( on == "CREATE" )
        {
            HostAllocateHook * hook;

            hook = new HostAllocateHook(name,cmd,arg,remote);

            add_hook(hook);
        }
        else if ( on == "DISABLE" )
        {
            HostStateHook * hook;

            hook = new HostStateHook(name, cmd, arg, remote, Host::DISABLED);

            add_hook(hook);

            state_hook = true;
        }
        else if ( on == "ERROR" )
        {
            HostStateHook * hook;

            hook = new HostStateHook(name, cmd, arg, remote, Host::ERROR);

            add_hook(hook);

            state_hook = true;
        }
    }

    if ( state_hook )
    {
        HostUpdateStateHook * hook;

        hook = new HostUpdateStateHook();

        add_hook(hook);
    }
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int HostPool::allocate (
    int * oid,
    const string& hostname,
    const string& im_mad_name,
    const string& vmm_mad_name,
    const string& vnm_mad_name,
    int           cluster_id,
    const string& cluster_name,
    string& error_str)
{
    Host *        host;
    ostringstream oss;

    if ( hostname.empty() )
    {
        goto error_name;
    }

    if ( hostname.length() > 128 )
    {
        goto error_name_length;
    }

    if ( im_mad_name.empty() )
    {
        goto error_im;
    }

    if ( vmm_mad_name.empty() )
    {
        goto error_vmm;
    }

    if ( vnm_mad_name.empty() )
    {
        goto error_vnm;
    }

    host = get(hostname,false);

    if ( host !=0)
    {
        goto error_duplicated;
    }

    // Build a new Host object

    host = new Host(
            -1,
            hostname,
            im_mad_name,
            vmm_mad_name,
            vnm_mad_name,
            cluster_id,
            cluster_name);

    // Insert the Object in the pool

    *oid = PoolSQL::allocate(host, error_str);

    return *oid;

error_name:
    oss << "NAME cannot be empty.";
    goto error_common;

error_name_length:
    oss << "NAME is too long; max length is 128 chars.";
    goto error_common;

error_im:
    oss << "IM_MAD_NAME cannot be empty.";
    goto error_common;

error_vmm:
    oss << "VMM_MAD_NAME cannot be empty.";
    goto error_common;

error_vnm:
    oss << "VNM_MAD_NAME cannot be empty.";
    goto error_common;

error_duplicated:
    oss << "NAME is already taken by HOST " << host->get_oid() << ".";

error_common:
    *oid = -1;
    error_str = oss.str();

    return *oid;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int HostPool::discover_cb(void * _set, int num, char **values, char **names)
{
    set<int> *  discovered_hosts;
    string      im_mad;
    int         hid;
    int         rc;

    discovered_hosts = static_cast<set<int> *>(_set);

    if ( (num<1) || (values[0] == 0) )
    {
        return -1;
    }

    hid = atoi(values[0]);

    discovered_hosts->insert(hid);

    return 0;
}

/* -------------------------------------------------------------------------- */

int HostPool::discover(set<int> * discovered_hosts, int host_limit)
{
    ostringstream   sql;
    int             rc;

    set_callback(static_cast<Callbackable::Callback>(&HostPool::discover_cb),
                 static_cast<void *>(discovered_hosts));

    sql << "SELECT oid FROM "
        << Host::table << " ORDER BY last_mon_time ASC LIMIT " << host_limit;

    rc = db->exec(sql,this);

    unset_callback();

    return rc;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int HostPool::dump_monitoring(
        ostringstream& oss,
        const string&  where)
{
    ostringstream cmd;

    cmd << "SELECT " << Host::monit_table << ".body FROM " << Host::monit_table
        << " INNER JOIN " << Host::table
        << " WHERE hid = oid";

    if ( !where.empty() )
    {
        cmd << " AND " << where;
    }

    cmd << " ORDER BY hid, " << Host::monit_table << ".last_mon_time;";

    return PoolSQL::dump(oss, "MONITORING_DATA", cmd);
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int HostPool::clean_expired_monitoring()
{
    if ( _monitor_expiration == 0 )
    {
        return 0;
    }

    int             rc;
    time_t          max_mon_time;
    ostringstream   oss;

    max_mon_time = time(0) - _monitor_expiration;

    oss << "DELETE FROM " << Host::monit_table
        << " WHERE last_mon_time < " << max_mon_time;

    rc = db->exec(oss);

    return rc;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int HostPool::clean_all_monitoring()
{
    ostringstream   oss;
    int             rc;

    oss << "DELETE FROM " << Host::monit_table;

    rc = db->exec(oss);

    return rc;
}
<commit_msg>Feature #1739: Remove unused var<commit_after>/* -------------------------------------------------------------------------- */
/* Copyright 2002-2013, OpenNebula Project (OpenNebula.org), C12G Labs        */
/*                                                                            */
/* Licensed under the Apache License, Version 2.0 (the "License"); you may    */
/* not use this file except in compliance with the License. You may obtain    */
/* a copy of the License at                                                   */
/*                                                                            */
/* http://www.apache.org/licenses/LICENSE-2.0                                 */
/*                                                                            */
/* Unless required by applicable law or agreed to in writing, software        */
/* distributed under the License is distributed on an "AS IS" BASIS,          */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   */
/* See the License for the specific language governing permissions and        */
/* limitations under the License.                                             */
/* -------------------------------------------------------------------------- */

/* ************************************************************************** */
/* Host Pool                                                                  */
/* ************************************************************************** */

#include <stdexcept>
#include <sstream>

#include "HostPool.h"
#include "HostHook.h"
#include "NebulaLog.h"
#include "GroupPool.h"

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

time_t HostPool::_monitor_expiration;

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

HostPool::HostPool(SqlDB*                    db,
                   vector<const Attribute *> hook_mads,
                   const string&             hook_location,
                   const string&             remotes_location,
                   time_t                    expire_time)
                        : PoolSQL(db, Host::table, true)
{

    _monitor_expiration = expire_time;

    if ( _monitor_expiration == 0 )
    {
        clean_all_monitoring();
    }

    // ------------------ Initialize Hooks for the pool ----------------------

    const VectorAttribute * vattr;

    string name;
    string on;
    string cmd;
    string arg;
    bool   remote;

    bool state_hook = false;

    for (unsigned int i = 0 ; i < hook_mads.size() ; i++ )
    {
        vattr = static_cast<const VectorAttribute *>(hook_mads[i]);

        name = vattr->vector_value("NAME");
        on   = vattr->vector_value("ON");
        cmd  = vattr->vector_value("COMMAND");
        arg  = vattr->vector_value("ARGUMENTS");
        vattr->vector_value("REMOTE", remote);

        transform (on.begin(),on.end(),on.begin(),(int(*)(int))toupper);

        if ( on.empty() || cmd.empty() )
        {
            ostringstream oss;

            oss << "Empty ON or COMMAND attribute in HOST_HOOK. Hook "
                << "not registered!";
            NebulaLog::log("VM",Log::WARNING,oss);

            continue;
        }

        if ( name.empty() )
        {
            name = cmd;
        }

        if (cmd[0] != '/')
        {
            ostringstream cmd_os;

            if ( remote )
            {
                cmd_os << hook_location << "/" << cmd;
            }
            else
            {
                cmd_os << remotes_location << "/hooks/" << cmd;
            }

            cmd = cmd_os.str();
        }

        if ( on == "CREATE" )
        {
            HostAllocateHook * hook;

            hook = new HostAllocateHook(name,cmd,arg,remote);

            add_hook(hook);
        }
        else if ( on == "DISABLE" )
        {
            HostStateHook * hook;

            hook = new HostStateHook(name, cmd, arg, remote, Host::DISABLED);

            add_hook(hook);

            state_hook = true;
        }
        else if ( on == "ERROR" )
        {
            HostStateHook * hook;

            hook = new HostStateHook(name, cmd, arg, remote, Host::ERROR);

            add_hook(hook);

            state_hook = true;
        }
    }

    if ( state_hook )
    {
        HostUpdateStateHook * hook;

        hook = new HostUpdateStateHook();

        add_hook(hook);
    }
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int HostPool::allocate (
    int * oid,
    const string& hostname,
    const string& im_mad_name,
    const string& vmm_mad_name,
    const string& vnm_mad_name,
    int           cluster_id,
    const string& cluster_name,
    string& error_str)
{
    Host *        host;
    ostringstream oss;

    if ( hostname.empty() )
    {
        goto error_name;
    }

    if ( hostname.length() > 128 )
    {
        goto error_name_length;
    }

    if ( im_mad_name.empty() )
    {
        goto error_im;
    }

    if ( vmm_mad_name.empty() )
    {
        goto error_vmm;
    }

    if ( vnm_mad_name.empty() )
    {
        goto error_vnm;
    }

    host = get(hostname,false);

    if ( host !=0)
    {
        goto error_duplicated;
    }

    // Build a new Host object

    host = new Host(
            -1,
            hostname,
            im_mad_name,
            vmm_mad_name,
            vnm_mad_name,
            cluster_id,
            cluster_name);

    // Insert the Object in the pool

    *oid = PoolSQL::allocate(host, error_str);

    return *oid;

error_name:
    oss << "NAME cannot be empty.";
    goto error_common;

error_name_length:
    oss << "NAME is too long; max length is 128 chars.";
    goto error_common;

error_im:
    oss << "IM_MAD_NAME cannot be empty.";
    goto error_common;

error_vmm:
    oss << "VMM_MAD_NAME cannot be empty.";
    goto error_common;

error_vnm:
    oss << "VNM_MAD_NAME cannot be empty.";
    goto error_common;

error_duplicated:
    oss << "NAME is already taken by HOST " << host->get_oid() << ".";

error_common:
    *oid = -1;
    error_str = oss.str();

    return *oid;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int HostPool::discover_cb(void * _set, int num, char **values, char **names)
{
    set<int> *  discovered_hosts;
    string      im_mad;
    int         hid;

    discovered_hosts = static_cast<set<int> *>(_set);

    if ( (num<1) || (values[0] == 0) )
    {
        return -1;
    }

    hid = atoi(values[0]);

    discovered_hosts->insert(hid);

    return 0;
}

/* -------------------------------------------------------------------------- */

int HostPool::discover(set<int> * discovered_hosts, int host_limit)
{
    ostringstream   sql;
    int             rc;

    set_callback(static_cast<Callbackable::Callback>(&HostPool::discover_cb),
                 static_cast<void *>(discovered_hosts));

    sql << "SELECT oid FROM "
        << Host::table << " ORDER BY last_mon_time ASC LIMIT " << host_limit;

    rc = db->exec(sql,this);

    unset_callback();

    return rc;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int HostPool::dump_monitoring(
        ostringstream& oss,
        const string&  where)
{
    ostringstream cmd;

    cmd << "SELECT " << Host::monit_table << ".body FROM " << Host::monit_table
        << " INNER JOIN " << Host::table
        << " WHERE hid = oid";

    if ( !where.empty() )
    {
        cmd << " AND " << where;
    }

    cmd << " ORDER BY hid, " << Host::monit_table << ".last_mon_time;";

    return PoolSQL::dump(oss, "MONITORING_DATA", cmd);
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int HostPool::clean_expired_monitoring()
{
    if ( _monitor_expiration == 0 )
    {
        return 0;
    }

    int             rc;
    time_t          max_mon_time;
    ostringstream   oss;

    max_mon_time = time(0) - _monitor_expiration;

    oss << "DELETE FROM " << Host::monit_table
        << " WHERE last_mon_time < " << max_mon_time;

    rc = db->exec(oss);

    return rc;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int HostPool::clean_all_monitoring()
{
    ostringstream   oss;
    int             rc;

    oss << "DELETE FROM " << Host::monit_table;

    rc = db->exec(oss);

    return rc;
}
<|endoftext|>