<commit_before>/**
 * \file
 * \brief SignalsCatcherControlBlock class header
 *
 * \author Copyright (C) 2015 Kamil Szczygiel http://www.distortec.com http://www.freddiechopin.info
 *
 * \par License
 * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not
 * distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * \date 2015-10-27
 */

#ifndef INCLUDE_DISTORTOS_SYNCHRONIZATION_SIGNALSCATCHERCONTROLBLOCK_HPP_
#define INCLUDE_DISTORTOS_SYNCHRONIZATION_SIGNALSCATCHERCONTROLBLOCK_HPP_

#include "distortos/SignalAction.hpp"

#include <memory>

namespace distortos
{

namespace scheduler
{

class ThreadControlBlock;

}	// namespace scheduler

namespace synchronization
{

class SignalsReceiverControlBlock;

/// SignalsCatcherControlBlock class is a structure required by threads for "catching" and "handling" of signals
class SignalsCatcherControlBlock
{
public:

	/// association of signal numbers (as SignalSet) with SignalAction
	using Association = std::pair<SignalSet, SignalAction>;

	/// type of uninitialized storage for Association objects
	using Storage = std::aligned_storage<sizeof(Association), alignof(Association)>::type;

	/// unique_ptr (with deleter) to Storage[]
	using StorageUniquePointer = std::unique_ptr<Storage[], void(&)(Storage*)>;

	/**
	 * \brief SignalsCatcherControlBlock's constructor
	 *
	 * \param [in] storage is a memory block for storage of Association objects, sufficiently large for \a storageSize
	 * elements
	 * \param [in] storageSize is the number of elements in \a storage array
	 */

	constexpr SignalsCatcherControlBlock(Storage* const storage, const size_t storageSize) :
			signalMask_{SignalSet::empty},
			associationsBegin_{reinterpret_cast<decltype(associationsBegin_)>(storage)},
			storageBegin_{storage},
			storageEnd_{storage + storageSize},
			deliveryIsPending_{}
	{

	}

	/**
	 * \brief SignalsCatcherControlBlock's destructor
	 */

	~SignalsCatcherControlBlock();

	/**
	 * \brief Hook function executed when delivery of signals is started.
	 *
	 * Clears "delivery pending" flag.
	 *
	 * \attention This function should be called only by SignalsReceiverControlBlock::deliveryOfSignalsFinishedHook().
	 */

	void deliveryOfSignalsStartedHook()
	{
		deliveryIsPending_ = false;
	}

	/**
	 * \brief Gets SignalAction associated with given signal number.
	 *
	 * \param [in] signalNumber is the signal for which the association is requested, [0; 31]
	 *
	 * \return pair with return code (0 on success, error code otherwise) and SignalAction that is associated with
	 * \a signalNumber, default-constructed object if no association was found;
	 * error codes:
	 * - EINVAL - \a signalNumber value is invalid;
	 */

	std::pair<int, SignalAction> getAssociation(uint8_t signalNumber) const;

	/**
	 * \return SignalSet with signal mask for associated thread
	 */

	SignalSet getSignalMask() const
	{
		return signalMask_;
	}

	/**
	 * \brief Part of SignalsReceiverControlBlock::postGenerate() specific to catching unmasked signals.
	 *
	 * Requests delivery of signals to associated thread if there is some non-default signal handler for the signal.
	 *
	 * \param [in] signalNumber is the unmasked signal that was generated, [0; 31]
	 * \param [in] threadControlBlock is a reference to associated ThreadControlBlock
	 *
	 * \return 0 on success, error code otherwise:
	 * - EINVAL - \a signalNumber value is invalid;
	 */

	int postGenerate(uint8_t signalNumber, scheduler::ThreadControlBlock& threadControlBlock);

	/**
	 * \brief Sets association for given signal number.
	 *
	 * \param [in] signalNumber is the signal for which the association will be set, [0; 31]
	 * \param [in] signalAction is a reference to SignalAction that will be associated with given signal number, object
	 * in internal storage is copy-constructed
	 *
	 * \return pair with return code (0 on success, error code otherwise) and SignalAction that was associated with
	 * \a signalNumber, default-constructed object if no association was found;
	 * error codes:
	 * - EAGAIN - no resources are available to associate \a signalNumber with \a signalAction;
	 * - EINVAL - \a signalNumber value is invalid;
	 */

	std::pair<int, SignalAction> setAssociation(uint8_t signalNumber, const SignalAction& signalAction);

	/**
	 * \brief Sets signal mask for associated thread.
	 *
	 * If any pending signal is unblocked and \a owner doesn't equal nullptr, then delivery of signals to associated
	 * thread will be requested.
	 *
	 * \param [in] signalMask is the SignalSet with new signal mask for associated thread
	 * \param [in] owner selects whether delivery of signals will be requested if any pending signal is unblocked
	 * (pointer to owner SignalsReceiverControlBlock object) or not (nullptr)
	 */

	void setSignalMask(SignalSet signalMask, const SignalsReceiverControlBlock* owner);

	SignalsCatcherControlBlock(const SignalsCatcherControlBlock&) = delete;
	SignalsCatcherControlBlock(SignalsCatcherControlBlock&&) = default;
	const SignalsCatcherControlBlock& operator=(const SignalsCatcherControlBlock&) = delete;
	SignalsCatcherControlBlock& operator=(SignalsCatcherControlBlock&&) = delete;

private:

	/**
	 * \brief Clears association for given signal number.
	 *
	 * \param [in] signalNumber is the signal for which the association will be cleared, [0; 31]
	 *
	 * \return SignalAction that was associated with \a signalNumber, default-constructed object if no association was
	 * found
	 */

	SignalAction clearAssociation(uint8_t signalNumber);

	/**
	 * \brief Clears given association for given signal number.
	 *
	 * \param [in] signalNumber is the signal for which the association will be cleared, [0; 31]
	 * \param [in] association is a reference to Association object from [associationsBegin_; associationsEnd_)
	 * range that will be removed
	 *
	 * \return SignalAction from \a association
	 */

	SignalAction clearAssociation(uint8_t signalNumber, Association& association);

	/**
	 * \brief Requests delivery of signals to associated thread.
	 *
	 * Delivery of signals (via special function executed in the associated thread) is requested only if it's not
	 * already pending. The thread is unblocked if it was blocked.
	 *
	 * \param [in] threadControlBlock is a reference to associated ThreadControlBlock
	 */

	void requestDeliveryOfSignals(scheduler::ThreadControlBlock& threadControlBlock);

	/// SignalSet with signal mask for associated thread
	SignalSet signalMask_;

	/// pointer to first element of range of Association objects
	Association* associationsBegin_;

	/// union binds \a associationsEnd_ and \a storageBegin_ - these point to the same address
	union
	{
		/// pointer to "one past the last" element of range of Association objects
		Association* associationsEnd_;

		/// pointer to first element of range of Storage objects
		Storage* storageBegin_;
	};

	/// pointer to "one past the last" element of range of Storage objects
	Storage* storageEnd_;

	/// true if signal delivery is pending, false otherwise
	bool deliveryIsPending_;
};

}	// namespace synchronization

}	// namespace distortos

#endif	// INCLUDE_DISTORTOS_SYNCHRONIZATION_SIGNALSCATCHERCONTROLBLOCK_HPP_
<commit_msg>SignalsCatcherControlBlock: keep storage in StorageUniquePointer<commit_after>/**
 * \file
 * \brief SignalsCatcherControlBlock class header
 *
 * \author Copyright (C) 2015 Kamil Szczygiel http://www.distortec.com http://www.freddiechopin.info
 *
 * \par License
 * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not
 * distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * \date 2015-10-27
 */

#ifndef INCLUDE_DISTORTOS_SYNCHRONIZATION_SIGNALSCATCHERCONTROLBLOCK_HPP_
#define INCLUDE_DISTORTOS_SYNCHRONIZATION_SIGNALSCATCHERCONTROLBLOCK_HPP_

#include "distortos/SignalAction.hpp"

#include "distortos/memory/dummyDeleter.hpp"

#include <memory>

namespace distortos
{

namespace scheduler
{

class ThreadControlBlock;

}	// namespace scheduler

namespace synchronization
{

class SignalsReceiverControlBlock;

/// SignalsCatcherControlBlock class is a structure required by threads for "catching" and "handling" of signals
class SignalsCatcherControlBlock
{
public:

	/// association of signal numbers (as SignalSet) with SignalAction
	using Association = std::pair<SignalSet, SignalAction>;

	/// type of uninitialized storage for Association objects
	using Storage = std::aligned_storage<sizeof(Association), alignof(Association)>::type;

	/// unique_ptr (with deleter) to Storage[]
	using StorageUniquePointer = std::unique_ptr<Storage[], void(&)(Storage*)>;

	/**
	 * \brief SignalsCatcherControlBlock's constructor
	 *
	 * \param [in] storage is a memory block for storage of Association objects, sufficiently large for \a storageSize
	 * elements
	 * \param [in] storageSize is the number of elements in \a storage array
	 */

	SignalsCatcherControlBlock(Storage* const storage, const size_t storageSize) :
			storageUniquePointer_{storage, memory::dummyDeleter},
			signalMask_{SignalSet::empty},
			associationsBegin_{reinterpret_cast<decltype(associationsBegin_)>(storage)},
			storageBegin_{storage},
			storageEnd_{storage + storageSize},
			deliveryIsPending_{}
	{

	}

	/**
	 * \brief SignalsCatcherControlBlock's destructor
	 */

	~SignalsCatcherControlBlock();

	/**
	 * \brief Hook function executed when delivery of signals is started.
	 *
	 * Clears "delivery pending" flag.
	 *
	 * \attention This function should be called only by SignalsReceiverControlBlock::deliveryOfSignalsFinishedHook().
	 */

	void deliveryOfSignalsStartedHook()
	{
		deliveryIsPending_ = false;
	}

	/**
	 * \brief Gets SignalAction associated with given signal number.
	 *
	 * \param [in] signalNumber is the signal for which the association is requested, [0; 31]
	 *
	 * \return pair with return code (0 on success, error code otherwise) and SignalAction that is associated with
	 * \a signalNumber, default-constructed object if no association was found;
	 * error codes:
	 * - EINVAL - \a signalNumber value is invalid;
	 */

	std::pair<int, SignalAction> getAssociation(uint8_t signalNumber) const;

	/**
	 * \return SignalSet with signal mask for associated thread
	 */

	SignalSet getSignalMask() const
	{
		return signalMask_;
	}

	/**
	 * \brief Part of SignalsReceiverControlBlock::postGenerate() specific to catching unmasked signals.
	 *
	 * Requests delivery of signals to associated thread if there is some non-default signal handler for the signal.
	 *
	 * \param [in] signalNumber is the unmasked signal that was generated, [0; 31]
	 * \param [in] threadControlBlock is a reference to associated ThreadControlBlock
	 *
	 * \return 0 on success, error code otherwise:
	 * - EINVAL - \a signalNumber value is invalid;
	 */

	int postGenerate(uint8_t signalNumber, scheduler::ThreadControlBlock& threadControlBlock);

	/**
	 * \brief Sets association for given signal number.
	 *
	 * \param [in] signalNumber is the signal for which the association will be set, [0; 31]
	 * \param [in] signalAction is a reference to SignalAction that will be associated with given signal number, object
	 * in internal storage is copy-constructed
	 *
	 * \return pair with return code (0 on success, error code otherwise) and SignalAction that was associated with
	 * \a signalNumber, default-constructed object if no association was found;
	 * error codes:
	 * - EAGAIN - no resources are available to associate \a signalNumber with \a signalAction;
	 * - EINVAL - \a signalNumber value is invalid;
	 */

