<commit_before>//----------------------------  solver_control.cc  ---------------------------
//    $Id$
//    Version: $Name$
//
//    Copyright (C) 1998, 1999, 2000, 2001 by the deal.II authors
//
//    This file is subject to QPL and may not be  distributed
//    without copyright and license information. Please refer
//    to the file deal.II/doc/license.html for the  text  and
//    further information on this license.
//
//----------------------------  solver_control.cc  ---------------------------

#include <base/logstream.h>
#include <base/parameter_handler.h>
#include <lac/solver_control.h>

#include <cmath>
#include <strstream>

/*----------------------- SolverControl ---------------------------------*/

SolverControl::NoConvergence::NoConvergence (const unsigned int last_step,
					     const double       last_residual)
		:
		last_step (last_step),
		last_residual (last_residual)
{};

const char *
SolverControl::NoConvergence::what () const throw ()
{
  				   // have a place where to store the
				   // description of the exception as a char *
				   //
				   // this thing obviously is not multi-threading
				   // safe, but we don't care about that for now
				   //
				   // we need to make this object static, since
				   // we want to return the data stored in it
				   // and therefore need a liftime which is
				   // longer than the execution time of this
				   // function
  static std::string description;
				   // convert the messages printed by the
				   // exceptions into a std::string
  std::ostrstream out;

  out << "Iterative method reported convergence failure in step "
      << last_step << " with residual " << last_residual << std::ends;

  description = out.str();
  return description.c_str();
}

SolverControl::SolverControl (const unsigned int maxiter,
			      const double tolerance,
			      const bool _log_history,
			      const bool _log_result)
		:
		maxsteps(maxiter),
		tol(tolerance),
		lvalue(1.e300),
		lstep(0),
		check_failure(false),
		relative_failure_residual(0),
		failure_residual(0),
		_log_history(_log_history),
		_log_frequency(1),
		_log_result(_log_result)
{};

SolverControl::~SolverControl()
{};

SolverControl::State
SolverControl::check (const unsigned int step,
		      const double check_value)
{
  if (_log_history && ((step % _log_frequency) == 0))
    deallog << "Check " << step << "\t" << check_value << std::endl;

  lstep  = step;
  lvalue = check_value;

  if (step==0)
    {
      if (check_failure)
	failure_residual=relative_failure_residual*check_value;

      if (_log_result)
	deallog << "Starting value " << check_value << std::endl;
    }

  if ((step >= maxsteps) ||
#ifdef HAVE_ISNAN
      isnan(check_value) ||
#else
#  if HAVE_UNDERSCORE_ISNAN
				       // on Microsoft Windows, the
				       // function is called _isnan
      _isnan(check_value) ||
#  endif
#endif
      (check_failure && (check_value > failure_residual))
  )
    {
      if (_log_result)
	deallog << "Failure step " << step
		<< " value " << check_value << std::endl;
      lcheck = failure;
      return failure;
    }

  if (check_value <= tol)
    {
      if (_log_result)
	deallog << "Convergence step " << step
		<< " value " << check_value << std::endl;
      lcheck = success;
      return success;
    }
  lcheck = iterate;
  return iterate;
}

SolverControl::State
SolverControl::last_check() const
{
  return lcheck;
}

double
SolverControl::last_value() const
{
  return lvalue;
}

unsigned int
SolverControl::last_step() const
{
  return lstep;
}

unsigned int
SolverControl::log_frequency (unsigned int f)
{
  if (f==0)
    f = 1;
  unsigned int old = _log_frequency;
  _log_frequency = f;
  return old;
}

void
SolverControl::declare_parameters (ParameterHandler& param)
{
  param.declare_entry ("Max steps", "100", Patterns::Integer());
  param.declare_entry ("Tolerance", "1.e-10", Patterns::Double());
  param.declare_entry ("Log history", "false", Patterns::Bool());
  param.declare_entry ("Log frequency", "1", Patterns::Integer());
  param.declare_entry ("Log result", "true", Patterns::Bool());
}

void SolverControl::parse_parameters (ParameterHandler& param)
{
  set_max_steps (param.get_integer("Max steps"));
  set_tolerance (param.get_double("Tolerance"));
  log_history (param.get_bool("Log history"));
  log_result (param.get_bool("Log result"));
  log_frequency (param.get_integer("Log frequency"));
}

/*----------------------- ReductionControl ---------------------------------*/

ReductionControl::ReductionControl(const unsigned int n,
				   const double tol,
				   const double red,
				   const bool _log_history,
				   const bool _log_result)
		:
		SolverControl (n, tol, _log_history, _log_result),
		reduce(red)
{};

ReductionControl::~ReductionControl()
{};

double
ReductionControl::initial_value() const {
  return initial_val;
};

SolverControl::State
ReductionControl::check (const unsigned int step,
			 const double check_value)
{
  if (step==0)
    {
      initial_val = check_value;
      reduced_tol = check_value * reduce;
    };

  if (check_value < reduced_tol)
    {
      if (_log_result)
	deallog << "Convergence step " << step
		<< " value " << check_value << std::endl;
      lcheck = success;
      return success;
    }
  else
    return SolverControl::check(step, check_value);
};

void
ReductionControl::declare_parameters (ParameterHandler& param)
{
  SolverControl::declare_parameters (param);
  param.declare_entry("Reduction", "1.e-2", Patterns::Double());
}

void
ReductionControl::parse_parameters (ParameterHandler& param)
{
  SolverControl::parse_parameters (param);
  set_reduction (param.get_double("Reduction"));
}

<commit_msg>Check reduced residual for equality as well.<commit_after>//----------------------------  solver_control.cc  ---------------------------
//    $Id$
//    Version: $Name$
//
//    Copyright (C) 1998, 1999, 2000, 2001 by the deal.II authors
//
//    This file is subject to QPL and may not be  distributed
//    without copyright and license information. Please refer
//    to the file deal.II/doc/license.html for the  text  and
//    further information on this license.
//
//----------------------------  solver_control.cc  ---------------------------

#include <base/logstream.h>
#include <base/parameter_handler.h>
#include <lac/solver_control.h>

#include <cmath>
#include <strstream>

/*----------------------- SolverControl ---------------------------------*/

SolverControl::NoConvergence::NoConvergence (const unsigned int last_step,
					     const double       last_residual)
		:
		last_step (last_step),
		last_residual (last_residual)
{};

const char *
SolverControl::NoConvergence::what () const throw ()
{
  				   // have a place where to store the
				   // description of the exception as a char *
				   //
				   // this thing obviously is not multi-threading
				   // safe, but we don't care about that for now
				   //
				   // we need to make this object static, since
				   // we want to return the data stored in it
				   // and therefore need a liftime which is
				   // longer than the execution time of this
				   // function
  static std::string description;
				   // convert the messages printed by the
				   // exceptions into a std::string
  std::ostrstream out;

  out << "Iterative method reported convergence failure in step "
      << last_step << " with residual " << last_residual << std::ends;

  description = out.str();
  return description.c_str();
}

SolverControl::SolverControl (const unsigned int maxiter,
			      const double tolerance,
			      const bool _log_history,
			      const bool _log_result)
		:
		maxsteps(maxiter),
		tol(tolerance),
		lvalue(1.e300),
		lstep(0),
		check_failure(false),
		relative_failure_residual(0),
		failure_residual(0),
		_log_history(_log_history),
		_log_frequency(1),
		_log_result(_log_result)
{};

SolverControl::~SolverControl()
{};

SolverControl::State
SolverControl::check (const unsigned int step,
		      const double check_value)
{
  if (_log_history && ((step % _log_frequency) == 0))
    deallog << "Check " << step << "\t" << check_value << std::endl;

  lstep  = step;
  lvalue = check_value;

  if (step==0)
    {
      if (check_failure)
	failure_residual=relative_failure_residual*check_value;

      if (_log_result)
	deallog << "Starting value " << check_value << std::endl;
    }

  if ((step >= maxsteps) ||
#ifdef HAVE_ISNAN
      isnan(check_value) ||
#else
#  if HAVE_UNDERSCORE_ISNAN
				       // on Microsoft Windows, the
				       // function is called _isnan
      _isnan(check_value) ||
#  endif
#endif
      (check_failure && (check_value > failure_residual))
  )
    {
      if (_log_result)
	deallog << "Failure step " << step
		<< " value " << check_value << std::endl;
      lcheck = failure;
      return failure;
    }

  if (check_value <= tol)
    {
      if (_log_result)
	deallog << "Convergence step " << step
		<< " value " << check_value << std::endl;
      lcheck = success;
      return success;
    }
  lcheck = iterate;
  return iterate;
}

SolverControl::State
SolverControl::last_check() const
{
  return lcheck;
}

double
SolverControl::last_value() const
{
  return lvalue;
}

unsigned int
SolverControl::last_step() const
{
  return lstep;
}

unsigned int
SolverControl::log_frequency (unsigned int f)
{
  if (f==0)
    f = 1;
  unsigned int old = _log_frequency;
  _log_frequency = f;
  return old;
}

void
SolverControl::declare_parameters (ParameterHandler& param)
{
  param.declare_entry ("Max steps", "100", Patterns::Integer());
  param.declare_entry ("Tolerance", "1.e-10", Patterns::Double());
  param.declare_entry ("Log history", "false", Patterns::Bool());
  param.declare_entry ("Log frequency", "1", Patterns::Integer());
  param.declare_entry ("Log result", "true", Patterns::Bool());
}

void SolverControl::parse_parameters (ParameterHandler& param)
{
  set_max_steps (param.get_integer("Max steps"));
  set_tolerance (param.get_double("Tolerance"));
  log_history (param.get_bool("Log history"));
  log_result (param.get_bool("Log result"));
  log_frequency (param.get_integer("Log frequency"));
}

/*----------------------- ReductionControl ---------------------------------*/

ReductionControl::ReductionControl(const unsigned int n,
				   const double tol,
				   const double red,
				   const bool _log_history,
				   const bool _log_result)
		:
		SolverControl (n, tol, _log_history, _log_result),
		reduce(red)
{};

ReductionControl::~ReductionControl()
{};

double
ReductionControl::initial_value() const {
  return initial_val;
};

SolverControl::State
ReductionControl::check (const unsigned int step,
			 const double check_value)
{
				   // if this is the first time we
				   // come here, then store the
				   // residual for later comparisons
  if (step==0)
    {
      initial_val = check_value;
      reduced_tol = check_value * reduce;
    };

				   // check whether desired reduction
				   // has been achieved. also check
				   // for equality in case initial
				   // residual already was zero
  if (check_value <= reduced_tol)
    {
      if (_log_result)
	deallog << "Convergence step " << step
		<< " value " << check_value << std::endl;
      lcheck = success;
      return success;
    }
  else
    return SolverControl::check(step, check_value);
};

void
ReductionControl::declare_parameters (ParameterHandler& param)
{
  SolverControl::declare_parameters (param);
  param.declare_entry("Reduction", "1.e-2", Patterns::Double());
}

void
ReductionControl::parse_parameters (ParameterHandler& param)
{
  SolverControl::parse_parameters (param);
  set_reduction (param.get_double("Reduction"));
}

<|endoftext|>


<commit_before>// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "resource_provider/storage/uri_disk_profile_adaptor.hpp"

#include <map>
#include <string>
#include <tuple>

#include <csi/spec.hpp>

#include <mesos/module/disk_profile_adaptor.hpp>

#include <process/defer.hpp>
#include <process/delay.hpp>
#include <process/dispatch.hpp>
#include <process/future.hpp>
#include <process/owned.hpp>
#include <process/socket.hpp>

