<commit_before>#include <switch.h>
#include <compress.h>

// Instead of relying on continuations and gotos for reentrancy
// which would require a function call, we should probably unpack one block/time
// so that we we 'll be able to operate on lists of documents and positions directly
// This also means that caches will remain hot for as long as we unpack a block
struct Indexer
{
        IOBuffer documentIdsBuf, hitsBuf;
        Switch::vector<std::pair<uint32_t, std::pair<uint32_t, uint32_t>>> skiplist;
        uint32_t totalDocuments{0};
        uint32_t documentsChunkSize{0}, hitsChunkSize{0};
        uint32_t skiplistThreshold{80 * 1024};
        static constexpr uint8_t blockCapacity{32};
        uint8_t blockSize{blockCapacity};
        IOBuffer blockDocumentIdsBuf, blockHitsBuf;
        uint32_t prevBlockLastDocumentId{0};
        uint32_t blockHitsBase;
	uint32_t lastDocumentId{0};

        struct
        {
                uint32_t hitsCnt;
                uint32_t hitsBase;
		uint16_t lastPos;
        } curDocument;

        void begin_document(const uint32_t id)
        {
                if (blockSize == blockCapacity)
                {
			if (prevBlockLastDocumentId)
                        {
                                const auto delta = lastDocumentId - prevBlockLastDocumentId;
                                const auto blockHitsChunkLen = hitsBuf.size() - blockHitsBase;

                                documentIdsBuf.SerializeVarUint32(lastBlockIdDelta);
                                documentIdsBuf.SerializeVarUint32(blockHitsChunkLen);

                                documentsChunkSize += blockLen;
                                hitsChunkSize += blockHitsChunkLen;
                        }

                        blockSize = 0;
                        blockHitsBase = hitsBuf.size();
                        blockHitsBuf.clear();

                        if (documentsChunkSize > skiplistThreshold)
                        {
                                skiplist.push_back({id, {documentsChunkSize, hitsChunkSize}});
                                skiplistThreshold = documentsChunkSize + 80 * 1024;
                        }
                }

		// We could use Rice-k or Gamma encoding ( see http://static.googleusercontent.com/media/research.google.com/en//people/jeff/WSDM09-keynote.pdf )
		// or we could use PFor (see Lucene, and Lemire's repos)

                curDocument.hitsCnt = 0;
                curDocument.hitsBase = hitsBuf.size();
		curDocument.lastPos = 0;
		curBlockDocumentsCnt = 0;

		const auto delta = id - lastDocumentId;

		documentIdsBuf.SerializeVarUint32(delta);
		lastDocumentId = id;
        }

        void register_hit(const uint32_t position, const uint32_t attributes)
        {
                // need 2 bits, do we have a position, do we have attributes?
                // encode:
                // 	0: no position, no attributes
                //
                // UPDATE: for now do something simple, figure out something that yields better compression once we get the baseline to work
                // It is important to consider situations where position is, well, 0
                // what happens then? we use delta encoding so we need to do something about it
                // UPDATE: when we decode words, if word is the same as the last one, that's not a word -- so ignore it
                const auto delta = position - curDocument.lastPos;

                curDocument.lastPos = position;
                if (!attributes)
                {
                        // Just the position
                        hitsBuf.SerializeVarUint32(delta << 1);
                }
                else
                {
                        hitsBuf.SerializeVarUint32((delta << 1) | 1);
                        hitsBuf.SerializeVarUint32(attributes);
                }

                ++curDocument.hitsCnt;
        }

        void end_document() noexcept
        {
        }
}

int
main()
{

	return 0;
}
<commit_msg>Updates<commit_after><|endoftext|>


<commit_before>
#include "tools/generate_configuration.hpp"

#include <filesystem>
#include <iomanip>
#include <limits>
#include <string>

#include "astronomy/epoch.hpp"
#include "astronomy/frames.hpp"
#include "geometry/named_quantities.hpp"
#include "glog/logging.h"
#include "physics/degrees_of_freedom.hpp"
#include "physics/solar_system.hpp"
#include "quantities/constants.hpp"
#include "quantities/named_quantities.hpp"
#include "quantities/parser.hpp"
#include "quantities/quantities.hpp"
#include "quantities/si.hpp"
#include "serialization/astronomy.pb.h"

namespace principia {

using astronomy::ICRFJ2000Equator;
using astronomy::J2000;
using astronomy::JulianDate;
using physics::DegreesOfFreedom;
using physics::SolarSystem;
using quantities::DebugString;
using quantities::GravitationalParameter;
using quantities::Length;
using quantities::Mass;
using quantities::ParseQuantity;
using quantities::Pow;
using quantities::constants::GravitationalConstant;
using quantities::si::Kilo;
using quantities::si::Metre;
using quantities::si::Second;

namespace {
constexpr char cfg[] = "cfg";
constexpr char proto_txt[] = "proto.txt";
}  // namespace

namespace tools {
namespace internal_generate_configuration {

std::string NormalizeLength(std::string const& s) {
  // If the string contains an R, it's expressed using astronomical radii.
  // Convert to kilometers.
  if (s.find('R') == std::string::npos) {
    return s;
  } else {
    Length const length = ParseQuantity<Length>(s);
    std::ostringstream stream;
    stream << std::scientific
           << std::setprecision(6)  // Accuracy of the conventional values.
           << length / Kilo(Metre) << " km";
    return stream.str();
  }
}

void GenerateConfiguration(std::string const& game_epoch,
                           std::string const& gravity_model_stem,
                           std::string const& initial_state_stem,
                           std::string const& numerics_blueprint_stem,
                           std::string const& needs) {
  std::filesystem::path const directory =
      SOLUTION_DIR / "astronomy";
  SolarSystem<ICRFJ2000Equator> solar_system(
      (directory / gravity_model_stem).replace_extension(proto_txt),
      (directory / initial_state_stem).replace_extension(proto_txt),
      /*ignore_frame=*/true);

  std::ofstream gravity_model_cfg(
      (directory / gravity_model_stem).replace_extension(cfg));
  CHECK(gravity_model_cfg.good());
  gravity_model_cfg << "principia_gravity_model:NEEDS[" << needs << "] {\n";
  for (std::string const& name : solar_system.names()) {
    serialization::GravityModel::Body const& body =
        solar_system.gravity_model_message(name);
    gravity_model_cfg << "  body {\n";
    gravity_model_cfg << "    name                    = "
                      << name << "\n";
    if (body.has_gravitational_parameter()) {
      gravity_model_cfg << "    gravitational_parameter = "
                        << body.gravitational_parameter() << "\n";
    } else {
      // If the mass was provided, convert to a gravitational parameter.
      Mass const mass = ParseQuantity<Mass>(body.mass());
      GravitationalParameter const gravitational_parameter =
          GravitationalConstant * mass;
      gravity_model_cfg << "    gravitational_parameter = "
                        << std::scientific
                        << std::setprecision(7)  // Acuracy of G.
                        << gravitational_parameter /
                               (Pow<3>(Kilo(Metre)) / Pow<2>(Second))
                        << " km^3/s^2\n";
    }
    if (body.has_reference_instant()) {
      gravity_model_cfg << "    reference_instant       = "
                        << body.reference_instant() << "\n";
    }
    if (body.has_mean_radius()) {
      gravity_model_cfg << "    mean_radius             = "
                        << NormalizeLength(body.mean_radius()) << "\n";
    }
    if (body.has_axis_right_ascension()) {
      gravity_model_cfg << "    axis_right_ascension    = "
                        << body.axis_right_ascension() << "\n";
    }
    if (body.has_axis_declination()) {
      gravity_model_cfg << "    axis_declination        = "
                        << body.axis_declination() << "\n";
    }
    if (body.has_reference_angle()) {
      gravity_model_cfg << "    reference_angle         = "
                        << body.reference_angle() << "\n";
    }
    if (body.has_angular_frequency()) {
      gravity_model_cfg << "    angular_frequency       = "
                        << body.angular_frequency() << "\n";
    }
    if (body.has_j2()) {
      gravity_model_cfg << "    j2                      = "
                        << std::scientific
                        << std::setprecision(
                               std::numeric_limits<double>::max_digits10)
                        << body.j2() << "\n";
    }
    if (body.has_reference_radius()) {
      gravity_model_cfg << "    reference_radius        = "
                        << NormalizeLength(body.reference_radius()) << "\n";
    }
    gravity_model_cfg << "  }\n";
  }
  gravity_model_cfg << "}\n";

  std::ofstream initial_state_cfg(
      (directory / initial_state_stem).replace_extension(cfg));
  CHECK(initial_state_cfg.good());
  initial_state_cfg << "principia_initial_state:NEEDS[" << needs << "] {\n";
  initial_state_cfg << "  game_epoch = " << game_epoch << "\n";
  initial_state_cfg << "  solar_system_epoch = "
                    << solar_system.epoch_literal() << "\n";

  if (solar_system.has_keplerian_initial_state_message(
          solar_system.names().front())) {
    // If the configuration is given in keplerian elements, convert it to
    // cartesian coordinates here.  This avoids depending on conversions done
    // by the game.
    auto hierarchical_system = solar_system.MakeHierarchicalSystem();
    auto const barycentric_system =
        hierarchical_system->ConsumeBarycentricSystem();

    auto displacement = [](DegreesOfFreedom<ICRFJ2000Equator> const& dof) {
      return (dof.position() - ICRFJ2000Equator::origin).coordinates();
    };
    auto velocity = [](DegreesOfFreedom<ICRFJ2000Equator> const& dof) {
      return dof.velocity().coordinates();
    };

    for (int i = 0; i < barycentric_system.bodies.size(); ++i) {
      auto const& body = barycentric_system.bodies[i];
      auto const& dof = barycentric_system.degrees_of_freedom[i];
      initial_state_cfg << "  body {\n";
      initial_state_cfg << "    name = " << body->name() << "\n";
      initial_state_cfg << "    x    = " << displacement(dof).x << "\n";
      initial_state_cfg << "    y    = " << displacement(dof).y << "\n";
      initial_state_cfg << "    z    = " << displacement(dof).z << "\n";
      initial_state_cfg << "    vx   = " << velocity(dof).x << "\n";
      initial_state_cfg << "    vy   = " << velocity(dof).y << "\n";
      initial_state_cfg << "    vz   = " << velocity(dof).z << "\n";
      initial_state_cfg << "  }\n";
    }
  } else {
    for (std::string const& name : solar_system.names()) {
      serialization::InitialState::Cartesian::Body const& body =
          solar_system.cartesian_initial_state_message(name);
      initial_state_cfg << "  body {\n";
      initial_state_cfg << "    name = " << name << "\n";
      initial_state_cfg << "    x    = " << body.x() << "\n";
      initial_state_cfg << "    y    = " << body.y() << "\n";
      initial_state_cfg << "    z    = " << body.z() << "\n";
      initial_state_cfg << "    vx   = " << body.vx() << "\n";
      initial_state_cfg << "    vy   = " << body.vy() << "\n";
      initial_state_cfg << "    vz   = " << body.vz() << "\n";
      initial_state_cfg << "  }\n";
    }
  }
  initial_state_cfg << "}\n";

  // Parse the numerics blueprint file here, it doesn't belong in class
  // SolarSystem.
  std::filesystem::path numerics_blueprint_filename =
      (directory / numerics_blueprint_stem).replace_extension(proto_txt);
  serialization::SolarSystemFile numerics_blueprint;
  std::ifstream numerics_blueprint_ifstream(numerics_blueprint_filename);
  CHECK(numerics_blueprint_ifstream.good());
  google::protobuf::io::IstreamInputStream numerics_blueprint_zcs(
                                               &numerics_blueprint_ifstream);
  CHECK(google::protobuf::TextFormat::Parse(&numerics_blueprint_zcs,
                                            &numerics_blueprint));
  CHECK(numerics_blueprint.has_numerics_blueprint());
  auto const& ephemeris = numerics_blueprint.numerics_blueprint().ephemeris();
  auto const& history = numerics_blueprint.numerics_blueprint().history();
  auto const& psychohistory =
      numerics_blueprint.numerics_blueprint().psychohistory();

  std::ofstream numerics_blueprint_cfg(
      (directory / numerics_blueprint_stem).replace_extension(cfg));
  CHECK(numerics_blueprint_cfg.good());
  numerics_blueprint_cfg <<
      "principia_numerics_blueprint:NEEDS[" << needs << "] {\n";

  numerics_blueprint_cfg << "  ephemeris {\n";
  numerics_blueprint_cfg
      << "    fixed_step_size_integrator = "
      << serialization::FixedStepSizeIntegrator::Kind_Name(
            ephemeris.integrator()) << "\n";
  numerics_blueprint_cfg << "    integration_step_size = " << ephemeris.step()
                         << "\n";
  numerics_blueprint_cfg << "  }\n";

  numerics_blueprint_cfg << "  history {\n";
  numerics_blueprint_cfg
      << "    fixed_step_size_integrator = "
      << serialization::FixedStepSizeIntegrator::Kind_Name(
            history.integrator()) << "\n";
  numerics_blueprint_cfg << "    integration_step_size = " << history.step()
                         << "\n";
  numerics_blueprint_cfg << "  }\n";

  numerics_blueprint_cfg << "  psychohistory {\n";
  numerics_blueprint_cfg
      << "    adaptive_step_size_integrator = "
      << serialization::AdaptiveStepSizeIntegrator::Kind_Name(
             psychohistory.integrator()) << "\n";
  numerics_blueprint_cfg << "    length_integration_tolerance = "
                         << psychohistory.length_integration_tolerance()
                         << "\n";
  numerics_blueprint_cfg << "    speed_integration_tolerance = "
                         << psychohistory.speed_integration_tolerance()
                         << "\n";
  numerics_blueprint_cfg << "  }\n";

  numerics_blueprint_cfg << "}\n";
}

}  // namespace internal_generate_configuration
}  // namespace tools
}  // namespace principia
<commit_msg>Print all the digits.<commit_after>
#include "tools/generate_configuration.hpp"

