<commit_before>// This file is part of OpenMVG, an Open Multiple View Geometry C++ library.

// Copyright (c) 2015 Pierre MOULON.

// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#include "openMVG/multiview/translation_averaging_common.hpp"
#include "openMVG/multiview/translation_averaging_solver.hpp"
#include "openMVG/numeric/eigen_alias_definition.hpp"
#include "openMVG/types.hpp"

#ifdef OPENMVG_USE_OPENMP
#include <omp.h>
#endif

#include <ceres/ceres.h>
#include <ceres/rotation.h>

#include <vector>

namespace openMVG {

// Main Cost functor for translation averaging:
// measure the consistency (residual error) from the relative translations (constant) to the scales and global camera translations
struct RelativeTranslationError
{
  RelativeTranslationError
  (
    double t_ij_x,
    double t_ij_y,
    double t_ij_z
  )
  : t_ij_x_(t_ij_x), t_ij_y_(t_ij_y), t_ij_z_(t_ij_z)
  {}

  template <typename T>
  bool operator()
  (
    const T* const t_i,
    const T* const t_j,
    const T* const R_ij,
    const T* const s_ij,
    T* residuals
  ) const
  {
    //
    // residual = t_j - R_ij t_i - s_ij * t_ij
    //
    T rotated_t_i[3];
    // Rotate the point according the relative local rotation
    ceres::AngleAxisRotatePoint(R_ij, t_i, rotated_t_i);

    residuals[0] = T(t_j[0] - rotated_t_i[0] - *s_ij * t_ij_x_);
    residuals[1] = T(t_j[1] - rotated_t_i[1] - *s_ij * t_ij_y_);
    residuals[2] = T(t_j[2] - rotated_t_i[2] - *s_ij * t_ij_z_);

    return true;
  }

  double t_ij_x_, t_ij_y_, t_ij_z_;
};

// Cost penalizing scales smaller than 1.
struct SmallScaleError
{
  explicit SmallScaleError
  (
    double weight = 1.0
  )
  : weight_(weight)
  {}

  template <typename T>
  bool operator()
  (
    const T* const s_ij, T* residual
  ) const
  {
    residual[0] = (*s_ij > T(1.0)) ? T(0.0) : (T(weight_) * (T(1.0) - *s_ij));
    return true;
  }