	std::pair<int, SignalAction> setAssociation(uint8_t signalNumber, const SignalAction& signalAction);

	/**
	 * \brief Sets signal mask for associated thread.
	 *
	 * If any pending signal is unblocked and \a owner doesn't equal nullptr, then delivery of signals to associated
	 * thread will be requested.
	 *
	 * \param [in] signalMask is the SignalSet with new signal mask for associated thread
	 * \param [in] owner selects whether delivery of signals will be requested if any pending signal is unblocked
	 * (pointer to owner SignalsReceiverControlBlock object) or not (nullptr)
	 */

	void setSignalMask(SignalSet signalMask, const SignalsReceiverControlBlock* owner);

	SignalsCatcherControlBlock(const SignalsCatcherControlBlock&) = delete;
	SignalsCatcherControlBlock(SignalsCatcherControlBlock&&) = default;
	const SignalsCatcherControlBlock& operator=(const SignalsCatcherControlBlock&) = delete;
	SignalsCatcherControlBlock& operator=(SignalsCatcherControlBlock&&) = delete;

private:

	/**
	 * \brief Clears association for given signal number.
	 *
	 * \param [in] signalNumber is the signal for which the association will be cleared, [0; 31]
	 *
	 * \return SignalAction that was associated with \a signalNumber, default-constructed object if no association was
	 * found
	 */

	SignalAction clearAssociation(uint8_t signalNumber);

	/**
	 * \brief Clears given association for given signal number.
	 *
	 * \param [in] signalNumber is the signal for which the association will be cleared, [0; 31]
	 * \param [in] association is a reference to Association object from [associationsBegin_; associationsEnd_)
	 * range that will be removed
	 *
	 * \return SignalAction from \a association
	 */

	SignalAction clearAssociation(uint8_t signalNumber, Association& association);

	/**
	 * \brief Requests delivery of signals to associated thread.
	 *
	 * Delivery of signals (via special function executed in the associated thread) is requested only if it's not
	 * already pending. The thread is unblocked if it was blocked.
	 *
	 * \param [in] threadControlBlock is a reference to associated ThreadControlBlock
	 */

	void requestDeliveryOfSignals(scheduler::ThreadControlBlock& threadControlBlock);

	/// storage for Association objects
	StorageUniquePointer storageUniquePointer_;

	/// SignalSet with signal mask for associated thread
	SignalSet signalMask_;

	/// pointer to first element of range of Association objects
	Association* associationsBegin_;

	/// union binds \a associationsEnd_ and \a storageBegin_ - these point to the same address
	union
	{
		/// pointer to "one past the last" element of range of Association objects
		Association* associationsEnd_;

		/// pointer to first element of range of Storage objects
		Storage* storageBegin_;
	};

	/// pointer to "one past the last" element of range of Storage objects
	Storage* storageEnd_;

	/// true if signal delivery is pending, false otherwise
	bool deliveryIsPending_;
};

}	// namespace synchronization

}	// namespace distortos

#endif	// INCLUDE_DISTORTOS_SYNCHRONIZATION_SIGNALSCATCHERCONTROLBLOCK_HPP_
<|endoftext|>


<commit_before>// Copyright (c) 2015, Cloudera, inc.
// Confidential Cloudera Information: Covered by NDA.

#include "kudu/util/monotime.h"
#include "kudu/util/random.h"
#include "kudu/util/striped64.h"
#include "kudu/util/threadlocal.h"

using kudu::striped64::internal::HashCode;
using kudu::striped64::internal::Cell;

namespace kudu {

namespace striped64 {
namespace internal {
//
// HashCode
//

HashCode::HashCode() {
  Random r(MonoTime::Now(MonoTime::FINE).GetDeltaSince(MonoTime::Min()).ToNanoseconds());
  const uint64_t hash = r.Next64();
  code_ = (hash == 0) ? 1 : hash;  // Avoid zero to allow xorShift rehash
}

//
// Cell
//

Cell::Cell()
    : value_(0) {
}
} // namespace internal
} // namespace striped64

//
// Striped64
//
const uint32_t Striped64::kNumCpus = sysconf(_SC_NPROCESSORS_ONLN);
DEFINE_STATIC_THREAD_LOCAL(HashCode, Striped64, hashcode_);

Striped64::Striped64()
    : busy_(false),
      cell_buffer_(NULL),
      cells_(NULL),
      num_cells_(0) {
}

Striped64::~Striped64() {
  // Cell is a POD, so no need to destruct each one.
  free(cell_buffer_);
}

void Striped64::RetryUpdate(int64_t x, Rehash contention) {
  uint64_t h = hashcode_->code_;
  // There are three operations in this loop.
  //
  // 1. Try to add to the Cell hash table entry for the thread if the table exists.
  //    When there's contention, rehash to try a different Cell.
  // 2. Try to initialize the hash table.
  // 3. Try to update the base counter.
  //
  // These are predicated on successful CAS operations, which is why it's all wrapped in an
  // infinite retry loop.
  while (true) {
    if (num_cells_ > 0) {
      if (contention == kRehash) {
        // CAS failed already, rehash before trying to increment.
        contention = kNoRehash;
      } else {
        Cell *cell = &(cells_[(num_cells_ - 1) & h]);
        int64_t v = cell->value_.Load();
        if (cell->CompareAndSwap(v, Fn(v, x))) {
          // Successfully CAS'd the corresponding cell, done.
          break;
        }
      }
      // Rehash since we failed to CAS, either previously or just now.
      h ^= h << 13;
      h ^= h >> 17;
      h ^= h << 5;
    } else if (num_cells_ == 0 && CasBusy()) {
      // We think table hasn't been initialized yet, try to do so.
      // Recheck preconditions, someone else might have init'd in the meantime.
      if (num_cells_ == 0) {
        size_t n = 1;
        // Calculate the size. Nearest power of two >= NCPU.
        // Also handle a negative NCPU, can happen if sysconf name is unknown
        while (kNumCpus > n) {
          n <<= 1;
        }
        // Allocate cache-aligned memory for use by the cells_ table.
        int err = posix_memalign(&cell_buffer_, CACHELINE_SIZE, sizeof(Cell)*n);
        CHECK_EQ(0, err) << "error calling posix_memalign" << std::endl;
        // Initialize the table
        cells_ = new (cell_buffer_) Cell[n];
        base::subtle::Release_Store(&num_cells_, n);
      }
      // End critical section
      busy_.Store(0);
    } else {
      // Fallback to adding to the base value.
      // Means the table wasn't initialized or we failed to init it.
      int64_t v = base_.value_.Load();
      if (CasBase(v, Fn(v, x))) {
        break;
      }
    }
  }
  // Record index for next time
  hashcode_->code_ = h;
}

void Striped64::InternalReset(int64_t initialValue) {
  base_.value_.Store(initialValue);
  for (int i = 0; i < num_cells_; i++) {
    cells_[i].value_.Store(initialValue);
  }
}

void LongAdder::IncrementBy(int64_t x) {
  INIT_STATIC_THREAD_LOCAL(HashCode, hashcode_);
  // Use hash table if present. If that fails, call RetryUpdate to rehash and retry.
  // If no hash table, try to CAS the base counter. If that fails, RetryUpdate to init the table.
  const int32_t n = base::subtle::Acquire_Load(&num_cells_);
  if (n > 0) {
    Cell *cell = &(cells_[(n - 1) & hashcode_->code_]);
    DCHECK_EQ(0, reinterpret_cast<const uintptr_t>(cell) & (sizeof(Cell) - 1))
        << " unaligned Cell not allowed for Striped64" << std::endl;
    const int64_t old = cell->value_.Load();
    if (!cell->CompareAndSwap(old, old + x)) {
      // When we hit a hash table contention, signal RetryUpdate to rehash.
      RetryUpdate(x, kRehash);
    }
  } else {
    int64_t b = base_.value_.Load();
    if (!base_.CompareAndSwap(b, b + x)) {
      // Attempt to initialize the table. No need to rehash since the contention was for the
      // base counter, not the hash table.
      RetryUpdate(x, kNoRehash);
    }
  }
}

//
// LongAdder
//

int64_t LongAdder::Value() const {
  int64_t sum = base_.value_.Load();
  const int32_t n = base::subtle::Acquire_Load(&num_cells_);
  for (int i = 0; i < n; i++) {
    sum += cells_[i].value_.Load();
  }
  return sum;
}

} // namespace kudu
<commit_msg>KUDU-594. Always use AcquireLoad to access Striped64::num_cells_ to placate TSAN.<commit_after>// Copyright (c) 2015, Cloudera, inc.
// Confidential Cloudera Information: Covered by NDA.

#include "kudu/util/monotime.h"
#include "kudu/util/random.h"
#include "kudu/util/striped64.h"
#include "kudu/util/threadlocal.h"

using kudu::striped64::internal::HashCode;
using kudu::striped64::internal::Cell;

namespace kudu {

namespace striped64 {
namespace internal {
//
// HashCode
//

HashCode::HashCode() {
  Random r(MonoTime::Now(MonoTime::FINE).GetDeltaSince(MonoTime::Min()).ToNanoseconds());
  const uint64_t hash = r.Next64();
  code_ = (hash == 0) ? 1 : hash;  // Avoid zero to allow xorShift rehash
}

//
// Cell
//

Cell::Cell()
    : value_(0) {
}
} // namespace internal
} // namespace striped64

//
// Striped64
//
const uint32_t Striped64::kNumCpus = sysconf(_SC_NPROCESSORS_ONLN);
DEFINE_STATIC_THREAD_LOCAL(HashCode, Striped64, hashcode_);

Striped64::Striped64()
    : busy_(false),
      cell_buffer_(NULL),
      cells_(NULL),
      num_cells_(0) {
}

Striped64::~Striped64() {
  // Cell is a POD, so no need to destruct each one.
  free(cell_buffer_);
}

void Striped64::RetryUpdate(int64_t x, Rehash contention) {
  uint64_t h = hashcode_->code_;
  // There are three operations in this loop.
  //
  // 1. Try to add to the Cell hash table entry for the thread if the table exists.
  //    When there's contention, rehash to try a different Cell.
  // 2. Try to initialize the hash table.
  // 3. Try to update the base counter.
  //
  // These are predicated on successful CAS operations, which is why it's all wrapped in an
  // infinite retry loop.
  while (true) {
    int32_t n = base::subtle::Acquire_Load(&num_cells_);
    if (n > 0) {
      if (contention == kRehash) {
        // CAS failed already, rehash before trying to increment.
        contention = kNoRehash;
      } else {
        Cell *cell = &(cells_[(n - 1) & h]);
        int64_t v = cell->value_.Load();
        if (cell->CompareAndSwap(v, Fn(v, x))) {
          // Successfully CAS'd the corresponding cell, done.
          break;
        }
      }
      // Rehash since we failed to CAS, either previously or just now.
      h ^= h << 13;
      h ^= h >> 17;
      h ^= h << 5;
    } else if (n == 0 && CasBusy()) {
      // We think table hasn't been initialized yet, try to do so.
      // Recheck preconditions, someone else might have init'd in the meantime.
      n = base::subtle::Acquire_Load(&num_cells_);
      if (n == 0) {
        n = 1;
        // Calculate the size. Nearest power of two >= NCPU.
        // Also handle a negative NCPU, can happen if sysconf name is unknown
        while (kNumCpus > n) {
          n <<= 1;
        }
        // Allocate cache-aligned memory for use by the cells_ table.
        int err = posix_memalign(&cell_buffer_, CACHELINE_SIZE, sizeof(Cell)*n);
        CHECK_EQ(0, err) << "error calling posix_memalign" << std::endl;
        // Initialize the table
        cells_ = new (cell_buffer_) Cell[n];
        base::subtle::Release_Store(&num_cells_, n);
      }
      // End critical section
      busy_.Store(0);
    } else {
      // Fallback to adding to the base value.
      // Means the table wasn't initialized or we failed to init it.
      int64_t v = base_.value_.Load();
      if (CasBase(v, Fn(v, x))) {
        break;
      }
    }
  }
  // Record index for next time
  hashcode_->code_ = h;
}

void Striped64::InternalReset(int64_t initialValue) {
  const int32_t n = base::subtle::Acquire_Load(&num_cells_);
  base_.value_.Store(initialValue);
  for (int i = 0; i < n; i++) {
    cells_[i].value_.Store(initialValue);
  }
}

void LongAdder::IncrementBy(int64_t x) {
  INIT_STATIC_THREAD_LOCAL(HashCode, hashcode_);
  // Use hash table if present. If that fails, call RetryUpdate to rehash and retry.
  // If no hash table, try to CAS the base counter. If that fails, RetryUpdate to init the table.
  const int32_t n = base::subtle::Acquire_Load(&num_cells_);
  if (n > 0) {
    Cell *cell = &(cells_[(n - 1) & hashcode_->code_]);
    DCHECK_EQ(0, reinterpret_cast<const uintptr_t>(cell) & (sizeof(Cell) - 1))
        << " unaligned Cell not allowed for Striped64" << std::endl;
    const int64_t old = cell->value_.Load();
    if (!cell->CompareAndSwap(old, old + x)) {
      // When we hit a hash table contention, signal RetryUpdate to rehash.
      RetryUpdate(x, kRehash);
    }
  } else {
    int64_t b = base_.value_.Load();
    if (!base_.CompareAndSwap(b, b + x)) {
      // Attempt to initialize the table. No need to rehash since the contention was for the
      // base counter, not the hash table.
      RetryUpdate(x, kNoRehash);
    }
  }
}

//
// LongAdder
//

int64_t LongAdder::Value() const {
  int64_t sum = base_.value_.Load();
  const int32_t n = base::subtle::Acquire_Load(&num_cells_);
  for (int i = 0; i < n; i++) {
    sum += cells_[i].value_.Load();
  }
  return sum;
}

} // namespace kudu
<|endoftext|>


