<commit_before>
/**
 *  @copyright Copyright 2017 The J-PET Framework 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 find a copy of the License in the LICENCE file.
 *
 * 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.
 *
 *  @file ImageReco.cpp
 */

#include "ImageReco.h"
#include <TH3D.h>
#include <TH1I.h>
#include "./JPetOptionsTools/JPetOptionsTools.h"
using namespace jpet_options_tools;

const int numberOfBins = 100;
const int xRange = 100;
const int yRange = 100;
const int zRange = 50;

const int numberOfHitsInEventHisto = 10;
const int numberOfConditions = 6;

int CUT_ON_Z_VALUE = 23;
int CUT_ON_LOR_DISTANCE_FROM_CENTER = 25;
int ANNIHILATION_POINT_Z = 23;
int TOT_MIN_VALUE = 15;
int TOT_MAX_VALUE = 25;
int ANGLE_DELTA_MIN_VALUE = 20;

ImageReco::ImageReco(const char* name) : JPetUserTask(name) {}

ImageReco::~ImageReco() {}

bool ImageReco::init()
{
  auto opts = getOptions();
  CUT_ON_Z_VALUE = getOptionAsInt(opts, "ImageReco_CUT_ON_Z_VALUE_int");
  CUT_ON_LOR_DISTANCE_FROM_CENTER = getOptionAsInt(opts, "ImageReco_CUT_ON_LOR_DISTANCE_FROM_CENTER_int");
  ANNIHILATION_POINT_Z = getOptionAsInt(opts, "ImageReco_ANNIHILATION_POINT_Z_int");
  TOT_MIN_VALUE = getOptionAsInt(opts, "ImageReco_TOT_MIN_VALUE_int");
  TOT_MAX_VALUE = getOptionAsInt(opts, "ImageReco_TOT_MAX_VALUE_int");
  ANGLE_DELTA_MIN_VALUE = getOptionAsInt(opts, "ImageReco_ANGLE_DELTA_MIN_VALUE_int");

  fOutputEvents = new JPetTimeWindow("JPetEvent");

  getStatistics().createHistogram(new TH3D("hits_pos",
                                  "Reconstructed hit pos",
                                  numberOfBins, -xRange, xRange,
                                  numberOfBins, -yRange, yRange,
                                  numberOfBins, -zRange, zRange));
  getStatistics().createHistogram(new TH1I("number_of_events",
                                  "Number of events with n hits",
                                  numberOfHitsInEventHisto, 0, numberOfHitsInEventHisto));
  getStatistics().createHistogram(new TH1I("number_of_hits_filtered_by_condition",
                                  "Number of hits filtered by condition",
                                  numberOfConditions, 0, numberOfConditions));

  //it is not really nessesery, but it is creating labels in given order
  getStatistics().getHisto<TH1I>("number_of_hits_filtered_by_condition").Fill("Cut on Z", 1);
  getStatistics().getHisto<TH1I>("number_of_hits_filtered_by_condition").Fill("Cut on LOR distance", 1);
  getStatistics().getHisto<TH1I>("number_of_hits_filtered_by_condition").Fill("Cut on delta angle", 1);
  getStatistics().getHisto<TH1I>("number_of_hits_filtered_by_condition").Fill("Cut on first hit TOT", 1);
  getStatistics().getHisto<TH1I>("number_of_hits_filtered_by_condition").Fill("Cut on second hit TOT", 1);
  getStatistics().getHisto<TH1I>("number_of_hits_filtered_by_condition").Fill("Cut on annihilation point Z", 1);

  return true;
}

bool ImageReco::exec()
{
  if (auto& timeWindow = dynamic_cast<const JPetTimeWindow* const>(fEvent)) {
    unsigned int numberOfEventsInTimeWindow = timeWindow->getNumberOfEvents();
    for (unsigned int i = 0; i < numberOfEventsInTimeWindow; i++) {
      auto event = dynamic_cast<const JPetEvent&>(timeWindow->operator[](static_cast<int>(i)));
      auto numberOfHits = event.getHits().size();
      getStatistics().getHisto<TH1I>("number_of_events").Fill(numberOfHits);
      if (numberOfHits <= 1)
        continue;
      else {
        auto hits = event.getHits();
        for (unsigned int i = 0; i < hits.size() - 1; i++) {
          if (!checkConditions(hits[i], hits[i + 1]))
            continue;
          calculateReconstructedPosition(hits[i], hits[i + 1]);
        }
      }
    }
  } else {
    ERROR("Returned event is not TimeWindow");
    return false;
  }
  return true;
}

bool ImageReco::terminate()
{
  return true;
}

bool ImageReco::checkConditions(const JPetHit& first, const JPetHit& second)
{
  if (!cutOnZ(first, second)) {
    getStatistics().getHisto<TH1I>("number_of_hits_filtered_by_condition").Fill("Cut on Z", 1);
    return false;
  }
  if (!cutOnLORDistanceFromCenter(first, second)) {
    getStatistics().getHisto<TH1I>("number_of_hits_filtered_by_condition").Fill("Cut on LOR distance", 1);
    return false;
  }
  if (angleDelta(first, second) < ANGLE_DELTA_MIN_VALUE) {
    getStatistics().getHisto<TH1I>("number_of_hits_filtered_by_condition").Fill("Cut on delta angle", 1);
    return false;
  }

  double totOfFirstHit = calculateSumOfTOTsOfHit(first);
  if (totOfFirstHit < TOT_MIN_VALUE || totOfFirstHit > TOT_MAX_VALUE) {
    getStatistics().getHisto<TH1I>("number_of_hits_filtered_by_condition").Fill("Cut on first hit TOT", 1);
    return false;
  }

  double totOfSecondHit = calculateSumOfTOTsOfHit(second);
  if (totOfSecondHit < TOT_MIN_VALUE || totOfSecondHit > TOT_MAX_VALUE) {
    getStatistics().getHisto<TH1I>("number_of_hits_filtered_by_condition").Fill("Cut on second hit TOT", 1);
    return false;
  }

  return true;
}

bool ImageReco::cutOnZ(const JPetHit& first, const JPetHit& second)
{
  return (std::fabs(first.getPosZ()) < CUT_ON_Z_VALUE) && (fabs(second.getPosZ()) < CUT_ON_Z_VALUE);
}

bool ImageReco::cutOnLORDistanceFromCenter(const JPetHit& first, const JPetHit& second)
{
  double x_a = first.getPosX();
  double x_b = second.getPosX();

  double y_a = first.getPosY();
  double y_b = second.getPosY();

  double a = (y_a - y_b) / (x_a - x_b);
  double c = y_a - ((y_a - y_b) / (x_a - x_b)) * x_a;

  return (std::fabs(c) / std::sqrt(a * a + 1)) < CUT_ON_LOR_DISTANCE_FROM_CENTER; //b is 1 and b*b is 1
}

float ImageReco::angleDelta(const JPetHit& first, const JPetHit& second)
{
  float delta = fabs(first.getBarrelSlot().getTheta() - second.getBarrelSlot().getTheta());
  return std::min(delta, 360 - delta);
}

double ImageReco::calculateSumOfTOTsOfHit(const JPetHit& hit)
{
  return calculateSumOfTOTs(hit.getSignalA()) + calculateSumOfTOTs(hit.getSignalB());
}

double ImageReco::calculateSumOfTOTs(const JPetPhysSignal& signal)
{
  double tot = 0.;
  std::map<int, double> leadingPoints, trailingPoints;
  leadingPoints = signal.getRecoSignal().getRawSignal().getTimesVsThresholdNumber(JPetSigCh::Leading);
  trailingPoints = signal.getRecoSignal().getRawSignal().getTimesVsThresholdNumber(JPetSigCh::Trailing);
  for (int i = 1; i < 5; i++) {
    auto leadSearch = leadingPoints.find(i);
    auto trailSearch = trailingPoints.find(i);

    if (leadSearch != leadingPoints.end() && trailSearch != trailingPoints.end())
      tot += (trailSearch->second - leadSearch->second) / 1000;
  }
  return tot;
}

bool ImageReco::calculateReconstructedPosition(const JPetHit& firstHit, const JPetHit& secondHit)
{
  double s1_a = static_cast<double>(firstHit.getSignalA().getTime());
  double s1_b = static_cast<double>(firstHit.getSignalB().getTime());
  double s2_a = static_cast<double>(secondHit.getSignalA().getTime());
  double s2_b = static_cast<double>(secondHit.getSignalB().getTime());

  double t_s1_ab = s1_a - s1_b;
  double t_s2_ab = s2_a - s2_b;

  double s1_z = (t_s1_ab * 11) / 2.0;
  double s2_z = (t_s2_ab * 11) / 2.0;

  double vdx = secondHit.getPosX() - firstHit.getPosX();
  double vdz = s2_z - s1_z;
  double vdy = secondHit.getPosY() - firstHit.getPosY();

  double dd = std::sqrt(vdx * vdx + vdz * vdz + vdy * vdy);

  double mtof_a = 0;
  if (firstHit.getPosY() > secondHit.getPosY()) {
    mtof_a = ((((s1_a + s1_b) / 2.0) - ((s2_a + s2_b) / 2.0)) * 30);
  } else {
    mtof_a = ((((s2_a + s2_b) / 2.0) - ((s1_a + s1_b) / 2.0)) * 30);
  }
  double x, y, z;
  x = firstHit.getPosX() + ((vdx / 2.0) + (vdx / dd * mtof_a));
  y = firstHit.getPosY() + ((vdy / 2.0) + (vdy / dd * mtof_a));
  z = s1_z + ((vdz / 2.0) + (vdz / dd * mtof_a));
  //x > -xRange && x < xRange && y > -yRange && y < yRange &&
  if (z > -ANNIHILATION_POINT_Z && z < ANNIHILATION_POINT_Z) {
    getStatistics().getHisto<TH3D>("hits_pos").Fill(x, y, z);
    return true;
  } else {
    getStatistics().getHisto<TH1I>("number_of_hits_filtered_by_condition").Fill("Cut on annihilation point Z", 1);
  }
  return false;
}
<commit_msg>Some refactor<commit_after>
/**
 *  @copyright Copyright 2017 The J-PET Framework 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 find a copy of the License in the LICENCE file.
 *
 * 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.
 *
 *  @file ImageReco.cpp
 */

#include "ImageReco.h"
#include <TH3D.h>
#include <TH1I.h>
#include "./JPetOptionsTools/JPetOptionsTools.h"
using namespace jpet_options_tools;

const int numberOfBins = 100;
const int xRange = 100;
const int yRange = 100;
const int zRange = 50;