  double weight_;
};

bool solve_translations_problem_softl1
(
  const std::vector<openMVG::RelativeInfo_Vec > & vec_relative_group_estimates,
  std::vector<Eigen::Vector3d> & translations,
  const double d_l1_loss_threshold
)
{
  //-- Count:
  //- #poses are used by the relative position estimates
  //- #relative estimates we will use

  std::set<unsigned int> count_set;
  unsigned int relative_info_count = 0;
  for (const openMVG::RelativeInfo_Vec & iter : vec_relative_group_estimates)
  {
    for (const relativeInfo & it_relative_motion : iter)
    {
      ++relative_info_count;
      count_set.insert(it_relative_motion.first.first);
      count_set.insert(it_relative_motion.first.second);
    }
  }
  const IndexT nb_poses = count_set.size();

  //--
  // Build the parameters arrays:
  //--
  // - camera translations
  // - relative translation scales (one per group)
  // - relative rotations

  std::vector<double> vec_translations(relative_info_count*3, 1.0);
  const unsigned nb_scales = vec_relative_group_estimates.size();
  std::vector<double> vec_scales(nb_scales, 1.0);

  // Setup the relative rotations array (angle axis parametrization)
  std::vector<double> vec_relative_rotations(relative_info_count*3, 0.0);
  unsigned int cpt = 0;
  for (const openMVG::RelativeInfo_Vec & iter : vec_relative_group_estimates)
  {
    for (const relativeInfo & info : iter)
    {
      ceres::RotationMatrixToAngleAxis(
        (const double*)info.second.first.data(),
        &vec_relative_rotations[cpt]);
      cpt += 3;
    }
  }

  ceres::LossFunction * loss =
    (d_l1_loss_threshold < 0) ? nullptr : new ceres::SoftLOneLoss(d_l1_loss_threshold);

  // Add constraints to the minimization problem
  ceres::Problem problem;
  //
  // A. Add cost functors:
  cpt = 0;
  IndexT scale_idx = 0;
  for (const openMVG::RelativeInfo_Vec & iter : vec_relative_group_estimates)
  {
    for (const relativeInfo & info : iter)
    {
      const Pair & ids = info.first;
      const IndexT I = ids.first;
      const IndexT J = ids.second;
      const Vec3 t_ij = info.second.second;

      // Each Residual block takes 2 camera translations & the relative rotation & a scale
      // and outputs a 3 dimensional residual.
      ceres::CostFunction* cost_function =
          new ceres::AutoDiffCostFunction<RelativeTranslationError, 3, 3, 3, 3,1>(
              new RelativeTranslationError(t_ij(0), t_ij(1), t_ij(2)));
      problem.AddResidualBlock(
        cost_function,
        loss,
        &vec_translations[I*3],
        &vec_translations[J*3],
        &vec_relative_rotations[cpt],
        &vec_scales[scale_idx]);
      // the relative rotation is set as constant
      problem.SetParameterBlockConstant(&vec_relative_rotations[cpt]);
      cpt+=3;
    }
    ++scale_idx; // One scale per relative_motion group
  }

  // B. Add constraint over the scale factors:
  //  Prefer scale > 1, since a trivial solution is translations = {0,...,0}).
  for (unsigned i = 0; i < nb_scales; ++i)
  {
    ceres::CostFunction* cost_function =
        new ceres::AutoDiffCostFunction<SmallScaleError, 1, 1>(
            new SmallScaleError(1.0));

    problem.AddResidualBlock(cost_function, nullptr, &vec_scales[i]);
  }
  // Set one center as known (to fix the gauge freedom)
  vec_translations[0] = vec_translations[1] = vec_translations[2] = 0.0;
  problem.SetParameterBlockConstant(&vec_translations[0]);

  // Solve
  ceres::Solver::Options options;
  options.minimizer_progress_to_stdout = false;
  if (ceres::IsSparseLinearAlgebraLibraryTypeAvailable(ceres::SUITE_SPARSE))
  {
    options.sparse_linear_algebra_library_type = ceres::SUITE_SPARSE;
    options.linear_solver_type = ceres::SPARSE_NORMAL_CHOLESKY;
  }
  else if (ceres::IsSparseLinearAlgebraLibraryTypeAvailable(ceres::CX_SPARSE))
  {
    options.sparse_linear_algebra_library_type = ceres::CX_SPARSE;
    options.linear_solver_type = ceres::SPARSE_NORMAL_CHOLESKY;
  }
  else if (ceres::IsSparseLinearAlgebraLibraryTypeAvailable(ceres::EIGEN_SPARSE))
  {
    options.sparse_linear_algebra_library_type = ceres::EIGEN_SPARSE;
    options.linear_solver_type = ceres::SPARSE_NORMAL_CHOLESKY;
  }
  else
  {
    options.linear_solver_type = ceres::DENSE_NORMAL_CHOLESKY;
  }
  options.max_num_iterations = std::max(50, (int)(nb_scales * 2));
  options.minimizer_progress_to_stdout = false;
  options.logging_type = ceres::SILENT;
#ifdef OPENMVG_USE_OPENMP
  options.num_threads = omp_get_max_threads();
#if CERES_VERSION_MAJOR < 2
  options.num_linear_solver_threads = omp_get_max_threads();
#endif
#endif // OPENMVG_USE_OPENMP
  ceres::Solver::Summary summary;
  ceres::Solve(options, &problem, &summary);

  if (!summary.IsSolutionUsable())
  {
    std::cout << summary.FullReport() << std::endl;
    return false;
  }

  // Fill the global translations array
  translations.resize(nb_poses);
  cpt = 0;
  for (unsigned int i = 0; i < nb_poses; ++i, cpt+=3)
  {
    translations[i] << vec_translations[cpt], vec_translations[cpt+1], vec_translations[cpt+2];
  }
  return true;
}

} // namespace openMVG
<commit_msg>[multiview] Fix size of the translation vector  (#1926)<commit_after>// This file is part of OpenMVG, an Open Multiple View Geometry C++ library.

// Copyright (c) 2015 Pierre MOULON.

// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#include "openMVG/multiview/translation_averaging_common.hpp"
#include "openMVG/multiview/translation_averaging_solver.hpp"
#include "openMVG/numeric/eigen_alias_definition.hpp"
#include "openMVG/types.hpp"

#ifdef OPENMVG_USE_OPENMP
#include <omp.h>
#endif

#include <ceres/ceres.h>
#include <ceres/rotation.h>

#include <vector>

namespace openMVG {

// Main Cost functor for translation averaging:
// measure the consistency (residual error) from the relative translations (constant) to the scales and global camera translations
struct RelativeTranslationError
{
  RelativeTranslationError
  (
    double t_ij_x,
    double t_ij_y,
    double t_ij_z
  )
  : t_ij_x_(t_ij_x), t_ij_y_(t_ij_y), t_ij_z_(t_ij_z)
  {}

  template <typename T>
  bool operator()
  (
    const T* const t_i,
    const T* const t_j,
    const T* const R_ij,
    const T* const s_ij,
    T* residuals
  ) const
  {
    //
    // residual = t_j - R_ij t_i - s_ij * t_ij
    //
    T rotated_t_i[3];
    // Rotate the point according the relative local rotation
    ceres::AngleAxisRotatePoint(R_ij, t_i, rotated_t_i);

    residuals[0] = T(t_j[0] - rotated_t_i[0] - *s_ij * t_ij_x_);
    residuals[1] = T(t_j[1] - rotated_t_i[1] - *s_ij * t_ij_y_);
    residuals[2] = T(t_j[2] - rotated_t_i[2] - *s_ij * t_ij_z_);

    return true;
  }

  double t_ij_x_, t_ij_y_, t_ij_z_;
};

// Cost penalizing scales smaller than 1.
struct SmallScaleError
{
  explicit SmallScaleError
  (
    double weight = 1.0
  )
  : weight_(weight)
  {}

  template <typename T>
  bool operator()
  (
    const T* const s_ij, T* residual
  ) const
  {
    residual[0] = (*s_ij > T(1.0)) ? T(0.0) : (T(weight_) * (T(1.0) - *s_ij));
    return true;
  }

  double weight_;
};

bool solve_translations_problem_softl1
(
  const std::vector<openMVG::RelativeInfo_Vec > & vec_relative_group_estimates,
  std::vector<Eigen::Vector3d> & translations,
  const double d_l1_loss_threshold
)
{
  //-- Count:
  //- #poses are used by the relative position estimates
  //- #relative estimates we will use

  std::set<unsigned int> count_set;
  unsigned int relative_info_count = 0;
  for (const openMVG::RelativeInfo_Vec & iter : vec_relative_group_estimates)
  {
    for (const relativeInfo & it_relative_motion : iter)
    {
      ++relative_info_count;
      count_set.insert(it_relative_motion.first.first);
      count_set.insert(it_relative_motion.first.second);
    }
  }
  const IndexT nb_poses = count_set.size();

  //--
  // Build the parameters arrays:
  //--
  // - camera translations
  // - relative translation scales (one per group)
  // - relative rotations

  std::vector<double> vec_translations(nb_poses*3, 1.0);
  const unsigned nb_scales = vec_relative_group_estimates.size();
  std::vector<double> vec_scales(nb_scales, 1.0);

  // Setup the relative rotations array (angle axis parametrization)
  std::vector<double> vec_relative_rotations(relative_info_count*3, 0.0);
  unsigned int cpt = 0;
  for (const openMVG::RelativeInfo_Vec & iter : vec_relative_group_estimates)
  {
    for (const relativeInfo & info : iter)
    {
      ceres::RotationMatrixToAngleAxis(
        (const double*)info.second.first.data(),
        &vec_relative_rotations[cpt]);
      cpt += 3;
    }
  }

  ceres::LossFunction * loss =
    (d_l1_loss_threshold < 0) ? nullptr : new ceres::SoftLOneLoss(d_l1_loss_threshold);

  // Add constraints to the minimization problem
  ceres::Problem problem;
  //
  // A. Add cost functors:
  cpt = 0;
  IndexT scale_idx = 0;
  for (const openMVG::RelativeInfo_Vec & iter : vec_relative_group_estimates)
  {
    for (const relativeInfo & info : iter)
    {
      const Pair & ids = info.first;
      const IndexT I = ids.first;
      const IndexT J = ids.second;
      const Vec3 t_ij = info.second.second;

      // Each Residual block takes 2 camera translations & the relative rotation & a scale
      // and outputs a 3 dimensional residual.
      ceres::CostFunction* cost_function =
          new ceres::AutoDiffCostFunction<RelativeTranslationError, 3, 3, 3, 3,1>(
              new RelativeTranslationError(t_ij(0), t_ij(1), t_ij(2)));
      problem.AddResidualBlock(
        cost_function,
        loss,
        &vec_translations[I*3],
        &vec_translations[J*3],
        &vec_relative_rotations[cpt],
        &vec_scales[scale_idx]);
      // the relative rotation is set as constant
      problem.SetParameterBlockConstant(&vec_relative_rotations[cpt]);
      cpt+=3;
    }
    ++scale_idx; // One scale per relative_motion group
  }

  // B. Add constraint over the scale factors:
  //  Prefer scale > 1, since a trivial solution is translations = {0,...,0}).
  for (unsigned i = 0; i < nb_scales; ++i)
  {
    ceres::CostFunction* cost_function =
        new ceres::AutoDiffCostFunction<SmallScaleError, 1, 1>(
            new SmallScaleError(1.0));

    problem.AddResidualBlock(cost_function, nullptr, &vec_scales[i]);
  }
  // Set one center as known (to fix the gauge freedom)
  vec_translations[0] = vec_translations[1] = vec_translations[2] = 0.0;
  problem.SetParameterBlockConstant(&vec_translations[0]);

  // Solve
  ceres::Solver::Options options;
  options.minimizer_progress_to_stdout = false;
  if (ceres::IsSparseLinearAlgebraLibraryTypeAvailable(ceres::SUITE_SPARSE))
  {
    options.sparse_linear_algebra_library_type = ceres::SUITE_SPARSE;
    options.linear_solver_type = ceres::SPARSE_NORMAL_CHOLESKY;
  }
  else if (ceres::IsSparseLinearAlgebraLibraryTypeAvailable(ceres::CX_SPARSE))
  {
    options.sparse_linear_algebra_library_type = ceres::CX_SPARSE;
    options.linear_solver_type = ceres::SPARSE_NORMAL_CHOLESKY;
  }
  else if (ceres::IsSparseLinearAlgebraLibraryTypeAvailable(ceres::EIGEN_SPARSE))
  {
    options.sparse_linear_algebra_library_type = ceres::EIGEN_SPARSE;
    options.linear_solver_type = ceres::SPARSE_NORMAL_CHOLESKY;
  }
  else
  {
    options.linear_solver_type = ceres::DENSE_NORMAL_CHOLESKY;
  }
  options.max_num_iterations = std::max(50, (int)(nb_scales * 2));
  options.minimizer_progress_to_stdout = false;
  options.logging_type = ceres::SILENT;
#ifdef OPENMVG_USE_OPENMP
  options.num_threads = omp_get_max_threads();
#if CERES_VERSION_MAJOR < 2
  options.num_linear_solver_threads = omp_get_max_threads();
#endif
#endif // OPENMVG_USE_OPENMP
  ceres::Solver::Summary summary;
  ceres::Solve(options, &problem, &summary);

  if (!summary.IsSolutionUsable())
  {
    std::cout << summary.FullReport() << std::endl;
    return false;
  }

  // Fill the global translations array
  translations.resize(nb_poses);
  cpt = 0;
  for (unsigned int i = 0; i < nb_poses; ++i, cpt+=3)
  {
    translations[i] = Eigen::Map<Eigen::Vector3d>(&vec_translations[cpt]);
  }
  return true;
}

} // namespace openMVG
<|endoftext|>


<commit_before>#include "BatteryPopulator.h"

BatteryPopulator::BatteryPopulator(I_PacketDecoder& packetDecoder,
                           I_BatteryData& batteryData)
: packetDecoder_(packetDecoder_)
, batteryData_(batteryData)
{
   connect(&packetDecoder_, SIGNAL(packetDecoded(const BatteryDataMessage)),
         this, SLOT(populateData(const FaultsMessage)));
}

void BatteryPopulator::populateData(const BatteryDataMessage message)
{
   batteryData_.setBatteryVoltage(message.batteryVoltage());
   batteryData_.setBatteryCurrent(message.batteryCurrent());
   // batteryData_.set***SOMETHINGHERE***(message.stateOfCharge());
   // batteryData_.set***SOMETHINGHERE***(message.balanceStateOfCharge());
   // batteryData_.set***SOMETHINGHERE***(message.secondaryBatteryUnderVoltage());
}
<commit_msg>fixed segfault error in batterypopulator<commit_after>#include "BatteryPopulator.h"

BatteryPopulator::BatteryPopulator(I_PacketDecoder& packetDecoder,
                           I_BatteryData& batteryData)
: packetDecoder_(packetDecoder)
, batteryData_(batteryData)
{
   connect(&packetDecoder_, SIGNAL(packetDecoded(const BatteryDataMessage)),
         this, SLOT(populateData(const BatteryDataMessage)));
}

void BatteryPopulator::populateData(const BatteryDataMessage message)
{
   batteryData_.setBatteryVoltage(message.batteryVoltage());
   batteryData_.setBatteryCurrent(message.batteryCurrent());
   // batteryData_.set***SOMETHINGHERE***(message.stateOfCharge());
   // batteryData_.set***SOMETHINGHERE***(message.balanceStateOfCharge());
   // batteryData_.set***SOMETHINGHERE***(message.secondaryBatteryUnderVoltage());
}
<|endoftext|>


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

#include "gtest/gtest.h"
#include "code_generation_test/MessageHeader.hpp"
#include "code_generation_test/Car.hpp"

using namespace std;
using namespace code_generation_test;

#define SERIAL_NUMBER 1234u
#define MODEL_YEAR 2013
#define AVAILABLE (BooleanType::T)
#define CODE (Model::A)
#define CRUISE_CONTROL (true)
#define SPORTS_PACK (true)
#define SUNROOF (false)

static char VEHICLE_CODE[] = { 'a', 'b', 'c', 'd', 'e', 'f' };
static char MANUFACTURER_CODE[] = { '1', '2', '3' };
static const char *MAKE = "Honda";
static const char *MODEL = "Civic VTi";
static const char *ACTIVATION_CODE = "deadbeef";

static const int encodedHdrSz = 8;
static const int encodedCarSz = 179;

class BoundsCheckTest : public testing::Test
{
public:

    virtual int encodeHdr(char *buffer, int offset, int bufferLength)
    {
        m_hdr.wrap(buffer, offset, 0, bufferLength)
            .blockLength(Car::sbeBlockLength())
            .templateId(Car::sbeTemplateId())
            .schemaId(Car::sbeSchemaId())
            .version(Car::sbeSchemaVersion());

        return m_hdr.size();
    }

    virtual int decodeHdr(char *buffer, int offset, int bufferLength)
    {
        m_hdrDecoder.wrap(buffer, offset, 0, bufferLength);

        EXPECT_EQ(m_hdrDecoder.blockLength(), Car::sbeBlockLength());
        EXPECT_EQ(m_hdrDecoder.templateId(), Car::sbeTemplateId());
        EXPECT_EQ(m_hdrDecoder.schemaId(), Car::sbeSchemaId());
        EXPECT_EQ(m_hdrDecoder.version(), Car::sbeSchemaVersion());

        return m_hdrDecoder.size();
    }

    virtual int encodeCarRoot(char *buffer, int offset, int bufferLength)
    {
        m_car.wrapForEncode(buffer, offset, bufferLength)
            .serialNumber(SERIAL_NUMBER)
            .modelYear(MODEL_YEAR)
            .available(AVAILABLE)
            .code(CODE)
            .putVehicleCode(VEHICLE_CODE);

        for (int i = 0; i < Car::someNumbersLength(); i++)
        {
            m_car.someNumbers(i, i);
        }

        m_car.extras().clear()
            .cruiseControl(CRUISE_CONTROL)
            .sportsPack(SPORTS_PACK)
            .sunRoof(SUNROOF);

        m_car.engine()
            .capacity(2000)
            .numCylinders((short)4)
            .putManufacturerCode(MANUFACTURER_CODE);

        return m_car.size();
    }

    virtual int encodeCarFuelFigures()
    {
        Car::FuelFigures& fuelFigures = m_car.fuelFiguresCount(3);

        fuelFigures
            .next().speed(30).mpg(35.9f);
        fuelFigures.putUsageDescription("Urban Cycle", 11);

        fuelFigures
            .next().speed(55).mpg(49.0f);
        fuelFigures.putUsageDescription("Combined Cycle", 14);

        fuelFigures
            .next().speed(75).mpg(40.0f);
        fuelFigures.putUsageDescription("Highway Cycle", 13);

        return m_car.size();
    }

    virtual int encodeCarPerformanceFigures()
    {
        Car::PerformanceFigures &perfFigs = m_car.performanceFiguresCount(2);

        perfFigs.next()
            .octaneRating((short)95)
            .accelerationCount(3)
                .next().mph(30).seconds(4.0f)
                .next().mph(60).seconds(7.5f)
                .next().mph(100).seconds(12.2f);

        perfFigs.next()
            .octaneRating((short)99)
            .accelerationCount(3)
                .next().mph(30).seconds(3.8f)
                .next().mph(60).seconds(7.1f)
                .next().mph(100).seconds(11.8f);

        return m_car.size();
    }

    virtual int encodeCarMakeModelAndActivationCode()
    {
        m_car.putMake(MAKE, static_cast<int>(strlen(MAKE)));
        m_car.putModel(MODEL, static_cast<int>(strlen(MODEL)));
        m_car.putActivationCode(ACTIVATION_CODE, static_cast<int>(strlen(ACTIVATION_CODE)));

        return m_car.size();
    }

    virtual int decodeCarRoot(char *buffer, const int offset, const int bufferLength)
    {
        m_carDecoder.wrapForDecode(buffer, offset, Car::sbeBlockLength(), Car::sbeSchemaVersion(), bufferLength);
        EXPECT_EQ(m_carDecoder.serialNumber(), SERIAL_NUMBER);
        EXPECT_EQ(m_carDecoder.modelYear(), MODEL_YEAR);
        EXPECT_EQ(m_carDecoder.available(), AVAILABLE);
        EXPECT_EQ(m_carDecoder.code(), CODE);

        EXPECT_EQ(m_carDecoder.someNumbersLength(), 5);
        for (int i = 0; i < 5; i++)
        {
            EXPECT_EQ(m_carDecoder.someNumbers(i), i);
        }

        EXPECT_EQ(m_carDecoder.vehicleCodeLength(), 6);
        EXPECT_EQ(std::string(m_carDecoder.vehicleCode(), 6), std::string(VEHICLE_CODE, 6));
        EXPECT_EQ(m_carDecoder.extras().cruiseControl(), true);
        EXPECT_EQ(m_carDecoder.extras().sportsPack(), true);
        EXPECT_EQ(m_carDecoder.extras().sunRoof(), false);

        Engine &engine = m_carDecoder.engine();
        EXPECT_EQ(engine.capacity(), 2000);
        EXPECT_EQ(engine.numCylinders(), 4);
        EXPECT_EQ(engine.maxRpm(), 9000);
        EXPECT_EQ(engine.manufacturerCodeLength(), 3);
        EXPECT_EQ(std::string(engine.manufacturerCode(), 3), std::string(MANUFACTURER_CODE, 3));
        EXPECT_EQ(engine.fuelLength(), 6);
        EXPECT_EQ(std::string(engine.fuel(), 6), std::string("Petrol"));

        return m_carDecoder.size();
    }

    virtual int decodeCarFuelFigures()
    {
        char tmp[256];
        Car::FuelFigures &fuelFigures = m_carDecoder.fuelFigures();
        EXPECT_EQ(fuelFigures.count(), 3);

        EXPECT_TRUE(fuelFigures.hasNext());
        fuelFigures.next();
        EXPECT_EQ(fuelFigures.speed(), 30);
        EXPECT_EQ(fuelFigures.mpg(), 35.9f);
        EXPECT_EQ(fuelFigures.getUsageDescription(tmp, sizeof(tmp)), 11);
        EXPECT_EQ(std::string(tmp, 11), "Urban Cycle");

        EXPECT_TRUE(fuelFigures.hasNext());
        fuelFigures.next();
        EXPECT_EQ(fuelFigures.speed(), 55);
        EXPECT_EQ(fuelFigures.mpg(), 49.0f);
        EXPECT_EQ(fuelFigures.getUsageDescription(tmp, sizeof(tmp)), 14);
        EXPECT_EQ(std::string(tmp, 14), "Combined Cycle");

        EXPECT_TRUE(fuelFigures.hasNext());
        fuelFigures.next();
        EXPECT_EQ(fuelFigures.speed(), 75);
        EXPECT_EQ(fuelFigures.mpg(), 40.0f);
        EXPECT_EQ(fuelFigures.getUsageDescription(tmp, sizeof(tmp)), 13);
        EXPECT_EQ(std::string(tmp, 13), "Highway Cycle");

        return m_carDecoder.size();
    }

    virtual int decodeCarPerformanceFigures()
    {
        Car::PerformanceFigures &performanceFigures = m_carDecoder.performanceFigures();
        EXPECT_EQ(performanceFigures.count(), 2);

        EXPECT_TRUE(performanceFigures.hasNext());
        performanceFigures.next();
        EXPECT_EQ(performanceFigures.octaneRating(), 95);

        Car::PerformanceFigures::Acceleration &acceleration = performanceFigures.acceleration();
        EXPECT_EQ(acceleration.count(), 3);
        EXPECT_TRUE(acceleration.hasNext());
        acceleration.next();
        EXPECT_EQ(acceleration.mph(), 30);
        EXPECT_EQ(acceleration.seconds(), 4.0f);

        EXPECT_TRUE(acceleration.hasNext());
        acceleration.next();
        EXPECT_EQ(acceleration.mph(), 60);
        EXPECT_EQ(acceleration.seconds(), 7.5f);

        EXPECT_TRUE(acceleration.hasNext());
        acceleration.next();
        EXPECT_EQ(acceleration.mph(), 100);
        EXPECT_EQ(acceleration.seconds(), 12.2f);

        EXPECT_TRUE(performanceFigures.hasNext());
        performanceFigures.next();
        EXPECT_EQ(performanceFigures.octaneRating(), 99);

        acceleration = performanceFigures.acceleration();
        EXPECT_EQ(acceleration.count(), 3);
        EXPECT_TRUE(acceleration.hasNext());
        acceleration.next();
        EXPECT_EQ(acceleration.mph(), 30);
        EXPECT_EQ(acceleration.seconds(), 3.8f);

        EXPECT_TRUE(acceleration.hasNext());
        acceleration.next();
        EXPECT_EQ(acceleration.mph(), 60);
        EXPECT_EQ(acceleration.seconds(), 7.1f);

        EXPECT_TRUE(acceleration.hasNext());
        acceleration.next();
        EXPECT_EQ(acceleration.mph(), 100);
        EXPECT_EQ(acceleration.seconds(), 11.8f);

        return m_carDecoder.size();
    }

    virtual int decodeCarMakeModelAndActivationCode()
    {
        char tmp[256];

        EXPECT_EQ(m_carDecoder.getMake(tmp, sizeof(tmp)), 5);
        EXPECT_EQ(std::string(tmp, 5), "Honda");

        EXPECT_EQ(m_carDecoder.getModel(tmp, sizeof(tmp)), 9);
        EXPECT_EQ(std::string(tmp, 9), "Civic VTi");

        EXPECT_EQ(m_carDecoder.getActivationCode(tmp, sizeof(tmp)), 8);
        EXPECT_EQ(std::string(tmp, 8), "deadbeef");

        EXPECT_EQ(m_carDecoder.size(), encodedCarSz);

        return m_carDecoder.size();
    }

    MessageHeader m_hdr;
    MessageHeader m_hdrDecoder;
    Car m_car;
    Car m_carDecoder;
};

class HeaderBoundsCheckTest : public BoundsCheckTest, public ::testing::WithParamInterface<int>
{
};

TEST_P(HeaderBoundsCheckTest, shouldExceptionWhenBufferTooShortForEncodeOfHeader)
{
    const int length = GetParam();
    std::unique_ptr<char[]> buffer(new char[length]);

    EXPECT_THROW(
    {
        encodeHdr(buffer.get(), 0, length);
    }, std::runtime_error);
}

TEST_P(HeaderBoundsCheckTest, shouldExceptionWhenBufferTooShortForDecodeOfHeader)
{
    const int length = GetParam();
    char encodeBuffer[MessageHeader::size()];
    std::unique_ptr<char[]> buffer(new char[length]);

    encodeHdr(encodeBuffer, 0, sizeof(encodeBuffer));

    EXPECT_THROW(
    {
        std::memcpy(buffer.get(), encodeBuffer, length);
        decodeHdr(buffer.get(), 0, length);
    }, std::runtime_error);
}

INSTANTIATE_TEST_CASE_P(
    HeaderLengthTest,
    HeaderBoundsCheckTest,
    ::testing::Range(0, encodedHdrSz, 1));

class MessageBoundsCheckTest : public BoundsCheckTest, public ::testing::WithParamInterface<int>
{
};

TEST_P(MessageBoundsCheckTest, shouldExceptionWhenBufferTooShortForEncodeOfMessage)
{
    const int length = GetParam();
    std::unique_ptr<char[]> buffer(new char[length]);

    EXPECT_THROW(
    {
        encodeCarRoot(buffer.get(), 0, length);
        encodeCarFuelFigures();
        encodeCarPerformanceFigures();
        encodeCarMakeModelAndActivationCode();
    }, std::runtime_error);
}

TEST_P(MessageBoundsCheckTest, shouldExceptionWhenBufferTooShortForDecodeOfMessage)
{
    const int length = GetParam();
    char encodeBuffer[179];
    std::unique_ptr<char[]> buffer(new char[length]);

    encodeCarRoot(encodeBuffer, 0, sizeof(encodeBuffer));
    encodeCarFuelFigures();
    encodeCarPerformanceFigures();
    encodeCarMakeModelAndActivationCode();

    EXPECT_THROW(
    {
        std::memcpy(buffer.get(), encodeBuffer, length);
        decodeCarRoot(buffer.get(), 0, length);
        decodeCarFuelFigures();
        decodeCarPerformanceFigures();
        decodeCarMakeModelAndActivationCode();
    }, std::runtime_error);
}

INSTANTIATE_TEST_CASE_P(
    MessageLengthTest,
    MessageBoundsCheckTest,
    ::testing::Range(0, encodedCarSz, 1));
<commit_msg>[C++]: add missing includes for Linux g++<commit_after>/*
 * Copyright 2014 Real Logic Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include <iostream>
#include <memory>
#include <cstring>

#include "gtest/gtest.h"
#include "code_generation_test/MessageHeader.hpp"
#include "code_generation_test/Car.hpp"

using namespace std;
using namespace code_generation_test;

#define SERIAL_NUMBER 1234u
#define MODEL_YEAR 2013
#define AVAILABLE (BooleanType::T)
#define CODE (Model::A)
#define CRUISE_CONTROL (true)
#define SPORTS_PACK (true)
#define SUNROOF (false)

static char VEHICLE_CODE[] = { 'a', 'b', 'c', 'd', 'e', 'f' };
static char MANUFACTURER_CODE[] = { '1', '2', '3' };
static const char *MAKE = "Honda";
static const char *MODEL = "Civic VTi";
static const char *ACTIVATION_CODE = "deadbeef";

static const int encodedHdrSz = 8;
static const int encodedCarSz = 179;

class BoundsCheckTest : public testing::Test
{
public:

    virtual int encodeHdr(char *buffer, int offset, int bufferLength)
    {
        m_hdr.wrap(buffer, offset, 0, bufferLength)
            .blockLength(Car::sbeBlockLength())
            .templateId(Car::sbeTemplateId())
            .schemaId(Car::sbeSchemaId())
            .version(Car::sbeSchemaVersion());

        return m_hdr.size();
    }

    virtual int decodeHdr(char *buffer, int offset, int bufferLength)
    {
        m_hdrDecoder.wrap(buffer, offset, 0, bufferLength);

        EXPECT_EQ(m_hdrDecoder.blockLength(), Car::sbeBlockLength());
        EXPECT_EQ(m_hdrDecoder.templateId(), Car::sbeTemplateId());
        EXPECT_EQ(m_hdrDecoder.schemaId(), Car::sbeSchemaId());
        EXPECT_EQ(m_hdrDecoder.version(), Car::sbeSchemaVersion());

        return m_hdrDecoder.size();
    }

    virtual int encodeCarRoot(char *buffer, int offset, int bufferLength)
    {
        m_car.wrapForEncode(buffer, offset, bufferLength)
            .serialNumber(SERIAL_NUMBER)
            .modelYear(MODEL_YEAR)
            .available(AVAILABLE)
            .code(CODE)
            .putVehicleCode(VEHICLE_CODE);

        for (int i = 0; i < Car::someNumbersLength(); i++)
        {
            m_car.someNumbers(i, i);
        }

        m_car.extras().clear()
            .cruiseControl(CRUISE_CONTROL)
            .sportsPack(SPORTS_PACK)
            .sunRoof(SUNROOF);

        m_car.engine()
            .capacity(2000)
            .numCylinders((short)4)
            .putManufacturerCode(MANUFACTURER_CODE);

        return m_car.size();
    }

    virtual int encodeCarFuelFigures()
    {
        Car::FuelFigures& fuelFigures = m_car.fuelFiguresCount(3);

        fuelFigures
            .next().speed(30).mpg(35.9f);
        fuelFigures.putUsageDescription("Urban Cycle", 11);

        fuelFigures
            .next().speed(55).mpg(49.0f);
        fuelFigures.putUsageDescription("Combined Cycle", 14);

        fuelFigures
            .next().speed(75).mpg(40.0f);
        fuelFigures.putUsageDescription("Highway Cycle", 13);

        return m_car.size();
    }

    virtual int encodeCarPerformanceFigures()
    {
        Car::PerformanceFigures &perfFigs = m_car.performanceFiguresCount(2);

        perfFigs.next()
            .octaneRating((short)95)
            .accelerationCount(3)
                .next().mph(30).seconds(4.0f)
                .next().mph(60).seconds(7.5f)
                .next().mph(100).seconds(12.2f);

        perfFigs.next()
            .octaneRating((short)99)
            .accelerationCount(3)
                .next().mph(30).seconds(3.8f)
                .next().mph(60).seconds(7.1f)
                .next().mph(100).seconds(11.8f);

        return m_car.size();
    }

    virtual int encodeCarMakeModelAndActivationCode()
    {
        m_car.putMake(MAKE, static_cast<int>(strlen(MAKE)));
        m_car.putModel(MODEL, static_cast<int>(strlen(MODEL)));
        m_car.putActivationCode(ACTIVATION_CODE, static_cast<int>(strlen(ACTIVATION_CODE)));

        return m_car.size();
    }

    virtual int decodeCarRoot(char *buffer, const int offset, const int bufferLength)
    {
        m_carDecoder.wrapForDecode(buffer, offset, Car::sbeBlockLength(), Car::sbeSchemaVersion(), bufferLength);
        EXPECT_EQ(m_carDecoder.serialNumber(), SERIAL_NUMBER);
        EXPECT_EQ(m_carDecoder.modelYear(), MODEL_YEAR);
        EXPECT_EQ(m_carDecoder.available(), AVAILABLE);
        EXPECT_EQ(m_carDecoder.code(), CODE);

        EXPECT_EQ(m_carDecoder.someNumbersLength(), 5);
        for (int i = 0; i < 5; i++)
        {
            EXPECT_EQ(m_carDecoder.someNumbers(i), i);
        }

        EXPECT_EQ(m_carDecoder.vehicleCodeLength(), 6);
        EXPECT_EQ(std::string(m_carDecoder.vehicleCode(), 6), std::string(VEHICLE_CODE, 6));
        EXPECT_EQ(m_carDecoder.extras().cruiseControl(), true);
        EXPECT_EQ(m_carDecoder.extras().sportsPack(), true);
        EXPECT_EQ(m_carDecoder.extras().sunRoof(), false);

        Engine &engine = m_carDecoder.engine();
        EXPECT_EQ(engine.capacity(), 2000);
        EXPECT_EQ(engine.numCylinders(), 4);
        EXPECT_EQ(engine.maxRpm(), 9000);
        EXPECT_EQ(engine.manufacturerCodeLength(), 3);
        EXPECT_EQ(std::string(engine.manufacturerCode(), 3), std::string(MANUFACTURER_CODE, 3));
        EXPECT_EQ(engine.fuelLength(), 6);
        EXPECT_EQ(std::string(engine.fuel(), 6), std::string("Petrol"));

        return m_carDecoder.size();
    }

    virtual int decodeCarFuelFigures()
    {
        char tmp[256];
        Car::FuelFigures &fuelFigures = m_carDecoder.fuelFigures();
        EXPECT_EQ(fuelFigures.count(), 3);

        EXPECT_TRUE(fuelFigures.hasNext());
        fuelFigures.next();
        EXPECT_EQ(fuelFigures.speed(), 30);
        EXPECT_EQ(fuelFigures.mpg(), 35.9f);
        EXPECT_EQ(fuelFigures.getUsageDescription(tmp, sizeof(tmp)), 11);
        EXPECT_EQ(std::string(tmp, 11), "Urban Cycle");

        EXPECT_TRUE(fuelFigures.hasNext());
        fuelFigures.next();
        EXPECT_EQ(fuelFigures.speed(), 55);
        EXPECT_EQ(fuelFigures.mpg(), 49.0f);
        EXPECT_EQ(fuelFigures.getUsageDescription(tmp, sizeof(tmp)), 14);
        EXPECT_EQ(std::string(tmp, 14), "Combined Cycle");

        EXPECT_TRUE(fuelFigures.hasNext());
        fuelFigures.next();
        EXPECT_EQ(fuelFigures.speed(), 75);
        EXPECT_EQ(fuelFigures.mpg(), 40.0f);
        EXPECT_EQ(fuelFigures.getUsageDescription(tmp, sizeof(tmp)), 13);
        EXPECT_EQ(std::string(tmp, 13), "Highway Cycle");

        return m_carDecoder.size();
    }

    virtual int decodeCarPerformanceFigures()
    {
        Car::PerformanceFigures &performanceFigures = m_carDecoder.performanceFigures();
        EXPECT_EQ(performanceFigures.count(), 2);

        EXPECT_TRUE(performanceFigures.hasNext());
        performanceFigures.next();
        EXPECT_EQ(performanceFigures.octaneRating(), 95);

        Car::PerformanceFigures::Acceleration &acceleration = performanceFigures.acceleration();
        EXPECT_EQ(acceleration.count(), 3);
        EXPECT_TRUE(acceleration.hasNext());
        acceleration.next();
        EXPECT_EQ(acceleration.mph(), 30);
        EXPECT_EQ(acceleration.seconds(), 4.0f);

        EXPECT_TRUE(acceleration.hasNext());
        acceleration.next();
        EXPECT_EQ(acceleration.mph(), 60);
        EXPECT_EQ(acceleration.seconds(), 7.5f);

        EXPECT_TRUE(acceleration.hasNext());
        acceleration.next();
        EXPECT_EQ(acceleration.mph(), 100);
        EXPECT_EQ(acceleration.seconds(), 12.2f);

        EXPECT_TRUE(performanceFigures.hasNext());
        performanceFigures.next();
        EXPECT_EQ(performanceFigures.octaneRating(), 99);

        acceleration = performanceFigures.acceleration();
        EXPECT_EQ(acceleration.count(), 3);
        EXPECT_TRUE(acceleration.hasNext());
        acceleration.next();
        EXPECT_EQ(acceleration.mph(), 30);
        EXPECT_EQ(acceleration.seconds(), 3.8f);

        EXPECT_TRUE(acceleration.hasNext());
        acceleration.next();
        EXPECT_EQ(acceleration.mph(), 60);
        EXPECT_EQ(acceleration.seconds(), 7.1f);

        EXPECT_TRUE(acceleration.hasNext());
        acceleration.next();
        EXPECT_EQ(acceleration.mph(), 100);
        EXPECT_EQ(acceleration.seconds(), 11.8f);

        return m_carDecoder.size();
    }

    virtual int decodeCarMakeModelAndActivationCode()
    {
        char tmp[256];

        EXPECT_EQ(m_carDecoder.getMake(tmp, sizeof(tmp)), 5);
        EXPECT_EQ(std::string(tmp, 5), "Honda");

        EXPECT_EQ(m_carDecoder.getModel(tmp, sizeof(tmp)), 9);
        EXPECT_EQ(std::string(tmp, 9), "Civic VTi");

        EXPECT_EQ(m_carDecoder.getActivationCode(tmp, sizeof(tmp)), 8);
        EXPECT_EQ(std::string(tmp, 8), "deadbeef");

        EXPECT_EQ(m_carDecoder.size(), encodedCarSz);

        return m_carDecoder.size();
    }

    MessageHeader m_hdr;
    MessageHeader m_hdrDecoder;
    Car m_car;
    Car m_carDecoder;
};

class HeaderBoundsCheckTest : public BoundsCheckTest, public ::testing::WithParamInterface<int>
{
};

TEST_P(HeaderBoundsCheckTest, shouldExceptionWhenBufferTooShortForEncodeOfHeader)
{
    const int length = GetParam();
    std::unique_ptr<char[]> buffer(new char[length]);

    EXPECT_THROW(
    {
        encodeHdr(buffer.get(), 0, length);
    }, std::runtime_error);
}

TEST_P(HeaderBoundsCheckTest, shouldExceptionWhenBufferTooShortForDecodeOfHeader)
{
    const int length = GetParam();
    char encodeBuffer[MessageHeader::size()];
    std::unique_ptr<char[]> buffer(new char[length]);

    encodeHdr(encodeBuffer, 0, sizeof(encodeBuffer));

    EXPECT_THROW(
    {
        std::memcpy(buffer.get(), encodeBuffer, length);
        decodeHdr(buffer.get(), 0, length);
    }, std::runtime_error);
}

INSTANTIATE_TEST_CASE_P(
    HeaderLengthTest,
    HeaderBoundsCheckTest,
    ::testing::Range(0, encodedHdrSz, 1));

class MessageBoundsCheckTest : public BoundsCheckTest, public ::testing::WithParamInterface<int>
{
};

TEST_P(MessageBoundsCheckTest, shouldExceptionWhenBufferTooShortForEncodeOfMessage)
{
    const int length = GetParam();
    std::unique_ptr<char[]> buffer(new char[length]);

    EXPECT_THROW(
    {
        encodeCarRoot(buffer.get(), 0, length);
        encodeCarFuelFigures();
        encodeCarPerformanceFigures();
        encodeCarMakeModelAndActivationCode();
    }, std::runtime_error);
}

TEST_P(MessageBoundsCheckTest, shouldExceptionWhenBufferTooShortForDecodeOfMessage)
{
    const int length = GetParam();
    char encodeBuffer[179];
    std::unique_ptr<char[]> buffer(new char[length]);

    encodeCarRoot(encodeBuffer, 0, sizeof(encodeBuffer));
    encodeCarFuelFigures();
    encodeCarPerformanceFigures();
    encodeCarMakeModelAndActivationCode();

    EXPECT_THROW(
    {
        std::memcpy(buffer.get(), encodeBuffer, length);
        decodeCarRoot(buffer.get(), 0, length);
        decodeCarFuelFigures();
        decodeCarPerformanceFigures();
        decodeCarMakeModelAndActivationCode();
    }, std::runtime_error);
}

INSTANTIATE_TEST_CASE_P(
    MessageLengthTest,
    MessageBoundsCheckTest,
    ::testing::Range(0, encodedCarSz, 1));
<|endoftext|>


<commit_before>// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

#include "dense_lambda_peek_optimizer.h"
#include "dense_tensor_view.h"
#include "dense_replace_type_function.h"
#include "dense_cell_range_function.h"
#include "dense_lambda_peek_function.h"
#include <vespa/eval/eval/value.h>
#include <vespa/eval/eval/node_tools.h>
#include <vespa/eval/eval/basic_nodes.h>
#include <vespa/eval/eval/operator_nodes.h>
#include <vespa/eval/eval/call_nodes.h>
#include <vespa/eval/eval/tensor_nodes.h>
#include <vespa/eval/eval/llvm/compile_cache.h>
#include <optional>

using namespace vespalib::eval;
using namespace vespalib::eval::nodes;

namespace vespalib::tensor {

namespace {

// 'simple peek': deterministic peek into a single parameter with
//                compilable dimension index expressions.
const TensorPeek *find_simple_peek(const tensor_function::Lambda &lambda) {
    const Function &function = lambda.lambda();
    const size_t num_dims = lambda.result_type().dimensions().size();
    auto peek = as<TensorPeek>(function.root());
    if (peek && (function.num_params() == (num_dims + 1))) {
        auto param = as<Symbol>(peek->get_child(0));
        if (param && (param->id() == num_dims)) {
            for (size_t i = 1; i < peek->num_children(); ++i) {
                const Node &dim_expr = peek->get_child(i);
                if (NodeTools::min_num_params(dim_expr) > num_dims) {
                    return nullptr;
                }
                if (CompiledFunction::detect_issues(dim_expr)) {
                    return nullptr;
                }
            }
            return peek;
        }
    }
    return nullptr;
}

Node_UP make_dim_expr(const TensorPeek::Dim &src_dim) {
    if (src_dim.second.is_expr()) {
        return NodeTools::copy(*src_dim.second.expr);
    } else {
        return std::make_unique<Number>(as_number(src_dim.second.label));
    }
}

template <typename OP>
Node_UP make_op(Node_UP a, Node_UP b) {
    auto res = std::make_unique<OP>();
    res->bind(std::move(a), std::move(b));
    return res;
}

Node_UP make_floor(Node_UP a) {
    auto res = std::make_unique<Floor>();
    res->bind_next(std::move(a));
    return res;
}

struct PeekAnalyzer {
    std::vector<size_t> dst_dim_sizes;
    std::vector<size_t> src_dim_sizes;
    std::vector<CompiledFunction::UP> src_dim_funs;
    std::shared_ptr<Function const> src_idx_fun;

    struct CellRange {
        size_t offset;
        size_t length;
        bool is_full(size_t num_cells) const {
            return ((offset == 0) && (length == num_cells));
        }
    };

    struct Result {
        bool valid;
        std::optional<CellRange> cell_range;
        static Result simple(CellRange range) { return Result{true, range}; }
        static Result complex() { return Result{true, std::nullopt}; }
        static Result invalid() { return Result{false, std::nullopt}; }
    };

    PeekAnalyzer(const ValueType &dst_type, const ValueType &src_type,
                 const TensorPeek::DimList &dim_list)
    {
        for (const auto dim: dst_type.dimensions()) {
            dst_dim_sizes.push_back(dim.size);
        }
        for (const auto dim: src_type.dimensions()) {
            src_dim_sizes.push_back(dim.size);
        }
        Node_UP idx_expr;
        size_t num_params = dst_dim_sizes.size();
        for (size_t i = 0; i < dim_list.size(); ++i) {
            auto dim_expr = make_dim_expr(dim_list[i]);
            src_dim_funs.push_back(std::make_unique<CompiledFunction>(*dim_expr, num_params, PassParams::ARRAY));
            if (i == 0) {
                idx_expr = std::move(dim_expr);
            } else {
                idx_expr = make_floor(std::move(idx_expr));
                idx_expr = make_op<Mul>(std::move(idx_expr), std::make_unique<Number>(src_dim_sizes[i]));
                idx_expr = make_op<Add>(std::move(idx_expr), std::move(dim_expr));
            }
        }
        src_idx_fun = Function::create(std::move(idx_expr), dst_type.dimension_names());
    }

    bool step_params(std::vector<double> &params) {
        for (size_t idx = params.size(); idx-- > 0; ) {
            if (size_t(params[idx] += 1.0) < dst_dim_sizes[idx]) {
                return true;
            } else {
                params[idx] = 0.0;
            }
        }
        return false;
    }

    size_t calculate_index(const std::vector<size_t> &src_address) {
        size_t result = 0;
        for (size_t i = 0; i < src_address.size(); ++i) {
            result *= src_dim_sizes[i];
            result += src_address[i];
        }
        return result;
    }

    Result analyze_indexes() {
        CellRange range{0,0};
        bool is_complex = false;
        std::vector<double> params(dst_dim_sizes.size(), 0.0);
        std::vector<size_t> src_address(src_dim_sizes.size(), 0);
        do {
            for (size_t i = 0; i < src_dim_funs.size(); ++i) {
                auto dim_fun = src_dim_funs[i]->get_function();
                size_t dim_idx = dim_fun(&params[0]);
                if (dim_idx >= src_dim_sizes[i]) {
                    return Result::invalid();
                }
                src_address[i] = dim_idx;
            }
            size_t idx = calculate_index(src_address);
            if (range.length == 0) {
                range.offset = idx;
            }
            if (idx == (range.offset + range.length)) {
                ++range.length;
            } else {
                is_complex = true;
            }
        } while(step_params(params));
        if (is_complex) {
            return Result::complex();
        }
        return Result::simple(range);
    }
};

} // namespace vespalib::tensor::<unnamed>

const TensorFunction &
DenseLambdaPeekOptimizer::optimize(const TensorFunction &expr, Stash &stash)
{
    if (auto lambda = as<tensor_function::Lambda>(expr)) {
        if (auto peek = find_simple_peek(*lambda)) {
            const ValueType &dst_type = lambda->result_type();
            const ValueType &src_type = lambda->types().get_type(peek->param());
            if (src_type.is_dense()) {
                assert(lambda->bindings().size() == 1);
                assert(src_type.dimensions().size() == peek->dim_list().size());
                size_t param_idx = lambda->bindings()[0];
                PeekAnalyzer analyzer(dst_type, src_type, peek->dim_list());
                auto result = analyzer.analyze_indexes();
                if (result.valid) {
                    const auto &get_param = tensor_function::inject(src_type, param_idx, stash);
                    if (result.cell_range && (dst_type.cell_type() == src_type.cell_type())) {
                        auto cell_range = result.cell_range.value();
                        if (cell_range.is_full(src_type.dense_subspace_size())) {
                            return DenseReplaceTypeFunction::create_compact(dst_type, get_param, stash);
                        } else {
                            return stash.create<DenseCellRangeFunction>(dst_type, get_param,
                                    cell_range.offset, cell_range.length);
                        }
                    } else {
                        return stash.create<DenseLambdaPeekFunction>(dst_type, get_param,
                                std::move(analyzer.src_idx_fun));
                    }
                }
            }
        }
    }
    return expr;
}

} // namespace vespalib::tensor
<commit_msg>Avoid making copies of container elements.<commit_after>// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

#include "dense_lambda_peek_optimizer.h"
#include "dense_tensor_view.h"
#include "dense_replace_type_function.h"
#include "dense_cell_range_function.h"
#include "dense_lambda_peek_function.h"
#include <vespa/eval/eval/value.h>
#include <vespa/eval/eval/node_tools.h>
#include <vespa/eval/eval/basic_nodes.h>
#include <vespa/eval/eval/operator_nodes.h>
#include <vespa/eval/eval/call_nodes.h>
#include <vespa/eval/eval/tensor_nodes.h>
#include <vespa/eval/eval/llvm/compile_cache.h>
#include <optional>

using namespace vespalib::eval;
using namespace vespalib::eval::nodes;

namespace vespalib::tensor {

namespace {

// 'simple peek': deterministic peek into a single parameter with
//                compilable dimension index expressions.
const TensorPeek *find_simple_peek(const tensor_function::Lambda &lambda) {
    const Function &function = lambda.lambda();
    const size_t num_dims = lambda.result_type().dimensions().size();
    auto peek = as<TensorPeek>(function.root());
    if (peek && (function.num_params() == (num_dims + 1))) {
        auto param = as<Symbol>(peek->get_child(0));
        if (param && (param->id() == num_dims)) {
            for (size_t i = 1; i < peek->num_children(); ++i) {
                const Node &dim_expr = peek->get_child(i);
                if (NodeTools::min_num_params(dim_expr) > num_dims) {
                    return nullptr;
                }
                if (CompiledFunction::detect_issues(dim_expr)) {
                    return nullptr;
                }
            }
            return peek;
        }
    }
    return nullptr;
}

Node_UP make_dim_expr(const TensorPeek::Dim &src_dim) {
    if (src_dim.second.is_expr()) {
        return NodeTools::copy(*src_dim.second.expr);
    } else {
        return std::make_unique<Number>(as_number(src_dim.second.label));
    }
}

template <typename OP>
Node_UP make_op(Node_UP a, Node_UP b) {
    auto res = std::make_unique<OP>();
    res->bind(std::move(a), std::move(b));
    return res;
}

Node_UP make_floor(Node_UP a) {
    auto res = std::make_unique<Floor>();
    res->bind_next(std::move(a));
    return res;
}

struct PeekAnalyzer {
    std::vector<size_t> dst_dim_sizes;
    std::vector<size_t> src_dim_sizes;
    std::vector<CompiledFunction::UP> src_dim_funs;
    std::shared_ptr<Function const> src_idx_fun;

    struct CellRange {
        size_t offset;
        size_t length;
        bool is_full(size_t num_cells) const {
            return ((offset == 0) && (length == num_cells));
        }
    };

    struct Result {
        bool valid;
        std::optional<CellRange> cell_range;
        static Result simple(CellRange range) { return Result{true, range}; }
        static Result complex() { return Result{true, std::nullopt}; }
        static Result invalid() { return Result{false, std::nullopt}; }
    };

    PeekAnalyzer(const ValueType &dst_type, const ValueType &src_type,
                 const TensorPeek::DimList &dim_list)
    {
        for (const auto& dim: dst_type.dimensions()) {
            dst_dim_sizes.push_back(dim.size);
        }
        for (const auto& dim: src_type.dimensions()) {
            src_dim_sizes.push_back(dim.size);
        }
        Node_UP idx_expr;
        size_t num_params = dst_dim_sizes.size();
        for (size_t i = 0; i < dim_list.size(); ++i) {
            auto dim_expr = make_dim_expr(dim_list[i]);
            src_dim_funs.push_back(std::make_unique<CompiledFunction>(*dim_expr, num_params, PassParams::ARRAY));
            if (i == 0) {
                idx_expr = std::move(dim_expr);
            } else {
                idx_expr = make_floor(std::move(idx_expr));
                idx_expr = make_op<Mul>(std::move(idx_expr), std::make_unique<Number>(src_dim_sizes[i]));
                idx_expr = make_op<Add>(std::move(idx_expr), std::move(dim_expr));
            }
        }
        src_idx_fun = Function::create(std::move(idx_expr), dst_type.dimension_names());
    }

    bool step_params(std::vector<double> &params) {
        for (size_t idx = params.size(); idx-- > 0; ) {
            if (size_t(params[idx] += 1.0) < dst_dim_sizes[idx]) {
                return true;
            } else {
                params[idx] = 0.0;
            }
        }
        return false;
    }

    size_t calculate_index(const std::vector<size_t> &src_address) {
        size_t result = 0;
        for (size_t i = 0; i < src_address.size(); ++i) {
            result *= src_dim_sizes[i];
            result += src_address[i];
        }
        return result;
    }

    Result analyze_indexes() {
        CellRange range{0,0};
        bool is_complex = false;
        std::vector<double> params(dst_dim_sizes.size(), 0.0);
        std::vector<size_t> src_address(src_dim_sizes.size(), 0);
        do {
            for (size_t i = 0; i < src_dim_funs.size(); ++i) {
                auto dim_fun = src_dim_funs[i]->get_function();
                size_t dim_idx = dim_fun(&params[0]);
                if (dim_idx >= src_dim_sizes[i]) {
                    return Result::invalid();
                }
                src_address[i] = dim_idx;
            }
            size_t idx = calculate_index(src_address);
            if (range.length == 0) {
                range.offset = idx;
            }
            if (idx == (range.offset + range.length)) {
                ++range.length;
            } else {
                is_complex = true;
            }
        } while(step_params(params));
        if (is_complex) {
            return Result::complex();
        }
        return Result::simple(range);
    }
};

} // namespace vespalib::tensor::<unnamed>

const TensorFunction &
DenseLambdaPeekOptimizer::optimize(const TensorFunction &expr, Stash &stash)
{
    if (auto lambda = as<tensor_function::Lambda>(expr)) {
        if (auto peek = find_simple_peek(*lambda)) {
            const ValueType &dst_type = lambda->result_type();
            const ValueType &src_type = lambda->types().get_type(peek->param());
            if (src_type.is_dense()) {
                assert(lambda->bindings().size() == 1);
                assert(src_type.dimensions().size() == peek->dim_list().size());
                size_t param_idx = lambda->bindings()[0];
                PeekAnalyzer analyzer(dst_type, src_type, peek->dim_list());
                auto result = analyzer.analyze_indexes();
                if (result.valid) {
                    const auto &get_param = tensor_function::inject(src_type, param_idx, stash);
                    if (result.cell_range && (dst_type.cell_type() == src_type.cell_type())) {
                        auto cell_range = result.cell_range.value();
                        if (cell_range.is_full(src_type.dense_subspace_size())) {
                            return DenseReplaceTypeFunction::create_compact(dst_type, get_param, stash);
                        } else {
                            return stash.create<DenseCellRangeFunction>(dst_type, get_param,
                                    cell_range.offset, cell_range.length);
                        }
                    } else {
                        return stash.create<DenseLambdaPeekFunction>(dst_type, get_param,
                                std::move(analyzer.src_idx_fun));
                    }
                }
            }
        }
    }
    return expr;
}

} // namespace vespalib::tensor
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2018, ARM Limited, All Rights Reserved
 * SPDX-License-Identifier: Apache-2.0
 *
 * 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.
 */

#if !defined(MBED_CONF_RTOS_PRESENT)
#error [NOT_SUPPORTED] dns test cases require a RTOS to run.
#else

#define WIFI 2
#if !defined(MBED_CONF_TARGET_NETWORK_DEFAULT_INTERFACE_TYPE) || \
    (MBED_CONF_TARGET_NETWORK_DEFAULT_INTERFACE_TYPE == WIFI && !defined(MBED_CONF_NSAPI_DEFAULT_WIFI_SSID))
#error [NOT_SUPPORTED] No network configuration found for this target.
#else

#include "mbed.h"
#include "greentea-client/test_env.h"
#include "unity.h"
#include "utest.h"
#include "nsapi_dns.h"
#include "events/EventQueue.h"
#include "dns_tests.h"
#include "ip6string.h"

using namespace utest::v1;

namespace {
NetworkInterface *net;
}

const char dns_test_hosts[MBED_CONF_APP_DNS_TEST_HOSTS_NUM][DNS_TEST_HOST_LEN] = MBED_CONF_APP_DNS_TEST_HOSTS;
const char dns_test_hosts_second[MBED_CONF_APP_DNS_TEST_HOSTS_NUM][DNS_TEST_HOST_LEN] = MBED_CONF_APP_DNS_TEST_HOSTS_SECOND;
const char dns_test_hosts_multi_ip[MBED_CONF_APP_DNS_SIMULT_QUERIES][DNS_TEST_HOST_LEN] = MBED_CONF_APP_DNS_TEST_MULTI_IP_HOSTS;

// Callback used for asynchronous DNS result
void hostbyname_cb(void *data, nsapi_error_t result, SocketAddress *address)
{
    dns_application_data *app_data = static_cast<dns_application_data *>(data);
    app_data->result = result;
    if (address) {
        app_data->addr = *address;
    }
    app_data->semaphore->release();
    app_data->value_set = true;
}

// General function to do asynchronous DNS host name resolution
void do_asynchronous_gethostbyname(const char hosts[][DNS_TEST_HOST_LEN], unsigned int op_count, int *exp_ok, int *exp_no_mem, int *exp_dns_failure, int *exp_timeout)
{
    // Verify that there is enough hosts in the host list
    TEST_ASSERT(op_count <= MBED_CONF_APP_DNS_TEST_HOSTS_NUM)

    // Reset counters
    (*exp_ok) = 0;
    (*exp_no_mem) = 0;
    (*exp_dns_failure) = 0;
    (*exp_timeout) = 0;

    // Create callback semaphore and data
    rtos::Semaphore semaphore;
    dns_application_data *data = new dns_application_data[op_count];

    unsigned int count = 0;
    for (unsigned int i = 0; i < op_count; i++) {
        data[i].semaphore = &semaphore;
        nsapi_error_t err = net->gethostbyname_async(hosts[i], mbed::Callback<void(nsapi_error_t, SocketAddress *)>(hostbyname_cb, (void *) &data[i]));
        TEST_ASSERT(err >= 0 || err == NSAPI_ERROR_NO_MEMORY || err == NSAPI_ERROR_BUSY);
        if (err >= 0) {
            // Callback will be called
            count++;
        } else {
            // No memory to initiate DNS query, callback will not be called
            data[i].result = err;
        }
    }

    // Wait for callback(s) to complete
    for (unsigned int i = 0; i < count; i++) {
        semaphore.acquire();
    }

    // Print result
    for (unsigned int i = 0; i < op_count; i++) {
        TEST_ASSERT(data[i].result > 0 || data[i].result == NSAPI_ERROR_NO_MEMORY || data[i].result == NSAPI_ERROR_BUSY || data[i].result == NSAPI_ERROR_DNS_FAILURE || data[i].result == NSAPI_ERROR_TIMEOUT);
        if (data[i].result > 0) {
            (*exp_ok)++;
            tr_info("DNS: query \"%s\" => \"%s\"",
                    hosts[i], data[i].addr.get_ip_address());
        } else if (data[i].result == NSAPI_ERROR_DNS_FAILURE) {
            (*exp_dns_failure)++;
            tr_error("DNS: query \"%s\" => DNS failure", hosts[i]);
        } else if (data[i].result == NSAPI_ERROR_TIMEOUT) {
            (*exp_timeout)++;
            tr_error("DNS: query \"%s\" => timeout", hosts[i]);
        } else if (data[i].result == NSAPI_ERROR_NO_MEMORY) {
            (*exp_no_mem)++;
            tr_error("DNS: query \"%s\" => no memory", hosts[i]);
        } else if (data[i].result == NSAPI_ERROR_BUSY) {
            (*exp_no_mem)++;
            tr_error("DNS: query \"%s\" => busy", hosts[i]);
        }
    }

    delete[] data;
}

void do_gethostbyname(const char hosts[][DNS_TEST_HOST_LEN], unsigned int op_count, int *exp_ok, int *exp_no_mem, int *exp_dns_failure, int *exp_timeout)
{
    // Verify that there is enough hosts in the host list
    TEST_ASSERT(op_count <= MBED_CONF_APP_DNS_TEST_HOSTS_NUM)

    // Reset counters
    (*exp_ok) = 0;
    (*exp_no_mem) = 0;
    (*exp_dns_failure) = 0;
    (*exp_timeout) = 0;

    for (unsigned int i = 0; i < op_count; i++) {
        SocketAddress address;
        nsapi_error_t err = net->gethostbyname(hosts[i], &address);

        if (err == NSAPI_ERROR_OK) {
            (*exp_ok)++;
            tr_info("DNS: query \"%s\" => \"%s\"",
                    hosts[i], address.get_ip_address());
        } else if (err == NSAPI_ERROR_DNS_FAILURE) {
            (*exp_dns_failure)++;
            tr_error("DNS: query \"%s\" => DNS failure", hosts[i]);
        } else if (err == NSAPI_ERROR_TIMEOUT) {
            (*exp_timeout)++;
            tr_error("DNS: query \"%s\" => timeout", hosts[i]);
        } else if (err == NSAPI_ERROR_NO_MEMORY) {
            (*exp_no_mem)++;
            tr_error("DNS: query \"%s\" => no memory", hosts[i]);
        } else if (err == NSAPI_ERROR_BUSY) {
            (*exp_no_mem)++;
            tr_error("DNS: query \"%s\" => busy", hosts[i]);
        } else {
            tr_error("DNS: query \"%s\" => %d, unexpected answer", hosts[i], err);
            TEST_ASSERT(err == NSAPI_ERROR_OK || err == NSAPI_ERROR_NO_MEMORY || err == NSAPI_ERROR_BUSY || err == NSAPI_ERROR_DNS_FAILURE || err == NSAPI_ERROR_TIMEOUT);
        }
    }
}

NetworkInterface *get_interface()
{
    return net;
}

static void net_bringup()
{
    nsapi_dns_reset();
    MBED_ASSERT(MBED_CONF_APP_DNS_TEST_HOSTS_NUM >= MBED_CONF_NSAPI_DNS_CACHE_SIZE && MBED_CONF_APP_DNS_TEST_HOSTS_NUM >= MBED_CONF_APP_DNS_SIMULT_QUERIES + 1);

    net = NetworkInterface::get_default_instance();
    nsapi_error_t err = net->connect();
    TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, err);
    SocketAddress address;
    net->get_ip_address(&address);

#define MESH 3
#if MBED_CONF_TARGET_NETWORK_DEFAULT_INTERFACE_TYPE == MESH
    printf("Waiting for GLOBAL_UP\n");
    while (net->get_connection_status() != NSAPI_STATUS_GLOBAL_UP) {
        ThisThread::sleep_for(500);
    }
#endif
    printf("MBED: IP address is '%s'\n", address ? address.get_ip_address() : "null");
}