<commit_before>/* Copyright (c) 2016 PaddlePaddle Authors. All Rights Reserve.

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 "paddle/framework/executor.h"
#include <iostream>
#include <memory>
#include <vector>
#include "paddle/framework/lod_tensor.h"
#include "paddle/framework/op_registry.h"
#include "paddle/framework/scope.h"

namespace paddle {
namespace framework {

Executor::Executor(const std::vector<platform::Place>& places) {
  device_contexts_.resize(places.size());
  for (size_t i = 0; i < places.size(); i++) {
    if (platform::is_cpu_place(places[i])) {
      device_contexts_[i] = new platform::CPUDeviceContext(
          boost::get<platform::CPUPlace>(places[i]));
    } else if (platform::is_gpu_place(places[i])) {
#ifdef PADDLE_WITH_CUDA
      device_contexts_[i] = new platform::CUDADeviceContext(
          boost::get<platform::GPUPlace>(places[i]));
#else
      PADDLE_THROW("'GPUPlace' is not supported in CPU only device.");
#endif
    }
  }
}

Executor::~Executor() {
  for (auto& device_context : device_contexts_) {
    if (device_context) {
      delete device_context;
    }
  }
}

void Executor::Run(const ProgramDesc& pdesc, Scope* scope) {
  // TODO(tonyyang-svail):
  //    - only runs the first block
  //    - only runs on the first device
  //    - test on gpu
  auto& block = pdesc.blocks(0);
  auto& device = device_contexts_[0];

  Scope& local_scope = scope->NewScope();

  for (auto& var : block.vars()) {
    scope->NewVar(var.name());
  }

  for (auto& op_desc : block.ops()) {
    auto op = paddle::framework::OpRegistry::CreateOp(op_desc);
    std::cout << op->DebugString() << std::endl;
    op->Run(local_scope, *device);
  }

  // TODO(tonyyang-svail): need to test gpu device
  for (auto& device_context : device_contexts_) {
    device_context->Wait();
  }
}

}  // namespace framework
}  // namespace paddle
<commit_msg>revert local scope to TODO<commit_after>/* Copyright (c) 2016 PaddlePaddle Authors. All Rights Reserve.

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 "paddle/framework/executor.h"
#include <iostream>
#include <memory>
#include <vector>
#include "paddle/framework/lod_tensor.h"
#include "paddle/framework/op_registry.h"
#include "paddle/framework/scope.h"

namespace paddle {
namespace framework {

Executor::Executor(const std::vector<platform::Place>& places) {
  device_contexts_.resize(places.size());
  for (size_t i = 0; i < places.size(); i++) {
    if (platform::is_cpu_place(places[i])) {
      device_contexts_[i] = new platform::CPUDeviceContext(
          boost::get<platform::CPUPlace>(places[i]));
    } else if (platform::is_gpu_place(places[i])) {
#ifdef PADDLE_WITH_CUDA
      device_contexts_[i] = new platform::CUDADeviceContext(
          boost::get<platform::GPUPlace>(places[i]));
#else
      PADDLE_THROW("'GPUPlace' is not supported in CPU only device.");
#endif
    }
  }
}

Executor::~Executor() {
  for (auto& device_context : device_contexts_) {
    if (device_context) {
      delete device_context;
    }
  }
}

void Executor::Run(const ProgramDesc& pdesc, Scope* scope) {
  // TODO(tonyyang-svail):
  //    - only runs the first block
  //    - only runs on the first device
  //    - test on gpu
  auto& block = pdesc.blocks(0);
  auto& device = device_contexts_[0];

  // TODO(tonyyang-svail):
  //    - runs on a new local scope
  // Scope& local_scope = scope->NewScope();

  for (auto& var : block.vars()) {
    scope->NewVar(var.name());
  }

  for (auto& op_desc : block.ops()) {
    auto op = paddle::framework::OpRegistry::CreateOp(op_desc);
    std::cout << op->DebugString() << std::endl;
    op->Run(*scope, *device);
  }

  // TODO(tonyyang-svail): need to test gpu device
  for (auto& device_context : device_contexts_) {
    device_context->Wait();
  }
}

}  // namespace framework
}  // namespace paddle
<|endoftext|>


<commit_before>
#include <common.h>
#include <math.h>
#include <iostream>
#include <string>

using namespace std;

device_info_t getDeviceInfo(cl::Device &d)
{
    device_info_t devInfo;

    devInfo.numCUs = d.getInfo<CL_DEVICE_MAX_COMPUTE_UNITS>();
    devInfo.maxWGSize = d.getInfo<CL_DEVICE_MAX_WORK_GROUP_SIZE>();
    // Limiting max work-group size to 256
    #define MAX_WG_SIZE 256
    devInfo.maxWGSize = MIN(devInfo.maxWGSize, MAX_WG_SIZE);

    devInfo.maxAllocSize = d.getInfo<CL_DEVICE_MAX_MEM_ALLOC_SIZE>();
    devInfo.maxGlobalSize = d.getInfo<CL_DEVICE_GLOBAL_MEM_SIZE>();
    devInfo.doubleSupported = false;

    std::string extns = d.getInfo<CL_DEVICE_EXTENSIONS>();
    if((extns.find("cl_khr_fp64") != std::string::npos) || (extns.find("cl_amd_fp64") != std::string::npos))
        devInfo.doubleSupported = true;

    devInfo.deviceType = d.getInfo<CL_DEVICE_TYPE>();

    if(devInfo.deviceType == CL_DEVICE_TYPE_CPU) {
        devInfo.gloalBWIters = 20;
        devInfo.computeWgsPerCU = 512;
        devInfo.computeIters = 10;
    } else {            // GPU
        devInfo.gloalBWIters = 50;
        devInfo.computeWgsPerCU = 2048;
        devInfo.computeIters = 30;
    }
    devInfo.transferBWIters = 20;
    devInfo.kernelLatencyIters = 20000;

    return devInfo;
}

float timeInUS(cl::Event &timeEvent)
{
    cl_ulong start = timeEvent.getProfilingInfo<CL_PROFILING_COMMAND_START>() / 1000;
    cl_ulong end = timeEvent.getProfilingInfo<CL_PROFILING_COMMAND_END>() / 1000;

    return ((float)end - (float)start);
}

void Timer::start()
{
    tick = chrono::high_resolution_clock::now();
}

float Timer::stopAndTime()
{
    tock = chrono::high_resolution_clock::now();
    return (float)(chrono::duration_cast<chrono::microseconds>(tock - tick).count());
}

void populate(float *ptr, uint N)
{
    srand(time(NULL));

    for(int i=0; i<(int)N; i++)
    {
        //ptr[i] = (float)rand();
        ptr[i] = (float)i;
    }
}

void populate(double *ptr, uint N)
{
    srand(time(NULL));

    for(int i=0; i<(int)N; i++)
    {
        //ptr[i] = (double)rand();
        ptr[i] = (double)i;
    }
}

#define MAX_POWER   25
uint roundToPowOf2(uint number)
{
    double logd = log(number) / log(2);
    logd = floor(logd);
    logd = MIN(logd, MAX_POWER);

    return pow(2, (int)logd);
}

<commit_msg>Fix event timer precision issue<commit_after>#include <common.h>
#include <math.h>
#include <iostream>
#include <string>

using namespace std;

device_info_t getDeviceInfo(cl::Device &d)
{
    device_info_t devInfo;

    devInfo.numCUs = d.getInfo<CL_DEVICE_MAX_COMPUTE_UNITS>();
    devInfo.maxWGSize = d.getInfo<CL_DEVICE_MAX_WORK_GROUP_SIZE>();
    // Limiting max work-group size to 256
    #define MAX_WG_SIZE 256
    devInfo.maxWGSize = MIN(devInfo.maxWGSize, MAX_WG_SIZE);

    devInfo.maxAllocSize = (unsigned int)d.getInfo<CL_DEVICE_MAX_MEM_ALLOC_SIZE>();
    devInfo.maxGlobalSize = (unsigned int)d.getInfo<CL_DEVICE_GLOBAL_MEM_SIZE>();
    devInfo.doubleSupported = false;

    std::string extns = d.getInfo<CL_DEVICE_EXTENSIONS>();
    if((extns.find("cl_khr_fp64") != std::string::npos) || (extns.find("cl_amd_fp64") != std::string::npos))
        devInfo.doubleSupported = true;

    devInfo.deviceType = d.getInfo<CL_DEVICE_TYPE>();

    if(devInfo.deviceType == CL_DEVICE_TYPE_CPU) {
        devInfo.gloalBWIters = 20;
        devInfo.computeWgsPerCU = 512;
        devInfo.computeIters = 10;
    } else {            // GPU
        devInfo.gloalBWIters = 50;
        devInfo.computeWgsPerCU = 2048;
        devInfo.computeIters = 30;
    }
    devInfo.transferBWIters = 20;
    devInfo.kernelLatencyIters = 20000;

    return devInfo;
}

float timeInUS(cl::Event &timeEvent)
{
    cl_ulong start = timeEvent.getProfilingInfo<CL_PROFILING_COMMAND_START>() / 1000;
    cl_ulong end = timeEvent.getProfilingInfo<CL_PROFILING_COMMAND_END>() / 1000;

    return (float)(end - start);
}

void Timer::start()
{
    tick = chrono::high_resolution_clock::now();
}

float Timer::stopAndTime()
{
    tock = chrono::high_resolution_clock::now();
    return (float)(chrono::duration_cast<chrono::microseconds>(tock - tick).count());
}

void populate(float *ptr, uint N)
{
    srand((unsigned int)time(NULL));

    for(int i=0; i<(int)N; i++)
    {
        //ptr[i] = (float)rand();
        ptr[i] = (float)i;
    }
}

void populate(double *ptr, uint N)
{
    srand((unsigned int)time(NULL));

    for(int i=0; i<(int)N; i++)
    {
        //ptr[i] = (double)rand();
        ptr[i] = (double)i;
    }
}

#define MAX_POWER   25
uint roundToPowOf2(uint number)
{
    double logd = log(number) / log(2);
    logd = floor(logd);
    logd = MIN(logd, MAX_POWER);

    return (uint)pow(2, (int)logd);
}

<|endoftext|>


<commit_before>#include "StdAfx.h"
#include "settings.h"
#include "res_settings.h"

// Pages
#include "settings_page.h"
#include "dlg_view.h"
#include "dlg_interface.h"
#include "dlg_color.h"
#include "dlg_language.h"
#include "dlg_controls.h"
#include "dlg_advanced.h"
#include "dlg_cache.h"
#include "dlg_about.h"
#include "dlg_keyboard.h"

#include "ctrl_button.h"

namespace App {
	using namespace Intl;
	using Geom::PointInt;

	void Settings::PerformOnCreate() {
		Caption(SIDSettings);
		ControlText(IDOK, SIDDialogOK);
		ControlText(IDCANCEL, SIDDialogCancel);
		ControlText(IDC_APPLY, SIDDialogApply);

		CreateButton(IDOK)->OnClick.connect([this]() { OnOk(); });
		CreateButton(IDC_APPLY)->OnClick.connect([this]() { OnApply(); });
		CreateButton(IDCANCEL)->OnClick.connect([this]() { OnCancel(); });
	}

	bool Settings::PerformOnInitDialog() {
		RECT rect;
		GetWindowRect(GetDlgItem(Handle(), IDC_TREE_NAV), &rect);
		POINT pt = {rect.right, rect.top};

		ScreenToClient(Handle(), &pt);

		auto m_pagePos = PointInt(pt.x, pt.y);

		// Create treeview
		HTREEITEM hPrev  = 0;
		HTREEITEM hRoot  = 0;
		HTREEITEM hFirst = 0;

		for (auto i = 0; i < m_pages.size(); ++i) {
			m_pages[i]->DoModeless(this);
			m_pages[i]->Move(m_pagePos);
			m_pages[i]->UpdateFromSettings(m_settings);
			if (m_pages[i]->IsRootPage()) {
				if (hRoot != 0)
					hPrev = hRoot;

				hPrev = AddSettingsPageRoot(m_pages[i]->Caption(), static_cast<int>(i), hPrev);
				hRoot = 0;
			}
			else {
				if (hRoot == 0) {
					hRoot = hPrev;
					hPrev = 0;
				}

				hPrev = AddSettingsPageChild(m_pages[i]->Caption(), static_cast<int>(i), hRoot, hPrev);
			}

			if (hFirst == 0)
				hFirst = hPrev;
		}

		// Pick first page by default
		TreeView_SelectItem(GetDlgItem(Handle(), IDC_TREE_NAV), hFirst);

		SetWindowTheme(GetDlgItem(Handle(), IDC_TREE_NAV), L"Explorer", 0);

		return true;
	}

	bool Settings::PerformOnNotify(DWORD id, LPNMHDR pnmh) {
		switch(id) {
			case IDC_TREE_NAV:
				{
					LPNMTREEVIEW pnmtv = (LPNMTREEVIEW)pnmh;
					switch(pnmh->code) {
						// Windows tends to send the wrong message, so look for either version
						case TVN_SELCHANGEDW:
						case TVN_SELCHANGEDA:
							m_pages[pnmtv->itemOld.lParam]->Show(false);
							m_pages[pnmtv->itemNew.lParam]->Show(true);
							break;
					}
					break;
				}
			default:
				return false;
		}
		return true;
	}

	void Settings::SetSettings(Reg::Settings settings) {
		m_settings = settings;
		for (auto page : m_pages) {
			page->UpdateFromSettings(m_settings);
		}
	}

	void Settings::FreeResources() {
		TreeView_DeleteAllItems(GetDlgItem(Handle(), IDC_TREE_NAV));
	}

	Settings::Settings():
		Win::Dialog(IDD_SETTINGS)
	{
		m_pages.push_back(std::make_shared<SetView>());
		m_pages.push_back(std::make_shared<SetInterface>());
		m_pages.push_back(std::make_shared<SetColor>());
		m_pages.push_back(std::make_shared<SetLanguage>());
		m_pages.push_back(std::make_shared<SetControls>());
		m_pages.push_back(std::make_shared<SetKeyboard>());
		m_pages.push_back(std::make_shared<SetAdvanced>());
		m_pages.push_back(std::make_shared<SetPageCache>());
		m_pages.push_back(std::make_shared<SetAbout>());
	}

	HTREEITEM Settings::AddSettingsPageRoot(const std::wstring& name, int index, HTREEITEM hPrev) {
		return AddSettingsPageChild(name, index, TVI_ROOT, hPrev);
	}

	HTREEITEM Settings::AddSettingsPageChild(const std::wstring& name, int index, HTREEITEM hRoot, HTREEITEM hPrev) {
		TVINSERTSTRUCT	tvins;

		SetTextTVITEM(&tvins.item, name);
		tvins.item.mask = TVIF_TEXT | TVIF_PARAM;
		tvins.item.lParam = index;
		tvins.hInsertAfter = hPrev;
		tvins.hParent	= hRoot;

		HWND hView = GetDlgItem(Handle(), IDC_TREE_NAV);
		HTREEITEM hItem = reinterpret_cast<HTREEITEM>(SendMessage(hView, TVM_INSERTITEM, 0, (LPARAM)&tvins));
		TreeView_SetItemState(hView, hItem, TVIS_EXPANDED, TVIS_EXPANDED);
		return hItem;
	}

	bool Settings::UpdateTreeList() {
		HWND hView = GetDlgItem(Handle(), IDC_TREE_NAV);
		HTREEITEM hRoot = TreeView_GetRoot(hView);
		updateTreeItem(hRoot);
		return true;
	}

	void Settings::updateTreeItem(HTREEITEM hItem) {
		auto hView = GetDlgItem(Handle(), IDC_TREE_NAV);

		if (hItem) {
			TVITEM tvi;
			tvi.hItem = hItem;
			tvi.mask = TVIF_PARAM | TVIF_HANDLE;
			TreeView_GetItem(hView, &tvi);

			tvi.mask = TVIF_TEXT | TVIF_HANDLE;
			// Make a scoped copy of the string, or TreeView_SetItem will end up playing with a deleted string.
			std::wstring name = m_pages[tvi.lParam]->Caption();
			SetTextTVITEM(&tvi, name);
			TreeView_SetItem(hView, &tvi);

			updateTreeItem(TreeView_GetChild(hView, hItem));
			updateTreeItem(TreeView_GetNextSibling(hView, hItem));
		}
	}

	void Settings::SetTextTVITEM(TVITEM* tvi, const std::wstring &name) {
		tvi->pszText = const_cast<LPWSTR>(name.c_str());
		tvi->cchTextMax	= static_cast<int>(name.length());
	}

	void Settings::OnOk() {
		OnApply();
		FreeResources();
		DestroyWindow(Handle());
	}

	void Settings::OnApply() {
		// Store all pages data and update strings
		for (size_t i = 0; i < m_pages.size(); ++i) {
			m_pages[i]->WriteSettings(m_settings);
		}

		UpdateTreeList();
		OnSettingsChanged(m_settings);
	}

	void Settings::OnCancel() {
		OnSettingsChanged(m_settings);
		FreeResources();
		DestroyWindow(Handle());
	}
}<commit_msg>Do not save settings when pressing cancel in settings dialog<commit_after>#include "StdAfx.h"
#include "settings.h"
#include "res_settings.h"

// Pages
#include "settings_page.h"
#include "dlg_view.h"
#include "dlg_interface.h"
#include "dlg_color.h"
#include "dlg_language.h"
#include "dlg_controls.h"
#include "dlg_advanced.h"
#include "dlg_cache.h"
#include "dlg_about.h"
#include "dlg_keyboard.h"

#include "ctrl_button.h"

namespace App {
	using namespace Intl;
	using Geom::PointInt;

	void Settings::PerformOnCreate() {
		Caption(SIDSettings);
		ControlText(IDOK, SIDDialogOK);
		ControlText(IDCANCEL, SIDDialogCancel);
		ControlText(IDC_APPLY, SIDDialogApply);

		CreateButton(IDOK)->OnClick.connect([this]() { OnOk(); });
		CreateButton(IDC_APPLY)->OnClick.connect([this]() { OnApply(); });
		CreateButton(IDCANCEL)->OnClick.connect([this]() { OnCancel(); });
	}

	bool Settings::PerformOnInitDialog() {
		RECT rect;
		GetWindowRect(GetDlgItem(Handle(), IDC_TREE_NAV), &rect);
		POINT pt = {rect.right, rect.top};

		ScreenToClient(Handle(), &pt);

		auto m_pagePos = PointInt(pt.x, pt.y);

		// Create treeview
		HTREEITEM hPrev  = 0;
		HTREEITEM hRoot  = 0;
		HTREEITEM hFirst = 0;

		for (auto i = 0; i < m_pages.size(); ++i) {
			m_pages[i]->DoModeless(this);
			m_pages[i]->Move(m_pagePos);
			m_pages[i]->UpdateFromSettings(m_settings);
			if (m_pages[i]->IsRootPage()) {
				if (hRoot != 0)
					hPrev = hRoot;

				hPrev = AddSettingsPageRoot(m_pages[i]->Caption(), static_cast<int>(i), hPrev);
				hRoot = 0;
			}
			else {
				if (hRoot == 0) {
					hRoot = hPrev;
					hPrev = 0;
				}

				hPrev = AddSettingsPageChild(m_pages[i]->Caption(), static_cast<int>(i), hRoot, hPrev);
			}

			if (hFirst == 0)
				hFirst = hPrev;
		}

		// Pick first page by default
		TreeView_SelectItem(GetDlgItem(Handle(), IDC_TREE_NAV), hFirst);

		SetWindowTheme(GetDlgItem(Handle(), IDC_TREE_NAV), L"Explorer", 0);

		return true;
	}

	bool Settings::PerformOnNotify(DWORD id, LPNMHDR pnmh) {
		switch(id) {
			case IDC_TREE_NAV:
				{
					LPNMTREEVIEW pnmtv = (LPNMTREEVIEW)pnmh;
					switch(pnmh->code) {
						// Windows tends to send the wrong message, so look for either version
						case TVN_SELCHANGEDW:
						case TVN_SELCHANGEDA:
							m_pages[pnmtv->itemOld.lParam]->Show(false);
							m_pages[pnmtv->itemNew.lParam]->Show(true);
							break;
					}
					break;
				}
			default:
				return false;
		}
		return true;
	}

	void Settings::SetSettings(Reg::Settings settings) {
		m_settings = settings;
		for (auto page : m_pages) {
			page->UpdateFromSettings(m_settings);
		}
	}

	void Settings::FreeResources() {
		TreeView_DeleteAllItems(GetDlgItem(Handle(), IDC_TREE_NAV));
	}

	Settings::Settings():
		Win::Dialog(IDD_SETTINGS)
	{
		m_pages.push_back(std::make_shared<SetView>());
		m_pages.push_back(std::make_shared<SetInterface>());
		m_pages.push_back(std::make_shared<SetColor>());
		m_pages.push_back(std::make_shared<SetLanguage>());
		m_pages.push_back(std::make_shared<SetControls>());
		m_pages.push_back(std::make_shared<SetKeyboard>());
		m_pages.push_back(std::make_shared<SetAdvanced>());
		m_pages.push_back(std::make_shared<SetPageCache>());
		m_pages.push_back(std::make_shared<SetAbout>());
	}

	HTREEITEM Settings::AddSettingsPageRoot(const std::wstring& name, int index, HTREEITEM hPrev) {
		return AddSettingsPageChild(name, index, TVI_ROOT, hPrev);
	}

	HTREEITEM Settings::AddSettingsPageChild(const std::wstring& name, int index, HTREEITEM hRoot, HTREEITEM hPrev) {
		TVINSERTSTRUCT	tvins;

		SetTextTVITEM(&tvins.item, name);
		tvins.item.mask = TVIF_TEXT | TVIF_PARAM;
		tvins.item.lParam = index;
		tvins.hInsertAfter = hPrev;
		tvins.hParent	= hRoot;

		HWND hView = GetDlgItem(Handle(), IDC_TREE_NAV);
		HTREEITEM hItem = reinterpret_cast<HTREEITEM>(SendMessage(hView, TVM_INSERTITEM, 0, (LPARAM)&tvins));
		TreeView_SetItemState(hView, hItem, TVIS_EXPANDED, TVIS_EXPANDED);
		return hItem;
	}

	bool Settings::UpdateTreeList() {
		HWND hView = GetDlgItem(Handle(), IDC_TREE_NAV);
		HTREEITEM hRoot = TreeView_GetRoot(hView);
		updateTreeItem(hRoot);
		return true;
	}

	void Settings::updateTreeItem(HTREEITEM hItem) {
		auto hView = GetDlgItem(Handle(), IDC_TREE_NAV);

		if (hItem) {
			TVITEM tvi;
			tvi.hItem = hItem;
			tvi.mask = TVIF_PARAM | TVIF_HANDLE;
			TreeView_GetItem(hView, &tvi);

			tvi.mask = TVIF_TEXT | TVIF_HANDLE;
			// Make a scoped copy of the string, or TreeView_SetItem will end up playing with a deleted string.
			std::wstring name = m_pages[tvi.lParam]->Caption();
			SetTextTVITEM(&tvi, name);
			TreeView_SetItem(hView, &tvi);

			updateTreeItem(TreeView_GetChild(hView, hItem));
			updateTreeItem(TreeView_GetNextSibling(hView, hItem));
		}
	}

	void Settings::SetTextTVITEM(TVITEM* tvi, const std::wstring &name) {
		tvi->pszText = const_cast<LPWSTR>(name.c_str());
		tvi->cchTextMax	= static_cast<int>(name.length());
	}

	void Settings::OnOk() {
		OnApply();
		FreeResources();
		DestroyWindow(Handle());
	}

	void Settings::OnApply() {
		// Store all pages data and update strings
		for (size_t i = 0; i < m_pages.size(); ++i) {
			m_pages[i]->WriteSettings(m_settings);
		}

		UpdateTreeList();
		OnSettingsChanged(m_settings);
	}

	void Settings::OnCancel() {
		FreeResources();
		DestroyWindow(Handle());
	}
}<|endoftext|>


<commit_before>/******************************************************************************
 * This file is part of the CutePaste project
 * Copyright (c) 2013 Laszlo Papp <lpapp@kde.org>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include <QSslError>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QTcpSocket>

#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonParseError>
#include <QFile>
#include <QScopedPointer>
#include <QTextStream>
#include <QStringList>
#include <QCoreApplication>

#include <QDebug>

int main(int argc, char **argv)
{
    QCoreApplication application{argc, argv};
    application.setOrganizationName("CutePaste");
    application.setApplicationName("CutePaste Desktop Console Frontend");

    QTextStream standardOutputStream{stdout};
    QFile dataFile;
    QString firstArgument{QCoreApplication::arguments().size() < 2 ? QString() : QCoreApplication::arguments().at(1)};
    if (!firstArgument.isEmpty()) {
        dataFile.setFileName(firstArgument);
        dataFile.open(QIODevice::ReadOnly);
    } else {
        dataFile.open(stdin, QIODevice::ReadOnly);
    }

    QByteArray pasteTextByteArray{dataFile.readAll()};

    QJsonObject requestJsonObject;
    requestJsonObject.insert(QStringLiteral("data"), QString::fromUtf8(pasteTextByteArray));
    requestJsonObject.insert(QStringLiteral("language"), QStringLiteral("text"));

    QJsonDocument requestJsonDocument{requestJsonObject};

    QString baseUrlString{QStringLiteral("http://pastebin.kde.org")};

    QNetworkRequest networkRequest;
    networkRequest.setAttribute(QNetworkRequest::DoNotBufferUploadDataAttribute, true);
    networkRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
    networkRequest.setUrl(QUrl(baseUrlString + "/api/json/create"));

    QNetworkAccessManager networkAccessManager;
    QScopedPointer<QNetworkReply> networkReplyScopedPointer(networkAccessManager.post(networkRequest, requestJsonDocument.toJson()));
    QObject::connect(networkReplyScopedPointer.data(), &QNetworkReply::finished, [&]() {

        QJsonParseError jsonParseError;
        QByteArray replyJsonByteArray{networkReplyScopedPointer->readAll()};
        QJsonDocument replyJsonDocument{QJsonDocument::fromJson(replyJsonByteArray, &jsonParseError)};
        if (jsonParseError.error != QJsonParseError::NoError) {
            qDebug() << "The json network reply is not valid json:" << jsonParseError.errorString();
            QCoreApplication::quit();
        }

        if (!replyJsonDocument.isObject()) {
            qDebug() << "The json network reply is not an object";
            QCoreApplication::quit();
        }

        QJsonObject replyJsonObject{replyJsonDocument.object()};
        QJsonValue resultValue{replyJsonObject.value(QStringLiteral("result"))};

        if (!resultValue.isObject()) {
            qDebug() << "The json network reply does not contain an object for the \"result\" key";
            QCoreApplication::quit();
        }

        QJsonValue identifierValue{resultValue.toObject().value(QStringLiteral("id"))};

        if (!identifierValue.isString()) {
            qDebug() << "The json network reply does not contain a string for the \"id\" key";
            QCoreApplication::quit();
        }

        endl(standardOutputStream << baseUrlString << '/' << identifierValue.toString());

        QCoreApplication::quit();
    });

    QObject::connect(networkReplyScopedPointer.data(), static_cast<void (QNetworkReply::*)(QNetworkReply::NetworkError)>(&QNetworkReply::error), [&](QNetworkReply::NetworkError networkReplyError) {
        if (networkReplyError != QNetworkReply::NoError)
            endl(standardOutputStream << networkReplyScopedPointer->errorString());
    });

    QObject::connect(networkReplyScopedPointer.data(), &QNetworkReply::sslErrors, [&](QList<QSslError> networkReplySslErrors) {
        if (!networkReplySslErrors.isEmpty()) {
            for (const auto &networkReplySslError : networkReplySslErrors)
                endl(standardOutputStream << networkReplySslError.errorString());
        }
    });

    int returnValue{application.exec()};

    dataFile.close();
    if (dataFile.error() != QFileDevice::NoError)
        endl(standardOutputStream << dataFile.errorString());

    return returnValue;
}
<commit_msg>C++11: use raw string literals<commit_after>/******************************************************************************
 * This file is part of the CutePaste project
 * Copyright (c) 2013 Laszlo Papp <lpapp@kde.org>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include <QSslError>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QTcpSocket>

#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonParseError>
#include <QFile>
#include <QScopedPointer>
#include <QTextStream>
#include <QStringList>
#include <QCoreApplication>

#include <QDebug>

int main(int argc, char **argv)
{
    QCoreApplication application{argc, argv};
    application.setOrganizationName(R"("CutePaste")");
    application.setApplicationName(R"("CutePaste Desktop Console Frontend")");

    QTextStream standardOutputStream{stdout};
    QFile dataFile;
    QString firstArgument{QCoreApplication::arguments().size() < 2 ? QString() : QCoreApplication::arguments().at(1)};
    if (!firstArgument.isEmpty()) {
        dataFile.setFileName(firstArgument);
        dataFile.open(QIODevice::ReadOnly);
    } else {
        dataFile.open(stdin, QIODevice::ReadOnly);
    }

    QByteArray pasteTextByteArray{dataFile.readAll()};

    QJsonObject requestJsonObject;
    requestJsonObject.insert(QStringLiteral("data"), QString::fromUtf8(pasteTextByteArray));
    requestJsonObject.insert(QStringLiteral("language"), QStringLiteral("text"));

    QJsonDocument requestJsonDocument{requestJsonObject};

    QString baseUrlString{QStringLiteral(R"("http://pastebin.kde.org")")};

    QNetworkRequest networkRequest;
    networkRequest.setAttribute(QNetworkRequest::DoNotBufferUploadDataAttribute, true);
    networkRequest.setHeader(QNetworkRequest::ContentTypeHeader, R"("application/json")");
    networkRequest.setUrl(QUrl(baseUrlString + R"("/api/json/create")"));

    QNetworkAccessManager networkAccessManager;
    QScopedPointer<QNetworkReply> networkReplyScopedPointer(networkAccessManager.post(networkRequest, requestJsonDocument.toJson()));
    QObject::connect(networkReplyScopedPointer.data(), &QNetworkReply::finished, [&]() {

        QJsonParseError jsonParseError;
        QByteArray replyJsonByteArray{networkReplyScopedPointer->readAll()};
        QJsonDocument replyJsonDocument{QJsonDocument::fromJson(replyJsonByteArray, &jsonParseError)};
        if (jsonParseError.error != QJsonParseError::NoError) {
            qDebug() << R"("The json network reply is not valid json:")" << jsonParseError.errorString();
            QCoreApplication::quit();
        }

        if (!replyJsonDocument.isObject()) {
            qDebug() << R"("The json network reply is not an object")";
            QCoreApplication::quit();
        }

        QJsonObject replyJsonObject{replyJsonDocument.object()};
        QJsonValue resultValue{replyJsonObject.value(QStringLiteral("result"))};

        if (!resultValue.isObject()) {
            qDebug() << R"("The json network reply does not contain an object for the "result" key")";
            QCoreApplication::quit();
        }

        QJsonValue identifierValue{resultValue.toObject().value(QStringLiteral("id"))};

        if (!identifierValue.isString()) {
            qDebug() << R"("The json network reply does not contain a string for the "id" key")";
            QCoreApplication::quit();
        }

        endl(standardOutputStream << baseUrlString << '/' << identifierValue.toString());

        QCoreApplication::quit();
    });

    QObject::connect(networkReplyScopedPointer.data(), static_cast<void (QNetworkReply::*)(QNetworkReply::NetworkError)>(&QNetworkReply::error), [&](QNetworkReply::NetworkError networkReplyError) {
        if (networkReplyError != QNetworkReply::NoError)
            endl(standardOutputStream << networkReplyScopedPointer->errorString());
    });

    QObject::connect(networkReplyScopedPointer.data(), &QNetworkReply::sslErrors, [&](QList<QSslError> networkReplySslErrors) {
        if (!networkReplySslErrors.isEmpty()) {
            for (const auto &networkReplySslError : networkReplySslErrors)
                endl(standardOutputStream << networkReplySslError.errorString());
        }
    });

    int returnValue{application.exec()};

    dataFile.close();
    if (dataFile.error() != QFileDevice::NoError)
        endl(standardOutputStream << dataFile.errorString());

    return returnValue;
}
<|endoftext|>


<commit_before>/*
 * SminaConverter.cpp
 *
 *  Created on: Jun 4, 2014
 *      Author: dkoes
 *
 *  Convert internal molecular data (ie OBMol) into smina parse tree.
 */

