<commit_before>/* Copyright 2017 The TensorFlow Authors. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

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

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

#include "tensorflow/compiler/xla/service/hlo_constant_folding.h"

#include <memory>
#include <string>
#include <utility>
#include <vector>

#include "absl/memory/memory.h"
#include "tensorflow/compiler/xla/layout_util.h"
#include "tensorflow/compiler/xla/literal.h"
#include "tensorflow/compiler/xla/service/dfs_hlo_visitor_with_default.h"
#include "tensorflow/compiler/xla/service/hlo_computation.h"
#include "tensorflow/compiler/xla/service/hlo_evaluator.h"
#include "tensorflow/compiler/xla/service/hlo_instruction.h"
#include "tensorflow/compiler/xla/service/hlo_opcode.h"
#include "tensorflow/compiler/xla/service/hlo_query.h"
#include "tensorflow/compiler/xla/service/slow_operation_alarm.h"
#include "tensorflow/compiler/xla/shape_util.h"
#include "tensorflow/compiler/xla/types.h"
#include "tensorflow/core/lib/core/errors.h"

namespace xla {

// Checks whether instr is or transitively contains an instruction that we
// shouldn't fold.
//
// Specifically, we don't fold kRng or kAfterAll instructions:
//
//  - kRng is already marked as side-effecting and so is skipped elsewhere, but
//    we check for it here.  Even kRng weren't side-effecting and took an
//    explicit seed, we *still* wouldn't want to constant-fold it, because the
//    evaluator's handling of rng is not guaranteed to be identical to any
//    particular backend's rng.
//
//  - kAfterAll needs to be skipped because a kAfterAll op with no args can
//    currently materialize a token "out of thin air".  TODO(b/110532604):
//    Remove this check once AfterAll requires at least one operand, in which
//    case constant folding will be impossible.
static bool IsOrContainsIllegalInstr(const HloInstruction* instr) {
  if (instr->opcode() == HloOpcode::kAfterAll ||
      instr->opcode() == HloOpcode::kRng) {
    return true;
  }
  for (const HloComputation* c : instr->called_computations()) {
    if (absl::c_any_of(c->instructions(), IsOrContainsIllegalInstr)) {
      return true;
    }
  }
  return false;
}

/*static*/ std::atomic<int64_t> HloConstantFolding::slow_op_counter_{0};

StatusOr<bool> HloConstantFolding::Run(HloModule* module) {
  // Limit the constant folding to 0 iterations to skip folding loops. This
  // retains the behavior from before while loop support in HloEvaluator and may
  // be revised.
  auto evaluator = absl::make_unique<HloEvaluator>(/*max_loop_iterations=*/0);
  // fast-path lets us e.g. use Eigen for matmuls.
  evaluator->set_use_fast_path(true);

  bool changed = false;

  for (auto* computation : module->MakeNonfusionComputations()) {
    for (auto instruction : computation->MakeInstructionPostOrder()) {
      // Skip dead code.
      if (instruction->IsDead()) {
        continue;
      }

      // We only handle instructions where
      //
      //  - at least one operand is a constant, and
      //  - all other operands are either constants or broadcast(constant).
      //
      // Why this particular set of rules around broadcasts?
      //
      //  - We don't want to fold broadcast(constant) on its own, because in
      //    general it's "simpler" to remember that it's a broadcast.  Also,
      //    algsimp will fold an all-one-value constant into a broadcast, so
      //    we'd just end up fighting with it.
      //
      //  - We don't want to fold an op where all operands are broadcasts of
      //    constants, because algsimp will transform op(broadcast(constant) =>
      //    broadcast(op(constant)).  Then we can constant-fold the smaller op.
      //
      //  - So the only remaining case is where some but not all operands are
      //    broadcasts of constants, e.g. op(constant, broadcast(constant)).
      //
      if (!absl::c_any_of(instruction->operands(),
                          [](const HloInstruction* operand) {
                            return operand->opcode() == HloOpcode::kConstant;
                          }) ||
          !absl::c_all_of(
              instruction->operands(), [](const HloInstruction* operand) {
                return operand->opcode() == HloOpcode::kConstant ||
                       (operand->opcode() == HloOpcode::kBroadcast &&
                        operand->operand(0)->opcode() == HloOpcode::kConstant);
              })) {
        continue;
      }

      // Don't fold Constant, Parameter, and Tuple instructions.  Tuple
      // constants are not directly supported by any backends, hence folding
      // Tuple is not useful and would in fact be expanded back into kTuple by
      // Algebraic Simplifier.
      //
      // (We do allow folding subcomputations that contain these instructions.)
      if (instruction->opcode() == HloOpcode::kParameter ||
          instruction->opcode() == HloOpcode::kConstant ||
          instruction->opcode() == HloOpcode::kTuple) {
        continue;
      }

      // Broadcasts dramatically increase the size of constants, which is often
      // detrimental to performance and memory capacity, so do not fold
      // broadcasts.
      if (instruction->opcode() == HloOpcode::kBroadcast ||
          instruction->opcode() == HloOpcode::kIota) {
        continue;
      }

      // Check for instructions that we can't fold even if they appear inside of
      // a subcomputation (e.g. a kCall).
      if (IsOrContainsIllegalInstr(instruction)) {
        continue;
      }

      // Don't constant-fold side-effecting instructions or instructions which
      // contain side-effecting instructions.
      if (instruction->HasSideEffect()) {
        continue;
      }

      // Don't constant fold unless it's a net positive or the output is small.
      if (instruction->shape().IsArray()) {
        int64_t elements_in_removed_operands = 0;
        for (HloInstruction* operand : instruction->operands()) {
          if (operand->user_count() == 1 && operand->shape().IsArray()) {
            elements_in_removed_operands +=
                ShapeUtil::ElementsIn(operand->shape());
          }
        }
        int64_t elements_in_constant =
            ShapeUtil::ElementsIn(instruction->shape());

        static const int64_t kMaximumConstantSizeElements = 45 * 1000 * 1000;
        if (elements_in_constant > elements_in_removed_operands &&
            elements_in_constant > kMaximumConstantSizeElements) {
          continue;
        }
      }

      VLOG(5) << "Constant folding: " << instruction->ToString();

      absl::Duration slow_timeout =
          absl::Seconds(uint64_t{1} << slow_op_counter_.load());
      SlowOperationAlarm slow_alarm(slow_timeout, [instruction, slow_timeout] {
        const bool ndebug =
#if NDEBUG
            true;
#else
            false;
#endif
        absl::string_view explanation_msg =
            ndebug
                ? "This isn't necessarily a bug; constant-folding is "
                  "inherently a trade-off between compilation time and speed "
                  "at runtime.  XLA has some guards that attempt to keep "
                  "constant folding from taking too long, but fundamentally "
                  "you'll always be able to come up with an input program that "
                  "takes a long time.\n\n"
                  "If you'd like to file a bug, run with envvar "
                  "XLA_FLAGS=--xla_dump_to=/tmp/foo and attach the results."
                : "XLA was built without compiler optimizations, which can be "
                  "slow.  Try rebuilding with -c opt.";
        return absl::StrFormat(
            "Constant folding an instrution is taking > %s:\n\n"
            "  %s\n\n"  // instruction->ToString()
            "%s",       // explanation_msg
            absl::FormatDuration(slow_timeout), instruction->ToString(),
            explanation_msg);
      });

      // Currently we skip unimplemented operations.
      // TODO(b/35975797): Fold constant computations for more operations.
      Literal result;
      if (!evaluator->TryEvaluate(
              instruction, &result,
              /*recursively_evaluate_nonconstant_operands=*/true)) {
        VLOG(2) << "Constant folding failed for instruction: "
                << instruction->ToString();
        continue;
      }

      slow_alarm.cancel();
      if (slow_alarm.fired()) {
        slow_op_counter_++;
      }

      VLOG(4) << "Constant folded: " << instruction->ToString();

      TF_RETURN_IF_ERROR(computation->ReplaceWithNewInstruction(
          instruction, HloInstruction::CreateConstant(std::move(result))));
      changed = true;
    }
  }
  return changed;
}

}  // namespace xla
<commit_msg>Fix typo in string.<commit_after>/* Copyright 2017 The TensorFlow Authors. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

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

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

#include "tensorflow/compiler/xla/service/hlo_constant_folding.h"

#include <memory>
#include <string>
#include <utility>
#include <vector>

#include "absl/memory/memory.h"
#include "tensorflow/compiler/xla/layout_util.h"
#include "tensorflow/compiler/xla/literal.h"
#include "tensorflow/compiler/xla/service/dfs_hlo_visitor_with_default.h"
#include "tensorflow/compiler/xla/service/hlo_computation.h"
#include "tensorflow/compiler/xla/service/hlo_evaluator.h"
#include "tensorflow/compiler/xla/service/hlo_instruction.h"
#include "tensorflow/compiler/xla/service/hlo_opcode.h"
#include "tensorflow/compiler/xla/service/hlo_query.h"
#include "tensorflow/compiler/xla/service/slow_operation_alarm.h"
#include "tensorflow/compiler/xla/shape_util.h"
#include "tensorflow/compiler/xla/types.h"
#include "tensorflow/core/lib/core/errors.h"

namespace xla {

// Checks whether instr is or transitively contains an instruction that we
// shouldn't fold.
//
// Specifically, we don't fold kRng or kAfterAll instructions:
//
//  - kRng is already marked as side-effecting and so is skipped elsewhere, but
//    we check for it here.  Even kRng weren't side-effecting and took an
//    explicit seed, we *still* wouldn't want to constant-fold it, because the
//    evaluator's handling of rng is not guaranteed to be identical to any
//    particular backend's rng.
//
//  - kAfterAll needs to be skipped because a kAfterAll op with no args can
//    currently materialize a token "out of thin air".  TODO(b/110532604):
//    Remove this check once AfterAll requires at least one operand, in which
//    case constant folding will be impossible.
static bool IsOrContainsIllegalInstr(const HloInstruction* instr) {
  if (instr->opcode() == HloOpcode::kAfterAll ||
      instr->opcode() == HloOpcode::kRng) {
    return true;
  }
  for (const HloComputation* c : instr->called_computations()) {
    if (absl::c_any_of(c->instructions(), IsOrContainsIllegalInstr)) {
      return true;
    }
  }
  return false;
}

/*static*/ std::atomic<int64_t> HloConstantFolding::slow_op_counter_{0};

