<commit_before>// Copyright (c) 2006-2008 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 "chrome/browser/hang_monitor/hung_window_detector.h"

#include <windows.h>

#include "base/logging.h"
#include "chrome/app/result_codes.h"

// How long do we wait for the terminated thread or process to die (in ms)
static const int kTerminateTimeout = 2000;

const wchar_t HungWindowDetector::kHungChildWindowTimeout[] =
    L"Chrome_HungChildWindowTimeout";

HungWindowDetector::HungWindowDetector(HungWindowNotification* notification)
    : notification_(notification),
      top_level_window_(NULL),
      enumerating_(false) {
  DCHECK(NULL != notification_);
}
// NOTE: It is the caller's responsibility to make sure that
// callbacks on this object have been stopped before
// destroying this object
HungWindowDetector::~HungWindowDetector() {
}

bool HungWindowDetector::Initialize(HWND top_level_window,
                                    int message_response_timeout) {
  if (NULL ==  notification_) {
    return false;
  }
  if (NULL == top_level_window) {
    return false;
  }
  // It is OK to call Initialize on this object repeatedly
  // with different top lebel HWNDs and timeout values each time.
  // And we do not need a lock for this because we are just
  // swapping DWORDs.
  top_level_window_ = top_level_window;
  message_response_timeout_ = message_response_timeout;
  return true;
}

void HungWindowDetector::OnTick() {
  do {
    AutoLock lock(hang_detection_lock_);
    // If we already are checking for hung windows on another thread,
    // don't do this again.
    if (enumerating_) {
      return;
    }
    enumerating_ = true;
  } while (false);  // To scope the AutoLock

  EnumChildWindows(top_level_window_, ChildWndEnumProc,
                   reinterpret_cast<LPARAM>(this));
  enumerating_ = false;
}

bool HungWindowDetector::CheckChildWindow(HWND child_window) {
  // It can happen that the window is DOA. It specifically happens
  // when we have just killed a plugin process and the enum is still
  // enumerating windows from that process.
  if (!IsWindow(child_window))  {
    return true;
  }

  DWORD top_level_window_thread_id =
      GetWindowThreadProcessId(top_level_window_, NULL);

  DWORD child_window_process_id = 0;
  DWORD child_window_thread_id =
      GetWindowThreadProcessId(child_window, &child_window_process_id);
  bool continue_hang_detection = true;

  if (top_level_window_thread_id != child_window_thread_id) {
    // The message timeout for a child window starts of with a default
    // value specified by the message_response_timeout_ member. It is
    // tracked by a property on the child window.
#pragma warning(disable:4311)
    int child_window_message_timeout =
        reinterpret_cast<int>(GetProp(child_window, kHungChildWindowTimeout));
#pragma warning(default:4311)
    if (!child_window_message_timeout) {
      child_window_message_timeout = message_response_timeout_;
    }

    DWORD result = 0;
    if (0 == SendMessageTimeout(child_window,
                                WM_NULL,
                                0,
                                0,
                                SMTO_BLOCK,
                                child_window_message_timeout,
                                &result)) {
      HungWindowNotification::ActionOnHungWindow action =
          HungWindowNotification::HUNG_WINDOW_IGNORE;
#pragma warning(disable:4312)
      SetProp(child_window, kHungChildWindowTimeout,
              reinterpret_cast<HANDLE>(child_window_message_timeout));
#pragma warning(default:4312)
      continue_hang_detection =
        notification_->OnHungWindowDetected(child_window, top_level_window_,
                                            &action);
      // Make sure this window still a child of our top-level parent
      if (!IsChild(top_level_window_, child_window)) {
        return continue_hang_detection;
      }

      switch (action) {
        case HungWindowNotification::HUNG_WINDOW_TERMINATE_THREAD: {
          CHandle child_thread(OpenThread(THREAD_TERMINATE,
                                          FALSE,
                                          child_window_thread_id));
          if (NULL == child_thread.m_h) {
            break;
          }
          // Before swinging the axe, do some sanity checks to make
          // sure this window still belongs to the same thread
          if (GetWindowThreadProcessId(child_window, NULL) !=
                  child_window_thread_id) {
            break;
          }
          TerminateThread(child_thread, 0);
          WaitForSingleObject(child_thread, kTerminateTimeout);
          child_thread.Close();
          break;
        }
        case HungWindowNotification::HUNG_WINDOW_TERMINATE_PROCESS: {
          CHandle child_process(OpenProcess(PROCESS_TERMINATE,
                                            FALSE,
                                            child_window_process_id));

          if (NULL == child_process.m_h)  {
            break;
          }
          // Before swinging the axe, do some sanity checks to make
          // sure this window still belongs to the same process
          DWORD process_id_check = 0;
          GetWindowThreadProcessId(child_window, &process_id_check);
          if (process_id_check !=  child_window_process_id) {
            break;
          }
          TerminateProcess(child_process, ResultCodes::HUNG);
          WaitForSingleObject(child_process, kTerminateTimeout);
          child_process.Close();
          break;
        }
        default: {
          break;
        }
      }
    } else {
      RemoveProp(child_window, kHungChildWindowTimeout);
    }
  }

  return continue_hang_detection;
}

BOOL CALLBACK HungWindowDetector::ChildWndEnumProc(HWND child_window,
                                                   LPARAM param) {
  HungWindowDetector* detector_instance =
      reinterpret_cast<HungWindowDetector*>(param);
  if (NULL == detector_instance) {
    NOTREACHED();
    return FALSE;
  }

  return detector_instance->CheckChildWindow(child_window);
}

<commit_msg>Build fix: altbase.h inclusion in hang_monitor<commit_after>// Copyright (c) 2006-2008 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 "chrome/browser/hang_monitor/hung_window_detector.h"

#include <windows.h>
#include <atlbase.h>

#include "base/logging.h"
#include "chrome/app/result_codes.h"

// How long do we wait for the terminated thread or process to die (in ms)
static const int kTerminateTimeout = 2000;

const wchar_t HungWindowDetector::kHungChildWindowTimeout[] =
    L"Chrome_HungChildWindowTimeout";

HungWindowDetector::HungWindowDetector(HungWindowNotification* notification)
    : notification_(notification),
      top_level_window_(NULL),
      enumerating_(false) {
  DCHECK(NULL != notification_);
}
// NOTE: It is the caller's responsibility to make sure that
// callbacks on this object have been stopped before
// destroying this object
HungWindowDetector::~HungWindowDetector() {
}

bool HungWindowDetector::Initialize(HWND top_level_window,
                                    int message_response_timeout) {
  if (NULL ==  notification_) {
    return false;
  }
  if (NULL == top_level_window) {
    return false;
  }
  // It is OK to call Initialize on this object repeatedly
  // with different top lebel HWNDs and timeout values each time.
  // And we do not need a lock for this because we are just
  // swapping DWORDs.
  top_level_window_ = top_level_window;
  message_response_timeout_ = message_response_timeout;
  return true;
}

void HungWindowDetector::OnTick() {
  do {
    AutoLock lock(hang_detection_lock_);
    // If we already are checking for hung windows on another thread,
    // don't do this again.
    if (enumerating_) {
      return;
    }
    enumerating_ = true;
  } while (false);  // To scope the AutoLock

  EnumChildWindows(top_level_window_, ChildWndEnumProc,
                   reinterpret_cast<LPARAM>(this));
  enumerating_ = false;
}

bool HungWindowDetector::CheckChildWindow(HWND child_window) {
  // It can happen that the window is DOA. It specifically happens
  // when we have just killed a plugin process and the enum is still
  // enumerating windows from that process.
  if (!IsWindow(child_window))  {
    return true;
  }

  DWORD top_level_window_thread_id =
      GetWindowThreadProcessId(top_level_window_, NULL);

  DWORD child_window_process_id = 0;
  DWORD child_window_thread_id =
      GetWindowThreadProcessId(child_window, &child_window_process_id);
  bool continue_hang_detection = true;

  if (top_level_window_thread_id != child_window_thread_id) {
    // The message timeout for a child window starts of with a default
    // value specified by the message_response_timeout_ member. It is
    // tracked by a property on the child window.
#pragma warning(disable:4311)
    int child_window_message_timeout =
        reinterpret_cast<int>(GetProp(child_window, kHungChildWindowTimeout));
#pragma warning(default:4311)
    if (!child_window_message_timeout) {
      child_window_message_timeout = message_response_timeout_;
    }

    DWORD result = 0;
    if (0 == SendMessageTimeout(child_window,
                                WM_NULL,
                                0,
                                0,
                                SMTO_BLOCK,
                                child_window_message_timeout,
                                &result)) {
      HungWindowNotification::ActionOnHungWindow action =
          HungWindowNotification::HUNG_WINDOW_IGNORE;
#pragma warning(disable:4312)
      SetProp(child_window, kHungChildWindowTimeout,
              reinterpret_cast<HANDLE>(child_window_message_timeout));
#pragma warning(default:4312)
      continue_hang_detection =
        notification_->OnHungWindowDetected(child_window, top_level_window_,
                                            &action);
      // Make sure this window still a child of our top-level parent
      if (!IsChild(top_level_window_, child_window)) {
        return continue_hang_detection;
      }

      switch (action) {
        case HungWindowNotification::HUNG_WINDOW_TERMINATE_THREAD: {
          CHandle child_thread(OpenThread(THREAD_TERMINATE,
                                          FALSE,
                                          child_window_thread_id));
          if (NULL == child_thread.m_h) {
            break;
          }
          // Before swinging the axe, do some sanity checks to make
          // sure this window still belongs to the same thread
          if (GetWindowThreadProcessId(child_window, NULL) !=
                  child_window_thread_id) {
            break;
          }
          TerminateThread(child_thread, 0);
          WaitForSingleObject(child_thread, kTerminateTimeout);
          child_thread.Close();
          break;
        }
        case HungWindowNotification::HUNG_WINDOW_TERMINATE_PROCESS: {
          CHandle child_process(OpenProcess(PROCESS_TERMINATE,
                                            FALSE,
                                            child_window_process_id));

          if (NULL == child_process.m_h)  {
            break;
          }
          // Before swinging the axe, do some sanity checks to make
          // sure this window still belongs to the same process
          DWORD process_id_check = 0;
          GetWindowThreadProcessId(child_window, &process_id_check);
          if (process_id_check !=  child_window_process_id) {
            break;
          }
          TerminateProcess(child_process, ResultCodes::HUNG);
          WaitForSingleObject(child_process, kTerminateTimeout);
          child_process.Close();
          break;
        }
        default: {
          break;
        }
      }
    } else {
      RemoveProp(child_window, kHungChildWindowTimeout);
    }
  }

  return continue_hang_detection;
}

BOOL CALLBACK HungWindowDetector::ChildWndEnumProc(HWND child_window,
                                                   LPARAM param) {
  HungWindowDetector* detector_instance =
      reinterpret_cast<HungWindowDetector*>(param);
  if (NULL == detector_instance) {
    NOTREACHED();
    return FALSE;
  }

  return detector_instance->CheckChildWindow(child_window);
}

<|endoftext|>


<commit_before>///
/// @file  FactorTable.hpp
/// @brief The FactorTable class is used to save memory. It combines
///        the lpf[n] (least prime factor) and mu[n] (Möbius function)
///        lookup tables into a single factors_[n] table which
///        furthermore only contains entries for numbers which are
///        not divisible by 2, 3, 5 and 7.
///        The factor table concept has first been devised and
///        implemented by Christian Bau in 2003.
///
///        FactorTable.lpf(index) is equal to (n = get_number(index)):
///
///         1) 0      if moebius(n) = 0
///         2) lpf    if !is_prime(n) && moebius(n) = -1
///         3) lpf-1  if !is_prime(n) && moebius(n) = 1
///         4) n      if  is_prime(n) && n < T_MAX
///         5) T_MAX  if  is_prime(n) && n > T_MAX
///
/// Copyright (C) 2016 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License. See the COPYING
/// file in the top level directory.
///

#ifndef FACTORTABLE_HPP
#define FACTORTABLE_HPP