#include <filesystem>
#include <iomanip>
#include <limits>
#include <string>

#include "astronomy/epoch.hpp"
#include "astronomy/frames.hpp"
#include "geometry/named_quantities.hpp"
#include "glog/logging.h"
#include "physics/degrees_of_freedom.hpp"
#include "physics/solar_system.hpp"
#include "quantities/constants.hpp"
#include "quantities/named_quantities.hpp"
#include "quantities/parser.hpp"
#include "quantities/quantities.hpp"
#include "quantities/si.hpp"
#include "serialization/astronomy.pb.h"

namespace principia {

using astronomy::ICRFJ2000Equator;
using astronomy::J2000;
using astronomy::JulianDate;
using physics::DegreesOfFreedom;
using physics::SolarSystem;
using quantities::DebugString;
using quantities::GravitationalParameter;
using quantities::Length;
using quantities::Mass;
using quantities::ParseQuantity;
using quantities::Pow;
using quantities::constants::GravitationalConstant;
using quantities::si::Kilo;
using quantities::si::Metre;
using quantities::si::Second;

namespace {
constexpr char cfg[] = "cfg";
constexpr char proto_txt[] = "proto.txt";
}  // namespace

namespace tools {
namespace internal_generate_configuration {

std::string NormalizeLength(std::string const& s) {
  // If the string contains an R, it's expressed using astronomical radii.
  // Convert to kilometers.
  if (s.find('R') == std::string::npos) {
    return s;
  } else {
    Length const length = ParseQuantity<Length>(s);
    std::ostringstream stream;
    stream << std::scientific
           << std::setprecision(std::numeric_limits<double>::max_digits10)
           << length / Kilo(Metre) << " km";
    return stream.str();
  }
}

void GenerateConfiguration(std::string const& game_epoch,
                           std::string const& gravity_model_stem,
                           std::string const& initial_state_stem,
                           std::string const& numerics_blueprint_stem,
                           std::string const& needs) {
  std::filesystem::path const directory =
      SOLUTION_DIR / "astronomy";
  SolarSystem<ICRFJ2000Equator> solar_system(
      (directory / gravity_model_stem).replace_extension(proto_txt),
      (directory / initial_state_stem).replace_extension(proto_txt),
      /*ignore_frame=*/true);

  std::ofstream gravity_model_cfg(
      (directory / gravity_model_stem).replace_extension(cfg));
  CHECK(gravity_model_cfg.good());
  gravity_model_cfg << "principia_gravity_model:NEEDS[" << needs << "] {\n";
  for (std::string const& name : solar_system.names()) {
    serialization::GravityModel::Body const& body =
        solar_system.gravity_model_message(name);
    gravity_model_cfg << "  body {\n";
    gravity_model_cfg << "    name                    = "
                      << name << "\n";
    if (body.has_gravitational_parameter()) {
      gravity_model_cfg << "    gravitational_parameter = "
                        << body.gravitational_parameter() << "\n";
    } else {
      // If the mass was provided, convert to a gravitational parameter.
      Mass const mass = ParseQuantity<Mass>(body.mass());
      GravitationalParameter const gravitational_parameter =
          GravitationalConstant * mass;
      gravity_model_cfg << "    gravitational_parameter = "
                        << std::scientific
                        << std::setprecision(
                               std::numeric_limits<double>::max_digits10)
                        << gravitational_parameter /
                               (Pow<3>(Kilo(Metre)) / Pow<2>(Second))
                        << " km^3/s^2\n";
    }
    if (body.has_reference_instant()) {
      gravity_model_cfg << "    reference_instant       = "
                        << body.reference_instant() << "\n";
    }
    if (body.has_mean_radius()) {
      gravity_model_cfg << "    mean_radius             = "
                        << NormalizeLength(body.mean_radius()) << "\n";
    }
    if (body.has_axis_right_ascension()) {
      gravity_model_cfg << "    axis_right_ascension    = "
                        << body.axis_right_ascension() << "\n";
    }
    if (body.has_axis_declination()) {
      gravity_model_cfg << "    axis_declination        = "
                        << body.axis_declination() << "\n";
    }
    if (body.has_reference_angle()) {
      gravity_model_cfg << "    reference_angle         = "
                        << body.reference_angle() << "\n";
    }
    if (body.has_angular_frequency()) {
      gravity_model_cfg << "    angular_frequency       = "
                        << body.angular_frequency() << "\n";
    }
    if (body.has_j2()) {
      gravity_model_cfg << "    j2                      = "
                        << std::scientific
                        << std::setprecision(
                               std::numeric_limits<double>::max_digits10)
                        << body.j2() << "\n";
    }
    if (body.has_reference_radius()) {
      gravity_model_cfg << "    reference_radius        = "
                        << NormalizeLength(body.reference_radius()) << "\n";
    }
    gravity_model_cfg << "  }\n";
  }
  gravity_model_cfg << "}\n";

  std::ofstream initial_state_cfg(
      (directory / initial_state_stem).replace_extension(cfg));
  CHECK(initial_state_cfg.good());
  initial_state_cfg << "principia_initial_state:NEEDS[" << needs << "] {\n";
  initial_state_cfg << "  game_epoch = " << game_epoch << "\n";
  initial_state_cfg << "  solar_system_epoch = "
                    << solar_system.epoch_literal() << "\n";

  if (solar_system.has_keplerian_initial_state_message(
          solar_system.names().front())) {
    // If the configuration is given in keplerian elements, convert it to
    // cartesian coordinates here.  This avoids depending on conversions done
    // by the game.
    auto hierarchical_system = solar_system.MakeHierarchicalSystem();
    auto const barycentric_system =
        hierarchical_system->ConsumeBarycentricSystem();

    auto displacement = [](DegreesOfFreedom<ICRFJ2000Equator> const& dof) {
      return (dof.position() - ICRFJ2000Equator::origin).coordinates();
    };
    auto velocity = [](DegreesOfFreedom<ICRFJ2000Equator> const& dof) {
      return dof.velocity().coordinates();
    };

    for (int i = 0; i < barycentric_system.bodies.size(); ++i) {
      auto const& body = barycentric_system.bodies[i];
      auto const& dof = barycentric_system.degrees_of_freedom[i];
      initial_state_cfg << "  body {\n";
      initial_state_cfg << "    name = " << body->name() << "\n";
      initial_state_cfg << "    x    = " << displacement(dof).x << "\n";
      initial_state_cfg << "    y    = " << displacement(dof).y << "\n";
      initial_state_cfg << "    z    = " << displacement(dof).z << "\n";
      initial_state_cfg << "    vx   = " << velocity(dof).x << "\n";
      initial_state_cfg << "    vy   = " << velocity(dof).y << "\n";
      initial_state_cfg << "    vz   = " << velocity(dof).z << "\n";
      initial_state_cfg << "  }\n";
    }
  } else {
    for (std::string const& name : solar_system.names()) {
      serialization::InitialState::Cartesian::Body const& body =
          solar_system.cartesian_initial_state_message(name);
      initial_state_cfg << "  body {\n";
      initial_state_cfg << "    name = " << name << "\n";
      initial_state_cfg << "    x    = " << body.x() << "\n";
      initial_state_cfg << "    y    = " << body.y() << "\n";
      initial_state_cfg << "    z    = " << body.z() << "\n";
      initial_state_cfg << "    vx   = " << body.vx() << "\n";
      initial_state_cfg << "    vy   = " << body.vy() << "\n";
      initial_state_cfg << "    vz   = " << body.vz() << "\n";
      initial_state_cfg << "  }\n";
    }
  }
  initial_state_cfg << "}\n";

  // Parse the numerics blueprint file here, it doesn't belong in class
  // SolarSystem.
  std::filesystem::path numerics_blueprint_filename =
      (directory / numerics_blueprint_stem).replace_extension(proto_txt);
  serialization::SolarSystemFile numerics_blueprint;
  std::ifstream numerics_blueprint_ifstream(numerics_blueprint_filename);
  CHECK(numerics_blueprint_ifstream.good());
  google::protobuf::io::IstreamInputStream numerics_blueprint_zcs(
                                               &numerics_blueprint_ifstream);
  CHECK(google::protobuf::TextFormat::Parse(&numerics_blueprint_zcs,
                                            &numerics_blueprint));
  CHECK(numerics_blueprint.has_numerics_blueprint());
  auto const& ephemeris = numerics_blueprint.numerics_blueprint().ephemeris();
  auto const& history = numerics_blueprint.numerics_blueprint().history();
  auto const& psychohistory =
      numerics_blueprint.numerics_blueprint().psychohistory();

  std::ofstream numerics_blueprint_cfg(
      (directory / numerics_blueprint_stem).replace_extension(cfg));
  CHECK(numerics_blueprint_cfg.good());
  numerics_blueprint_cfg <<
      "principia_numerics_blueprint:NEEDS[" << needs << "] {\n";

  numerics_blueprint_cfg << "  ephemeris {\n";
  numerics_blueprint_cfg
      << "    fixed_step_size_integrator = "
      << serialization::FixedStepSizeIntegrator::Kind_Name(
            ephemeris.integrator()) << "\n";
  numerics_blueprint_cfg << "    integration_step_size = " << ephemeris.step()
                         << "\n";
  numerics_blueprint_cfg << "  }\n";

  numerics_blueprint_cfg << "  history {\n";
  numerics_blueprint_cfg
      << "    fixed_step_size_integrator = "
      << serialization::FixedStepSizeIntegrator::Kind_Name(
            history.integrator()) << "\n";
  numerics_blueprint_cfg << "    integration_step_size = " << history.step()
                         << "\n";
  numerics_blueprint_cfg << "  }\n";

  numerics_blueprint_cfg << "  psychohistory {\n";
  numerics_blueprint_cfg
      << "    adaptive_step_size_integrator = "
      << serialization::AdaptiveStepSizeIntegrator::Kind_Name(
             psychohistory.integrator()) << "\n";
  numerics_blueprint_cfg << "    length_integration_tolerance = "
                         << psychohistory.length_integration_tolerance()
                         << "\n";
  numerics_blueprint_cfg << "    speed_integration_tolerance = "
                         << psychohistory.speed_integration_tolerance()
                         << "\n";
  numerics_blueprint_cfg << "  }\n";

  numerics_blueprint_cfg << "}\n";
}

}  // namespace internal_generate_configuration
}  // namespace tools
}  // namespace principia
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: tcommuni.cxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: hr $ $Date: 2003-03-18 16:03:49 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2002
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2002 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2002 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _SV_CONFIG_HXX //autogen
#include <vcl/config.hxx>
#endif
#ifndef _SV_SVAPP_HXX //autogen
#include <vcl/svapp.hxx>
#endif
#ifndef _TOOLS_TIME_HXX //autogen
#include <tools/time.hxx>
#endif
#ifndef _DEBUG_HXX //autogen
#include <tools/debug.hxx>
#endif
#ifndef _VOS_PROCESS_HXX_
#include <vos/process.hxx>
#endif