StatusOr<bool> HloConstantFolding::Run(HloModule* module) {
  // Limit the constant folding to 0 iterations to skip folding loops. This
  // retains the behavior from before while loop support in HloEvaluator and may
  // be revised.
  auto evaluator = absl::make_unique<HloEvaluator>(/*max_loop_iterations=*/0);
  // fast-path lets us e.g. use Eigen for matmuls.
  evaluator->set_use_fast_path(true);

  bool changed = false;

  for (auto* computation : module->MakeNonfusionComputations()) {
    for (auto instruction : computation->MakeInstructionPostOrder()) {
      // Skip dead code.
      if (instruction->IsDead()) {
        continue;
      }

      // We only handle instructions where
      //
      //  - at least one operand is a constant, and
      //  - all other operands are either constants or broadcast(constant).
      //
      // Why this particular set of rules around broadcasts?
      //
      //  - We don't want to fold broadcast(constant) on its own, because in
      //    general it's "simpler" to remember that it's a broadcast.  Also,
      //    algsimp will fold an all-one-value constant into a broadcast, so
      //    we'd just end up fighting with it.
      //
      //  - We don't want to fold an op where all operands are broadcasts of
      //    constants, because algsimp will transform op(broadcast(constant) =>
      //    broadcast(op(constant)).  Then we can constant-fold the smaller op.
      //
      //  - So the only remaining case is where some but not all operands are
      //    broadcasts of constants, e.g. op(constant, broadcast(constant)).
      //
      if (!absl::c_any_of(instruction->operands(),
                          [](const HloInstruction* operand) {
                            return operand->opcode() == HloOpcode::kConstant;
                          }) ||
          !absl::c_all_of(
              instruction->operands(), [](const HloInstruction* operand) {
                return operand->opcode() == HloOpcode::kConstant ||
                       (operand->opcode() == HloOpcode::kBroadcast &&
                        operand->operand(0)->opcode() == HloOpcode::kConstant);
              })) {
        continue;
      }

      // Don't fold Constant, Parameter, and Tuple instructions.  Tuple
      // constants are not directly supported by any backends, hence folding
      // Tuple is not useful and would in fact be expanded back into kTuple by
      // Algebraic Simplifier.
      //
      // (We do allow folding subcomputations that contain these instructions.)
      if (instruction->opcode() == HloOpcode::kParameter ||
          instruction->opcode() == HloOpcode::kConstant ||
          instruction->opcode() == HloOpcode::kTuple) {
        continue;
      }

      // Broadcasts dramatically increase the size of constants, which is often
      // detrimental to performance and memory capacity, so do not fold
      // broadcasts.
      if (instruction->opcode() == HloOpcode::kBroadcast ||
          instruction->opcode() == HloOpcode::kIota) {
        continue;
      }

      // Check for instructions that we can't fold even if they appear inside of
      // a subcomputation (e.g. a kCall).
      if (IsOrContainsIllegalInstr(instruction)) {
        continue;
      }

      // Don't constant-fold side-effecting instructions or instructions which
      // contain side-effecting instructions.
      if (instruction->HasSideEffect()) {
        continue;
      }

      // Don't constant fold unless it's a net positive or the output is small.
      if (instruction->shape().IsArray()) {
        int64_t elements_in_removed_operands = 0;
        for (HloInstruction* operand : instruction->operands()) {
          if (operand->user_count() == 1 && operand->shape().IsArray()) {
            elements_in_removed_operands +=
                ShapeUtil::ElementsIn(operand->shape());
          }
        }
        int64_t elements_in_constant =
            ShapeUtil::ElementsIn(instruction->shape());

        static const int64_t kMaximumConstantSizeElements = 45 * 1000 * 1000;
        if (elements_in_constant > elements_in_removed_operands &&
            elements_in_constant > kMaximumConstantSizeElements) {
          continue;
        }
      }

      VLOG(5) << "Constant folding: " << instruction->ToString();

      absl::Duration slow_timeout =
          absl::Seconds(uint64_t{1} << slow_op_counter_.load());
      SlowOperationAlarm slow_alarm(slow_timeout, [instruction, slow_timeout] {
        const bool ndebug =
#if NDEBUG
            true;
#else
            false;
#endif
        absl::string_view explanation_msg =
            ndebug
                ? "This isn't necessarily a bug; constant-folding is "
                  "inherently a trade-off between compilation time and speed "
                  "at runtime.  XLA has some guards that attempt to keep "
                  "constant folding from taking too long, but fundamentally "
                  "you'll always be able to come up with an input program that "
                  "takes a long time.\n\n"
                  "If you'd like to file a bug, run with envvar "
                  "XLA_FLAGS=--xla_dump_to=/tmp/foo and attach the results."
                : "XLA was built without compiler optimizations, which can be "
                  "slow.  Try rebuilding with -c opt.";
        return absl::StrFormat(
            "Constant folding an instruction is taking > %s:\n\n"
            "  %s\n\n"  // instruction->ToString()
            "%s",       // explanation_msg
            absl::FormatDuration(slow_timeout), instruction->ToString(),
            explanation_msg);
      });

      // Currently we skip unimplemented operations.
      // TODO(b/35975797): Fold constant computations for more operations.
      Literal result;
      if (!evaluator->TryEvaluate(
              instruction, &result,
              /*recursively_evaluate_nonconstant_operands=*/true)) {
        VLOG(2) << "Constant folding failed for instruction: "
                << instruction->ToString();
        continue;
      }

      slow_alarm.cancel();
      if (slow_alarm.fired()) {
        slow_op_counter_++;
      }

      VLOG(4) << "Constant folded: " << instruction->ToString();

      TF_RETURN_IF_ERROR(computation->ReplaceWithNewInstruction(
          instruction, HloInstruction::CreateConstant(std::move(result))));
      changed = true;
    }
  }
  return changed;
}

}  // namespace xla
<|endoftext|>