const int numberOfHitsInEventHisto = 10;
const int numberOfConditions = 6;

int CUT_ON_Z_VALUE = 23;
int CUT_ON_LOR_DISTANCE_FROM_CENTER = 25;
int ANNIHILATION_POINT_Z = 23;
int TOT_MIN_VALUE_IN_NS = 15;
int TOT_MAX_VALUE_IN_NS = 25;
int ANGLE_DELTA_MIN_VALUE = 20;

ImageReco::ImageReco(const char* name) : JPetUserTask(name) {}

ImageReco::~ImageReco() {}

bool ImageReco::init()
{
  auto opts = getOptions();
  CUT_ON_Z_VALUE = getOptionAsInt(opts, "ImageReco_CUT_ON_Z_VALUE_int");
  CUT_ON_LOR_DISTANCE_FROM_CENTER = getOptionAsInt(opts, "ImageReco_CUT_ON_LOR_DISTANCE_FROM_CENTER_int");
  ANNIHILATION_POINT_Z = getOptionAsInt(opts, "ImageReco_ANNIHILATION_POINT_Z_int");
  TOT_MIN_VALUE_IN_NS = getOptionAsInt(opts, "ImageReco_TOT_MIN_VALUE_IN_NS_int");
  TOT_MAX_VALUE_IN_NS = getOptionAsInt(opts, "ImageReco_TOT_MAX_VALUE_IN_NS_int");
  ANGLE_DELTA_MIN_VALUE = getOptionAsInt(opts, "ImageReco_ANGLE_DELTA_MIN_VALUE_int");

  fOutputEvents = new JPetTimeWindow("JPetEvent");

  getStatistics().createHistogram(new TH3D("hits_pos",
                                  "Reconstructed hit pos",
                                  numberOfBins, -xRange, xRange,
                                  numberOfBins, -yRange, yRange,
                                  numberOfBins, -zRange, zRange));
  getStatistics().createHistogram(new TH1I("number_of_events",
                                  "Number of events with n hits",
                                  numberOfHitsInEventHisto, 0, numberOfHitsInEventHisto));
  getStatistics().createHistogram(new TH1I("number_of_hits_filtered_by_condition",
                                  "Number of hits filtered by condition",
                                  numberOfConditions, 0, numberOfConditions));

  //it is not really nessesery, but it is creating labels in given order
  getStatistics().getHisto<TH1I>("number_of_hits_filtered_by_condition").Fill("Cut on Z", 1);
  getStatistics().getHisto<TH1I>("number_of_hits_filtered_by_condition").Fill("Cut on LOR distance", 1);
  getStatistics().getHisto<TH1I>("number_of_hits_filtered_by_condition").Fill("Cut on delta angle", 1);
  getStatistics().getHisto<TH1I>("number_of_hits_filtered_by_condition").Fill("Cut on first hit TOT", 1);
  getStatistics().getHisto<TH1I>("number_of_hits_filtered_by_condition").Fill("Cut on second hit TOT", 1);
  getStatistics().getHisto<TH1I>("number_of_hits_filtered_by_condition").Fill("Cut on annihilation point Z", 1);

  return true;
}

bool ImageReco::exec()
{
  if (auto& timeWindow = dynamic_cast<const JPetTimeWindow* const>(fEvent)) {
    unsigned int numberOfEventsInTimeWindow = timeWindow->getNumberOfEvents();
    for (unsigned int i = 0; i < numberOfEventsInTimeWindow; i++) {
      auto event = dynamic_cast<const JPetEvent&>(timeWindow->operator[](static_cast<int>(i)));
      auto numberOfHits = event.getHits().size();
      getStatistics().getHisto<TH1I>("number_of_events").Fill(numberOfHits);
      if (numberOfHits <= 1)
        continue;
      else {
        auto hits = event.getHits();
        for (unsigned int i = 0; i < hits.size() - 1; i++) {
          if (!checkConditions(hits[i], hits[i + 1]))
            continue;
          calculateReconstructedPosition(hits[i], hits[i + 1]);
        }
      }
    }
  } else {
    ERROR("Returned event is not TimeWindow");
    return false;
  }
  return true;
}

bool ImageReco::terminate()
{
  return true;
}

bool ImageReco::checkConditions(const JPetHit& first, const JPetHit& second)
{
  if (!cutOnZ(first, second)) {
    getStatistics().getHisto<TH1I>("number_of_hits_filtered_by_condition").Fill("Cut on Z", 1);
    return false;
  }
  if (!cutOnLORDistanceFromCenter(first, second)) {
    getStatistics().getHisto<TH1I>("number_of_hits_filtered_by_condition").Fill("Cut on LOR distance", 1);
    return false;
  }
  if (angleDelta(first, second) < ANGLE_DELTA_MIN_VALUE) {
    getStatistics().getHisto<TH1I>("number_of_hits_filtered_by_condition").Fill("Cut on delta angle", 1);
    return false;
  }

  double totOfFirstHit = calculateSumOfTOTsOfHit(first);
  if (totOfFirstHit < TOT_MIN_VALUE_IN_NS || totOfFirstHit > TOT_MAX_VALUE_IN_NS) {
    getStatistics().getHisto<TH1I>("number_of_hits_filtered_by_condition").Fill("Cut on first hit TOT", 1);
    return false;
  }

  double totOfSecondHit = calculateSumOfTOTsOfHit(second);
  if (totOfSecondHit < TOT_MIN_VALUE_IN_NS || totOfSecondHit > TOT_MAX_VALUE_IN_NS) {
    getStatistics().getHisto<TH1I>("number_of_hits_filtered_by_condition").Fill("Cut on second hit TOT", 1);
    return false;
  }

  return true;
}

bool ImageReco::cutOnZ(const JPetHit& first, const JPetHit& second)
{
  return (std::fabs(first.getPosZ()) < CUT_ON_Z_VALUE) && (fabs(second.getPosZ()) < CUT_ON_Z_VALUE);
}

bool ImageReco::cutOnLORDistanceFromCenter(const JPetHit& first, const JPetHit& second)
{
  double x_a = first.getPosX();
  double x_b = second.getPosX();

  double y_a = first.getPosY();
  double y_b = second.getPosY();

  double a = (y_a - y_b) / (x_a - x_b);
  double c = y_a - ((y_a - y_b) / (x_a - x_b)) * x_a;

  return (std::fabs(c) / std::sqrt(a * a + 1)) < CUT_ON_LOR_DISTANCE_FROM_CENTER; //b is 1 and b*b is 1
}

float ImageReco::angleDelta(const JPetHit& first, const JPetHit& second)
{
  float delta = fabs(first.getBarrelSlot().getTheta() - second.getBarrelSlot().getTheta());
  return std::min(delta, (float)360 - delta);
}

double ImageReco::calculateSumOfTOTsOfHit(const JPetHit& hit)
{
  return calculateSumOfTOTs(hit.getSignalA()) + calculateSumOfTOTs(hit.getSignalB());
}

double ImageReco::calculateSumOfTOTs(const JPetPhysSignal& signal)
{
  double tot = 0.;
  std::map<int, double> leadingPoints, trailingPoints;
  leadingPoints = signal.getRecoSignal().getRawSignal().getTimesVsThresholdNumber(JPetSigCh::Leading);
  trailingPoints = signal.getRecoSignal().getRawSignal().getTimesVsThresholdNumber(JPetSigCh::Trailing);
  for (int i = 1; i < 5; i++) {
    auto leadSearch = leadingPoints.find(i);
    auto trailSearch = trailingPoints.find(i);

    if (leadSearch != leadingPoints.end() && trailSearch != trailingPoints.end())
      tot += (trailSearch->second - leadSearch->second);
  }
  return tot / 1000.;
}

bool ImageReco::calculateReconstructedPosition(const JPetHit& firstHit, const JPetHit& secondHit)
{
  double s1_a = static_cast<double>(firstHit.getSignalA().getTime());
  double s1_b = static_cast<double>(firstHit.getSignalB().getTime());
  double s2_a = static_cast<double>(secondHit.getSignalA().getTime());
  double s2_b = static_cast<double>(secondHit.getSignalB().getTime());

  double t_s1_ab = s1_a - s1_b;
  double t_s2_ab = s2_a - s2_b;

  double s1_z = (t_s1_ab * 11) / 2.0;
  double s2_z = (t_s2_ab * 11) / 2.0;

  double vdx = secondHit.getPosX() - firstHit.getPosX();
  double vdz = s2_z - s1_z;
  double vdy = secondHit.getPosY() - firstHit.getPosY();

  double dd = std::sqrt(vdx * vdx + vdz * vdz + vdy * vdy);

  double mtof_a = 0;
  if (firstHit.getPosY() > secondHit.getPosY()) {
    mtof_a = ((((s1_a + s1_b) / 2.0) - ((s2_a + s2_b) / 2.0)) * 30);
  } else {
    mtof_a = ((((s2_a + s2_b) / 2.0) - ((s1_a + s1_b) / 2.0)) * 30);
  }
  double x, y, z;
  x = firstHit.getPosX() + ((vdx / 2.0) + (vdx / dd * mtof_a));
  y = firstHit.getPosY() + ((vdy / 2.0) + (vdy / dd * mtof_a));
  z = s1_z + ((vdz / 2.0) + (vdz / dd * mtof_a));
  //x > -xRange && x < xRange && y > -yRange && y < yRange &&
  if (z > -ANNIHILATION_POINT_Z && z < ANNIHILATION_POINT_Z) {
    getStatistics().getHisto<TH3D>("hits_pos").Fill(x, y, z);
    return true;
  } else {
    getStatistics().getHisto<TH1I>("number_of_hits_filtered_by_condition").Fill("Cut on annihilation point Z", 1);
  }
  return false;
}
<|endoftext|>


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

#include "webkit/fileapi/native_file_util.h"

#include "base/file_util.h"
#include "base/memory/scoped_ptr.h"
#include "webkit/fileapi/file_system_operation_context.h"