#include "SminaConverter.h"
#include "parsing.h"
#include "PDBQTUtilities.h"

#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/iostreams/filter/gzip.hpp>
#include <map>
#include <openbabel/obconversion.h>

namespace SminaConverter
{

using namespace OpenBabel;
using namespace std;

MCMolConverter::MCMolConverter(OpenBabel::OBMol& m) :
		mol(m)
{
	//precompute fragments and tree
	int nc = mol.NumConformers();
	mol.SetConformer(0);
	mol.AddHydrogens();

	mol.SetAutomaticFormalCharge(false);
	DeleteHydrogens(mol); //leaves just polars

	//we kind of assume a connected molecule
	unsigned best_root_atom = FindFragments(mol, rigid_fragments);
	torsdof = rigid_fragments.size() - 1;

	unsigned int root_piece = 0;
	for (unsigned j = 0; j < rigid_fragments.size(); j++)
	{
		if (IsIn((rigid_fragments[j]), best_root_atom))
		{
			root_piece = j;
			break;
		} //this is the root rigid molecule fragment
	}

	ConstructTree(tree, rigid_fragments, root_piece, mol, true);

	if(nc != mol.NumConformers())  //didn't lose any in analysis, did we?
	{
	  abort(); //there was a bug in openbabel where addhydrogens would eliminate conformers
	}
}

//output data for this conformer
void MCMolConverter::convertConformer(unsigned conf, std::ostream& out)
{
	parsing_struct p;
	context c;

	mol.SetConformer(conf);

	std::map<unsigned int, obbranch> tmptree(tree); //tree gets modified by outputtree
	OutputTree(mol, c, p, tmptree, torsdof);

	boost::iostreams::filtering_stream<boost::iostreams::output> strm;
	strm.push(boost::iostreams::gzip_compressor());
	strm.push(out);

	boost::archive::binary_oarchive serialout(strm,
			boost::archive::no_header | boost::archive::no_tracking);

	serialout << torsdof;
	serialout << p;
	serialout << c;
}

//sets up data structures used by both text and binary
//we link with smina to ensure compatibility
//rootatom, an obatom index (starting at 1) can be specified, if not
//the "best" root is chosen
unsigned convertParsing(OBMol& mol, parsing_struct& p, context& c, int rootatom,
		const vector<int>& norotate, bool addH)
{
	if(addH)
		mol.AddHydrogens();

	mol.SetAutomaticFormalCharge(false);
	DeleteHydrogens(mol); //leaves just polars

	vector<vector<int> > rigid_fragments; //the vector of all the rigid molecule fragments, using atom indexes
	map<unsigned int, obbranch> tree;

	//we kind of assume a connected molecule
	unsigned best_root_atom = FindFragments(mol, rigid_fragments, rootatom,
			norotate);
	unsigned torsdof = rigid_fragments.size() - 1;

	if (rootatom > 0)
	{
		//user user supplied root
		best_root_atom = rootatom;
	}

	unsigned int root_piece = 0;
	for (unsigned j = 0; j < rigid_fragments.size(); j++)
	{
		if (IsIn((rigid_fragments[j]), best_root_atom))
		{
			root_piece = j;
			break;
		} //this is the root rigid molecule fragment
	}

	ConstructTree(tree, rigid_fragments, root_piece, mol, true);

	OutputTree(mol, c, p, tree, torsdof);

	return torsdof;
}

unsigned convertParsing(OpenBabel::OBMol& mol, parsing_struct& p, context& c, bool addH)
{
	std::vector<int> nr;
	return convertParsing(mol, p, c, 0, nr, addH);
}

template<class T>
static void convert(OBMol& mol, T& serialout, ostream& out, int rootatom,
		const vector<int>& norotate)
{
	parsing_struct p;
	context c;
	unsigned torsdof = convertParsing(mol, p, c, rootatom, norotate);
	serialout << torsdof;
	serialout << p;
	serialout << c;
}

//text output
void convertText(OBMol& mol, ostream& out, int rootatom,
		const vector<int>& norotate)
{
	boost::archive::text_oarchive serialout(out,
			boost::archive::no_header | boost::archive::no_tracking);
	convert(mol, serialout, out, rootatom, norotate);
}

void convertText(OpenBabel::OBMol& mol, std::ostream& out)
{
	std::vector<int> nr;
	convertText(mol, out, 0, nr);
}

//binary output
void convertBinary(OBMol& mol, ostream& out, int rootatom,
		const vector<int>& norotate)
{
	//by definition, smina format is gzipped
	boost::iostreams::filtering_stream<boost::iostreams::output> strm;
	strm.push(boost::iostreams::gzip_compressor());
	strm.push(out);

	boost::archive::binary_oarchive serialout(strm,
			boost::archive::no_header | boost::archive::no_tracking);
	convert(mol, serialout, strm, rootatom, norotate);
}

void convertBinary(OpenBabel::OBMol& mol, std::ostream& out)
{
	std::vector<int> nr;
	convertBinary(mol, out, 0, nr);
}

} //namespace SminaConverter
<commit_msg>convert fix<commit_after>/*
 * SminaConverter.cpp
 *
 *  Created on: Jun 4, 2014
 *      Author: dkoes
 *
 *  Convert internal molecular data (ie OBMol) into smina parse tree.
 */