<commit_before>/* Copyright 2016 The TensorFlow Authors. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

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

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

#include "tensorflow/core/common_runtime/optimization_registry.h"
#include "tensorflow/core/util/dump_graph.h"

namespace tensorflow {

// static
OptimizationPassRegistry* OptimizationPassRegistry::Global() {
  static OptimizationPassRegistry* global_optimization_registry =
      new OptimizationPassRegistry;
  return global_optimization_registry;
}

void OptimizationPassRegistry::Register(
    Grouping grouping, int phase, std::unique_ptr<GraphOptimizationPass> pass) {
  groups_[grouping][phase].push_back(std::move(pass));
}

Status OptimizationPassRegistry::RunGrouping(
    Grouping grouping, const GraphOptimizationPassOptions& options) {
  LOG(INFO)
      << "Running all optimization passes in grouping " << grouping
      << ". If you see this a lot, you might be extending the graph too many "
         "times (which means you modify the graph many times before "
         "execution). Try reducing graph modifications or using SavedModel to "
         "avoid any graph modification";
  auto group = groups_.find(grouping);
  if (group != groups_.end()) {
    for (auto& phase : group->second) {
      VLOG(1) << "Running optimization phase " << phase.first;
      for (auto& pass : phase.second) {
        VLOG(1) << "Running optimization pass: " << pass->name();
        Status s = pass->Run(options);
        if (!s.ok()) return s;
        if (VLOG_IS_ON(1)) {
          if (options.graph) {
            DumpGraphToFile(
                strings::StrCat(
                    "after_phase_", phase.first, "_", pass->name(), "_",
                    reinterpret_cast<uintptr_t>((*options.graph).get())),
                **options.graph, options.flib_def);
          }
          if (options.partition_graphs) {
            for (auto& part : *options.partition_graphs) {
              DumpGraphToFile(
                  strings::StrCat(
                      "after_phase_", phase.first, "_", pass->name(),
                      "_partition_", part.first, "_",
                      reinterpret_cast<uintptr_t>(part.second.get())),
                  *part.second, options.flib_def);
            }
          }
        }
      }
    }
  }
  return Status::OK();
}

void OptimizationPassRegistry::LogGrouping(Grouping grouping, int vlog_level) {
  auto group = groups_.find(grouping);
  if (group != groups_.end()) {
    for (auto& phase : group->second) {
      for (auto& pass : phase.second) {
        VLOG(vlog_level) << "Registered optimization pass grouping " << grouping
                         << " phase " << phase.first << ": " << pass->name();
      }
    }
  }
}

void OptimizationPassRegistry::LogAllGroupings(int vlog_level) {
  for (auto group = groups_.begin(); group != groups_.end(); ++group) {
    LogGrouping(group->first, vlog_level);
  }
}

}  // namespace tensorflow
<commit_msg>Automated rollback of commit 4eada543abd9b7d681d8263215259b2db9f9ebbe<commit_after>/* Copyright 2016 The TensorFlow Authors. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

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

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

#include "tensorflow/core/common_runtime/optimization_registry.h"
#include "tensorflow/core/util/dump_graph.h"

namespace tensorflow {

// static
OptimizationPassRegistry* OptimizationPassRegistry::Global() {
  static OptimizationPassRegistry* global_optimization_registry =
      new OptimizationPassRegistry;
  return global_optimization_registry;
}

void OptimizationPassRegistry::Register(
    Grouping grouping, int phase, std::unique_ptr<GraphOptimizationPass> pass) {
  groups_[grouping][phase].push_back(std::move(pass));
}

Status OptimizationPassRegistry::RunGrouping(
    Grouping grouping, const GraphOptimizationPassOptions& options) {
  auto group = groups_.find(grouping);
  if (group != groups_.end()) {
    for (auto& phase : group->second) {
      VLOG(1) << "Running optimization phase " << phase.first;
      for (auto& pass : phase.second) {
        VLOG(1) << "Running optimization pass: " << pass->name();
        Status s = pass->Run(options);
        if (!s.ok()) return s;
        if (VLOG_IS_ON(1)) {
          if (options.graph) {
            DumpGraphToFile(
                strings::StrCat(
                    "after_phase_", phase.first, "_", pass->name(), "_",
                    reinterpret_cast<uintptr_t>((*options.graph).get())),
                **options.graph, options.flib_def);
          }
          if (options.partition_graphs) {
            for (auto& part : *options.partition_graphs) {
              DumpGraphToFile(
                  strings::StrCat(
                      "after_phase_", phase.first, "_", pass->name(),
                      "_partition_", part.first, "_",
                      reinterpret_cast<uintptr_t>(part.second.get())),
                  *part.second, options.flib_def);
            }
          }
        }
      }
    }
  }
  return Status::OK();
}

void OptimizationPassRegistry::LogGrouping(Grouping grouping, int vlog_level) {
  auto group = groups_.find(grouping);
  if (group != groups_.end()) {
    for (auto& phase : group->second) {
      for (auto& pass : phase.second) {
        VLOG(vlog_level) << "Registered optimization pass grouping " << grouping
                         << " phase " << phase.first << ": " << pass->name();
      }
    }
  }
}

void OptimizationPassRegistry::LogAllGroupings(int vlog_level) {
  for (auto group = groups_.begin(); group != groups_.end(); ++group) {
    LogGrouping(group->first, vlog_level);
  }
}

}  // namespace tensorflow
<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    GradientMagnitudeRecursiveGaussianImageFilter.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) 2002 Insight Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

//  Software Guide : BeginLatex
//
//  Differentiation is an ill-defined operation over digital data. In practice
//  it results convenient to define a scale over which the differentiation
//  should be performed. This is usually done by preprocessing the data with a
//  smoothing filter. It has been shown that a Gaussian kernel is the most
//  convinient choice for performing such smoothing. By chossing a particular
//  value for the sigma in the gaussian, an associated scale is selected. This
//  allows to neglect details with high frequency content that are commonly
//  considered image noise.
//
//  The \code{itk::GradientMagnitudeRecursiveGaussianImageFilter} computes the
//  magnitude of the image gradient at each pixel location.  The computational
//  process is equivalent to first smoothing the image by convolving it with a
//  gaussian kernel and then applying a differential operator.  The user
//  selects the value of sigma.
//
//  Internally this is done by applying a IIR \footnote{Infinite Impulsional
//  Response} filter that approximates a convolution with the derivative of the
//  gaussian kernel. The advantage of this approach is that the performance is
//  largely superior, in particular when large sigmas are selected for the
//  gaussian kernel.
//
//  This filter will work on images of any dimension by taking advantage of the
//  natural separability of the gaussian kernel and its derivatives.
//
//  \index{itk::GradientMagnitudeRecursiveGaussianImageFilter|textbf}
//
//  Software Guide : EndLatex

#include "itkImage.h"
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"
#include "itkRescaleIntensityImageFilter.h"

//  Software Guide : BeginLatex
//
//  The first step required for using this filter is to include its header file
//
//  \index{itk::GradientMagnitudeRecursiveGaussianImageFilter!header}
//
//  Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
#include "itkGradientMagnitudeRecursiveGaussianImageFilter.h"
// Software Guide : EndCodeSnippet

int main( int argc, char ** argv )
{

  if( argc < 4 )
    {
    std::cerr << "Usage: " << std::endl;
    std::cerr << argv[0] << "  inputImageFile   sigma  outputImageFile " << std::endl;
    return 1;
    }

  //  Software Guide : BeginLatex
  //
  //  Types should be choosen for the pixels of the input and output images.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  typedef    float    InputPixelType;
  typedef    float    OutputPixelType;
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  With them, the input and output image types can be instantiated.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  typedef itk::Image< InputPixelType,  2 >   InputImageType;
  typedef itk::Image< OutputPixelType, 2 >   OutputImageType;
  // Software Guide : EndCodeSnippet

  typedef itk::ImageFileReader< InputImageType >  ReaderType;

  //  Software Guide : BeginLatex
  //
  //  The filter type is now instantiated using both the input image and the
  //  output image types.
  //
  //  \index{itk::GradientMagnitudeRecursiveGaussianImageFilter!Instantiation}
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  typedef itk::GradientMagnitudeRecursiveGaussianImageFilter<
                        InputImageType, OutputImageType >  FilterType;
  // Software Guide : EndCodeSnippet

  ReaderType::Pointer reader = ReaderType::New();
  reader->SetFileName( argv[1] );

  //  Software Guide : BeginLatex
  //
  //  A filter object is created by invoking the \code{New()} method and
  //  assigning the result to a SmartPointer.
  //
  //  \index{itk::GradientMagnitudeRecursiveGaussianImageFilter!New()}
  //  \index{itk::GradientMagnitudeRecursiveGaussianImageFilter!Pointer}
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  FilterType::Pointer filter = FilterType::New();
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  The input image can be obtained from the output of another filter. Here,
  //  an image reader is used as source.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  filter->SetInput( reader->GetOutput() );
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  It is not time for selecting the sigma of the gaussian to use for
  //  smoothing the data prior to te differentiation.
  //
  //  \index{itk::GradientMagnitudeRecursiveGaussianImageFilter!SetSigma()}
  //  \index{SetSigma()!itk::GradientMagnitudeRecursiveGaussianImageFilter}
  //
  //  Software Guide : EndLatex
  const double sigma = atof( argv[2] );

  // Software Guide : BeginCodeSnippet
  filter->SetSigma( sigma );
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  Finally the filter is executed by invoking the \code{Update()} method.
  //
  //  \index{itk::GradientMagnitudeRecursiveGaussianImageFilter!Update()}
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  filter->Update();
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  If the output of this filter has been connected to other filters down the
  //  pipeline, updating any of the downstream filters would have triggered the
  //  execution of this one. For example, a rescale filter followed by a writer
  //  could have been used after the gradient magnitude.
  //
  //  Software Guide : EndLatex

  typedef  unsigned char  WritePixelType;
  typedef itk::Image< WritePixelType, 2 >    WriteImageType;

  typedef itk::RescaleIntensityImageFilter<
                   OutputImageType, WriteImageType > RescaleFilterType;

  RescaleFilterType::Pointer rescaler = RescaleFilterType::New();

  rescaler->SetOutputMinimum(   0 );
  rescaler->SetOutputMaximum( 255 );

  typedef itk::ImageFileWriter< WriteImageType >  WriterType;

  WriterType::Pointer writer = WriterType::New();

  writer->SetFileName( argv[3] );

  // Software Guide : BeginCodeSnippet
  rescaler->SetInput( filter->GetOutput() );
  writer->SetInput( rescaler->GetOutput() );
  writer->Update();
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  // \begin{figure}
  // \center
  // \includegraphics[width=6cm]{GradientMagnitudeRecursiveGaussianImageFilterOutput3.eps}
  // \includegraphics[width=6cm]{GradientMagnitudeRecursiveGaussianImageFilterOutput5.eps}
  // \caption{Effect of the GradientMagnitudeRecursiveGaussianImageFilter on a slice from a MRI
  // Proton Density image  of the brain.}
  // \label{fig:GradientMagnitudeRecursiveGaussianImageFilterInputOutput}
  // \end{figure}
  //
  //  Figure \ref{fig:GradientMagnitudeRecursiveGaussianImageFilterInputOutput}
  //  illustrates the effect of this filter on a MRI proton density image of
  //  the brain using a sigma value of 3 (left) and a value of 5 (right). The
  //  figure shows how the sensitivity to noise can be regulated by selecting
  //  an apropriate sigma.  This type of scale-tunable filter is suitable for
  //  performing scale space analysis.
  //
  //  Attention should be paid to the image type choosen for representing the
  //  input and output images since the dynamic range of gradient magnitudes is
  //  usually quite smaller than the dynamic range of the input image
  //  intensities.
  //
  //  Software Guide : EndLatex

  return 0;

}

<commit_msg>DOC: typo fixed.<commit_after>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    GradientMagnitudeRecursiveGaussianImageFilter.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) 2002 Insight Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

//  Software Guide : BeginLatex
//
//  Differentiation is an ill-defined operation over digital data. In practice
//  it results convenient to define a scale over which the differentiation
//  should be performed. This is usually done by preprocessing the data with a
//  smoothing filter. It has been shown that a Gaussian kernel is the most
//  convinient choice for performing such smoothing. By chossing a particular
//  value for the sigma in the gaussian, an associated scale is selected. This
//  allows to neglect details with high frequency content that are commonly
//  considered image noise.
//
//  The \code{itk::GradientMagnitudeRecursiveGaussianImageFilter} computes the
//  magnitude of the image gradient at each pixel location.  The computational
//  process is equivalent to first smoothing the image by convolving it with a
//  gaussian kernel and then applying a differential operator.  The user
//  selects the value of sigma.
//
//  Internally this is done by applying a IIR \footnote{Infinite Impulsional
//  Response} filter that approximates a convolution with the derivative of the
//  gaussian kernel. The advantage of this approach is that the performance is
//  largely superior, in particular when large sigmas are selected for the
//  gaussian kernel.
//
//  This filter will work on images of any dimension by taking advantage of the
//  natural separability of the gaussian kernel and its derivatives.
//
//  \index{itk::GradientMagnitudeRecursiveGaussianImageFilter|textbf}
//
//  Software Guide : EndLatex

#include "itkImage.h"
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"
#include "itkRescaleIntensityImageFilter.h"

//  Software Guide : BeginLatex
//
//  The first step required for using this filter is to include its header file
//
//  \index{itk::GradientMagnitudeRecursiveGaussianImageFilter!header}
//
//  Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
#include "itkGradientMagnitudeRecursiveGaussianImageFilter.h"
// Software Guide : EndCodeSnippet

int main( int argc, char ** argv )
{

  if( argc < 4 )
    {
    std::cerr << "Usage: " << std::endl;
    std::cerr << argv[0] << "  inputImageFile   sigma  outputImageFile " << std::endl;
    return 1;
    }

  //  Software Guide : BeginLatex
  //
  //  Types should be choosen for the pixels of the input and output images.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  typedef    float    InputPixelType;
  typedef    float    OutputPixelType;
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  With them, the input and output image types can be instantiated.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  typedef itk::Image< InputPixelType,  2 >   InputImageType;
  typedef itk::Image< OutputPixelType, 2 >   OutputImageType;
  // Software Guide : EndCodeSnippet

  typedef itk::ImageFileReader< InputImageType >  ReaderType;

  //  Software Guide : BeginLatex
  //
  //  The filter type is now instantiated using both the input image and the
  //  output image types.
  //
  //  \index{itk::GradientMagnitudeRecursiveGaussianImageFilter!Instantiation}
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  typedef itk::GradientMagnitudeRecursiveGaussianImageFilter<
                        InputImageType, OutputImageType >  FilterType;
  // Software Guide : EndCodeSnippet

  ReaderType::Pointer reader = ReaderType::New();
  reader->SetFileName( argv[1] );

  //  Software Guide : BeginLatex
  //
  //  A filter object is created by invoking the \code{New()} method and
  //  assigning the result to a SmartPointer.
  //
  //  \index{itk::GradientMagnitudeRecursiveGaussianImageFilter!New()}
  //  \index{itk::GradientMagnitudeRecursiveGaussianImageFilter!Pointer}
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  FilterType::Pointer filter = FilterType::New();
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  The input image can be obtained from the output of another filter. Here,
  //  an image reader is used as source.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  filter->SetInput( reader->GetOutput() );
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  It is now time for selecting the sigma of the gaussian to use for
  //  smoothing the data prior to te differentiation.
  //
  //  \index{itk::GradientMagnitudeRecursiveGaussianImageFilter!SetSigma()}
  //  \index{SetSigma()!itk::GradientMagnitudeRecursiveGaussianImageFilter}
  //
  //  Software Guide : EndLatex
  const double sigma = atof( argv[2] );

  // Software Guide : BeginCodeSnippet
  filter->SetSigma( sigma );
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  Finally the filter is executed by invoking the \code{Update()} method.
  //
  //  \index{itk::GradientMagnitudeRecursiveGaussianImageFilter!Update()}
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  filter->Update();
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  If the output of this filter has been connected to other filters down the
  //  pipeline, updating any of the downstream filters would have triggered the
  //  execution of this one. For example, a rescale filter followed by a writer
  //  could have been used after the gradient magnitude.
  //
  //  Software Guide : EndLatex

  typedef  unsigned char  WritePixelType;
  typedef itk::Image< WritePixelType, 2 >    WriteImageType;

  typedef itk::RescaleIntensityImageFilter<
                   OutputImageType, WriteImageType > RescaleFilterType;

  RescaleFilterType::Pointer rescaler = RescaleFilterType::New();

  rescaler->SetOutputMinimum(   0 );
  rescaler->SetOutputMaximum( 255 );

  typedef itk::ImageFileWriter< WriteImageType >  WriterType;

  WriterType::Pointer writer = WriterType::New();

  writer->SetFileName( argv[3] );

  // Software Guide : BeginCodeSnippet
  rescaler->SetInput( filter->GetOutput() );
  writer->SetInput( rescaler->GetOutput() );
  writer->Update();
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  // \begin{figure}
  // \center
  // \includegraphics[width=6cm]{GradientMagnitudeRecursiveGaussianImageFilterOutput3.eps}
  // \includegraphics[width=6cm]{GradientMagnitudeRecursiveGaussianImageFilterOutput5.eps}
  // \caption{Effect of the GradientMagnitudeRecursiveGaussianImageFilter on a slice from a MRI
  // Proton Density image  of the brain.}
  // \label{fig:GradientMagnitudeRecursiveGaussianImageFilterInputOutput}
  // \end{figure}
  //
  //  Figure \ref{fig:GradientMagnitudeRecursiveGaussianImageFilterInputOutput}
  //  illustrates the effect of this filter on a MRI proton density image of
  //  the brain using a sigma value of 3 (left) and a value of 5 (right). The
  //  figure shows how the sensitivity to noise can be regulated by selecting
  //  an apropriate sigma.  This type of scale-tunable filter is suitable for
  //  performing scale space analysis.
  //
  //  Attention should be paid to the image type choosen for representing the
  //  input and output images since the dynamic range of gradient magnitudes is
  //  usually quite smaller than the dynamic range of the input image
  //  intensities.
  //
  //  Software Guide : EndLatex

  return 0;

}

<|endoftext|>


<commit_before>/*************************************************************************
 *   Copyright (C) 2011-2012 by Paul-Louis Ageneau                       *
 *   paul-louis (at) ageneau (dot) org                                   *
 *                                                                       *
 *   This file is part of TeapotNet.                                     *
 *                                                                       *
 *   TeapotNet is free software: you can redistribute it and/or modify   *
 *   it under the terms of the GNU Affero General Public License as      *
 *   published by the Free Software Foundation, either version 3 of      *
 *   the License, or (at your option) any later version.                 *
 *                                                                       *
 *   TeapotNet 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 Affero General Public License for more details.                 *
 *                                                                       *
 *   You should have received a copy of the GNU Affero General Public    *
 *   License along with TeapotNet.                                       *
 *   If not, see <http://www.gnu.org/licenses/>.                         *
 *************************************************************************/