#include <stout/duration.hpp>
#include <stout/error.hpp>
#include <stout/json.hpp>
#include <stout/option.hpp>
#include <stout/protobuf.hpp>
#include <stout/result.hpp>
#include <stout/strings.hpp>

#include "csi/utils.hpp"

#include "resource_provider/storage/disk_profile_utils.hpp"

using namespace mesos;
using namespace process;

using std::map;
using std::string;
using std::tuple;

using google::protobuf::Map;

using mesos::resource_provider::DiskProfileMapping;

namespace mesos {
namespace internal {
namespace storage {

bool operator==(
    const Map<string, string>& left,
    const Map<string, string>& right) {
  if (left.size() != right.size()) {
    return false;
  }

  typename Map<string, string>::const_iterator iterator = left.begin();
  while (iterator != left.end()) {
    if (right.count(iterator->first) != 1) {
      return false;
    }

    if (iterator->second != right.at(iterator->first)) {
      return false;
    }
  }

  return true;
}

UriDiskProfileAdaptor::UriDiskProfileAdaptor(const Flags& _flags)
  : flags(_flags),
    process(new UriDiskProfileAdaptorProcess(flags))
{
  spawn(process.get());
}

UriDiskProfileAdaptor::~UriDiskProfileAdaptor()
{
  terminate(process.get());
  wait(process.get());
}

Future<DiskProfileAdaptor::ProfileInfo> UriDiskProfileAdaptor::translate(
    const string& profile,
    const ResourceProviderInfo& resourceProviderInfo)
{
  return dispatch(
      process.get(),
      &UriDiskProfileAdaptorProcess::translate,
      profile,
      resourceProviderInfo);
}

Future<hashset<string>> UriDiskProfileAdaptor::watch(
    const hashset<string>& knownProfiles,
    const ResourceProviderInfo& resourceProviderInfo)
{
  return dispatch(
      process.get(),
      &UriDiskProfileAdaptorProcess::watch,
      knownProfiles,
      resourceProviderInfo);
}

UriDiskProfileAdaptorProcess::UriDiskProfileAdaptorProcess(
    const UriDiskProfileAdaptor::Flags& _flags)
  : ProcessBase(ID::generate("uri-disk-profile-adaptor")),
    flags(_flags),
    watchPromise(new Promise<Nothing>()) {}

void UriDiskProfileAdaptorProcess::initialize()
{
  poll();
}

Future<DiskProfileAdaptor::ProfileInfo>
  UriDiskProfileAdaptorProcess::translate(
      const string& profile,
      const ResourceProviderInfo& resourceProviderInfo)
{
  if (profileMatrix.count(profile) != 1) {
    return Failure("Profile '" + profile + "' not found");
  }

  const DiskProfileMapping::CSIManifest& manifest = profileMatrix.at(profile);

  // TODO(chhsiao): A storage resource provider may need to translate
  // a profile that no longer applies to it to replay a `CREATE_VOLUME`
  // or `CREATE_BLOCK` operation during recovery, so resource provider
  // selection is only done in `watch()` but not here. We should do the
  // selection once profiles are checkpointed in the resource provider.
  return DiskProfileAdaptor::ProfileInfo{
    manifest.volume_capabilities(),
    manifest.create_parameters()
  };
}

Future<hashset<string>> UriDiskProfileAdaptorProcess::watch(
    const hashset<string>& knownProfiles,
    const ResourceProviderInfo& resourceProviderInfo)
{
  // Calculate the new set of profiles for the resource provider.
  // TODO(chhsiao): A storage resource provider assumes that the new set
  // should be a superset of `knownProfiles`, so we bypass resource
  // provider selection if a profile is already known. We should do the
  // selection once profiles are checkpointed in the resource provider.
  hashset<string> newProfiles = knownProfiles;
  foreachpair (const string& profile,
               const DiskProfileMapping::CSIManifest& manifest,
               profileMatrix) {
    if (knownProfiles.contains(profile)) {
      continue;
    }

    if (isSelectedResourceProvider(manifest, resourceProviderInfo)) {
      newProfiles.insert(profile);
    }
  }

  if (newProfiles != knownProfiles) {
    return newProfiles;
  }

  // Wait for the next update if there is no change.
  return watchPromise->future()
    .then(defer(self(), &Self::watch, knownProfiles, resourceProviderInfo));
}

void UriDiskProfileAdaptorProcess::poll()
{
  // NOTE: The flags do not allow relative paths, so this is guaranteed to
  // be either 'http://' or 'https://'.
  if (strings::startsWith(flags.uri, "http")) {
    // NOTE: We already validated that this URI is parsable in the flags.
    Try<http::URL> url = http::URL::parse(flags.uri.string());
    CHECK_SOME(url);

    http::get(url.get())
      .onAny(defer(self(), [=](const Future<http::Response>& future) {
        if (future.isReady()) {
          // NOTE: We don't check the HTTP status code because we don't know
          // what potential codes are considered successful.
          _poll(future->body);
        } else if (future.isFailed()) {
          _poll(Error(future.failure()));
        } else {
          _poll(Error("Future discarded or abandoned"));
        }
      }));
  } else {
    _poll(os::read(flags.uri.string()));
  }
}

void UriDiskProfileAdaptorProcess::_poll(const Try<string>& fetched)
{
  if (fetched.isSome()) {
    Try<DiskProfileMapping> parsed = parseDiskProfileMapping(fetched.get());

    if (parsed.isSome()) {
      notify(parsed.get());
    } else {
      LOG(ERROR) << "Failed to parse result: " << parsed.error();
    }
  } else {
    LOG(WARNING) << "Failed to poll URI: " << fetched.error();
  }

  // TODO(josephw): Do we want to retry if polling fails and no polling
  // interval is set? Or perhaps we should exit in that case?
  if (flags.poll_interval.isSome()) {
    delay(flags.poll_interval.get(), self(), &Self::poll);
  }
}

void UriDiskProfileAdaptorProcess::notify(
    const DiskProfileMapping& parsed)
{
  bool hasErrors = false;

  foreachpair (const string& profile,
               const DiskProfileMapping::CSIManifest& manifest,
               profileMatrix) {
    if (parsed.profile_matrix().count(profile) != 1) {
      hasErrors = true;

      LOG(WARNING)
        << "Fetched profile mapping does not contain profile '" << profile
        << "'. The fetched mapping will be ignored entirely";
      continue;
    }

    bool matchingCapability =
      manifest.volume_capabilities() ==
        parsed.profile_matrix().at(profile).volume_capabilities();

    bool matchingParameters =
      manifest.create_parameters() ==
        parsed.profile_matrix().at(profile).create_parameters();

    if (!matchingCapability || !matchingParameters) {
      hasErrors = true;

      LOG(WARNING)
        << "Fetched profile mapping for profile '" << profile << "'"
        << " does not match earlier data."
        << " The fetched mapping will be ignored entirely";
    }
  }

  // When encountering a data conflict, this module assumes there is a
  // problem upstream (i.e. in the `--uri`). It is up to the operator
  // to notice and resolve this.
  if (hasErrors) {
    return;
  }

  // Profiles can only be added, so if the parsed data is the same size,
  // nothing has changed and no notifications need to be sent.
  if (parsed.profile_matrix().size() <= profileMatrix.size()) {
    return;
  }

  // The fetched mapping satisfies our invariants.

  // Save the protobuf as a map.
  profileMatrix = map<string, DiskProfileMapping::CSIManifest>(
      parsed.profile_matrix().begin(),
      parsed.profile_matrix().end());

  // Notify any watchers and then prepare a new promise for the next
  // iteration of polling.
  //
  // TODO(josephw): Delay this based on the `--max_random_wait` option.
  watchPromise->set(Nothing());
  watchPromise.reset(new Promise<Nothing>());

  LOG(INFO)
    << "Updated disk profile mapping to " << profileMatrix.size()
    << " total profiles";
}

} // namespace storage {
} // namespace internal {
} // namespace mesos {

mesos::modules::Module<DiskProfileAdaptor>
org_apache_mesos_UriDiskProfileAdaptor(
    MESOS_MODULE_API_VERSION,
    MESOS_VERSION,
    "Apache Mesos",
    "modules@mesos.apache.org",
    "URI Disk Profile Adaptor module.",
    nullptr,
    [](const Parameters& parameters) -> DiskProfileAdaptor* {
      // Convert `parameters` into a map.
      map<string, string> values;
      foreach (const Parameter& parameter, parameters.parameter()) {
        values[parameter.key()] = parameter.value();
      }

      // Load and validate flags from the map.
      mesos::internal::storage::UriDiskProfileAdaptor::Flags flags;
      Try<flags::Warnings> load = flags.load(values);

      if (load.isError()) {
        LOG(ERROR) << "Failed to parse parameters: " << load.error();
        return nullptr;
      }

      // Log any flag warnings.
      foreach (const flags::Warning& warning, load->warnings) {
        LOG(WARNING) << warning.message;
      }

      return new mesos::internal::storage::UriDiskProfileAdaptor(flags);
    });
<commit_msg>Made `UriDiskProfileAdaptor` be able to update profile selectors.<commit_after>// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "resource_provider/storage/uri_disk_profile_adaptor.hpp"

#include <map>
#include <string>
#include <tuple>

#include <csi/spec.hpp>

#include <mesos/module/disk_profile_adaptor.hpp>

#include <process/defer.hpp>
#include <process/delay.hpp>
#include <process/dispatch.hpp>
#include <process/future.hpp>
#include <process/owned.hpp>
#include <process/socket.hpp>

#include <stout/duration.hpp>
#include <stout/error.hpp>
#include <stout/json.hpp>
#include <stout/option.hpp>
#include <stout/protobuf.hpp>
#include <stout/result.hpp>
#include <stout/strings.hpp>

#include "csi/utils.hpp"

#include "resource_provider/storage/disk_profile_utils.hpp"

using namespace mesos;
using namespace process;

using std::map;
using std::string;
using std::tuple;

using google::protobuf::Map;

using mesos::resource_provider::DiskProfileMapping;