namespace fileapi {

namespace {

// Sets permissions on directory at |dir_path| based on the target platform.
// Returns true on success, or false otherwise.
//
// TODO(benchan): Find a better place outside webkit to host this function.
bool SetPlatformSpecificDirectoryPermissions(const base::FilePath& dir_path) {
#if defined(OS_CHROMEOS)
    // System daemons on Chrome OS may run as a user different than the Chrome
    // process but need to access files under the directories created here.
    // Because of that, grant the execute permission on the created directory
    // to group and other users.
    if (HANDLE_EINTR(chmod(dir_path.value().c_str(),
                           S_IRWXU | S_IXGRP | S_IXOTH)) != 0) {
      return false;
    }
#endif
    // Keep the directory permissions unchanged on non-Chrome OS platforms.
    return true;
}

}  // namespace

using base::PlatformFile;
using base::PlatformFileError;

class NativeFileEnumerator : public FileSystemFileUtil::AbstractFileEnumerator {
 public:
  NativeFileEnumerator(const base::FilePath& root_path,
                       bool recursive,
                       int file_type)
    : file_enum_(root_path, recursive, file_type) {
#if defined(OS_WIN)
    memset(&file_util_info_, 0, sizeof(file_util_info_));
#endif  // defined(OS_WIN)
  }

  virtual ~NativeFileEnumerator() {}

  virtual base::FilePath Next() OVERRIDE;
  virtual int64 Size() OVERRIDE;
  virtual base::Time LastModifiedTime() OVERRIDE;
  virtual bool IsDirectory() OVERRIDE;

 private:
  file_util::FileEnumerator file_enum_;
  file_util::FileEnumerator::FindInfo file_util_info_;
};

base::FilePath NativeFileEnumerator::Next() {
  base::FilePath rv = file_enum_.Next();
  if (!rv.empty())
    file_enum_.GetFindInfo(&file_util_info_);
  return rv;
}

int64 NativeFileEnumerator::Size() {
  return file_util::FileEnumerator::GetFilesize(file_util_info_);
}

base::Time NativeFileEnumerator::LastModifiedTime() {
  return file_util::FileEnumerator::GetLastModifiedTime(file_util_info_);
}

bool NativeFileEnumerator::IsDirectory() {
  return file_util::FileEnumerator::IsDirectory(file_util_info_);
}

PlatformFileError NativeFileUtil::CreateOrOpen(
    const base::FilePath& path, int file_flags,
    PlatformFile* file_handle, bool* created) {
  if (!file_util::DirectoryExists(path.DirName())) {
    // If its parent does not exist, should return NOT_FOUND error.
    return base::PLATFORM_FILE_ERROR_NOT_FOUND;
  }
  PlatformFileError error_code = base::PLATFORM_FILE_OK;
  *file_handle = base::CreatePlatformFile(path, file_flags,
                                          created, &error_code);
  return error_code;
}

PlatformFileError NativeFileUtil::Close(PlatformFile file_handle) {
  if (!base::ClosePlatformFile(file_handle))
    return base::PLATFORM_FILE_ERROR_FAILED;
  return base::PLATFORM_FILE_OK;
}

PlatformFileError NativeFileUtil::EnsureFileExists(
    const base::FilePath& path,
    bool* created) {
  if (!file_util::DirectoryExists(path.DirName()))
    // If its parent does not exist, should return NOT_FOUND error.
    return base::PLATFORM_FILE_ERROR_NOT_FOUND;
  PlatformFileError error_code = base::PLATFORM_FILE_OK;
  // Tries to create the |path| exclusively.  This should fail
  // with base::PLATFORM_FILE_ERROR_EXISTS if the path already exists.
  PlatformFile handle = base::CreatePlatformFile(
      path,
      base::PLATFORM_FILE_CREATE | base::PLATFORM_FILE_READ,
      created, &error_code);
  if (error_code == base::PLATFORM_FILE_ERROR_EXISTS) {
    // Make sure created_ is false.
    if (created)
      *created = false;
    error_code = base::PLATFORM_FILE_OK;
  }
  if (handle != base::kInvalidPlatformFileValue)
    base::ClosePlatformFile(handle);
  return error_code;
}

PlatformFileError NativeFileUtil::CreateDirectory(
    const base::FilePath& path,
    bool exclusive,
    bool recursive) {
  // If parent dir of file doesn't exist.
  if (!recursive && !file_util::PathExists(path.DirName()))
    return base::PLATFORM_FILE_ERROR_NOT_FOUND;

  bool path_exists = file_util::PathExists(path);
  if (exclusive && path_exists)
    return base::PLATFORM_FILE_ERROR_EXISTS;

  // If file exists at the path.
  if (path_exists && !file_util::DirectoryExists(path))
    return base::PLATFORM_FILE_ERROR_EXISTS;

  if (!file_util::CreateDirectory(path))
    return base::PLATFORM_FILE_ERROR_FAILED;

  if (!SetPlatformSpecificDirectoryPermissions(path))
    return base::PLATFORM_FILE_ERROR_FAILED;

  return base::PLATFORM_FILE_OK;
}

PlatformFileError NativeFileUtil::GetFileInfo(
    const base::FilePath& path,
    base::PlatformFileInfo* file_info) {
  if (!file_util::PathExists(path))
    return base::PLATFORM_FILE_ERROR_NOT_FOUND;
  if (!file_util::GetFileInfo(path, file_info))
    return base::PLATFORM_FILE_ERROR_FAILED;
  return base::PLATFORM_FILE_OK;
}

scoped_ptr<FileSystemFileUtil::AbstractFileEnumerator>
    NativeFileUtil::CreateFileEnumerator(const base::FilePath& root_path,
                                         bool recursive) {
  return make_scoped_ptr(new NativeFileEnumerator(
      root_path, recursive,
      file_util::FileEnumerator::FILES |
          file_util::FileEnumerator::DIRECTORIES))
      .PassAs<FileSystemFileUtil::AbstractFileEnumerator>();
}

PlatformFileError NativeFileUtil::Touch(
    const base::FilePath& path,
    const base::Time& last_access_time,
    const base::Time& last_modified_time) {
  if (!file_util::TouchFile(
          path, last_access_time, last_modified_time))
    return base::PLATFORM_FILE_ERROR_FAILED;
  return base::PLATFORM_FILE_OK;
}

PlatformFileError NativeFileUtil::Truncate(const base::FilePath& path, int64 length) {
  PlatformFileError error_code(base::PLATFORM_FILE_ERROR_FAILED);
  PlatformFile file =
      base::CreatePlatformFile(
          path,
          base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_WRITE,
          NULL,
          &error_code);
  if (error_code != base::PLATFORM_FILE_OK) {
    return error_code;
  }
  DCHECK_NE(base::kInvalidPlatformFileValue, file);
  if (!base::TruncatePlatformFile(file, length))
    error_code = base::PLATFORM_FILE_ERROR_FAILED;
  base::ClosePlatformFile(file);
  return error_code;
}

bool NativeFileUtil::PathExists(const base::FilePath& path) {
  return file_util::PathExists(path);
}

bool NativeFileUtil::DirectoryExists(const base::FilePath& path) {
  return file_util::DirectoryExists(path);
}

PlatformFileError NativeFileUtil::CopyOrMoveFile(
    const base::FilePath& src_path,
    const base::FilePath& dest_path,
    bool copy) {
  base::PlatformFileInfo info;
  base::PlatformFileError error = NativeFileUtil::GetFileInfo(src_path, &info);
  if (error != base::PLATFORM_FILE_OK)
    return error;
  if (info.is_directory)
    return base::PLATFORM_FILE_ERROR_NOT_A_FILE;

  error = NativeFileUtil::GetFileInfo(dest_path, &info);
  if (error != base::PLATFORM_FILE_OK &&
      error != base::PLATFORM_FILE_ERROR_NOT_FOUND)
    return error;
  if (info.is_directory)
    return base::PLATFORM_FILE_ERROR_INVALID_OPERATION;
  if (error == base::PLATFORM_FILE_ERROR_NOT_FOUND) {
    error = NativeFileUtil::GetFileInfo(dest_path.DirName(), &info);
    if (error != base::PLATFORM_FILE_OK)
      return error;
    if (!info.is_directory)
      return base::PLATFORM_FILE_ERROR_NOT_FOUND;
  }

  if (copy) {
    if (file_util::CopyFile(src_path, dest_path))
      return base::PLATFORM_FILE_OK;
  } else {
    if (file_util::Move(src_path, dest_path))
      return base::PLATFORM_FILE_OK;
  }
  return base::PLATFORM_FILE_ERROR_FAILED;
}

PlatformFileError NativeFileUtil::DeleteFile(const base::FilePath& path) {
  if (!file_util::PathExists(path))
    return base::PLATFORM_FILE_ERROR_NOT_FOUND;
  if (file_util::DirectoryExists(path))
    return base::PLATFORM_FILE_ERROR_NOT_A_FILE;
  if (!file_util::Delete(path, false))
    return base::PLATFORM_FILE_ERROR_FAILED;
  return base::PLATFORM_FILE_OK;
}

PlatformFileError NativeFileUtil::DeleteDirectory(const base::FilePath& path) {
  if (!file_util::PathExists(path))
    return base::PLATFORM_FILE_ERROR_NOT_FOUND;
  if (!file_util::DirectoryExists(path))
    return base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY;
  if (!file_util::IsDirectoryEmpty(path))
    return base::PLATFORM_FILE_ERROR_NOT_EMPTY;
  if (!file_util::Delete(path, false))
    return base::PLATFORM_FILE_ERROR_FAILED;
  return base::PLATFORM_FILE_OK;
}

}  // namespace fileapi
<commit_msg>Do not return file descriptor if target is a directory in IsolatedFileSystem<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "webkit/fileapi/native_file_util.h"

#include "base/file_util.h"
#include "base/memory/scoped_ptr.h"
#include "webkit/fileapi/file_system_operation_context.h"

namespace fileapi {

namespace {

// Sets permissions on directory at |dir_path| based on the target platform.
// Returns true on success, or false otherwise.
//
// TODO(benchan): Find a better place outside webkit to host this function.
bool SetPlatformSpecificDirectoryPermissions(const base::FilePath& dir_path) {
#if defined(OS_CHROMEOS)
    // System daemons on Chrome OS may run as a user different than the Chrome
    // process but need to access files under the directories created here.
    // Because of that, grant the execute permission on the created directory
    // to group and other users.
    if (HANDLE_EINTR(chmod(dir_path.value().c_str(),
                           S_IRWXU | S_IXGRP | S_IXOTH)) != 0) {
      return false;
    }
#endif
    // Keep the directory permissions unchanged on non-Chrome OS platforms.
    return true;
}

}  // namespace

using base::PlatformFile;
using base::PlatformFileError;

class NativeFileEnumerator : public FileSystemFileUtil::AbstractFileEnumerator {
 public:
  NativeFileEnumerator(const base::FilePath& root_path,
                       bool recursive,
                       int file_type)
    : file_enum_(root_path, recursive, file_type) {
#if defined(OS_WIN)
    memset(&file_util_info_, 0, sizeof(file_util_info_));
#endif  // defined(OS_WIN)
  }