#include "tracker.h"

namespace tpot
{

Tracker::Tracker(int port) :
		Http::Server(port)
{

}

Tracker::~Tracker(void)
{

}

void Tracker::process(Http::Request &request)
{
	Synchronize(this);
	//Log("Tracker", "URL " + request.url);

	if(!request.url[0] == '/') throw 404;
	request.url.ignore();

	List<String> list;
	request.url.explode(list, '/');
	if(list.size() != 2 && list.size() != 3) throw 404;
	if(list.size() == 3)
	{
		if(!list.back().empty()) throw 404;
		list.pop_back();
	}

	if(list.front() != "tracker") throw 404;
	list.pop_front();

	try {
		Identifier identifier;
		String tmp(list.front());
		tmp >> identifier;

		if(identifier.size() != 64) throw Exception("Invalid indentifier size");

		if(request.method == "POST")
		{
			String host, port;

			if(!request.post.get("port", port))
				throw Exception("Missing port number");

			if(!request.post.get("host", host))
			{
				if(request.headers.contains("X-Forwarded-For"))
					host = request.headers["X-Forwarded-For"];
				else host = request.sock->getRemoteAddress().host();
			}

			Address addr(host, port);
			insert(identifier,addr);

			//Log("Tracker", "POST " + identifier.toString() + " -> " + addr.toString());

			Http::Response response(request,200);
			response.send();
		}
		else {
			SerializableArray<Address> addrs;
			retrieve(identifier, addrs);
			if(addrs.empty()) throw 404;

			//Log("Tracker", "GET " + identifier.toString());

			Http::Response response(request,200);
			response.headers["Content-Type"] = "text/plain";
			response.send();
			response.sock->write(addrs);
		}
	}
	catch(int code)
	{
		Http::Response response(request,code);
                response.send();
	}
	catch(const Exception &e)
	{
		Log("Tracker", String("Error: ") + e.what());
		Http::Response response(request,400);
                response.send();
	}
}

void Tracker::insert(const Identifier &identifier, const Address &addr)
{
	Synchronize(this);

	Map<Address,time_t> &map = mMap[identifier];
	map[addr] = time(NULL);
}

void Tracker::retrieve(const Identifier &identifier, Array<Address> &array)
{
	Synchronize(this);

	array.clear();

	map_t::iterator it = mMap.find(identifier);
	if(it == mMap.end()) return;

	Map<Address,time_t> &map = it->second;
	if(map.empty()) return;

	array.reserve(map.size());
	for(	Map<Address,time_t>::iterator it = map.begin();
			it != map.end();
			++it)
	{
		array.push_back(it->first);
	}

	std::random_shuffle(array.begin(), array.end());
}

}
<commit_msg>Tracker synchronization corrected<commit_after>/*************************************************************************
 *   Copyright (C) 2011-2012 by Paul-Louis Ageneau                       *
 *   paul-louis (at) ageneau (dot) org                                   *
 *                                                                       *
 *   This file is part of TeapotNet.                                     *
 *                                                                       *
 *   TeapotNet is free software: you can redistribute it and/or modify   *
 *   it under the terms of the GNU Affero General Public License as      *
 *   published by the Free Software Foundation, either version 3 of      *
 *   the License, or (at your option) any later version.                 *
 *                                                                       *
 *   TeapotNet 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 Affero General Public License for more details.                 *
 *                                                                       *
 *   You should have received a copy of the GNU Affero General Public    *
 *   License along with TeapotNet.                                       *
 *   If not, see <http://www.gnu.org/licenses/>.                         *
 *************************************************************************/

#include "tracker.h"

namespace tpot
{

Tracker::Tracker(int port) :
		Http::Server(port)
{

}

Tracker::~Tracker(void)
{

}

void Tracker::process(Http::Request &request)
{
	Synchronize(this);
	//Log("Tracker", "URL " + request.url);

	if(!request.url[0] == '/') throw 404;
	request.url.ignore();

	List<String> list;
	request.url.explode(list, '/');
	if(list.size() != 2 && list.size() != 3) throw 404;
	if(list.size() == 3)
	{
		if(!list.back().empty()) throw 404;
		list.pop_back();
	}

	if(list.front() != "tracker") throw 404;
	list.pop_front();

	try {
		Identifier identifier;
		String tmp(list.front());
		tmp >> identifier;

		if(identifier.size() != 64) throw Exception("Invalid indentifier size");

		if(request.method == "POST")
		{
			String host, port;

			if(!request.post.get("port", port))
				throw Exception("Missing port number");

			if(!request.post.get("host", host))
			{
				if(request.headers.contains("X-Forwarded-For"))
					host = request.headers["X-Forwarded-For"];
				else host = request.sock->getRemoteAddress().host();
			}

			Address addr(host, port);
			insert(identifier,addr);

			//Log("Tracker", "POST " + identifier.toString() + " -> " + addr.toString());

			Http::Response response(request,200);
			response.send();
		}
		else {
			SerializableArray<Address> addrs;
			retrieve(identifier, addrs);
			if(addrs.empty()) throw 404;

			//Log("Tracker", "GET " + identifier.toString());

			Http::Response response(request,200);
			response.headers["Content-Type"] = "text/plain";
			response.send();
			response.sock->write(addrs);
		}
	}
	catch(int code)
	{
		Http::Response response(request,code);
                response.send();
	}
	catch(const Exception &e)
	{
		Log("Tracker", String("Error: ") + e.what());
		Http::Response response(request,400);
                response.send();
	}
}

void Tracker::insert(const Identifier &identifier, const Address &addr)
{
	Map<Address,time_t> &map = mMap[identifier];
	map[addr] = time(NULL);
}

void Tracker::retrieve(const Identifier &identifier, Array<Address> &array)
{
	array.clear();

	map_t::iterator it = mMap.find(identifier);
	if(it == mMap.end()) return;

	Map<Address,time_t> &map = it->second;
	if(map.empty()) return;

	array.reserve(map.size());
	for(	Map<Address,time_t>::iterator it = map.begin();
			it != map.end();
			++it)
	{
		array.push_back(it->first);
	}

	std::random_shuffle(array.begin(), array.end());
}

}
<|endoftext|>


<commit_before>/*
 * Appcelerator Kroll - licensed under the Apache Public License 2
 * see LICENSE in the root folder for details on the license.
 * Copyright (c) 2008 Appcelerator, Inc. All Rights Reserved.
 */

#include "../kroll.h"
namespace kroll
{
	unsigned int EventListener::currentId = 1;
	std::map<KEventObject*, std::vector<EventListener*>*> KEventObject::listenerMap;
	Poco::Mutex KEventObject::listenerMapMutex;
	AutoPtr<KEventObject> KEventObject::root = new KEventObject(true, "Host");

	KEventObject::KEventObject(const char *type) :
		AccessorBoundObject(type),
		isRoot(false)
	{
		{
			Poco::Mutex::ScopedLock lock(listenerMapMutex);
			std::vector<EventListener*>* listeners = new std::vector<EventListener*>();
			KEventObject::listenerMap[this] = listeners;
		}

		this->SetMethod("addEventListener", &KEventObject::_AddEventListener);
		this->SetMethod("removeEventListener", &KEventObject::_RemoveEventListener);
	}

	KEventObject::KEventObject(bool isRoot, const char *type) :
		AccessorBoundObject(type),
		isRoot(isRoot)
	{
		{
			Poco::Mutex::ScopedLock lock(listenerMapMutex);
			std::vector<EventListener*>* listeners = new std::vector<EventListener*>();
			KEventObject::listenerMap[this] = listeners;
		}

		this->SetMethod("addEventListener", &KEventObject::_AddEventListener);
		this->SetMethod("removeEventListener", &KEventObject::_RemoveEventListener);
	}

	KEventObject::~KEventObject()
	{
		Poco::Mutex::ScopedLock lock(listenerMapMutex);
		std::vector<EventListener*>* listeners = KEventObject::listenerMap[this];
		std::vector<EventListener*>::iterator i = listeners->begin();
		while (i != listeners->end())
		{
			EventListener* listener = *i++;
			delete listener;
		}
		listeners->clear();

		KEventObject::listenerMap.erase(this);
		delete listeners;
	}