namespace mesos {
namespace internal {
namespace storage {

bool operator==(
    const Map<string, string>& left,
    const Map<string, string>& right) {
  if (left.size() != right.size()) {
    return false;
  }

  typename Map<string, string>::const_iterator iterator = left.begin();
  while (iterator != left.end()) {
    if (right.count(iterator->first) != 1) {
      return false;
    }

    if (iterator->second != right.at(iterator->first)) {
      return false;
    }
  }

  return true;
}

UriDiskProfileAdaptor::UriDiskProfileAdaptor(const Flags& _flags)
  : flags(_flags),
    process(new UriDiskProfileAdaptorProcess(flags))
{
  spawn(process.get());
}

UriDiskProfileAdaptor::~UriDiskProfileAdaptor()
{
  terminate(process.get());
  wait(process.get());
}

Future<DiskProfileAdaptor::ProfileInfo> UriDiskProfileAdaptor::translate(
    const string& profile,
    const ResourceProviderInfo& resourceProviderInfo)
{
  return dispatch(
      process.get(),
      &UriDiskProfileAdaptorProcess::translate,
      profile,
      resourceProviderInfo);
}

Future<hashset<string>> UriDiskProfileAdaptor::watch(
    const hashset<string>& knownProfiles,
    const ResourceProviderInfo& resourceProviderInfo)
{
  return dispatch(
      process.get(),
      &UriDiskProfileAdaptorProcess::watch,
      knownProfiles,
      resourceProviderInfo);
}

UriDiskProfileAdaptorProcess::UriDiskProfileAdaptorProcess(
    const UriDiskProfileAdaptor::Flags& _flags)
  : ProcessBase(ID::generate("uri-disk-profile-adaptor")),
    flags(_flags),
    watchPromise(new Promise<Nothing>()) {}

void UriDiskProfileAdaptorProcess::initialize()
{
  poll();
}

Future<DiskProfileAdaptor::ProfileInfo>
  UriDiskProfileAdaptorProcess::translate(
      const string& profile,
      const ResourceProviderInfo& resourceProviderInfo)
{
  if (profileMatrix.count(profile) != 1) {
    return Failure("Profile '" + profile + "' not found");
  }

  const DiskProfileMapping::CSIManifest& manifest = profileMatrix.at(profile);

  // TODO(chhsiao): A storage resource provider may need to translate
  // a profile that no longer applies to it to replay a `CREATE_VOLUME`
  // or `CREATE_BLOCK` operation during recovery, so resource provider
  // selection is only done in `watch()` but not here. We should do the
  // selection once profiles are checkpointed in the resource provider.
  return DiskProfileAdaptor::ProfileInfo{
    manifest.volume_capabilities(),
    manifest.create_parameters()
  };
}

Future<hashset<string>> UriDiskProfileAdaptorProcess::watch(
    const hashset<string>& knownProfiles,
    const ResourceProviderInfo& resourceProviderInfo)
{
  // Calculate the new set of profiles for the resource provider.
  // TODO(chhsiao): A storage resource provider assumes that the new set
  // should be a superset of `knownProfiles`, so we bypass resource
  // provider selection if a profile is already known. We should do the
  // selection once profiles are checkpointed in the resource provider.
  hashset<string> newProfiles = knownProfiles;
  foreachpair (const string& profile,
               const DiskProfileMapping::CSIManifest& manifest,
               profileMatrix) {
    if (knownProfiles.contains(profile)) {
      continue;
    }

    if (isSelectedResourceProvider(manifest, resourceProviderInfo)) {
      newProfiles.insert(profile);
    }
  }

  if (newProfiles != knownProfiles) {
    return newProfiles;
  }

  // Wait for the next update if there is no change.
  return watchPromise->future()
    .then(defer(self(), &Self::watch, knownProfiles, resourceProviderInfo));
}

void UriDiskProfileAdaptorProcess::poll()
{
  // NOTE: The flags do not allow relative paths, so this is guaranteed to
  // be either 'http://' or 'https://'.
  if (strings::startsWith(flags.uri, "http")) {
    // NOTE: We already validated that this URI is parsable in the flags.
    Try<http::URL> url = http::URL::parse(flags.uri.string());
    CHECK_SOME(url);

    http::get(url.get())
      .onAny(defer(self(), [=](const Future<http::Response>& future) {
        if (future.isReady()) {
          // NOTE: We don't check the HTTP status code because we don't know
          // what potential codes are considered successful.
          _poll(future->body);
        } else if (future.isFailed()) {
          _poll(Error(future.failure()));
        } else {
          _poll(Error("Future discarded or abandoned"));
        }
      }));
  } else {
    _poll(os::read(flags.uri.string()));
  }
}

void UriDiskProfileAdaptorProcess::_poll(const Try<string>& fetched)
{
  if (fetched.isSome()) {
    Try<DiskProfileMapping> parsed = parseDiskProfileMapping(fetched.get());

    if (parsed.isSome()) {
      notify(parsed.get());
    } else {
      LOG(ERROR) << "Failed to parse result: " << parsed.error();
    }
  } else {
    LOG(WARNING) << "Failed to poll URI: " << fetched.error();
  }

  // TODO(josephw): Do we want to retry if polling fails and no polling
  // interval is set? Or perhaps we should exit in that case?
  if (flags.poll_interval.isSome()) {
    delay(flags.poll_interval.get(), self(), &Self::poll);
  }
}

void UriDiskProfileAdaptorProcess::notify(
    const DiskProfileMapping& parsed)
{
  bool hasErrors = false;

  foreachpair (const string& profile,
               const DiskProfileMapping::CSIManifest& manifest,
               profileMatrix) {
    if (parsed.profile_matrix().count(profile) != 1) {
      hasErrors = true;

      LOG(WARNING)
        << "Fetched profile mapping does not contain profile '" << profile
        << "'. The fetched mapping will be ignored entirely";
      continue;
    }

    bool matchingCapability =
      manifest.volume_capabilities() ==
        parsed.profile_matrix().at(profile).volume_capabilities();

    bool matchingParameters =
      manifest.create_parameters() ==
        parsed.profile_matrix().at(profile).create_parameters();

    if (!matchingCapability || !matchingParameters) {
      hasErrors = true;

      LOG(WARNING)
        << "Fetched profile mapping for profile '" << profile << "'"
        << " does not match earlier data."
        << " The fetched mapping will be ignored entirely";
    }
  }

  // When encountering a data conflict, this module assumes there is a
  // problem upstream (i.e. in the `--uri`). It is up to the operator
  // to notice and resolve this.
  if (hasErrors) {
    return;
  }

  // TODO(chhsiao): No need to update the profile matrix and send notifications
  // if the parsed mapping has the same size and profile selectors.

  // The fetched mapping satisfies our invariants.

  // Save the protobuf as a map.
  profileMatrix = map<string, DiskProfileMapping::CSIManifest>(
      parsed.profile_matrix().begin(),
      parsed.profile_matrix().end());

  // Notify any watchers and then prepare a new promise for the next
  // iteration of polling.
  //
  // TODO(josephw): Delay this based on the `--max_random_wait` option.
  watchPromise->set(Nothing());
  watchPromise.reset(new Promise<Nothing>());

  LOG(INFO)
    << "Updated disk profile mapping to " << profileMatrix.size()
    << " total profiles";
}

} // namespace storage {
} // namespace internal {
} // namespace mesos {

mesos::modules::Module<DiskProfileAdaptor>
org_apache_mesos_UriDiskProfileAdaptor(
    MESOS_MODULE_API_VERSION,
    MESOS_VERSION,
    "Apache Mesos",
    "modules@mesos.apache.org",
    "URI Disk Profile Adaptor module.",
    nullptr,
    [](const Parameters& parameters) -> DiskProfileAdaptor* {
      // Convert `parameters` into a map.
      map<string, string> values;
      foreach (const Parameter& parameter, parameters.parameter()) {
        values[parameter.key()] = parameter.value();
      }

      // Load and validate flags from the map.
      mesos::internal::storage::UriDiskProfileAdaptor::Flags flags;
      Try<flags::Warnings> load = flags.load(values);

      if (load.isError()) {
        LOG(ERROR) << "Failed to parse parameters: " << load.error();
        return nullptr;
      }

      // Log any flag warnings.
      foreach (const flags::Warning& warning, load->warnings) {
        LOG(WARNING) << warning.message;
      }

      return new mesos::internal::storage::UriDiskProfileAdaptor(flags);
    });
<|endoftext|>


<commit_before>/**
 * @file ngram_word_analyzer.cpp
 * @author Sean Massung
 */

#include "cpptoml.h"
#include "corpus/document.h"
#include "analyzers/ngram/ngram_word_analyzer.h"
#include "analyzers/token_stream.h"

namespace meta {
namespace analyzers {

ngram_word_analyzer::ngram_word_analyzer(uint16_t n,
                                         std::unique_ptr<token_stream> stream)
    : base{n}, stream_{std::move(stream)}
{
    // nothing
}

ngram_word_analyzer::ngram_word_analyzer(const ngram_word_analyzer& other)
    : base{other.n_value()}, stream_{other.stream_->clone()}
{
    // nothing
}

void ngram_word_analyzer::tokenize(corpus::document & doc)
{
    // first, get tokens
    stream_->set_content(get_content(doc));
    std::vector<std::string> tokens;
    while (*stream_)
        tokens.push_back(stream_->next());

    // second, create ngrams from them
    for(size_t i = n_value() - 1; i < tokens.size(); ++i)
    {
        std::string combined = tokens[i];
        for(size_t j = 1; j < n_value(); ++j)
            combined = tokens[i - j] + "_" + combined;

        doc.increment(combined, 1);
    }
}

}
}
<commit_msg>Clean up includes for ngram_word_analyzer.cpp<commit_after>/**
 * @file ngram_word_analyzer.cpp
 * @author Sean Massung
 */

#include <string>
#include <vector>

#include "corpus/document.h"
#include "analyzers/ngram/ngram_word_analyzer.h"
#include "analyzers/token_stream.h"

namespace meta {
namespace analyzers {

ngram_word_analyzer::ngram_word_analyzer(uint16_t n,
                                         std::unique_ptr<token_stream> stream)
    : base{n}, stream_{std::move(stream)}
{
    // nothing
}

ngram_word_analyzer::ngram_word_analyzer(const ngram_word_analyzer& other)
    : base{other.n_value()}, stream_{other.stream_->clone()}
{
    // nothing
}

void ngram_word_analyzer::tokenize(corpus::document & doc)
{
    // first, get tokens
    stream_->set_content(get_content(doc));
    std::vector<std::string> tokens;
    while (*stream_)
        tokens.push_back(stream_->next());

    // second, create ngrams from them
    for(size_t i = n_value() - 1; i < tokens.size(); ++i)
    {
        std::string combined = tokens[i];
        for(size_t j = 1; j < n_value(); ++j)
            combined = tokens[i - j] + "_" + combined;

        doc.increment(combined, 1);
    }
}

}
}
<|endoftext|>


<commit_before>// Copyright (C) 2015 The Regents of the University of California (Regents).
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//
//     * Redistributions in binary form must reproduce the above
//       copyright notice, this list of conditions and the following
//       disclaimer in the documentation and/or other materials provided
//       with the distribution.
//
//     * Neither the name of The Regents or University of California nor the
//       names of its contributors may be used to endorse or promote products
//       derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// Please contact the author of this library if you have any questions.
// Author: Chris Sweeney (cmsweeney@cs.ucsb.edu)

#include "theia/sfm/bundle_adjustment/bundle_adjust_two_views.h"

#include <ceres/ceres.h>
#include <Eigen/Core>
#include <vector>

#include "theia/util/timer.h"
#include "theia/sfm/bundle_adjustment/angular_epipolar_error.h"
#include "theia/sfm/bundle_adjustment/bundle_adjustment.h"
#include "theia/sfm/bundle_adjustment/unit_norm_three_vector_parameterization.h"
#include "theia/sfm/camera/camera.h"
#include "theia/sfm/camera/camera_intrinsics.h"
#include "theia/sfm/camera/reprojection_error.h"
#include "theia/matching/feature_correspondence.h"
#include "theia/sfm/triangulation/triangulation.h"
#include "theia/sfm/twoview_info.h"
#include "theia/sfm/types.h"