#include <primecount.hpp>
#include <primecount-internal.hpp>
#include <primesieve.hpp>
#include <pmath.hpp>
#include <int128.hpp>

#include <algorithm>
#include <cassert>
#include <limits>
#include <stdint.h>
#include <vector>
#include <iostream>

#ifdef _OPENMP
  #include <omp.h>
#endif

namespace primecount {

/// AbstractFactorTable contains static FactorTable
/// data and it used to convert:
/// 1) A number into a FactorTable index.
/// 2) A FactorTable index into a number.
///
class AbstractFactorTable
{
protected:
  virtual ~AbstractFactorTable() { }

public:
  /// @pre number > 0
  static void to_index(int64_t* number)
  {
    assert(*number > 0);
    *number = get_index(*number);
  }

  /// @pre number > 0
  static int64_t get_index(uint64_t number)
  {
    assert(number > 0);
    uint64_t q = number / 210;
    uint64_t r = number % 210;
    return 48 * q + indexes_[r];
  }

  static int64_t get_number(uint64_t index)
  {
    uint64_t q = index / 48;
    uint64_t r = index % 48;
    return 210 * q + numbers_[r];
  }

private:
  static const uint8_t numbers_[48];
  static const  int8_t indexes_[210];
};

template <typename T>
class FactorTable : public AbstractFactorTable
{
public:
  /// Factor numbers <= y
  FactorTable(int64_t y, int threads)
  {
    if (y > max())
      throw primecount_error("y must be <= FactorTable::max().");
    y = std::max<int64_t>(8, y);
    T T_MAX = std::numeric_limits<T>::max();
    init_factors(y, T_MAX, threads);
  }

  static maxint_t max()
  {
    maxint_t T_MAX = std::numeric_limits<T>::max();
    return ipow(T_MAX - 1, 2) - 1;
  }

  /// Get the least prime factor (lpf) of the number get_number(index).
  /// The result is different from lpf in some situations:
  /// 1) lpf(index) returns T_MAX if get_number(index) is a prime > T_MAX.
  /// 2) lpf(index) returns lpf minus one if mu(index) == 1.
  /// 3) lpf(index) returns 0 if get_number(index) has a squared prime factor.
  ///
  int64_t lpf(int64_t index) const
  {
    return factors_[index];
  }

  /// Get the Möbius function value of the number get_number(index).
  /// For performance reasons mu(index) == 0 is not supported.
  /// @pre mu(index) != 0 (i.e. lpf(index) != 0)
  ///
  int64_t mu(int64_t index) const
  {
    assert(lpf(index) != 0);
    return (factors_[index] & 1) ? -1 : 1;
  }

private:
  void init_factors(int64_t y, T T_MAX, int threads)
  {
    int64_t sqrty = isqrt(y);
    factors_.resize(get_index(y) + 1, T_MAX);
    factors_[0] = T_MAX - 1;

    int64_t thread_threshold = ipow(10, 7);
    threads = validate_threads(threads, y, thread_threshold);
    int64_t thread_interval = ceil_div(y, threads);

    #pragma omp parallel for num_threads(threads)
    for (int t = 0; t < threads; t++)
    {
      int64_t low = thread_interval * t;
      int64_t high = std::min(low + thread_interval, y);
      int64_t wheel_prime = get_number(1);
      primesieve::iterator iter(wheel_prime - 1, high);
      int64_t prime;

      while ((prime = iter.next_prime()) <= high)
      {
        // case 4), store prime
        if (prime > low &&
            prime < T_MAX)
          factors_[get_index(prime)] = (T) prime;

        int64_t i;
        int64_t min_index = 1;

        for (int64_t multiple = next_multiple(low, prime, min_index, &i);
             multiple <= high;
             multiple = prime * get_number(i++))
        {
          int64_t mi = get_index(multiple);
          // case 5), prime is the smallest factor of multiple
          if (factors_[mi] == T_MAX)
            factors_[mi] = (T) prime;
          // case 2) & 3), the least significant bit indicates whether
          // multiple has an even or odd number of prime factors
          else if (factors_[mi] != 0)
            factors_[mi] ^= 1;
        }

        if (prime <= sqrty)
        {
          min_index = 0;

          // case 1), set 0 if moebius(n) = 0
          for (int64_t multiple = next_multiple(low, prime * prime, min_index, &i);
               multiple <= high;
               multiple = prime * prime * get_number(i++))
            factors_[get_index(multiple)] = 0;
        }
      }
    }
  }

  /// Find the first multiple > low of prime which
  /// is not divisible by any prime <= 7.
  ///
  static int64_t next_multiple(int64_t low,
                               int64_t prime,
                               int64_t min_index,
                               int64_t* index)
  {
    int64_t quotient = (low / prime) + 1;
    int64_t i = std::max(min_index, get_index(quotient));
    int64_t multiple = prime * get_number(i++);

    for (; multiple <= low; i++)
      multiple = prime * get_number(i);

    *index = i;
    return multiple;
  }

  std::vector<T> factors_;
};

} // namespace

#endif
<commit_msg>15% speed improvement<commit_after>///
/// @file  FactorTable.hpp
/// @brief The FactorTable class is used to save memory. It combines
///        the lpf[n] (least prime factor) and mu[n] (Möbius function)
///        lookup tables into a single factors_[n] table which
///        furthermore only contains entries for numbers which are
///        not divisible by 2, 3, 5 and 7.
///        The factor table concept has first been devised and
///        implemented by Christian Bau in 2003.
///
///        FactorTable.lpf(index) is equal to (n = get_number(index)):
///
///         1) 0      if moebius(n) = 0
///         2) lpf    if !is_prime(n) && moebius(n) = -1
///         3) lpf-1  if !is_prime(n) && moebius(n) = 1
///         4) n      if  is_prime(n) && n < T_MAX
///         5) T_MAX  if  is_prime(n) && n > T_MAX
///
/// Copyright (C) 2016 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License. See the COPYING
/// file in the top level directory.
///

#ifndef FACTORTABLE_HPP
#define FACTORTABLE_HPP

#include <primecount.hpp>
#include <primecount-internal.hpp>
#include <primesieve.hpp>
#include <pmath.hpp>
#include <int128.hpp>

#include <algorithm>
#include <cassert>
#include <limits>
#include <stdint.h>
#include <vector>
#include <iostream>

#ifdef _OPENMP
  #include <omp.h>
#endif

namespace primecount {

/// AbstractFactorTable contains static FactorTable
/// data and it used to convert:
/// 1) A number into a FactorTable index.
/// 2) A FactorTable index into a number.
///
class AbstractFactorTable
{
protected:
  virtual ~AbstractFactorTable() { }

public:
  /// @pre number > 0
  static void to_index(int64_t* number)
  {
    assert(*number > 0);
    *number = get_index(*number);
  }

  /// @pre number > 0
  static int64_t get_index(uint64_t number)
  {
    assert(number > 0);
    uint64_t q = number / 210;
    uint64_t r = number % 210;
    return 48 * q + indexes_[r];
  }

  static int64_t get_number(uint64_t index)
  {
    uint64_t q = index / 48;
    uint64_t r = index % 48;
    return 210 * q + numbers_[r];
  }

private:
  static const uint8_t numbers_[48];
  static const  int8_t indexes_[210];
};

template <typename T>
class FactorTable : public AbstractFactorTable
{
public:
  /// Factor numbers <= y
  FactorTable(int64_t y, int threads)
  {
    if (y > max())
      throw primecount_error("y must be <= FactorTable::max().");
    y = std::max<int64_t>(8, y);
    T T_MAX = std::numeric_limits<T>::max();
    init_factors(y, T_MAX, threads);
  }

  static maxint_t max()
  {
    maxint_t T_MAX = std::numeric_limits<T>::max();
    return ipow(T_MAX - 1, 2) - 1;
  }

  /// Get the least prime factor (lpf) of the number get_number(index).
  /// The result is different from lpf in some situations:
  /// 1) lpf(index) returns T_MAX if get_number(index) is a prime > T_MAX.
  /// 2) lpf(index) returns lpf minus one if mu(index) == 1.
  /// 3) lpf(index) returns 0 if get_number(index) has a squared prime factor.
  ///
  int64_t lpf(int64_t index) const
  {
    return factors_[index];
  }

  /// Get the Möbius function value of the number get_number(index).
  /// For performance reasons mu(index) == 0 is not supported.
  /// @pre mu(index) != 0 (i.e. lpf(index) != 0)
  ///
  int64_t mu(int64_t index) const
  {
    assert(lpf(index) != 0);
    return (factors_[index] & 1) ? -1 : 1;
  }

private:
  void init_factors(int64_t y, T T_MAX, int threads)
  {
    int64_t sqrty = isqrt(y);
    factors_.resize(get_index(y) + 1, T_MAX);
    factors_[0] = T_MAX - 1;

    int64_t thread_threshold = ipow(10, 7);
    threads = validate_threads(threads, y, thread_threshold);
    int64_t thread_interval = ceil_div(y, threads);

    #pragma omp parallel for num_threads(threads)
    for (int t = 0; t < threads; t++)
    {
      int64_t low = thread_interval * t;
      int64_t high = std::min(low + thread_interval, y);
      int64_t wheel_prime = get_number(1);
      primesieve::iterator iter(wheel_prime - 1, high);
      int64_t prime, i;

      while ((prime = iter.next_prime()) <= high)
      {
        // case 4), store prime
        if (prime > low && prime < T_MAX)
          factors_[get_index(prime)] = (T) prime;

        int64_t multiple = next_multiple(low, prime, 1, &i);

        // no more work todo
        if (prime >= T_MAX && multiple > high)
          break;

        for (; multiple <= high; multiple = prime * get_number(i++))
        {
          int64_t mi = get_index(multiple);
          // case 5), prime is the smallest factor of multiple
          if (factors_[mi] == T_MAX)
            factors_[mi] = (T) prime;
          // case 2) & 3), the least significant bit indicates
          // whether multiple has an even (0) or odd (1)
          // number of prime factors
          else if (factors_[mi] != 0)
            factors_[mi] ^= 1;
        }

        if (prime <= sqrty)
        {
          int64_t square = prime * prime;
          multiple = next_multiple(low, square, 0, &i);

          // case 1), set 0 if moebius(n) = 0
          for (; multiple <= high; multiple = square * get_number(i++))
            factors_[get_index(multiple)] = 0;
        }
      }
    }
  }

  /// Find the first multiple > low of prime which
  /// is not divisible by any prime <= 7.
  ///
  static int64_t next_multiple(int64_t low,
                               int64_t prime,
                               int64_t min_index,
                               int64_t* index)
  {
    int64_t quotient = (low / prime) + 1;
    int64_t i = std::max(min_index, get_index(quotient));
    int64_t multiple = prime * get_number(i++);

    for (; multiple <= low; i++)
      multiple = prime * get_number(i);

    *index = i;
    return multiple;
  }

  std::vector<T> factors_;
};

} // namespace

#endif
<|endoftext|>


<commit_before>#pragma once

namespace OpenSofa {

class ByteInputStream {
public:
  size_t read(uint8_t* buf, size_t count);
  void close();
};

class ByteOutputStream {
public:
  int write(const uint8_t* buf, size_t count);
  void close();
};

}
<commit_msg>Remove InputStream file(s)<commit_after><|endoftext|>


<commit_before>class Solution {
public:
    int firstMissingPositive(vector<int>& nums) {
        int n = nums.size();
        int i = 0;
        while(i < n) {
            if(nums[i] >= 1 && nums[i] <= n && nums[i] != nums[nums[i]-1]) {
                swap(nums[i], nums[nums[i]-1]);
            } else {
                ++i;
            }
        }
        for(i = 0; i < n; i++) {
            if(nums[i] != i+1) return i+1;
        }
        return n+1;
    }
};<commit_msg>Update 041-FirstMissingPositive.cpp<commit_after>/*
 * Array
 *
 */

class Solution {
public:
    int firstMissingPositive(vector<int>& nums) {
        int n = nums.size();
        int i = 0;
        while(i < n) {
            if(nums[i] >= 1 && nums[i] <= n && nums[i] != nums[nums[i]-1]) {
                swap(nums[i], nums[nums[i]-1]);
            } else {
                ++i;
            }
        }
        for(i = 0; i < n; i++) {
            if(nums[i] != i+1) return i+1;
        }
        return n+1;
    }
};