static void net_bringdown()
{
    NetworkInterface::get_default_instance()->disconnect();
    tr_info("MBED: ifdown");
}

// Test setup
utest::v1::status_t test_setup(const size_t number_of_cases)
{
    GREENTEA_SETUP(dns_global::TESTS_TIMEOUT, "default_auto");
    net_bringup();
    return verbose_test_setup_handler(number_of_cases);
}

void greentea_teardown(const size_t passed, const size_t failed, const failure_t failure)
{
    net_bringdown();
    return greentea_test_teardown_handler(passed, failed, failure);
}

Case cases[] = {
    Case("ASYNCHRONOUS_DNS", ASYNCHRONOUS_DNS),
    Case("ASYNCHRONOUS_DNS_SIMULTANEOUS", ASYNCHRONOUS_DNS_SIMULTANEOUS),
    Case("ASYNCHRONOUS_DNS_SIMULTANEOUS_CACHE", ASYNCHRONOUS_DNS_SIMULTANEOUS_CACHE),
    Case("SYNCHRONOUS_DNS_CACHE", SYNCHRONOUS_DNS_CACHE),
#ifndef MBED_CONF_CELLULAR_OFFLOAD_DNS_QUERIES
    Case("ASYNCHRONOUS_DNS_CACHE", ASYNCHRONOUS_DNS_CACHE),
#endif
#if !defined MBED_CONF_CELLULAR_OFFLOAD_DNS_QUERIES || MBED_CONF_CELLULAR_OFFLOAD_DNS_QUERIES > MBED_CONF_APP_DNS_TEST_HOSTS_NUM
    Case("ASYNCHRONOUS_DNS_NON_ASYNC_AND_ASYNC", ASYNCHRONOUS_DNS_NON_ASYNC_AND_ASYNC),
#endif
    Case("ASYNCHRONOUS_DNS_CANCEL", ASYNCHRONOUS_DNS_CANCEL),
#ifndef MBED_CONF_CELLULAR_OFFLOAD_DNS_QUERIES
    Case("ASYNCHRONOUS_DNS_EXTERNAL_EVENT_QUEUE", ASYNCHRONOUS_DNS_EXTERNAL_EVENT_QUEUE),
    Case("ASYNCHRONOUS_DNS_INVALID_HOST", ASYNCHRONOUS_DNS_INVALID_HOST),
    Case("ASYNCHRONOUS_DNS_TIMEOUTS", ASYNCHRONOUS_DNS_TIMEOUTS),
#endif
    Case("ASYNCHRONOUS_DNS_SIMULTANEOUS_REPEAT",  ASYNCHRONOUS_DNS_SIMULTANEOUS_REPEAT),
    Case("SYNCHRONOUS_DNS", SYNCHRONOUS_DNS),
    Case("SYNCHRONOUS_DNS_MULTIPLE", SYNCHRONOUS_DNS_MULTIPLE),
    Case("SYNCHRONOUS_DNS_INVALID", SYNCHRONOUS_DNS_INVALID),
    Case("SYNCHRONOUS_DNS_MULTI_IP", SYNCHRONOUS_DNS_MULTI_IP),
    Case("ASYNCHRONOUS_DNS_MULTI_IP", ASYNCHRONOUS_DNS_MULTI_IP),
};