namespace theia {

namespace {

void SetSolverOptions(const BundleAdjustmentOptions& options,
                      ceres::Solver::Options* solver_options) {
  CHECK_NOTNULL(solver_options);
  solver_options->linear_solver_type = ceres::DENSE_SCHUR;
  solver_options->visibility_clustering_type = ceres::SINGLE_LINKAGE;
  solver_options->logging_type = ceres::SILENT;
  solver_options->num_threads = options.num_threads;
  solver_options->num_linear_solver_threads = options.num_threads;
  solver_options->max_num_iterations = 200;
  // Solver options takes ownership of the ordering so that we can order the BA
  // problem by points and cameras.
  solver_options->linear_solver_ordering.reset(
      new ceres::ParameterBlockOrdering);
}

void SetCamera(const double focal_length,
               const double principal_point[2],
               const Eigen::Vector3d& position,
               const Eigen::Vector3d& rotation,
               Camera* camera) {
  camera->SetFocalLength(focal_length);
  camera->SetPrincipalPoint(principal_point[0],
                             principal_point[1]);
  camera->SetPosition(position);
  camera->SetOrientationFromAngleAxis(rotation);
}

void AddCameraParametersToProblem(const bool constant_camera_parameters,
                                  double* camera_parameters,
                                  ceres::Problem* problem) {
  // Keep the intrinsic parameters constant.
  std::vector<int> constant_intrinsics;
  for (int i = 0; i < Camera::kIntrinsicsSize; i++) {
    constant_intrinsics.push_back(Camera::kExtrinsicsSize + i);
  }
  ceres::SubsetParameterization* subset_parameterization =
      new ceres::SubsetParameterization(Camera::kParameterSize,
                                        constant_intrinsics);
  problem->AddParameterBlock(camera_parameters, Camera::kParameterSize,
                             subset_parameterization);

  if (constant_camera_parameters) {
    problem->SetParameterBlockConstant(camera_parameters);
  }
}

void TriangulatePoints(
    const Camera& camera1,
    const Camera& camera2,
    const std::vector<FeatureCorrespondence>& correspondences,
    std::vector<Eigen::Vector4d>* tracks) {
  Matrix3x4d projection_matrix1, projection_matrix2;
  camera1.GetProjectionMatrix(&projection_matrix1);
  camera2.GetProjectionMatrix(&projection_matrix2);

  tracks->resize(correspondences.size());
  for (int i = 0; i < correspondences.size(); i++) {
    Triangulate(projection_matrix1,
                projection_matrix2,
                correspondences[i].feature1,
                correspondences[i].feature2,
                &(*tracks)[i]);
  }
}

}  // namespace

// Triangulates all 3d points and performs standard bundle adjustment on the
// points and cameras.
BundleAdjustmentSummary BundleAdjustTwoViews(
    const BundleAdjustmentOptions& options,
    const std::vector<FeatureCorrespondence>& correspondences,
    const CameraIntrinsics& intrinsics1,
    const CameraIntrinsics& intrinsics2,
    TwoViewInfo* info) {
  CHECK_NOTNULL(info);

  BundleAdjustmentSummary summary;

  // Start setup timer.
  Timer timer;

  // Set problem options.
  ceres::Problem::Options problem_options;
  ceres::Problem problem(problem_options);

  // Set solver options.
  ceres::Solver::Options solver_options;
  SetSolverOptions(options, &solver_options);
  ceres::ParameterBlockOrdering* parameter_ordering =
      solver_options.linear_solver_ordering.get();

  // Set cameras from two view info.
  Camera camera1, camera2;
  SetCamera(info->focal_length_1,
            intrinsics1.principal_point,
            Eigen::Vector3d::Zero(),
            Eigen::Vector3d::Zero(),
            &camera1);
  SetCamera(info->focal_length_2,
            intrinsics2.principal_point,
            info->position_2,
            info->rotation_2,
            &camera2);

  // Add the two cameras as parameter blocks.
  AddCameraParametersToProblem(true, camera1.mutable_parameters(), &problem);
  AddCameraParametersToProblem(false, camera2.mutable_parameters(), &problem);
  parameter_ordering->AddElementToGroup(camera1.mutable_parameters(), 1);
  parameter_ordering->AddElementToGroup(camera2.mutable_parameters(), 1);

  // Triangulate all features.
  std::vector<Eigen::Vector4d> tracks;
  TriangulatePoints(camera1, camera2, correspondences, &tracks);

  // Add triangulated points to the problem.
  for (int i = 0; i < correspondences.size(); i++) {
    const FeatureCorrespondence& match = correspondences[i];
    problem.AddResidualBlock(
        ReprojectionError::Create(match.feature1),
        NULL,
        camera1.mutable_parameters(),
        tracks[i].data());
    problem.AddResidualBlock(
        ReprojectionError::Create(match.feature2),
        NULL,
        camera2.mutable_parameters(),
        tracks[i].data());

    parameter_ordering->AddElementToGroup(tracks[i].data(), 0);
  }

  // End setup time.
  summary.setup_time_in_seconds = timer.ElapsedTimeInSeconds();

  // Solve the problem.
  ceres::Solver::Summary solver_summary;
  ceres::Solve(solver_options, &problem, &solver_summary);
  LOG_IF(INFO, options.verbose) << solver_summary.FullReport();

  // Set the BundleAdjustmentSummary.
  summary.solve_time_in_seconds = solver_summary.total_time_in_seconds;
  summary.initial_cost = solver_summary.initial_cost;
  summary.final_cost = solver_summary.final_cost;

  // This only indicates whether the optimization was successfully run and makes
  // no guarantees on the quality or convergence.
  summary.success = solver_summary.termination_type != ceres::FAILURE;

  // Update the relative pose.
  info->rotation_2 = camera2.GetOrientationAsAngleAxis();
  info->position_2 = camera2.GetPosition();
  info->position_2.normalize();

  return summary;
}

BundleAdjustmentSummary BundleAdjustTwoViewsAngular(
    const BundleAdjustmentOptions& options,
    const std::vector<FeatureCorrespondence>& correspondences,
    TwoViewInfo* info) {
  CHECK_NOTNULL(info);

  BundleAdjustmentSummary summary;

  // Start setup timer.
  Timer timer;

  // Set problem options.
  ceres::Problem::Options problem_options;

  ceres::Problem problem(problem_options);

  // Set solver options.
  ceres::Solver::Options solver_options;
  SetSolverOptions(options, &solver_options);
  // Allow Ceres to determine the ordering.
  solver_options.linear_solver_ordering.reset();

  // Add the relative rotation as a parameter block.
  const int kParameterBlockSize = 3;
  problem.AddParameterBlock(info->rotation_2.data(), kParameterBlockSize);
  // Add the position as a parameter block, ensuring that the norm is 1.
  ceres::LocalParameterization* position_parameterization =
      new ceres::AutoDiffLocalParameterization<
          UnitNormThreeVectorParameterization, 3, 3>;
  problem.AddParameterBlock(info->position_2.data(),
                            kParameterBlockSize,
                            position_parameterization);

  // Add all the epipolar constraints from feature matches.
  for (const FeatureCorrespondence& match : correspondences) {
    problem.AddResidualBlock(
        AngularEpipolarError::Create(match.feature1, match.feature2),
        NULL,
        info->rotation_2.data(),
        info->position_2.data());
  }

  // End setup time.
  summary.setup_time_in_seconds = timer.ElapsedTimeInSeconds();

  // Solve the problem.
  ceres::Solver::Summary solver_summary;
  ceres::Solve(solver_options, &problem, &solver_summary);
  LOG_IF(INFO, options.verbose) << solver_summary.FullReport();

  // Set the BundleAdjustmentSummary.
  summary.solve_time_in_seconds = solver_summary.total_time_in_seconds;
  summary.initial_cost = solver_summary.initial_cost;
  summary.final_cost = solver_summary.final_cost;

  // This only indicates whether the optimization was successfully run and makes
  // no guarantees on the quality or convergence.
  summary.success = solver_summary.termination_type != ceres::FAILURE;
  return summary;
}

}  // namespace theia
<commit_msg>Two view BA will no longer use badly triangulated points<commit_after>// Copyright (C) 2015 The Regents of the University of California (Regents).
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//
//     * Redistributions in binary form must reproduce the above
//       copyright notice, this list of conditions and the following
//       disclaimer in the documentation and/or other materials provided
//       with the distribution.
//
//     * Neither the name of The Regents or University of California nor the
//       names of its contributors may be used to endorse or promote products
//       derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// Please contact the author of this library if you have any questions.
// Author: Chris Sweeney (cmsweeney@cs.ucsb.edu)

#include "theia/sfm/bundle_adjustment/bundle_adjust_two_views.h"

#include <ceres/ceres.h>
#include <Eigen/Core>
#include <vector>

#include "theia/util/timer.h"
#include "theia/sfm/bundle_adjustment/angular_epipolar_error.h"
#include "theia/sfm/bundle_adjustment/bundle_adjustment.h"
#include "theia/sfm/bundle_adjustment/unit_norm_three_vector_parameterization.h"
#include "theia/sfm/camera/camera.h"
#include "theia/sfm/camera/camera_intrinsics.h"
#include "theia/sfm/camera/reprojection_error.h"
#include "theia/matching/feature_correspondence.h"
#include "theia/sfm/triangulation/triangulation.h"
#include "theia/sfm/twoview_info.h"
#include "theia/sfm/types.h"