// Conclusion:
// This one is interesting!

<|endoftext|>


<commit_before>// Copyright (c) 2009 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 "chrome/browser/views/options/passwords_page_view.h"

#include "app/l10n_util.h"
#include "base/string_util.h"
#include "chrome/browser/profile.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/pref_service.h"
#include "grit/generated_resources.h"
#include "views/background.h"
#include "views/controls/button/native_button.h"
#include "views/grid_layout.h"
#include "views/standard_layout.h"

using views::ColumnSet;
using views::GridLayout;

///////////////////////////////////////////////////////////////////////////////
// MultiLabelButtons
MultiLabelButtons::MultiLabelButtons(views::ButtonListener* listener,
                                     const std::wstring& label,
                                     const std::wstring& alt_label)
    : NativeButton(listener, label),
      label_(label),
      alt_label_(alt_label),
      pref_size_(-1, -1) {
}

gfx::Size MultiLabelButtons::GetPreferredSize() {
  if (pref_size_.width() == -1 && pref_size_.height() == -1) {
    // Let's compute our preferred size.
    std::wstring current_label = label();
    SetLabel(label_);
    pref_size_ = NativeButton::GetPreferredSize();
    SetLabel(alt_label_);
    gfx::Size alt_pref_size = NativeButton::GetPreferredSize();
    // Revert to the original label.
    SetLabel(current_label);
    pref_size_.SetSize(std::max(pref_size_.width(), alt_pref_size.width()),
                       std::max(pref_size_.height(), alt_pref_size.height()));
  }
  return gfx::Size(pref_size_.width(), pref_size_.height());
}

///////////////////////////////////////////////////////////////////////////////
// PasswordsTableModel, public
PasswordsTableModel::PasswordsTableModel(Profile* profile)
    : observer_(NULL),
      row_count_observer_(NULL),
      pending_login_query_(NULL),
      saved_signons_cleanup_(&saved_signons_),
      profile_(profile) {
  DCHECK(profile && profile->GetWebDataService(Profile::EXPLICIT_ACCESS));
}

PasswordsTableModel::~PasswordsTableModel() {
  CancelLoginsQuery();
}

int PasswordsTableModel::RowCount() {
  return static_cast<int>(saved_signons_.size());
}

std::wstring PasswordsTableModel::GetText(int row,
                                          int col_id) {
  switch (col_id) {
    case IDS_PASSWORDS_PAGE_VIEW_SITE_COLUMN: {  // Site.
      const std::wstring& url = saved_signons_[row]->display_url.display_url();
      // Force URL to have LTR directionality.
      if (l10n_util::GetTextDirection() == l10n_util::RIGHT_TO_LEFT) {
        std::wstring localized_url = url;
        l10n_util::WrapStringWithLTRFormatting(&localized_url);
        return localized_url;
      }
      return url;
    }
    case IDS_PASSWORDS_PAGE_VIEW_USERNAME_COLUMN: {  // Username.
      std::wstring username = GetPasswordFormAt(row)->username_value;
      l10n_util::AdjustStringForLocaleDirection(username, &username);
      return username;
    }
    default:
      NOTREACHED() << "Invalid column.";
      return std::wstring();
  }
}

int PasswordsTableModel::CompareValues(int row1, int row2,
                                       int column_id) {
  if (column_id == IDS_PASSWORDS_PAGE_VIEW_SITE_COLUMN) {
    return saved_signons_[row1]->display_url.Compare(
        saved_signons_[row2]->display_url, GetCollator());
  }
  return TableModel::CompareValues(row1, row2, column_id);
}

void PasswordsTableModel::SetObserver(
    views::TableModelObserver* observer) {
  observer_ = observer;
}

void PasswordsTableModel::GetAllSavedLoginsForProfile() {
  DCHECK(!pending_login_query_);
  pending_login_query_ = web_data_service()->GetAllAutofillableLogins(this);
}

void PasswordsTableModel::OnWebDataServiceRequestDone(
    WebDataService::Handle h,
    const WDTypedResult* result) {
  DCHECK_EQ(pending_login_query_, h);
  pending_login_query_ = NULL;

  if (!result)
    return;

  DCHECK(result->GetType() == PASSWORD_RESULT);

  // Get the result from the database into a useable form.
  const WDResult<std::vector<PasswordForm*> >* r =
      static_cast<const WDResult<std::vector<PasswordForm*> >*>(result);
  std::vector<PasswordForm*> rows = r->GetValue();
  STLDeleteElements<PasswordRows>(&saved_signons_);
  saved_signons_.resize(rows.size(), NULL);
  std::wstring languages =
      profile_->GetPrefs()->GetString(prefs::kAcceptLanguages);
  for (size_t i = 0; i < rows.size(); ++i) {
    saved_signons_[i] = new PasswordRow(
        gfx::SortedDisplayURL(rows[i]->origin, languages), rows[i]);
  }
  if (observer_)
    observer_->OnModelChanged();
  if (row_count_observer_)
    row_count_observer_->OnRowCountChanged(RowCount());
}

PasswordForm* PasswordsTableModel::GetPasswordFormAt(int row) {
  DCHECK(row >= 0 && row < RowCount());
  return saved_signons_[row]->form.get();
}

void PasswordsTableModel::ForgetAndRemoveSignon(int row) {
  DCHECK(row >= 0 && row < RowCount());
  PasswordRows::iterator target_iter = saved_signons_.begin() + row;
  // Remove from DB, memory, and vector.
  PasswordRow* password_row = *target_iter;
  web_data_service()->RemoveLogin(*(password_row->form.get()));
  delete password_row;
  saved_signons_.erase(target_iter);
  if (observer_)
    observer_->OnItemsRemoved(row, 1);
  if (row_count_observer_)
    row_count_observer_->OnRowCountChanged(RowCount());
}

void PasswordsTableModel::ForgetAndRemoveAllSignons() {
  PasswordRows::iterator iter = saved_signons_.begin();
  while (iter != saved_signons_.end()) {
    // Remove from DB, memory, and vector.
    PasswordRow* row = *iter;
    web_data_service()->RemoveLogin(*(row->form.get()));
    delete row;
    iter = saved_signons_.erase(iter);
  }
  if (observer_)
    observer_->OnModelChanged();
  if (row_count_observer_)
    row_count_observer_->OnRowCountChanged(RowCount());
}

///////////////////////////////////////////////////////////////////////////////
// PasswordsTableModel, private
void PasswordsTableModel::CancelLoginsQuery() {
  if (pending_login_query_) {
    web_data_service()->CancelRequest(pending_login_query_);
    pending_login_query_ = NULL;
  }
}

///////////////////////////////////////////////////////////////////////////////
// PasswordsPageView, public
PasswordsPageView::PasswordsPageView(Profile* profile)
    : OptionsPageView(profile),
      show_button_(
          this,
          l10n_util::GetString(IDS_PASSWORDS_PAGE_VIEW_SHOW_BUTTON),
          l10n_util::GetString(IDS_PASSWORDS_PAGE_VIEW_HIDE_BUTTON)),
      remove_button_(this, l10n_util::GetString(
          IDS_PASSWORDS_PAGE_VIEW_REMOVE_BUTTON)),
      remove_all_button_(this, l10n_util::GetString(
          IDS_PASSWORDS_PAGE_VIEW_REMOVE_ALL_BUTTON)),
      table_model_(profile),
      table_view_(NULL) {
}

void PasswordsPageView::OnSelectionChanged() {
  bool has_selection = table_view_->SelectedRowCount() > 0;
  remove_button_.SetEnabled(has_selection);
  // Reset the password related views.
  show_button_.SetLabel(
      l10n_util::GetString(IDS_PASSWORDS_PAGE_VIEW_SHOW_BUTTON));
  show_button_.SetEnabled(has_selection);
  password_label_.SetText(std::wstring());
}

void PasswordsPageView::ButtonPressed(views::Button* sender) {
  // Close will result in our destruction.
  if (sender == &remove_all_button_) {
    table_model_.ForgetAndRemoveAllSignons();
    return;
  }

  // The following require a selection (and only one, since table is single-
  // select only).
  views::TableSelectionIterator iter = table_view_->SelectionBegin();
  int row = *iter;
  PasswordForm* selected = table_model_.GetPasswordFormAt(row);
  DCHECK(++iter == table_view_->SelectionEnd());

  if (sender == &remove_button_) {
    table_model_.ForgetAndRemoveSignon(row);
  } else if (sender == &show_button_) {
    if (password_label_.GetText().length() == 0) {
      password_label_.SetText(selected->password_value);
      show_button_.SetLabel(
          l10n_util::GetString(IDS_PASSWORDS_PAGE_VIEW_HIDE_BUTTON));
    } else {
      password_label_.SetText(L"");
      show_button_.SetLabel(
          l10n_util::GetString(IDS_PASSWORDS_PAGE_VIEW_SHOW_BUTTON));
    }
  } else {
    NOTREACHED() << "Invalid button.";
  }
}

void PasswordsPageView::OnRowCountChanged(size_t rows) {
  remove_all_button_.SetEnabled(rows > 0);
}

///////////////////////////////////////////////////////////////////////////////
// PasswordsPageView, protected
void PasswordsPageView::InitControlLayout() {
  SetupButtonsAndLabels();
  SetupTable();

  // Do the layout thing.
  const int top_column_set_id = 0;
  const int lower_column_set_id = 1;
  GridLayout* layout = CreatePanelGridLayout(this);
  SetLayoutManager(layout);

  // Design the grid.
  ColumnSet* column_set = layout->AddColumnSet(top_column_set_id);
  column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1,
                        GridLayout::FIXED, 300, 0);
  column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing);
  column_set->AddColumn(GridLayout::FILL, GridLayout::LEADING, 0,
                        GridLayout::USE_PREF, 0, 0);

  column_set = layout->AddColumnSet(lower_column_set_id);
  column_set->AddColumn(GridLayout::FILL, GridLayout::LEADING, 0,
                        GridLayout::USE_PREF, 0, 0);
  column_set->AddPaddingColumn(1, kRelatedControlHorizontalSpacing);
  column_set->AddColumn(GridLayout::FILL, GridLayout::LEADING, 0,
                        GridLayout::USE_PREF, 0, 0);
  column_set->LinkColumnSizes(0, 2, -1);

  // Fill the grid.
  layout->StartRow(0.05f, top_column_set_id);
  layout->AddView(table_view_, 1, 4);
  layout->AddView(&remove_button_);
  layout->StartRow(0.05f, top_column_set_id);
  layout->SkipColumns(1);
  layout->AddView(&remove_all_button_);
  layout->StartRow(0.05f, top_column_set_id);
  layout->SkipColumns(1);
  layout->AddView(&show_button_);
  layout->StartRow(0.80f, top_column_set_id);
  layout->SkipColumns(1);
  layout->AddView(&password_label_);
  layout->AddPaddingRow(0, kRelatedControlVerticalSpacing);

  // Ask the database for saved password data.
  table_model_.GetAllSavedLoginsForProfile();
}

///////////////////////////////////////////////////////////////////////////////
// PasswordsPageView, private
void PasswordsPageView::SetupButtonsAndLabels() {
  // Disable all buttons in the first place.
  show_button_.SetParentOwned(false);
  show_button_.SetEnabled(false);

  remove_button_.SetParentOwned(false);
  remove_button_.SetEnabled(false);

  remove_all_button_.SetParentOwned(false);
  remove_all_button_.SetEnabled(false);

  password_label_.SetParentOwned(false);
}