#include "SminaConverter.h"
#include "parsing.h"
#include "PDBQTUtilities.h"

#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/iostreams/filter/gzip.hpp>
#include <map>
#include <openbabel/obconversion.h>

namespace SminaConverter
{

using namespace OpenBabel;
using namespace std;

MCMolConverter::MCMolConverter(OpenBabel::OBMol& m) :
		mol(m)
{
	//precompute fragments and tree
	int nc = mol.NumConformers();
	mol.SetConformer(0);
	mol.AddHydrogens();

	mol.SetAutomaticFormalCharge(false);
	DeleteHydrogens(mol); //leaves just polars
	if(mol.NumAtoms() == 0) return;

	//we kind of assume a connected molecule
	unsigned best_root_atom = FindFragments(mol, rigid_fragments);
	torsdof = rigid_fragments.size() - 1;

	unsigned int root_piece = 0;
	for (unsigned j = 0; j < rigid_fragments.size(); j++)
	{
		if (IsIn((rigid_fragments[j]), best_root_atom))
		{
			root_piece = j;
			break;
		} //this is the root rigid molecule fragment
	}

	ConstructTree(tree, rigid_fragments, root_piece, mol, true);

	if(nc != mol.NumConformers())  //didn't lose any in analysis, did we?
	{
	  abort(); //there was a bug in openbabel where addhydrogens would eliminate conformers
	}
}

//output data for this conformer
void MCMolConverter::convertConformer(unsigned conf, std::ostream& out)
{
	parsing_struct p;
	context c;

	mol.SetConformer(conf);

	std::map<unsigned int, obbranch> tmptree(tree); //tree gets modified by outputtree
	OutputTree(mol, c, p, tmptree, torsdof);

	boost::iostreams::filtering_stream<boost::iostreams::output> strm;
	strm.push(boost::iostreams::gzip_compressor());
	strm.push(out);

	boost::archive::binary_oarchive serialout(strm,
			boost::archive::no_header | boost::archive::no_tracking);

	serialout << torsdof;
	serialout << p;
	serialout << c;
}

//sets up data structures used by both text and binary
//we link with smina to ensure compatibility
//rootatom, an obatom index (starting at 1) can be specified, if not
//the "best" root is chosen
unsigned convertParsing(OBMol& mol, parsing_struct& p, context& c, int rootatom,
		const vector<int>& norotate, bool addH)
{
	if(addH)
		mol.AddHydrogens();

	mol.SetAutomaticFormalCharge(false);
	DeleteHydrogens(mol); //leaves just polars

	vector<vector<int> > rigid_fragments; //the vector of all the rigid molecule fragments, using atom indexes
	map<unsigned int, obbranch> tree;

	//we kind of assume a connected molecule
	unsigned best_root_atom = FindFragments(mol, rigid_fragments, rootatom,
			norotate);
	unsigned torsdof = rigid_fragments.size() - 1;

	if (rootatom > 0)
	{
		//user user supplied root
		best_root_atom = rootatom;
	}

	unsigned int root_piece = 0;
	for (unsigned j = 0; j < rigid_fragments.size(); j++)
	{
		if (IsIn((rigid_fragments[j]), best_root_atom))
		{
			root_piece = j;
			break;
		} //this is the root rigid molecule fragment
	}

	ConstructTree(tree, rigid_fragments, root_piece, mol, true);

	OutputTree(mol, c, p, tree, torsdof);

	return torsdof;
}

unsigned convertParsing(OpenBabel::OBMol& mol, parsing_struct& p, context& c, bool addH)
{
	std::vector<int> nr;
	return convertParsing(mol, p, c, 0, nr, addH);
}

template<class T>
static void convert(OBMol& mol, T& serialout, ostream& out, int rootatom,
		const vector<int>& norotate)
{
	parsing_struct p;
	context c;
	unsigned torsdof = convertParsing(mol, p, c, rootatom, norotate);
	serialout << torsdof;
	serialout << p;
	serialout << c;
}

//text output
void convertText(OBMol& mol, ostream& out, int rootatom,
		const vector<int>& norotate)
{
	boost::archive::text_oarchive serialout(out,
			boost::archive::no_header | boost::archive::no_tracking);
	convert(mol, serialout, out, rootatom, norotate);
}

void convertText(OpenBabel::OBMol& mol, std::ostream& out)
{
	std::vector<int> nr;
	convertText(mol, out, 0, nr);
}

//binary output
void convertBinary(OBMol& mol, ostream& out, int rootatom,
		const vector<int>& norotate)
{
	//by definition, smina format is gzipped
	boost::iostreams::filtering_stream<boost::iostreams::output> strm;
	strm.push(boost::iostreams::gzip_compressor());
	strm.push(out);

	boost::archive::binary_oarchive serialout(strm,
			boost::archive::no_header | boost::archive::no_tracking);
	convert(mol, serialout, strm, rootatom, norotate);
}

void convertBinary(OpenBabel::OBMol& mol, std::ostream& out)
{
	std::vector<int> nr;
	convertBinary(mol, out, 0, nr);
}

} //namespace SminaConverter
<|endoftext|>