namespace theia {

namespace {

void SetSolverOptions(const BundleAdjustmentOptions& options,
                      ceres::Solver::Options* solver_options) {
  CHECK_NOTNULL(solver_options);
  solver_options->linear_solver_type = ceres::DENSE_SCHUR;
  solver_options->visibility_clustering_type = ceres::SINGLE_LINKAGE;
  solver_options->logging_type = ceres::SILENT;
  solver_options->num_threads = options.num_threads;
  solver_options->num_linear_solver_threads = options.num_threads;
  solver_options->max_num_iterations = 200;
  // Solver options takes ownership of the ordering so that we can order the BA
  // problem by points and cameras.
  solver_options->linear_solver_ordering.reset(
      new ceres::ParameterBlockOrdering);
}

void SetCamera(const double focal_length,
               const double principal_point[2],
               const Eigen::Vector3d& position,
               const Eigen::Vector3d& rotation,
               Camera* camera) {
  camera->SetFocalLength(focal_length);
  camera->SetPrincipalPoint(principal_point[0],
                             principal_point[1]);
  camera->SetPosition(position);
  camera->SetOrientationFromAngleAxis(rotation);
}

void AddCameraParametersToProblem(const bool constant_camera_parameters,
                                  double* camera_parameters,
                                  ceres::Problem* problem) {
  // Keep the intrinsic parameters constant.
  std::vector<int> constant_intrinsics;
  for (int i = 0; i < Camera::kIntrinsicsSize; i++) {
    constant_intrinsics.push_back(Camera::kExtrinsicsSize + i);
  }
  ceres::SubsetParameterization* subset_parameterization =
      new ceres::SubsetParameterization(Camera::kParameterSize,
                                        constant_intrinsics);
  problem->AddParameterBlock(camera_parameters, Camera::kParameterSize,
                             subset_parameterization);

  if (constant_camera_parameters) {
    problem->SetParameterBlockConstant(camera_parameters);
  }
}

void TriangulatePoints(
    const Camera& camera1,
    const Camera& camera2,
    const std::vector<FeatureCorrespondence>& correspondences,
    std::vector<FeatureCorrespondence>* triangulated_matches,
    std::vector<Eigen::Vector4d>* tracks) {
  Matrix3x4d projection_matrix1, projection_matrix2;
  camera1.GetProjectionMatrix(&projection_matrix1);
  camera2.GetProjectionMatrix(&projection_matrix2);

  triangulated_matches->reserve(correspondences.size());
  tracks->reserve(correspondences.size());
  for (int i = 0; i < correspondences.size(); i++) {
    Eigen::Vector4d point;

    if (Triangulate(projection_matrix1,
                    projection_matrix2,
                    correspondences[i].feature1,
                    correspondences[i].feature2,
                    &point)) {
      tracks->emplace_back(point);
      triangulated_matches->emplace_back(correspondences[i]);
    }
  }
}

}  // namespace

// Triangulates all 3d points and performs standard bundle adjustment on the
// points and cameras.
BundleAdjustmentSummary BundleAdjustTwoViews(
    const BundleAdjustmentOptions& options,
    const std::vector<FeatureCorrespondence>& correspondences,
    const CameraIntrinsics& intrinsics1,
    const CameraIntrinsics& intrinsics2,
    TwoViewInfo* info) {
  CHECK_NOTNULL(info);

  BundleAdjustmentSummary summary;

  // Start setup timer.
  Timer timer;

  // Set problem options.
  ceres::Problem::Options problem_options;
  ceres::Problem problem(problem_options);

  // Set solver options.
  ceres::Solver::Options solver_options;
  SetSolverOptions(options, &solver_options);
  ceres::ParameterBlockOrdering* parameter_ordering =
      solver_options.linear_solver_ordering.get();

  // Set cameras from two view info.
  Camera camera1, camera2;
  SetCamera(info->focal_length_1,
            intrinsics1.principal_point,
            Eigen::Vector3d::Zero(),
            Eigen::Vector3d::Zero(),
            &camera1);
  SetCamera(info->focal_length_2,
            intrinsics2.principal_point,
            info->position_2,
            info->rotation_2,
            &camera2);

  // Add the two cameras as parameter blocks.
  AddCameraParametersToProblem(true, camera1.mutable_parameters(), &problem);
  AddCameraParametersToProblem(false, camera2.mutable_parameters(), &problem);
  parameter_ordering->AddElementToGroup(camera1.mutable_parameters(), 1);
  parameter_ordering->AddElementToGroup(camera2.mutable_parameters(), 1);

  // Triangulate all features.
  std::vector<FeatureCorrespondence> triangulated_matches;
  std::vector<Eigen::Vector4d> tracks;
  TriangulatePoints(camera1,
                    camera2,
                    correspondences,
                    &triangulated_matches,
                    &tracks);

  // Add triangulated points to the problem.
  for (int i = 0; i < triangulated_matches.size(); i++) {
    const FeatureCorrespondence& match = triangulated_matches[i];
    problem.AddResidualBlock(
        ReprojectionError::Create(match.feature1),
        NULL,
        camera1.mutable_parameters(),
        tracks[i].data());
    problem.AddResidualBlock(
        ReprojectionError::Create(match.feature2),
        NULL,
        camera2.mutable_parameters(),
        tracks[i].data());

    parameter_ordering->AddElementToGroup(tracks[i].data(), 0);
  }

  // End setup time.
  summary.setup_time_in_seconds = timer.ElapsedTimeInSeconds();

  // Solve the problem.
  ceres::Solver::Summary solver_summary;
  ceres::Solve(solver_options, &problem, &solver_summary);
  LOG_IF(INFO, options.verbose) << solver_summary.FullReport();

  // Set the BundleAdjustmentSummary.
  summary.solve_time_in_seconds = solver_summary.total_time_in_seconds;
  summary.initial_cost = solver_summary.initial_cost;
  summary.final_cost = solver_summary.final_cost;

  // This only indicates whether the optimization was successfully run and makes
  // no guarantees on the quality or convergence.
  summary.success = solver_summary.termination_type != ceres::FAILURE;

  // Update the relative pose.
  info->rotation_2 = camera2.GetOrientationAsAngleAxis();
  info->position_2 = camera2.GetPosition();
  info->position_2.normalize();

  return summary;
}

BundleAdjustmentSummary BundleAdjustTwoViewsAngular(
    const BundleAdjustmentOptions& options,
    const std::vector<FeatureCorrespondence>& correspondences,
    TwoViewInfo* info) {
  CHECK_NOTNULL(info);

  BundleAdjustmentSummary summary;

  // Start setup timer.
  Timer timer;

  // Set problem options.
  ceres::Problem::Options problem_options;

  ceres::Problem problem(problem_options);

  // Set solver options.
  ceres::Solver::Options solver_options;
  SetSolverOptions(options, &solver_options);
  // Allow Ceres to determine the ordering.
  solver_options.linear_solver_ordering.reset();

  // Add the relative rotation as a parameter block.
  const int kParameterBlockSize = 3;
  problem.AddParameterBlock(info->rotation_2.data(), kParameterBlockSize);
  // Add the position as a parameter block, ensuring that the norm is 1.
  ceres::LocalParameterization* position_parameterization =
      new ceres::AutoDiffLocalParameterization<
          UnitNormThreeVectorParameterization, 3, 3>;
  problem.AddParameterBlock(info->position_2.data(),
                            kParameterBlockSize,
                            position_parameterization);

  // Add all the epipolar constraints from feature matches.
  for (const FeatureCorrespondence& match : correspondences) {
    problem.AddResidualBlock(
        AngularEpipolarError::Create(match.feature1, match.feature2),
        NULL,
        info->rotation_2.data(),
        info->position_2.data());
  }

  // End setup time.
  summary.setup_time_in_seconds = timer.ElapsedTimeInSeconds();

  // Solve the problem.
  ceres::Solver::Summary solver_summary;
  ceres::Solve(solver_options, &problem, &solver_summary);
  LOG_IF(INFO, options.verbose) << solver_summary.FullReport();

  // Set the BundleAdjustmentSummary.
  summary.solve_time_in_seconds = solver_summary.total_time_in_seconds;
  summary.initial_cost = solver_summary.initial_cost;
  summary.final_cost = solver_summary.final_cost;

  // This only indicates whether the optimization was successfully run and makes
  // no guarantees on the quality or convergence.
  summary.success = solver_summary.termination_type != ceres::FAILURE;
  return summary;
}

}  // namespace theia
<|endoftext|>


<commit_before><commit_msg>missing file<commit_after><|endoftext|>


<commit_before>// Copyright (c) 2018 The Bitcoin Core developers
// Copyright (c) 2014-2019 The Auroracoin developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <stdio.h>
#include <util/system.h>
#include <walletinitinterface.h>

class CWallet;

namespace interfaces {
class Chain;
}

class DummyWalletInit : public WalletInitInterface {
public:

    bool HasWalletSupport() const override {return false;}
    void AddWalletOptions() const override;
    bool ParameterInteraction() const override {return true;}
    void Construct(InitInterfaces& interfaces) const override {LogPrintf("No wallet support compiled in!\n");}
};

void DummyWalletInit::AddWalletOptions() const
{
    std::vector<std::string> opts = {"-addresstype", "-changetype", "-disablewallet", "-discardfee=<amt>", "-fallbackfee=<amt>",
        "-keypool=<n>", "-mintxfee=<amt>", "-paytxfee=<amt>", "-rescan", "-salvagewallet", "-spendzeroconfchange",  "-txconfirmtarget=<n>",
        "-upgradewallet", "-wallet=<path>", "-walletbroadcast", "-walletdir=<dir>", "-walletnotify=<cmd>", "-walletrbf", "-zapwallettxes=<mode>",
        "-dblogsize=<n>", "-flushwallet", "-privdb", "-walletrejectlongchains"};
    gArgs.AddHiddenArgs(opts);
}

const WalletInitInterface& g_wallet_init_interface = DummyWalletInit();

fs::path GetWalletDir()
{
    throw std::logic_error("Wallet function called in non-wallet build.");
}

std::vector<fs::path> ListWalletDir()
{
    throw std::logic_error("Wallet function called in non-wallet build.");
}

std::vector<std::shared_ptr<CWallet>> GetWallets()
{
    throw std::logic_error("Wallet function called in non-wallet build.");
}

std::shared_ptr<CWallet> LoadWallet(interfaces::Chain& chain, const std::string& name, std::string& error, std::string& warning)
{
    throw std::logic_error("Wallet function called in non-wallet build.");
}

namespace interfaces {

class Wallet;

std::unique_ptr<Wallet> MakeWallet(const std::shared_ptr<CWallet>& wallet)
{
    throw std::logic_error("Wallet function called in non-wallet build.");
}

} // namespace interfaces<commit_msg>Bitcoin: 206c30f6d7ff9fbcdb0f0b882e8da54870f8ee73 (dummywallet: Reformat ignored wallet options list).<commit_after>// Copyright (c) 2018 The Bitcoin Core developers
// Copyright (c) 2014-2019 The Auroracoin developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <stdio.h>
#include <util/system.h>
#include <walletinitinterface.h>

class CWallet;

namespace interfaces {
class Chain;
}

class DummyWalletInit : public WalletInitInterface {
public:

    bool HasWalletSupport() const override {return false;}
    void AddWalletOptions() const override;
    bool ParameterInteraction() const override {return true;}
    void Construct(InitInterfaces& interfaces) const override {LogPrintf("No wallet support compiled in!\n");}
};

void DummyWalletInit::AddWalletOptions() const
{
    std::vector<std::string> opts = {
        "-addresstype",
        "-changetype",
        "-disablewallet",
        "-discardfee=<amt>",
        "-fallbackfee=<amt>",
        "-keypool=<n>",
        "-mintxfee=<amt>",
        "-paytxfee=<amt>",
        "-rescan",
        "-salvagewallet",
        "-spendzeroconfchange",
        "-txconfirmtarget=<n>",
        "-upgradewallet",
        "-wallet=<path>",
        "-walletbroadcast",
        "-walletdir=<dir>",
        "-walletnotify=<cmd>",
        "-walletrbf",
        "-zapwallettxes=<mode>",
        "-dblogsize=<n>",
        "-flushwallet",
        "-privdb",
        "-walletrejectlongchains",
    };
    gArgs.AddHiddenArgs(opts);
}

const WalletInitInterface& g_wallet_init_interface = DummyWalletInit();

fs::path GetWalletDir()
{
    throw std::logic_error("Wallet function called in non-wallet build.");
}

std::vector<fs::path> ListWalletDir()
{
    throw std::logic_error("Wallet function called in non-wallet build.");
}

std::vector<std::shared_ptr<CWallet>> GetWallets()
{
    throw std::logic_error("Wallet function called in non-wallet build.");
}

std::shared_ptr<CWallet> LoadWallet(interfaces::Chain& chain, const std::string& name, std::string& error, std::string& warning)
{
    throw std::logic_error("Wallet function called in non-wallet build.");
}

namespace interfaces {

class Wallet;

std::unique_ptr<Wallet> MakeWallet(const std::shared_ptr<CWallet>& wallet)
{
    throw std::logic_error("Wallet function called in non-wallet build.");
}

} // namespace interfaces<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: AccessibleSpreadsheet.hxx,v $
 *
 *  $Revision: 1.22 $
 *
 *  last change: $Author: sab $ $Date: 2002-11-05 07:56:44 $
 *
 *  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, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 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 EXPRESSED 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: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _SC_ACCESSIBLESPREADSHEET_HXX
#define _SC_ACCESSIBLESPREADSHEET_HXX

#include "AccessibleTableBase.hxx"
#ifndef SC_VIEWDATA_HXX
#include "viewdata.hxx"
#endif

#include <vector>

class ScMyAddress : public ScAddress
{
public:
    ScMyAddress() : ScAddress() {}
    ScMyAddress(sal_uInt16 nCol, sal_uInt16 nRow, sal_uInt16 nTab) : ScAddress(nCol, nRow, nTab) {}
    ScMyAddress(const ScAddress& rAddress) : ScAddress(rAddress) {}

    sal_Bool operator< ( const ScMyAddress& rAddress ) const
    {
        if( Row() != rAddress.Row() )
            return (Row() < rAddress.Row());
        else
            return (Col() < rAddress.Col());
    }
};

class ScTabViewShell;
class ScAccessibleDocument;
class ScAccessibleCell;