  virtual ~NativeFileEnumerator() {}

  virtual base::FilePath Next() OVERRIDE;
  virtual int64 Size() OVERRIDE;
  virtual base::Time LastModifiedTime() OVERRIDE;
  virtual bool IsDirectory() OVERRIDE;

 private:
  file_util::FileEnumerator file_enum_;
  file_util::FileEnumerator::FindInfo file_util_info_;
};

base::FilePath NativeFileEnumerator::Next() {
  base::FilePath rv = file_enum_.Next();
  if (!rv.empty())
    file_enum_.GetFindInfo(&file_util_info_);
  return rv;
}

int64 NativeFileEnumerator::Size() {
  return file_util::FileEnumerator::GetFilesize(file_util_info_);
}

base::Time NativeFileEnumerator::LastModifiedTime() {
  return file_util::FileEnumerator::GetLastModifiedTime(file_util_info_);
}

bool NativeFileEnumerator::IsDirectory() {
  return file_util::FileEnumerator::IsDirectory(file_util_info_);
}

PlatformFileError NativeFileUtil::CreateOrOpen(
    const base::FilePath& path, int file_flags,
    PlatformFile* file_handle, bool* created) {
  if (!file_util::DirectoryExists(path.DirName())) {
    // If its parent does not exist, should return NOT_FOUND error.
    return base::PLATFORM_FILE_ERROR_NOT_FOUND;
  }
  if (file_util::DirectoryExists(path))
    return base::PLATFORM_FILE_ERROR_NOT_A_FILE;
  PlatformFileError error_code = base::PLATFORM_FILE_OK;
  *file_handle = base::CreatePlatformFile(path, file_flags,
                                          created, &error_code);
  return error_code;
}

PlatformFileError NativeFileUtil::Close(PlatformFile file_handle) {
  if (!base::ClosePlatformFile(file_handle))
    return base::PLATFORM_FILE_ERROR_FAILED;
  return base::PLATFORM_FILE_OK;
}

PlatformFileError NativeFileUtil::EnsureFileExists(
    const base::FilePath& path,
    bool* created) {
  if (!file_util::DirectoryExists(path.DirName()))
    // If its parent does not exist, should return NOT_FOUND error.
    return base::PLATFORM_FILE_ERROR_NOT_FOUND;
  PlatformFileError error_code = base::PLATFORM_FILE_OK;
  // Tries to create the |path| exclusively.  This should fail
  // with base::PLATFORM_FILE_ERROR_EXISTS if the path already exists.
  PlatformFile handle = base::CreatePlatformFile(
      path,
      base::PLATFORM_FILE_CREATE | base::PLATFORM_FILE_READ,
      created, &error_code);
  if (error_code == base::PLATFORM_FILE_ERROR_EXISTS) {
    // Make sure created_ is false.
    if (created)
      *created = false;
    error_code = base::PLATFORM_FILE_OK;
  }
  if (handle != base::kInvalidPlatformFileValue)
    base::ClosePlatformFile(handle);
  return error_code;
}

PlatformFileError NativeFileUtil::CreateDirectory(
    const base::FilePath& path,
    bool exclusive,
    bool recursive) {
  // If parent dir of file doesn't exist.
  if (!recursive && !file_util::PathExists(path.DirName()))
    return base::PLATFORM_FILE_ERROR_NOT_FOUND;

  bool path_exists = file_util::PathExists(path);
  if (exclusive && path_exists)
    return base::PLATFORM_FILE_ERROR_EXISTS;

  // If file exists at the path.
  if (path_exists && !file_util::DirectoryExists(path))
    return base::PLATFORM_FILE_ERROR_EXISTS;

  if (!file_util::CreateDirectory(path))
    return base::PLATFORM_FILE_ERROR_FAILED;

  if (!SetPlatformSpecificDirectoryPermissions(path))
    return base::PLATFORM_FILE_ERROR_FAILED;

  return base::PLATFORM_FILE_OK;
}

PlatformFileError NativeFileUtil::GetFileInfo(
    const base::FilePath& path,
    base::PlatformFileInfo* file_info) {
  if (!file_util::PathExists(path))
    return base::PLATFORM_FILE_ERROR_NOT_FOUND;
  if (!file_util::GetFileInfo(path, file_info))
    return base::PLATFORM_FILE_ERROR_FAILED;
  return base::PLATFORM_FILE_OK;
}

scoped_ptr<FileSystemFileUtil::AbstractFileEnumerator>
    NativeFileUtil::CreateFileEnumerator(const base::FilePath& root_path,
                                         bool recursive) {
  return make_scoped_ptr(new NativeFileEnumerator(
      root_path, recursive,
      file_util::FileEnumerator::FILES |
          file_util::FileEnumerator::DIRECTORIES))
      .PassAs<FileSystemFileUtil::AbstractFileEnumerator>();
}

PlatformFileError NativeFileUtil::Touch(
    const base::FilePath& path,
    const base::Time& last_access_time,
    const base::Time& last_modified_time) {
  if (!file_util::TouchFile(
          path, last_access_time, last_modified_time))
    return base::PLATFORM_FILE_ERROR_FAILED;
  return base::PLATFORM_FILE_OK;
}

PlatformFileError NativeFileUtil::Truncate(const base::FilePath& path, int64 length) {
  PlatformFileError error_code(base::PLATFORM_FILE_ERROR_FAILED);
  PlatformFile file =
      base::CreatePlatformFile(
          path,
          base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_WRITE,
          NULL,
          &error_code);
  if (error_code != base::PLATFORM_FILE_OK) {
    return error_code;
  }
  DCHECK_NE(base::kInvalidPlatformFileValue, file);
  if (!base::TruncatePlatformFile(file, length))
    error_code = base::PLATFORM_FILE_ERROR_FAILED;
  base::ClosePlatformFile(file);
  return error_code;
}

bool NativeFileUtil::PathExists(const base::FilePath& path) {
  return file_util::PathExists(path);
}

bool NativeFileUtil::DirectoryExists(const base::FilePath& path) {
  return file_util::DirectoryExists(path);
}

PlatformFileError NativeFileUtil::CopyOrMoveFile(
    const base::FilePath& src_path,
    const base::FilePath& dest_path,
    bool copy) {
  base::PlatformFileInfo info;
  base::PlatformFileError error = NativeFileUtil::GetFileInfo(src_path, &info);
  if (error != base::PLATFORM_FILE_OK)
    return error;
  if (info.is_directory)
    return base::PLATFORM_FILE_ERROR_NOT_A_FILE;

  error = NativeFileUtil::GetFileInfo(dest_path, &info);
  if (error != base::PLATFORM_FILE_OK &&
      error != base::PLATFORM_FILE_ERROR_NOT_FOUND)
    return error;
  if (info.is_directory)
    return base::PLATFORM_FILE_ERROR_INVALID_OPERATION;
  if (error == base::PLATFORM_FILE_ERROR_NOT_FOUND) {
    error = NativeFileUtil::GetFileInfo(dest_path.DirName(), &info);
    if (error != base::PLATFORM_FILE_OK)
      return error;
    if (!info.is_directory)
      return base::PLATFORM_FILE_ERROR_NOT_FOUND;
  }

  if (copy) {
    if (file_util::CopyFile(src_path, dest_path))
      return base::PLATFORM_FILE_OK;
  } else {
    if (file_util::Move(src_path, dest_path))
      return base::PLATFORM_FILE_OK;
  }
  return base::PLATFORM_FILE_ERROR_FAILED;
}

PlatformFileError NativeFileUtil::DeleteFile(const base::FilePath& path) {
  if (!file_util::PathExists(path))
    return base::PLATFORM_FILE_ERROR_NOT_FOUND;
  if (file_util::DirectoryExists(path))
    return base::PLATFORM_FILE_ERROR_NOT_A_FILE;
  if (!file_util::Delete(path, false))
    return base::PLATFORM_FILE_ERROR_FAILED;
  return base::PLATFORM_FILE_OK;
}

PlatformFileError NativeFileUtil::DeleteDirectory(const base::FilePath& path) {
  if (!file_util::PathExists(path))
    return base::PLATFORM_FILE_ERROR_NOT_FOUND;
  if (!file_util::DirectoryExists(path))
    return base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY;
  if (!file_util::IsDirectoryEmpty(path))
    return base::PLATFORM_FILE_ERROR_NOT_EMPTY;
  if (!file_util::Delete(path, false))
    return base::PLATFORM_FILE_ERROR_FAILED;
  return base::PLATFORM_FILE_OK;
}

}  // namespace fileapi
<|endoftext|>


<commit_before>#include "UnixFilesystem.h"
#include "BigFix/DataRef.h"
#include "BigFix/Error.h"
#include <fcntl.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <unistd.h>