#ifndef _BASIC_TTRESHLP_HXX
#include <basic/ttstrhlp.hxx>
#endif

#include "rcontrol.hxx"
#include "tcommuni.hxx"
#include <basic/testtool.hxx>
#include <basic/process.hxx>

CommunicationManagerClientViaSocketTT::CommunicationManagerClientViaSocketTT()
: CommunicationManagerClientViaSocket( TRUE )
, aAppPath()
, aAppParams()
, pProcess( NULL )
{
}

BOOL CommunicationManagerClientViaSocketTT::StartCommunication()
{
    bApplicationStarted = FALSE;
    return CommunicationManagerClientViaSocket::StartCommunication( ByteString( GetHostConfig(), RTL_TEXTENCODING_UTF8 ), GetTTPortConfig() );
}

BOOL CommunicationManagerClientViaSocketTT::StartCommunication( String aApp, String aParams )
{
    aAppPath = aApp;
    aAppParams = aParams;
    return StartCommunication();
}

BOOL CommunicationManagerClientViaSocketTT::RetryConnect()
{
    if ( !bApplicationStarted )
    {
        // Die App ist wohl nicht da. Starten wir sie mal.
        if ( aAppPath.Len() )
        {
            delete pProcess;

            pProcess = new Process();
            pProcess->SetImage( aAppPath, aAppParams );

            BOOL bSucc = pProcess->Start();
            bApplicationStarted = TRUE;

            if ( bSucc )
            {
                aFirstRetryCall = Time() + Time( 0, 1 );    // Max eine Minute Zeit
                for ( int i = 10 ; i-- ; )
                    GetpApp()->Reschedule();
            }
            return bSucc;
        }
        return FALSE;
    }
    else
    {
        if ( aFirstRetryCall > Time() )
        {
            for ( int i = 10 ; i-- ; )
                GetpApp()->Reschedule();
            return TRUE;
        }
        else
            return FALSE;
    }
}

#define GETSET(aVar, KeyName, Dafault)                 \
    aVar = aConf.ReadKey(KeyName,"No Entry");          \
    if ( aVar.CompareTo("No Entry") == COMPARE_EQUAL ) \
    {                                                  \
        aVar = ByteString(Dafault);                    \
        aConf.WriteKey(KeyName, aVar);                 \
    }

String GetHostConfig()
{
    String aHostToTalk;

    for ( int i = 0 ; i < Application::GetCommandLineParamCount() ; i++ )
    {
        if ( Application::GetCommandLineParam( i ).Copy(0,6).CompareIgnoreCaseToAscii("-host=") == COMPARE_EQUAL
#ifndef UNX
          || Application::GetCommandLineParam( i ).Copy(0,6).CompareIgnoreCaseToAscii("/host=") == COMPARE_EQUAL
#endif
          )
            return Application::GetCommandLineParam( i ).Copy(6);
    }

    ByteString abHostToTalk;
    Config aConf(Config::GetConfigName( Config::GetDefDirectory(), CUniString("testtool") ));
    aConf.SetGroup("Communication");

    GETSET( abHostToTalk, "Host", DEFAULT_HOST );
    return UniString( abHostToTalk, RTL_TEXTENCODING_UTF8 );
}

ULONG GetTTPortConfig()
{
    String aPortToTalk;

    for ( int i = 0 ; i < Application::GetCommandLineParamCount() ; i++ )
    {
        if ( Application::GetCommandLineParam( i ).Copy(0,6).CompareIgnoreCaseToAscii("-port=") == COMPARE_EQUAL
#ifndef UNX
          || Application::GetCommandLineParam( i ).Copy(0,6).CompareIgnoreCaseToAscii("/port=") == COMPARE_EQUAL
#endif
          )
        {
            aPortToTalk = Application::GetCommandLineParam( i ).Copy(6);
            return aPortToTalk.ToInt64();
        }
    }

    ByteString abPortToTalk;
    Config aConf(Config::GetConfigName( Config::GetDefDirectory(), CUniString("testtool") ));
    aConf.SetGroup("Communication");

    GETSET( abPortToTalk, "TTPort", ByteString::CreateFromInt32( TESTTOOL_DEFAULT_PORT ) );
    return abPortToTalk.ToInt64();
}

ULONG GetUnoPortConfig()
{
    String aPortToTalk;

    for ( int i = 0 ; i < Application::GetCommandLineParamCount() ; i++ )
    {
        if ( Application::GetCommandLineParam( i ).Copy(0,9).CompareIgnoreCaseToAscii("-unoport=") == COMPARE_EQUAL
#ifndef UNX
          || Application::GetCommandLineParam( i ).Copy(0,9).CompareIgnoreCaseToAscii("/unoport=") == COMPARE_EQUAL
#endif
          )
        {
            aPortToTalk = Application::GetCommandLineParam( i ).Copy(6);
            return aPortToTalk.ToInt64();
        }
    }

    ByteString abPortToTalk;
    Config aConf(Config::GetConfigName( Config::GetDefDirectory(), CUniString("testtool") ));
    aConf.SetGroup("Communication");

    GETSET( abPortToTalk, "UnoPort", ByteString::CreateFromInt32( UNO_DEFAULT_PORT ) );
    return abPortToTalk.ToInt64();
}
<commit_msg>INTEGRATION: CWS vclcleanup02 (1.2.50); FILE MERGED 2003/12/10 15:55:59 mt 1.2.50.1: #i23061# VCL cleanup, removed headers, methods and types...<commit_after>/*************************************************************************
 *
 *  $RCSfile: tcommuni.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: vg $ $Date: 2004-01-06 17:09:15 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2002
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2002 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2002 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _CONFIG_HXX
#include <tools/config.hxx>
#endif
#ifndef _SV_SVAPP_HXX //autogen
#include <vcl/svapp.hxx>
#endif
#ifndef _TOOLS_TIME_HXX //autogen
#include <tools/time.hxx>
#endif
#ifndef _DEBUG_HXX //autogen
#include <tools/debug.hxx>
#endif
#ifndef _VOS_PROCESS_HXX_
#include <vos/process.hxx>
#endif

#ifndef _BASIC_TTRESHLP_HXX
#include <basic/ttstrhlp.hxx>
#endif

#include "rcontrol.hxx"
#include "tcommuni.hxx"
#include <basic/testtool.hxx>
#include <basic/process.hxx>

CommunicationManagerClientViaSocketTT::CommunicationManagerClientViaSocketTT()
: CommunicationManagerClientViaSocket( TRUE )
, aAppPath()
, aAppParams()
, pProcess( NULL )
{
}

BOOL CommunicationManagerClientViaSocketTT::StartCommunication()
{
    bApplicationStarted = FALSE;
    return CommunicationManagerClientViaSocket::StartCommunication( ByteString( GetHostConfig(), RTL_TEXTENCODING_UTF8 ), GetTTPortConfig() );
}

BOOL CommunicationManagerClientViaSocketTT::StartCommunication( String aApp, String aParams )
{
    aAppPath = aApp;
    aAppParams = aParams;
    return StartCommunication();
}

BOOL CommunicationManagerClientViaSocketTT::RetryConnect()
{
    if ( !bApplicationStarted )
    {
        // Die App ist wohl nicht da. Starten wir sie mal.
        if ( aAppPath.Len() )
        {
            delete pProcess;

            pProcess = new Process();
            pProcess->SetImage( aAppPath, aAppParams );

            BOOL bSucc = pProcess->Start();
            bApplicationStarted = TRUE;

            if ( bSucc )
            {
                aFirstRetryCall = Time() + Time( 0, 1 );    // Max eine Minute Zeit
                for ( int i = 10 ; i-- ; )
                    GetpApp()->Reschedule();
            }
            return bSucc;
        }
        return FALSE;
    }
    else
    {
        if ( aFirstRetryCall > Time() )
        {
            for ( int i = 10 ; i-- ; )
                GetpApp()->Reschedule();
            return TRUE;
        }
        else
            return FALSE;
    }
}

#define GETSET(aVar, KeyName, Dafault)                 \
    aVar = aConf.ReadKey(KeyName,"No Entry");          \
    if ( aVar.CompareTo("No Entry") == COMPARE_EQUAL ) \
    {                                                  \
        aVar = ByteString(Dafault);                    \
        aConf.WriteKey(KeyName, aVar);                 \
    }

String GetHostConfig()
{
    String aHostToTalk;

    for ( int i = 0 ; i < Application::GetCommandLineParamCount() ; i++ )
    {
        if ( Application::GetCommandLineParam( i ).Copy(0,6).CompareIgnoreCaseToAscii("-host=") == COMPARE_EQUAL
#ifndef UNX
          || Application::GetCommandLineParam( i ).Copy(0,6).CompareIgnoreCaseToAscii("/host=") == COMPARE_EQUAL
#endif
          )
            return Application::GetCommandLineParam( i ).Copy(6);
    }

    ByteString abHostToTalk;
    Config aConf(Config::GetConfigName( Config::GetDefDirectory(), CUniString("testtool") ));
    aConf.SetGroup("Communication");

    GETSET( abHostToTalk, "Host", DEFAULT_HOST );
    return UniString( abHostToTalk, RTL_TEXTENCODING_UTF8 );
}

ULONG GetTTPortConfig()
{
    String aPortToTalk;

    for ( int i = 0 ; i < Application::GetCommandLineParamCount() ; i++ )
    {
        if ( Application::GetCommandLineParam( i ).Copy(0,6).CompareIgnoreCaseToAscii("-port=") == COMPARE_EQUAL
#ifndef UNX
          || Application::GetCommandLineParam( i ).Copy(0,6).CompareIgnoreCaseToAscii("/port=") == COMPARE_EQUAL
#endif
          )
        {
            aPortToTalk = Application::GetCommandLineParam( i ).Copy(6);
            return aPortToTalk.ToInt64();
        }
    }

    ByteString abPortToTalk;
    Config aConf(Config::GetConfigName( Config::GetDefDirectory(), CUniString("testtool") ));
    aConf.SetGroup("Communication");

    GETSET( abPortToTalk, "TTPort", ByteString::CreateFromInt32( TESTTOOL_DEFAULT_PORT ) );
    return abPortToTalk.ToInt64();
}

ULONG GetUnoPortConfig()
{
    String aPortToTalk;

    for ( int i = 0 ; i < Application::GetCommandLineParamCount() ; i++ )
    {
        if ( Application::GetCommandLineParam( i ).Copy(0,9).CompareIgnoreCaseToAscii("-unoport=") == COMPARE_EQUAL
#ifndef UNX
          || Application::GetCommandLineParam( i ).Copy(0,9).CompareIgnoreCaseToAscii("/unoport=") == COMPARE_EQUAL
#endif
          )
        {
            aPortToTalk = Application::GetCommandLineParam( i ).Copy(6);
            return aPortToTalk.ToInt64();
        }
    }

    ByteString abPortToTalk;
    Config aConf(Config::GetConfigName( Config::GetDefDirectory(), CUniString("testtool") ));
    aConf.SetGroup("Communication");

    GETSET( abPortToTalk, "UnoPort", ByteString::CreateFromInt32( UNO_DEFAULT_PORT ) );
    return abPortToTalk.ToInt64();
}
<|endoftext|>


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

#include <gtest/gtest.h>

#include <string>
#include <sys/wait.h>

#include "base/bind.h"
#include "base/eintr_wrapper.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop.h"
#include "base/process_util.h"
#include "base/synchronization/waitable_event.h"
#include "base/threading/thread.h"
#include "chrome/browser/chromeos/process_proxy/process_proxy_registry.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/public/browser/browser_thread.h"

using content::BrowserThread;

namespace {

// The test line must have all distinct characters.
const char kTestLineToSend[] = "abcdefgh\n";
const char kTestLineExpected[] = "abcdefgh\r\n";

const char kCatCommand[] = "cat";
const char kStdoutType[] = "stdout";
const int kTestLineNum = 100;

class TestRunner {
 public:
  virtual ~TestRunner() {}
  virtual void SetupExpectations(pid_t pid) = 0;
  virtual void OnSomeRead(pid_t pid, const std::string& type,
                          const std::string& output) = 0;
  virtual void StartRegistryTest(ProcessProxyRegistry* registry) = 0;

 protected:
  pid_t pid_;
};

class RegistryTestRunner : public TestRunner {
 public:
  virtual ~RegistryTestRunner() {}