void PasswordsPageView::SetupTable() {
  // Tell the table model we are concern about how many rows it has.
  table_model_.set_row_count_observer(this);

  // Creates the different columns for the table.
  // The float resize values are the result of much tinkering.
  std::vector<views::TableColumn> columns;
  columns.push_back(views::TableColumn(IDS_PASSWORDS_PAGE_VIEW_SITE_COLUMN,
                                       views::TableColumn::LEFT, -1, 0.55f));
  columns.back().sortable = true;
  columns.push_back(views::TableColumn(
      IDS_PASSWORDS_PAGE_VIEW_USERNAME_COLUMN, views::TableColumn::RIGHT,
      -1, 0.37f));
  columns.back().sortable = true;
  table_view_ = new views::TableView(&table_model_, columns, views::TEXT_ONLY,
                                     true, true, true);
  // Make the table initially sorted by host.
  views::TableView::SortDescriptors sort;
  sort.push_back(views::TableView::SortDescriptor(
      IDS_PASSWORDS_PAGE_VIEW_SITE_COLUMN, true));
  table_view_->SetSortDescriptors(sort);
  table_view_->SetObserver(this);
}
<commit_msg>Fix regression caused by gfx::Size no longer accepting negative  dimensions.<commit_after>// Copyright (c) 2009 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 "chrome/browser/views/options/passwords_page_view.h"

#include "app/l10n_util.h"
#include "base/string_util.h"
#include "chrome/browser/profile.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/pref_service.h"
#include "grit/generated_resources.h"
#include "views/background.h"
#include "views/controls/button/native_button.h"
#include "views/grid_layout.h"
#include "views/standard_layout.h"

using views::ColumnSet;
using views::GridLayout;

///////////////////////////////////////////////////////////////////////////////
// MultiLabelButtons
MultiLabelButtons::MultiLabelButtons(views::ButtonListener* listener,
                                     const std::wstring& label,
                                     const std::wstring& alt_label)
    : NativeButton(listener, label),
      label_(label),
      alt_label_(alt_label) {
}

gfx::Size MultiLabelButtons::GetPreferredSize() {
  if (pref_size_.IsEmpty()) {
    // Let's compute our preferred size.
    std::wstring current_label = label();
    SetLabel(label_);
    pref_size_ = NativeButton::GetPreferredSize();
    SetLabel(alt_label_);
    gfx::Size alt_pref_size = NativeButton::GetPreferredSize();
    // Revert to the original label.
    SetLabel(current_label);
    pref_size_.SetSize(std::max(pref_size_.width(), alt_pref_size.width()),
                       std::max(pref_size_.height(), alt_pref_size.height()));
  }
  return gfx::Size(pref_size_.width(), pref_size_.height());
}

///////////////////////////////////////////////////////////////////////////////
// PasswordsTableModel, public
PasswordsTableModel::PasswordsTableModel(Profile* profile)
    : observer_(NULL),
      row_count_observer_(NULL),
      pending_login_query_(NULL),
      saved_signons_cleanup_(&saved_signons_),
      profile_(profile) {
  DCHECK(profile && profile->GetWebDataService(Profile::EXPLICIT_ACCESS));
}

PasswordsTableModel::~PasswordsTableModel() {
  CancelLoginsQuery();
}

int PasswordsTableModel::RowCount() {
  return static_cast<int>(saved_signons_.size());
}

std::wstring PasswordsTableModel::GetText(int row,
                                          int col_id) {
  switch (col_id) {
    case IDS_PASSWORDS_PAGE_VIEW_SITE_COLUMN: {  // Site.
      const std::wstring& url = saved_signons_[row]->display_url.display_url();
      // Force URL to have LTR directionality.
      if (l10n_util::GetTextDirection() == l10n_util::RIGHT_TO_LEFT) {
        std::wstring localized_url = url;
        l10n_util::WrapStringWithLTRFormatting(&localized_url);
        return localized_url;
      }
      return url;
    }
    case IDS_PASSWORDS_PAGE_VIEW_USERNAME_COLUMN: {  // Username.
      std::wstring username = GetPasswordFormAt(row)->username_value;
      l10n_util::AdjustStringForLocaleDirection(username, &username);
      return username;
    }
    default:
      NOTREACHED() << "Invalid column.";
      return std::wstring();
  }
}

int PasswordsTableModel::CompareValues(int row1, int row2,
                                       int column_id) {
  if (column_id == IDS_PASSWORDS_PAGE_VIEW_SITE_COLUMN) {
    return saved_signons_[row1]->display_url.Compare(
        saved_signons_[row2]->display_url, GetCollator());
  }
  return TableModel::CompareValues(row1, row2, column_id);
}

void PasswordsTableModel::SetObserver(
    views::TableModelObserver* observer) {
  observer_ = observer;
}

void PasswordsTableModel::GetAllSavedLoginsForProfile() {
  DCHECK(!pending_login_query_);
  pending_login_query_ = web_data_service()->GetAllAutofillableLogins(this);
}

void PasswordsTableModel::OnWebDataServiceRequestDone(
    WebDataService::Handle h,
    const WDTypedResult* result) {
  DCHECK_EQ(pending_login_query_, h);
  pending_login_query_ = NULL;

  if (!result)
    return;

  DCHECK(result->GetType() == PASSWORD_RESULT);

  // Get the result from the database into a useable form.
  const WDResult<std::vector<PasswordForm*> >* r =
      static_cast<const WDResult<std::vector<PasswordForm*> >*>(result);
  std::vector<PasswordForm*> rows = r->GetValue();
  STLDeleteElements<PasswordRows>(&saved_signons_);
  saved_signons_.resize(rows.size(), NULL);
  std::wstring languages =
      profile_->GetPrefs()->GetString(prefs::kAcceptLanguages);
  for (size_t i = 0; i < rows.size(); ++i) {
    saved_signons_[i] = new PasswordRow(
        gfx::SortedDisplayURL(rows[i]->origin, languages), rows[i]);
  }
  if (observer_)
    observer_->OnModelChanged();
  if (row_count_observer_)
    row_count_observer_->OnRowCountChanged(RowCount());
}

PasswordForm* PasswordsTableModel::GetPasswordFormAt(int row) {
  DCHECK(row >= 0 && row < RowCount());
  return saved_signons_[row]->form.get();
}

void PasswordsTableModel::ForgetAndRemoveSignon(int row) {
  DCHECK(row >= 0 && row < RowCount());
  PasswordRows::iterator target_iter = saved_signons_.begin() + row;
  // Remove from DB, memory, and vector.
  PasswordRow* password_row = *target_iter;
  web_data_service()->RemoveLogin(*(password_row->form.get()));
  delete password_row;
  saved_signons_.erase(target_iter);
  if (observer_)
    observer_->OnItemsRemoved(row, 1);
  if (row_count_observer_)
    row_count_observer_->OnRowCountChanged(RowCount());
}

void PasswordsTableModel::ForgetAndRemoveAllSignons() {
  PasswordRows::iterator iter = saved_signons_.begin();
  while (iter != saved_signons_.end()) {
    // Remove from DB, memory, and vector.
    PasswordRow* row = *iter;
    web_data_service()->RemoveLogin(*(row->form.get()));
    delete row;
    iter = saved_signons_.erase(iter);
  }
  if (observer_)
    observer_->OnModelChanged();
  if (row_count_observer_)
    row_count_observer_->OnRowCountChanged(RowCount());
}

///////////////////////////////////////////////////////////////////////////////
// PasswordsTableModel, private
void PasswordsTableModel::CancelLoginsQuery() {
  if (pending_login_query_) {
    web_data_service()->CancelRequest(pending_login_query_);
    pending_login_query_ = NULL;
  }
}

///////////////////////////////////////////////////////////////////////////////
// PasswordsPageView, public
PasswordsPageView::PasswordsPageView(Profile* profile)
    : OptionsPageView(profile),
      show_button_(
          this,
          l10n_util::GetString(IDS_PASSWORDS_PAGE_VIEW_SHOW_BUTTON),
          l10n_util::GetString(IDS_PASSWORDS_PAGE_VIEW_HIDE_BUTTON)),
      remove_button_(this, l10n_util::GetString(
          IDS_PASSWORDS_PAGE_VIEW_REMOVE_BUTTON)),
      remove_all_button_(this, l10n_util::GetString(
          IDS_PASSWORDS_PAGE_VIEW_REMOVE_ALL_BUTTON)),
      table_model_(profile),
      table_view_(NULL) {
}

void PasswordsPageView::OnSelectionChanged() {
  bool has_selection = table_view_->SelectedRowCount() > 0;
  remove_button_.SetEnabled(has_selection);
  // Reset the password related views.
  show_button_.SetLabel(
      l10n_util::GetString(IDS_PASSWORDS_PAGE_VIEW_SHOW_BUTTON));
  show_button_.SetEnabled(has_selection);
  password_label_.SetText(std::wstring());
}

void PasswordsPageView::ButtonPressed(views::Button* sender) {
  // Close will result in our destruction.
  if (sender == &remove_all_button_) {
    table_model_.ForgetAndRemoveAllSignons();
    return;
  }

  // The following require a selection (and only one, since table is single-
  // select only).
  views::TableSelectionIterator iter = table_view_->SelectionBegin();
  int row = *iter;
  PasswordForm* selected = table_model_.GetPasswordFormAt(row);
  DCHECK(++iter == table_view_->SelectionEnd());

  if (sender == &remove_button_) {
    table_model_.ForgetAndRemoveSignon(row);
  } else if (sender == &show_button_) {
    if (password_label_.GetText().length() == 0) {
      password_label_.SetText(selected->password_value);
      show_button_.SetLabel(
          l10n_util::GetString(IDS_PASSWORDS_PAGE_VIEW_HIDE_BUTTON));
    } else {
      password_label_.SetText(L"");
      show_button_.SetLabel(
          l10n_util::GetString(IDS_PASSWORDS_PAGE_VIEW_SHOW_BUTTON));
    }
  } else {
    NOTREACHED() << "Invalid button.";
  }
}

void PasswordsPageView::OnRowCountChanged(size_t rows) {
  remove_all_button_.SetEnabled(rows > 0);
}

///////////////////////////////////////////////////////////////////////////////
// PasswordsPageView, protected
void PasswordsPageView::InitControlLayout() {
  SetupButtonsAndLabels();
  SetupTable();

  // Do the layout thing.
  const int top_column_set_id = 0;
  const int lower_column_set_id = 1;
  GridLayout* layout = CreatePanelGridLayout(this);
  SetLayoutManager(layout);

  // Design the grid.
  ColumnSet* column_set = layout->AddColumnSet(top_column_set_id);
  column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1,
                        GridLayout::FIXED, 300, 0);
  column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing);
  column_set->AddColumn(GridLayout::FILL, GridLayout::LEADING, 0,
                        GridLayout::USE_PREF, 0, 0);

  column_set = layout->AddColumnSet(lower_column_set_id);
  column_set->AddColumn(GridLayout::FILL, GridLayout::LEADING, 0,
                        GridLayout::USE_PREF, 0, 0);
  column_set->AddPaddingColumn(1, kRelatedControlHorizontalSpacing);
  column_set->AddColumn(GridLayout::FILL, GridLayout::LEADING, 0,
                        GridLayout::USE_PREF, 0, 0);
  column_set->LinkColumnSizes(0, 2, -1);

  // Fill the grid.
  layout->StartRow(0.05f, top_column_set_id);
  layout->AddView(table_view_, 1, 4);
  layout->AddView(&remove_button_);
  layout->StartRow(0.05f, top_column_set_id);
  layout->SkipColumns(1);
  layout->AddView(&remove_all_button_);
  layout->StartRow(0.05f, top_column_set_id);
  layout->SkipColumns(1);
  layout->AddView(&show_button_);
  layout->StartRow(0.80f, top_column_set_id);
  layout->SkipColumns(1);
  layout->AddView(&password_label_);
  layout->AddPaddingRow(0, kRelatedControlVerticalSpacing);

  // Ask the database for saved password data.
  table_model_.GetAllSavedLoginsForProfile();
}

///////////////////////////////////////////////////////////////////////////////
// PasswordsPageView, private
void PasswordsPageView::SetupButtonsAndLabels() {
  // Disable all buttons in the first place.
  show_button_.SetParentOwned(false);
  show_button_.SetEnabled(false);

  remove_button_.SetParentOwned(false);
  remove_button_.SetEnabled(false);

  remove_all_button_.SetParentOwned(false);
  remove_all_button_.SetEnabled(false);

  password_label_.SetParentOwned(false);
}