	void KEventObject::RemoveEventListener(std::string& eventName, SharedKMethod listener)
	{
		this->RemoveEventListener(eventName, 0, listener);
	}

	void KEventObject::RemoveEventListener(std::string& eventName, unsigned int listenerId)
	{
		this->RemoveEventListener(eventName, listenerId, 0);
	}

	void KEventObject::RemoveEventListener(
		std::string& eventName, unsigned int listenerId, SharedKMethod callback)
	{
		Poco::Mutex::ScopedLock lock(listenerMapMutex);
		std::vector<EventListener*>* listeners = KEventObject::listenerMap[this];
		std::vector<EventListener*>::iterator i = listeners->begin();
		while (i != listeners->end())
		{
			EventListener* listener = *i;
			if (listener->Matches(eventName, listenerId, callback))
			{
				i = listeners->erase(i);
				delete listener;
			}
			else
			{
				i++;
			}
		}
	}

	unsigned int KEventObject::AddEventListener(
		std::string& eventName, SharedKMethod callback)
	{
		Poco::Mutex::ScopedLock lock(listenerMapMutex);
		EventListener* listener = new EventListener(eventName, callback);
		std::vector<EventListener*>* listeners = KEventObject::listenerMap[this];
		listeners->push_back(listener);
		return listener->listenerId;
	}

	unsigned int KEventObject::AddEventListenerForAllEvents(SharedKMethod callback)
	{
		Poco::Mutex::ScopedLock lock(listenerMapMutex);
		EventListener* listener = new EventListener(Event::ALL, callback);
		std::vector<EventListener*>* listeners = KEventObject::listenerMap[this];
		listeners->push_back(listener);
		return listener->listenerId;
	}

	void KEventObject::FireRootEvent(std::string& eventName)
	{
		KEventObject::root->FireEvent(eventName);
	}

	void KEventObject::FireRootEvent(AutoPtr<Event>event)
	{
		KEventObject::root->FireEvent(event);
	}

	void KEventObject::FireEvent(std::string& eventName)
	{
		this->duplicate();
		AutoPtr<KEventObject> target = this;
		AutoPtr<Event> event = new Event(target, eventName);
		this->FireEvent(event);
	}

	void KEventObject::FireEvent(AutoPtr<Event> event)
	{
		Poco::Mutex::ScopedLock lock(listenerMapMutex);
		std::vector<EventListener*>* listeners = KEventObject::listenerMap[this];
		std::vector<EventListener*>::iterator li = listeners->begin();
		while (li != listeners->end())
		{
			EventListener* listener = *li++;
			listener->FireEventIfMatches(event);

			if (event->stopped)
				return;
		}

		if (!this->isRoot) {
			KEventObject::root->FireEvent(event);
		}
	}

	void KEventObject::_AddEventListener(const ValueList& args, SharedValue result)
	{
		unsigned int listenerId;
		if (args.size() > 1 && args.at(0)->IsString() && args.at(1)->IsMethod()) {
			std::string eventName = args.GetString(0);
			listenerId = this->AddEventListener(eventName, args.GetMethod(1));

		} else if (args.size() > 0 && args.at(0)->IsMethod()) {
			listenerId = this->AddEventListenerForAllEvents(args.GetMethod(0));

		} else {
			throw ValueException::FromString("Incorrect arguments passed to addEventListener");
		}

		result->SetDouble((double) listenerId);
	}

	void KEventObject::_RemoveEventListener(const ValueList& args, SharedValue result)
	{
		args.VerifyException("removeEventListener", "s n|m");

		std::string eventName = args.GetString(0);
		if (args.at(1)->IsMethod()) {
			this->RemoveEventListener(eventName, args.GetMethod(1));
		} else {
			this->RemoveEventListener(eventName, args.GetInt(1));
		}
	}

	void EventListener::FireEventIfMatches(AutoPtr<Event> event)
	{
		if (event->eventName != this->eventName && this->eventName != Event::ALL)
			return;

		try {
			Host* host = Host::GetInstance();
			host->InvokeMethodOnMainThread(
				callback, ValueList(Value::NewObject(event)));

		} catch (ValueException &e) {
			Logger* logger = Logger::Get("KEventObject");
			SharedString ss = e.DisplayString();
			logger->Error("Exception caught during window event callback: %s", ss->c_str());
		}
	}

	bool EventListener::Matches(
		std::string& eventName, unsigned int listenerId, SharedKMethod callback)
	{
		return eventName == eventName &&
			((callback.isNull() && listenerId == 0) ||
			(!callback.isNull() && callback->Equals(this->callback)) ||
			(listenerId != 0 && listenerId == this->listenerId));
	}
}

<commit_msg>KEventObject: Don't hold the lock during callback invocation<commit_after>/*
 * Appcelerator Kroll - licensed under the Apache Public License 2
 * see LICENSE in the root folder for details on the license.
 * Copyright (c) 2008 Appcelerator, Inc. All Rights Reserved.
 */

#include "../kroll.h"
namespace kroll
{
	unsigned int EventListener::currentId = 1;
	std::map<KEventObject*, std::vector<EventListener*>*> KEventObject::listenerMap;
	Poco::Mutex KEventObject::listenerMapMutex;
	AutoPtr<KEventObject> KEventObject::root = new KEventObject(true, "Host");

	KEventObject::KEventObject(const char *type) :
		AccessorBoundObject(type),
		isRoot(false)
	{
		{
			Poco::Mutex::ScopedLock lock(listenerMapMutex);
			std::vector<EventListener*>* listeners = new std::vector<EventListener*>();
			KEventObject::listenerMap[this] = listeners;
		}

		this->SetMethod("addEventListener", &KEventObject::_AddEventListener);
		this->SetMethod("removeEventListener", &KEventObject::_RemoveEventListener);
	}

	KEventObject::KEventObject(bool isRoot, const char *type) :
		AccessorBoundObject(type),
		isRoot(isRoot)
	{
		{
			Poco::Mutex::ScopedLock lock(listenerMapMutex);
			std::vector<EventListener*>* listeners = new std::vector<EventListener*>();
			KEventObject::listenerMap[this] = listeners;
		}

		this->SetMethod("addEventListener", &KEventObject::_AddEventListener);
		this->SetMethod("removeEventListener", &KEventObject::_RemoveEventListener);
	}

	KEventObject::~KEventObject()
	{
		Poco::Mutex::ScopedLock lock(listenerMapMutex);
		std::vector<EventListener*>* listeners = KEventObject::listenerMap[this];
		std::vector<EventListener*>::iterator i = listeners->begin();
		while (i != listeners->end())
		{
			EventListener* listener = *i++;
			delete listener;
		}
		listeners->clear();

		KEventObject::listenerMap.erase(this);
		delete listeners;
	}

	void KEventObject::RemoveEventListener(std::string& eventName, SharedKMethod listener)
	{
		this->RemoveEventListener(eventName, 0, listener);
	}

	void KEventObject::RemoveEventListener(std::string& eventName, unsigned int listenerId)
	{
		this->RemoveEventListener(eventName, listenerId, 0);
	}

	void KEventObject::RemoveEventListener(
		std::string& eventName, unsigned int listenerId, SharedKMethod callback)
	{
		Poco::Mutex::ScopedLock lock(listenerMapMutex);
		std::vector<EventListener*>* listeners = KEventObject::listenerMap[this];
		std::vector<EventListener*>::iterator i = listeners->begin();
		while (i != listeners->end())
		{
			EventListener* listener = *i;
			if (listener->Matches(eventName, listenerId, callback))
			{
				i = listeners->erase(i);
				delete listener;
			}
			else
			{
				i++;
			}
		}
	}

	unsigned int KEventObject::AddEventListener(
		std::string& eventName, SharedKMethod callback)
	{
		Poco::Mutex::ScopedLock lock(listenerMapMutex);
		EventListener* listener = new EventListener(eventName, callback);
		std::vector<EventListener*>* listeners = KEventObject::listenerMap[this];
		listeners->push_back(listener);
		return listener->listenerId;
	}

	unsigned int KEventObject::AddEventListenerForAllEvents(SharedKMethod callback)
	{
		Poco::Mutex::ScopedLock lock(listenerMapMutex);
		EventListener* listener = new EventListener(Event::ALL, callback);
		std::vector<EventListener*>* listeners = KEventObject::listenerMap[this];
		listeners->push_back(listener);
		return listener->listenerId;
	}

	void KEventObject::FireRootEvent(std::string& eventName)
	{
		KEventObject::root->FireEvent(eventName);
	}

	void KEventObject::FireRootEvent(AutoPtr<Event>event)
	{
		KEventObject::root->FireEvent(event);
	}

	void KEventObject::FireEvent(std::string& eventName)
	{
		this->duplicate();
		AutoPtr<KEventObject> target = this;
		AutoPtr<Event> event = new Event(target, eventName);
		this->FireEvent(event);
	}

	void KEventObject::FireEvent(AutoPtr<Event> event)
	{
		std::vector<EventListener*> listeners;
		{
			// We cannot block any threads wile we handle callbacks, so
			// we must make a copy of this map while we handle callbacks. Always
			// remember: premature optimization is the root of all evil.
			Poco::Mutex::ScopedLock lock(listenerMapMutex);
			listeners = *(KEventObject::listenerMap[this]);
		}

		std::vector<EventListener*>::iterator li = listeners.begin();
		while (li != listeners.end())
		{
			EventListener* listener = *li++;
			listener->FireEventIfMatches(event);

			if (event->stopped)
				return;
		}

		if (!this->isRoot)
			KEventObject::root->FireEvent(event);
	}

	void KEventObject::_AddEventListener(const ValueList& args, SharedValue result)
	{
		unsigned int listenerId;
		if (args.size() > 1 && args.at(0)->IsString() && args.at(1)->IsMethod()) {
			std::string eventName = args.GetString(0);
			listenerId = this->AddEventListener(eventName, args.GetMethod(1));

		} else if (args.size() > 0 && args.at(0)->IsMethod()) {
			listenerId = this->AddEventListenerForAllEvents(args.GetMethod(0));

		} else {
			throw ValueException::FromString("Incorrect arguments passed to addEventListener");
		}

		result->SetDouble((double) listenerId);
	}

	void KEventObject::_RemoveEventListener(const ValueList& args, SharedValue result)
	{
		args.VerifyException("removeEventListener", "s n|m");

		std::string eventName = args.GetString(0);
		if (args.at(1)->IsMethod()) {
			this->RemoveEventListener(eventName, args.GetMethod(1));
		} else {
			this->RemoveEventListener(eventName, args.GetInt(1));
		}
	}