  virtual void SetupExpectations(pid_t pid) OVERRIDE {
    pid_ = pid;
    left_to_check_index_[0] = 0;
    left_to_check_index_[1] = 0;
    // We consider that a line processing has started if a value in
    // left_to_check__[index] is set to 0, thus -2.
    lines_left_ = 2 * kTestLineNum - 2;
    expected_line_ = kTestLineExpected;
  }

  // Method to test validity of received input. We will receive two streams of
  // the same data. (input will be echoed twice by the testing process). Each
  // stream will contain the same string repeated |kTestLineNum| times. So we
  // have to match 2 * |kTestLineNum| lines. The problem is the received lines
  // from different streams may be interleaved (e.g. we may receive
  // abc|abcdef|defgh|gh). To deal with that, we allow to test received text
  // against two lines. The lines MUST NOT have two same characters for this
  // algorithm to work.
  virtual void OnSomeRead(pid_t pid, const std::string& type,
                          const std::string& output) OVERRIDE {
    EXPECT_EQ(type, kStdoutType);
    EXPECT_EQ(pid_, pid);

    bool valid = true;
    for (size_t i = 0; i < output.length(); i++) {
      // The character output[i] should be next in at least one of the lines we
      // are testing.
      valid = (ProcessReceivedCharacter(output[i], 0) ||
               ProcessReceivedCharacter(output[i], 1));
      EXPECT_TRUE(valid) << "Received: " << output;
    }

    if (!valid || TestSucceeded()) {
      content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
                                       MessageLoop::QuitClosure());
    }
  }

  virtual void StartRegistryTest(ProcessProxyRegistry* registry) OVERRIDE {
    for (int i = 0; i < kTestLineNum; i++) {
      EXPECT_TRUE(registry->SendInput(pid_, kTestLineToSend));
    }
  }

 private:
  bool ProcessReceivedCharacter(char received, size_t stream) {
    if (stream < 0 || stream >= arraysize(left_to_check_index_))
      return false;
    bool success = left_to_check_index_[stream] < expected_line_.length() &&
                   expected_line_[left_to_check_index_[stream]] == received;
    if (success)
      left_to_check_index_[stream]++;
    if (left_to_check_index_[stream] == expected_line_.length() &&
        lines_left_ > 0) {
      // Take another line to test for this stream, if there are any lines left.
      // If not, this stream is done.
      left_to_check_index_[stream] = 0;
      lines_left_--;
    }
    return success;
  }

  bool TestSucceeded() {
    return left_to_check_index_[0] == expected_line_.length() &&
           left_to_check_index_[1] == expected_line_.length() &&
           lines_left_ == 0;
  }

  size_t left_to_check_index_[2];
  size_t lines_left_;
  std::string expected_line_;
};

class RegistryNotifiedOnProcessExitTestRunner : public TestRunner {
 public:
  virtual ~RegistryNotifiedOnProcessExitTestRunner() {}

  virtual void SetupExpectations(pid_t pid) OVERRIDE {
    output_received_ = false;
    pid_ = pid;
  }

  virtual void OnSomeRead(pid_t pid, const std::string& type,
                          const std::string& output) OVERRIDE {
    EXPECT_EQ(pid_, pid);
    if (!output_received_) {
      output_received_ = true;
      EXPECT_EQ(type, "stdout");
      EXPECT_EQ(output, "p");
      base::KillProcess(pid_, 0 , true);
      return;
    }
    EXPECT_EQ("exit", type);
    content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
                                     MessageLoop::QuitClosure());
  }

  virtual void StartRegistryTest(ProcessProxyRegistry* registry) {
    EXPECT_TRUE(registry->SendInput(pid_, "p"));
  }

 private:
  bool output_received_;
};

class SigIntTestRunner : public TestRunner {
 public:
  virtual ~SigIntTestRunner() {}

  virtual void SetupExpectations(pid_t pid) OVERRIDE {
    pid_ = pid;
  }

  virtual void OnSomeRead(pid_t pid, const std::string& type,
                          const std::string& output) OVERRIDE {
    EXPECT_EQ(pid_, pid);
    // We may receive ^C on stdout, but we don't care about that, as long as we
    // eventually received exit event.
    if (type == "exit") {
      content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
                                       MessageLoop::QuitClosure());
    }
 }

  virtual void StartRegistryTest(ProcessProxyRegistry* registry) {
    // Send SingInt and verify the process exited.
    EXPECT_TRUE(registry->SendInput(pid_, "\003"));
  }

 private:
  bool output_received_;
};

}  // namespace

class ProcessProxyTest : public InProcessBrowserTest {
 public:
  ProcessProxyTest() {}
  ~ProcessProxyTest() {}

 protected:
  void InitRegistryTest() {
    registry_ = ProcessProxyRegistry::Get();

    EXPECT_TRUE(registry_->OpenProcess(kCatCommand, &pid_,
        base::Bind(&TestRunner::OnSomeRead,
                   base::Unretained(test_runner_.get()))));

    test_runner_->SetupExpectations(pid_);
    test_runner_->StartRegistryTest(registry_);
  }

  void EndRegistryTest() {
    registry_->CloseProcess(pid_);

    base::TerminationStatus status = base::GetTerminationStatus(pid_, NULL);
    EXPECT_NE(base::TERMINATION_STATUS_STILL_RUNNING, status);
    if (status == base::TERMINATION_STATUS_STILL_RUNNING)
      base::KillProcess(pid_, 0, true);

    content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
                                     MessageLoop::QuitClosure());
  }

  void RunTest() {
    BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
         base::Bind(&ProcessProxyTest::InitRegistryTest,
                    base::Unretained(this)));

    // Wait until all data from output watcher is received (QuitTask will be
    // fired on watcher thread).
    ui_test_utils::RunMessageLoop();

    BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
         base::Bind(&ProcessProxyTest::EndRegistryTest,
                    base::Unretained(this)));

    // Wait until we clean up the process proxy.
    ui_test_utils::RunMessageLoop();
  }

  scoped_ptr<TestRunner> test_runner_;

 private:
  ProcessProxyRegistry* registry_;
  pid_t pid_;
};

// Test will open new process that will run cat command, and verify data we
// write to process gets echoed back.
IN_PROC_BROWSER_TEST_F(ProcessProxyTest, RegistryTest) {
  test_runner_.reset(new RegistryTestRunner());
  RunTest();
}

// Open new process, then kill it. Verifiy that we detect when the process dies.
IN_PROC_BROWSER_TEST_F(ProcessProxyTest, RegistryNotifiedOnProcessExit) {
  test_runner_.reset(new RegistryNotifiedOnProcessExitTestRunner());
  RunTest();
}

// Test verifies that \003 message send to process is processed as SigInt.
// Timing out on the waterfall: http://crbug.com/115064
IN_PROC_BROWSER_TEST_F(ProcessProxyTest, DISABLED_SigInt) {
  test_runner_.reset(new SigIntTestRunner());
  RunTest();
}
<commit_msg>Fix clang compile error<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <gtest/gtest.h>

#include <string>
#include <sys/wait.h>

#include "base/bind.h"
#include "base/eintr_wrapper.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop.h"
#include "base/process_util.h"
#include "base/synchronization/waitable_event.h"
#include "base/threading/thread.h"
#include "chrome/browser/chromeos/process_proxy/process_proxy_registry.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/public/browser/browser_thread.h"

using content::BrowserThread;

namespace {

// The test line must have all distinct characters.
const char kTestLineToSend[] = "abcdefgh\n";
const char kTestLineExpected[] = "abcdefgh\r\n";

const char kCatCommand[] = "cat";
const char kStdoutType[] = "stdout";
const int kTestLineNum = 100;

class TestRunner {
 public:
  virtual ~TestRunner() {}
  virtual void SetupExpectations(pid_t pid) = 0;
  virtual void OnSomeRead(pid_t pid, const std::string& type,
                          const std::string& output) = 0;
  virtual void StartRegistryTest(ProcessProxyRegistry* registry) = 0;

 protected:
  pid_t pid_;
};

class RegistryTestRunner : public TestRunner {
 public:
  virtual ~RegistryTestRunner() {}

  virtual void SetupExpectations(pid_t pid) OVERRIDE {
    pid_ = pid;
    left_to_check_index_[0] = 0;
    left_to_check_index_[1] = 0;
    // We consider that a line processing has started if a value in
    // left_to_check__[index] is set to 0, thus -2.
    lines_left_ = 2 * kTestLineNum - 2;
    expected_line_ = kTestLineExpected;
  }

  // Method to test validity of received input. We will receive two streams of
  // the same data. (input will be echoed twice by the testing process). Each
  // stream will contain the same string repeated |kTestLineNum| times. So we
  // have to match 2 * |kTestLineNum| lines. The problem is the received lines
  // from different streams may be interleaved (e.g. we may receive
  // abc|abcdef|defgh|gh). To deal with that, we allow to test received text
  // against two lines. The lines MUST NOT have two same characters for this
  // algorithm to work.
  virtual void OnSomeRead(pid_t pid, const std::string& type,
                          const std::string& output) OVERRIDE {
    EXPECT_EQ(type, kStdoutType);
    EXPECT_EQ(pid_, pid);

    bool valid = true;
    for (size_t i = 0; i < output.length(); i++) {
      // The character output[i] should be next in at least one of the lines we
      // are testing.
      valid = (ProcessReceivedCharacter(output[i], 0) ||
               ProcessReceivedCharacter(output[i], 1));
      EXPECT_TRUE(valid) << "Received: " << output;
    }

    if (!valid || TestSucceeded()) {
      content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
                                       MessageLoop::QuitClosure());
    }
  }

  virtual void StartRegistryTest(ProcessProxyRegistry* registry) OVERRIDE {
    for (int i = 0; i < kTestLineNum; i++) {
      EXPECT_TRUE(registry->SendInput(pid_, kTestLineToSend));
    }
  }

 private:
  bool ProcessReceivedCharacter(char received, size_t stream) {
    if (stream >= arraysize(left_to_check_index_))
      return false;
    bool success = left_to_check_index_[stream] < expected_line_.length() &&
                   expected_line_[left_to_check_index_[stream]] == received;
    if (success)
      left_to_check_index_[stream]++;
    if (left_to_check_index_[stream] == expected_line_.length() &&
        lines_left_ > 0) {
      // Take another line to test for this stream, if there are any lines left.
      // If not, this stream is done.
      left_to_check_index_[stream] = 0;
      lines_left_--;
    }
    return success;
  }

  bool TestSucceeded() {
    return left_to_check_index_[0] == expected_line_.length() &&
           left_to_check_index_[1] == expected_line_.length() &&
           lines_left_ == 0;
  }

  size_t left_to_check_index_[2];
  size_t lines_left_;
  std::string expected_line_;
};

class RegistryNotifiedOnProcessExitTestRunner : public TestRunner {
 public:
  virtual ~RegistryNotifiedOnProcessExitTestRunner() {}

  virtual void SetupExpectations(pid_t pid) OVERRIDE {
    output_received_ = false;
    pid_ = pid;
  }

  virtual void OnSomeRead(pid_t pid, const std::string& type,
                          const std::string& output) OVERRIDE {
    EXPECT_EQ(pid_, pid);
    if (!output_received_) {
      output_received_ = true;
      EXPECT_EQ(type, "stdout");
      EXPECT_EQ(output, "p");
      base::KillProcess(pid_, 0 , true);
      return;
    }
    EXPECT_EQ("exit", type);
    content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
                                     MessageLoop::QuitClosure());
  }

  virtual void StartRegistryTest(ProcessProxyRegistry* registry) {
    EXPECT_TRUE(registry->SendInput(pid_, "p"));
  }

 private:
  bool output_received_;
};

class SigIntTestRunner : public TestRunner {
 public:
  virtual ~SigIntTestRunner() {}

  virtual void SetupExpectations(pid_t pid) OVERRIDE {
    pid_ = pid;
  }

  virtual void OnSomeRead(pid_t pid, const std::string& type,
                          const std::string& output) OVERRIDE {
    EXPECT_EQ(pid_, pid);
    // We may receive ^C on stdout, but we don't care about that, as long as we
    // eventually received exit event.
    if (type == "exit") {
      content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
                                       MessageLoop::QuitClosure());
    }
 }

  virtual void StartRegistryTest(ProcessProxyRegistry* registry) {
    // Send SingInt and verify the process exited.
    EXPECT_TRUE(registry->SendInput(pid_, "\003"));
  }

 private:
  bool output_received_;
};

}  // namespace