void PasswordsPageView::SetupTable() {
  // Tell the table model we are concern about how many rows it has.
  table_model_.set_row_count_observer(this);

  // Creates the different columns for the table.
  // The float resize values are the result of much tinkering.
  std::vector<views::TableColumn> columns;
  columns.push_back(views::TableColumn(IDS_PASSWORDS_PAGE_VIEW_SITE_COLUMN,
                                       views::TableColumn::LEFT, -1, 0.55f));
  columns.back().sortable = true;
  columns.push_back(views::TableColumn(
      IDS_PASSWORDS_PAGE_VIEW_USERNAME_COLUMN, views::TableColumn::RIGHT,
      -1, 0.37f));
  columns.back().sortable = true;
  table_view_ = new views::TableView(&table_model_, columns, views::TEXT_ONLY,
                                     true, true, true);
  // Make the table initially sorted by host.
  views::TableView::SortDescriptors sort;
  sort.push_back(views::TableView::SortDescriptor(
      IDS_PASSWORDS_PAGE_VIEW_SITE_COLUMN, true));
  table_view_->SetSortDescriptors(sort);
  table_view_->SetObserver(this);
}
<|endoftext|>


<commit_before>#ifndef MTL_BINARY_STREAM
#define MTL_BINARY_STREAM

#include <sstream>
#include <type_traits>

namespace mtl
{
	class binary_stream
	{
	public:

		void seekp(std::streampos p)
		{
			_ss.seekp(p);
		}

		std::streampos tellp()
		{
			return _ss.tellp();
		}

		void seekg(std::streampos p)
		{
			_ss.seekg(p);
		}

		std::streampos tellg()
		{
			return _ss.tellg();
		}

		binary_stream& write(const char* s, std::streamsize n)
		{
			_ss.write(s, n);
			return *this;
		}

		binary_stream& read(char* s, std::streamsize n)
		{
			_ss.read(s, n);
			return *this;
		}
	private:
		std::stringstream _ss;
	};

}

//arithmethic (TODO endianess)
template<typename T>
typename std::enable_if< std::is_arithmetic<T>::value, mtl::binary_stream>::type&
operator >> (mtl::binary_stream& ss, T& t)
{
	ss.read((char*)&t, sizeof(T));
	return ss;
}

template<typename T>
typename std::enable_if< std::is_arithmetic<T>::value, mtl::binary_stream>::type&
operator << (mtl::binary_stream& ss, const T& t)
{
	ss.write((char*)&t, sizeof(T));
	return ss;
}

//std::string
mtl::binary_stream& operator >> (mtl::binary_stream& ss, std::string& t)
{
	std::size_t size;
	ss >> size;
	t.resize(size);

	for (auto &c : t)
		ss >> c;
	return ss;
}

mtl::binary_stream& operator << (mtl::binary_stream& ss, std::string& t)
{
	std::size_t size = t.size();
	ss << size;
	ss.write((char*)t.c_str(), size);
	return ss;
}

//const char * (C style string)
mtl::binary_stream& operator << (mtl::binary_stream& ss, const char* str)
{
	std::size_t size = strlen(str);
	ss << size;
	ss.write(str, size);
	return ss;
}

#endif<commit_msg>added str to binary_stream<commit_after>#ifndef MTL_BINARY_STREAM
#define MTL_BINARY_STREAM

#include <sstream>
#include <type_traits>

namespace mtl
{
	class binary_stream
	{
	public:

		void seekp(std::streampos p)
		{
			_ss.seekp(p);
		}

		std::streampos tellp()
		{
			return _ss.tellp();
		}

		void seekg(std::streampos p)
		{
			_ss.seekg(p);
		}

		std::streampos tellg()
		{
			return _ss.tellg();
		}

		binary_stream& write(const char* s, std::streamsize n)
		{
			_ss.write(s, n);
			return *this;
		}

		binary_stream& read(char* s, std::streamsize n)
		{
			_ss.read(s, n);
			return *this;
		}

		auto str()
		{
			return _ss.str();
		}
	private:
		std::stringstream _ss;
	};

}

//arithmethic (TODO endianess)
template<typename T>
typename std::enable_if< std::is_arithmetic<T>::value, mtl::binary_stream>::type&
operator >> (mtl::binary_stream& ss, T& t)
{
	ss.read((char*)&t, sizeof(T));
	return ss;
}

template<typename T>
typename std::enable_if< std::is_arithmetic<T>::value, mtl::binary_stream>::type&
operator << (mtl::binary_stream& ss, const T& t)
{
	ss.write((char*)&t, sizeof(T));
	return ss;
}

//std::string
mtl::binary_stream& operator >> (mtl::binary_stream& ss, std::string& t)
{
	std::size_t size;
	ss >> size;
	t.resize(size);

	for (auto &c : t)
		ss >> c;
	return ss;
}

mtl::binary_stream& operator << (mtl::binary_stream& ss, std::string& t)
{
	std::size_t size = t.size();
	ss << size;
	ss.write((char*)t.c_str(), size);
	return ss;
}

//const char * (C style string)
mtl::binary_stream& operator << (mtl::binary_stream& ss, const char* str)
{
	std::size_t size = strlen(str);
	ss << size;
	ss.write(str, size);
	return ss;
}

#endif<|endoftext|>


<commit_before>/**
 * @file		compmanager.cpp
 * @brief		COSSB component manager
 * @author		Byunghun Hwang<bhhwang@nsynapse.com>
 * @date 		2015. 6. 21
 * @details
 */

#include "manager.hpp"
#include "container.hpp"
#include "broker.hpp"
#include "driver.hpp"
#include <list>

using namespace std;

namespace cossb {
namespace manager {

component_manager::component_manager()
{

}

component_manager::~component_manager()
{
	stop();
	cossb_component_container->destroy();
}

bool component_manager::install(const char* component_name)
{
	if(cossb_component_container->add(component_name, new driver::component_driver(component_name)))
	{
		cossb_component_container->get_driver(component_name)->setup();
		return true;
	}
	return false;
}

bool component_manager::uninstall(const char* component_name)
{
	if(cossb_component_container->exist(component_name))
	{
		cossb_component_container->get_driver(component_name)->stop();
		cossb_component_container->remove(component_name);
		return true;
	}
	return false;
}

bool component_manager::run(const char* component_name)
{
	if(cossb_component_container->exist(component_name))
	{
		cossb_component_container->get_driver(component_name)->run();
		return true;
	}
	return false;
}

bool component_manager::run()
{
	for(auto comp:cossb_component_container->_container) {
		this->run(comp.first.c_str());
	}
	return true;
}

bool component_manager::stop(const char* component_name)
{
	if(cossb_component_container->exist(component_name))
		cossb_component_container->get_driver(component_name)->stop();
	return true;
}

bool component_manager::stop()
{
	for(auto comp:cossb_component_container->_container) {
		this->stop(comp.first.c_str());
	}
	return true;
}

int component_manager::count()
{
	return 0;
}

} /* namespace manager */
} /* namespace cossb */
<commit_msg>edit stop function<commit_after>/**
 * @file		compmanager.cpp
 * @brief		COSSB component manager
 * @author		Byunghun Hwang<bhhwang@nsynapse.com>
 * @date 		2015. 6. 21
 * @details
 */

#include "manager.hpp"
#include "container.hpp"
#include "broker.hpp"
#include "driver.hpp"
#include <list>

using namespace std;

namespace cossb {
namespace manager {

component_manager::component_manager()
{

}

component_manager::~component_manager()
{
	stop();
	cossb_component_container->destroy();
}

bool component_manager::install(const char* component_name)
{
	if(cossb_component_container->add(component_name, new driver::component_driver(component_name)))
	{
		cossb_component_container->get_driver(component_name)->setup();
		return true;
	}
	return false;
}

bool component_manager::uninstall(const char* component_name)
{
	if(cossb_component_container->exist(component_name))
	{
		cossb_component_container->get_driver(component_name)->stop();
		cossb_component_container->remove(component_name);
		return true;
	}
	return false;
}

bool component_manager::run(const char* component_name)
{
	if(cossb_component_container->exist(component_name))
	{
		cossb_component_container->get_driver(component_name)->run();
		return true;
	}
	return false;
}

bool component_manager::run()
{
	for(auto comp:cossb_component_container->_container) {
		this->run(comp.first.c_str());
	}
	return true;
}

bool component_manager::stop(const char* component_name)
{
	if(cossb_component_container->exist(component_name)) {
		cossb_component_container->get_driver(component_name)->stop();
		return true;
	}
	return false;
}

bool component_manager::stop()
{
	for(auto comp:cossb_component_container->_container) {
		this->stop(comp.first.c_str());
	}
	return true;
}

int component_manager::count()
{
	return 0;
}

} /* namespace manager */
} /* namespace cossb */
<|endoftext|>


<commit_before>//=======================================================================
// Copyright (c) 2014-2016 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

/*!
 * \file
 * \brief Contains some global functions.
*/

#pragma once

#include "etl/temporary.hpp"

#include "etl/impl/decomposition.hpp"