<commit_before>// -*- Mode: C++; tab-width: 2; -*-
// vi: set ts=2:
//
// $Id: ContourSurface_bench.C,v 1.1 2003/05/03 17:29:31 oliver Exp $
//
#include <BALL/CONCEPT/benchmark.h>

///////////////////////////

#include <BALL/DATATYPE/contourSurface.h>

///////////////////////////

using namespace BALL;

START_BENCHMARK(ContourSurface, 1.0, "$Id: ContourSurface_bench.C,v 1.1 2003/05/03 17:29:31 oliver Exp $")

/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////

START_SECTION(Ocatahedra, 0.2)
	ContourSurface cs;
	RegularData3D grid(Vector3(-2.0), Vector3(2.0), 5, 5, 5);
	for (Position i = 0; i < grid.size(); grid[i++] = 1.0);
	grid[2 + 2 * 5 + 2 * 25] = -1.0;
	for (Position i = 0; i < 5000; i++)
	{
		START_TIMER
		cs << grid;
		STOP_TIMER
	}
END_SECTION

START_SECTION(Large Grid, 0.8)
	ContourSurface cs2(5.0);
	RegularData3D grid2(Vector3(-10.0), Vector3(10.0), 200,200,200);
	for (Position i = 0; i < grid2.size(); i++)
	{
		grid2[i] = grid2.getCoordinates(i).getLength();
	}
	for (Position i = 0; i < 10; i++)
	{
		START_TIMER
		cs2 << grid2;
		STOP_TIMER
	}