namespace BigFix
{

UnixFile::UnixFile( int fd, const std::string& path )
  : m_fd( fd ), m_path( path )
{
}

UnixFile::~UnixFile()
{
  close( m_fd );
}

void UnixFile::SetModificationTime( const DateTime& mtime )
{
  struct tm systemTime;
  memset( &systemTime, 0, sizeof( systemTime ) );

  systemTime.tm_year = mtime.Year() - 1900;
  systemTime.tm_mon = mtime.Month() - 1;
  systemTime.tm_mday = mtime.Day();
  systemTime.tm_wday = mtime.DayOfWeek() - 1;
  systemTime.tm_hour = mtime.Hour();
  systemTime.tm_min = mtime.Minute();
  systemTime.tm_sec = mtime.Second();

  time_t unixTime = timegm( &systemTime );

  struct timeval fileTimes[2];
  fileTimes[0].tv_sec = unixTime;
  fileTimes[1].tv_sec = unixTime;

  if ( utimes( m_path.c_str(), fileTimes ) )
    throw Error( "Failed to set modification time" );
}

size_t UnixFile::Read( uint8_t* buffer, size_t length )
{
  ssize_t nread = read( m_fd, buffer, length );

  if ( nread < 0 )
    throw Error( "Failed to read file" );

  return nread;
}

void UnixFile::Write( DataRef data )
{
  const uint8_t* start = data.Start();
  const uint8_t* end = data.End();

  while ( start != end )
  {
    ssize_t nwritten = write( m_fd, start, end - start );

    if ( nwritten < 0 )
      throw Error( "Failed to write file" );

    start += nwritten;
  }
}

static std::auto_ptr<File> NewFile( const char* path, int fd )
{
  if ( fd < 0 )
    throw Error( "Failed to open or create file" );

  std::auto_ptr<File> file;

  try
  {
    file.reset( new UnixFile( fd, path ) );
  }
  catch ( ... )
  {
    close( fd );
    throw;
  }

  return file;
}

std::auto_ptr<File> OpenNewFile( const char* path )
{
  return NewFile(
    path,
    open( path,
          O_WRONLY | O_CREAT | O_EXCL,
          S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH ) );
}

std::auto_ptr<File> OpenExistingFile( const char* path )
{
  return NewFile( path, open( path, O_RDONLY ) );
}

void MakeDir( const char* path )
{
  if ( mkdir( path, S_IRWXU ) )
    throw Error( "Failed to create directory" );
}

FileStatus Stat( const char* path )
{
  struct stat stats;

  if ( stat( path, &stats ) )
    throw Error( "Failed to stat file" );

  struct tm result;
  if ( gmtime_r( &stats.st_mtime, &result ) == 0 )
    throw Error( "Failed to convert file time to DateTime" );

  DateTime mtime( result.tm_year + 1900,
                  result.tm_mon + 1,
                  result.tm_mday,
                  result.tm_wday + 1,
                  result.tm_hour,
                  result.tm_min,
                  result.tm_sec );

  return FileStatus(
    stats.st_size, mtime, S_ISDIR( stats.st_mode ), S_ISREG( stats.st_mode ) );
}

void StreamStdIn( Stream& stream )
{
  uint8_t buffer[4096];

  while ( true )
  {
    ssize_t nread = read( 0, buffer, sizeof( buffer ) );

    if ( nread < 0 )
      throw Error( "Failed to read from stdin" );

    if ( nread == 0 )
      break;

    stream.Write( DataRef( buffer, buffer + nread ) );
  }

  stream.End();
}

OpenDir::OpenDir( const char* path )
{
  m_dir = opendir( path );

  if ( !m_dir )
    throw Error( "Failed to open directory" );
}

OpenDir::~OpenDir()
{
  closedir( m_dir );
}

std::vector<std::string> ReadDir( const char* path )
{
  OpenDir dir( path );

  std::vector<std::string> entries;

  while ( true )
  {
    struct dirent entry;
    struct dirent* result;

    if ( readdir_r( dir, &entry, &result ) )
      throw Error( "Failed to read directory contents" );

    if ( !result )
      break;

    if ( !IsDots( result->d_name ) )
      entries.push_back( result->d_name );
  }

  return entries;
}

// This non-implementation of LocalPathToUTF8Path isn't correct, but there isn't
// a correct thing to do in all cases.

std::string LocalPathToUTF8Path( const char* path )
{
  return path;
}

std::string LocalPathToUTF8Path( const char* path, int codepage )
{
  return path;
}

}
<commit_msg>Fix bug<commit_after>#include "UnixFilesystem.h"
#include "BigFix/DataRef.h"
#include "BigFix/Error.h"
#include <fcntl.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <unistd.h>

namespace BigFix
{

UnixFile::UnixFile( int fd, const std::string& path )
  : m_fd( fd ), m_path( path )
{
}

UnixFile::~UnixFile()
{
  close( m_fd );
}

void UnixFile::SetModificationTime( const DateTime& mtime )
{
  struct tm systemTime;
  memset( &systemTime, 0, sizeof( systemTime ) );

  systemTime.tm_year = mtime.Year() - 1900;
  systemTime.tm_mon = mtime.Month() - 1;
  systemTime.tm_mday = mtime.Day();
  systemTime.tm_wday = mtime.DayOfWeek() - 1;
  systemTime.tm_hour = mtime.Hour();
  systemTime.tm_min = mtime.Minute();
  systemTime.tm_sec = mtime.Second();

  time_t unixTime = timegm( &systemTime );

  struct timeval fileTimes[2];
  memset( &fileTimes, 0, sizeof( fileTimes ) );

  fileTimes[0].tv_sec = unixTime;
  fileTimes[1].tv_sec = unixTime;

  if ( utimes( m_path.c_str(), fileTimes ) )
    throw Error( "Failed to set modification time" );
}

size_t UnixFile::Read( uint8_t* buffer, size_t length )
{
  ssize_t nread = read( m_fd, buffer, length );

  if ( nread < 0 )
    throw Error( "Failed to read file" );

  return nread;
}

void UnixFile::Write( DataRef data )
{
  const uint8_t* start = data.Start();
  const uint8_t* end = data.End();

  while ( start != end )
  {
    ssize_t nwritten = write( m_fd, start, end - start );

    if ( nwritten < 0 )
      throw Error( "Failed to write file" );

    start += nwritten;
  }
}

static std::auto_ptr<File> NewFile( const char* path, int fd )
{
  if ( fd < 0 )
    throw Error( "Failed to open or create file" );

  std::auto_ptr<File> file;

  try
  {
    file.reset( new UnixFile( fd, path ) );
  }
  catch ( ... )
  {
    close( fd );
    throw;
  }

  return file;
}

std::auto_ptr<File> OpenNewFile( const char* path )
{
  return NewFile(
    path,
    open( path,
          O_WRONLY | O_CREAT | O_EXCL,
          S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH ) );
}

std::auto_ptr<File> OpenExistingFile( const char* path )
{
  return NewFile( path, open( path, O_RDONLY ) );
}

void MakeDir( const char* path )
{
  if ( mkdir( path, S_IRWXU ) )
    throw Error( "Failed to create directory" );
}

FileStatus Stat( const char* path )
{
  struct stat stats;

  if ( stat( path, &stats ) )
    throw Error( "Failed to stat file" );

  struct tm result;
  if ( gmtime_r( &stats.st_mtime, &result ) == 0 )
    throw Error( "Failed to convert file time to DateTime" );

  DateTime mtime( result.tm_year + 1900,
                  result.tm_mon + 1,
                  result.tm_mday,
                  result.tm_wday + 1,
                  result.tm_hour,
                  result.tm_min,
                  result.tm_sec );

  return FileStatus(
    stats.st_size, mtime, S_ISDIR( stats.st_mode ), S_ISREG( stats.st_mode ) );
}

void StreamStdIn( Stream& stream )
{
  uint8_t buffer[4096];

  while ( true )
  {
    ssize_t nread = read( 0, buffer, sizeof( buffer ) );

    if ( nread < 0 )
      throw Error( "Failed to read from stdin" );

    if ( nread == 0 )
      break;

    stream.Write( DataRef( buffer, buffer + nread ) );
  }

  stream.End();
}

OpenDir::OpenDir( const char* path )
{
  m_dir = opendir( path );

  if ( !m_dir )
    throw Error( "Failed to open directory" );
}

OpenDir::~OpenDir()
{
  closedir( m_dir );
}

std::vector<std::string> ReadDir( const char* path )
{
  OpenDir dir( path );

  std::vector<std::string> entries;

  while ( true )
  {
    struct dirent entry;
    struct dirent* result;

    if ( readdir_r( dir, &entry, &result ) )
      throw Error( "Failed to read directory contents" );

    if ( !result )
      break;

    if ( !IsDots( result->d_name ) )
      entries.push_back( result->d_name );
  }

  return entries;
}

// This non-implementation of LocalPathToUTF8Path isn't correct, but there isn't
// a correct thing to do in all cases.

std::string LocalPathToUTF8Path( const char* path )
{
  return path;
}

std::string LocalPathToUTF8Path( const char* path, int codepage )
{
  return path;
}

}
<|endoftext|>