namespace etl {

/*!
 * \brief Indicates if the given expression is a square matrix or not.
 * \param expr The expression to test
 * \return true if the given expression is a square matrix, false otherwise.
 */
template <typename E>
bool is_square(E&& expr) {
    return decay_traits<E>::dimensions() == 2 && etl::dim<0>(expr) == etl::dim<1>(expr);
}

/*!
 * \brief Indicates if the given expression is a real matrix or not.
 * \param expr The expression to test
 * \return true if the given expression is a real matrix, false otherwise.
 */
template <typename E>
bool is_real_matrix(E&& expr) {
    cpp_unused(expr);
    return !is_complex<E>::value;
}

/*!
 * \brief Indicates if the given expression is a complex matrix or not.
 * \param expr The expression to test
 * \return true if the given expression is a complex matrix, false otherwise.
 */
template <typename E>
bool is_complex_matrix(E&& expr) {
    cpp_unused(expr);
    return is_complex<E>::value;
}

/*!
 * \brief Indicates if the given expression is a rectangular matrix or not.
 * \param expr The expression to test
 * \return true if the given expression is a rectangular matrix, false otherwise.
 */
template <typename E>
bool is_rectangular(E&& expr) {
    return decay_traits<E>::dimensions() == 2 && etl::dim<0>(expr) != etl::dim<1>(expr);
}

/*!
 * \brief Indicates if the given expression contains sub matrices that are square.
 * \param expr The expression to test
 * \return true if the given expression contains sub matrices that are square, false otherwise.
 */
template <typename E>
bool is_sub_square(E&& expr) {
    return decay_traits<E>::dimensions() == 3 && etl::dim<1>(expr) == etl::dim<2>(expr);
}

/*!
 * \brief Indicates if the given expression contains sub matrices that are rectangular.
 * \param expr The expression to test
 * \return true if the given expression contains sub matrices that are rectangular, false otherwise.
 */
template <typename E>
bool is_sub_rectangular(E&& expr) {
    return decay_traits<E>::dimensions() == 3 && etl::dim<1>(expr) != etl::dim<2>(expr);
}

/*!
 * \brief Indicates if the given expression is a symmetric matrix or not.
 * \param expr The expression to test
 * \return true if the given expression is a symmetric matrix, false otherwise.
 */
template <typename E>
bool is_symmetric(E&& expr) {
    if (is_square(expr)) {
        for (std::size_t i = 0; i < etl::dim<0>(expr) - 1; ++i) {
            for (std::size_t j = i + 1; j < etl::dim<0>(expr); ++j) {
                if (expr(i, j) != expr(j, i)) {
                    return false;
                }
            }
        }

        return true;
    }

    return false;
}

/*!
 * \brief Indicates if the given expression is a lower triangular matrix or not.
 * \param expr The expression to test
 * \return true if the given expression is a lower triangular matrix, false otherwise.
 */
template <typename E>
bool is_lower_triangular(E&& expr) {
    if (is_square(expr)) {
        for (std::size_t i = 0; i < etl::dim<0>(expr) - 1; ++i) {
            for (std::size_t j = i + 1; j < etl::dim<0>(expr); ++j) {
                if (expr(i, j) != 0.0) {
                    return false;
                }
            }
        }

        return true;
    }

    return false;
}

/*!
 * \brief Indicates if the given expression is a strictly lower triangular matrix or not.
 * \param expr The expression to test
 * \return true if the given expression is a strictly lower triangular matrix, false otherwise.
 */
template <typename E>
bool is_strictly_lower_triangular(E&& expr) {
    if (is_square(expr)) {
        for (std::size_t i = 0; i < etl::dim<0>(expr); ++i) {
            for (std::size_t j = i; j < etl::dim<0>(expr); ++j) {
                if (expr(i, j) != 0.0) {
                    return false;
                }
            }
        }

        return true;
    }

    return false;
}

/*!
 * \brief Indicates if the given expression is a upper triangular matrix or not.
 * \param expr The expression to test
 * \return true if the given expression is a upper triangular matrix, false otherwise.
 */
template <typename E>
bool is_upper_triangular(E&& expr) {
    if (is_square(expr)) {
        for (std::size_t i = 1; i < etl::dim<0>(expr); ++i) {
            for (std::size_t j = 0; j < i; ++j) {
                if (expr(i, j) != 0.0) {
                    return false;
                }
            }
        }

        return true;
    }

    return false;
}

/*!
 * \brief Indicates if the given expression is a strictly upper triangular matrix or not.
 * \param expr The expression to test
 * \return true if the given expression is a strictly upper triangular matrix, false otherwise.
 */
template <typename E>
bool is_strictly_upper_triangular(E&& expr) {
    if (is_square(expr)) {
        for (std::size_t i = 0; i < etl::dim<0>(expr); ++i) {
            for (std::size_t j = 0; j <= i; ++j) {
                if (expr(i, j) != 0.0) {
                    return false;
                }
            }
        }

        return true;
    }

    return false;
}

/*!
 * \brief Indicates if the given expression is a diagonal matrix or not.
 * \param expr The expression to test
 * \return true if the given expression is a diagonal matrix, false otherwise.
 */
template <typename E>
bool is_diagonal(E&& expr) {
    if (is_square(expr)) {
        for (std::size_t i = 0; i < etl::dim<0>(expr); ++i) {
            for (std::size_t j = 0; j < etl::dim<0>(expr); ++j) {
                if (i != j && expr(i, j) != 0.0) {
                    return false;
                }
            }
        }

        return true;
    }

    return false;
}

/*!
 * \brief Indicates if the given expression is uniform (all elements of the same value)
 * \param expr The expression to test
 * \return true if the given expression is uniform, false otherwise.
 */
template <typename E>
bool is_uniform(E&& expr) {
    if (!etl::size(expr)) {
        return false;
    }

    auto first = *expr.begin();

    for (auto v : expr) {
        if (v != first) {
            return false;
        }
    }

    return true;
}

/*!
 * \brief Indicates if the given expression represents an hermitian matrix
 * \param expr The expression to test
 * \return true if the given expression is an hermitian matrix, false otherwise.
 */
template <typename E, cpp_enable_if(is_complex<E>::value)>
bool is_hermitian(E&& expr){
    if(!is_square(expr)){
        return false;
    }

    for (std::size_t i = 0; i < etl::dim<0>(expr); ++i) {
        for (std::size_t j = 0; j < etl::dim<0>(expr); ++j) {
            if(i != j && expr(i, j) != get_conj(expr(j, i))){
                return false;
            }
        }
    }

    return true;
}

/*!
 * \brief Indicates if the given expression represents an hermitian matrix
 * \param expr The expression to test
 * \return true if the given expression is an hermitian matrix, false otherwise.
 */
template <typename E, cpp_disable_if(is_complex<E>::value)>
bool is_hermitian(E&& expr){
    cpp_unused(expr);
    return false;
}

/*!
 * \brief Returns the trace of the given square matrix.
 *
 * If the given expression does not represent a square matrix, this function will fail
 *
 * \param expr The expression to get the trace from.
 * \return The trace of the given expression
 */
template <typename E>
value_t<E> trace(E&& expr) {
    assert_square(expr);

    auto value = value_t<E>();

    for (std::size_t i = 0; i < etl::dim<0>(expr); ++i) {
        value += expr(i, i);
    }

    return value;
}

template <typename AT, typename LT, typename UT, typename PT>
bool lu(const AT& A, LT& L, UT& U, PT& P) {
    // All matrices must be square
    if (!is_square(A) || !is_square(L) || !is_square(U) || !is_square(P)) {
        return false;
    }

    // All matrices must be of the same dimension
    if (etl::dim(A, 0) != etl::dim(L, 0) || etl::dim(A, 0) != etl::dim(U, 0) || etl::dim(A, 0) != etl::dim(P, 0)) {
        return true;
    }

    detail::lu_impl::apply(A, L, U, P);

    return true;
}

} //end of namespace etl
<commit_msg>New function: is_permutation_matrix<commit_after>//=======================================================================
// Copyright (c) 2014-2016 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

/*!
 * \file
 * \brief Contains some global functions.
*/

#pragma once

#include "etl/temporary.hpp"

#include "etl/impl/decomposition.hpp"

namespace etl {

/*!
 * \brief Indicates if the given expression is a square matrix or not.
 * \param expr The expression to test
 * \return true if the given expression is a square matrix, false otherwise.
 */
template <typename E>
bool is_square(E&& expr) {
    return decay_traits<E>::dimensions() == 2 && etl::dim<0>(expr) == etl::dim<1>(expr);
}

/*!
 * \brief Indicates if the given expression is a real matrix or not.
 * \param expr The expression to test
 * \return true if the given expression is a real matrix, false otherwise.
 */
template <typename E>
bool is_real_matrix(E&& expr) {
    cpp_unused(expr);
    return !is_complex<E>::value;
}

/*!
 * \brief Indicates if the given expression is a complex matrix or not.
 * \param expr The expression to test
 * \return true if the given expression is a complex matrix, false otherwise.
 */
template <typename E>
bool is_complex_matrix(E&& expr) {
    cpp_unused(expr);
    return is_complex<E>::value;
}

/*!
 * \brief Indicates if the given expression is a rectangular matrix or not.
 * \param expr The expression to test
 * \return true if the given expression is a rectangular matrix, false otherwise.
 */
template <typename E>
bool is_rectangular(E&& expr) {
    return decay_traits<E>::dimensions() == 2 && etl::dim<0>(expr) != etl::dim<1>(expr);
}

/*!
 * \brief Indicates if the given expression contains sub matrices that are square.
 * \param expr The expression to test
 * \return true if the given expression contains sub matrices that are square, false otherwise.
 */
template <typename E>
bool is_sub_square(E&& expr) {
    return decay_traits<E>::dimensions() == 3 && etl::dim<1>(expr) == etl::dim<2>(expr);
}

/*!
 * \brief Indicates if the given expression contains sub matrices that are rectangular.
 * \param expr The expression to test
 * \return true if the given expression contains sub matrices that are rectangular, false otherwise.
 */
template <typename E>
bool is_sub_rectangular(E&& expr) {
    return decay_traits<E>::dimensions() == 3 && etl::dim<1>(expr) != etl::dim<2>(expr);
}

/*!
 * \brief Indicates if the given expression is a symmetric matrix or not.
 * \param expr The expression to test
 * \return true if the given expression is a symmetric matrix, false otherwise.
 */
template <typename E>
bool is_symmetric(E&& expr) {
    if (is_square(expr)) {
        for (std::size_t i = 0; i < etl::dim<0>(expr) - 1; ++i) {
            for (std::size_t j = i + 1; j < etl::dim<0>(expr); ++j) {
                if (expr(i, j) != expr(j, i)) {
                    return false;
                }
            }
        }

        return true;
    }

    return false;
}

/*!
 * \brief Indicates if the given expression is a lower triangular matrix or not.
 * \param expr The expression to test
 * \return true if the given expression is a lower triangular matrix, false otherwise.
 */
template <typename E>
bool is_lower_triangular(E&& expr) {
    if (is_square(expr)) {
        for (std::size_t i = 0; i < etl::dim<0>(expr) - 1; ++i) {
            for (std::size_t j = i + 1; j < etl::dim<0>(expr); ++j) {
                if (expr(i, j) != 0.0) {
                    return false;
                }
            }
        }

        return true;
    }

    return false;
}

/*!
 * \brief Indicates if the given expression is a strictly lower triangular matrix or not.
 * \param expr The expression to test
 * \return true if the given expression is a strictly lower triangular matrix, false otherwise.
 */
template <typename E>
bool is_strictly_lower_triangular(E&& expr) {
    if (is_square(expr)) {
        for (std::size_t i = 0; i < etl::dim<0>(expr); ++i) {
            for (std::size_t j = i; j < etl::dim<0>(expr); ++j) {
                if (expr(i, j) != 0.0) {
                    return false;
                }
            }
        }

        return true;
    }

    return false;
}

/*!
 * \brief Indicates if the given expression is a upper triangular matrix or not.
 * \param expr The expression to test
 * \return true if the given expression is a upper triangular matrix, false otherwise.
 */
template <typename E>
bool is_upper_triangular(E&& expr) {
    if (is_square(expr)) {
        for (std::size_t i = 1; i < etl::dim<0>(expr); ++i) {
            for (std::size_t j = 0; j < i; ++j) {
                if (expr(i, j) != 0.0) {
                    return false;
                }
            }
        }

        return true;
    }

    return false;
}

/*!
 * \brief Indicates if the given expression is a strictly upper triangular matrix or not.
 * \param expr The expression to test
 * \return true if the given expression is a strictly upper triangular matrix, false otherwise.
 */
template <typename E>
bool is_strictly_upper_triangular(E&& expr) {
    if (is_square(expr)) {
        for (std::size_t i = 0; i < etl::dim<0>(expr); ++i) {
            for (std::size_t j = 0; j <= i; ++j) {
                if (expr(i, j) != 0.0) {
                    return false;
                }
            }
        }

        return true;
    }

    return false;
}

/*!
 * \brief Indicates if the given expression is a diagonal matrix or not.
 * \param expr The expression to test
 * \return true if the given expression is a diagonal matrix, false otherwise.
 */
template <typename E>
bool is_diagonal(E&& expr) {
    if (is_square(expr)) {
        for (std::size_t i = 0; i < etl::dim<0>(expr); ++i) {
            for (std::size_t j = 0; j < etl::dim<0>(expr); ++j) {
                if (i != j && expr(i, j) != 0.0) {
                    return false;
                }
            }
        }

        return true;
    }

    return false;
}

/*!
 * \brief Indicates if the given expression is uniform (all elements of the same value)
 * \param expr The expression to test
 * \return true if the given expression is uniform, false otherwise.
 */
template <typename E>
bool is_uniform(E&& expr) {
    if (!etl::size(expr)) {
        return false;
    }

    auto first = *expr.begin();

    for (auto v : expr) {
        if (v != first) {
            return false;
        }
    }

    return true;
}

/*!
 * \brief Indicates if the given expression represents a permutation matrix
 * \param expr The expression to test
 * \return true if the given expression is an hermitian matrix, false otherwise.
 */
template <typename E>
bool is_permutation_matrix(E&& expr){
    if(!is_square(expr)){
        return false;
    }

    auto sum = value_t<E>(0);

    for (std::size_t i = 0; i < etl::dim<0>(expr); ++i) {
        for (std::size_t j = 0; j < etl::dim<0>(expr); ++j) {
            if(expr(i, j) != value_t<E>(0) && expr(i, j) != value_t<E>(1)){
                return false;
            }

            sum += expr(i, j);
        }
    }

    return sum == etl::dim<0>(expr);
}

/*!
 * \brief Indicates if the given expression represents an hermitian matrix
 * \param expr The expression to test
 * \return true if the given expression is an hermitian matrix, false otherwise.
 */
template <typename E, cpp_enable_if(is_complex<E>::value)>
bool is_hermitian(E&& expr){
    if(!is_square(expr)){
        return false;
    }

    for (std::size_t i = 0; i < etl::dim<0>(expr); ++i) {
        for (std::size_t j = 0; j < etl::dim<0>(expr); ++j) {
            if(i != j && expr(i, j) != get_conj(expr(j, i))){
                return false;
            }
        }
    }

    return true;
}

/*!
 * \brief Indicates if the given expression represents an hermitian matrix
 * \param expr The expression to test
 * \return true if the given expression is an hermitian matrix, false otherwise.
 */
template <typename E, cpp_disable_if(is_complex<E>::value)>
bool is_hermitian(E&& expr){
    cpp_unused(expr);
    return false;
}

/*!
 * \brief Returns the trace of the given square matrix.
 *
 * If the given expression does not represent a square matrix, this function will fail
 *
 * \param expr The expression to get the trace from.
 * \return The trace of the given expression
 */
template <typename E>
value_t<E> trace(E&& expr) {
    assert_square(expr);

    auto value = value_t<E>();

    for (std::size_t i = 0; i < etl::dim<0>(expr); ++i) {
        value += expr(i, i);
    }

    return value;
}

template <typename AT, typename LT, typename UT, typename PT>
bool lu(const AT& A, LT& L, UT& U, PT& P) {
    // All matrices must be square
    if (!is_square(A) || !is_square(L) || !is_square(U) || !is_square(P)) {
        return false;
    }

    // All matrices must be of the same dimension
    if (etl::dim(A, 0) != etl::dim(L, 0) || etl::dim(A, 0) != etl::dim(U, 0) || etl::dim(A, 0) != etl::dim(P, 0)) {
        return true;
    }

    detail::lu_impl::apply(A, L, U, P);

    return true;
}

} //end of namespace etl
<|endoftext|>