class ProcessProxyTest : public InProcessBrowserTest {
 public:
  ProcessProxyTest() {}
  ~ProcessProxyTest() {}

 protected:
  void InitRegistryTest() {
    registry_ = ProcessProxyRegistry::Get();

    EXPECT_TRUE(registry_->OpenProcess(kCatCommand, &pid_,
        base::Bind(&TestRunner::OnSomeRead,
                   base::Unretained(test_runner_.get()))));

    test_runner_->SetupExpectations(pid_);
    test_runner_->StartRegistryTest(registry_);
  }

  void EndRegistryTest() {
    registry_->CloseProcess(pid_);

    base::TerminationStatus status = base::GetTerminationStatus(pid_, NULL);
    EXPECT_NE(base::TERMINATION_STATUS_STILL_RUNNING, status);
    if (status == base::TERMINATION_STATUS_STILL_RUNNING)
      base::KillProcess(pid_, 0, true);

    content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
                                     MessageLoop::QuitClosure());
  }

  void RunTest() {
    BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
         base::Bind(&ProcessProxyTest::InitRegistryTest,
                    base::Unretained(this)));

    // Wait until all data from output watcher is received (QuitTask will be
    // fired on watcher thread).
    ui_test_utils::RunMessageLoop();

    BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
         base::Bind(&ProcessProxyTest::EndRegistryTest,
                    base::Unretained(this)));

    // Wait until we clean up the process proxy.
    ui_test_utils::RunMessageLoop();
  }

  scoped_ptr<TestRunner> test_runner_;

 private:
  ProcessProxyRegistry* registry_;
  pid_t pid_;
};

// Test will open new process that will run cat command, and verify data we
// write to process gets echoed back.
IN_PROC_BROWSER_TEST_F(ProcessProxyTest, RegistryTest) {
  test_runner_.reset(new RegistryTestRunner());
  RunTest();
}

// Open new process, then kill it. Verifiy that we detect when the process dies.
IN_PROC_BROWSER_TEST_F(ProcessProxyTest, RegistryNotifiedOnProcessExit) {
  test_runner_.reset(new RegistryNotifiedOnProcessExitTestRunner());
  RunTest();
}

// Test verifies that \003 message send to process is processed as SigInt.
// Timing out on the waterfall: http://crbug.com/115064
IN_PROC_BROWSER_TEST_F(ProcessProxyTest, DISABLED_SigInt) {
  test_runner_.reset(new SigIntTestRunner());
  RunTest();
}
<|endoftext|>


<commit_before>/////////////// CppExceptionConversion.proto ///////////////

#ifndef __Pyx_CppExn2PyErr
#include <new>
#include <typeinfo>
#include <stdexcept>
#include <iostream>

static void __Pyx_CppExn2PyErr() {
  // Catch a handful of different errors here and turn them into the
  // equivalent Python errors.
  try {
    if (PyErr_Occurred())
      ; // let the latest Python exn pass through and ignore the current one
    else
      throw;
  } catch (const std::bad_alloc& exn) {
    PyErr_SetString(PyExc_MemoryError, exn.what());
  } catch (const std::bad_cast& exn) {
    PyErr_SetString(PyExc_TypeError, exn.what());
  } catch (const std::domain_error& exn) {
    PyErr_SetString(PyExc_ValueError, exn.what());
  } catch (const std::invalid_argument& exn) {
    PyErr_SetString(PyExc_ValueError, exn.what());
  } catch (const std::ios_base::failure& exn) {
    // Unfortunately, in standard C++ we have no way of distinguishing EOF
    // from other errors here; be careful with the exception mask
    PyErr_SetString(PyExc_IOError, exn.what());
  } catch (const std::out_of_range& exn) {
    // Change out_of_range to IndexError
    PyErr_SetString(PyExc_IndexError, exn.what());
  } catch (const std::overflow_error& exn) {
    PyErr_SetString(PyExc_OverflowError, exn.what());
  } catch (const std::range_error& exn) {
    PyErr_SetString(PyExc_ArithmeticError, exn.what());
  } catch (const std::underflow_error& exn) {
    PyErr_SetString(PyExc_ArithmeticError, exn.what());
  } catch (const std::exception& exn) {
    PyErr_SetString(PyExc_RuntimeError, exn.what());
  }
  catch (...)
  {
    PyErr_SetString(PyExc_RuntimeError, "Unknown exception");
  }
}
#endif
<commit_msg>use <ios> instead of <iostream><commit_after>/////////////// CppExceptionConversion.proto ///////////////

#ifndef __Pyx_CppExn2PyErr
#include <new>
#include <typeinfo>
#include <stdexcept>
#include <ios>

static void __Pyx_CppExn2PyErr() {
  // Catch a handful of different errors here and turn them into the
  // equivalent Python errors.
  try {
    if (PyErr_Occurred())
      ; // let the latest Python exn pass through and ignore the current one
    else
      throw;
  } catch (const std::bad_alloc& exn) {
    PyErr_SetString(PyExc_MemoryError, exn.what());
  } catch (const std::bad_cast& exn) {
    PyErr_SetString(PyExc_TypeError, exn.what());
  } catch (const std::domain_error& exn) {
    PyErr_SetString(PyExc_ValueError, exn.what());
  } catch (const std::invalid_argument& exn) {
    PyErr_SetString(PyExc_ValueError, exn.what());
  } catch (const std::ios_base::failure& exn) {
    // Unfortunately, in standard C++ we have no way of distinguishing EOF
    // from other errors here; be careful with the exception mask
    PyErr_SetString(PyExc_IOError, exn.what());
  } catch (const std::out_of_range& exn) {
    // Change out_of_range to IndexError
    PyErr_SetString(PyExc_IndexError, exn.what());
  } catch (const std::overflow_error& exn) {
    PyErr_SetString(PyExc_OverflowError, exn.what());
  } catch (const std::range_error& exn) {
    PyErr_SetString(PyExc_ArithmeticError, exn.what());
  } catch (const std::underflow_error& exn) {
    PyErr_SetString(PyExc_ArithmeticError, exn.what());
  } catch (const std::exception& exn) {
    PyErr_SetString(PyExc_RuntimeError, exn.what());
  }
  catch (...)
  {
    PyErr_SetString(PyExc_RuntimeError, "Unknown exception");
  }
}
#endif
<|endoftext|>


<commit_before>/*
 * ESASM (v1.0.0) by EvolSoft
 * Developer: EvolSoft
 * Website: http://www.evolsoft.tk
 * Date: 06/06/2015 04:01 PM (UTC)
 * Copyright & License: (C) 2015 EvolSoft
 * Licensed under MIT (https://github.com/EvolSoft/ESASM/blob/master/LICENSE)
 */

#include <iostream>
#include <io.h>
#include <fstream>
#include <string>
#include <sstream>
#include <vector>
#include <iterator>
#include "parser.h"
//Opcodes
#include "opcodes\aaa.h"

using namespace std;

string trim(string line){
    size_t f = line.find_first_not_of(' ');
    size_t l = line.find_last_not_of(' ');
    return line.substr(f, l-f+1);
}

vector<string> split(string line) {
    vector<string> elements;
    stringstream ss(line);
    string token;
    while(getline(ss, token, ' ')) {
        elements.push_back(token);
    }
    return elements;
}

void Parser::parse(string filename, int type){
    ifstream file(filename.c_str());
    string line;
    if(file.is_open()){
        status = 0;
        int fileline = 0;
        while(getline(file, line)){
            fileline += 1;
            line = trim(line);
            vector<string> el = split(line);
            transform(el[0].begin(), el[0].end(), el[0].begin(), ::tolower);
            if(el[0].compare("aaa") == 0){
               aaa aaa_ = aaa(this, el, filename, fileline);
            }
        }
    }else{
        cout << "Error: Can't read source file. Permission denied.";
        status = 1;
    }
}
int Parser::getStatus(){
    return status;
}
<commit_msg>Added comment support<commit_after>/*
 * ESASM (v1.0.0) by EvolSoft
 * Developer: EvolSoft
 * Website: http://www.evolsoft.tk
 * Date: 07/06/2015 11:43 AM (UTC)
 * Copyright & License: (C) 2015 EvolSoft
 * Licensed under MIT (https://github.com/EvolSoft/ESASM/blob/master/LICENSE)
 */

#include <iostream>
#include <io.h>
#include <fstream>
#include <string>
#include <sstream>
#include <vector>
#include <iterator>
#include "parser.h"
//Opcodes
#include "opcodes\aaa.h"
#include "opcodes\aad.h"

using namespace std;

string trim(string line){
    size_t f = line.find_first_not_of(' ');
    size_t l = line.find_last_not_of(' ');
    return line.substr(f, l-f+1);
}

vector<string> split(string line) {
    vector<string> elements;
    stringstream ss(line);
    string token;
    while(getline(ss, token, ' ')) {
        elements.push_back(token);
    }
    return elements;
}

string removeComments(string line){
    bool is_string = false;
    int pos = line.length();
    for(int i = 0; i <= line.length(); i++){
        if((line[i] == '\"' && line[i] == '\'') && line[i-1] != '\\'){
            is_string = !is_string;
        }
        if(line[i] == ';' && !is_string){
            pos = i;
            break;
        }
    }
    return line.substr(0, pos);
}

void Parser::parse(string filename, int type){
    ifstream file(filename.c_str());
    string line;
    if(file.is_open()){
        status = 0;
        int fileline = 0;
        while(getline(file, line)){
            fileline += 1;
            line = trim(line);
            line = removeComments(line);
            vector<string> el = split(line);
            transform(el[0].begin(), el[0].end(), el[0].begin(), ::tolower);
            if(el[0].compare("aaa") == 0){
                aaa aaa_ = aaa(this, el, filename, fileline);
            }else if(el[0].compare("aad") == 0){
                aad aad_ = aad(this, el, filename, fileline);
            }
        }
    }else{
        cout << "\nError: Can't read source file. Permission denied.";
        status = 1;
    }
}
int Parser::getStatus(){
    return status;
}
<|endoftext|>


<commit_before>
#include <togo/error/assert.hpp>
#include <togo/log/log.hpp>
#include <togo/collection/fixed_array.hpp>
#include <togo/string/string.hpp>
#include <togo/system/system.hpp>
#include <togo/filesystem/filesystem.hpp>

using namespace togo;

signed main() {
	StringRef const exec_dir = filesystem::exec_dir();
	TOGO_LOGF("exec_dir: '%.*s'\n", exec_dir.size, exec_dir.data);

	// Working directory
	FixedArray<char, 256> wd_init{};
	unsigned const wd_init_size = filesystem::working_dir(wd_init);
	TOGO_LOGF("wd_init: '%.*s'\n", string::size(wd_init), fixed_array::begin(wd_init));
	TOGO_ASSERTE(wd_init_size > 0 && wd_init_size == fixed_array::size(wd_init));

	// Change directory
	TOGO_ASSERTE(filesystem::set_working_dir("/"));
	FixedArray<char, 256> wd_root{};
	unsigned const wd_root_size = filesystem::working_dir(wd_root);
	TOGO_LOGF("wd_root: '%.*s'\n", string::size(wd_root), fixed_array::begin(wd_root));
	TOGO_ASSERTE(wd_root_size > 0 && wd_root_size == fixed_array::size(wd_root));
	TOGO_ASSERTE(string::compare_equal(wd_root, "/"));

	// Move to group dir
	TOGO_ASSERTE(filesystem::set_working_dir(exec_dir));

	// Invariants based on test & filesystem
	TOGO_ASSERTE(!filesystem::is_file("/non/existent/file"));
	TOGO_ASSERTE(!filesystem::is_file("."));
	#if defined(TOGO_PLATFORM_LINUX)
		TOGO_ASSERTE(filesystem::is_file("general.elf"));
	#elif defined(TOGO_PLATFORM_WINDOWS)
		TOGO_ASSERTE(filesystem::is_file("general.exe"));
	#endif

	TOGO_ASSERTE(!filesystem::is_directory("/non/existent/directory"));
	TOGO_ASSERTE( filesystem::is_directory("."));
	TOGO_ASSERTE( filesystem::is_directory(".."));

	#define TEST_DIR "test_dir"
	#define TEST_FILE TEST_DIR "/test_file"

	// Directory creation
	TOGO_ASSERTE(!filesystem::is_directory(TEST_DIR));
	TOGO_ASSERTE(filesystem::create_directory(TEST_DIR));
	TOGO_ASSERTE(filesystem::is_directory(TEST_DIR));
	TOGO_ASSERTE(!filesystem::create_directory(TEST_DIR));
	TOGO_ASSERTE(
		filesystem::time_last_modified(TEST_DIR) >
		system::secs_since_epoch() - 2
	);

	// File creation
	TOGO_ASSERTE(!filesystem::is_file(TEST_FILE));
	TOGO_ASSERTE(filesystem::create_file(TEST_FILE));
	TOGO_ASSERTE(filesystem::is_file(TEST_FILE));
	TOGO_ASSERTE(!filesystem::create_file(TEST_FILE));
	TOGO_ASSERTE(
		filesystem::time_last_modified(TEST_FILE) >
		system::secs_since_epoch() - 2
	);
	TOGO_ASSERTE(filesystem::file_size(TEST_FILE) == 0);

	// File removal
	TOGO_ASSERTE(filesystem::remove_file(TEST_FILE));
	TOGO_ASSERTE(!filesystem::is_file(TEST_FILE));
	TOGO_ASSERTE(!filesystem::remove_file(TEST_FILE));
	TOGO_ASSERTE(filesystem::file_size(TEST_FILE) == 0);

	// Directory removal
	TOGO_ASSERTE(filesystem::remove_directory(TEST_DIR));
	TOGO_ASSERTE(!filesystem::is_directory(TEST_DIR));
	TOGO_ASSERTE(!filesystem::remove_directory(TEST_DIR));

	return 0;
}
<commit_msg>test/filesystem/general: added filesystem::move_file() tests.<commit_after>
#include <togo/error/assert.hpp>
#include <togo/log/log.hpp>
#include <togo/collection/fixed_array.hpp>
#include <togo/string/string.hpp>
#include <togo/system/system.hpp>
#include <togo/filesystem/filesystem.hpp>