<commit_before>/**
 * Copyright (c) 2013 Egor Pushkin. All rights reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#include "Common/Common.h"

#include "NetworkHelper.h"

#include "Config.h"

namespace RemotePC
{

	std::vector< std::string > NetworkHelper::EnumHostEndpoints()
	{
		std::vector< std::string > endpoints;

		boost::asio::io_service service;
		boost::asio::ip::tcp::resolver resolver(service);
		boost::asio::ip::tcp::resolver::query query(boost::asio::ip::host_name(), Config::Instance().GetService());
		boost::asio::ip::tcp::resolver::iterator endpointIterator = resolver.resolve(query);
		boost::asio::ip::tcp::resolver::iterator end;

		boost::system::error_code error = boost::asio::error::host_not_found;
		while ( error && endpointIterator != end )
		{
			boost::asio::ip::tcp::endpoint endpoint = *endpointIterator++;
			if ( !endpoint.address().is_v4() )
				continue;
			endpoints.push_back(endpoint.address().to_string());
		}

		return endpoints;
	}

}
<commit_msg>RPC. Self IP resolution code was made exception safe.<commit_after>/**
 * Copyright (c) 2013 Egor Pushkin. All rights reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#include "Common/Common.h"

#include "NetworkHelper.h"

#include "Config.h"

namespace RemotePC
{

	std::vector< std::string > NetworkHelper::EnumHostEndpoints()
	{
		std::vector< std::string > endpoints;

        try
        {
            boost::asio::io_service service;
            boost::asio::ip::tcp::resolver resolver(service);
            boost::asio::ip::tcp::resolver::query query(boost::asio::ip::host_name(), Config::Instance().GetService());
            boost::asio::ip::tcp::resolver::iterator endpointIterator = resolver.resolve(query);
            boost::asio::ip::tcp::resolver::iterator end;

            boost::system::error_code error = boost::asio::error::host_not_found;
            while ( error && endpointIterator != end )
            {
                boost::asio::ip::tcp::endpoint endpoint = *endpointIterator++;
                if ( !endpoint.address().is_v4() )
                    continue;
                std::string address = endpoint.address().to_string();
                if ( endpoints.end() != std::find(endpoints.begin(), endpoints.end(), address) )
                    continue;
                endpoints.push_back(address);
            }
        }
        catch ( ... )
        {
            endpoints.push_back("Unknown");
        }

		return endpoints;
	}

}
<|endoftext|>


<commit_before>// This may look like C code, but it is really -*- C++ -*-
//
// Copyright Bob Friesenhahn, 2003
//
// Test STL colorHistogram function
//

#undef USE_VECTOR
#define USE_MAP

#include <Magick++.h>
#include <string>
#include <iostream>
#include <iomanip>
#if defined(USE_VECTOR)
#  include <vector>
#  include <utility>
#endif
#if defined(USE_MAP)
#  include <map>
#endif

using namespace std;

using namespace Magick;

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

  // Initialize ImageMagick install location for Windows
  InitializeMagick(*argv);

  int failures=0;

  try {

    string srcdir("");
    if(getenv("SRCDIR") != 0)
      srcdir = getenv("SRCDIR");

    // Read image
    Image image;
    image.read( srcdir + "test_image.miff" );

    // Create histogram vector
#if defined(USE_MAP)
    std::map<Color,size_t> histogram;
#elif defined(USE_VECTOR)
    std::vector<std::pair<Color,size_t> > histogram;
#endif

    colorHistogram( &histogram, image );

    // Print out histogram
#if (MAGICKCORE_QUANTUM_DEPTH == 8)
    int quantum_width=3;
#elif (MAGICKCORE_QUANTUM_DEPTH == 16)
    int quantum_width=5;
#else
    int quantum_width=10;
#endif

    cout << "Histogram for file \"" << image.fileName() << "\"" << endl
         << histogram.size() << " entries:" << endl;

#if defined(USE_MAP)
    std::map<Color,size_t>::const_iterator p=histogram.begin();
#elif defined(USE_VECTOR)
    std::vector<std::pair<Color,size_t> >::const_iterator p=histogram.begin();
#endif
    while (p != histogram.end())
      {
        cout << setw(10) << (int)p->second << ": ("
             << setw(quantum_width) << (int)p->first.redQuantum() << ","
             << setw(quantum_width) << (int)p->first.greenQuantum() << ","
             << setw(quantum_width) << (int)p->first.blueQuantum() << ")"
             << endl;
        p++;
      }
  }

  catch( Exception &error_ )
    {
      cout << "Caught exception: " << error_.what() << endl;
      return 1;
    }
  catch( exception &error_ )
    {
      cout << "Caught exception: " << error_.what() << endl;
      return 1;
    }

  if ( failures )
    {
      cout << failures << " failures" << endl;
      return 1;
    }

  return 0;
}

<commit_msg>Fixed test.<commit_after>// This may look like C code, but it is really -*- C++ -*-
//
// Copyright Bob Friesenhahn, 2003
//
// Test STL colorHistogram function
//

#undef USE_VECTOR
#define USE_MAP

#include <Magick++.h>
#include <string>
#include <iostream>
#include <iomanip>
#if defined(USE_VECTOR)
#  include <vector>
#  include <utility>
#endif
#if defined(USE_MAP)
#  include <map>
#endif

using namespace std;

using namespace Magick;

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

  // Initialize ImageMagick install location for Windows
  InitializeMagick(*argv);

  int failures=0;

  try {

    string srcdir("");
    if(getenv("SRCDIR") != 0)
      srcdir = getenv("SRCDIR");

    // Read image
    Image image;
    image.read( srcdir + "test_image.miff" );

    // Create histogram vector
#if defined(USE_MAP)
    std::map<Color,size_t> histogram;
#elif defined(USE_VECTOR)
    std::vector<std::pair<Color,size_t> > histogram;
#endif

    colorHistogram( &histogram, image );

    // Print out histogram
#if (MAGICKCORE_QUANTUM_DEPTH == 8)
    int quantum_width=3;
#elif (MAGICKCORE_QUANTUM_DEPTH == 16)
    int quantum_width=5;
#else
    int quantum_width=10;
#endif

    cout << "Histogram for file \"" << image.fileName() << "\"" << endl
         << histogram.size() << " entries:" << endl;

#if defined(USE_MAP)
    std::map<Color,size_t>::const_iterator p=histogram.begin();
#elif defined(USE_VECTOR)
    std::vector<std::pair<Color,size_t> >::const_iterator p=histogram.begin();
#endif
    while (p != histogram.end())
      {
        cout << setw(10) << (int)p->second << ": ("
             << setw(quantum_width) << (int)p->first.quantumRed() << ","
             << setw(quantum_width) << (int)p->first.quantumGreen() << ","
             << setw(quantum_width) << (int)p->first.quantumBlue() << ")"
             << endl;
        p++;
      }
  }

  catch( Exception &error_ )
    {
      cout << "Caught exception: " << error_.what() << endl;
      return 1;
    }
  catch( exception &error_ )
    {
      cout << "Caught exception: " << error_.what() << endl;
      return 1;
    }

  if ( failures )
    {
      cout << failures << " failures" << endl;
      return 1;
    }

  return 0;
}

<|endoftext|>


<commit_before>/******************************************************************
*
* uSQL for C++
*
* Copyright (C) Satoshi Konno 2012
*
* This is licensed under BSD-style license, see file COPYING.
*
******************************************************************/

#include <strstream>

#include <antlr3.h>
#include <usql/SQLParser.h>
#include <usql/parser/antlr/SQLLexer.h>
#include <usql/parser/antlr/SQLParser.h>

void uSQLDisplayRecognitionError (pANTLR3_BASE_RECOGNIZER recognizer, pANTLR3_UINT8 * tokenNames)
{
  pANTLR3_PARSER parser = (pANTLR3_PARSER)(recognizer->super);
  pSQLParser sqlParser = (pSQLParser)parser->super;
  uSQL::SQLParser *uSqlParser = (uSQL::SQLParser *)sqlParser->uSqlParser;
  uSQL::SQLError *uSqlError = uSqlParser->getError();

  uSqlError->setCode(recognizer->state->exception->type);
  uSqlError->setLine(recognizer->state->exception->line);
  uSqlError->setOffset(recognizer->state->exception->charPositionInLine + 1);

  std::strstream errorMessage;
  std::string message = (const char *)(recognizer->state->exception->message);
  errorMessage << "Parser Error (" << uSqlError->getLine() << ") : " << message << " at offset " << uSqlError->getOffset();
  uSqlError->setMessage(errorMessage.str());
}

uSQL::SQLParser::SQLParser()
{
}

uSQL::SQLParser::~SQLParser()
{
  clear();
}

void uSQL::SQLParser::setStatementType(int type)
{
  for (std::vector<SQLStatement *>::iterator stmt = statements.begin(); stmt != statements.end(); stmt++)
    (*stmt)->setStatementType(type);
}

void uSQL::SQLParser::clear()
{
  for (std::vector<SQLStatement *>::iterator stmt = statements.begin(); stmt != statements.end(); stmt++)
    delete *stmt;
  this->statements.clear();
  this->error.clear();
}

bool uSQL::SQLParser::parse(const std::string &queryString)
{
  clear();

  pANTLR3_INPUT_STREAM input  = antlr3StringStreamNew(
        (pANTLR3_UINT8)queryString.c_str(),
        ANTLR3_ENC_UTF8,
        (ANTLR3_UINT32)queryString.length(),
        (pANTLR3_UINT8)"");

  pSQLLexer lexer = SQLLexerNew(input);

  pANTLR3_COMMON_TOKEN_STREAM tokens = antlr3CommonTokenStreamSourceNew(ANTLR3_SIZE_HINT, TOKENSOURCE(lexer));
  pSQLParser parser = SQLParserNew(tokens);
  parser->uSqlParser = this;
  parser->statement_list(parser, this);

  bool parserResult = true;
  if (0 < parser->pParser->rec->state->errorCount) {
    parserResult = false;
  }

  parser->free(parser);
  tokens->free(tokens);
  lexer->free(lexer);
  input->close(input);

  return parserResult;
}
<commit_msg>* Updated SQLParser::parse() to compile with ANTLR 3.2 for Ubuntu 14.04.<commit_after>/******************************************************************
*
* uSQL for C++
*
* Copyright (C) Satoshi Konno 2012
*
* This is licensed under BSD-style license, see file COPYING.
*
******************************************************************/

#include <strstream>

#include <antlr3.h>
#include <usql/SQLParser.h>
#include <usql/parser/antlr/SQLLexer.h>
#include <usql/parser/antlr/SQLParser.h>

void uSQLDisplayRecognitionError (pANTLR3_BASE_RECOGNIZER recognizer, pANTLR3_UINT8 * tokenNames)
{
  pANTLR3_PARSER parser = (pANTLR3_PARSER)(recognizer->super);
  pSQLParser sqlParser = (pSQLParser)parser->super;
  uSQL::SQLParser *uSqlParser = (uSQL::SQLParser *)sqlParser->uSqlParser;
  uSQL::SQLError *uSqlError = uSqlParser->getError();

  uSqlError->setCode(recognizer->state->exception->type);
  uSqlError->setLine(recognizer->state->exception->line);
  uSqlError->setOffset(recognizer->state->exception->charPositionInLine + 1);

  std::strstream errorMessage;
  std::string message = (const char *)(recognizer->state->exception->message);
  errorMessage << "Parser Error (" << uSqlError->getLine() << ") : " << message << " at offset " << uSqlError->getOffset();
  uSqlError->setMessage(errorMessage.str());
}

uSQL::SQLParser::SQLParser()
{
}

uSQL::SQLParser::~SQLParser()
{
  clear();
}

void uSQL::SQLParser::setStatementType(int type)
{
  for (std::vector<SQLStatement *>::iterator stmt = statements.begin(); stmt != statements.end(); stmt++)
    (*stmt)->setStatementType(type);
}

void uSQL::SQLParser::clear()
{
  for (std::vector<SQLStatement *>::iterator stmt = statements.begin(); stmt != statements.end(); stmt++)
    delete *stmt;
  this->statements.clear();
  this->error.clear();
}

bool uSQL::SQLParser::parse(const std::string &queryString)
{
  clear();

#if defined(USE_ANTLR3_STRINGSTREAMNEW)
  pANTLR3_INPUT_STREAM input  = antlr3StringStreamNew(
        (pANTLR3_UINT8)queryString.c_str(),
        ANTLR3_ENC_UTF8,
        (ANTLR3_UINT32)queryString.length(),
        (pANTLR3_UINT8)"");
#else
  pANTLR3_INPUT_STREAM input  = antlr3NewAsciiStringInPlaceStream(
        (pANTLR3_UINT8)queryString.c_str(),
        (ANTLR3_UINT32)queryString.length(),
        (pANTLR3_UINT8)"");
#endif

  pSQLLexer lexer = SQLLexerNew(input);

  pANTLR3_COMMON_TOKEN_STREAM tokens = antlr3CommonTokenStreamSourceNew(ANTLR3_SIZE_HINT, TOKENSOURCE(lexer));
  pSQLParser parser = SQLParserNew(tokens);
  parser->uSqlParser = this;
  parser->statement_list(parser, this);

  bool parserResult = true;
  if (0 < parser->pParser->rec->state->errorCount) {
    parserResult = false;
  }

  parser->free(parser);
  tokens->free(tokens);
  lexer->free(lexer);
  input->close(input);

  return parserResult;
}
<|endoftext|>


<commit_before>
#ifndef CHROMOSOME_HPP_
#define CHROMOSOME_HPP_

#include <iostream>

#include <time.h>
#include <stdlib.h>
#include <vector>
#include <algorithm>
#include <random>