/** @descr
        This base class provides an implementation of the
        AccessibleTable service.
*/
class ScAccessibleSpreadsheet
    :   public  ScAccessibleTableBase
{
public:
    //=====  internal  ========================================================
    ScAccessibleSpreadsheet(
        ScAccessibleDocument* pAccDoc,
        ScTabViewShell* pViewShell,
        sal_uInt16  nTab,
        ScSplitPos eSplitPos);
protected:
    virtual ~ScAccessibleSpreadsheet();
public:

     virtual void SAL_CALL disposing();

    void CompleteSelectionChanged(sal_Bool bNewState);

    virtual void LostFocus();

    virtual void GotFocus();

    void BoundingBoxChanged();

    void VisAreaChanged();

    ///=====  SfxListener  =====================================================

    virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );

    ///=====  XAccessibleTable  ================================================

    /// Returns the selected rows in a table.
    virtual ::com::sun::star::uno::Sequence< sal_Int32 > SAL_CALL
                getSelectedAccessibleRows(  )
                    throw (::com::sun::star::uno::RuntimeException);

    /// Returns the selected columns in a table.
    virtual ::com::sun::star::uno::Sequence< sal_Int32 > SAL_CALL
                getSelectedAccessibleColumns(  )
                    throw (::com::sun::star::uno::RuntimeException);

    /// Returns a boolean value indicating whether the specified row is selected.
    virtual sal_Bool SAL_CALL
                isAccessibleRowSelected( sal_Int32 nRow )
                    throw (::com::sun::star::uno::RuntimeException,
                    ::com::sun::star::lang::IndexOutOfBoundsException);

    /// Returns a boolean value indicating whether the specified column is selected.
    virtual sal_Bool SAL_CALL
                isAccessibleColumnSelected( sal_Int32 nColumn )
                    throw (::com::sun::star::uno::RuntimeException,
                    ::com::sun::star::lang::IndexOutOfBoundsException);

    /// Returns the Accessible at a specified row and column in the table.
    virtual ::com::sun::star::uno::Reference< ::drafts::com::sun::star::accessibility::XAccessible > SAL_CALL
                getAccessibleCellAt( sal_Int32 nRow, sal_Int32 nColumn )
                    throw (::com::sun::star::uno::RuntimeException,
                            ::com::sun::star::lang::IndexOutOfBoundsException);

    ScAccessibleCell* GetAccessibleCellAt(sal_Int32 nRow, sal_Int32 nColumn);

    /// Returns a boolean value indicating whether the accessible at a specified row and column is selected.
    virtual sal_Bool SAL_CALL
                isAccessibleSelected( sal_Int32 nRow, sal_Int32 nColumn )
                    throw (::com::sun::star::uno::RuntimeException,
                    ::com::sun::star::lang::IndexOutOfBoundsException);

    ///=====  XAccessibleComponent  ============================================

    virtual ::com::sun::star::uno::Reference< ::drafts::com::sun::star::accessibility::XAccessible >
        SAL_CALL getAccessibleAt(
        const ::com::sun::star::awt::Point& rPoint )
        throw (::com::sun::star::uno::RuntimeException);

    virtual void SAL_CALL grabFocus(  )
        throw (::com::sun::star::uno::RuntimeException);

    virtual sal_Int32 SAL_CALL getForeground(  )
        throw (::com::sun::star::uno::RuntimeException);

    virtual sal_Int32 SAL_CALL getBackground(  )
        throw (::com::sun::star::uno::RuntimeException);

    ///=====  XAccessibleContext  ==============================================

    /// Return NULL to indicate that an empty relation set.
    virtual ::com::sun::star::uno::Reference<
            ::drafts::com::sun::star::accessibility::XAccessibleRelationSet> SAL_CALL
        getAccessibleRelationSet(void)
        throw (::com::sun::star::uno::RuntimeException);

    /// Return the set of current states.
    virtual ::com::sun::star::uno::Reference<
            ::drafts::com::sun::star::accessibility::XAccessibleStateSet> SAL_CALL
        getAccessibleStateSet(void)
        throw (::com::sun::star::uno::RuntimeException);

    ///=====  XAccessibleSelection  ===========================================

    virtual void SAL_CALL
        selectAccessibleChild( sal_Int32 nChildIndex )
        throw (::com::sun::star::lang::IndexOutOfBoundsException,
        ::com::sun::star::uno::RuntimeException);

    virtual void SAL_CALL
        clearAccessibleSelection(  )
        throw (::com::sun::star::uno::RuntimeException);

    virtual void SAL_CALL
        selectAllAccessible(  )
        throw (::com::sun::star::uno::RuntimeException);

    virtual sal_Int32 SAL_CALL
        getSelectedAccessibleChildCount(  )
        throw (::com::sun::star::uno::RuntimeException);

    virtual ::com::sun::star::uno::Reference<
        ::drafts::com::sun::star::accessibility::XAccessible > SAL_CALL
        getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex )
        throw (::com::sun::star::lang::IndexOutOfBoundsException,
        ::com::sun::star::uno::RuntimeException);

    virtual void SAL_CALL
        deselectSelectedAccessibleChild( sal_Int32 nChildIndex )
        throw (::com::sun::star::lang::IndexOutOfBoundsException,
        ::com::sun::star::uno::RuntimeException);

    ///=====  XServiceInfo  ====================================================

    /** Returns an identifier for the implementation of this object.
    */
    virtual ::rtl::OUString SAL_CALL
        getImplementationName(void)
        throw (::com::sun::star::uno::RuntimeException);

    /** Returns a list of all supported services.
    */
    virtual ::com::sun::star::uno::Sequence< ::rtl::OUString> SAL_CALL
        getSupportedServiceNames(void)
        throw (::com::sun::star::uno::RuntimeException);

    ///=====  XTypeProvider  ===================================================

    /** Returns a implementation id.
    */
    virtual ::com::sun::star::uno::Sequence<sal_Int8> SAL_CALL
        getImplementationId(void)
        throw (::com::sun::star::uno::RuntimeException);

    ///=====  XAccessibleEventBroadcaster  =====================================

    /** Add listener that is informed of future changes of name,
          description and so on events.
    */
    virtual void SAL_CALL
        addEventListener(
            const ::com::sun::star::uno::Reference<
                ::drafts::com::sun::star::accessibility::XAccessibleEventListener>& xListener)
        throw (com::sun::star::uno::RuntimeException);

protected:
    /// Return the object's current bounding box relative to the desktop.
    virtual Rectangle GetBoundingBoxOnScreen(void) const
        throw (::com::sun::star::uno::RuntimeException);

    /// Return the object's current bounding box relative to the parent object.
    virtual Rectangle GetBoundingBox(void) const
        throw (::com::sun::star::uno::RuntimeException);
private:
    ScTabViewShell* mpViewShell;
    ScRangeList*    mpMarkedRanges;
    std::vector<ScMyAddress>* mpSortedMarkedCells;
    ScAccessibleDocument* mpAccDoc;
    ScAccessibleCell*   mpAccCell;
    Rectangle       maVisCells;
    ScSplitPos      meSplitPos;
    ScAddress       maActiveCell;
    sal_Bool        mbHasSelection;
    sal_Bool        mbDelIns;
    sal_Bool        mbIsFocusSend;

    sal_Bool IsDefunc(
        const com::sun::star::uno::Reference<
        ::drafts::com::sun::star::accessibility::XAccessibleStateSet>& rxParentStates);
    sal_Bool IsEditable(
        const com::sun::star::uno::Reference<
        ::drafts::com::sun::star::accessibility::XAccessibleStateSet>& rxParentStates);
    sal_Bool IsFocused();
    sal_Bool IsCompleteSheetSelected();

    void SelectCell(sal_Int32 nRow, sal_Int32 nCol, sal_Bool bDeselect);
    void CreateSortedMarkedCells();
    void AddMarkedRange(const ScRange& rRange);

    ScDocument* GetDocument(ScTabViewShell* pViewShell);
    Rectangle   GetVisArea(ScTabViewShell* pViewShell, ScSplitPos eSplitPos);
    Rectangle   GetVisCells(const Rectangle& rVisArea);
};

#endif
<commit_msg>INTEGRATION: CWS uaa02 (1.22.128); FILE MERGED 2003/04/22 08:15:02 mt 1.22.128.1: #108656# Moved Accessibility from drafts to final<commit_after>/*************************************************************************
 *
 *  $RCSfile: AccessibleSpreadsheet.hxx,v $
 *
 *  $Revision: 1.23 $
 *
 *  last change: $Author: vg $ $Date: 2003-04-24 17:15:54 $
 *
 *  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, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 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 EXPRESSED 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: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _SC_ACCESSIBLESPREADSHEET_HXX
#define _SC_ACCESSIBLESPREADSHEET_HXX

#include "AccessibleTableBase.hxx"
#ifndef SC_VIEWDATA_HXX
#include "viewdata.hxx"
#endif

#include <vector>

class ScMyAddress : public ScAddress
{
public:
    ScMyAddress() : ScAddress() {}
    ScMyAddress(sal_uInt16 nCol, sal_uInt16 nRow, sal_uInt16 nTab) : ScAddress(nCol, nRow, nTab) {}
    ScMyAddress(const ScAddress& rAddress) : ScAddress(rAddress) {}

    sal_Bool operator< ( const ScMyAddress& rAddress ) const
    {
        if( Row() != rAddress.Row() )
            return (Row() < rAddress.Row());
        else
            return (Col() < rAddress.Col());
    }
};

class ScTabViewShell;
class ScAccessibleDocument;
class ScAccessibleCell;