<commit_before>// Created on February 11, 2014 by Lu, Wangshan.
#include <iostream>
#include <fstream>
#include <memory>
#include <thread>
#include <diffusion/factory.hpp>
int main(int argc, char * argv[]) {
    if (argc < 3) {
        std::cerr << "Usage: " << argv[0] << " listening_port input_text_file" << std::endl;
        return 0;
    }
    std::ifstream input_text_file(argv[2]);
    std::uint16_t listening_port = std::stoi(argv[1]);
    auto net_writer = std::shared_ptr<diffusion::Writer>(diffusion::create_network_writer(listening_port));
    while (true) {
        std::string current_line;
        std::getline(input_text_file, current_line);
        if (!input_text_file)
            input_text_file.open(argv[2]);
        net_writer->write(diffusion::ByteBuffer(current_line));
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }
    return 0;
}
<commit_msg>More on t_net_writer.<commit_after>// Created on February 11, 2014 by Lu, Wangshan.
#include <iostream>
#include <fstream>
#include <memory>
#include <thread>
#include <diffusion/factory.hpp>
int main(int argc, char * argv[]) {
    if (argc < 3) {
        std::cerr << "Usage: " << argv[0] << " listening_port input_text_file" << std::endl;
        return 0;
    }
    std::ifstream input_text_file(argv[2]);
    std::uint16_t listening_port = std::stoi(argv[1]);
    auto net_writer = std::shared_ptr<diffusion::Writer>(diffusion::create_network_writer(listening_port));
    std::string current_line;
    while (input_text_file) {
        std::getline(input_text_file, current_line);
        std::cout << ":" << current_line << ":" << std::endl;
        net_writer->write(diffusion::ByteBuffer(current_line));
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }
    return 0;
}
<|endoftext|>


<commit_before>//------------------------------------------------------------------------------
// CLING - the C++ LLVM-based InterpreterG :)
// author:  Vassil Vassilev <vasil.georgiev.vasilev@cern.ch>
//
// This file is dual-licensed: you can choose to license it under the University
// of Illinois Open Source License or the GNU Lesser General Public License. See
// LICENSE.TXT for details.
//------------------------------------------------------------------------------

#include "cling/Interpreter/DynamicLibraryManager.h"
#include "cling/Interpreter/InterpreterCallbacks.h"
#include "cling/Interpreter/InvocationOptions.h"
#include "cling/Utils/Paths.h"
#include "cling/Utils/Platform.h"
#include "cling/Utils/Output.h"

#include "llvm/BinaryFormat/Magic.h"
#include "llvm/Support/DynamicLibrary.h"
#include "llvm/Support/Path.h"

#include <system_error>
#include <sys/stat.h>

namespace cling {
  DynamicLibraryManager::DynamicLibraryManager(const InvocationOptions& Opts)
    : m_Opts(Opts) {
    const llvm::SmallVector<const char*, 10> kSysLibraryEnv = {
      "LD_LIBRARY_PATH",
  #if __APPLE__
      "DYLD_LIBRARY_PATH",
      "DYLD_FALLBACK_LIBRARY_PATH",
      /*
      "DYLD_VERSIONED_LIBRARY_PATH",
      "DYLD_FRAMEWORK_PATH",
      "DYLD_FALLBACK_FRAMEWORK_PATH",
      "DYLD_VERSIONED_FRAMEWORK_PATH",
      */
  #elif defined(_WIN32)
      "PATH",
  #endif
    };

    // Behaviour is to not add paths that don't exist...In an interpreted env
    // does this make sense? Path could pop into existance at any time.
    for (const char* Var : kSysLibraryEnv) {
      if (Opts.Verbose())
        cling::log() << "Adding library paths from '" << Var << "':\n";
      if (const char* Env = ::getenv(Var)) {
        llvm::SmallVector<llvm::StringRef, 10> CurPaths;
        SplitPaths(Env, CurPaths, utils::kPruneNonExistant, platform::kEnvDelim,
                   Opts.Verbose());
        for (const auto& Path : CurPaths)
          m_SearchPaths.push_back({Path.str(), /*IsUser*/true});
      }
    }

    llvm::SmallVector<std::string, 64> SysPaths;
    platform::GetSystemLibraryPaths(SysPaths);

    for (const std::string& P : SysPaths)
      m_SearchPaths.push_back({P, /*IsUser*/false});

    // This will currently be the last path searched, should it be pushed to
    // the front of the line, or even to the front of user paths?
    m_SearchPaths.push_back({".", /*IsUser*/true});
  }

  std::string
  DynamicLibraryManager::lookupLibInPaths(llvm::StringRef libStem) const {
    llvm::SmallVector<SearchPathInfo, 128> Paths;
    for (const std::string &P : m_Opts.LibSearchPath)
      Paths.push_back({P, /*IsUser*/true});

    Paths.append(m_SearchPaths.begin(), m_SearchPaths.end());

    llvm::SmallString<512> ThisPath;
    for (const SearchPathInfo& Info : Paths) {
      ThisPath = Info.Path;
      llvm::sys::path::append(ThisPath, libStem);
      bool exists;
      if (isSharedLibrary(ThisPath.str(), &exists))
        return ThisPath.str();
      if (exists)
        return "";
    }
    return "";
  }

  std::string
  DynamicLibraryManager::lookupLibMaybeAddExt(llvm::StringRef libStem) const {
    using namespace llvm::sys;

    std::string foundDyLib = lookupLibInPaths(libStem);

    if (foundDyLib.empty()) {
      // Add DyLib extension:
      llvm::SmallString<512> filenameWithExt(libStem);
#if defined(LLVM_ON_UNIX)
#ifdef __APPLE__
      llvm::SmallString<512>::iterator IStemEnd = filenameWithExt.end() - 1;
#endif
      static const char* DyLibExt = ".so";
#elif defined(_WIN32)
      static const char* DyLibExt = ".dll";
#else
# error "Unsupported platform."
#endif
      filenameWithExt += DyLibExt;
      foundDyLib = lookupLibInPaths(filenameWithExt);
#ifdef __APPLE__
      if (foundDyLib.empty()) {
        filenameWithExt.erase(IStemEnd + 1, filenameWithExt.end());
        filenameWithExt += ".dylib";
        foundDyLib = lookupLibInPaths(filenameWithExt);
      }
#endif
    }

    if (foundDyLib.empty())
      return std::string();

    // get canonical path name and check if already loaded
    const std::string Path = platform::NormalizePath(foundDyLib);
    if (Path.empty()) {
      cling::errs() << "cling::DynamicLibraryManager::lookupLibMaybeAddExt(): "
        "error getting real (canonical) path of library " << foundDyLib << '\n';
      return foundDyLib;
    }
    return Path;
  }

  std::string DynamicLibraryManager::normalizePath(llvm::StringRef path) {
    // Make the path canonical if the file exists.
    const std::string Path = path.str();
    struct stat buffer;
    if (::stat(Path.c_str(), &buffer) != 0)
      return std::string();

    const std::string NPath = platform::NormalizePath(Path);
    if (NPath.empty())
      cling::log() << "Could not normalize: '" << Path << "'";
    return NPath;
  }

  std::string
  DynamicLibraryManager::lookupLibrary(llvm::StringRef libStem) const {
    // If it is an absolute path, don't try iterate over the paths.
    if (llvm::sys::path::is_absolute(libStem)) {
      if (isSharedLibrary(libStem))
        return normalizePath(libStem);
      else
        return std::string();
    }

    std::string foundName = lookupLibMaybeAddExt(libStem);
    if (foundName.empty() && !libStem.startswith("lib")) {
      // try with "lib" prefix:
      foundName = lookupLibMaybeAddExt("lib" + libStem.str());
    }

    if (!foundName.empty() && isSharedLibrary(foundName))
      return platform::NormalizePath(foundName);

    return std::string();
  }

  DynamicLibraryManager::LoadLibResult
  DynamicLibraryManager::loadLibrary(const std::string& libStem,
                                     bool permanent, bool resolved) {
    std::string lResolved;
    const std::string& canonicalLoadedLib = resolved ? libStem : lResolved;
    if (!resolved) {
      lResolved = lookupLibrary(libStem);
      if (lResolved.empty())
        return kLoadLibNotFound;
    }

    if (m_LoadedLibraries.find(canonicalLoadedLib) != m_LoadedLibraries.end())
      return kLoadLibAlreadyLoaded;

    // TODO: !permanent case

    std::string errMsg;
    DyLibHandle dyLibHandle = platform::DLOpen(canonicalLoadedLib, &errMsg);
    if (!dyLibHandle) {
      // We emit callback to LibraryLoadingFailed when we get error with error message.
      if (InterpreterCallbacks* C = getCallbacks()) {
        if (C->LibraryLoadingFailed(errMsg, libStem, permanent, resolved))
          return kLoadLibSuccess;
      }

      cling::errs() << "cling::DynamicLibraryManager::loadLibrary(): " << errMsg
                    << '\n';
      return kLoadLibLoadError;
    }
    else if (InterpreterCallbacks* C = getCallbacks())
      C->LibraryLoaded(dyLibHandle, canonicalLoadedLib);

    std::pair<DyLibs::iterator, bool> insRes
      = m_DyLibs.insert(std::pair<DyLibHandle, std::string>(dyLibHandle,
                                                            canonicalLoadedLib));
    if (!insRes.second)
      return kLoadLibAlreadyLoaded;
    m_LoadedLibraries.insert(canonicalLoadedLib);
    return kLoadLibSuccess;
  }

  void DynamicLibraryManager::unloadLibrary(llvm::StringRef libStem) {
    std::string canonicalLoadedLib = lookupLibrary(libStem);
    if (!isLibraryLoaded(canonicalLoadedLib))
      return;

    DyLibHandle dyLibHandle = 0;
    for (DyLibs::const_iterator I = m_DyLibs.begin(), E = m_DyLibs.end();
         I != E; ++I) {
      if (I->second == canonicalLoadedLib) {
        dyLibHandle = I->first;
        break;
      }
    }

    // TODO: !permanent case

    std::string errMsg;
    platform::DLClose(dyLibHandle, &errMsg);
    if (!errMsg.empty()) {
      cling::errs() << "cling::DynamicLibraryManager::unloadLibrary(): "
                    << errMsg << '\n';
    }

    if (InterpreterCallbacks* C = getCallbacks())
      C->LibraryUnloaded(dyLibHandle, canonicalLoadedLib);

    m_DyLibs.erase(dyLibHandle);
    m_LoadedLibraries.erase(canonicalLoadedLib);
  }