#define MINIMUM_NUMBER 0

template <class T>
class Chromosome {

protected:
    std::vector<T > chromosome;

    // random number generator values.
    static std::mt19937 random_engine;
    static std::uniform_int_distribution<int> rand_chrom_elem;
    static std::uniform_real_distribution<> rand_value;

public:

    /**
     * Create a chromosome of the given size
     * @param chromosome_size The size of the chromosome.
     */
    Chromosome(unsigned int chromosome_size) : chromosome(chromosome_size){
    }

    ~Chromosome() {

    }

    /**
     * Create a chromosome of the given size
     * @param chromosome_size The size of the chromosome.
     */
    Chromosome(std::vector<T > chromosome) {
    	this->chromosome = chromosome;
    }

    //TODO create random chromosome generator.

    /**
     * Set up the random number generator engines to allow within the defined ranges.
     * @param chromosome_size The size of the chromosome.
     * @param min_chromosome_value The minimum value of a chromosome element.
     * @param max_chromosome_value The maximum value of a chromosome element.
     */
    static void initialize(unsigned int chromosome_size, T min_chromosome_value, T max_chromosome_value) {

		// Set up the random number generator engines.
		std::random_device rd;
		random_engine = std::mt19937 (rd());
		rand_chrom_elem = std::uniform_int_distribution<int> (MINIMUM_NUMBER, chromosome_size - 1);
		rand_value = std::uniform_real_distribution<> (min_chromosome_value, max_chromosome_value);
    }

    /**
     * Apply the mutation operation to the chromosome and put it into the next generation.
     * @param children The next generation of chromosomes (the next population) that is currently being bread.
     */
    void mutate(std::vector<Chromosome<T > > &children) {
    	clonning(children);

    	// Identify element that will be changed
    	int mutated_index = getRandomElement();

    	// Apply mutation operation to the chromosome
    	if(std::is_same<T, bool>::value) {
    		// Flip the bit
    		children.back()[mutated_index] = !children.back()[mutated_index];
    	} else {
		// This will really only work for 'primitive types'
    		// Choose a random number within the range
    		children.back()[mutated_index] = rand_value(random_engine);
    	}
    }

    /**
     * Apply the crossover operation to the chromosome and the other chromosome provided.
     * This will produce two offspring that are placed in the next generation.
     * *Note, Assumed that the two chromosomes (this and other) are of the same length.
     * @param other The second chromosome involved in the crossover operation
     * @param children The next generation of the population.
     *
     * Note that there are two possible methods to apply this crossover: index inclusive and index exclusive.
     * Currently index inclusive is used, this is where the site where the chromosomes are crossed over is
     * included in the crossover. Exclusive is the opposite where the index where the chromosomes are
     * crossed over is not included in the crossover.
     *
     * The crossover will work as:
     * chromosome1 = l1 + r1
     * chromosome2 = l2 + r2
     * after the crossover:
     * chromosome1 = l1 + r2
     * chromosome2 = l2 + r1
     * Where l1 and l2 are subsets of the chromosome = chromosome[0..crossover_site-1] for each respective chromosome
     * and r1 and r2 are subsets of the chromosome = chromosome[crossover_site..chromosome.size()-1] for each respective chromosome.
     */
    void crossover(Chromosome<T > &other, std::vector<Chromosome<T > > &children) {
    	// Copy value to the next population
    	clonning(children);
    	// Copy other to the next population
    	other.clonning(children);

    	// Randomly pick one point (where the cross over starts)
    	// Doesn't work for index of 0 so we use restrictive getRandomElement
    	int crossover_index = getRandomElement(0);

    	// Using the index inclusive approach
    	// First gets l1 + r2 and second gets l2 + r1
    	std::swap_ranges((*(children.end()-2)).chromosome.begin(), (*(children.end()-2)).chromosome.begin()+crossover_index, (*(children.end()-1)).chromosome.rbegin()+(7-crossover_index)+1);

    	// Alternative exclusive index approach
    	//std::swap_ranges((*(children.end()-2)).begin(), (*(children.end()-2)).begin()+crossover_index+1, (*(children.end()-1)).rbegin()+crossover_index);

    }

    /**
     * Copy the chromosome to the next generation.
     * @param children The next generation.
     */
    void clonning(std::vector<Chromosome<T > > &children) {
    	// Copy value to the next population
    	children.push_back(*this);
    }

    /**
     * Overload the array operator.
     * @param n The index to retrieve the value at.
     * @return The value.
     */
    T operator[](unsigned int n) const {
    	return *this->chromosome[n];
    }

    /**
     * Overload the array operator
     * @param n The index to retrieve the value at.
     * @return The reference to the value.
     */
    T& operator[](unsigned int n) {
		return this->chromosome[n];
	}

    /**
     * Overload the == operation.
     * @param other The Chromosome to compare too.
     * @return Whether the two chromosomes are the same.
     */
    inline bool operator==(const Chromosome<T >& other){ return this->chromosome == other.chromosome; }

    /**
     * Overload the != operation, makes use of == operator overload
     * @param other The chromosome to check equality.
     * @return Whether the two chromosomes are different.
     */
    inline bool operator!=(const Chromosome<T >& other){ return !(*this == other); }

private:

    /**
     * Get a random index to allow for the retrieval a random element within the chromosome.
     * @return The random index.
     */
    unsigned int getRandomElement() {
    	return rand_chrom_elem(random_engine);
    }

	/**
	 * Get a random number between 0 and chromosome.size()-1 that is not index
	 * @param index The only value within the range that the return cannot be.
	 * @return A number within the defined range that is not index.
	 */
	unsigned int getRandomElement(unsigned int index) {
		unsigned int val = getRandomElement();

		while(val == index) {
			val = getRandomElement();
		}
		return val;
	}

};

template<class T>
std::mt19937 Chromosome<T >::random_engine;
template<class T>
std::uniform_int_distribution<int> Chromosome<T >::rand_chrom_elem;
template<class T>
std::uniform_real_distribution<> Chromosome<T >::rand_value;

#endif /* CHROMOSOME_HPP_ */
<commit_msg>FIXED: chromosome crossover issue<commit_after>
#ifndef CHROMOSOME_HPP_
#define CHROMOSOME_HPP_

#include <iostream>

#include <time.h>
#include <stdlib.h>
#include <vector>
#include <algorithm>
#include <random>

#define MINIMUM_NUMBER 0

template <class T>
class Chromosome {

protected:
    std::vector<T > chromosome;

    // random number generator values.
    static std::mt19937 random_engine;
    static std::uniform_int_distribution<int> rand_chrom_elem;
    static std::uniform_real_distribution<> rand_value;

public:

    /**
     * Create a chromosome of the given size
     * @param chromosome_size The size of the chromosome.
     */
    Chromosome(unsigned int chromosome_size) : chromosome(chromosome_size){
    }

    ~Chromosome() {

    }

    /**
     * Create a chromosome of the given size
     * @param chromosome_size The size of the chromosome.
     */
    Chromosome(std::vector<T > chromosome) {
    	this->chromosome = chromosome;
    }

    //TODO create random chromosome generator.

    /**
     * Set up the random number generator engines to allow within the defined ranges.
     * @param chromosome_size The size of the chromosome.
     * @param min_chromosome_value The minimum value of a chromosome element.
     * @param max_chromosome_value The maximum value of a chromosome element.
     */
    static void initialize(unsigned int chromosome_size, T min_chromosome_value, T max_chromosome_value) {

		// Set up the random number generator engines.
		std::random_device rd;
		random_engine = std::mt19937 (rd());
		rand_chrom_elem = std::uniform_int_distribution<int> (MINIMUM_NUMBER, chromosome_size - 1);
		rand_value = std::uniform_real_distribution<> (min_chromosome_value, max_chromosome_value);
    }

    /**
     * Apply the mutation operation to the chromosome and put it into the next generation.
     * @param children The next generation of chromosomes (the next population) that is currently being bread.
     */
    void mutate(std::vector<Chromosome<T > > &children) {
    	clonning(children);

    	// Identify element that will be changed
    	int mutated_index = getRandomElement();

    	// Apply mutation operation to the chromosome
    	if(std::is_same<T, bool>::value) {
    		// Flip the bit
    		children.back()[mutated_index] = !children.back()[mutated_index];
    	} else {
		// This will really only work for 'primitive types'
    		// Choose a random number within the range
    		children.back()[mutated_index] = rand_value(random_engine);
    	}
    }

    /**
     * Apply the crossover operation to the chromosome and the other chromosome provided.
     * This will produce two offspring that are placed in the next generation.
     * *Note, Assumed that the two chromosomes (this and other) are of the same length.
     * @param other The second chromosome involved in the crossover operation
     * @param children The next generation of the population.
     *
     * Note that there are two possible methods to apply this crossover: index inclusive and index exclusive.
     * Currently index inclusive is used, this is where the site where the chromosomes are crossed over is
     * included in the crossover. Exclusive is the opposite where the index where the chromosomes are
     * crossed over is not included in the crossover.
     *
     * The crossover will work as:
     * chromosome1 = l1 + r1
     * chromosome2 = l2 + r2
     * after the crossover:
     * chromosome1 = l1 + r2
     * chromosome2 = l2 + r1
     * Where l1 and l2 are subsets of the chromosome = chromosome[0..crossover_site-1] for each respective chromosome
     * and r1 and r2 are subsets of the chromosome = chromosome[crossover_site..chromosome.size()-1] for each respective chromosome.
     */
    void crossover(Chromosome<T > &other, std::vector<Chromosome<T > > &children) {
    	// Copy value to the next population
    	clonning(children);
    	// Copy other to the next population
    	other.clonning(children);

    	// Randomly pick one point (where the cross over starts)
    	// Doesn't work for index of 0 so we use restrictive getRandomElement
    	int crossover_index = getRandomElement(0);

    	// Using the index inclusive approach
    	// First gets l1 + r2 and second gets l2 + r1
    	std::swap_ranges((*(children.end()-2)).chromosome.begin(), (*(children.end()-2)).chromosome.begin()+crossover_index, (*(children.end()-1)).chromosome.rbegin()+(chromosome.size()-1-crossover_index)+1);

    	// Alternative exclusive index approach
    	//std::swap_ranges((*(children.end()-2)).begin(), (*(children.end()-2)).begin()+crossover_index+1, (*(children.end()-1)).rbegin()+crossover_index);

    }

    /**
     * Copy the chromosome to the next generation.
     * @param children The next generation.
     */
    void clonning(std::vector<Chromosome<T > > &children) {
    	// Copy value to the next population
    	children.push_back(*this);
    }