Specification specification(test_setup, cases, greentea_teardown, greentea_continue_handlers);

int main()
{
    return !Harness::run(specification);
}

#endif // !defined(MBED_CONF_TARGET_NETWORK_DEFAULT_INTERFACE_TYPE) || (MBED_CONF_TARGET_NETWORK_DEFAULT_INTERFACE_TYPE == WIFI && !defined(MBED_CONF_NSAPI_DEFAULT_WIFI_SSID))
#endif // !defined(MBED_CONF_RTOS_PRESENT)
<commit_msg>Enable SYNCHRONOUS_DNS_CACHE just for NSAPI_PPP_AVAILABLE<commit_after>/*
 * Copyright (c) 2018, ARM Limited, All Rights Reserved
 * SPDX-License-Identifier: Apache-2.0
 *
 * 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.
 */

#if !defined(MBED_CONF_RTOS_PRESENT)
#error [NOT_SUPPORTED] dns test cases require a RTOS to run.
#else

#define WIFI 2
#if !defined(MBED_CONF_TARGET_NETWORK_DEFAULT_INTERFACE_TYPE) || \
    (MBED_CONF_TARGET_NETWORK_DEFAULT_INTERFACE_TYPE == WIFI && !defined(MBED_CONF_NSAPI_DEFAULT_WIFI_SSID))