using namespace togo;

signed main() {
	StringRef const exec_dir = filesystem::exec_dir();
	TOGO_LOGF("exec_dir: '%.*s'\n", exec_dir.size, exec_dir.data);

	// Working directory
	FixedArray<char, 256> wd_init{};
	unsigned const wd_init_size = filesystem::working_dir(wd_init);
	TOGO_LOGF("wd_init: '%.*s'\n", string::size(wd_init), fixed_array::begin(wd_init));
	TOGO_ASSERTE(wd_init_size > 0 && wd_init_size == fixed_array::size(wd_init));

	// Change directory
	TOGO_ASSERTE(filesystem::set_working_dir("/"));
	FixedArray<char, 256> wd_root{};
	unsigned const wd_root_size = filesystem::working_dir(wd_root);
	TOGO_LOGF("wd_root: '%.*s'\n", string::size(wd_root), fixed_array::begin(wd_root));
	TOGO_ASSERTE(wd_root_size > 0 && wd_root_size == fixed_array::size(wd_root));
	TOGO_ASSERTE(string::compare_equal(wd_root, "/"));

	// Move to group dir
	TOGO_ASSERTE(filesystem::set_working_dir(exec_dir));

	// Invariants based on test & filesystem
	TOGO_ASSERTE(!filesystem::is_file("/non/existent/file"));
	TOGO_ASSERTE(!filesystem::is_file("."));
	#if defined(TOGO_PLATFORM_LINUX)
		TOGO_ASSERTE(filesystem::is_file("general.elf"));
	#elif defined(TOGO_PLATFORM_WINDOWS)
		TOGO_ASSERTE(filesystem::is_file("general.exe"));
	#endif

	TOGO_ASSERTE(!filesystem::is_directory("/non/existent/directory"));
	TOGO_ASSERTE( filesystem::is_directory("."));
	TOGO_ASSERTE( filesystem::is_directory(".."));

	#define TEST_DIR "test_dir"
	#define TEST_FILE TEST_DIR "/test_file"
	#define TEST_FILE_MOVED TEST_DIR "/test_file_moved"

	// Directory creation
	TOGO_ASSERTE(!filesystem::is_directory(TEST_DIR));
	TOGO_ASSERTE(filesystem::create_directory(TEST_DIR));
	TOGO_ASSERTE(filesystem::is_directory(TEST_DIR));
	TOGO_ASSERTE(!filesystem::create_directory(TEST_DIR));
	TOGO_ASSERTE(
		filesystem::time_last_modified(TEST_DIR) >
		system::secs_since_epoch() - 2
	);

	// File creation
	TOGO_ASSERTE(!filesystem::is_file(TEST_FILE));
	TOGO_ASSERTE(filesystem::create_file(TEST_FILE));
	TOGO_ASSERTE(filesystem::is_file(TEST_FILE));
	TOGO_ASSERTE(!filesystem::create_file(TEST_FILE));
	TOGO_ASSERTE(
		filesystem::time_last_modified(TEST_FILE) >
		system::secs_since_epoch() - 2
	);
	TOGO_ASSERTE(filesystem::file_size(TEST_FILE) == 0);

	// File move
	TOGO_ASSERTE(filesystem::move_file(TEST_FILE, TEST_FILE_MOVED));
	TOGO_ASSERTE(!filesystem::is_file(TEST_FILE));
	TOGO_ASSERTE(filesystem::is_file(TEST_FILE_MOVED));
	TOGO_ASSERTE(!filesystem::move_file(TEST_FILE, TEST_FILE_MOVED));

	TOGO_ASSERTE(filesystem::move_file(TEST_FILE_MOVED, TEST_FILE));
	TOGO_ASSERTE(filesystem::is_file(TEST_FILE));
	TOGO_ASSERTE(!filesystem::is_file(TEST_FILE_MOVED));

	// File removal
	TOGO_ASSERTE(filesystem::remove_file(TEST_FILE));
	TOGO_ASSERTE(!filesystem::is_file(TEST_FILE));
	TOGO_ASSERTE(!filesystem::remove_file(TEST_FILE));
	TOGO_ASSERTE(filesystem::file_size(TEST_FILE) == 0);

	// Directory removal
	TOGO_ASSERTE(filesystem::remove_directory(TEST_DIR));
	TOGO_ASSERTE(!filesystem::is_directory(TEST_DIR));
	TOGO_ASSERTE(!filesystem::remove_directory(TEST_DIR));

	return 0;
}
<|endoftext|>


<commit_before>#ifndef ATL_CONVERSION_HH
#define ATL_CONVERSION_HH
/**
 * @file /home/ryan/programming/atl/conversion.hpp
 * @author Ryan Domigan <ryan_domigan@sutdents@uml.edu>
 * Created on Jul 10, 2013
 */

#include <string>
#include "./type.hpp"
#include "./type_traits.hpp"
#include "./utility.hpp"

#include <boost/mpl/at.hpp>
#include <boost/mpl/map.hpp>

namespace atl {
	namespace unwrapping {
		template<class T>
		struct Pimpl {
			static_assert(type_mapping::unwrappable_type<T>::value, "T is not an unwrappable_type");
			static inline constexpr T& a(atl::Any& aa) {return *reinterpret_cast<T*>(aa.value);}
			static inline constexpr T const& a(atl::Any const& aa) {return *reinterpret_cast<T*>(aa.value);}};

		template<class T>
		struct Reinterpret {
			static_assert(type_mapping::unwrappable_type<T>::value, "T is not an unwrappable_type");
			static inline constexpr T& a(atl::Any& aa) {return reinterpret_cast<T&>(aa);}
			static inline constexpr T const& a(atl::Any const& aa) {return reinterpret_cast<T const&>(aa);}};

		template<class T>
		struct Any
			: public std::conditional< is_reinterperable<typename std::decay<T>::type>::value,
			                           Reinterpret<T>,
			                           Pimpl<T>
			                           >::type
		{};
	}

	template<class T>
	static inline T& explicit_unwrap(Any& input)
	{ return unwrapping::Any<T>::a(input); }

	template<class T>
	static inline T const& explicit_unwrap(Any const& input)
	{ return unwrapping::Any<T>::a(input); }

	template<class T>
	static inline T& unwrap(Any& input)
	{
		// AstData needs to be passed as reference, so I it needs to
		// be wrapped and unwrapped with care.  Use explicit_unwrap if
		// you need to.
		static_assert(!std::is_same<AstData, T>::value,
		              "AstData type requires special handling");
		return unwrapping::Any<T>::a(input);
	}

	template<class T>
	static inline T const& unwrap(Any const& input)
	{ return unwrapping::Any<T>::a(input); }

	template<class T>
	static inline T& modify(Any const& input)
	{
		static_assert(is_pimpl<T>::value,
		              "Can't modify a const if it's a PIMPL");
		return unwrapping::Any<T>::a(const_cast<Any&>(input));
	}

	/*********************************/
	/* __        __                  */
	/* \ \      / / __ __ _ _ __     */
	/*  \ \ /\ / / '__/ _` | '_ \    */
	/*   \ V  V /| | | (_| | |_) |   */
	/*    \_/\_/ |_|  \__,_| .__/    */
	/*                     |_|       */
	/*********************************/
	namespace wrapping
	{
		template<class T>
		struct Reinterpret
		{
			static_assert(atl::is_reinterperable<T>::value, "Cannot wrap T");

			static inline Any a(T const& aa)
			{ return Any(aa._tag, (void*)aa.value); }
		};

		template<>
		struct Reinterpret<Type>
		{ static inline Any a(Type const& aa) { return Any(aa._tag, (void*)aa._value); } };

		template<class T>
		struct Pimpl
		{
			typedef typename std::remove_pointer<T>::type Bare;
			static_assert(type_mapping::unwrappable_type<Bare>::value,
			              "Cannot wrap type T");

			static inline Any a(T aa)
			{ return Any(tag<Bare>::value, aa); }
		};

		template<class T>
		struct Any
			: std::conditional< is_reinterperable<T>::value,
			                    Reinterpret<T>,
			                    Pimpl<T>
			                    >::type
		{};
	}

	template<class T> static inline constexpr Any wrap(T* vv)
	{
		static_assert(is_pimpl<T>::value,
		              "Cannot wrap pointer to non-pimpl: wrapped the dereferenced value "
		              "or use some other mechanism.");
		return Any(tag<T>::value, vv);
	}

	template<class T>
	static inline constexpr Any wrap(T const& vv)
	{
		using namespace tmpl;
		return Apply<wrapping::Any,
		             Apply<type_mapping::cxx_to_atl,
		                   Identity<T> >
		             >::a(vv);
	}

	static inline constexpr Any wrap(Any* vv) { return Any(tag<Pointer>::value, vv); }
	static inline constexpr Any wrap(Any const& vv) { return vv; }

	static inline Any wrap(const Fixnum& vv) {
		return Any(tag<Fixnum>::value,
		           (void*)vv.value);
	}

	template<class T>
	static inline Any wrap() { return Any(tag<T>::value, nullptr); }

	template<class T, class Arg>
	static inline Any wrap(Arg arg) { return wrap(T(arg)); }

	template<class T>
	inline Any& ref_wrap(T& value)
	{
		static_assert(is_reinterperable<T>::value,
		              "A ref_wrap is a simple cast -- can only be done with reinterperable types");
		return reinterpret_cast<Any&>(value);
	}

	namespace get_value
	{
		using namespace tmpl;

		// 'mpl::at' with a default (in other words, the interface the
		// boost docs advertise).
		template <typename Seq, typename Key, typename Def>
		struct AtDef
			: std::conditional<mpl::has_key<Seq, Key>::value,
			                   mpl::at<Seq, Key>,
			                   mpl::identity<Def>
			                   >::type {};

		typedef mpl::map<mpl::pair<bool, Bool>
		                 , mpl::pair<long, Fixnum>
		                 > CxxToAtlType;

		// const in c++ sucks.
		template<class T, class Input>
		struct GetConstValue
		{
			typedef typename Apply<AtDef,
			                       CxxToAtlType,
			                       Apply<std::remove_reference,
			                             std::remove_pointer<T> >,
			                       Identity<T>
			                       >::type AtlType;

			typedef decltype(AtlType::value) const& Return;

			static Return a(Input input) { return unwrap<AtlType>(input).value; }
		};

		template<class T, class Input>
		struct GetRefValue
		{
			typedef typename AtDef<CxxToAtlType, T, T>::type AtlType;

			typedef decltype(AtlType::value)& Return;

			static Return a(Input input) { return unwrap<AtlType>(input).value; }
		};

		// is the object referenced or pointed to const?
		template<class T>
		struct IsConstObject
			: Apply<std::is_const, Apply<std::remove_pointer, std::remove_reference<T> >
			        >::type {};