END_SECTION

/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////

END_BENCHMARK
<commit_msg>fixed: adapted to new interface of TRegData2D<commit_after>// -*- Mode: C++; tab-width: 2; -*-
// vi: set ts=2:
//
// $Id: ContourSurface_bench.C,v 1.2 2003/05/06 20:20:20 oliver Exp $
//
#include <BALL/CONCEPT/benchmark.h>

///////////////////////////

#include <BALL/DATATYPE/contourSurface.h>

///////////////////////////

using namespace BALL;

START_BENCHMARK(ContourSurface, 1.0, "$Id: ContourSurface_bench.C,v 1.2 2003/05/06 20:20:20 oliver Exp $")

/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////

START_SECTION(Ocatahedra, 0.2)
	ContourSurface cs;
	RegularData3D grid(RegularData3D::IndexType(5, 5, 5), Vector3(-2.0), Vector3(2.0));
	for (Position i = 0; i < grid.size(); grid[i++] = 1.0);
	grid[2 + 2 * 5 + 2 * 25] = -1.0;
	for (Position i = 0; i < 5000; i++)
	{
		START_TIMER
		cs << grid;
		STOP_TIMER
	}
END_SECTION

START_SECTION(Large Grid, 0.8)
	ContourSurface cs2(5.0);
	RegularData3D grid2(RegularData3D::IndexType(200, 200, 200), Vector3(-10.0), Vector3(10.0));
	for (Position i = 0; i < grid2.size(); i++)
	{
		grid2[i] = grid2.getCoordinates(i).getLength();
	}
	for (Position i = 0; i < 10; i++)
	{
		START_TIMER
		cs2 << grid2;
		STOP_TIMER
	}
END_SECTION

/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////

END_BENCHMARK
<|endoftext|>


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

#include "IECoreAlembic/ObjectReader.h"

#include "IECoreScene/Camera.h"
#include "IECoreScene/Transform.h"

#include "IECore/SimpleTypedData.h"

#include "Alembic/AbcGeom/ICamera.h"

using namespace IECore;
using namespace IECoreScene;
using namespace IECoreAlembic;
using namespace Alembic::AbcGeom;

namespace
{

class CameraReader : public IECoreAlembic::ObjectReader
{

	public :

		CameraReader( const ICamera &camera )
			:	m_camera( camera )
		{
		}

		const Alembic::Abc::IObject &object() const override
		{
			return m_camera;
		}

		Alembic::Abc::IBox3dProperty readBoundProperty() const override
		{
			return IBox3dProperty();
		}

		size_t readNumSamples() const override
		{
			return m_camera.getSchema().getNumSamples();
		}

		Alembic::AbcCoreAbstract::TimeSamplingPtr readTimeSampling() const override
		{
			return m_camera.getSchema().getTimeSampling();
		}

		IECore::ObjectPtr readSample( const Alembic::Abc::ISampleSelector &sampleSelector ) const override
		{
			const ICameraSchema &cameraSchema = m_camera.getSchema();
			CameraSample sample;
			cameraSchema.get( sample, sampleSelector );

			CameraPtr result = new Camera;
			result->parameters()["projection"] = new StringData( "perspective" );

			double top, bottom, left, right;
			sample.getScreenWindow( top, bottom, left, right );
			result->parameters()["screenWindow"] = new Box2fData( Box2f( V2f( left, bottom ), V2f( right, top ) ) );
			result->parameters()["projection:fov"] = new FloatData( sample.getFieldOfView() );

			return result;
		}

	private :

		const ICamera m_camera;

		static Description<CameraReader, ICamera> g_description;
};

IECoreAlembic::ObjectReader::Description<CameraReader, ICamera> CameraReader::g_description( Camera::staticTypeId() );

} // namespace
<commit_msg>IECoreAlembic : Update CameraReader to new camera interface<commit_after>//////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2012, John Haddon. All rights reserved.
//  Copyright (c) 2017, Image Engine Design Inc. All rights reserved.
//
//  Redistribution and use in source and binary forms, with or without
//  modification, are permitted provided that the following conditions are
//  met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//
//     * Neither the name of Image Engine Design nor the names of any
//       other contributors to this software may be used to endorse or
//       promote products derived from this software without specific prior
//       written permission.
//
//  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
//  IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
//  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
//  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
//  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
//  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
//  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
//  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
//  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
//  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
//  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////

#include "IECoreAlembic/ObjectReader.h"

#include "IECoreScene/Camera.h"
#include "IECoreScene/Transform.h"

#include "IECore/SimpleTypedData.h"

#include "Alembic/AbcGeom/ICamera.h"

using namespace IECore;
using namespace IECoreScene;
using namespace IECoreAlembic;
using namespace Alembic::AbcGeom;

namespace
{

class CameraReader : public IECoreAlembic::ObjectReader
{

	public :

		CameraReader( const ICamera &camera )
			:	m_camera( camera )
		{
		}

		const Alembic::Abc::IObject &object() const override
		{
			return m_camera;
		}

		Alembic::Abc::IBox3dProperty readBoundProperty() const override
		{
			return IBox3dProperty();
		}

		size_t readNumSamples() const override
		{
			return m_camera.getSchema().getNumSamples();
		}

		Alembic::AbcCoreAbstract::TimeSamplingPtr readTimeSampling() const override
		{
			return m_camera.getSchema().getTimeSampling();
		}

		IECore::ObjectPtr readSample( const Alembic::Abc::ISampleSelector &sampleSelector ) const override
		{
			const ICameraSchema &cameraSchema = m_camera.getSchema();
			CameraSample sample;
			cameraSchema.get( sample, sampleSelector );

			CameraPtr result = new Camera;
			result->setProjection( "perspective" );

			result->setFocalLength( sample.getFocalLength() );
			result->setAperture( 10.0f *
				Imath::V2f( sample.getHorizontalAperture(), sample.getVerticalAperture() )
			);
			result->setApertureOffset( 10.0f *
				Imath::V2f( sample.getHorizontalFilmOffset(), sample.getVerticalFilmOffset() )
			);

			result->setClippingPlanes(
				Imath::V2f( sample.getNearClippingPlane(), sample.getFarClippingPlane() )
			);
			result->setFStop( sample.getFStop() );
			result->setFocalLengthWorldScale( 0.1 ); // Alembic stores focal length in tenths of world units
			result->setFocusDistance( sample.getFocusDistance() );

			return result;
		}

	private :

		const ICamera m_camera;

		static Description<CameraReader, ICamera> g_description;
};

IECoreAlembic::ObjectReader::Description<CameraReader, ICamera> CameraReader::g_description( Camera::staticTypeId() );

} // namespace
<|endoftext|>


<commit_before>/* libvisio
 * Copyright (C) 2011 Fridrich Strba <fridrich.strba@bluewin.ch>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA  02111-1301 USA
 */

#include "libvisio_utils.h"

#define VSD_NUM_ELEMENTS(array) sizeof(array)/sizeof(array[0])

uint8_t readU8(WPXInputStream *input)
{
	if (!input || input->atEOS())
		return (uint8_t)0;
	unsigned long numBytesRead;
	uint8_t const * p = input->read(sizeof(uint8_t), numBytesRead);

	if (p && numBytesRead == sizeof(uint8_t))
		return *(uint8_t const *)(p);
	return (uint8_t)0;
}

uint16_t readU16(WPXInputStream *input)
{
	uint16_t p0 = (uint16_t)readU8(input);
	uint16_t p1 = (uint16_t)readU8(input);
	return (uint16_t)(p0|(p1<<8));
}

uint32_t readU32(WPXInputStream *input)
{
	uint32_t p0 = (uint32_t)readU8(input);
	uint32_t p1 = (uint32_t)readU8(input);
	uint32_t p2 = (uint32_t)readU8(input);
	uint32_t p3 = (uint32_t)readU8(input);
	return (uint32_t)(p0|(p1<<8)|(p2<<16)|(p3<<24));
}

uint64_t readU64(WPXInputStream *input)
{
	uint64_t p0 = (uint64_t)readU8(input);
	uint64_t p1 = (uint64_t)readU8(input);
	uint64_t p2 = (uint64_t)readU8(input);
	uint64_t p3 = (uint64_t)readU8(input);
	uint64_t p4 = (uint64_t)readU8(input);
	uint64_t p5 = (uint64_t)readU8(input);
	uint64_t p6 = (uint64_t)readU8(input);
	uint64_t p7 = (uint64_t)readU8(input);
	return (uint64_t)(p0|(p1<<8)|(p2<<16)|(p3<<24)|(p4<<32)|(p5<<40)|(p6<<48)|(p7<<56));
}

double readDouble(WPXInputStream *input)
{
#if defined (_MSC_VER) && (_MSC_VER <= 1200)
    return static_cast<double>(static_cast<__int64>(readU64(input)));
#else
	return static_cast<double>(readU64(input));
#endif
}
<commit_msg>use union where reinterpret cast is not possible<commit_after>/* libvisio
 * Copyright (C) 2011 Fridrich Strba <fridrich.strba@bluewin.ch>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA  02111-1301 USA
 */

#include "libvisio_utils.h"

#define VSD_NUM_ELEMENTS(array) sizeof(array)/sizeof(array[0])

uint8_t readU8(WPXInputStream *input)
{
	if (!input || input->atEOS())
		return (uint8_t)0;
	unsigned long numBytesRead;
	uint8_t const * p = input->read(sizeof(uint8_t), numBytesRead);

	if (p && numBytesRead == sizeof(uint8_t))
		return *(uint8_t const *)(p);
	return (uint8_t)0;
}

uint16_t readU16(WPXInputStream *input)
{
	uint16_t p0 = (uint16_t)readU8(input);
	uint16_t p1 = (uint16_t)readU8(input);
	return (uint16_t)(p0|(p1<<8));
}

uint32_t readU32(WPXInputStream *input)
{
	uint32_t p0 = (uint32_t)readU8(input);
	uint32_t p1 = (uint32_t)readU8(input);
	uint32_t p2 = (uint32_t)readU8(input);
	uint32_t p3 = (uint32_t)readU8(input);
	return (uint32_t)(p0|(p1<<8)|(p2<<16)|(p3<<24));
}

uint64_t readU64(WPXInputStream *input)
{
	uint64_t p0 = (uint64_t)readU8(input);
	uint64_t p1 = (uint64_t)readU8(input);
	uint64_t p2 = (uint64_t)readU8(input);
	uint64_t p3 = (uint64_t)readU8(input);
	uint64_t p4 = (uint64_t)readU8(input);
	uint64_t p5 = (uint64_t)readU8(input);
	uint64_t p6 = (uint64_t)readU8(input);
	uint64_t p7 = (uint64_t)readU8(input);
	return (uint64_t)(p0|(p1<<8)|(p2<<16)|(p3<<24)|(p4<<32)|(p5<<40)|(p6<<48)|(p7<<56));
}

double readDouble(WPXInputStream *input)
{
	union
	{
		uint64_t *a;
		double *b;
	};

	uint64_t value = readU64(input);

	a = &value;

	return *b;
}
<|endoftext|>


<commit_before>/*
 * Copyright 2016 Adam Chyła, adam@chyla.org
 * All rights reserved. Distributed under the terms of the MIT License.
 */

#include "daily_user_statistics_creator.h"