#error [NOT_SUPPORTED] No network configuration found for this target.
#else

#include "mbed.h"
#include "greentea-client/test_env.h"
#include "unity.h"
#include "utest.h"
#include "nsapi_dns.h"
#include "events/EventQueue.h"
#include "dns_tests.h"
#include "ip6string.h"

using namespace utest::v1;

namespace {
NetworkInterface *net;
}

const char dns_test_hosts[MBED_CONF_APP_DNS_TEST_HOSTS_NUM][DNS_TEST_HOST_LEN] = MBED_CONF_APP_DNS_TEST_HOSTS;
const char dns_test_hosts_second[MBED_CONF_APP_DNS_TEST_HOSTS_NUM][DNS_TEST_HOST_LEN] = MBED_CONF_APP_DNS_TEST_HOSTS_SECOND;
const char dns_test_hosts_multi_ip[MBED_CONF_APP_DNS_SIMULT_QUERIES][DNS_TEST_HOST_LEN] = MBED_CONF_APP_DNS_TEST_MULTI_IP_HOSTS;

// Callback used for asynchronous DNS result
void hostbyname_cb(void *data, nsapi_error_t result, SocketAddress *address)
{
    dns_application_data *app_data = static_cast<dns_application_data *>(data);
    app_data->result = result;
    if (address) {
        app_data->addr = *address;
    }
    app_data->semaphore->release();
    app_data->value_set = true;
}