/** @descr
        This base class provides an implementation of the
        AccessibleTable service.
*/
class ScAccessibleSpreadsheet
    :   public  ScAccessibleTableBase
{
public:
    //=====  internal  ========================================================
    ScAccessibleSpreadsheet(
        ScAccessibleDocument* pAccDoc,
        ScTabViewShell* pViewShell,
        sal_uInt16  nTab,
        ScSplitPos eSplitPos);
protected:
    virtual ~ScAccessibleSpreadsheet();
public:

     virtual void SAL_CALL disposing();

    void CompleteSelectionChanged(sal_Bool bNewState);

    virtual void LostFocus();

    virtual void GotFocus();

    void BoundingBoxChanged();

    void VisAreaChanged();

    ///=====  SfxListener  =====================================================

    virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );

    ///=====  XAccessibleTable  ================================================

    /// Returns the selected rows in a table.
    virtual ::com::sun::star::uno::Sequence< sal_Int32 > SAL_CALL
                getSelectedAccessibleRows(  )
                    throw (::com::sun::star::uno::RuntimeException);

    /// Returns the selected columns in a table.
    virtual ::com::sun::star::uno::Sequence< sal_Int32 > SAL_CALL
                getSelectedAccessibleColumns(  )
                    throw (::com::sun::star::uno::RuntimeException);

    /// Returns a boolean value indicating whether the specified row is selected.
    virtual sal_Bool SAL_CALL
                isAccessibleRowSelected( sal_Int32 nRow )
                    throw (::com::sun::star::uno::RuntimeException,
                    ::com::sun::star::lang::IndexOutOfBoundsException);

    /// Returns a boolean value indicating whether the specified column is selected.
    virtual sal_Bool SAL_CALL
                isAccessibleColumnSelected( sal_Int32 nColumn )
                    throw (::com::sun::star::uno::RuntimeException,
                    ::com::sun::star::lang::IndexOutOfBoundsException);

    /// Returns the Accessible at a specified row and column in the table.
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL
                getAccessibleCellAt( sal_Int32 nRow, sal_Int32 nColumn )
                    throw (::com::sun::star::uno::RuntimeException,
                            ::com::sun::star::lang::IndexOutOfBoundsException);

    ScAccessibleCell* GetAccessibleCellAt(sal_Int32 nRow, sal_Int32 nColumn);

    /// Returns a boolean value indicating whether the accessible at a specified row and column is selected.
    virtual sal_Bool SAL_CALL
                isAccessibleSelected( sal_Int32 nRow, sal_Int32 nColumn )
                    throw (::com::sun::star::uno::RuntimeException,
                    ::com::sun::star::lang::IndexOutOfBoundsException);

    ///=====  XAccessibleComponent  ============================================

    virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >
        SAL_CALL getAccessibleAtPoint(
        const ::com::sun::star::awt::Point& rPoint )
        throw (::com::sun::star::uno::RuntimeException);

    virtual void SAL_CALL grabFocus(  )
        throw (::com::sun::star::uno::RuntimeException);

    virtual sal_Int32 SAL_CALL getForeground(  )
        throw (::com::sun::star::uno::RuntimeException);

    virtual sal_Int32 SAL_CALL getBackground(  )
        throw (::com::sun::star::uno::RuntimeException);

    ///=====  XAccessibleContext  ==============================================

    /// Return NULL to indicate that an empty relation set.
    virtual ::com::sun::star::uno::Reference<
            ::com::sun::star::accessibility::XAccessibleRelationSet> SAL_CALL
        getAccessibleRelationSet(void)
        throw (::com::sun::star::uno::RuntimeException);

    /// Return the set of current states.
    virtual ::com::sun::star::uno::Reference<
            ::com::sun::star::accessibility::XAccessibleStateSet> SAL_CALL
        getAccessibleStateSet(void)
        throw (::com::sun::star::uno::RuntimeException);

    ///=====  XAccessibleSelection  ===========================================

    virtual void SAL_CALL
        selectAccessibleChild( sal_Int32 nChildIndex )
        throw (::com::sun::star::lang::IndexOutOfBoundsException,
        ::com::sun::star::uno::RuntimeException);

    virtual void SAL_CALL
        clearAccessibleSelection(  )
        throw (::com::sun::star::uno::RuntimeException);

    virtual void SAL_CALL
        selectAllAccessible(  )
        throw (::com::sun::star::uno::RuntimeException);

    virtual sal_Int32 SAL_CALL
        getSelectedAccessibleChildCount(  )
        throw (::com::sun::star::uno::RuntimeException);

    virtual ::com::sun::star::uno::Reference<
        ::com::sun::star::accessibility::XAccessible > SAL_CALL
        getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex )
        throw (::com::sun::star::lang::IndexOutOfBoundsException,
        ::com::sun::star::uno::RuntimeException);

    virtual void SAL_CALL
        deselectAccessibleChild( sal_Int32 nChildIndex )
        throw (::com::sun::star::lang::IndexOutOfBoundsException,
        ::com::sun::star::uno::RuntimeException);

    ///=====  XServiceInfo  ====================================================

    /** Returns an identifier for the implementation of this object.
    */
    virtual ::rtl::OUString SAL_CALL
        getImplementationName(void)
        throw (::com::sun::star::uno::RuntimeException);

    /** Returns a list of all supported services.
    */
    virtual ::com::sun::star::uno::Sequence< ::rtl::OUString> SAL_CALL
        getSupportedServiceNames(void)
        throw (::com::sun::star::uno::RuntimeException);

    ///=====  XTypeProvider  ===================================================

    /** Returns a implementation id.
    */
    virtual ::com::sun::star::uno::Sequence<sal_Int8> SAL_CALL
        getImplementationId(void)
        throw (::com::sun::star::uno::RuntimeException);

    ///=====  XAccessibleEventBroadcaster  =====================================

    /** Add listener that is informed of future changes of name,
          description and so on events.
    */
    virtual void SAL_CALL
        addEventListener(
            const ::com::sun::star::uno::Reference<
                ::com::sun::star::accessibility::XAccessibleEventListener>& xListener)
        throw (com::sun::star::uno::RuntimeException);

protected:
    /// Return the object's current bounding box relative to the desktop.
    virtual Rectangle GetBoundingBoxOnScreen(void) const
        throw (::com::sun::star::uno::RuntimeException);

    /// Return the object's current bounding box relative to the parent object.
    virtual Rectangle GetBoundingBox(void) const
        throw (::com::sun::star::uno::RuntimeException);
private:
    ScTabViewShell* mpViewShell;
    ScRangeList*    mpMarkedRanges;
    std::vector<ScMyAddress>* mpSortedMarkedCells;
    ScAccessibleDocument* mpAccDoc;
    ScAccessibleCell*   mpAccCell;
    Rectangle       maVisCells;
    ScSplitPos      meSplitPos;
    ScAddress       maActiveCell;
    sal_Bool        mbHasSelection;
    sal_Bool        mbDelIns;
    sal_Bool        mbIsFocusSend;

    sal_Bool IsDefunc(
        const com::sun::star::uno::Reference<
        ::com::sun::star::accessibility::XAccessibleStateSet>& rxParentStates);
    sal_Bool IsEditable(
        const com::sun::star::uno::Reference<
        ::com::sun::star::accessibility::XAccessibleStateSet>& rxParentStates);
    sal_Bool IsFocused();
    sal_Bool IsCompleteSheetSelected();

    void SelectCell(sal_Int32 nRow, sal_Int32 nCol, sal_Bool bDeselect);
    void CreateSortedMarkedCells();
    void AddMarkedRange(const ScRange& rRange);

    ScDocument* GetDocument(ScTabViewShell* pViewShell);
    Rectangle   GetVisArea(ScTabViewShell* pViewShell, ScSplitPos eSplitPos);
    Rectangle   GetVisCells(const Rectangle& rVisArea);
};

#endif
<|endoftext|>


<commit_before>#include <prng/prng.hpp>
#include <aes/aes.hpp>
#include <sha/sha.hpp>
#include <ring/ring.hpp>
#include <QFile>

#define BUFFERSIZE 1024
#define SALTSIZE 1024
#define IVSIZE 16
#define MUTATIONINTERVAL 16
#define AESKEYLENGTH 32
#define RINGKEYLENGTH 32

bool encodeFile(const char* inputFile, const char* key, unsigned int keyLength)
{
	printf("encoding %s", inputFile);
	char salt[SALTSIZE];
	char iv[IVSIZE];
	Prng prng;
	prng.generate(salt, SALTSIZE);
	Sha sha;
	char hashedKey[RINGKEYLENGTH];
	sha.update(key, keyLength);
	sha.getHash(hashedKey);
	Ring ring(hashedKey, RINGKEYLENGTH, salt, SALTSIZE, MUTATIONINTERVAL);
	Aes aes(hashedKey, AESKEYLENGTH, iv, IVSIZE, true);
	char outputFile[strlen(inputFile)+4+1];
	strcpy(outputFile, inputFile);
	strcat(outputFile, ".enc");
	QFile out(outputFile);
/*	if (out.exists())
	{
		printf("\rfailed to encode %s: outputfile already exists\n", inputFile);
		return false;
	}*/
	if (!out.open(QIODevice::WriteOnly))
	{
		printf("\r                                                                                \rfailed to encode %s: outputfile not openable\n", inputFile);
		return false;
	}
	if (out.write(salt, SALTSIZE) != SALTSIZE)
	{
		printf("\r                                                                                \rfailed to encode %s: outputfile not writeable\n", inputFile);
		out.close();
		out.remove();
		return false;
	}
	if (out.write(iv, IVSIZE) != IVSIZE)
	{
		printf("\r                                                                                \rfailed to encode %s: outputfile not writeable\n", inputFile);
		out.close();
		out.remove();
		return false;
	}
	QFile in(inputFile);
	if (!in.open(QIODevice::ReadOnly))
	{
		printf("\r                                                                                \rfailed to encode %s: inputfile not openable\n", inputFile);
		out.close();
		out.remove();
		return false;
	}
	unsigned int treated = 0;
	unsigned int toTreat = in.size();
	while (treated < toTreat)
	{
		printf("\r                                                                                \rencoding %s: %.1f %%", inputFile, (float)(treated*100)/toTreat);
		unsigned int bufSize = BUFFERSIZE;
		if (treated+bufSize > toTreat)
		{
			bufSize = toTreat-treated;
		}
		char buf[bufSize];
		if (in.read(buf, bufSize) != bufSize)
		{
			printf("\r                                                                                \rfailed to encode %s: inputfile not readable\n", inputFile);
			in.close();
			out.close();
			out.remove();
			return false;
		}
		sha.update(buf, bufSize);
		ring.encode(buf, bufSize);
		aes.encode(buf, bufSize);
		if (out.write(buf, bufSize) != bufSize)
		{
			printf("\r                                                                                \rfailed to encode %s: outputfile not writeable\n", inputFile);
			in.close();
			out.close();
			out.remove();
			return false;
		}
		treated += bufSize;
	}
	in.close();
	printf("\r                                                                                \rencoding %s: %.1f %%", inputFile, (float)(treated*100)/toTreat);
	char hash[sha.size()];
	sha.getHash(hash);
	if (out.write(hash, sha.size()) != sha.size())
	{
		printf("\r                                                                                \rfailed to encode %s: outputfile not writeable\n", inputFile);
		out.close();
		out.remove();
		return false;
	}
	out.close();
/*	if (!in.remove())
	{
		return false;
	}*/
	printf("\r                                                                                \rsucceed encoding %s\n", inputFile);
	return true;
}

bool decodeFile(const char* inputFile, const char* key, unsigned int keyLength)
{
	printf("decoding %s", inputFile);
	QFile in(inputFile);
	if (!in.open(QIODevice::ReadOnly))
	{
		printf("\r                                                                                \rfailed to decode %s: inputfile not openable\n", inputFile);
		return false;
	}
	char salt[SALTSIZE];
	if (in.read(salt, SALTSIZE) != SALTSIZE)
	{
		printf("\r                                                                                \rfailed to decode %s: inputfile not readable\n", inputFile);
		in.close();
		return false;
	}
	char iv[IVSIZE];
	if (in.read(iv, IVSIZE) != IVSIZE)
	{
		printf("\r                                                                                \rfailed to decode %s: inputfile not readable\n", inputFile);
		in.close();
		return false;
	}
	Sha sha;
	char hashedKey[RINGKEYLENGTH];
	sha.update(key, keyLength);
	sha.getHash(hashedKey);

	Ring ring(hashedKey, RINGKEYLENGTH, salt, SALTSIZE, MUTATIONINTERVAL);
	Aes aes(hashedKey, AESKEYLENGTH, iv, IVSIZE, false);
	char outputFile[strlen(inputFile)-4+1];
	strncpy(outputFile, inputFile, strlen(inputFile)-4);
	QFile out(outputFile);
/*	if (out.exists())
	{
		printf("\nfailed to decode %s: outputfile already exists\n", inputFile);
		in.close();
		return false;
	}*/
	if (!out.open(QIODevice::WriteOnly))
	{
		printf("\r                                                                                \rfailed to decode %s: outputfile not openable\n", inputFile);
		in.close();
		return false;
	}
	unsigned int toTreat = in.size()-SALTSIZE-IVSIZE-sha.size();
	unsigned int treated = 0;
	while (treated < toTreat)
	{
		printf("\r                                                                                \rdecoding %s: %.1f %%", inputFile, (float)(treated*100)/toTreat);
		unsigned int bufSize = BUFFERSIZE;
		if (treated+bufSize > toTreat)
		{
			bufSize = toTreat-treated;
		}
		char buf[bufSize];
		if (in.read(buf, bufSize) != bufSize)
		{
			printf("\r                                                                                \rfailed to decode %s: inputfile not readable\n", inputFile);
			in.close();
			out.close();
			out.remove();
			return false;
		}
		aes.decode(buf, bufSize);
		ring.decode(buf, bufSize);
		sha.update(buf, bufSize);
		if (out.write(buf, bufSize) != bufSize)
		{
			printf("\r                                                                                \rfailed to decode %s: outputfile not writeable\n", inputFile);
			in.close();
			out.close();
			out.remove();
			return false;
		}
		treated += bufSize;
	}
	out.close();
	printf("\r                                                                                \rdecoding %s: %.1f %%", inputFile, (float)(treated*100)/toTreat);
	char hash[sha.size()];
	if (in.read(hash, sha.size()) != sha.size())
	{
		printf("\r                                                                                \rfailed to decode %s: inputfile not readable\n", inputFile);
		in.close();
		out.remove();
		return false;
	}
	in.close();
	if (!sha.matches(hash))
	{
		printf("\r                                                                                \rfailed to decode %s: inputfile modified\n", inputFile);
		//out.remove();
		return false;
	}
/*	if (!in.remove())
	{
		return false;
	}*/
	printf("\r                                                                                \rsucceed decoding %s\n", inputFile);
	return true;
}