	void EventListener::FireEventIfMatches(AutoPtr<Event> event)
	{
		if (event->eventName != this->eventName && this->eventName != Event::ALL)
			return;

		try {
			Host* host = Host::GetInstance();
			host->InvokeMethodOnMainThread(
				callback, ValueList(Value::NewObject(event)));

		} catch (ValueException &e) {
			Logger* logger = Logger::Get("KEventObject");
			SharedString ss = e.DisplayString();
			logger->Error("Exception caught during window event callback: %s", ss->c_str());
		}
	}

	bool EventListener::Matches(
		std::string& eventName, unsigned int listenerId, SharedKMethod callback)
	{
		return eventName == eventName &&
			((callback.isNull() && listenerId == 0) ||
			(!callback.isNull() && callback->Equals(this->callback)) ||
			(listenerId != 0 && listenerId == this->listenerId));
	}
}

<|endoftext|>


<commit_before>// RUN: %clangxx -O0 -g %s -lutil -o %t && %run %t
// This test depends on the glibc layout of struct sem_t and checks that we
// don't leave sem_t::private uninitialized.
// UNSUPPORTED: android, lsan-x86
#include <features.h>
#include <assert.h>
#include <semaphore.h>
#include <string.h>
#include <stdint.h>

// This condition needs to correspond to __HAVE_64B_ATOMICS macro in glibc.
#if (defined(__x86_64__) || defined(__aarch64__) || defined(__powerpc64__) || \
     defined(__s390x__) || defined(__sparc64__) || defined(__alpha__) || \
     defined(__ia64__) || defined(__m68k__)) && __GLIBC_PREREQ(2, 21)
typedef uint64_t semval_t;
#else
typedef unsigned semval_t;
#endif

// glibc 2.21 has introduced some changes in the way the semaphore value is
// handled for 32-bit platforms, but since these changes are not ABI-breaking
// they are not versioned. On newer platforms such as ARM, there is only one
// version of the symbol, so it's enough to check the glibc version. However,
// for old platforms such as i386, glibc contains two or even three versions of
// the sem_init symbol, and the sanitizers always pick the oldest one.
// Therefore, it is not enough to rely on the __GLIBC_PREREQ macro - we should
// instead check the platform as well to make sure we only expect the new
// behavior on platforms where the older symbols do not exist.
#if defined(__arm__) && __GLIBC_PREREQ(2, 21)
#define GET_SEM_VALUE(V) ((V) >> 1)
#else
#define GET_SEM_VALUE(V) (V)
#endif

void my_sem_init(bool priv, int value, semval_t *a, unsigned char *b) {
  sem_t sem;
  memset(&sem, 0xAB, sizeof(sem));
  sem_init(&sem, priv, value);

  char *p = (char *)&sem;
  memcpy(a, p, sizeof(semval_t));
  memcpy(b, p + sizeof(semval_t), sizeof(char));

  sem_destroy(&sem);
}

int main() {
  semval_t a;
  unsigned char b;

  my_sem_init(false, 42, &a, &b);
  assert(GET_SEM_VALUE(a) == 42);
  assert(b != 0xAB);

  my_sem_init(true, 43, &a, &b);
  assert(GET_SEM_VALUE(a) == 43);
  assert(b != 0xAB);
}
<commit_msg>[PowerPC] Fix test case sem_init_glibc.cc for powerpc64be<commit_after>// RUN: %clangxx -O0 -g %s -lutil -o %t && %run %t
// This test depends on the glibc layout of struct sem_t and checks that we
// don't leave sem_t::private uninitialized.
// UNSUPPORTED: android, lsan-x86
#include <features.h>
#include <assert.h>
#include <semaphore.h>
#include <string.h>
#include <stdint.h>

// On powerpc64be semval_t must be 64 bits even with "old" versions of glibc.
#if __PPC64__ && __BIG_ENDIAN__
typedef uint64_t semval_t;

// This condition needs to correspond to __HAVE_64B_ATOMICS macro in glibc.
#elif (defined(__x86_64__) || defined(__aarch64__) || defined(__powerpc64__) || \
     defined(__s390x__) || defined(__sparc64__) || defined(__alpha__) || \
     defined(__ia64__) || defined(__m68k__)) && __GLIBC_PREREQ(2, 21)
typedef uint64_t semval_t;
#else
typedef unsigned semval_t;
#endif

// glibc 2.21 has introduced some changes in the way the semaphore value is
// handled for 32-bit platforms, but since these changes are not ABI-breaking
// they are not versioned. On newer platforms such as ARM, there is only one
// version of the symbol, so it's enough to check the glibc version. However,
// for old platforms such as i386, glibc contains two or even three versions of
// the sem_init symbol, and the sanitizers always pick the oldest one.
// Therefore, it is not enough to rely on the __GLIBC_PREREQ macro - we should
// instead check the platform as well to make sure we only expect the new
// behavior on platforms where the older symbols do not exist.
#if defined(__arm__) && __GLIBC_PREREQ(2, 21)
#define GET_SEM_VALUE(V) ((V) >> 1)
#else
#define GET_SEM_VALUE(V) (V)
#endif

void my_sem_init(bool priv, int value, semval_t *a, unsigned char *b) {
  sem_t sem;
  memset(&sem, 0xAB, sizeof(sem));
  sem_init(&sem, priv, value);

  char *p = (char *)&sem;
  memcpy(a, p, sizeof(semval_t));
  memcpy(b, p + sizeof(semval_t), sizeof(char));

  sem_destroy(&sem);
}

int main() {
  semval_t a;
  unsigned char b;

  my_sem_init(false, 42, &a, &b);
  assert(GET_SEM_VALUE(a) == 42);
  assert(b != 0xAB);

  my_sem_init(true, 43, &a, &b);
  assert(GET_SEM_VALUE(a) == 43);
  assert(b != 0xAB);
}
<|endoftext|>


<commit_before>//$Id$

#ifndef MECHANICFORCETRANSFORMER_HPP_INCLUDED
#define MECHANICFORCETRANSFORMER_HPP_INCLUDED

#include "../../ComponentEssentials.h"

namespace hopsan {

    //!
    //! @brief
    //! @ingroup MechanicalComponents
    //!
    class MechanicForceTransformer : public ComponentC
    {

    private:
        //double mStartPosition;
        //double mStartVelocity;
        //double mStartForce;
        double mSignal;
        Port *mpIn, *mpP1;

    public:
        static Component *Creator()
        {
            return new MechanicForceTransformer("ForceTransformer");
        }

        MechanicForceTransformer(const std::string name) : ComponentC(name)
        {
            //Set member attributes
            mTypeName = "MechanicForceTransformer";
            //mStartPosition = 0.0;
            //mStartVelocity = 0.0;
            //mStartForce = 0.0;
            mSignal = 0.0;

            //Add ports to the component
            mpIn = addReadPort("in", "NodeSignal", Port::NOTREQUIRED);
            mpP1 = addPowerPort("P1", "NodeMechanic");

            //Register changable parameters to the HOPSAN++ core
            //registerParameter("x0", "Initial Position", "[m]", mStartPosition);
            //registerParameter("v0", "Initial Velocity", "[m/s]", mStartVelocity);
            registerParameter("Force", "Generated force", "[N]", mSignal);
        }

        void initialize()
        {
            //mpP1->writeNode(NodeMechanic::POSITION, mStartPosition);
            //mpP1->writeNode(NodeMechanic::VELOCITY, mStartVelocity);
            //mpP1->writeNode(NodeMechanic::FORCE, mStartForce);
            mpP1->writeNode(NodeMechanic::CHARIMP, 0.0);
            mpP1->writeNode(NodeMechanic::WAVEVARIABLE, 0.0);
        }

        void simulateOneTimestep()
        {
            double signal;
            //Get variable values from nodes
            if(mpIn->isConnected())
                signal  = mpIn->readNode(NodeSignal::VALUE);
            else
                signal = mSignal;

            //Transformer equations
            double c = signal;
            double Zc = 0.0;

            //Write new values to nodes
            mpP1->writeNode(NodeMechanic::WAVEVARIABLE, c);
            mpP1->writeNode(NodeMechanic::CHARIMP, Zc);
        }
    };

    //!
    //! @brief
    //! @ingroup MechanicalComponents
    //!
    class MechanicOptimizedForceTransformer : public ComponentC
    {

    private:
        double mStartPosition;
        double mStartVelocity;
        double mStartForce;
        double mSignal;
        Port *mpIn, *mpP1;

        double *x1, *v1, *F1, *c1, *Zc1, *input;

    public:
        static Component *Creator()
        {
            return new MechanicOptimizedForceTransformer("ForceTransformer");
        }

        MechanicOptimizedForceTransformer(const std::string name) : ComponentC(name)
        {
            //Set member attributes
            mTypeName = "MechanicOptimizedForceTransformer";
            mStartPosition = 0.0;
            mStartVelocity = 0.0;
            mStartForce = 0.0;
            mSignal = 0.0;

            //Add ports to the component
            mpIn = addReadPort("in", "NodeSignal", Port::NOTREQUIRED);
            mpP1 = addPowerPort("P1", "NodeMechanic");

            //Register changable parameters to the HOPSAN++ core
            registerParameter("x0", "Initial Position", "[m]", mStartPosition);
            registerParameter("v0", "Initial Velocity", "[m/s]", mStartVelocity);
            registerParameter("Force", "Generated force", "[N]", mSignal);
        }

        void initialize()
        {
            x1 = mpP1->getNodeDataPtr(NodeMechanic::POSITION);
            v1 = mpP1->getNodeDataPtr(NodeMechanic::VELOCITY);
            F1 = mpP1->getNodeDataPtr(NodeMechanic::FORCE);
            c1 = mpP1->getNodeDataPtr(NodeMechanic::WAVEVARIABLE);
            Zc1 = mpP1->getNodeDataPtr(NodeMechanic::CHARIMP);

            if(mpIn->isConnected())
            {
                input = mpIn->getNodeDataPtr(NodeSignal::VALUE);
            }

            *x1 = mStartPosition;
            *v1 = mStartVelocity;
            *F1 = mStartForce;
            *c1 = 0.0;
            *Zc1 = 0.0;
        }

        void simulateOneTimestep()
        {
            if(mpIn->isConnected())
                *c1  = *input;
            else
                *c1 = mSignal;

            *Zc1 = 0.0;
        }
    };
}

#endif // MECHANICFORCETRANSFORMER_HPP_INCLUDED
<commit_msg>removed hard coded start values in force transformer<commit_after>//$Id$

#ifndef MECHANICFORCETRANSFORMER_HPP_INCLUDED
#define MECHANICFORCETRANSFORMER_HPP_INCLUDED

#include "../../ComponentEssentials.h"

namespace hopsan {

    //!
    //! @brief
    //! @ingroup MechanicalComponents
    //!
    class MechanicForceTransformer : public ComponentC
    {