// General function to do asynchronous DNS host name resolution
void do_asynchronous_gethostbyname(const char hosts[][DNS_TEST_HOST_LEN], unsigned int op_count, int *exp_ok, int *exp_no_mem, int *exp_dns_failure, int *exp_timeout)
{
    // Verify that there is enough hosts in the host list
    TEST_ASSERT(op_count <= MBED_CONF_APP_DNS_TEST_HOSTS_NUM)

    // Reset counters
    (*exp_ok) = 0;
    (*exp_no_mem) = 0;
    (*exp_dns_failure) = 0;
    (*exp_timeout) = 0;

    // Create callback semaphore and data
    rtos::Semaphore semaphore;
    dns_application_data *data = new dns_application_data[op_count];

    unsigned int count = 0;
    for (unsigned int i = 0; i < op_count; i++) {
        data[i].semaphore = &semaphore;
        nsapi_error_t err = net->gethostbyname_async(hosts[i], mbed::Callback<void(nsapi_error_t, SocketAddress *)>(hostbyname_cb, (void *) &data[i]));
        TEST_ASSERT(err >= 0 || err == NSAPI_ERROR_NO_MEMORY || err == NSAPI_ERROR_BUSY);
        if (err >= 0) {
            // Callback will be called
            count++;
        } else {
            // No memory to initiate DNS query, callback will not be called
            data[i].result = err;
        }
    }

    // Wait for callback(s) to complete
    for (unsigned int i = 0; i < count; i++) {
        semaphore.acquire();
    }

    // Print result
    for (unsigned int i = 0; i < op_count; i++) {
        TEST_ASSERT(data[i].result > 0 || data[i].result == NSAPI_ERROR_NO_MEMORY || data[i].result == NSAPI_ERROR_BUSY || data[i].result == NSAPI_ERROR_DNS_FAILURE || data[i].result == NSAPI_ERROR_TIMEOUT);
        if (data[i].result > 0) {
            (*exp_ok)++;
            tr_info("DNS: query \"%s\" => \"%s\"",
                    hosts[i], data[i].addr.get_ip_address());
        } else if (data[i].result == NSAPI_ERROR_DNS_FAILURE) {
            (*exp_dns_failure)++;
            tr_error("DNS: query \"%s\" => DNS failure", hosts[i]);
        } else if (data[i].result == NSAPI_ERROR_TIMEOUT) {
            (*exp_timeout)++;
            tr_error("DNS: query \"%s\" => timeout", hosts[i]);
        } else if (data[i].result == NSAPI_ERROR_NO_MEMORY) {
            (*exp_no_mem)++;
            tr_error("DNS: query \"%s\" => no memory", hosts[i]);
        } else if (data[i].result == NSAPI_ERROR_BUSY) {
            (*exp_no_mem)++;
            tr_error("DNS: query \"%s\" => busy", hosts[i]);
        }
    }

    delete[] data;
}