int main(int argc, char* argv[])
{
	bool inputFileParam = false;
	bool keyParam = false;
	bool encodeParam = false;
	bool decodeParam = false;
	bool unknownParam = false;
	char inputFile[1024];
	char key[1024];
	for (int i=1; i<argc; i++)
	{
		if (strcmp(argv[i], "-i") == 0)
		{
			i++;
			if (i<argc)
			{
				strcpy(inputFile, argv[i]);
				inputFileParam = true;
				continue;
			}
		}
		if (strcmp(argv[i], "-k") == 0)
		{
			i++;
			if (i<argc)
			{
				strcpy(key, argv[i]);
				keyParam = true;
				continue;
			}
		}
		if (strcmp(argv[i], "-d") == 0)
		{
			decodeParam = true;
			continue;
		}
		if (strcmp(argv[i], "-e") == 0)
		{
			encodeParam = true;
			continue;
		}
		unknownParam = true;
	}
	if (!encodeParam && !decodeParam)
	{
		encodeParam = true;
	}
	if (!inputFileParam || !keyParam || (encodeParam && decodeParam) || unknownParam)
	{
		printf("%s -i <inputfile> -k <key> [-e|-d]\n", argv[0]);
		return -1;
	}
	bool ret;
	if (encodeParam)
	{
		ret = encodeFile(inputFile, key, strlen(key));
	}
	else
	{
		ret = decodeFile(inputFile, key, strlen(key));
	}
	if (ret)
	{
		return 0;
	}
	else
	{
		return -1;
	}
}
<commit_msg>no debug anylonger<commit_after>#include <prng/prng.hpp>
#include <aes/aes.hpp>
#include <sha/sha.hpp>
#include <ring/ring.hpp>
#include <QFile>

#define BUFFERSIZE 1024
#define SALTSIZE 1024
#define IVSIZE 16
#define MUTATIONINTERVAL 16
#define AESKEYLENGTH 32
#define RINGKEYLENGTH 32

bool encodeFile(const char* inputFile, const char* key, unsigned int keyLength)
{
	printf("encoding %s", inputFile);
	char salt[SALTSIZE];
	char iv[IVSIZE];
	Prng prng;
	prng.generate(salt, SALTSIZE);
	Sha sha;
	char hashedKey[RINGKEYLENGTH];
	sha.update(key, keyLength);
	sha.getHash(hashedKey);
	Ring ring(hashedKey, RINGKEYLENGTH, salt, SALTSIZE, MUTATIONINTERVAL);
	Aes aes(hashedKey, AESKEYLENGTH, iv, IVSIZE, true);
	char outputFile[strlen(inputFile)+4+1];
	strcpy(outputFile, inputFile);
	strcat(outputFile, ".enc");
	QFile out(outputFile);
	if (out.exists())
	{
		printf("\rfailed to encode %s: outputfile already exists\n", inputFile);
		return false;
	}
	if (!out.open(QIODevice::WriteOnly))
	{
		printf("\r                                                                                \rfailed to encode %s: outputfile not openable\n", inputFile);
		return false;
	}
	if (out.write(salt, SALTSIZE) != SALTSIZE)
	{
		printf("\r                                                                                \rfailed to encode %s: outputfile not writeable\n", inputFile);
		out.close();
		out.remove();
		return false;
	}
	if (out.write(iv, IVSIZE) != IVSIZE)
	{
		printf("\r                                                                                \rfailed to encode %s: outputfile not writeable\n", inputFile);
		out.close();
		out.remove();
		return false;
	}
	QFile in(inputFile);
	if (!in.open(QIODevice::ReadOnly))
	{
		printf("\r                                                                                \rfailed to encode %s: inputfile not openable\n", inputFile);
		out.close();
		out.remove();
		return false;
	}
	unsigned int treated = 0;
	unsigned int toTreat = in.size();
	while (treated < toTreat)
	{
		printf("\r                                                                                \rencoding %s: %.1f %%", inputFile, (float)(treated*100)/toTreat);
		unsigned int bufSize = BUFFERSIZE;
		if (treated+bufSize > toTreat)
		{
			bufSize = toTreat-treated;
		}
		char buf[bufSize];
		if (in.read(buf, bufSize) != bufSize)
		{
			printf("\r                                                                                \rfailed to encode %s: inputfile not readable\n", inputFile);
			in.close();
			out.close();
			out.remove();
			return false;
		}
		sha.update(buf, bufSize);
		ring.encode(buf, bufSize);
		aes.encode(buf, bufSize);
		if (out.write(buf, bufSize) != bufSize)
		{
			printf("\r                                                                                \rfailed to encode %s: outputfile not writeable\n", inputFile);
			in.close();
			out.close();
			out.remove();
			return false;
		}
		treated += bufSize;
	}
	in.close();
	printf("\r                                                                                \rencoding %s: %.1f %%", inputFile, (float)(treated*100)/toTreat);
	char hash[sha.size()];
	sha.getHash(hash);
	if (out.write(hash, sha.size()) != sha.size())
	{
		printf("\r                                                                                \rfailed to encode %s: outputfile not writeable\n", inputFile);
		out.close();
		out.remove();
		return false;
	}
	out.close();
	if (!in.remove())
	{
		return false;
	}
	printf("\r                                                                                \rsucceed encoding %s\n", inputFile);
	return true;
}

bool decodeFile(const char* inputFile, const char* key, unsigned int keyLength)
{
	printf("decoding %s", inputFile);
	QFile in(inputFile);
	if (!in.open(QIODevice::ReadOnly))
	{
		printf("\r                                                                                \rfailed to decode %s: inputfile not openable\n", inputFile);
		return false;
	}
	char salt[SALTSIZE];
	if (in.read(salt, SALTSIZE) != SALTSIZE)
	{
		printf("\r                                                                                \rfailed to decode %s: inputfile not readable\n", inputFile);
		in.close();
		return false;
	}
	char iv[IVSIZE];
	if (in.read(iv, IVSIZE) != IVSIZE)
	{
		printf("\r                                                                                \rfailed to decode %s: inputfile not readable\n", inputFile);
		in.close();
		return false;
	}
	Sha sha;
	char hashedKey[RINGKEYLENGTH];
	sha.update(key, keyLength);
	sha.getHash(hashedKey);

	Ring ring(hashedKey, RINGKEYLENGTH, salt, SALTSIZE, MUTATIONINTERVAL);
	Aes aes(hashedKey, AESKEYLENGTH, iv, IVSIZE, false);
	char outputFile[strlen(inputFile)-4+1];
	strncpy(outputFile, inputFile, strlen(inputFile)-4);
	QFile out(outputFile);
	if (out.exists())
	{
		printf("\nfailed to decode %s: outputfile already exists\n", inputFile);
		in.close();
		return false;
	}
	if (!out.open(QIODevice::WriteOnly))
	{
		printf("\r                                                                                \rfailed to decode %s: outputfile not openable\n", inputFile);
		in.close();
		return false;
	}
	unsigned int toTreat = in.size()-SALTSIZE-IVSIZE-sha.size();
	unsigned int treated = 0;
	while (treated < toTreat)
	{
		printf("\r                                                                                \rdecoding %s: %.1f %%", inputFile, (float)(treated*100)/toTreat);
		unsigned int bufSize = BUFFERSIZE;
		if (treated+bufSize > toTreat)
		{
			bufSize = toTreat-treated;
		}
		char buf[bufSize];
		if (in.read(buf, bufSize) != bufSize)
		{
			printf("\r                                                                                \rfailed to decode %s: inputfile not readable\n", inputFile);
			in.close();
			out.close();
			out.remove();
			return false;
		}
		aes.decode(buf, bufSize);
		ring.decode(buf, bufSize);
		sha.update(buf, bufSize);
		if (out.write(buf, bufSize) != bufSize)
		{
			printf("\r                                                                                \rfailed to decode %s: outputfile not writeable\n", inputFile);
			in.close();
			out.close();
			out.remove();
			return false;
		}
		treated += bufSize;
	}
	out.close();
	printf("\r                                                                                \rdecoding %s: %.1f %%", inputFile, (float)(treated*100)/toTreat);
	char hash[sha.size()];
	if (in.read(hash, sha.size()) != sha.size())
	{
		printf("\r                                                                                \rfailed to decode %s: inputfile not readable\n", inputFile);
		in.close();
		out.remove();
		return false;
	}
	in.close();
	if (!sha.matches(hash))
	{
		printf("\r                                                                                \rfailed to decode %s: inputfile modified\n", inputFile);
		out.remove();
		return false;
	}
	if (!in.remove())
	{
		return false;
	}
	printf("\r                                                                                \rsucceed decoding %s\n", inputFile);
	return true;
}

int main(int argc, char* argv[])
{
	bool inputFileParam = false;
	bool keyParam = false;
	bool encodeParam = false;
	bool decodeParam = false;
	bool unknownParam = false;
	char inputFile[1024];
	char key[1024];
	for (int i=1; i<argc; i++)
	{
		if (strcmp(argv[i], "-i") == 0)
		{
			i++;
			if (i<argc)
			{
				strcpy(inputFile, argv[i]);
				inputFileParam = true;
				continue;
			}
		}
		if (strcmp(argv[i], "-k") == 0)
		{
			i++;
			if (i<argc)
			{
				strcpy(key, argv[i]);
				keyParam = true;
				continue;
			}
		}
		if (strcmp(argv[i], "-d") == 0)
		{
			decodeParam = true;
			continue;
		}
		if (strcmp(argv[i], "-e") == 0)
		{
			encodeParam = true;
			continue;
		}
		unknownParam = true;
	}
	if (!encodeParam && !decodeParam)
	{
		encodeParam = true;
	}
	if (!inputFileParam || !keyParam || (encodeParam && decodeParam) || unknownParam)
	{
		printf("%s -i <inputfile> -k <key> [-e|-d]\n", argv[0]);
		return -1;
	}
	bool ret;
	if (encodeParam)
	{
		ret = encodeFile(inputFile, key, strlen(key));
	}
	else
	{
		ret = decodeFile(inputFile, key, strlen(key));
	}
	if (ret)
	{
		return 0;
	}
	else
	{
		return -1;
	}
}
<|endoftext|>