		template<class T, class Input>
		struct FromAtl
			: std::conditional< IsConstObject<T>::value || IsConstObject<Input>::value,
			                    GetConstValue<T, Input>,
			                    GetRefValue<T, Input>
			                    >::type
		{};

		template<class T>
		struct FromAtl<T, T>
		{
			typedef T AtlType;
			typedef T Return;

			static T& a(T& input) { return input; }
			static T a(T const& input) { return input; }
		};
	}

	template<class T, class Input>
	typename get_value::FromAtl<T, Input>::Return
	value(Input&& input) {
		return get_value::FromAtl<T, Input >::a(input);
	}
}

#endif
<commit_msg>conversion: Where possible, unwrap reference from const reference<commit_after>#ifndef ATL_CONVERSION_HH
#define ATL_CONVERSION_HH
/**
 * @file /home/ryan/programming/atl/conversion.hpp
 * @author Ryan Domigan <ryan_domigan@sutdents@uml.edu>
 * Created on Jul 10, 2013
 */

#include <string>
#include <type_traits.hpp>

#include "./type.hpp"
#include "./type_traits.hpp"
#include "./utility.hpp"

#include <boost/mpl/at.hpp>
#include <boost/mpl/map.hpp>

namespace atl {
	namespace unwrapping {
		template<class T>
		struct Pimpl {
			static_assert(type_mapping::unwrappable_type<T>::value, "T is not an unwrappable_type");
			static inline constexpr T& a(atl::Any& aa) {return *reinterpret_cast<T*>(aa.value);}
			static inline constexpr T& a(atl::Any const& aa) {return *reinterpret_cast<T*>(aa.value);}};

		template<class T>
		struct Reinterpret {
			static_assert(type_mapping::unwrappable_type<T>::value, "T is not an unwrappable_type");
			static inline constexpr T& a(atl::Any& aa) {return reinterpret_cast<T&>(aa);}
			static inline constexpr T const& a(atl::Any const& aa) {return reinterpret_cast<T const&>(aa);}};

		template<class T>
		struct Any
			: public std::conditional< is_reinterperable<typename std::decay<T>::type>::value,
			                           Reinterpret<T>,
			                           Pimpl<T>
			                           >::type
		{};
	}

	template<class T>
	static inline T& explicit_unwrap(Any& input)
	{ return unwrapping::Any<T>::a(input); }

	template<class T>
	static inline T const& explicit_unwrap(Any const& input)
	{ return unwrapping::Any<T>::a(input); }

	template<class T>
	static inline T& unwrap(Any& input)
	{
		// AstData needs to be passed as reference, so I it needs to
		// be wrapped and unwrapped with care.  Use explicit_unwrap if
		// you need to.
		static_assert(!std::is_same<AstData, T>::value,
		              "AstData type requires special handling");
		return unwrapping::Any<T>::a(input);
	}

	template<class T>
	static inline
	typename std::conditional<is_pimpl<T>::value,
	                          T&,
	                          T>::type
	unwrap(Any const& input)
	{ return unwrapping::Any<T>::a(input); }

	template<class T>
	static inline T& modify(Any const& input)
	{
		static_assert(is_pimpl<T>::value,
		              "Can't modify a const if it's a PIMPL");
		return unwrapping::Any<T>::a(const_cast<Any&>(input));
	}

	/*********************************/
	/* __        __                  */
	/* \ \      / / __ __ _ _ __     */
	/*  \ \ /\ / / '__/ _` | '_ \    */
	/*   \ V  V /| | | (_| | |_) |   */
	/*    \_/\_/ |_|  \__,_| .__/    */
	/*                     |_|       */
	/*********************************/
	namespace wrapping
	{
		template<class T>
		struct Reinterpret
		{
			static_assert(atl::is_reinterperable<T>::value, "Cannot wrap T");

			static inline Any a(T const& aa)
			{ return Any(aa._tag, (void*)aa.value); }
		};

		template<>
		struct Reinterpret<Type>
		{ static inline Any a(Type const& aa) { return Any(aa._tag, (void*)aa._value); } };

		template<class T>
		struct Pimpl
		{
			typedef typename std::remove_pointer<T>::type Bare;
			static_assert(type_mapping::unwrappable_type<Bare>::value,
			              "Cannot wrap type T");

			static inline Any a(T aa)
			{ return Any(tag<Bare>::value, aa); }
		};

		template<class T>
		struct Any
			: std::conditional< is_reinterperable<T>::value,
			                    Reinterpret<T>,
			                    Pimpl<T>
			                    >::type
		{};
	}

	template<class T> static inline constexpr Any wrap(T* vv)
	{
		static_assert(is_pimpl<T>::value,
		              "Cannot wrap pointer to non-pimpl: wrapped the dereferenced value "
		              "or use some other mechanism.");
		return Any(tag<T>::value, vv);
	}

	template<class T>
	static inline constexpr Any wrap(T const& vv)
	{
		using namespace tmpl;
		return Apply<wrapping::Any,
		             Apply<type_mapping::cxx_to_atl,
		                   Identity<T> >
		             >::a(vv);
	}

	static inline constexpr Any wrap(Any* vv) { return Any(tag<Pointer>::value, vv); }
	static inline constexpr Any wrap(Any const& vv) { return vv; }

	static inline Any wrap(const Fixnum& vv) {
		return Any(tag<Fixnum>::value,
		           (void*)vv.value);
	}

	template<class T>
	static inline Any wrap() { return Any(tag<T>::value, nullptr); }

	template<class T, class Arg>
	static inline Any wrap(Arg arg) { return wrap(T(arg)); }

	template<class T>
	inline Any& ref_wrap(T& value)
	{
		static_assert(is_reinterperable<T>::value,
		              "A ref_wrap is a simple cast -- can only be done with reinterperable types");
		return reinterpret_cast<Any&>(value);
	}

	namespace get_value
	{
		using namespace tmpl;

		// 'mpl::at' with a default (in other words, the interface the
		// boost docs advertise).
		template <typename Seq, typename Key, typename Def>
		struct AtDef
			: std::conditional<mpl::has_key<Seq, Key>::value,
			                   mpl::at<Seq, Key>,
			                   mpl::identity<Def>
			                   >::type {};

		typedef mpl::map<mpl::pair<bool, Bool>
		                 , mpl::pair<long, Fixnum>
		                 > CxxToAtlType;

		// const in c++ sucks.
		template<class T, class Input>
		struct GetConstValue
		{
			typedef typename Apply<AtDef,
			                       CxxToAtlType,
			                       Apply<std::remove_reference,
			                             std::remove_pointer<T> >,
			                       Identity<T>
			                       >::type AtlType;

			typedef decltype(AtlType::value) const& Return;

			static Return a(Input input) { return unwrap<AtlType>(input).value; }
		};

		template<class T, class Input>
		struct GetRefValue
		{
			typedef typename AtDef<CxxToAtlType, T, T>::type AtlType;

			typedef decltype(AtlType::value)& Return;

			static Return a(Input input) { return unwrap<AtlType>(input).value; }
		};

		// is the object referenced or pointed to const?
		template<class T>
		struct IsConstObject
			: Apply<std::is_const, Apply<std::remove_pointer, std::remove_reference<T> >
			        >::type {};

		template<class T, class Input>
		struct FromAtl
			: std::conditional< IsConstObject<T>::value || IsConstObject<Input>::value,
			                    GetConstValue<T, Input>,
			                    GetRefValue<T, Input>
			                    >::type
		{};

		template<class T>
		struct FromAtl<T, T>
		{
			typedef T AtlType;
			typedef T Return;

			static T& a(T& input) { return input; }
			static T a(T const& input) { return input; }
		};
	}

	template<class T, class Input>
	typename get_value::FromAtl<T, Input>::Return
	value(Input&& input) {
		return get_value::FromAtl<T, Input >::a(input);
	}
}

#endif
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2017 ScyllaDB
 */

/*
 * This file is part of Scylla.
 *
 * Scylla is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Scylla is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#pragma once

#include <memory>

#include <seastar/core/future.hh>
#include <seastar/core/sstring.hh>

#include "auth/authenticator.hh"
#include "auth/authorizer.hh"
#include "auth/authenticated_user.hh"
#include "auth/permission.hh"
#include "auth/permissions_cache.hh"
#include "delayed_tasks.hh"
#include "seastarx.hh"

namespace cql3 {
class query_processor;
}

namespace db {
class config;
}

namespace service {
class migration_manager;
class migration_listener;
}

namespace auth {

class authenticator;
class authorizer;

struct service_config final {
    static service_config from_db_config(const db::config&);

    sstring authorizer_java_name;
    sstring authenticator_java_name;
};

class service final {
    permissions_cache_config _cache_config;

    cql3::query_processor& _qp;

    ::service::migration_manager& _migration_manager;

    std::unique_ptr<authorizer> _authorizer;

    std::unique_ptr<authenticator> _authenticator;

    // Only one of these should be registered, so we end up with some unused instances. Not the end of the world.
    std::unique_ptr<::service::migration_listener> _migration_listener;

    delayed_tasks<> _delayed{};

public:
    service(
            permissions_cache_config,
            cql3::query_processor&,
            ::service::migration_manager&,
            std::unique_ptr<authorizer>,
            std::unique_ptr<authenticator>);

    service(
            permissions_cache_config,
            cql3::query_processor&,
            ::service::migration_manager&,
            const service_config&);

    future<> start();

    future<> stop();

    future<bool> is_existing_user(const sstring& name) const;

    future<bool> is_super_user(const sstring& name) const;

    future<> insert_user(const sstring& name, bool is_superuser);

    future<> delete_user(const sstring& name);

    future<permission_set> get_permissions(::shared_ptr<authenticated_user>, data_resource) const;

    authenticator& underlying_authenticator() {
        return *_authenticator;
    }

    const authenticator& underlying_authenticator() const {
        return *_authenticator;
    }

    authorizer& underlying_authorizer() {
        return *_authorizer;
    }

    const authorizer& underlying_authorizer() const {
        return *_authorizer;
    }

private:
    future<bool> has_existing_users() const;

    future<> create_keyspace_if_missing() const;

    bool should_create_metadata() const;

    future<> create_metadata_if_missing();
};

future<bool> is_super_user(const service&, const authenticated_user&);

}
<commit_msg>auth/service.cc: Remove redundant declarations<commit_after>/*
 * Copyright (C) 2017 ScyllaDB
 */