void do_gethostbyname(const char hosts[][DNS_TEST_HOST_LEN], unsigned int op_count, int *exp_ok, int *exp_no_mem, int *exp_dns_failure, int *exp_timeout)
{
    // Verify that there is enough hosts in the host list
    TEST_ASSERT(op_count <= MBED_CONF_APP_DNS_TEST_HOSTS_NUM)

    // Reset counters
    (*exp_ok) = 0;
    (*exp_no_mem) = 0;
    (*exp_dns_failure) = 0;
    (*exp_timeout) = 0;

    for (unsigned int i = 0; i < op_count; i++) {
        SocketAddress address;
        nsapi_error_t err = net->gethostbyname(hosts[i], &address);

        if (err == NSAPI_ERROR_OK) {
            (*exp_ok)++;
            tr_info("DNS: query \"%s\" => \"%s\"",
                    hosts[i], address.get_ip_address());
        } else if (err == NSAPI_ERROR_DNS_FAILURE) {
            (*exp_dns_failure)++;
            tr_error("DNS: query \"%s\" => DNS failure", hosts[i]);
        } else if (err == NSAPI_ERROR_TIMEOUT) {
            (*exp_timeout)++;
            tr_error("DNS: query \"%s\" => timeout", hosts[i]);
        } else if (err == NSAPI_ERROR_NO_MEMORY) {
            (*exp_no_mem)++;
            tr_error("DNS: query \"%s\" => no memory", hosts[i]);
        } else if (err == NSAPI_ERROR_BUSY) {
            (*exp_no_mem)++;
            tr_error("DNS: query \"%s\" => busy", hosts[i]);
        } else {
            tr_error("DNS: query \"%s\" => %d, unexpected answer", hosts[i], err);
            TEST_ASSERT(err == NSAPI_ERROR_OK || err == NSAPI_ERROR_NO_MEMORY || err == NSAPI_ERROR_BUSY || err == NSAPI_ERROR_DNS_FAILURE || err == NSAPI_ERROR_TIMEOUT);
        }
    }
}

NetworkInterface *get_interface()
{
    return net;
}

static void net_bringup()
{
    nsapi_dns_reset();
    MBED_ASSERT(MBED_CONF_APP_DNS_TEST_HOSTS_NUM >= MBED_CONF_NSAPI_DNS_CACHE_SIZE && MBED_CONF_APP_DNS_TEST_HOSTS_NUM >= MBED_CONF_APP_DNS_SIMULT_QUERIES + 1);

    net = NetworkInterface::get_default_instance();
    nsapi_error_t err = net->connect();
    TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, err);
    SocketAddress address;
    net->get_ip_address(&address);

#define MESH 3
#if MBED_CONF_TARGET_NETWORK_DEFAULT_INTERFACE_TYPE == MESH
    printf("Waiting for GLOBAL_UP\n");
    while (net->get_connection_status() != NSAPI_STATUS_GLOBAL_UP) {
        ThisThread::sleep_for(500);
    }
#endif
    printf("MBED: IP address is '%s'\n", address ? address.get_ip_address() : "null");
}

static void net_bringdown()
{
    NetworkInterface::get_default_instance()->disconnect();
    tr_info("MBED: ifdown");
}

// Test setup
utest::v1::status_t test_setup(const size_t number_of_cases)
{
    GREENTEA_SETUP(dns_global::TESTS_TIMEOUT, "default_auto");
    net_bringup();
    return verbose_test_setup_handler(number_of_cases);
}

void greentea_teardown(const size_t passed, const size_t failed, const failure_t failure)
{
    net_bringdown();
    return greentea_test_teardown_handler(passed, failed, failure);
}

Case cases[] = {
    Case("ASYNCHRONOUS_DNS", ASYNCHRONOUS_DNS),
    Case("ASYNCHRONOUS_DNS_SIMULTANEOUS", ASYNCHRONOUS_DNS_SIMULTANEOUS),
    Case("ASYNCHRONOUS_DNS_SIMULTANEOUS_CACHE", ASYNCHRONOUS_DNS_SIMULTANEOUS_CACHE),
#if NSAPI_PPP_AVAILABLE
    Case("SYNCHRONOUS_DNS_CACHE", SYNCHRONOUS_DNS_CACHE),
#endif
#ifndef MBED_CONF_CELLULAR_OFFLOAD_DNS_QUERIES
    Case("ASYNCHRONOUS_DNS_CACHE", ASYNCHRONOUS_DNS_CACHE),
#endif
#if !defined MBED_CONF_CELLULAR_OFFLOAD_DNS_QUERIES || MBED_CONF_CELLULAR_OFFLOAD_DNS_QUERIES > MBED_CONF_APP_DNS_TEST_HOSTS_NUM
    Case("ASYNCHRONOUS_DNS_NON_ASYNC_AND_ASYNC", ASYNCHRONOUS_DNS_NON_ASYNC_AND_ASYNC),
#endif
    Case("ASYNCHRONOUS_DNS_CANCEL", ASYNCHRONOUS_DNS_CANCEL),
#ifndef MBED_CONF_CELLULAR_OFFLOAD_DNS_QUERIES
    Case("ASYNCHRONOUS_DNS_EXTERNAL_EVENT_QUEUE", ASYNCHRONOUS_DNS_EXTERNAL_EVENT_QUEUE),
    Case("ASYNCHRONOUS_DNS_INVALID_HOST", ASYNCHRONOUS_DNS_INVALID_HOST),
    Case("ASYNCHRONOUS_DNS_TIMEOUTS", ASYNCHRONOUS_DNS_TIMEOUTS),
#endif
    Case("ASYNCHRONOUS_DNS_SIMULTANEOUS_REPEAT",  ASYNCHRONOUS_DNS_SIMULTANEOUS_REPEAT),
    Case("SYNCHRONOUS_DNS", SYNCHRONOUS_DNS),
    Case("SYNCHRONOUS_DNS_MULTIPLE", SYNCHRONOUS_DNS_MULTIPLE),
    Case("SYNCHRONOUS_DNS_INVALID", SYNCHRONOUS_DNS_INVALID),
    Case("SYNCHRONOUS_DNS_MULTI_IP", SYNCHRONOUS_DNS_MULTI_IP),
    Case("ASYNCHRONOUS_DNS_MULTI_IP", ASYNCHRONOUS_DNS_MULTI_IP),
};

Specification specification(test_setup, cases, greentea_teardown, greentea_continue_handlers);

int main()
{
    return !Harness::run(specification);
}

#endif // !defined(MBED_CONF_TARGET_NETWORK_DEFAULT_INTERFACE_TYPE) || (MBED_CONF_TARGET_NETWORK_DEFAULT_INTERFACE_TYPE == WIFI && !defined(MBED_CONF_NSAPI_DEFAULT_WIFI_SSID))
#endif // !defined(MBED_CONF_RTOS_PRESENT)
<|endoftext|>


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

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

#include "defaulthelpprovider.hxx"
#include "pcrcommon.hxx"
#include "modulepcr.hxx"

/** === begin UNO includes === **/
#ifndef _COM_SUN_STAR_UCB_ALREADYINITIALIZEDEXCEPTION_HPP_
#include <com/sun/star/ucb/AlreadyInitializedException.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_ILLEGALARGUMENTEXCEPTION_HPP_
#include <com/sun/star/lang/IllegalArgumentException.hpp>
#endif
#ifndef _COM_SUN_STAR_AWT_XVCLWINDOWPEER_HPP_
#include <com/sun/star/awt/XVclWindowPeer.hpp>
#endif
/** === end UNO includes === **/

#include <toolkit/helper/vclunohelper.hxx>
#include <vcl/window.hxx>
#include <tools/diagnose_ex.h>

//------------------------------------------------------------------------
extern "C" void SAL_CALL createRegistryInfo_DefaultHelpProvider()
{
    ::pcr::OAutoRegistration< ::pcr::DefaultHelpProvider > aAutoRegistration;
}

//........................................................................
namespace pcr
{
//........................................................................

    /** === begin UNO using === **/
    using ::com::sun::star::uno::Reference;
    using ::com::sun::star::uno::XComponentContext;
    using ::com::sun::star::inspection::XPropertyControl;
    using ::com::sun::star::uno::RuntimeException;
    using ::com::sun::star::uno::Sequence;
    using ::com::sun::star::uno::Any;
    using ::com::sun::star::uno::Exception;
    using ::com::sun::star::inspection::XObjectInspectorUI;
    using ::com::sun::star::uno::XInterface;
    using ::com::sun::star::ucb::AlreadyInitializedException;
    using ::com::sun::star::lang::IllegalArgumentException;
    using ::com::sun::star::uno::UNO_QUERY;
    using ::com::sun::star::uno::UNO_QUERY_THROW;
    using ::com::sun::star::awt::XWindow;
    using ::com::sun::star::awt::XVclWindowPeer;
    /** === end UNO using === **/