    /**
     * Overload the array operator.
     * @param n The index to retrieve the value at.
     * @return The value.
     */
    T operator[](unsigned int n) const {
    	return *this->chromosome[n];
    }

    /**
     * Overload the array operator
     * @param n The index to retrieve the value at.
     * @return The reference to the value.
     */
    T& operator[](unsigned int n) {
		return this->chromosome[n];
	}

    /**
     * Overload the == operation.
     * @param other The Chromosome to compare too.
     * @return Whether the two chromosomes are the same.
     */
    inline bool operator==(const Chromosome<T >& other){ return this->chromosome == other.chromosome; }

    /**
     * Overload the != operation, makes use of == operator overload
     * @param other The chromosome to check equality.
     * @return Whether the two chromosomes are different.
     */
    inline bool operator!=(const Chromosome<T >& other){ return !(*this == other); }

private:

    /**
     * Get a random index to allow for the retrieval a random element within the chromosome.
     * @return The random index.
     */
    unsigned int getRandomElement() {
    	return rand_chrom_elem(random_engine);
    }

	/**
	 * Get a random number between 0 and chromosome.size()-1 that is not index
	 * @param index The only value within the range that the return cannot be.
	 * @return A number within the defined range that is not index.
	 */
	unsigned int getRandomElement(unsigned int index) {
		unsigned int val = getRandomElement();

		while(val == index) {
			val = getRandomElement();
		}
		return val;
	}

};

template<class T>
std::mt19937 Chromosome<T >::random_engine;
template<class T>
std::uniform_int_distribution<int> Chromosome<T >::rand_chrom_elem;
template<class T>
std::uniform_real_distribution<> Chromosome<T >::rand_value;

#endif /* CHROMOSOME_HPP_ */
<|endoftext|>


<commit_before>/*
  This file is part of KOrganizer.

  Requires the Qt and KDE widget libraries, available at no cost at
  http://www.troll.no and http://www.kde.org respectively

  Copyright (c) 2003
  Reinhold Kainhofer <reinhold@kainhofer.com>

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/

#include <libkcal/incidence.h>
#include <libkcal/event.h>
#include <libkcal/todo.h>
#include <libkcal/journal.h>

#include <klocale.h>
#include "koincidencetooltip.h"

/**
@author Reinhold Kainhofer
some improvements by Mikolaj Machowski
*/

void KOIncidenceToolTip::add ( QWidget * widget, Incidence *incidence,
        QToolTipGroup * group, const QString & longText )
{
  if ( !widget || !incidence ) return;
  QString tipText;
  ToolTipVisitor v;
  v.act( incidence, &tipText, true );
  QToolTip::add(widget, tipText, group, longText);
}

QString ToolTipVisitor::dateRangeText( Event*event )
{
  QString ret;
  QString tmp;
  if ( event->isMultiDay() ) {

    tmp = "
" + i18n("Event start", "From: %1");
    if (event->doesFloat())
      ret += tmp.arg( event->dtStartDateStr().replace(" ", " ") );
    else
      ret += tmp.arg( event->dtStartStr().replace(" ", " ") );

    tmp = "
" + i18n("To: %1");
    if (event->doesFloat())
      ret += tmp.arg( event->dtEndDateStr().replace(" ", " ") );
    else
      ret += tmp.arg( event->dtEndStr().replace(" ", " ") );

  } else {

    ret += "
"+i18n("Date: %1").
        arg( event->dtStartDateStr().replace(" ", " ") );
    if ( !event->doesFloat() ) {
      tmp = "
" + i18n("time range for event,   to prevent ugly line breaks",
        "Time: %1 - %2").
        arg( event->dtStartTimeStr().replace(" ", " ") ).
        arg( event->dtEndTimeStr().replace(" ", " ") );
      ret += tmp;
    }

  }
  return ret;
}

QString ToolTipVisitor::dateRangeText( Todo*todo )
{
  QString ret;
  bool floats( todo->doesFloat() );
  if (todo->hasStartDate())
    // No need to add  here. This is separated issue and each line
    // is very visible on its own. On the other hand... Yes, I like it
    // italics here :)
    ret += "
" + i18n("Start: %1").arg(
      (floats)
        ?(todo->dtStartDateStr().replace(" ", " "))
        :(todo->dtStartStr().replace(" ", " ")) ) ;
  if (todo->hasDueDate())
    ret += "
" + i18n("Due: %1").arg(
      (floats)
        ?(todo->dtDueDateStr().replace(" ", " "))
        :(todo->dtDueStr().replace(" ", " ")) );
  if (todo->isCompleted())
    ret += "
" + i18n("Completed: %1").arg( todo->completedStr().replace(" ", " ") );
  else
    ret += "
" + i18n("%1 % completed").arg(todo->percentComplete());

  return ret;
}

QString ToolTipVisitor::dateRangeText( Journal* )
{
  QString ret;
  return ret;
}

bool ToolTipVisitor::visit( Event *event )
{
  QString dtRangeText( dateRangeText( event ) );
  return generateToolTip( event, dtRangeText  );
}

bool ToolTipVisitor::visit( Todo *todo )
{
  QString dtRangeText( dateRangeText( todo ) );
  return generateToolTip( todo, dtRangeText  );
}

bool ToolTipVisitor::visit( Journal *journal )
{
  QString dtRangeText( dateRangeText( journal ) );
  return generateToolTip( journal, dtRangeText  );
}

bool ToolTipVisitor::generateToolTip( Incidence* incidence, QString dtRangeText )
{
  QString tipText = "<qt>"+ incidence->summary().replace("\n", "
")+"";

  tipText += dtRangeText;

  if (!incidence->location().isEmpty()) {
    // Put Location: in italics
    tipText += "
"+i18n("Location: %1").
      arg( incidence->location().replace("\n", "
") );
  }
  if (!incidence->description().isEmpty()) {
    QString desc(incidence->description());
    if (desc.length()>120) {
      desc = desc.left(120) + "...";
    }
    tipText += "

" + desc.replace("\n", "
");
  }
  tipText += "</qt>";
  *mTipText = tipText;
  return true;
}
<commit_msg>Insert   to prevent ugly line breaks in the start/end times in the tooltips. Replaced
 by "----------" to prevent the tooltips from being ways too wide.<commit_after>/*
  This file is part of KOrganizer.

  Requires the Qt and KDE widget libraries, available at no cost at
  http://www.troll.no and http://www.kde.org respectively

  Copyright (c) 2003
  Reinhold Kainhofer <reinhold@kainhofer.com>

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/

#include <libkcal/incidence.h>
#include <libkcal/event.h>
#include <libkcal/todo.h>
#include <libkcal/journal.h>

#include <klocale.h>
#include "koincidencetooltip.h"

/**
@author Reinhold Kainhofer
some improvements by Mikolaj Machowski
*/

void KOIncidenceToolTip::add ( QWidget * widget, Incidence *incidence,
        QToolTipGroup * group, const QString & longText )
{
  if ( !widget || !incidence ) return;
  QString tipText;
  ToolTipVisitor v;
  v.act( incidence, &tipText, true );
  QToolTip::add(widget, tipText, group, longText);
}

QString ToolTipVisitor::dateRangeText( Event*event )
{
  QString ret;
  QString tmp;
  if ( event->isMultiDay() ) {

    tmp = "
" + i18n("Event start", "From: %1");
    if (event->doesFloat())
      ret += tmp.arg( event->dtStartDateStr().replace(" ", " ") );
    else
      ret += tmp.arg( event->dtStartStr().replace(" ", " ") );

    tmp = "
" + i18n("To: %1");
    if (event->doesFloat())
      ret += tmp.arg( event->dtEndDateStr().replace(" ", " ") );
    else
      ret += tmp.arg( event->dtEndStr().replace(" ", " ") );

  } else {

    ret += "
"+i18n("Date: %1").
        arg( event->dtStartDateStr().replace(" ", " ") );
    if ( !event->doesFloat() ) {
      tmp = "
" + i18n("time range for event,   to prevent ugly line breaks",
        "Time: %1 - %2").
        arg( event->dtStartTimeStr().replace(" ", " ") ).
        arg( event->dtEndTimeStr().replace(" ", " ") );
      ret += tmp;
    }

  }
  return ret;
}

QString ToolTipVisitor::dateRangeText( Todo*todo )
{
  QString ret;
  bool floats( todo->doesFloat() );
  if (todo->hasStartDate())
    // No need to add  here. This is separated issue and each line
    // is very visible on its own. On the other hand... Yes, I like it
    // italics here :)
    ret += "
" + i18n("Start: %1").arg(
      (floats)
        ?(todo->dtStartDateStr().replace(" ", " "))
        :(todo->dtStartStr().replace(" ", " ")) ) ;
  if (todo->hasDueDate())
    ret += "
" + i18n("Due: %1").arg(
      (floats)
        ?(todo->dtDueDateStr().replace(" ", " "))
        :(todo->dtDueStr().replace(" ", " ")) );
  if (todo->isCompleted())
    ret += "
" + i18n("Completed: %1").arg( todo->completedStr().replace(" ", " ") );
  else
    ret += "
" + i18n("%1 % completed").arg(todo->percentComplete());

  return ret;
}

QString ToolTipVisitor::dateRangeText( Journal* )
{
  QString ret;
  return ret;
}

bool ToolTipVisitor::visit( Event *event )
{
  QString dtRangeText( dateRangeText( event ) );
  return generateToolTip( event, dtRangeText  );
}

bool ToolTipVisitor::visit( Todo *todo )
{
  QString dtRangeText( dateRangeText( todo ) );
  return generateToolTip( todo, dtRangeText  );
}

bool ToolTipVisitor::visit( Journal *journal )
{
  QString dtRangeText( dateRangeText( journal ) );
  return generateToolTip( journal, dtRangeText  );
}

bool ToolTipVisitor::generateToolTip( Incidence* incidence, QString dtRangeText )
{
  QString tipText = "<qt>"+ incidence->summary().replace("\n", "
")+"";

  tipText += dtRangeText;

  if (!incidence->location().isEmpty()) {
    // Put Location: in italics
    tipText += "
"+i18n("Location: %1").
      arg( incidence->location().replace("\n", "
") );
  }
  if (!incidence->description().isEmpty()) {
    QString desc(incidence->description());
    if (desc.length()>120) {
      desc = desc.left(120) + "...";
    }
    tipText += "
----------
" + i18n("Description:
") + desc.replace("\n", "
");
  }
  tipText += "</qt>";
  *mTipText = tipText;
  return true;
}
<|endoftext|>