  bool DynamicLibraryManager::isLibraryLoaded(llvm::StringRef fullPath) const {
    std::string canonPath = normalizePath(fullPath);
    if (m_LoadedLibraries.find(canonPath) != m_LoadedLibraries.end())
      return true;
    return false;
  }

  void DynamicLibraryManager::ExposeHiddenSharedLibrarySymbols(void* handle) {
    llvm::sys::DynamicLibrary::addPermanentLibrary(const_cast<void*>(handle));
  }

  bool DynamicLibraryManager::isSharedLibrary(llvm::StringRef libFullPath,
                                              bool* exists /*=0*/) {
    using namespace llvm;
    file_magic Magic;
    const std::error_code Error = identify_magic(libFullPath, Magic);
    if (exists)
      *exists = !Error;

    return !Error &&
#ifdef __APPLE__
      (Magic == file_magic::macho_fixed_virtual_memory_shared_lib
       || Magic == file_magic::macho_dynamically_linked_shared_lib
       || Magic == file_magic::macho_dynamically_linked_shared_lib_stub
       || Magic == file_magic::macho_universal_binary)
#elif defined(LLVM_ON_UNIX)
#ifdef __CYGWIN__
      (Magic == file_magic::pecoff_executable)
#else
      (Magic == file_magic::elf_shared_object)
#endif
#elif defined(_WIN32)
      (Magic == file_magic::pecoff_executable
       || platform::IsDLL(libFullPath.str()))
#else
# error "Unsupported platform."
#endif
      ;
  }

} // end namespace cling
<commit_msg>Skip non-regular files to find dylibs:<commit_after>//------------------------------------------------------------------------------
// CLING - the C++ LLVM-based InterpreterG :)
// author:  Vassil Vassilev <vasil.georgiev.vasilev@cern.ch>
//
// This file is dual-licensed: you can choose to license it under the University
// of Illinois Open Source License or the GNU Lesser General Public License. See
// LICENSE.TXT for details.
//------------------------------------------------------------------------------

#include "cling/Interpreter/DynamicLibraryManager.h"
#include "cling/Interpreter/InterpreterCallbacks.h"
#include "cling/Interpreter/InvocationOptions.h"
#include "cling/Utils/Paths.h"
#include "cling/Utils/Platform.h"
#include "cling/Utils/Output.h"

#include "llvm/BinaryFormat/Magic.h"
#include "llvm/Support/DynamicLibrary.h"
#include "llvm/Support/Path.h"

#include <system_error>
#include <sys/stat.h>

namespace cling {
  DynamicLibraryManager::DynamicLibraryManager(const InvocationOptions& Opts)
    : m_Opts(Opts) {
    const llvm::SmallVector<const char*, 10> kSysLibraryEnv = {
      "LD_LIBRARY_PATH",
  #if __APPLE__
      "DYLD_LIBRARY_PATH",
      "DYLD_FALLBACK_LIBRARY_PATH",
      /*
      "DYLD_VERSIONED_LIBRARY_PATH",
      "DYLD_FRAMEWORK_PATH",
      "DYLD_FALLBACK_FRAMEWORK_PATH",
      "DYLD_VERSIONED_FRAMEWORK_PATH",
      */
  #elif defined(_WIN32)
      "PATH",
  #endif
    };

    // Behaviour is to not add paths that don't exist...In an interpreted env
    // does this make sense? Path could pop into existance at any time.
    for (const char* Var : kSysLibraryEnv) {
      if (Opts.Verbose())
        cling::log() << "Adding library paths from '" << Var << "':\n";
      if (const char* Env = ::getenv(Var)) {
        llvm::SmallVector<llvm::StringRef, 10> CurPaths;
        SplitPaths(Env, CurPaths, utils::kPruneNonExistant, platform::kEnvDelim,
                   Opts.Verbose());
        for (const auto& Path : CurPaths)
          m_SearchPaths.push_back({Path.str(), /*IsUser*/true});
      }
    }

    llvm::SmallVector<std::string, 64> SysPaths;
    platform::GetSystemLibraryPaths(SysPaths);

    for (const std::string& P : SysPaths)
      m_SearchPaths.push_back({P, /*IsUser*/false});

    // This will currently be the last path searched, should it be pushed to
    // the front of the line, or even to the front of user paths?
    m_SearchPaths.push_back({".", /*IsUser*/true});
  }

  std::string
  DynamicLibraryManager::lookupLibInPaths(llvm::StringRef libStem) const {
    llvm::SmallVector<SearchPathInfo, 128> Paths;
    for (const std::string &P : m_Opts.LibSearchPath)
      Paths.push_back({P, /*IsUser*/true});

    Paths.append(m_SearchPaths.begin(), m_SearchPaths.end());

    llvm::SmallString<512> ThisPath;
    for (const SearchPathInfo& Info : Paths) {
      ThisPath = Info.Path;
      llvm::sys::path::append(ThisPath, libStem);
      bool exists;
      if (isSharedLibrary(ThisPath.str(), &exists))
        return ThisPath.str();
      if (exists)
        return "";
    }
    return "";
  }

  std::string
  DynamicLibraryManager::lookupLibMaybeAddExt(llvm::StringRef libStem) const {
    using namespace llvm::sys;

    std::string foundDyLib = lookupLibInPaths(libStem);

    if (foundDyLib.empty()) {
      // Add DyLib extension:
      llvm::SmallString<512> filenameWithExt(libStem);
#if defined(LLVM_ON_UNIX)
#ifdef __APPLE__
      llvm::SmallString<512>::iterator IStemEnd = filenameWithExt.end() - 1;
#endif
      static const char* DyLibExt = ".so";
#elif defined(_WIN32)
      static const char* DyLibExt = ".dll";
#else
# error "Unsupported platform."
#endif
      filenameWithExt += DyLibExt;
      foundDyLib = lookupLibInPaths(filenameWithExt);
#ifdef __APPLE__
      if (foundDyLib.empty()) {
        filenameWithExt.erase(IStemEnd + 1, filenameWithExt.end());
        filenameWithExt += ".dylib";
        foundDyLib = lookupLibInPaths(filenameWithExt);
      }
#endif
    }

    if (foundDyLib.empty())
      return std::string();

    // get canonical path name and check if already loaded
    const std::string Path = platform::NormalizePath(foundDyLib);
    if (Path.empty()) {
      cling::errs() << "cling::DynamicLibraryManager::lookupLibMaybeAddExt(): "
        "error getting real (canonical) path of library " << foundDyLib << '\n';
      return foundDyLib;
    }
    return Path;
  }

  std::string DynamicLibraryManager::normalizePath(llvm::StringRef path) {
    // Make the path canonical if the file exists.
    const std::string Path = path.str();
    struct stat buffer;
    if (::stat(Path.c_str(), &buffer) != 0)
      return std::string();

    const std::string NPath = platform::NormalizePath(Path);
    if (NPath.empty())
      cling::log() << "Could not normalize: '" << Path << "'";
    return NPath;
  }

  std::string
  DynamicLibraryManager::lookupLibrary(llvm::StringRef libStem) const {
    // If it is an absolute path, don't try iterate over the paths.
    if (llvm::sys::path::is_absolute(libStem)) {
      if (isSharedLibrary(libStem))
        return normalizePath(libStem);
      else
        return std::string();
    }

    std::string foundName = lookupLibMaybeAddExt(libStem);
    if (foundName.empty() && !libStem.startswith("lib")) {
      // try with "lib" prefix:
      foundName = lookupLibMaybeAddExt("lib" + libStem.str());
    }

    if (!foundName.empty() && isSharedLibrary(foundName))
      return platform::NormalizePath(foundName);

    return std::string();
  }

  DynamicLibraryManager::LoadLibResult
  DynamicLibraryManager::loadLibrary(const std::string& libStem,
                                     bool permanent, bool resolved) {
    std::string lResolved;
    const std::string& canonicalLoadedLib = resolved ? libStem : lResolved;
    if (!resolved) {
      lResolved = lookupLibrary(libStem);
      if (lResolved.empty())
        return kLoadLibNotFound;
    }

    if (m_LoadedLibraries.find(canonicalLoadedLib) != m_LoadedLibraries.end())
      return kLoadLibAlreadyLoaded;

    // TODO: !permanent case

    std::string errMsg;
    DyLibHandle dyLibHandle = platform::DLOpen(canonicalLoadedLib, &errMsg);
    if (!dyLibHandle) {
      // We emit callback to LibraryLoadingFailed when we get error with error message.
      if (InterpreterCallbacks* C = getCallbacks()) {
        if (C->LibraryLoadingFailed(errMsg, libStem, permanent, resolved))
          return kLoadLibSuccess;
      }

      cling::errs() << "cling::DynamicLibraryManager::loadLibrary(): " << errMsg
                    << '\n';
      return kLoadLibLoadError;
    }
    else if (InterpreterCallbacks* C = getCallbacks())
      C->LibraryLoaded(dyLibHandle, canonicalLoadedLib);

    std::pair<DyLibs::iterator, bool> insRes
      = m_DyLibs.insert(std::pair<DyLibHandle, std::string>(dyLibHandle,
                                                            canonicalLoadedLib));
    if (!insRes.second)
      return kLoadLibAlreadyLoaded;
    m_LoadedLibraries.insert(canonicalLoadedLib);
    return kLoadLibSuccess;
  }

  void DynamicLibraryManager::unloadLibrary(llvm::StringRef libStem) {
    std::string canonicalLoadedLib = lookupLibrary(libStem);
    if (!isLibraryLoaded(canonicalLoadedLib))
      return;

    DyLibHandle dyLibHandle = 0;
    for (DyLibs::const_iterator I = m_DyLibs.begin(), E = m_DyLibs.end();
         I != E; ++I) {
      if (I->second == canonicalLoadedLib) {
        dyLibHandle = I->first;
        break;
      }
    }

    // TODO: !permanent case

    std::string errMsg;
    platform::DLClose(dyLibHandle, &errMsg);
    if (!errMsg.empty()) {
      cling::errs() << "cling::DynamicLibraryManager::unloadLibrary(): "
                    << errMsg << '\n';
    }

    if (InterpreterCallbacks* C = getCallbacks())
      C->LibraryUnloaded(dyLibHandle, canonicalLoadedLib);

    m_DyLibs.erase(dyLibHandle);
    m_LoadedLibraries.erase(canonicalLoadedLib);
  }

  bool DynamicLibraryManager::isLibraryLoaded(llvm::StringRef fullPath) const {
    std::string canonPath = normalizePath(fullPath);
    if (m_LoadedLibraries.find(canonPath) != m_LoadedLibraries.end())
      return true;
    return false;
  }

  void DynamicLibraryManager::ExposeHiddenSharedLibrarySymbols(void* handle) {
    llvm::sys::DynamicLibrary::addPermanentLibrary(const_cast<void*>(handle));
  }

  bool DynamicLibraryManager::isSharedLibrary(llvm::StringRef libFullPath,
                                              bool* exists /*=0*/) {
    using namespace llvm;
    auto filetype = sys::fs::get_file_type(libFullPath, /*Follow*/ true);
    if (filetype != sys::fs::file_type::regular_file) {
      if (exists) {
        // get_file_type returns status_error also in case of file_not_found.
        *exists = filetype != sys::fs::file_type::status_error;
      }
      return false;
    }

    file_magic Magic;
    const std::error_code Error = identify_magic(libFullPath, Magic);
    if (exists)
      *exists = !Error;

    return !Error &&
#ifdef __APPLE__
      (Magic == file_magic::macho_fixed_virtual_memory_shared_lib
       || Magic == file_magic::macho_dynamically_linked_shared_lib
       || Magic == file_magic::macho_dynamically_linked_shared_lib_stub
       || Magic == file_magic::macho_universal_binary)
#elif defined(LLVM_ON_UNIX)
#ifdef __CYGWIN__
      (Magic == file_magic::pecoff_executable)
#else
      (Magic == file_magic::elf_shared_object)
#endif
#elif defined(_WIN32)
      (Magic == file_magic::pecoff_executable
       || platform::IsDLL(libFullPath.str()))
#else
# error "Unsupported platform."
#endif
      ;
  }

} // end namespace cling
<|endoftext|>