    //====================================================================
    //= DefaultHelpProvider
    //====================================================================
    //--------------------------------------------------------------------
    DefaultHelpProvider::DefaultHelpProvider( const Reference< XComponentContext >& _rxContext )
        :m_aContext( _rxContext )
        ,m_bConstructed( false )
    {
    }

    //--------------------------------------------------------------------
    DefaultHelpProvider::~DefaultHelpProvider()
    {
    }

    //------------------------------------------------------------------------
    ::rtl::OUString DefaultHelpProvider::getImplementationName_static(  ) throw(RuntimeException)
    {
        return ::rtl::OUString::createFromAscii( "org.openoffice.comp.extensions.DefaultHelpProvider");
    }

    //------------------------------------------------------------------------
    Sequence< ::rtl::OUString > DefaultHelpProvider::getSupportedServiceNames_static(  ) throw(RuntimeException)
    {
        Sequence< ::rtl::OUString > aSupported(1);
        aSupported[0] = ::rtl::OUString::createFromAscii( "com.sun.star.inspection.DefaultHelpProvider" );
        return aSupported;
    }

    //------------------------------------------------------------------------
    Reference< XInterface > SAL_CALL DefaultHelpProvider::Create( const Reference< XComponentContext >& _rxContext )
    {
        return *new DefaultHelpProvider( _rxContext );
    }

    //--------------------------------------------------------------------
    void SAL_CALL DefaultHelpProvider::focusGained( const Reference< XPropertyControl >& _Control ) throw (RuntimeException)
    {
        if ( !m_xInspectorUI.is() )
            throw RuntimeException( ::rtl::OUString(), *this );

        try
        {
            m_xInspectorUI->setHelpSectionText( impl_getHelpText_nothrow( _Control ) );
        }
        catch( const Exception& )
        {
            DBG_UNHANDLED_EXCEPTION();
        }
    }

    //--------------------------------------------------------------------
    void SAL_CALL DefaultHelpProvider::valueChanged( const Reference< XPropertyControl >& /*_Control*/ ) throw (RuntimeException)
    {
        // not interested in
    }

    //--------------------------------------------------------------------
    void SAL_CALL DefaultHelpProvider::initialize( const Sequence< Any >& _arguments ) throw (Exception, RuntimeException)
    {
        if ( m_bConstructed )
            throw AlreadyInitializedException();

        StlSyntaxSequence< Any > arguments( _arguments );
        if ( arguments.size() == 1 )
        {   // constructor: "create( XObjectInspectorUI )"
            Reference< XObjectInspectorUI > xUI( arguments[0], UNO_QUERY );
            create( xUI );
            return;
        }

        throw IllegalArgumentException( ::rtl::OUString(), *this, 0 );
    }

    //--------------------------------------------------------------------
    void DefaultHelpProvider::create( const Reference< XObjectInspectorUI >& _rxUI )
    {
        if ( !_rxUI.is() )
            throw IllegalArgumentException( ::rtl::OUString(), *this, 1 );

        try
        {
            m_xInspectorUI = _rxUI;
            m_xInspectorUI->registerControlObserver( this );
        }
        catch( const Exception& )
        {
            DBG_UNHANDLED_EXCEPTION();
        }

        m_bConstructed = true;
    }

    //--------------------------------------------------------------------
    Window* DefaultHelpProvider::impl_getVclControlWindow_nothrow( const Reference< XPropertyControl >& _rxControl )
    {
        Window* pControlWindow = NULL;
        OSL_PRECOND( _rxControl.is(), "DefaultHelpProvider::impl_getVclControlWindow_nothrow: illegal control!" );
        if ( !_rxControl.is() )
            return pControlWindow;

        try
        {
            Reference< XWindow > xControlWindow( _rxControl->getControlWindow(), UNO_QUERY_THROW );
            pControlWindow = VCLUnoHelper::GetWindow( xControlWindow );
        }
        catch( const Exception& )
        {
            DBG_UNHANDLED_EXCEPTION();
        }

        return pControlWindow;
    }

    //--------------------------------------------------------------------
    ::rtl::OUString DefaultHelpProvider::impl_getHelpText_nothrow( const Reference< XPropertyControl >& _rxControl )
    {
        ::rtl::OUString sHelpText;
        OSL_PRECOND( _rxControl.is(), "DefaultHelpProvider::impl_getHelpText_nothrow: illegal control!" );
        if ( !_rxControl.is() )
            return sHelpText;

        Window* pControlWindow( impl_getVclControlWindow_nothrow( _rxControl ) );
        OSL_ENSURE( pControlWindow, "DefaultHelpProvider::impl_getHelpText_nothrow: could not determine the VCL window!" );
        if ( !pControlWindow )
            return sHelpText;

        sHelpText = pControlWindow->GetHelpText();
        return sHelpText;
    }
//........................................................................
} // namespace pcr
//........................................................................
<commit_msg>INTEGRATION: CWS changefileheader (1.3.222); FILE MERGED 2008/04/01 12:29:48 thb 1.3.222.2: #i85898# Stripping all external header guards 2008/03/31 12:31:40 rt 1.3.222.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: defaulthelpprovider.cxx,v $
 * $Revision: 1.4 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

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

#include "defaulthelpprovider.hxx"
#include "pcrcommon.hxx"
#include "modulepcr.hxx"

/** === begin UNO includes === **/
#include <com/sun/star/ucb/AlreadyInitializedException.hpp>
#include <com/sun/star/lang/IllegalArgumentException.hpp>
#include <com/sun/star/awt/XVclWindowPeer.hpp>
/** === end UNO includes === **/

#include <toolkit/helper/vclunohelper.hxx>
#include <vcl/window.hxx>
#include <tools/diagnose_ex.h>

//------------------------------------------------------------------------
extern "C" void SAL_CALL createRegistryInfo_DefaultHelpProvider()
{
    ::pcr::OAutoRegistration< ::pcr::DefaultHelpProvider > aAutoRegistration;
}

//........................................................................
namespace pcr
{
//........................................................................

    /** === begin UNO using === **/
    using ::com::sun::star::uno::Reference;
    using ::com::sun::star::uno::XComponentContext;
    using ::com::sun::star::inspection::XPropertyControl;
    using ::com::sun::star::uno::RuntimeException;
    using ::com::sun::star::uno::Sequence;
    using ::com::sun::star::uno::Any;
    using ::com::sun::star::uno::Exception;
    using ::com::sun::star::inspection::XObjectInspectorUI;
    using ::com::sun::star::uno::XInterface;
    using ::com::sun::star::ucb::AlreadyInitializedException;
    using ::com::sun::star::lang::IllegalArgumentException;
    using ::com::sun::star::uno::UNO_QUERY;
    using ::com::sun::star::uno::UNO_QUERY_THROW;
    using ::com::sun::star::awt::XWindow;
    using ::com::sun::star::awt::XVclWindowPeer;
    /** === end UNO using === **/

    //====================================================================
    //= DefaultHelpProvider
    //====================================================================
    //--------------------------------------------------------------------
    DefaultHelpProvider::DefaultHelpProvider( const Reference< XComponentContext >& _rxContext )
        :m_aContext( _rxContext )
        ,m_bConstructed( false )
    {
    }

    //--------------------------------------------------------------------
    DefaultHelpProvider::~DefaultHelpProvider()
    {
    }

    //------------------------------------------------------------------------
    ::rtl::OUString DefaultHelpProvider::getImplementationName_static(  ) throw(RuntimeException)
    {
        return ::rtl::OUString::createFromAscii( "org.openoffice.comp.extensions.DefaultHelpProvider");
    }

    //------------------------------------------------------------------------
    Sequence< ::rtl::OUString > DefaultHelpProvider::getSupportedServiceNames_static(  ) throw(RuntimeException)
    {
        Sequence< ::rtl::OUString > aSupported(1);
        aSupported[0] = ::rtl::OUString::createFromAscii( "com.sun.star.inspection.DefaultHelpProvider" );
        return aSupported;
    }

    //------------------------------------------------------------------------
    Reference< XInterface > SAL_CALL DefaultHelpProvider::Create( const Reference< XComponentContext >& _rxContext )
    {
        return *new DefaultHelpProvider( _rxContext );
    }

    //--------------------------------------------------------------------
    void SAL_CALL DefaultHelpProvider::focusGained( const Reference< XPropertyControl >& _Control ) throw (RuntimeException)
    {
        if ( !m_xInspectorUI.is() )
            throw RuntimeException( ::rtl::OUString(), *this );

        try
        {
            m_xInspectorUI->setHelpSectionText( impl_getHelpText_nothrow( _Control ) );
        }
        catch( const Exception& )
        {
            DBG_UNHANDLED_EXCEPTION();
        }
    }

    //--------------------------------------------------------------------
    void SAL_CALL DefaultHelpProvider::valueChanged( const Reference< XPropertyControl >& /*_Control*/ ) throw (RuntimeException)
    {
        // not interested in
    }

    //--------------------------------------------------------------------
    void SAL_CALL DefaultHelpProvider::initialize( const Sequence< Any >& _arguments ) throw (Exception, RuntimeException)
    {
        if ( m_bConstructed )
            throw AlreadyInitializedException();

        StlSyntaxSequence< Any > arguments( _arguments );
        if ( arguments.size() == 1 )
        {   // constructor: "create( XObjectInspectorUI )"
            Reference< XObjectInspectorUI > xUI( arguments[0], UNO_QUERY );
            create( xUI );
            return;
        }

        throw IllegalArgumentException( ::rtl::OUString(), *this, 0 );
    }

    //--------------------------------------------------------------------
    void DefaultHelpProvider::create( const Reference< XObjectInspectorUI >& _rxUI )
    {
        if ( !_rxUI.is() )
            throw IllegalArgumentException( ::rtl::OUString(), *this, 1 );

        try
        {
            m_xInspectorUI = _rxUI;
            m_xInspectorUI->registerControlObserver( this );
        }
        catch( const Exception& )
        {
            DBG_UNHANDLED_EXCEPTION();
        }

        m_bConstructed = true;
    }

    //--------------------------------------------------------------------
    Window* DefaultHelpProvider::impl_getVclControlWindow_nothrow( const Reference< XPropertyControl >& _rxControl )
    {
        Window* pControlWindow = NULL;
        OSL_PRECOND( _rxControl.is(), "DefaultHelpProvider::impl_getVclControlWindow_nothrow: illegal control!" );
        if ( !_rxControl.is() )
            return pControlWindow;

        try
        {
            Reference< XWindow > xControlWindow( _rxControl->getControlWindow(), UNO_QUERY_THROW );
            pControlWindow = VCLUnoHelper::GetWindow( xControlWindow );
        }
        catch( const Exception& )
        {
            DBG_UNHANDLED_EXCEPTION();
        }

        return pControlWindow;
    }

    //--------------------------------------------------------------------
    ::rtl::OUString DefaultHelpProvider::impl_getHelpText_nothrow( const Reference< XPropertyControl >& _rxControl )
    {
        ::rtl::OUString sHelpText;
        OSL_PRECOND( _rxControl.is(), "DefaultHelpProvider::impl_getHelpText_nothrow: illegal control!" );
        if ( !_rxControl.is() )
            return sHelpText;

        Window* pControlWindow( impl_getVclControlWindow_nothrow( _rxControl ) );
        OSL_ENSURE( pControlWindow, "DefaultHelpProvider::impl_getHelpText_nothrow: could not determine the VCL window!" );
        if ( !pControlWindow )
            return sHelpText;

        sHelpText = pControlWindow->GetHelpText();
        return sHelpText;
    }
//........................................................................
} // namespace pcr
//........................................................................
<|endoftext|>


<commit_before>#include "sprite.h"

sprite::sprite(boolean isSolid, int xPosition, int yPosition)
{
    xPosition=xPosition;
    yPosition=yPosition;
    isSolid=isSolid;
}
<commit_msg>Cleaning up redundant files.<commit_after><|endoftext|>