/*
 * This file is part of Scylla.
 *
 * Scylla is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Scylla is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#pragma once

#include <memory>

#include <seastar/core/future.hh>
#include <seastar/core/sstring.hh>

#include "auth/authenticator.hh"
#include "auth/authorizer.hh"
#include "auth/authenticated_user.hh"
#include "auth/permission.hh"
#include "auth/permissions_cache.hh"
#include "delayed_tasks.hh"
#include "seastarx.hh"

namespace cql3 {
class query_processor;
}

namespace db {
class config;
}

namespace service {
class migration_manager;
class migration_listener;
}

namespace auth {

struct service_config final {
    static service_config from_db_config(const db::config&);

    sstring authorizer_java_name;
    sstring authenticator_java_name;
};

class service final {
    permissions_cache_config _cache_config;

    cql3::query_processor& _qp;

    ::service::migration_manager& _migration_manager;

    std::unique_ptr<authorizer> _authorizer;

    std::unique_ptr<authenticator> _authenticator;

    // Only one of these should be registered, so we end up with some unused instances. Not the end of the world.
    std::unique_ptr<::service::migration_listener> _migration_listener;

    delayed_tasks<> _delayed{};

public:
    service(
            permissions_cache_config,
            cql3::query_processor&,
            ::service::migration_manager&,
            std::unique_ptr<authorizer>,
            std::unique_ptr<authenticator>);

    service(
            permissions_cache_config,
            cql3::query_processor&,
            ::service::migration_manager&,
            const service_config&);

    future<> start();

    future<> stop();

    future<bool> is_existing_user(const sstring& name) const;

    future<bool> is_super_user(const sstring& name) const;

    future<> insert_user(const sstring& name, bool is_superuser);

    future<> delete_user(const sstring& name);

    future<permission_set> get_permissions(::shared_ptr<authenticated_user>, data_resource) const;

    authenticator& underlying_authenticator() {
        return *_authenticator;
    }

    const authenticator& underlying_authenticator() const {
        return *_authenticator;
    }

    authorizer& underlying_authorizer() {
        return *_authorizer;
    }

    const authorizer& underlying_authorizer() const {
        return *_authorizer;
    }

private:
    future<bool> has_existing_users() const;

    future<> create_keyspace_if_missing() const;

    bool should_create_metadata() const;

    future<> create_metadata_if_missing();
};

future<bool> is_super_user(const service&, const authenticated_user&);

}
<|endoftext|>


<commit_before>// @(#)root/test:$Name:  $:$Id: Aclock.cxx,v 1.2 2000/07/11 18:05:26 rdm Exp $
// Author: Valeriy Onuchin & Fons Rademakers   04/10/98

///////////////////////////////////////////////////////////////////
//  ROOT implementation of the X11 xclock.
//
//  To run this example do the following:
//  $ root
//  root [0] gSystem.Load("Aclock")
//  root [1] Aclock a
//  <enjoy>
//  root [2] .q
//
//  Other ROOT fun examples: Tetris, Hello ...
//
//  Begin_Html
//
//  End_Html
//
///////////////////////////////////////////////////////////////////

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

ClassImp(Aclock)

Float_t MinuteHand::fgMinuteHandX[] = { -0.05, 0, 0.05 };
Float_t MinuteHand::fgMinuteHandY[] = { -0.04, 0.625, -0.04 };

Float_t HourHand::fgHourHandX[] = { -0.05, 0, 0.05 };
Float_t HourHand::fgHourHandY[] = { -0.04, 0.4, -0.04 };

Float_t SecondHand::fgSecondHandX[] = { 0., 0.035, 0., -0.035 };
Float_t SecondHand::fgSecondHandY[] = { 0.78, 0.73, 0.68, 0.73 };

TDatime *ClockHand::fgTime = new TDatime;

TPolygon::TPolygon(Int_t n, Float_t *x, Float_t *y) : TPolyLine(n+1,x,y)
{
   // Create filled polygon. Polygon will be added to current pad.

   if (!TVirtualPad::Pad()) { Error("Constructor","Create TPad first!"); return; }

   fPad  = (TPad*)TVirtualPad::Pad();
   fX[n] = x[0];             // create an extra point to connect polyline ends
   fY[n] = y[0];
   Draw();                   // append to fPad
}

void TPolygon::Paint(Option_t *)
{
   // Paint filled polygon.

   TAttLine::Modify();
   TAttFill::Modify();
   fPad->PaintFillArea(fN-1, fX, fY);
   fPad->PaintPolyLine(fN, fX, fY, "");
}

ClockHand::ClockHand(Int_t n, Float_t *x, Float_t *y) : TPolygon(n,x,y)
{
   // Create clockhand

   fPrevTimeValue = 0;
   fX0 = new Float_t[GetN()];   // initial shape and position
   fY0 = new Float_t[GetN()];   // initial shape and position

   for (int i = 0; i < GetN(); i++) {
     fX0[i] = fX[i];
     fY0[i] = fY[i];
   }
   SetFillColor(9);            // default fill color
}

void ClockHand::Update()
{
   // Update hand position

   if (!IsModified()) return;

   fPrevTimeValue = GetTimeValue();
   Move(GetHandAngle());
}

void ClockHand::Move(Float_t clock_angle)
{
   // Move clockhand.

  Int_t n = GetN();

  // ClockPoints used to rotate,scale and shift initial points
  static ClockPoints *points = new ClockPoints();

  Float_t wh = (Float_t)fPad->XtoPixel(fPad->GetX2());
  Float_t hh = (Float_t)fPad->YtoPixel(fPad->GetY1());

  for (int i = 0; i < n; i++) {
     points->SetXY(fX0[i],fY0[i]);
     points->Rotate(clock_angle);

     if (wh < hh) points->Scale(0.5,0.5*wh/hh);    //  scale to have a circular clock
     else         points->Scale(0.5*hh/wh,0.5);

     points->Shift(0.5,0.5);                      // move to the center of pad
     fX[i] = points->GetX();
     fY[i] = points->GetY();
   }
}

Aclock::Aclock(Int_t csize) : TTimer(500, kTRUE)
{
   // Create a clock in a new canvas.

   fPad = new TCanvas("Aclock:canvas","xclock",-csize,csize);

   fPad->SetFillColor(14);     // grey

   fMinuteHand = new MinuteHand();
   fSecondHand = new SecondHand();
   fHourHand   = new HourHand();

   SetBit(kCanDelete);
   Draw();                         // append this Aclock to fPad
   Animate();
   gSystem->AddTimer(this);        // start timer = start animation
}

Aclock::~Aclock()
{
   // Clean up the clock.

   delete fMinuteHand;
   delete fSecondHand;
   delete fHourHand;
}

void Aclock::Paint(Option_t *)
{
   // Just draw clock scale (time and minutes ticks)

   static ClockPoints *point1 = new ClockPoints();
   static ClockPoints *point2 = new ClockPoints();

   Float_t wh = (Float_t)fPad->XtoPixel(fPad->GetX2());
   Float_t hh = (Float_t)fPad->YtoPixel(fPad->GetY1());

   for (int i = 0; i < 60; i++ ) {             // draw minute/hour ticks
      point1->SetXY(0.,0.9);

      if (!(i%5)) point2->SetXY(0.,0.8);       // hour  ticks  are longer
      else        point2->SetXY(0.,0.87);

      Float_t angle = 6.*i;
      point1->Rotate(angle);
      point2->Rotate(angle);

      if (wh < hh) {                   // scale in oder to draw circle scale
         point1->Scale(0.5,0.5*wh/hh);
         point2->Scale(0.5,0.5*wh/hh);
      } else {
         point1->Scale(0.5*hh/wh,0.5);
         point2->Scale(0.5*hh/wh,0.5);
      }

      point1->Shift(0.5,0.5);              // move to center of pad
      point2->Shift(0.5,0.5);

      fPad->PaintLine(point1->GetX(),point1->GetY(),point2->GetX(),point2->GetY());
   }
}

void Aclock::Animate()
{
   // Update clock hand positions and redraw the fPad

   if (!fSecondHand->IsModified()) return;

   fHourHand->Update();            //  update position every minute
   fMinuteHand->Update();          //  update position every minute
   fSecondHand->Update();          //  update position every second
   fPad->Modified();               //  drawing ...
   fPad->Update();
}

Bool_t Aclock::Notify()
{
   // Actions after timer's time-out

   Animate();
   TTimer::Reset();
   return kFALSE;
}
<commit_msg>This example requires libGpad to be loaded too.<commit_after>// @(#)root/test:$Name:  $:$Id: Aclock.cxx,v 1.3 2004/02/19 07:24:38 brun Exp $
// Author: Valeriy Onuchin & Fons Rademakers   04/10/98

///////////////////////////////////////////////////////////////////
//  ROOT implementation of the X11 xclock.
//
//  To run this example do the following:
//  $ root
//  root [0] gSystem.Load("libGpad")
//  root [1] gSystem.Load("Aclock")
//  root [1] Aclock a
//  <enjoy>
//  root [2] .q
//
//  Other ROOT fun examples: Tetris, Hello ...
//
//  Begin_Html
//
//  End_Html
//
///////////////////////////////////////////////////////////////////

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

ClassImp(Aclock)

Float_t MinuteHand::fgMinuteHandX[] = { -0.05, 0, 0.05 };
Float_t MinuteHand::fgMinuteHandY[] = { -0.04, 0.625, -0.04 };

Float_t HourHand::fgHourHandX[] = { -0.05, 0, 0.05 };
Float_t HourHand::fgHourHandY[] = { -0.04, 0.4, -0.04 };

Float_t SecondHand::fgSecondHandX[] = { 0., 0.035, 0., -0.035 };
Float_t SecondHand::fgSecondHandY[] = { 0.78, 0.73, 0.68, 0.73 };

TDatime *ClockHand::fgTime = new TDatime;

TPolygon::TPolygon(Int_t n, Float_t *x, Float_t *y) : TPolyLine(n+1,x,y)
{
   // Create filled polygon. Polygon will be added to current pad.

   if (!TVirtualPad::Pad()) { Error("Constructor","Create TPad first!"); return; }

   fPad  = (TPad*)TVirtualPad::Pad();
   fX[n] = x[0];             // create an extra point to connect polyline ends
   fY[n] = y[0];
   Draw();                   // append to fPad
}

void TPolygon::Paint(Option_t *)
{
   // Paint filled polygon.

   TAttLine::Modify();
   TAttFill::Modify();
   fPad->PaintFillArea(fN-1, fX, fY);
   fPad->PaintPolyLine(fN, fX, fY, "");
}

ClockHand::ClockHand(Int_t n, Float_t *x, Float_t *y) : TPolygon(n,x,y)
{
   // Create clockhand

   fPrevTimeValue = 0;
   fX0 = new Float_t[GetN()];   // initial shape and position
   fY0 = new Float_t[GetN()];   // initial shape and position

   for (int i = 0; i < GetN(); i++) {
     fX0[i] = fX[i];
     fY0[i] = fY[i];
   }
   SetFillColor(9);            // default fill color
}

void ClockHand::Update()
{
   // Update hand position

   if (!IsModified()) return;

   fPrevTimeValue = GetTimeValue();
   Move(GetHandAngle());
}

void ClockHand::Move(Float_t clock_angle)
{
   // Move clockhand.

  Int_t n = GetN();

  // ClockPoints used to rotate,scale and shift initial points
  static ClockPoints *points = new ClockPoints();

  Float_t wh = (Float_t)fPad->XtoPixel(fPad->GetX2());
  Float_t hh = (Float_t)fPad->YtoPixel(fPad->GetY1());

  for (int i = 0; i < n; i++) {
     points->SetXY(fX0[i],fY0[i]);
     points->Rotate(clock_angle);

     if (wh < hh) points->Scale(0.5,0.5*wh/hh);    //  scale to have a circular clock
     else         points->Scale(0.5*hh/wh,0.5);

     points->Shift(0.5,0.5);                      // move to the center of pad
     fX[i] = points->GetX();
     fY[i] = points->GetY();
   }
}

Aclock::Aclock(Int_t csize) : TTimer(500, kTRUE)
{
   // Create a clock in a new canvas.

   fPad = new TCanvas("Aclock:canvas","xclock",-csize,csize);

   fPad->SetFillColor(14);     // grey

   fMinuteHand = new MinuteHand();
   fSecondHand = new SecondHand();
   fHourHand   = new HourHand();

   SetBit(kCanDelete);
   Draw();                         // append this Aclock to fPad
   Animate();
   gSystem->AddTimer(this);        // start timer = start animation
}

Aclock::~Aclock()
{
   // Clean up the clock.

   delete fMinuteHand;
   delete fSecondHand;
   delete fHourHand;
}

void Aclock::Paint(Option_t *)
{
   // Just draw clock scale (time and minutes ticks)

   static ClockPoints *point1 = new ClockPoints();
   static ClockPoints *point2 = new ClockPoints();

   Float_t wh = (Float_t)fPad->XtoPixel(fPad->GetX2());
   Float_t hh = (Float_t)fPad->YtoPixel(fPad->GetY1());

   for (int i = 0; i < 60; i++ ) {             // draw minute/hour ticks
      point1->SetXY(0.,0.9);

      if (!(i%5)) point2->SetXY(0.,0.8);       // hour  ticks  are longer
      else        point2->SetXY(0.,0.87);

      Float_t angle = 6.*i;
      point1->Rotate(angle);
      point2->Rotate(angle);

      if (wh < hh) {                   // scale in oder to draw circle scale
         point1->Scale(0.5,0.5*wh/hh);
         point2->Scale(0.5,0.5*wh/hh);
      } else {
         point1->Scale(0.5*hh/wh,0.5);
         point2->Scale(0.5*hh/wh,0.5);
      }

      point1->Shift(0.5,0.5);              // move to center of pad
      point2->Shift(0.5,0.5);

      fPad->PaintLine(point1->GetX(),point1->GetY(),point2->GetX(),point2->GetY());
   }
}

void Aclock::Animate()
{
   // Update clock hand positions and redraw the fPad

   if (!fSecondHand->IsModified()) return;

   fHourHand->Update();            //  update position every minute
   fMinuteHand->Update();          //  update position every minute
   fSecondHand->Update();          //  update position every second
   fPad->Modified();               //  drawing ...
   fPad->Update();
}

Bool_t Aclock::Notify()
{
   // Actions after timer's time-out

   Animate();
   TTimer::Reset();
   return kFALSE;
}
<|endoftext|>