    private:
        //double mStartPosition;
        //double mStartVelocity;
        //double mStartForce;
        double mSignal;
        Port *mpIn, *mpP1;

    public:
        static Component *Creator()
        {
            return new MechanicForceTransformer("ForceTransformer");
        }

        MechanicForceTransformer(const std::string name) : ComponentC(name)
        {
            //Set member attributes
            mTypeName = "MechanicForceTransformer";
            //mStartPosition = 0.0;
            //mStartVelocity = 0.0;
            //mStartForce = 0.0;
            mSignal = 0.0;

            //Add ports to the component
            mpIn = addReadPort("in", "NodeSignal", Port::NOTREQUIRED);
            mpP1 = addPowerPort("P1", "NodeMechanic");

            //Register changable parameters to the HOPSAN++ core
            //registerParameter("x0", "Initial Position", "[m]", mStartPosition);
            //registerParameter("v0", "Initial Velocity", "[m/s]", mStartVelocity);
            registerParameter("Force", "Generated force", "[N]", mSignal);
        }

        void initialize()
        {
            //mpP1->writeNode(NodeMechanic::POSITION, mStartPosition);
            //mpP1->writeNode(NodeMechanic::VELOCITY, mStartVelocity);
            //mpP1->writeNode(NodeMechanic::FORCE, mStartForce);
            mpP1->writeNode(NodeMechanic::CHARIMP, 0.0);
            mpP1->writeNode(NodeMechanic::WAVEVARIABLE, 0.0);
        }

        void simulateOneTimestep()
        {
            double signal;
            //Get variable values from nodes
            if(mpIn->isConnected())
                signal  = mpIn->readNode(NodeSignal::VALUE);
            else
                signal = mSignal;

            //Transformer equations
            double c = signal;
            double Zc = 0.0;

            //Write new values to nodes
            mpP1->writeNode(NodeMechanic::WAVEVARIABLE, c);
            mpP1->writeNode(NodeMechanic::CHARIMP, Zc);
        }
    };

    //!
    //! @brief
    //! @ingroup MechanicalComponents
    //!
    class MechanicOptimizedForceTransformer : public ComponentC
    {

    private:
        //double mStartPosition;
        //double mStartVelocity;
        //double mStartForce;
        double mSignal;
        Port *mpIn, *mpP1;

        double *x1, *v1, *F1, *c1, *Zc1, *input;

    public:
        static Component *Creator()
        {
            return new MechanicOptimizedForceTransformer("ForceTransformer");
        }

        MechanicOptimizedForceTransformer(const std::string name) : ComponentC(name)
        {
            //Set member attributes
            mTypeName = "MechanicOptimizedForceTransformer";
            //mStartPosition = 0.0;
            //mStartVelocity = 0.0;
            //mStartForce = 0.0;
            mSignal = 0.0;

            //Add ports to the component
            mpIn = addReadPort("in", "NodeSignal", Port::NOTREQUIRED);
            mpP1 = addPowerPort("P1", "NodeMechanic");

            //Register changable parameters to the HOPSAN++ core
            //registerParameter("x0", "Initial Position", "[m]", mStartPosition);
            //registerParameter("v0", "Initial Velocity", "[m/s]", mStartVelocity);
            registerParameter("Force", "Generated force", "[N]", mSignal);
        }

        void initialize()
        {
            x1 = mpP1->getNodeDataPtr(NodeMechanic::POSITION);
            v1 = mpP1->getNodeDataPtr(NodeMechanic::VELOCITY);
            F1 = mpP1->getNodeDataPtr(NodeMechanic::FORCE);
            c1 = mpP1->getNodeDataPtr(NodeMechanic::WAVEVARIABLE);
            Zc1 = mpP1->getNodeDataPtr(NodeMechanic::CHARIMP);

            if(mpIn->isConnected())
            {
                input = mpIn->getNodeDataPtr(NodeSignal::VALUE);
            }

            //*x1 = mStartPosition;
            //*v1 = mStartVelocity;
            //*F1 = mStartForce;
            *c1 = 0.0;
            *Zc1 = 0.0;
        }

        void simulateOneTimestep()
        {
            if(mpIn->isConnected())
                *c1  = *input;
            else
                *c1 = mSignal;

            *Zc1 = 0.0;
        }
    };
}

#endif // MECHANICFORCETRANSFORMER_HPP_INCLUDED
<|endoftext|>


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

#include "script_error.h"

const char* ScriptErrorString(const ScriptError serror)
{
    switch (serror)
    {
        case SCRIPT_ERR_OK:
            return "No error";
        case SCRIPT_ERR_EVAL_FALSE:
            return "Script evaluated without error but finished with a false/empty top stack element";
        case SCRIPT_ERR_VERIFY:
            return "Script failed an OP_VERIFY operation";
        case SCRIPT_ERR_EQUALVERIFY:
            return "Script failed an OP_EQUALVERIFY operation";
        case SCRIPT_ERR_CHECKMULTISIGVERIFY:
            return "Script failed an OP_CHECKMULTISIGVERIFY operation";
        case SCRIPT_ERR_CHECKSIGVERIFY:
            return "Script failed an OP_CHECKSIGVERIFY operation";
        case SCRIPT_ERR_NUMEQUALVERIFY:
            return "Script failed an OP_NUMEQUALVERIFY operation";
        case SCRIPT_ERR_SCRIPT_SIZE:
            return "Script is too big";
        case SCRIPT_ERR_PUSH_SIZE:
            return "Push value size limit exceeded";
        case SCRIPT_ERR_OP_COUNT:
            return "Operation limit exceeded";
        case SCRIPT_ERR_STACK_SIZE:
            return "Stack size limit exceeded";
        case SCRIPT_ERR_SIG_COUNT:
            return "Signature count negative or greater than pubkey count";
        case SCRIPT_ERR_PUBKEY_COUNT:
            return "Pubkey count negative or limit exceeded";
        case SCRIPT_ERR_BAD_OPCODE:
            return "Opcode missing or not understood";
        case SCRIPT_ERR_DISABLED_OPCODE:
            return "Attempted to use a disabled opcode";
        case SCRIPT_ERR_INVALID_STACK_OPERATION:
            return "Operation not valid with the current stack size";
        case SCRIPT_ERR_INVALID_ALTSTACK_OPERATION:
            return "Operation not valid with the current altstack size";
        case SCRIPT_ERR_OP_RETURN:
            return "OP_RETURN was encountered";
        case SCRIPT_ERR_UNBALANCED_CONDITIONAL:
            return "Invalid OP_IF construction";
        case SCRIPT_ERR_NEGATIVE_LOCKTIME:
            return "Negative locktime";
        case SCRIPT_ERR_UNSATISFIED_LOCKTIME:
            return "Locktime requirement not satisfied";
        case SCRIPT_ERR_SIG_HASHTYPE:
            return "Signature hash type missing or not understood";
        case SCRIPT_ERR_SIG_DER:
            return "Non-canonical DER signature";
        case SCRIPT_ERR_MINIMALDATA:
            return "Data push larger than necessary";
        case SCRIPT_ERR_SIG_PUSHONLY:
            return "Only non-push operators allowed in signatures";
        case SCRIPT_ERR_SIG_HIGH_S:
            return "Non-canonical signature: S value is unnecessarily high";
        case SCRIPT_ERR_SIG_NULLDUMMY:
            return "Dummy CHECKMULTISIG argument must be zero";
        case SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS:
            return "NOPx reserved for soft-fork upgrades";
        case SCRIPT_ERR_PUBKEYTYPE:
            return "Public key is neither compressed or uncompressed";
        case SCRIPT_ERR_LAMPORTCHECKSIG:
            return "Script failed an OP_LAMPORTCHECKSIG operation";
        case SCRIPT_ERR_LAMPORTCHECKSIGVERIFY:
            return "Script failed an OP_LAMPORTCHECKSIGVERIFY operation";
        case SCRIPT_ERR_LAMPORTCHECKMULTISIG:
            return "Script failed an OP_LAMPORTCHECKMULTISIG operation";
        case SCRIPT_ERR_LAMPORTCHECKMULTISIGVERIFY:
            return "Script failed an OP_LAMPORTCHECKMULTISIGVERIFY operation";
        case SCRIPT_ERR_UNKNOWN_ERROR:
        case SCRIPT_ERR_ERROR_COUNT:
        default: break;
    }
    return "unknown error";
}
<commit_msg>Update script_error.cpp<commit_after>// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "script_error.h"

const char* ScriptErrorString(const ScriptError serror)
{
    switch (serror)
    {
        case SCRIPT_ERR_OK:
            return "No error";
        case SCRIPT_ERR_EVAL_FALSE:
            return "Script evaluated without error but finished with a false/empty top stack element";
        case SCRIPT_ERR_VERIFY:
            return "Script failed an OP_VERIFY operation";
        case SCRIPT_ERR_EQUALVERIFY:
            return "Script failed an OP_EQUALVERIFY operation";
        case SCRIPT_ERR_CHECKMULTISIGVERIFY:
            return "Script failed an OP_CHECKMULTISIGVERIFY operation";
        case SCRIPT_ERR_CHECKSIGVERIFY:
            return "Script failed an OP_CHECKSIGVERIFY operation";
        case SCRIPT_ERR_NUMEQUALVERIFY:
            return "Script failed an OP_NUMEQUALVERIFY operation";
        case SCRIPT_ERR_SCRIPT_SIZE:
            return "Script is too big";
        case SCRIPT_ERR_PUSH_SIZE:
            return "Push value size limit exceeded";
        case SCRIPT_ERR_OP_COUNT:
            return "Operation limit exceeded";
        case SCRIPT_ERR_STACK_SIZE:
            return "Stack size limit exceeded";
        case SCRIPT_ERR_SIG_COUNT:
            return "Signature count negative or greater than pubkey count";
        case SCRIPT_ERR_PUBKEY_COUNT:
            return "Pubkey count negative or limit exceeded";
        case SCRIPT_ERR_BAD_OPCODE:
            return "Opcode missing or not understood";
        case SCRIPT_ERR_DISABLED_OPCODE:
            return "Attempted to use a disabled opcode";
        case SCRIPT_ERR_INVALID_STACK_OPERATION:
            return "Operation not valid with the current stack size";
        case SCRIPT_ERR_INVALID_ALTSTACK_OPERATION:
            return "Operation not valid with the current altstack size";
        case SCRIPT_ERR_OP_RETURN:
            return "OP_RETURN was encountered";
        case SCRIPT_ERR_UNBALANCED_CONDITIONAL:
            return "Invalid OP_IF construction";
        case SCRIPT_ERR_NEGATIVE_LOCKTIME:
            return "Negative locktime";
        case SCRIPT_ERR_UNSATISFIED_LOCKTIME:
            return "Locktime requirement not satisfied";
        case SCRIPT_ERR_SIG_HASHTYPE:
            return "Signature hash type missing or not understood";
        case SCRIPT_ERR_SIG_DER:
            return "Non-canonical DER signature";
        case SCRIPT_ERR_MINIMALDATA:
            return "Data push larger than necessary";
        case SCRIPT_ERR_SIG_PUSHONLY:
            return "Only non-push operators allowed in signatures";
        case SCRIPT_ERR_SIG_HIGH_S:
            return "Non-canonical signature: S value is unnecessarily high";
        case SCRIPT_ERR_SIG_NULLDUMMY:
            return "Dummy CHECKMULTISIG argument must be zero";
        case SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS:
            return "NOPx reserved for soft-fork upgrades";
        case SCRIPT_ERR_PUBKEYTYPE:
            return "Public key is neither compressed or uncompressed";
        case SCRIPT_ERR_UNKNOWN_ERROR:
        case SCRIPT_ERR_ERROR_COUNT:
        default: break;
    }
    return "unknown error";
}
<|endoftext|>