#include "src/bash/database/detail/entity/daily_user_statistic.h"
#include "src/bash/database/detail/entity/daily_user_command_statistic.h"

#include <boost/log/trivial.hpp>

namespace bash
{

namespace analyzer
{

namespace detail
{

DailyUserStatisticsCreatorPtr DailyUserStatisticsCreator::Create(::bash::database::detail::DatabaseFunctionsInterfacePtr database_functions,
                                                                 ::database::detail::GeneralDatabaseFunctionsInterfacePtr general_database_functions) {
  return DailyUserStatisticsCreatorPtr(new DailyUserStatisticsCreator(database_functions, general_database_functions));
}

void DailyUserStatisticsCreator::CreateStatistics(const ::type::Date &today) {
  BOOST_LOG_TRIVIAL(debug) << "bash::analyzer::detail::DailyUserStatisticsCreator::CreateStatistics: Function call";

  ::bash::database::detail::entity::DailyUserStatistic us;
  ::bash::database::detail::entity::DailyUserCommandStatistic ucs;

  us.classification = ::database::type::Classification::UNKNOWN;

  auto agents = general_database_functions_->GetAgentsIds();
  BOOST_LOG_TRIVIAL(debug) << "bash::analyzer::detail::DailyUserStatisticsCreator::CreateStatistics: Found " << agents.size() << " agents";
  for (const auto &agent : agents) {
    us.agent_name_id = agent;

    auto users = database_functions_->GetSystemUsersIdsFromLogs(agent);
    BOOST_LOG_TRIVIAL(debug) << "bash::analyzer::detail::DailyUserStatisticsCreator::CreateStatistics: Found " << users.size() << " users for agent " << agent;
    for (const auto &user : users) {
      us.user_id = user;

      auto dates = database_functions_->GetNotCalculatedDatesIdsFromLogs(agent, user);
      BOOST_LOG_TRIVIAL(debug) << "bash::analyzer::detail::DailyUserStatisticsCreator::CreateStatistics: Found " << dates.size() << " dates for agent " << agent << ", user " << user;
      for (const auto &date : dates) {
        us.date_id = date;

        database_functions_->AddDailyUserStatistic(us);
        us.id = database_functions_->GetDailyUserStatisticId(agent, user, date);

        auto commands = database_functions_->GetCommandsIdsFromLogs(agent, user, date);
        BOOST_LOG_TRIVIAL(debug) << "bash::analyzer::detail::DailyUserStatisticsCreator::CreateStatistics: Found " << commands.size() << " commands for agent " << agent << ", user " << user << ", date " << date;
        for (const auto &command : commands) {
          BOOST_LOG_TRIVIAL(debug) << "bash::analyzer::detail::DailyUserStatisticsCreator::CreateStatistics: Analyzing command: " << command;

          ucs.daily_user_statistic_id = us.id;
          ucs.command_id = command;
          ucs.summary = database_functions_->CountCommandsForUserDailyStatisticFromLogs(agent, date, user, command);

          BOOST_LOG_TRIVIAL(debug) << "bash::analyzer::detail::DailyUserStatisticsCreator::CreateStatistics: Summary for command " << command << ": " << ucs.summary;

          database_functions_->AddDailyUserCommandStatistic(ucs);
        }
      }
    }
  }
}

DailyUserStatisticsCreator::DailyUserStatisticsCreator(::bash::database::detail::DatabaseFunctionsInterfacePtr database_functions,
                                                       ::database::detail::GeneralDatabaseFunctionsInterfacePtr general_database_functions) :
database_functions_(database_functions),
general_database_functions_(general_database_functions) {
}

}

}

}
<commit_msg>Ignore current date when creating bash statistics<commit_after>/*
 * Copyright 2016 Adam Chyła, adam@chyla.org
 * All rights reserved. Distributed under the terms of the MIT License.
 */

#include "daily_user_statistics_creator.h"

#include "src/bash/database/detail/entity/daily_user_statistic.h"
#include "src/bash/database/detail/entity/daily_user_command_statistic.h"

#include <boost/log/trivial.hpp>

namespace bash
{

namespace analyzer
{

namespace detail
{

DailyUserStatisticsCreatorPtr DailyUserStatisticsCreator::Create(::bash::database::detail::DatabaseFunctionsInterfacePtr database_functions,
                                                                 ::database::detail::GeneralDatabaseFunctionsInterfacePtr general_database_functions) {
  return DailyUserStatisticsCreatorPtr(new DailyUserStatisticsCreator(database_functions, general_database_functions));
}

void DailyUserStatisticsCreator::CreateStatistics(const ::type::Date &today) {
  BOOST_LOG_TRIVIAL(debug) << "bash::analyzer::detail::DailyUserStatisticsCreator::CreateStatistics: Function call";

  ::bash::database::detail::entity::DailyUserStatistic us;
  ::bash::database::detail::entity::DailyUserCommandStatistic ucs;

  us.classification = ::database::type::Classification::UNKNOWN;

  auto current_date_id = general_database_functions_->GetDateId(today);

  auto agents = general_database_functions_->GetAgentsIds();
  BOOST_LOG_TRIVIAL(debug) << "bash::analyzer::detail::DailyUserStatisticsCreator::CreateStatistics: Found " << agents.size() << " agents";
  for (const auto &agent : agents) {
    us.agent_name_id = agent;

    auto users = database_functions_->GetSystemUsersIdsFromLogs(agent);
    BOOST_LOG_TRIVIAL(debug) << "bash::analyzer::detail::DailyUserStatisticsCreator::CreateStatistics: Found " << users.size() << " users for agent " << agent;
    for (const auto &user : users) {
      us.user_id = user;

      auto dates = database_functions_->GetNotCalculatedDatesIdsFromLogs(agent, user);
      BOOST_LOG_TRIVIAL(debug) << "bash::analyzer::detail::DailyUserStatisticsCreator::CreateStatistics: Found " << dates.size() << " dates for agent " << agent << ", user " << user;
      for (const auto &date : dates) {
        if (date == current_date_id) {
          BOOST_LOG_TRIVIAL(debug) << "bash::analyzer::detail::DailyUserStatisticsCreator::CreateStatistics: Ignoring current date (id=" << current_date_id << ")";
          continue;
        }

        us.date_id = date;

        database_functions_->AddDailyUserStatistic(us);
        us.id = database_functions_->GetDailyUserStatisticId(agent, user, date);

        auto commands = database_functions_->GetCommandsIdsFromLogs(agent, user, date);
        BOOST_LOG_TRIVIAL(debug) << "bash::analyzer::detail::DailyUserStatisticsCreator::CreateStatistics: Found " << commands.size() << " commands for agent " << agent << ", user " << user << ", date " << date;
        for (const auto &command : commands) {
          BOOST_LOG_TRIVIAL(debug) << "bash::analyzer::detail::DailyUserStatisticsCreator::CreateStatistics: Analyzing command: " << command;

          ucs.daily_user_statistic_id = us.id;
          ucs.command_id = command;
          ucs.summary = database_functions_->CountCommandsForUserDailyStatisticFromLogs(agent, date, user, command);

          BOOST_LOG_TRIVIAL(debug) << "bash::analyzer::detail::DailyUserStatisticsCreator::CreateStatistics: Summary for command " << command << ": " << ucs.summary;

          database_functions_->AddDailyUserCommandStatistic(ucs);
        }
      }
    }
  }
}

DailyUserStatisticsCreator::DailyUserStatisticsCreator(::bash::database::detail::DatabaseFunctionsInterfacePtr database_functions,
                                                       ::database::detail::GeneralDatabaseFunctionsInterfacePtr general_database_functions) :
database_functions_(database_functions),
general_database_functions_(general_database_functions) {
}

}

}

}
<|endoftext|>


<commit_before>/* This file is part of the KDE libraries
 * Copyright (C) 2008 Dmitry Suzdalev <dimsuz@gmail.com>
 * Copyright (C) 2008 Erlend Hamberg <ehamberg@gmail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) version 3.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#include "katevimodebar.h"
#include "kateviinputmodemanager.h"
#include "katevinormalmode.h"
#include "katevivisualmode.h"
#include "kateviinsertmode.h"

#include <QtGui/QLabel>
#include <QtGui/QHBoxLayout>

#include "klocale.h"

KateViModeBar::KateViModeBar(KateView* view, QWidget* parent)
: KateViewBarWidget(false, view, parent),
  m_labelStatus(new QLabel(this)),
  m_labelCommand(new QLabel(this))
{
  QHBoxLayout *lay = new QHBoxLayout(this);
  lay->addWidget(m_labelStatus);
  lay->addStretch(1);
  lay->addWidget(m_labelCommand);
  lay->addSpacing(30);

  // otherwise the command will look 'jumpy' as new symbols are added to it
  // 50 pix should be enough i think
  m_labelCommand->setFixedWidth(50);

  QWidget* widget = centralWidget();
  widget->setLayout(lay);
}

KateViModeBar::~KateViModeBar()
{

}

void KateViModeBar::updateViMode(ViMode mode)
{
  m_labelStatus->setText(modeToString(mode));
}

void KateViModeBar::updatePartialCommand(const QString &cmd)
{
  m_labelCommand->setText(cmd);
}
QString KateViModeBar::modeToString(ViMode mode) const
{
  QString modeStr;
  switch (mode) {
    case InsertMode:
      modeStr = i18n("VI: INSERT MODE");
      break;
    case NormalMode:
      modeStr = i18n("VI: NORMAL MODE");
      break;
    case VisualMode:
      modeStr = i18n("VI: VISUAL");
      break;
    case VisualLineMode:
      modeStr = i18n("VI: VISUAL LINE");
      break;
  }
  return modeStr;
}
<commit_msg>remove Qt warning, widget already have a layout<commit_after>/* This file is part of the KDE libraries
 * Copyright (C) 2008 Dmitry Suzdalev <dimsuz@gmail.com>
 * Copyright (C) 2008 Erlend Hamberg <ehamberg@gmail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) version 3.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#include "katevimodebar.h"
#include "kateviinputmodemanager.h"
#include "katevinormalmode.h"
#include "katevivisualmode.h"
#include "kateviinsertmode.h"

#include <QtGui/QLabel>
#include <QtGui/QHBoxLayout>

#include "klocale.h"

KateViModeBar::KateViModeBar(KateView* view, QWidget* parent)
: KateViewBarWidget(false, view, parent),
  m_labelStatus(new QLabel(this)),
  m_labelCommand(new QLabel(this))
{
  QHBoxLayout *lay = static_cast<QHBoxLayout*>(layout());
  lay->addWidget(m_labelStatus);
  lay->addStretch(1);
  lay->addWidget(m_labelCommand);
  lay->addSpacing(30);

  // otherwise the command will look 'jumpy' as new symbols are added to it
  // 50 pix should be enough i think
  m_labelCommand->setFixedWidth(50);
}

KateViModeBar::~KateViModeBar()
{

}

void KateViModeBar::updateViMode(ViMode mode)
{
  m_labelStatus->setText(modeToString(mode));
}

void KateViModeBar::updatePartialCommand(const QString &cmd)
{
  m_labelCommand->setText(cmd);
}
QString KateViModeBar::modeToString(ViMode mode) const
{
  QString modeStr;
  switch (mode) {
    case InsertMode:
      modeStr = i18n("VI: INSERT MODE");
      break;
    case NormalMode:
      modeStr = i18n("VI: NORMAL MODE");
      break;
    case VisualMode:
      modeStr = i18n("VI: VISUAL");
      break;
    case VisualLineMode:
      modeStr = i18n("VI: VISUAL LINE");
      break;
  }
  return modeStr;
}
<|endoftext|>