<commit_before>// This file is distributed under the BSD License.
// See "license.txt" for details.
// Copyright 2009-2011, Jonathan Turner (jonathan@emptycrate.com)
// and Jason Turner (jason@emptycrate.com)
// http://www.chaiscript.com

#include <boost/preprocessor.hpp>

#define addparam(z,n,text)  params.push_back((std::is_reference<Param ## n>::value&&!(std::is_same<chaiscript::Boxed_Value, typename std::remove_const<typename std::remove_reference<Param ## n>::type>::type>::value))?Boxed_Value(std::ref(BOOST_PP_CAT(p, n))):Boxed_Value(BOOST_PP_CAT(p, n) ));
#define curry(z,n,text)  BOOST_PP_CAT(std::placeholders::_, BOOST_PP_INC(n))

#ifndef  BOOST_PP_IS_ITERATING
#ifndef CHAISCRIPT_FUNCTION_CALL_DETAIL_HPP_
#define CHAISCRIPT_FUNCTION_CALL_DETAIL_HPP_

#include <string>
#include <vector>
#include "proxy_functions.hpp"

namespace chaiscript
{
  namespace dispatch
  {
    namespace detail
    {

      /**
       * Internal helper class for handling the return
       * value of a build_function_caller
       */
      template<typename Ret>
        struct Function_Caller_Ret
        {
          static Ret call(const std::vector<Const_Proxy_Function> &t_funcs,
              const std::vector<Boxed_Value> &params)
          {
            return boxed_cast<Ret>(dispatch::dispatch(t_funcs, params));
          }
        };

      /**
       * Specialization for void return types
       */
      template<>
        struct Function_Caller_Ret<void>
        {
          static void call(const std::vector<Const_Proxy_Function> &t_funcs,
              const std::vector<Boxed_Value> &params)
          {
            dispatch::dispatch(t_funcs, params);
          }
        };
    }
  }
}

#define BOOST_PP_ITERATION_LIMITS ( 0, 9 )
#define BOOST_PP_FILENAME_1 <chaiscript/dispatchkit/function_call_detail.hpp>
#include BOOST_PP_ITERATE()

# endif
#else
# define n BOOST_PP_ITERATION()

namespace chaiscript
{
  namespace dispatch
  {
    namespace detail
    {
      /**
       * used internally for unwrapping a function call's types
       */
      template<typename Ret BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, typename Param) >
        Ret function_caller(const std::vector<Const_Proxy_Function> &funcs
            BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_BINARY_PARAMS(n, Param, p) )
        {
          std::vector<Boxed_Value> params;

          BOOST_PP_REPEAT(n, addparam, ~)

            return Function_Caller_Ret<Ret>::call(funcs, params);
        }

      /**
       * used internally for unwrapping a function call's types
       */
      template<typename Ret BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, typename Param) >
        std::function<Ret (BOOST_PP_ENUM_PARAMS(n, Param)) >
        build_function_caller_helper(Ret (BOOST_PP_ENUM_PARAMS(n, Param)), const std::vector<Const_Proxy_Function> &funcs)
        {
          if (funcs.size() == 1)
          {
            std::shared_ptr<const Proxy_Function_Impl<Ret (BOOST_PP_ENUM_PARAMS(n, Param))> > pfi =
              std::dynamic_pointer_cast<const Proxy_Function_Impl<Ret (BOOST_PP_ENUM_PARAMS(n, Param))> >
              (funcs[0]);

            if (pfi)
            {
              return pfi->internal_function();
            }
            // looks like this either wasn't a Proxy_Function_Impl or the types didn't match
            // we cannot make any other guesses or assumptions really, so continuing
          }

          return std::bind(&function_caller<Ret BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, Param)>, funcs
              BOOST_PP_ENUM_TRAILING(n, curry, ~));
        }
    }
  }
}
#undef n

#endif

<commit_msg>One more file with boost_pp removed<commit_after>// This file is distributed under the BSD License.
// See "license.txt" for details.
// Copyright 2009-2011, Jonathan Turner (jonathan@emptycrate.com)
// and Jason Turner (jason@emptycrate.com)
// http://www.chaiscript.com

#ifndef CHAISCRIPT_FUNCTION_CALL_DETAIL_HPP_
#define CHAISCRIPT_FUNCTION_CALL_DETAIL_HPP_

#include <string>
#include <vector>
#include "proxy_functions.hpp"

namespace chaiscript
{
  namespace dispatch
  {
    namespace detail
    {

      /**
       * Internal helper class for handling the return
       * value of a build_function_caller
       */
      template<typename Ret>
        struct Function_Caller_Ret
        {
          static Ret call(const std::vector<Const_Proxy_Function> &t_funcs,
              const std::vector<Boxed_Value> &params)
          {
            return boxed_cast<Ret>(dispatch::dispatch(t_funcs, params));
          }
        };

      /**
       * Specialization for void return types
       */
      template<>
        struct Function_Caller_Ret<void>
        {
          static void call(const std::vector<Const_Proxy_Function> &t_funcs,
              const std::vector<Boxed_Value> &params)
          {
            dispatch::dispatch(t_funcs, params);
          }
        };

      /**
       * used internally for unwrapping a function call's types
       */
      template<typename Ret, typename ... Param>
        struct Build_Function_Caller_Helper
        {
          Build_Function_Caller_Helper(const std::vector<Const_Proxy_Function> &t_funcs)
            : m_funcs(t_funcs)
          {
          }

          Ret operator()(Param...param)
          {
            return Function_Caller_Ret<Ret>::call(m_funcs, {
(std::is_reference<Param>::value&&!(std::is_same<chaiscript::Boxed_Value, typename std::remove_const<typename std::remove_reference<Param>::type>::type>::value))?Boxed_Value(std::ref(param)):Boxed_Value(param)...
          }

          );

          }

          std::vector<Const_Proxy_Function> m_funcs;
        };

      template<typename Ret, typename ... Params>
        std::function<Ret (Params...)> build_function_caller_helper(Ret (Params...), const std::vector<Const_Proxy_Function> &funcs)
        {
          if (funcs.size() == 1)
          {
            std::shared_ptr<const Proxy_Function_Impl<Ret (Params...)>> pfi =
              std::dynamic_pointer_cast<const Proxy_Function_Impl<Ret (Params...)> >
                (funcs[0]);

            if (pfi)
            {
              return pfi->internal_function();
            }
            // looks like this either wasn't a Proxy_Function_Impl or the types didn't match
            // we cannot make any other guesses or assumptions really, so continuing
          }

          return std::function<Ret (Params...)>(Build_Function_Caller_Helper<Ret, Params...>(funcs));
        }
    }
  }
}

#endif

<|endoftext|>


<commit_before>#include <sstream>
#include <string>
#include <iostream>
#include <boost/array.hpp>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include "ProxyHandler.h"

void ProxyHandler::Configure(const NginxConfig& child_config_block) {
    host = "www.caltech.edu";
    port = "80";
}

std::string ProxyHandler::HandleRequest(const HTTPRequest& req) {
    boost::asio::io_service io_service;
    boost::asio::ip::tcp::resolver resolver(io_service);
    // Construct query using name of server and service
    boost::asio::ip::tcp::resolver::query query("localhost", "1080");
    boost::asio::ip::tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
    boost::asio::ip::tcp::socket socket(io_service);

    // Try connecting to server
    boost::asio::connect(socket,endpoint_iterator);

    // Send get request
    std::stringstream request_;
    request_ << req.method + " " + req.path + " HTTP/1.1\r\n";
    for (int i = 0; i < req.headers.size(); i++) {
        request_ << req.headers.first + " " + req.headers.second + "\r\n";
    }
    request_ << "\r\n" + req.request_body;
    boost::asio::write(socket, boost::asio::buffer(request_.str()), error);

    std::string response = "";
    for (;;) {
        boost::array<char, 128> buf;
        boost::system::error_code error;
        // Read reply from server
        size_t len = socket.read_some(boost::asio::buffer(buf), error);
        if (error == boost::asio::error::eof)
        {
            break;
        }
        else if (error)
        {
            throw boost::system::system_error(error);
        }
        std::string str_buffer(buf.data(), len);
        response += str_buffer;
    }
    std::cout << "Response: " << response << '\n';
    return response;
}
<commit_msg>Mapped to host and port.<commit_after>#include <sstream>
#include <string>
#include <iostream>
#include <boost/array.hpp>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include "ProxyHandler.h"

void ProxyHandler::Configure(const NginxConfig& child_config_block) {
    host = "www.caltech.edu";
    port = "80";
}

std::string ProxyHandler::HandleRequest(const HTTPRequest& req) {
    boost::asio::io_service io_service;
    boost::asio::ip::tcp::resolver resolver(io_service);
    // Construct query using name of server and service
    boost::asio::ip::tcp::resolver::query query(host, port);
    boost::asio::ip::tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
    boost::asio::ip::tcp::socket socket(io_service);

    // Try connecting to server
    boost::asio::connect(socket,endpoint_iterator);

    // Send get request
    std::stringstream request_;
    request_ << req.method + " " + req.path + " HTTP/1.1\r\n";
    for (int i = 0; i < req.headers.size(); i++) {
        request_ << req.headers[i].first + " " + req.headers[i].second + "\r\n";
    }
    request_ << "\r\n" + req.request_body;
    std::cout << "Request: " << request_.str() << '\n';
    boost::system::error_code error;
    boost::asio::write(socket, boost::asio::buffer(request_.str()), error);

    std::string response = "";
    for (;;) {
        boost::array<char, 128> buf;
        // Read reply from server
        size_t len = socket.read_some(boost::asio::buffer(buf), error);
        if (error == boost::asio::error::eof)
        {
            break;
        }
        else if (error)
        {
            throw boost::system::system_error(error);
        }
        std::string str_buffer(buf.data(), len);
        response += str_buffer;
    }
    std::cout << "Response: " << response << '\n';
    return response;
}
<|endoftext|>