<commit_before>// @Alan
//
// Exercise 11.27:
// What kinds of problems would you use count to solve?
// When might you use find instead?
//  I would use count to deal with multimap or multi multiset.
//  As for the associative container that have unique key, I would use find instead of count.
//
// Exercise 11.28:
// Define and initialize a variable to hold the result of
// calling find on a map from string to vector of int.
//
// Exercise 11.29:
// What do upper_bound, lower_bound, and equal_range return
// when you pass them a key that is not in the container?
//  If the element is not in the multimap, then lower_bound
//  and upper_bound will return equal iterators; both will
//  refer to the point at which the key can be inserted without
//  disrupting the order.
//
//  If no matching element is found, then both the first and
//  second iterators refer to the position where this key can
//  be inserted.
//
// Exercise 11.30:
// Explain the meaning of the operand pos.first->second used
// in the output expression of the final program in this section.
//     cout << pos.first->second << endl;
//              ^^^^^^^^^^^^^^^^^
//  pos                     a pair
//  pos.first               the iterator refering to the first element with the matching key
//  pos.first->second       the value part of the key-value of the first element with the matching key

#include <iostream>
#include <map>
#include <string>
#include <algorithm>
#include <vector>

int main()
{
    std::map<std::string, std::vector<int>> m;
    m = { { "Alan",{ 1,2,3,4,5, } },{ "John",{ 1,5,6,7,8 } } };

    // ex11.28
    std::map<std::string, std::vector<int>>::iterator it;
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// type used to define this iterator.

    it = m.find("Alan");

    return 0;
}
<commit_msg>Update ex11_27_28_29_30.cpp<commit_after>// @Alan
//
// Exercise 11.27:
// What kinds of problems would you use count to solve?
// When might you use find instead?
//  I would use count to deal with multimap or multi multiset.
//  As for the associative container that have unique key, I would use find instead of count.
//
// Exercise 11.28:
// Define and initialize a variable to hold the result of
// calling find on a map from string to vector of int.
//
// Exercise 11.29:
// What do upper_bound, lower_bound, and equal_range return
// when you pass them a key that is not in the container?
//  If the element is not in the multimap, then lower_bound
//  and upper_bound will return equal iterators; both will
//  refer to the point at which the key can be inserted without
//  disrupting the order.
//
//  If no matching element is found, then both the first and
//  second iterators refer to the position where this key can
//  be inserted.
//
// Exercise 11.30:
// Explain the meaning of the operand pos.first->second used
// in the output expression of the final program in this section.
//     cout << pos.first->second << endl;
//              ^^^^^^^^^^^^^^^^^
//  pos                     a pair
//  pos.first               the iterator refering to the first element with the matching key
//  pos.first->second       the value part of the key-value of the first element with the matching key

#include <iostream>
#include <map>
#include <string>
#include <algorithm>
#include <vector>

int main()
{
    std::map<std::string, std::vector<int>> m = { { "Alan",{ 1,2,3,4,5, } },{ "John",{ 1,5,6,7,8 } } };

    // ex11.28
    std::map<std::string, std::vector<int>>::iterator it;
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// type used to define this iterator.

    it = m.find("Alan");

    return 0;
}
<|endoftext|>


<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 <windows.h>
#include <shlwapi.h>

#include "chrome/app/breakpad_win.h"
#include "chrome/app/client_util.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/result_codes.h"
#include "chrome/installer/util/browser_distribution.h"
#include "chrome/installer/util/install_util.h"
#include "chrome/installer/util/google_update_constants.h"
#include "chrome/installer/util/util_constants.h"

namespace {
// The entry point signature of chrome.dll.
typedef int (*DLL_MAIN)(HINSTANCE, sandbox::SandboxInterfaceInfo*, wchar_t*);

typedef void (*RelaunchChromeBrowserWithNewCommandLineIfNeededFunc)();

// Not generic, we only handle strings up to 128 chars.
bool ReadRegistryStr(HKEY key, const wchar_t* name, std::wstring* value) {
  BYTE out[128 * sizeof(wchar_t)];
  DWORD size = sizeof(out);
  DWORD type = 0;
  if (ERROR_SUCCESS != ::RegQueryValueExW(key, name, NULL, &type, out, &size))
    return false;
  if (type != REG_SZ)
    return false;
  value->assign(reinterpret_cast<wchar_t*>(out));
  return true;
}

// Gets chrome version according to the load path. |exe_path| must be the
// backslash terminated directory of the current chrome.exe.
bool GetVersion(const wchar_t* exe_path, const wchar_t* key_path,
                std::wstring* version) {
  HKEY reg_root = InstallUtil::IsPerUserInstall(exe_path) ? HKEY_CURRENT_USER :
                                                            HKEY_LOCAL_MACHINE;
  HKEY key;
  if (::RegOpenKeyEx(reg_root, key_path, 0, KEY_READ, &key) != ERROR_SUCCESS)
    return false;

  // If 'new_chrome.exe' is present it means chrome was auto-updated while
  // running. We need to consult the opv value so we can load the old dll.
  // TODO(cpu) : This is solving the same problem as the environment variable
  // so one of them will eventually be deprecated.
  std::wstring new_chrome_exe(exe_path);
  new_chrome_exe.append(installer_util::kChromeNewExe);
  if (::PathFileExistsW(new_chrome_exe.c_str()) &&
      ReadRegistryStr(key, google_update::kRegOldVersionField, version)) {
    ::RegCloseKey(key);
    return true;
  }

  bool ret = ReadRegistryStr(key, google_update::kRegVersionField, version);
  ::RegCloseKey(key);
  return ret;
}

// Gets the path of the current exe with a trailing backslash.
std::wstring GetExecutablePath() {
  wchar_t path[MAX_PATH];
  ::GetModuleFileNameW(NULL, path, MAX_PATH);
  if (!::PathRemoveFileSpecW(path))
    return std::wstring();
  std::wstring exe_path(path);
  return exe_path.append(L"\\");
}

// Not generic, we only handle strings up to 128 chars.
bool EnvQueryStr(const wchar_t* key_name, std::wstring* value) {
  wchar_t out[128];
  DWORD count = sizeof(out)/sizeof(out[0]);
  DWORD rv = ::GetEnvironmentVariableW(key_name, out, count);
  if ((rv == 0) || (rv >= count))
    return false;
  *value = out;
  return true;
}

bool IsRunningHeadless() {
  return (0 != ::GetEnvironmentVariableW(L"CHROME_HEADLESS", NULL, 0));
}

// Expects that |dir| has a trailing backslash. |dir| is modified so it
// contains the full path that was tried. Caller must check for the return
// value not being null to dermine if this path contains a valid dll.
HMODULE LoadChromeWithDirectory(std::wstring* dir) {
  ::SetCurrentDirectoryW(dir->c_str());
  const CommandLine& cmd_line = *CommandLine::ForCurrentProcess();
#ifdef _WIN64
  if ((cmd_line.GetSwitchValueASCII(switches::kProcessType) ==
      switches::kNaClBrokerProcess) ||
      (cmd_line.GetSwitchValueASCII(switches::kProcessType) ==
      switches::kNaClLoaderProcess)) {
    // Load the 64-bit DLL when running in a 64-bit process.
    dir->append(installer_util::kChromeNaCl64Dll);
  } else {
    // Only NaCl broker and loader can be launched as Win64 processes.
    NOTREACHED();
    return NULL;
  }
#else
  dir->append(installer_util::kChromeDll);
#endif

  // Experimental pre-reading optimization
  // The idea is to pre read significant portion of chrome.dll in advance
  // so that subsequent hard page faults are avoided.
  DWORD pre_read_size_mb = 0;
  if (!cmd_line.HasSwitch(switches::kProcessType) &&
      (IsRunningHeadless() || InstallUtil::IsChromeFrameProcess())) {
    HKEY key = NULL;
    if (::RegOpenKeyEx(HKEY_CURRENT_USER, L"Software\\Google\\ChromeFrame",
                       0, KEY_QUERY_VALUE, &key) == ERROR_SUCCESS) {
      DWORD unused = sizeof(pre_read_size_mb);
      RegQueryValueEx(key, L"PreRead", NULL, NULL,
                      reinterpret_cast<LPBYTE>(&pre_read_size_mb), &unused);
      RegCloseKey(key);
      key = NULL;
    } else {
      pre_read_size_mb = 16; // Read in first 16 MB by default.
    }
  }

  if (pre_read_size_mb) {
    HANDLE chrome_dll = CreateFile(dir->c_str(),
                                       GENERIC_READ,
                                       FILE_SHARE_READ | FILE_SHARE_WRITE,
                                       NULL,
                                       OPEN_EXISTING,
                                       FILE_FLAG_SEQUENTIAL_SCAN,
                                       NULL);
    if (chrome_dll == INVALID_HANDLE_VALUE) {
      DWORD error = GetLastError();
      DLOG(ERROR) << __FUNCTION__ << " CreateFile( "
          << dir->c_str() << " ) failed. Error: " << error;
    } else {
      const size_t kChunkSize = 1024 * 1024; // 1 MB
      void* buffer = VirtualAlloc(NULL, kChunkSize, MEM_COMMIT, PAGE_READWRITE);
      if (buffer) {
        size_t read_size = pre_read_size_mb * kChunkSize;
        DWORD read = 0;
        while (::ReadFile(chrome_dll, buffer, kChunkSize, &read, NULL)) {
          // nothing to do here...
          read_size -= std::min(size_t(read), read_size);
          if (!read || !read_size)
            break;
        }

        VirtualFree(buffer, 0, MEM_RELEASE);
      }

      CloseHandle(chrome_dll);
    }
  }

  return ::LoadLibraryExW(dir->c_str(), NULL,
                          LOAD_WITH_ALTERED_SEARCH_PATH);
}

// Set did_run "dr" in omaha's client state for this product.
bool SetDidRunState(const wchar_t* guid, const wchar_t* value) {
  std::wstring key_path(google_update::kRegPathClientState);
  key_path.append(L"\\").append(guid);
  HKEY reg_key;
  if (::RegCreateKeyExW(HKEY_CURRENT_USER, key_path.c_str(), 0, NULL,
                        REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL,
                        &reg_key, NULL) == ERROR_SUCCESS) {
    // Note that the length here must be in bytes and must account for the
    // terminating null char.
    ::RegSetValueExW(reg_key, google_update::kRegDidRunField, 0, REG_SZ,
                     reinterpret_cast<const BYTE *>(value),
                     (::lstrlenW(value) + 1) * sizeof(wchar_t));
    ::RegCloseKey(reg_key);
    return true;
  }
  return false;
}

bool RecordDidRun(const wchar_t* guid) {
  return SetDidRunState(guid, L"1");
}

bool ClearDidRun(const wchar_t* guid) {
  return SetDidRunState(guid, L"0");
}

}
//=============================================================================

MainDllLoader::MainDllLoader() : dll_(NULL) {
}

MainDllLoader::~MainDllLoader() {
#ifdef PURIFY
  // We should never unload the dll. There is only risk and no gain from
  // doing so. The singleton dtors have been already run by AtExitManager.
  ::FreeLibrary(dll_);
#endif
}

// Loading chrome is an interesting afair. First we try loading from the current
// directory to support run-what-you-compile and other development scenarios.
// If that fails then we look at the 'CHROME_VERSION' env variable to determine
// if we should stick with an older dll version even if a new one is available
// to support upgrade-in-place scenarios, and if that fails we finally we look
// at the registry which should point us to the latest version.
HMODULE MainDllLoader::Load(std::wstring* version, std::wstring* file) {
  std::wstring dir(GetExecutablePath());
  *file = dir;
  HMODULE dll = LoadChromeWithDirectory(file);
  if (dll)
    return dll;

  if (!EnvQueryStr(
          BrowserDistribution::GetDistribution()->GetEnvVersionKey().c_str(),
          version)) {
    std::wstring reg_path(GetRegistryPath());
    // Look into the registry to find the latest version.
    if (!GetVersion(dir.c_str(), reg_path.c_str(), version))
      return NULL;
  }

  *file = dir;
  file->append(*version).append(L"\\");
  return LoadChromeWithDirectory(file);
}

// Launching is a matter of loading the right dll, setting the CHROME_VERSION
// environment variable and just calling the entry point. Derived classes can
// add custom code in the OnBeforeLaunch callback.
int MainDllLoader::Launch(HINSTANCE instance,
                          sandbox::SandboxInterfaceInfo* sbox_info) {
  std::wstring version;
  std::wstring file;
  dll_ = Load(&version, &file);
  if (!dll_)
    return ResultCodes::MISSING_DATA;

  ::SetEnvironmentVariableW(
      BrowserDistribution::GetDistribution()->GetEnvVersionKey().c_str(),
      version.c_str());

  InitCrashReporterWithDllPath(file);
  OnBeforeLaunch(version);

  DLL_MAIN entry_point =
      reinterpret_cast<DLL_MAIN>(::GetProcAddress(dll_, "ChromeMain"));
  if (!entry_point)
    return ResultCodes::BAD_PROCESS_TYPE;

  int rc = entry_point(instance, sbox_info, ::GetCommandLineW());
  return OnBeforeExit(rc);
}

void MainDllLoader::RelaunchChromeBrowserWithNewCommandLineIfNeeded() {
  RelaunchChromeBrowserWithNewCommandLineIfNeededFunc relaunch_function =
      reinterpret_cast<RelaunchChromeBrowserWithNewCommandLineIfNeededFunc>(
          ::GetProcAddress(dll_,
                           "RelaunchChromeBrowserWithNewCommandLineIfNeeded"));
  if (!relaunch_function) {
    LOG(ERROR) << "Could not find exported function "
               << "RelaunchChromeBrowserWithNewCommandLineIfNeeded";
  } else {
    relaunch_function();
  }
}

//=============================================================================

class ChromeDllLoader : public MainDllLoader {
 public:
  virtual std::wstring GetRegistryPath() {
    std::wstring key(google_update::kRegPathClients);
    BrowserDistribution* dist = BrowserDistribution::GetDistribution();
    key.append(L"\\").append(dist->GetAppGuid());
    return key;
  }

  virtual void OnBeforeLaunch(const std::wstring& version) {
    BrowserDistribution* dist = BrowserDistribution::GetDistribution();
    RecordDidRun(dist->GetAppGuid().c_str());
  }

  virtual int OnBeforeExit(int return_code) {
    // NORMAL_EXIT_CANCEL is used for experiments when the user cancels
    // so we need to reset the did_run signal so omaha does not count
    // this run as active usage.
    if (ResultCodes::NORMAL_EXIT_CANCEL == return_code) {
      BrowserDistribution* dist = BrowserDistribution::GetDistribution();
      ClearDidRun(dist->GetAppGuid().c_str());
    }
    return return_code;
  }
};

//=============================================================================

class ChromiumDllLoader : public MainDllLoader {
 public:
  virtual std::wstring GetRegistryPath() {
    BrowserDistribution* dist = BrowserDistribution::GetDistribution();
    return dist->GetVersionKey();
  }
};

MainDllLoader* MakeMainDllLoader() {
#if defined(GOOGLE_CHROME_BUILD)
  return new ChromeDllLoader();
#else
  return new ChromiumDllLoader();
#endif
}
<commit_msg>Previously we didn't pre-read at all if there was any configuration in the ChromeFrame key. This change makes that decision sensitive to the existance of the PreRead value, not just the existance of the ChromeFrame key.<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 <windows.h>
#include <shlwapi.h>

#include "chrome/app/breakpad_win.h"
#include "chrome/app/client_util.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/result_codes.h"
#include "chrome/installer/util/browser_distribution.h"
#include "chrome/installer/util/install_util.h"
#include "chrome/installer/util/google_update_constants.h"
#include "chrome/installer/util/util_constants.h"

namespace {
// The entry point signature of chrome.dll.
typedef int (*DLL_MAIN)(HINSTANCE, sandbox::SandboxInterfaceInfo*, wchar_t*);

typedef void (*RelaunchChromeBrowserWithNewCommandLineIfNeededFunc)();

// Not generic, we only handle strings up to 128 chars.
bool ReadRegistryStr(HKEY key, const wchar_t* name, std::wstring* value) {
  BYTE out[128 * sizeof(wchar_t)];
  DWORD size = sizeof(out);
  DWORD type = 0;
  if (ERROR_SUCCESS != ::RegQueryValueExW(key, name, NULL, &type, out, &size))
    return false;
  if (type != REG_SZ)
    return false;
  value->assign(reinterpret_cast<wchar_t*>(out));
  return true;
}

// Gets chrome version according to the load path. |exe_path| must be the
// backslash terminated directory of the current chrome.exe.
bool GetVersion(const wchar_t* exe_path, const wchar_t* key_path,
                std::wstring* version) {
  HKEY reg_root = InstallUtil::IsPerUserInstall(exe_path) ? HKEY_CURRENT_USER :
                                                            HKEY_LOCAL_MACHINE;
  HKEY key;
  if (::RegOpenKeyEx(reg_root, key_path, 0, KEY_READ, &key) != ERROR_SUCCESS)
    return false;

  // If 'new_chrome.exe' is present it means chrome was auto-updated while
  // running. We need to consult the opv value so we can load the old dll.
  // TODO(cpu) : This is solving the same problem as the environment variable
  // so one of them will eventually be deprecated.
  std::wstring new_chrome_exe(exe_path);
  new_chrome_exe.append(installer_util::kChromeNewExe);
  if (::PathFileExistsW(new_chrome_exe.c_str()) &&
      ReadRegistryStr(key, google_update::kRegOldVersionField, version)) {
    ::RegCloseKey(key);
    return true;
  }

  bool ret = ReadRegistryStr(key, google_update::kRegVersionField, version);
  ::RegCloseKey(key);
  return ret;
}

// Gets the path of the current exe with a trailing backslash.
std::wstring GetExecutablePath() {
  wchar_t path[MAX_PATH];
  ::GetModuleFileNameW(NULL, path, MAX_PATH);
  if (!::PathRemoveFileSpecW(path))
    return std::wstring();
  std::wstring exe_path(path);
  return exe_path.append(L"\\");
}

// Not generic, we only handle strings up to 128 chars.
bool EnvQueryStr(const wchar_t* key_name, std::wstring* value) {
  wchar_t out[128];
  DWORD count = sizeof(out)/sizeof(out[0]);
  DWORD rv = ::GetEnvironmentVariableW(key_name, out, count);
  if ((rv == 0) || (rv >= count))
    return false;
  *value = out;
  return true;
}

bool IsRunningHeadless() {
  return (0 != ::GetEnvironmentVariableW(L"CHROME_HEADLESS", NULL, 0));
}

// Expects that |dir| has a trailing backslash. |dir| is modified so it
// contains the full path that was tried. Caller must check for the return
// value not being null to dermine if this path contains a valid dll.
HMODULE LoadChromeWithDirectory(std::wstring* dir) {
  ::SetCurrentDirectoryW(dir->c_str());
  const CommandLine& cmd_line = *CommandLine::ForCurrentProcess();
#ifdef _WIN64
  if ((cmd_line.GetSwitchValueASCII(switches::kProcessType) ==
      switches::kNaClBrokerProcess) ||
      (cmd_line.GetSwitchValueASCII(switches::kProcessType) ==
      switches::kNaClLoaderProcess)) {
    // Load the 64-bit DLL when running in a 64-bit process.
    dir->append(installer_util::kChromeNaCl64Dll);
  } else {
    // Only NaCl broker and loader can be launched as Win64 processes.
    NOTREACHED();
    return NULL;
  }
#else
  dir->append(installer_util::kChromeDll);
#endif

  // Experimental pre-reading optimization
  // The idea is to pre read significant portion of chrome.dll in advance
  // so that subsequent hard page faults are avoided.
  DWORD pre_read_size_mb = 0;
  if (!cmd_line.HasSwitch(switches::kProcessType) &&
      (IsRunningHeadless() || InstallUtil::IsChromeFrameProcess())) {
    HKEY key = NULL;
    if (::RegOpenKeyEx(HKEY_CURRENT_USER, L"Software\\Google\\ChromeFrame",
                       0, KEY_QUERY_VALUE, &key) == ERROR_SUCCESS) {
      DWORD unused = sizeof(pre_read_size_mb);
      if (::RegQueryValueEx(key, L"PreRead", NULL, NULL,
                            reinterpret_cast<LPBYTE>(&pre_read_size_mb),
                            &unused) != ERROR_SUCCESS) {
        pre_read_size_mb = 16; // Default
      }
      RegCloseKey(key);
      key = NULL;
    } else {
      pre_read_size_mb = 16; // Read in first 16 MB by default.
    }
  }

  if (pre_read_size_mb) {
    HANDLE chrome_dll = CreateFile(dir->c_str(),
                                       GENERIC_READ,
                                       FILE_SHARE_READ | FILE_SHARE_WRITE,
                                       NULL,
                                       OPEN_EXISTING,
                                       FILE_FLAG_SEQUENTIAL_SCAN,
                                       NULL);
    if (chrome_dll == INVALID_HANDLE_VALUE) {
      DWORD error = GetLastError();
      DLOG(ERROR) << __FUNCTION__ << " CreateFile( "
          << dir->c_str() << " ) failed. Error: " << error;
    } else {
      const size_t kChunkSize = 1024 * 1024; // 1 MB
      void* buffer = VirtualAlloc(NULL, kChunkSize, MEM_COMMIT, PAGE_READWRITE);
      if (buffer) {
        size_t read_size = pre_read_size_mb * kChunkSize;
        DWORD read = 0;
        while (::ReadFile(chrome_dll, buffer, kChunkSize, &read, NULL)) {
          // nothing to do here...
          read_size -= std::min(size_t(read), read_size);
          if (!read || !read_size)
            break;
        }

        VirtualFree(buffer, 0, MEM_RELEASE);
      }

      CloseHandle(chrome_dll);
    }
  }

  return ::LoadLibraryExW(dir->c_str(), NULL,
                          LOAD_WITH_ALTERED_SEARCH_PATH);
}

// Set did_run "dr" in omaha's client state for this product.
bool SetDidRunState(const wchar_t* guid, const wchar_t* value) {
  std::wstring key_path(google_update::kRegPathClientState);
  key_path.append(L"\\").append(guid);
  HKEY reg_key;
  if (::RegCreateKeyExW(HKEY_CURRENT_USER, key_path.c_str(), 0, NULL,
                        REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL,
                        &reg_key, NULL) == ERROR_SUCCESS) {
    // Note that the length here must be in bytes and must account for the
    // terminating null char.
    ::RegSetValueExW(reg_key, google_update::kRegDidRunField, 0, REG_SZ,
                     reinterpret_cast<const BYTE *>(value),
                     (::lstrlenW(value) + 1) * sizeof(wchar_t));
    ::RegCloseKey(reg_key);
    return true;
  }
  return false;
}

bool RecordDidRun(const wchar_t* guid) {
  return SetDidRunState(guid, L"1");
}

bool ClearDidRun(const wchar_t* guid) {
  return SetDidRunState(guid, L"0");
}

}
//=============================================================================

MainDllLoader::MainDllLoader() : dll_(NULL) {
}

MainDllLoader::~MainDllLoader() {
#ifdef PURIFY
  // We should never unload the dll. There is only risk and no gain from
  // doing so. The singleton dtors have been already run by AtExitManager.
  ::FreeLibrary(dll_);
#endif
}

// Loading chrome is an interesting afair. First we try loading from the current
// directory to support run-what-you-compile and other development scenarios.
// If that fails then we look at the 'CHROME_VERSION' env variable to determine
// if we should stick with an older dll version even if a new one is available
// to support upgrade-in-place scenarios, and if that fails we finally we look
// at the registry which should point us to the latest version.
HMODULE MainDllLoader::Load(std::wstring* version, std::wstring* file) {
  std::wstring dir(GetExecutablePath());
  *file = dir;
  HMODULE dll = LoadChromeWithDirectory(file);
  if (dll)
    return dll;

  if (!EnvQueryStr(
          BrowserDistribution::GetDistribution()->GetEnvVersionKey().c_str(),
          version)) {
    std::wstring reg_path(GetRegistryPath());
    // Look into the registry to find the latest version.
    if (!GetVersion(dir.c_str(), reg_path.c_str(), version))
      return NULL;
  }

  *file = dir;
  file->append(*version).append(L"\\");
  return LoadChromeWithDirectory(file);
}

// Launching is a matter of loading the right dll, setting the CHROME_VERSION
// environment variable and just calling the entry point. Derived classes can
// add custom code in the OnBeforeLaunch callback.
int MainDllLoader::Launch(HINSTANCE instance,
                          sandbox::SandboxInterfaceInfo* sbox_info) {
  std::wstring version;
  std::wstring file;
  dll_ = Load(&version, &file);
  if (!dll_)
    return ResultCodes::MISSING_DATA;

  ::SetEnvironmentVariableW(
      BrowserDistribution::GetDistribution()->GetEnvVersionKey().c_str(),
      version.c_str());

  InitCrashReporterWithDllPath(file);
  OnBeforeLaunch(version);

  DLL_MAIN entry_point =
      reinterpret_cast<DLL_MAIN>(::GetProcAddress(dll_, "ChromeMain"));
  if (!entry_point)
    return ResultCodes::BAD_PROCESS_TYPE;

  int rc = entry_point(instance, sbox_info, ::GetCommandLineW());
  return OnBeforeExit(rc);
}

void MainDllLoader::RelaunchChromeBrowserWithNewCommandLineIfNeeded() {
  RelaunchChromeBrowserWithNewCommandLineIfNeededFunc relaunch_function =
      reinterpret_cast<RelaunchChromeBrowserWithNewCommandLineIfNeededFunc>(
          ::GetProcAddress(dll_,
                           "RelaunchChromeBrowserWithNewCommandLineIfNeeded"));
  if (!relaunch_function) {
    LOG(ERROR) << "Could not find exported function "
               << "RelaunchChromeBrowserWithNewCommandLineIfNeeded";
  } else {
    relaunch_function();
  }
}

//=============================================================================

class ChromeDllLoader : public MainDllLoader {
 public:
  virtual std::wstring GetRegistryPath() {
    std::wstring key(google_update::kRegPathClients);
    BrowserDistribution* dist = BrowserDistribution::GetDistribution();
    key.append(L"\\").append(dist->GetAppGuid());
    return key;
  }

  virtual void OnBeforeLaunch(const std::wstring& version) {
    BrowserDistribution* dist = BrowserDistribution::GetDistribution();
    RecordDidRun(dist->GetAppGuid().c_str());
  }

  virtual int OnBeforeExit(int return_code) {
    // NORMAL_EXIT_CANCEL is used for experiments when the user cancels
    // so we need to reset the did_run signal so omaha does not count
    // this run as active usage.
    if (ResultCodes::NORMAL_EXIT_CANCEL == return_code) {
      BrowserDistribution* dist = BrowserDistribution::GetDistribution();
      ClearDidRun(dist->GetAppGuid().c_str());
    }
    return return_code;
  }
};

//=============================================================================

class ChromiumDllLoader : public MainDllLoader {
 public:
  virtual std::wstring GetRegistryPath() {
    BrowserDistribution* dist = BrowserDistribution::GetDistribution();
    return dist->GetVersionKey();
  }
};

MainDllLoader* MakeMainDllLoader() {
#if defined(GOOGLE_CHROME_BUILD)
  return new ChromeDllLoader();
#else
  return new ChromiumDllLoader();
#endif
}
<|endoftext|>


<commit_before>#include <iostream>
#include <cstdlib>
#include <cstdio>
#include "util.h"

using namespace std;

void status(string message) {
  cout << "[+] " << message << "\n";
}

void header() {
  cout << "SIC-Disassembler v1.0 by Jay Bosamiya\n"
          "-------------------------------------\n\n";
}

void usage(string progname) {
  cerr << "Usage: " << progname << " input_object_file output_assembly_file\n";
  exit(-2);
}

void error(string err) {
  cerr << "[!] Error: " << err << "\n";
}

void fatal(string err, int code) {
  error(err);
  exit(code);
}

bool is_hex_digit(char c) {
	return
		(c >= 'A' && c <= 'F') ||
		(c >= '0' && c <= '9');
}

bool is_hex_string(std::string s) {
	bool ret = true;
	for ( const char *c = s.c_str(); *c && ret ; c++ ) {
		ret = ret && is_hex_digit(*c);
	}
	return ret;
}

void make_upper_case(std::string &s) {
	for ( string::iterator c = s.begin() ; c != s.end() ; c++ ) {
		if ( *c >= 'a' && *c <= 'z' ) {
			*c = (*c - 'a') + 'A';
		}
	}
}

int hexchar2int(char c) {
	int ret = -1;
	if ( c >= '0' && c <= '9' ) {
		ret = (c-'0');
	} else if ( c >= 'A' && c <= 'F' ) {
		ret = (c-'A')+10;
	}
	return ret;
}

int hex2int(string s) {
	int ret = 0;
	for ( const char * cc = s.c_str() ; *cc ; cc++ ) {
		ret *= 16;
		const char &c = *cc;
		if ( is_hex_digit(c) ) {
			ret += hexchar2int(c);
		} else {
			fatal("Hex values need to be 0-9 or A-F");
		}
	}
	return ret;
}

string byte2hex(int c) {
	string ret = "";
	if ( c < 0 || c >= 256 ) {
		fatal("Illegal value for byte");
	}
	ret += (c/16 < 10)?('0'+c/16):('A'+c/16-10);
	ret += (c%16 < 10)?('0'+c%16):('A'+c%16-10);
	return ret;
}

string int2hex(int c, int bytes) {
	if ( c < 0 ) {
		return int2hex(c&0x7FFFFFFF,bytes);
	}
	if ( bytes <= 0 ) {
		return "";
	}
	return int2hex(c/256,bytes-1)+byte2hex(c%256);
}

std::string int2str(int c) {
	char ret[20];
	sprintf(ret,"%d",c);
	return ret;
}
<commit_msg>Change version number<commit_after>#include <iostream>
#include <cstdlib>
#include <cstdio>
#include "util.h"

using namespace std;

void status(string message) {
  cout << "[+] " << message << "\n";
}

void header() {
  cout << "SIC-Disassembler v1.1 by Jay Bosamiya\n"
          "-------------------------------------\n\n";
}

void usage(string progname) {
  cerr << "Usage: " << progname << " input_object_file output_assembly_file\n";
  exit(-2);
}

void error(string err) {
  cerr << "[!] Error: " << err << "\n";
}

void fatal(string err, int code) {
  error(err);
  exit(code);
}

bool is_hex_digit(char c) {
	return
		(c >= 'A' && c <= 'F') ||
		(c >= '0' && c <= '9');
}

bool is_hex_string(std::string s) {
	bool ret = true;
	for ( const char *c = s.c_str(); *c && ret ; c++ ) {
		ret = ret && is_hex_digit(*c);
	}
	return ret;
}

void make_upper_case(std::string &s) {
	for ( string::iterator c = s.begin() ; c != s.end() ; c++ ) {
		if ( *c >= 'a' && *c <= 'z' ) {
			*c = (*c - 'a') + 'A';
		}
	}
}

int hexchar2int(char c) {
	int ret = -1;
	if ( c >= '0' && c <= '9' ) {
		ret = (c-'0');
	} else if ( c >= 'A' && c <= 'F' ) {
		ret = (c-'A')+10;
	}
	return ret;
}

int hex2int(string s) {
	int ret = 0;
	for ( const char * cc = s.c_str() ; *cc ; cc++ ) {
		ret *= 16;
		const char &c = *cc;
		if ( is_hex_digit(c) ) {
			ret += hexchar2int(c);
		} else {
			fatal("Hex values need to be 0-9 or A-F");
		}
	}
	return ret;
}

string byte2hex(int c) {
	string ret = "";
	if ( c < 0 || c >= 256 ) {
		fatal("Illegal value for byte");
	}
	ret += (c/16 < 10)?('0'+c/16):('A'+c/16-10);
	ret += (c%16 < 10)?('0'+c%16):('A'+c%16-10);
	return ret;
}

string int2hex(int c, int bytes) {
	if ( c < 0 ) {
		return int2hex(c&0x7FFFFFFF,bytes);
	}
	if ( bytes <= 0 ) {
		return "";
	}
	return int2hex(c/256,bytes-1)+byte2hex(c%256);
}

std::string int2str(int c) {
	char ret[20];
	sprintf(ret,"%d",c);
	return ret;
}
<|endoftext|>


<commit_before>#include "LevelEditDlg.h"

#include "dataset/LevelCfg.h"
#include "dataset/DynamicWidget.h"

namespace lr
{

LevelEditDlg::LevelEditDlg(wxWindow* parent, d2d::ISprite* spr)
	: CfgEditDlg(parent, "Level", spr)
{
	InitData(spr);
	InitLayout();
}

std::string LevelEditDlg::ToString()
{
	std::string ret = "type=" + m_type + ";";
 	for (int i = 0, n = m_widgets.size(); i < n; ++i) {
 		DynamicWidget* dw = m_widgets[i];
		if (dw->GetValue() == DEFAULT_VAL) {
			continue;
		}
		if (dw->GetTag() == "sprite" || dw->IsChanged()) {
			ret += dw->GetKey() + "=" + dw->GetValue() + ";";
 		}
 	}
	return ret;
}

void LevelEditDlg::InitData(d2d::ISprite* spr)
{
	if (spr->tag.find("[symbol]") != std::string::npos) {
		m_info.LoadFromString(spr->GetSymbol().tag, "symbol");
	}
	m_info.LoadFromString(spr->tag, "sprite");

	m_type = m_info.QueryValue("type");
}

void LevelEditDlg::InitLayout()
{
	if (m_type.empty()) {
		return;
	}

	int col;
	if (!LevelCfg::Instance()->QueryLayout(m_type, col, m_widgets)) {
		return;
	}

	CfgEditDlg::InitLayout(col, m_widgets);
}

}<commit_msg>[ADDED] lr level dlg's type<commit_after>#include "LevelEditDlg.h"

#include "dataset/LevelCfg.h"
#include "dataset/DynamicWidget.h"

namespace lr
{

LevelEditDlg::LevelEditDlg(wxWindow* parent, d2d::ISprite* spr)
	: CfgEditDlg(parent, "Level", spr)
{
	InitData(spr);
	InitLayout();

	SetTitle(m_type.c_str());
}

std::string LevelEditDlg::ToString()
{
	std::string ret = "type=" + m_type + ";";
 	for (int i = 0, n = m_widgets.size(); i < n; ++i) {
 		DynamicWidget* dw = m_widgets[i];
		if (dw->GetValue() == DEFAULT_VAL) {
			continue;
		}
		if (dw->GetTag() == "sprite" || dw->IsChanged()) {
			ret += dw->GetKey() + "=" + dw->GetValue() + ";";
 		}
 	}
	return ret;
}

void LevelEditDlg::InitData(d2d::ISprite* spr)
{
	if (spr->tag.find("[symbol]") != std::string::npos) {
		m_info.LoadFromString(spr->GetSymbol().tag, "symbol");
	}
	m_info.LoadFromString(spr->tag, "sprite");

	m_type = m_info.QueryValue("type");
}

void LevelEditDlg::InitLayout()
{
	if (m_type.empty()) {
		return;
	}

	int col;
	if (!LevelCfg::Instance()->QueryLayout(m_type, col, m_widgets)) {
		return;
	}

	CfgEditDlg::InitLayout(col, m_widgets);
}

}<|endoftext|>


<commit_before>#include "ltl/detail/task_queue_impl.hpp"

#include "ltlcontext/ltlcontext.hpp"
#include "ltl/detail/task_context.hpp"
#include "ltl/detail/current_task_context.hpp"
#include "ltl/detail/log.hpp"

#include <condition_variable>
#include <thread>
#include <mutex>
#include <deque>
#include <vector>

#include "stdio.h"
#include "assert.h"

namespace ltl {
namespace detail {

namespace {
enum class scheduling_policy { resumable, non_resumable };
using namespace std::placeholders;
} // namespace

struct task_queue_impl::impl
{
    explicit impl(task_queue_impl* task_queue, char const* name)
    : main_context_(create_main_context(), &destroy_main_context)
    , name_(name ? name : "unnamed")
    , mutex_()
    , join_(false)
    , cv_()
    , queue_()
    , thread_([&]() {
        auto&& work_to_do = [&](){ return !queue_.empty() || join_; };

        while (true)
        {
            work_item wi;
            {
                std::unique_lock<std::mutex> lock(mutex_);

                if (!work_to_do())
                {
                    LTL_LOG("task_queue_impl waiting... %s\n", name_);
                    cv_.wait(lock, work_to_do);
                    LTL_LOG("task_queue_impl wakeup %s\n", name_);
                }

                if (join_ && in_progress_count_ == 0)
                    break;

                if (queue_.empty())
                    continue;

                wi.swap(queue_.front());
                queue_.pop_front();
            }

            if (wi.first)
            {
                if (wi.second == scheduling_policy::resumable)
                {
                    run_in_new_context(std::move(wi.first));
                }
                else
                {
                    LTL_LOG("task_queue_impl run first %s\n", name_);
                    wi.first();
                }
            }
        }

        LTL_LOG("task_queue_impl leaving thread loop %s\n", name_);
    })
    , task_queue_(task_queue)
    , in_progress_count_(0)
    {

    }

    void run_in_new_context(std::function<void()>&& func)
    {
        assert(!current_task_context::get());

        std::shared_ptr<task_context> ctx;
        if (free_task_contexts_.empty())
        {
            ctx = task_context::create(main_context_.get(), std::bind(&impl::task_complete, this, _1),
                                       task_queue_);
        }
        else
        {
            ctx = free_task_contexts_.back();
            free_task_contexts_.pop_back();
        }
        LTL_LOG("task_queue_impl::run_in_new_context %s %p\n", name_, ctx.get());

        ctx->reset(std::move(func));
        ++in_progress_count_;
        ctx->resume();

        LTL_LOG("task_queue_impl::run_in_new_context complete %s %p\n", name_, ctx.get());
    }

    ~impl()
    {
        join();
    }

    void push_back(std::function<void()> task, scheduling_policy sched_policy)
    {
        std::lock_guard<std::mutex> lock(mutex_);
        queue_.emplace_back(work_item(std::move(task), sched_policy));
        if (queue_.size() == 1)
            cv_.notify_one();
    }

    void push_front(std::function<void()> task)
    {
        std::lock_guard<std::mutex> lock(mutex_);
        queue_.emplace_front(work_item(std::move(task), scheduling_policy::non_resumable));
        if (queue_.size() == 1)
            cv_.notify_one();
    }

    void join()
    {
        if (thread_.joinable())
        {
            {
                std::lock_guard<std::mutex> lock(mutex_);
                queue_.clear();
                join_ = true;
                cv_.notify_one();
            }
            thread_.join();
        }
    }

    void task_complete(std::shared_ptr<task_context> const& ctx)
    {
        --in_progress_count_;
        free_task_contexts_.push_back(ctx);

        if (in_progress_count_ == 0)
        {
            std::lock_guard<std::mutex> lock(mutex_);
            if (join_)
                cv_.notify_one();
        }
    }

    typedef std::function<void()> task;
    typedef std::pair<task, scheduling_policy> work_item;

    std::unique_ptr<context, void(*)(context*)> main_context_;
    char const* const name_;
    mutable std::mutex mutex_;
    bool join_;
    std::condition_variable cv_;
    std::deque<work_item> queue_;
    std::thread thread_;
    std::vector<std::shared_ptr<task_context>> free_task_contexts_;
    task_queue_impl* const task_queue_;
    int in_progress_count_;
};

task_queue_impl::task_queue_impl(char const* name)
: impl_(new impl(this, name))
{

}

task_queue_impl::~task_queue_impl()
{

}

void task_queue_impl::push_back_resumable(std::function<void()> task)
{
    impl_->push_back(std::move(task), scheduling_policy::resumable);
}

void task_queue_impl::push_back(std::function<void()> task)
{
    impl_->push_back(std::move(task), scheduling_policy::non_resumable);
}

void task_queue_impl::push_front(std::function<void()> task)
{
    impl_->push_front(std::move(task));
}

void task_queue_impl::join()
{
    impl_->join();
}

} // namespace detail
} // namespace ltl
<commit_msg>Now calling create_main_context from correct thread (required for fibers).<commit_after>#include "ltl/detail/task_queue_impl.hpp"

#include "ltlcontext/ltlcontext.hpp"
#include "ltl/detail/task_context.hpp"
#include "ltl/detail/current_task_context.hpp"
#include "ltl/detail/log.hpp"

#include <condition_variable>
#include <thread>
#include <mutex>
#include <deque>
#include <vector>

#include "stdio.h"
#include "assert.h"

namespace ltl {
namespace detail {

namespace {
enum class scheduling_policy { resumable, non_resumable };
using namespace std::placeholders;
} // namespace

struct task_queue_impl::impl
{
    explicit impl(task_queue_impl* task_queue, char const* name)
    : main_context_(nullptr, &destroy_main_context)
    , name_(name ? name : "unnamed")
    , mutex_()
    , join_(false)
    , cv_()
    , queue_()
    , thread_([&]() {
		main_context_.reset(create_main_context());

        auto&& work_to_do = [&](){ return !queue_.empty() || join_; };

        while (true)
        {
            work_item wi;
            {
                std::unique_lock<std::mutex> lock(mutex_);

                if (!work_to_do())
                {
                    LTL_LOG("task_queue_impl waiting... %s\n", name_);
                    cv_.wait(lock, work_to_do);
                    LTL_LOG("task_queue_impl wakeup %s\n", name_);
                }

                if (join_ && in_progress_count_ == 0)
                    break;

                if (queue_.empty())
                    continue;

                wi.swap(queue_.front());
                queue_.pop_front();
            }

            if (wi.first)
            {
                if (wi.second == scheduling_policy::resumable)
                {
                    run_in_new_context(std::move(wi.first));
                }
                else
                {
                    LTL_LOG("task_queue_impl run first %s\n", name_);
                    wi.first();
                }
            }
        }

        LTL_LOG("task_queue_impl leaving thread loop %s\n", name_);
    })
    , task_queue_(task_queue)
    , in_progress_count_(0)
    {

    }

    void run_in_new_context(std::function<void()>&& func)
    {
        assert(!current_task_context::get());

        std::shared_ptr<task_context> ctx;
        if (free_task_contexts_.empty())
        {
            ctx = task_context::create(main_context_.get(), std::bind(&impl::task_complete, this, _1),
                                       task_queue_);
        }
        else
        {
            ctx = free_task_contexts_.back();
            free_task_contexts_.pop_back();
        }
        LTL_LOG("task_queue_impl::run_in_new_context %s %p\n", name_, ctx.get());

        ctx->reset(std::move(func));
        ++in_progress_count_;
        ctx->resume();

        LTL_LOG("task_queue_impl::run_in_new_context complete %s %p\n", name_, ctx.get());
    }

    ~impl()
    {
        join();
    }

    void push_back(std::function<void()> task, scheduling_policy sched_policy)
    {
        std::lock_guard<std::mutex> lock(mutex_);
        queue_.emplace_back(work_item(std::move(task), sched_policy));
        if (queue_.size() == 1)
            cv_.notify_one();
    }

    void push_front(std::function<void()> task)
    {
        std::lock_guard<std::mutex> lock(mutex_);
        queue_.emplace_front(work_item(std::move(task), scheduling_policy::non_resumable));
        if (queue_.size() == 1)
            cv_.notify_one();
    }

    void join()
    {
        if (thread_.joinable())
        {
            {
                std::lock_guard<std::mutex> lock(mutex_);
                queue_.clear();
                join_ = true;
                cv_.notify_one();
            }
            thread_.join();
        }
    }

    void task_complete(std::shared_ptr<task_context> const& ctx)
    {
        --in_progress_count_;
        free_task_contexts_.push_back(ctx);

        if (in_progress_count_ == 0)
        {
            std::lock_guard<std::mutex> lock(mutex_);
            if (join_)
                cv_.notify_one();
        }
    }

    typedef std::function<void()> task;
    typedef std::pair<task, scheduling_policy> work_item;

    std::unique_ptr<context, void(*)(context*)> main_context_;
    char const* const name_;
    mutable std::mutex mutex_;
    bool join_;
    std::condition_variable cv_;
    std::deque<work_item> queue_;
    std::thread thread_;
    std::vector<std::shared_ptr<task_context>> free_task_contexts_;
    task_queue_impl* const task_queue_;
    int in_progress_count_;
};

task_queue_impl::task_queue_impl(char const* name)
: impl_(new impl(this, name))
{

}

task_queue_impl::~task_queue_impl()
{

}

void task_queue_impl::push_back_resumable(std::function<void()> task)
{
    impl_->push_back(std::move(task), scheduling_policy::resumable);
}

void task_queue_impl::push_back(std::function<void()> task)
{
    impl_->push_back(std::move(task), scheduling_policy::non_resumable);
}

void task_queue_impl::push_front(std::function<void()> task)
{
    impl_->push_front(std::move(task));
}

void task_queue_impl::join()
{
    impl_->join();
}

} // namespace detail
} // namespace ltl
<|endoftext|>


<commit_before>// Copyright 2018 Global Phasing Ltd.

#include <complex>

// for symmetrize_min and symmetrize_max
bool operator<(const std::complex<float>& a, const std::complex<float>& b) {
    return std::norm(a) < std::norm(b);
}
bool operator>(const std::complex<float>& a, const std::complex<float>& b) {
    return std::norm(a) > std::norm(b);
}

#include "gemmi/grid.hpp"
#include "gemmi/solmask.hpp"  // for mask_points_in_constant_radius
#include "gemmi/tostr.hpp"

#include "common.h"
#include <pybind11/complex.h>
#include <pybind11/stl.h>
#include <pybind11/numpy.h>

namespace py = pybind11;
using namespace gemmi;

template<typename T>
void add_grid(py::module& m, const std::string& name) {
  using GrBase = GridBase<T>;
  using Gr = Grid<T>;
  using Masked = MaskedGrid<T>;
  using GrPoint = typename Gr::Point;

  py::class_<GrBase> pyGridBase(m, (name + "Base").c_str(), py::buffer_protocol());
  py::class_<Gr, GrBase> gr(m, name.c_str());
  py::class_<Masked> pyMaskedGrid (m, ("Masked" + name).c_str());
  py::class_<GrPoint> pyGrPoint(gr, "Point");

  pyGridBase
    .def_buffer([](GrBase &g) {
      return py::buffer_info(g.data.data(),
                             {g.nu, g.nv, g.nw},       // dimensions
                             {sizeof(T),               // strides
                              sizeof(T) * g.nu,
                              sizeof(T) * g.nu * g.nv});
    })
    .def_readonly("nu", &GrBase::nu, "size in the first (fastest-changing) dim")
    .def_readonly("nv", &GrBase::nv, "size in the second dimension")
    .def_readonly("nw", &GrBase::nw, "size in the third (slowest-changing) dim")
    .def_property_readonly("shape", [](const GrBase& self){
      return py::make_tuple(self.nu, self.nv, self.nw);
    })
    .def_readwrite("spacegroup", &GrBase::spacegroup)
    .def_readwrite("unit_cell", &GrBase::unit_cell)
    .def_readonly("axis_order", &GrBase::axis_order)
    .def_property_readonly("point_count", &GrBase::point_count)
    .def("fill", &GrBase::fill, py::arg("value"))
    .def("sum", &GrBase::sum)
    .def("__iter__", [](GrBase& self) { return py::make_iterator(self); },
         py::keep_alive<0, 1>())
    ;

  gr
    .def(py::init<>())
    .def(py::init([](int nx, int ny, int nz) {
      Gr* grid = new Gr();
      grid->set_size(nx, ny, nz);
      return grid;
    }), py::arg("nx"), py::arg("ny"), py::arg("nz"))
    .def(py::init([](py::array_t<T> arr, const UnitCell *cell, const SpaceGroup* sg) {
      auto r = arr.template unchecked<3>();
      Gr* grid = new Gr();
      grid->set_size((int)r.shape(0), (int)r.shape(1), (int)r.shape(2));
      for (int k = 0; k < r.shape(2); ++k)
        for (int j = 0; j < r.shape(1); ++j)
          for (int i = 0; i < r.shape(0); ++i)
            grid->data[grid->index_q(i, j, k)] = r(i, j, k);
      if (cell)
        grid->set_unit_cell(*cell);
      if (sg)
        grid->spacegroup = sg;
      return grid;
    }), py::arg().noconvert(), py::arg("cell")=nullptr, py::arg("spacegroup")=nullptr)
    .def_property_readonly("spacing", [](const Gr& self){
        return py::make_tuple(self.spacing[0], self.spacing[1], self.spacing[2]);
    })
    .def("get_value", &Gr::get_value)
    .def("set_value", &Gr::set_value)
    .def("get_point", &Gr::get_point)
    .def("point_to_fractional", &Gr::point_to_fractional)
    .def("point_to_position", &Gr::point_to_position)
    .def("point_to_position", [](const Gr& self, int u, int v, int w) {
      GrPoint p = {u, v, w, nullptr};
      return self.point_to_position(p);
    }, py::arg("u"), py::arg("v"), py::arg("w"))
    .def("point_to_index", &Gr::point_to_index)
    .def("interpolate_value",
         (T (Gr::*)(const Fractional&) const) &Gr::interpolate_value)
    .def("interpolate_value",
         (T (Gr::*)(const Position&) const) &Gr::interpolate_value)
    .def("interpolate_values",
         [](const Gr& self, py::array_t<T> arr, const Transform& tr) {
        auto r = arr.template mutable_unchecked<3>();
        for (int i = 0; i < r.shape(0); ++i)
          for (int j = 0; j < r.shape(1); ++j)
            for (int k = 0; k < r.shape(2); ++k) {
              Position pos(tr.apply(Vec3(i, j, k)));
              r(i, j, k) = self.interpolate_value(pos);
            }
    }, py::arg().noconvert(), py::arg())
    .def("set_unit_cell", (void (Gr::*)(const UnitCell&)) &Gr::set_unit_cell)
    .def("set_points_around", &Gr::set_points_around,
         py::arg("position"), py::arg("radius"), py::arg("value"))
    .def("symmetrize_min", &Gr::symmetrize_min)
    .def("symmetrize_max", &Gr::symmetrize_max)
    .def("asu", &Gr::asu)
    .def("mask_points_in_constant_radius", &mask_points_in_constant_radius<T>,
         py::arg("model"), py::arg("radius"), py::arg("value"))
    .def("__repr__", [=](const Gr& self) {
        return tostr("<gemmi.", name, '(', self.nu, ", ", self.nv, ", ", self.nw, ")>");
    });

  pyGrPoint
    .def_readonly("u", &GrPoint::u)
    .def_readonly("v", &GrPoint::v)
    .def_readonly("w", &GrPoint::w)
    .def_property("value",
                  [](const GrPoint& self) { return *self.value; },
                  [](GrPoint& self, T x) { *self.value = x; })
    .def("__repr__", [=](const GrPoint& self) {
        return tostr("<gemmi.", name, "Point (", self.u, ", ", self.v, ", ",
                     self.w, ") -> ", +*self.value, '>');
    });
    ;

  pyMaskedGrid
    .def_readonly("grid", &Masked::grid, py::return_value_policy::reference)
    .def_readonly("mask", &Masked::mask)
    .def("__iter__", [](Masked& self) { return py::make_iterator(self); },
         py::keep_alive<0, 1>())
    ;
}

void add_grid(py::module& m) {
  py::enum_<AxisOrder>(m, "AxisOrder")
    .value("XYZ", AxisOrder::XYZ)
    .value("ZYX", AxisOrder::ZYX);
  add_grid<int8_t>(m, "Int8Grid");
  add_grid<float>(m, "FloatGrid");
  add_grid<std::complex<float>>(m, "ComplexGrid");
}
<commit_msg>python: add interpolate_positions() for pandda<commit_after>// Copyright 2018 Global Phasing Ltd.

#include <complex>

// for symmetrize_min and symmetrize_max
bool operator<(const std::complex<float>& a, const std::complex<float>& b) {
    return std::norm(a) < std::norm(b);
}
bool operator>(const std::complex<float>& a, const std::complex<float>& b) {
    return std::norm(a) > std::norm(b);
}

#include "gemmi/grid.hpp"
#include "gemmi/solmask.hpp"  // for mask_points_in_constant_radius
#include "gemmi/tostr.hpp"

#include "common.h"
#include <pybind11/complex.h>
#include <pybind11/stl.h>
#include <pybind11/numpy.h>

namespace py = pybind11;
using namespace gemmi;

template<typename T>
void add_grid(py::module& m, const std::string& name) {
  using GrBase = GridBase<T>;
  using Gr = Grid<T>;
  using Masked = MaskedGrid<T>;
  using GrPoint = typename Gr::Point;

  py::class_<GrBase> pyGridBase(m, (name + "Base").c_str(), py::buffer_protocol());
  py::class_<Gr, GrBase> gr(m, name.c_str());
  py::class_<Masked> pyMaskedGrid (m, ("Masked" + name).c_str());
  py::class_<GrPoint> pyGrPoint(gr, "Point");

  pyGridBase
    .def_buffer([](GrBase &g) {
      return py::buffer_info(g.data.data(),
                             {g.nu, g.nv, g.nw},       // dimensions
                             {sizeof(T),               // strides
                              sizeof(T) * g.nu,
                              sizeof(T) * g.nu * g.nv});
    })
    .def_readonly("nu", &GrBase::nu, "size in the first (fastest-changing) dim")
    .def_readonly("nv", &GrBase::nv, "size in the second dimension")
    .def_readonly("nw", &GrBase::nw, "size in the third (slowest-changing) dim")
    .def_property_readonly("shape", [](const GrBase& self){
      return py::make_tuple(self.nu, self.nv, self.nw);
    })
    .def_readwrite("spacegroup", &GrBase::spacegroup)
    .def_readwrite("unit_cell", &GrBase::unit_cell)
    .def_readonly("axis_order", &GrBase::axis_order)
    .def_property_readonly("point_count", &GrBase::point_count)
    .def("fill", &GrBase::fill, py::arg("value"))
    .def("sum", &GrBase::sum)
    .def("__iter__", [](GrBase& self) { return py::make_iterator(self); },
         py::keep_alive<0, 1>())
    ;

  gr
    .def(py::init<>())
    .def(py::init([](int nx, int ny, int nz) {
      Gr* grid = new Gr();
      grid->set_size(nx, ny, nz);
      return grid;
    }), py::arg("nx"), py::arg("ny"), py::arg("nz"))
    .def(py::init([](py::array_t<T> arr, const UnitCell *cell, const SpaceGroup* sg) {
      auto r = arr.template unchecked<3>();
      Gr* grid = new Gr();
      grid->set_size((int)r.shape(0), (int)r.shape(1), (int)r.shape(2));
      for (int k = 0; k < r.shape(2); ++k)
        for (int j = 0; j < r.shape(1); ++j)
          for (int i = 0; i < r.shape(0); ++i)
            grid->data[grid->index_q(i, j, k)] = r(i, j, k);
      if (cell)
        grid->set_unit_cell(*cell);
      if (sg)
        grid->spacegroup = sg;
      return grid;
    }), py::arg().noconvert(), py::arg("cell")=nullptr, py::arg("spacegroup")=nullptr)
    .def_property_readonly("spacing", [](const Gr& self){
        return py::make_tuple(self.spacing[0], self.spacing[1], self.spacing[2]);
    })
    .def("get_value", &Gr::get_value)
    .def("set_value", &Gr::set_value)
    .def("get_point", &Gr::get_point)
    .def("point_to_fractional", &Gr::point_to_fractional)
    .def("point_to_position", &Gr::point_to_position)
    .def("point_to_position", [](const Gr& self, int u, int v, int w) {
      GrPoint p = {u, v, w, nullptr};
      return self.point_to_position(p);
    }, py::arg("u"), py::arg("v"), py::arg("w"))
    .def("point_to_index", &Gr::point_to_index)
    .def("interpolate_value",
         (T (Gr::*)(const Fractional&) const) &Gr::interpolate_value)
    .def("interpolate_value",
         (T (Gr::*)(const Position&) const) &Gr::interpolate_value)
    .def("interpolate_values",
         [](const Gr& self, py::array_t<T> arr, const Transform& tr) {
        auto r = arr.template mutable_unchecked<3>();
        for (int i = 0; i < r.shape(0); ++i)
          for (int j = 0; j < r.shape(1); ++j)
            for (int k = 0; k < r.shape(2); ++k) {
              Position pos(tr.apply(Vec3(i, j, k)));
              r(i, j, k) = self.interpolate_value(pos);
            }
    }, py::arg().noconvert(), py::arg())
    .def("set_unit_cell", (void (Gr::*)(const UnitCell&)) &Gr::set_unit_cell)
    .def("set_points_around", &Gr::set_points_around,
         py::arg("position"), py::arg("radius"), py::arg("value"))
    .def("symmetrize_min", &Gr::symmetrize_min)
    .def("symmetrize_max", &Gr::symmetrize_max)
    .def("asu", &Gr::asu)
    .def("mask_points_in_constant_radius", &mask_points_in_constant_radius<T>,
         py::arg("model"), py::arg("radius"), py::arg("value"))
    .def("__repr__", [=](const Gr& self) {
        return tostr("<gemmi.", name, '(', self.nu, ", ", self.nv, ", ", self.nw, ")>");
    });

  pyGrPoint
    .def_readonly("u", &GrPoint::u)
    .def_readonly("v", &GrPoint::v)
    .def_readonly("w", &GrPoint::w)
    .def_property("value",
                  [](const GrPoint& self) { return *self.value; },
                  [](GrPoint& self, T x) { *self.value = x; })
    .def("__repr__", [=](const GrPoint& self) {
        return tostr("<gemmi.", name, "Point (", self.u, ", ", self.v, ", ",
                     self.w, ") -> ", +*self.value, '>');
    });
    ;

  pyMaskedGrid
    .def_readonly("grid", &Masked::grid, py::return_value_policy::reference)
    .def_readonly("mask", &Masked::mask)
    .def("__iter__", [](Masked& self) { return py::make_iterator(self); },
         py::keep_alive<0, 1>())
    ;
}

// for pandda-2
Grid<float> interpolate_positions(const Grid<float>& moving_map,
                                  Grid<float> interpolated_map,
                                  const std::vector<std::array<int,3>>& points,
                                  const std::vector<Fractional>& positions) {
  py::gil_scoped_release release;  // Release gil for threading support
  if (points.size() != positions.size())
    fail("interpolate_positions(): list sizes differ");
  for (std::size_t i = 0; i < positions.size(); i++)
    interpolated_map.set_value(points[i][0],
                               points[i][1],
                               points[i][2],
                               moving_map.interpolate_value(positions[i]));
  return interpolated_map;
}

void add_grid(py::module& m) {
  py::enum_<AxisOrder>(m, "AxisOrder")
    .value("XYZ", AxisOrder::XYZ)
    .value("ZYX", AxisOrder::ZYX);
  add_grid<int8_t>(m, "Int8Grid");
  add_grid<float>(m, "FloatGrid");
  add_grid<std::complex<float>>(m, "ComplexGrid");
  m.def("interpolate_positions", &interpolate_positions);
}
<|endoftext|>


<commit_before>#include "sitkImage.h"
#include "sitkImage.txx"

namespace {

}

namespace itk
{
  namespace simple
  {

    template<class TImageType>
    typename EnableIf<IsBasic<TImageType>::Value>::Type
    Image::AllocateInternal ( uint64_t Width, uint64_t Height, uint64_t Depth )
    {
      typename TImageType::IndexType  index;
      typename TImageType::SizeType   size;
      typename TImageType::RegionType region;
      index.Fill ( 0 );
      size.Fill(1);
      size[0] = Width;
      size[1] = Height;
      if ( TImageType::ImageDimension > 2 && Depth != 0 ) {
        size[2] = Depth;
      }
      region.SetSize ( size );
      region.SetIndex ( index );
      typename TImageType::Pointer image = TImageType::New();
      image->SetRegions ( region );
      image->Allocate();
      image->FillBuffer ( 0.0 );
      m_PimpleImage.reset( new PimpleImage<TImageType>( image ) );
    }

  template<class TImageType>
  typename EnableIf<IsVector<TImageType>::Value>::Type
  Image::AllocateInternal ( uint64_t Width, uint64_t Height, uint64_t Depth )
  {
    typename TImageType::IndexType  index;
    typename TImageType::SizeType   size;
    typename TImageType::RegionType region;
    typename TImageType::PixelType  zero;

    index.Fill ( 0 );
    size.Fill(1);
    size[0] = Width;
    size[1] = Height;
    if ( TImageType::ImageDimension > 2 && Depth != 0 )
      {
      size[2] = Depth;
      }
    region.SetSize ( size );
    region.SetIndex ( index );

    zero.SetSize( TImageType::ImageDimension );
    zero.Fill( 0.0 );

    typename TImageType::Pointer image = TImageType::New();
    image->SetRegions ( region );
    image->SetVectorLength( TImageType::ImageDimension );
    image->Allocate();
    image->FillBuffer ( zero );
    m_PimpleImage.reset( new PimpleImage<TImageType>( image ) );
  }

  template<class TImageType>
  typename EnableIf<IsLabel<TImageType>::Value>::Type
  Image::AllocateInternal ( uint64_t Width, uint64_t Height, uint64_t Depth )
  {
    typename TImageType::IndexType  index;
    typename TImageType::SizeType   size;
    typename TImageType::RegionType region;

    index.Fill ( 0 );
    size.Fill(1);
    size[0] = Width;
    size[1] = Height;
    if ( TImageType::ImageDimension > 2 )
      {
      assert(Depth == 0 );
      size[2] = Depth;
      }
    region.SetSize ( size );
    region.SetIndex ( index );

    typename TImageType::Pointer image = TImageType::New();
    image->SetRegions ( region );
    image->Allocate();
    image->SetBackgroundValue( 0 );
    m_PimpleImage.reset( new PimpleImage<TImageType>( image ) );
  }

    void Image::Allocate ( uint64_t Width, uint64_t Height, uint64_t Depth, PixelIDValueEnum ValueEnum ) {
      // Allocate an image

      detail::MemberFunctionFactory<MemberFunctionType, AllocateAddressor> allocateMemberFactory(this);
      allocateMemberFactory.RegisterMemberFunctions< PixelIDTypeList, 3 > ();
      allocateMemberFactory.RegisterMemberFunctions< PixelIDTypeList, 2 > ();

      if ( ValueEnum == sitkUnknown )
        {
        sitkExceptionMacro( "Unable to construct image of unsupported pixel type" );
        }

      PixelIDValueType type = ValueEnum;
      if ( Depth == 0 ) {
        allocateMemberFactory.GetMemberFunction( type, 2 )( Width, Height, Depth );
      } else {
        allocateMemberFactory.GetMemberFunction( type, 3 )( Width, Height, Depth );
      }
    }

    Image::Image( uint64_t Width, uint64_t Height, PixelIDValueEnum ValueEnum ) {
      Allocate ( Width, Height, 0, ValueEnum );
    }
    Image::Image( uint64_t Width, uint64_t Height, uint64_t Depth, PixelIDValueEnum ValueEnum ) {
      Allocate ( Width, Height, Depth, ValueEnum );
    }

    itk::DataObject::Pointer Image::GetImageBase( void )
    {
      assert( m_PimpleImage.get() );
      return m_PimpleImage->GetDataBase();
    }

    itk::DataObject::ConstPointer Image::GetImageBase( void ) const
    {
      assert( m_PimpleImage.get() );
      return m_PimpleImage->GetDataBase().GetPointer();
    }

    PixelIDValueType Image::GetPixelIDValue( void ) const
    {
      return this->m_PimpleImage->GetPixelIDValue();
    }

    unsigned int Image::GetDimension( void ) const
    {
      return this->m_PimpleImage->GetDimension();
    }

    std::string Image::GetPixelIDTypeAsString( void ) const
    {
      return std::string( GetPixelIDValueAsString( this->GetPixelIDValue() ) );
    }

    std::string Image::ToString( void )
    {
      return this->m_PimpleImage->ToString();
    }

    uint64_t Image::GetWidth( void )
    {
      return this->m_PimpleImage->GetWidth();
    }

    uint64_t Image::GetHeight( void )
    {
      return this->m_PimpleImage->GetHeight();
    }

    uint64_t Image::GetDepth( void )
    {
      return this->m_PimpleImage->GetDepth();
    }

    PixelContainer::Pointer Image::GetPixelContainer()
    {
      return this->m_PimpleImage->GetPixelContainer();
    }

    /*
    void Image::Show(const std::string name) const
    {
      // Try to find ImageJ, write out a file and open
#if defined(__WIN32__)
      // Windows
#elseif defined(__APPLE__)
      // Mac
      char *filename = malloc ( sizeof(char) * (100 + name.size()) );
      sprintf ( filename, "/tmp/%s-XXXXX.nrrd", name.c_str() );
      mktemp ( filename );
      ImageFileWriter().SetFilename ( filename ).Execute ( this );
      std::cout << "Show Filename: " << filename << std::endl;
#else
      // Linux
#endif
    }
    */

  }
}
<commit_msg>BUG: incorrect assert in Image::AllocateInternal<commit_after>#include "sitkImage.h"
#include "sitkImage.txx"

namespace {

}

namespace itk
{
  namespace simple
  {

    template<class TImageType>
    typename EnableIf<IsBasic<TImageType>::Value>::Type
    Image::AllocateInternal ( uint64_t Width, uint64_t Height, uint64_t Depth )
    {
      typename TImageType::IndexType  index;
      typename TImageType::SizeType   size;
      typename TImageType::RegionType region;
      index.Fill ( 0 );
      size.Fill(1);
      size[0] = Width;
      size[1] = Height;
      if ( TImageType::ImageDimension > 2 ) {
      assert(Depth != 0 );
        size[2] = Depth;
      }
      region.SetSize ( size );
      region.SetIndex ( index );
      typename TImageType::Pointer image = TImageType::New();
      image->SetRegions ( region );
      image->Allocate();
      image->FillBuffer ( 0.0 );
      m_PimpleImage.reset( new PimpleImage<TImageType>( image ) );
    }

  template<class TImageType>
  typename EnableIf<IsVector<TImageType>::Value>::Type
  Image::AllocateInternal ( uint64_t Width, uint64_t Height, uint64_t Depth )
  {
    typename TImageType::IndexType  index;
    typename TImageType::SizeType   size;
    typename TImageType::RegionType region;
    typename TImageType::PixelType  zero;

    index.Fill ( 0 );
    size.Fill(1);
    size[0] = Width;
    size[1] = Height;
    if ( TImageType::ImageDimension > 2 )
      {
      assert(Depth != 0 );
      size[2] = Depth;
      }
    region.SetSize ( size );
    region.SetIndex ( index );

    zero.SetSize( TImageType::ImageDimension );
    zero.Fill( 0.0 );

    typename TImageType::Pointer image = TImageType::New();
    image->SetRegions ( region );
    image->SetVectorLength( TImageType::ImageDimension );
    image->Allocate();
    image->FillBuffer ( zero );
    m_PimpleImage.reset( new PimpleImage<TImageType>( image ) );
  }

  template<class TImageType>
  typename EnableIf<IsLabel<TImageType>::Value>::Type
  Image::AllocateInternal ( uint64_t Width, uint64_t Height, uint64_t Depth )
  {
    typename TImageType::IndexType  index;
    typename TImageType::SizeType   size;
    typename TImageType::RegionType region;

    index.Fill ( 0 );
    size.Fill(1);
    size[0] = Width;
    size[1] = Height;
    if ( TImageType::ImageDimension > 2 )
      {
      assert(Depth != 0 );
      size[2] = Depth;
      }
    region.SetSize ( size );
    region.SetIndex ( index );

    typename TImageType::Pointer image = TImageType::New();
    image->SetRegions ( region );
    image->Allocate();
    image->SetBackgroundValue( 0 );
    m_PimpleImage.reset( new PimpleImage<TImageType>( image ) );
  }

    void Image::Allocate ( uint64_t Width, uint64_t Height, uint64_t Depth, PixelIDValueEnum ValueEnum ) {
      // Allocate an image

      detail::MemberFunctionFactory<MemberFunctionType, AllocateAddressor> allocateMemberFactory(this);
      allocateMemberFactory.RegisterMemberFunctions< PixelIDTypeList, 3 > ();
      allocateMemberFactory.RegisterMemberFunctions< PixelIDTypeList, 2 > ();

      if ( ValueEnum == sitkUnknown )
        {
        sitkExceptionMacro( "Unable to construct image of unsupported pixel type" );
        }

      PixelIDValueType type = ValueEnum;
      if ( Depth == 0 ) {
        allocateMemberFactory.GetMemberFunction( type, 2 )( Width, Height, Depth );
      } else {
        allocateMemberFactory.GetMemberFunction( type, 3 )( Width, Height, Depth );
      }
    }

    Image::Image( uint64_t Width, uint64_t Height, PixelIDValueEnum ValueEnum ) {
      Allocate ( Width, Height, 0, ValueEnum );
    }
    Image::Image( uint64_t Width, uint64_t Height, uint64_t Depth, PixelIDValueEnum ValueEnum ) {
      Allocate ( Width, Height, Depth, ValueEnum );
    }

    itk::DataObject::Pointer Image::GetImageBase( void )
    {
      assert( m_PimpleImage.get() );
      return m_PimpleImage->GetDataBase();
    }

    itk::DataObject::ConstPointer Image::GetImageBase( void ) const
    {
      assert( m_PimpleImage.get() );
      return m_PimpleImage->GetDataBase().GetPointer();
    }

    PixelIDValueType Image::GetPixelIDValue( void ) const
    {
      return this->m_PimpleImage->GetPixelIDValue();
    }

    unsigned int Image::GetDimension( void ) const
    {
      return this->m_PimpleImage->GetDimension();
    }

    std::string Image::GetPixelIDTypeAsString( void ) const
    {
      return std::string( GetPixelIDValueAsString( this->GetPixelIDValue() ) );
    }

    std::string Image::ToString( void )
    {
      return this->m_PimpleImage->ToString();
    }

    uint64_t Image::GetWidth( void )
    {
      return this->m_PimpleImage->GetWidth();
    }

    uint64_t Image::GetHeight( void )
    {
      return this->m_PimpleImage->GetHeight();
    }

    uint64_t Image::GetDepth( void )
    {
      return this->m_PimpleImage->GetDepth();
    }

    PixelContainer::Pointer Image::GetPixelContainer()
    {
      return this->m_PimpleImage->GetPixelContainer();
    }

    /*
    void Image::Show(const std::string name) const
    {
      // Try to find ImageJ, write out a file and open
#if defined(__WIN32__)
      // Windows
#elseif defined(__APPLE__)
      // Mac
      char *filename = malloc ( sizeof(char) * (100 + name.size()) );
      sprintf ( filename, "/tmp/%s-XXXXX.nrrd", name.c_str() );
      mktemp ( filename );
      ImageFileWriter().SetFilename ( filename ).Execute ( this );
      std::cout << "Show Filename: " << filename << std::endl;
#else
      // Linux
#endif
    }
    */

  }
}
<|endoftext|>


<commit_before><commit_msg>Benchmarks for checkpointer.<commit_after><|endoftext|>


<commit_before>// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include <vespa/fastos/fastos.h>
#include <iostream>
#include <string>
#include <cstdlib>

#include <boost/program_options.hpp>
#include <boost/lambda/bind.hpp>
#include <boost/lambda/lambda.hpp>
#include <boost/thread/thread.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/noncopyable.hpp>
#include <boost/date_time/posix_time/posix_time_types.hpp>
#include <boost/exception/diagnostic_information.hpp>
#include <boost/scope_exit.hpp>

#include <vespa/fastos/app.h>
#include <vespa/config-zookeepers.h>

#include <vespa/fileacquirer/config-filedistributorrpc.h>
#include <vespa/filedistribution/distributor/config-filedistributor.h>
#include <vespa/filedistribution/model/config-filereferences.h>

#include <vespa/filedistribution/distributor/filedistributortrackerimpl.h>
#include <vespa/filedistribution/distributor/filedownloadermanager.h>
#include <vespa/filedistribution/distributor/filedownloader.h>
#include <vespa/filedistribution/distributor/signalhandling.h>
#include <vespa/filedistribution/distributor/state_server_impl.h>

#include <vespa/filedistribution/model/filedistributionmodelimpl.h>
#include <vespa/filedistribution/rpc/filedistributorrpc.h>
#include <vespa/filedistribution/common/exception.h>
#include <vespa/filedistribution/common/componentsdeleter.h>

namespace {
const char* programName = "filedistributor";
}

#include <vespa/log/log.h>
LOG_SETUP(programName);

namespace ll = boost::lambda;

using namespace filedistribution;
using cloud::config::ZookeepersConfig;
using cloud::config::filedistribution::FiledistributorConfig;
using cloud::config::filedistribution::FiledistributorrpcConfig;

class FileDistributor : public config::IFetcherCallback<ZookeepersConfig>,
                        public config::IFetcherCallback<FiledistributorConfig>,
                        public config::IFetcherCallback<FiledistributorrpcConfig>,
                        public config::IGenerationCallback,
                        boost::noncopyable
{
    class Components : boost::noncopyable {
        ComponentsDeleter _componentsDeleter;
    public:
        const boost::shared_ptr<ZKFacade> _zk;
        const boost::shared_ptr<FileDistributionModelImpl> _model;
        const boost::shared_ptr<FileDistributorTrackerImpl> _tracker;
        const boost::shared_ptr<FileDownloader> _downloader;
        const boost::shared_ptr<FileDownloaderManager> _manager;
        const boost::shared_ptr<FileDistributorRPC> _rpcHandler;
        const boost::shared_ptr<StateServerImpl> _stateServer;

    private:
        boost::thread _downloaderEventLoopThread;
        config::ConfigFetcher _configFetcher;

        template <class T>
        typename boost::shared_ptr<T> track(T* component) {
            return _componentsDeleter.track(component);
        }

    public:

        Components(const boost::shared_ptr<ExceptionRethrower>& exceptionRethrower,
                   const config::ConfigUri & configUri,
                   const ZookeepersConfig& zooKeepersConfig,
                   const FiledistributorConfig& fileDistributorConfig,
                   const FiledistributorrpcConfig& rpcConfig)
            :_zk(track(new ZKFacade(zooKeepersConfig.zookeeperserverlist, exceptionRethrower))),
             _model(track(new FileDistributionModelImpl(
                                     fileDistributorConfig.hostname,
                                     fileDistributorConfig.torrentport,
                                     _zk,
                                     exceptionRethrower))),
             _tracker(track(new FileDistributorTrackerImpl(_model, exceptionRethrower))),
             _downloader(track(new FileDownloader(
                                     _tracker,
                                     fileDistributorConfig.hostname,
                                     fileDistributorConfig.torrentport,
                                     boost::filesystem::path(fileDistributorConfig.filedbpath),
                                     exceptionRethrower))),
             _manager(track(new FileDownloaderManager(_downloader, _model))),
             _rpcHandler(track(new FileDistributorRPC(rpcConfig.connectionspec, _manager))),
             _stateServer(track(new StateServerImpl(fileDistributorConfig.stateport))),
             _downloaderEventLoopThread(
                    ll::bind(&FileDownloader::runEventLoop, _downloader.get())),
             _configFetcher(configUri.getContext())

        {
            _manager->start();
            _rpcHandler->start();

            _tracker->setDownloader(_downloader);
            _configFetcher.subscribe<FilereferencesConfig>(configUri.getConfigId(), _model.get());
            _configFetcher.start();
            updatedConfig(_configFetcher.getGeneration());
        }

        void updatedConfig(int64_t generation) {
            vespalib::ComponentConfigProducer::Config curr("filedistributor", generation);
            _stateServer->myComponents.addConfig(curr);
        }

        ~Components() {
            _configFetcher.close();
            //Do not waste time retrying zookeeper operations when going down.
            _zk->disableRetries();

            _downloaderEventLoopThread.interrupt();
            _downloaderEventLoopThread.join();
        }

    };

    typedef boost::lock_guard<boost::mutex> LockGuard;
    boost::mutex _configMutex;

    bool _completeReconfigurationNeeded;
    std::unique_ptr<ZookeepersConfig> _zooKeepersConfig;
    std::unique_ptr<FiledistributorConfig> _fileDistributorConfig;
    std::unique_ptr<FiledistributorrpcConfig> _rpcConfig;

    boost::shared_ptr<ExceptionRethrower> _exceptionRethrower;
    std::unique_ptr<Components> _components;
public:
    FileDistributor()
        : _configMutex(),
          _completeReconfigurationNeeded(false),
          _zooKeepersConfig(),
          _fileDistributorConfig(),
          _rpcConfig(),
          _exceptionRethrower(),
          _components()
    { }

    void notifyGenerationChange(int64_t generation) {
        if (_components && ! completeReconfigurationNeeded()) {
            _components->updatedConfig(generation);
        }
    }

    //configure overrides
    void configure(std::unique_ptr<ZookeepersConfig> config) {
        LockGuard guard(_configMutex);
        _zooKeepersConfig = std::move(config);
        _completeReconfigurationNeeded = true;
    }

    void configure(std::unique_ptr<FiledistributorConfig> config) {
        LockGuard guard(_configMutex);
        if (_fileDistributorConfig.get() != NULL &&
            (config->torrentport != _fileDistributorConfig->torrentport ||
             config->stateport   != _fileDistributorConfig->stateport ||
             config->hostname    != _fileDistributorConfig->hostname ||
             config->filedbpath  != _fileDistributorConfig->filedbpath))
        {
            _completeReconfigurationNeeded = true;
        } else if (_components.get()) {
            configureSpeedLimits(*config);
        }
        _fileDistributorConfig = std::move(config);

    }

    void configure(std::unique_ptr<FiledistributorrpcConfig> config) {
        LockGuard guard(_configMutex);
        _rpcConfig = std::move(config);
        _completeReconfigurationNeeded = true;
    }

    void run(const config::ConfigUri & configUri) {
        while (!askedToShutDown()) {
            clearReinitializeFlag();
            _exceptionRethrower.reset(new ExceptionRethrower());
            runImpl(configUri);

            if (_exceptionRethrower->exceptionStored())
                _exceptionRethrower->rethrow();
        }
    }

    static void ensureExceptionsStored(const boost::shared_ptr<ExceptionRethrower>& exceptionRethrower) {
        //TODO: this is somewhat hackish, refactor to eliminate this later.
        LOG(debug, "Waiting for shutdown");
        for (int i=0;
             i<50 && !exceptionRethrower.unique();
                ++i) {
            boost::this_thread::sleep(boost::posix_time::milliseconds(100));
        }
        LOG(debug, "Done waiting for shutdown");

        if (!exceptionRethrower.unique()) {
            EV_STOPPING(programName, "Forced termination");
            kill(getpid(), SIGKILL);
        }
    }

    void createComponents(const boost::shared_ptr<ExceptionRethrower>& exceptionRethrower, const config::ConfigUri & configUri) {
        LockGuard guard(_configMutex);
        _components.reset(
                new Components(exceptionRethrower,
                        configUri,
                        *_zooKeepersConfig,
                        *_fileDistributorConfig,
                        *_rpcConfig));

        configureSpeedLimits(*_fileDistributorConfig);
        _completeReconfigurationNeeded = false;
    }

    bool completeReconfigurationNeeded() {
        LockGuard guard(_configMutex);
        if (_completeReconfigurationNeeded) {
            LOG(debug, "Complete reconfiguration needed");
        }
        return _completeReconfigurationNeeded;
    }

    void configureSpeedLimits(const FiledistributorConfig& config) {
        FileDownloader& downloader = *_components->_downloader;
        downloader.setMaxDownloadSpeed(config.maxdownloadspeed);
        downloader.setMaxUploadSpeed(config.maxuploadspeed);
    }

    //avoid warning due to scope exit macro
#pragma GCC diagnostic ignored "-Wshadow"
    void runImpl(const config::ConfigUri & configUri) {

        BOOST_SCOPE_EXIT((&_components)(&_exceptionRethrower)) {
            _components.reset();
            //Ensures that any exception stored during destruction will be available when returning.
            ensureExceptionsStored(_exceptionRethrower);
        } BOOST_SCOPE_EXIT_END

        createComponents(_exceptionRethrower, configUri);

        // We do not want back to back reinitializing as it gives zero time for serving
        // some torrents.
        int postPoneAskedToReinitializedSecs = 50;

        while (!askedToShutDown() &&
	       (postPoneAskedToReinitializedSecs > 0 || !askedToReinitialize()) &&
	       !completeReconfigurationNeeded() &&
	       !_exceptionRethrower->exceptionStored()) {
	  postPoneAskedToReinitializedSecs--;
	  boost::this_thread::sleep(boost::posix_time::seconds(1));
        }
    }
};

//TODO: use pop in gcc 4.6
#pragma GCC diagnostic warning "-Wshadow"

class FileDistributorApplication : public FastOS_Application {
    const config::ConfigUri _configUri;
public:
    FileDistributorApplication(const config::ConfigUri & configUri);

    //overrides
    int Main();
};

namespace {

struct ProgramOptionException {
    std::string _msg;
    ProgramOptionException(const std::string & msg)
        : _msg(msg)
    {}
};

bool exists(const std::string& optionName, const boost::program_options::variables_map& map) {
    return map.find(optionName) != map.end();
}

void ensureExists(const std::string& optionName, const boost::program_options::variables_map& map \
                  ) {
    if (!exists(optionName, map)) {
        throw ProgramOptionException("Error: Missing option " + optionName);
    }
}

} //anonymous namespace

FileDistributorApplication::FileDistributorApplication(const config::ConfigUri & configUri)
    :_configUri(configUri) {
}

int
FileDistributorApplication::Main() {
    try {
        FileDistributor distributor;

        config::ConfigFetcher configFetcher(_configUri.getContext());
        configFetcher.subscribe<ZookeepersConfig>(_configUri.getConfigId(), &distributor);
        configFetcher.subscribe<FiledistributorConfig>(_configUri.getConfigId(), &distributor);
        configFetcher.subscribe<FiledistributorrpcConfig>(_configUri.getConfigId(), &distributor);
        configFetcher.subscribeGenerationChanges(&distributor);
        configFetcher.start();

        distributor.run(_configUri);

        EV_STOPPING(programName, "Clean exit");
        return 0;
    } catch(const FileDoesNotExistException & e) {
        std::string s = boost::diagnostic_information(e);
        EV_STOPPING(programName, s.c_str());
        return 1;
    } catch(const ZKNodeDoesNotExistsException & e) {
        std::string s = boost::diagnostic_information(e);
        EV_STOPPING(programName, s.c_str());
        return 2;
    } catch(const ZKSessionExpired & e) {
        std::string s = boost::diagnostic_information(e);
        EV_STOPPING(programName, s.c_str());
        return 3;
    } catch(const config::ConfigTimeoutException & e) {
        std::string s = boost::diagnostic_information(e);
        EV_STOPPING(programName, s.c_str());
        return 4;
    } catch(const FailedListeningException & e) {
        std::string s = boost::diagnostic_information(e);
        EV_STOPPING(programName, s.c_str());
        return 5;
    } catch(const ZKGenericException & e) {
        std::string s = boost::diagnostic_information(e);
        EV_STOPPING(programName, s.c_str());
        return 99;
    } catch(const boost::unknown_exception & e) {
        std::string s = boost::diagnostic_information(e);
        LOG(warning, "Caught '%s'", s.c_str());
        EV_STOPPING(programName, s.c_str());
        return 255;
#if 0
    /*
     These are kept hanging around for reference as to how it was when we just held our ears
     singing "na, na, na, na..." no matter if the sun was shining or if the world imploded.
    */
    } catch(const boost::exception& e) {
        std::string s = boost::diagnostic_information(e);
        LOG(error, "Caught '%s'", s.c_str());
        EV_STOPPING(programName, s.c_str());
        return -1;
    } catch(const std::string& msg) {
        std::string s = "Error: " + msg;
        LOG(error, "Caught '%s'", s.c_str());
        EV_STOPPING(programName, s.c_str());
        return -1;
#endif
    }
}

int
executeApplication(int argc, char** argv) {
    const char
        *configId("configid"),
        *help("help");

    namespace po = boost::program_options;
    po::options_description description;
    description.add_options()
        (configId, po::value<std::string > (), "id to request config for")
        (help, "help");

    try {
        po::variables_map values;
        po::store(
                po::parse_command_line(argc, argv, description),
                values);

        if (exists(help, values)) {
            std::cout <<description;
            return 0;
        }
        ensureExists(configId, values);

        FileDistributorApplication application(
                values[configId].as<std::string > ());
        return application.Entry(argc, argv);

    } catch(ProgramOptionException& e) {
        std::cerr <<e._msg <<std::endl;
        return -1;
    }
}

void terminate() {
    std::cerr <<"Terminate called: " <<std::endl;
    Backtrace backtrace;
    std::cerr <<backtrace <<std::endl;
}

int
main(int argc, char** argv) {
    EV_STARTED(programName);
    initSignals();

    std::srand(std::time(0));
    std::set_terminate(terminate);
    filedistribution::setupZooKeeperLogging();

    return executeApplication(argc, argv);
}
<commit_msg>No hiding of coredumps.<commit_after>// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include <vespa/fastos/fastos.h>
#include <iostream>
#include <string>
#include <cstdlib>

#include <boost/program_options.hpp>
#include <boost/lambda/bind.hpp>
#include <boost/lambda/lambda.hpp>
#include <boost/thread/thread.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/noncopyable.hpp>
#include <boost/date_time/posix_time/posix_time_types.hpp>
#include <boost/exception/diagnostic_information.hpp>
#include <boost/scope_exit.hpp>

#include <vespa/fastos/app.h>
#include <vespa/config-zookeepers.h>

#include <vespa/fileacquirer/config-filedistributorrpc.h>
#include <vespa/filedistribution/distributor/config-filedistributor.h>
#include <vespa/filedistribution/model/config-filereferences.h>

#include <vespa/filedistribution/distributor/filedistributortrackerimpl.h>
#include <vespa/filedistribution/distributor/filedownloadermanager.h>
#include <vespa/filedistribution/distributor/filedownloader.h>
#include <vespa/filedistribution/distributor/signalhandling.h>
#include <vespa/filedistribution/distributor/state_server_impl.h>

#include <vespa/filedistribution/model/filedistributionmodelimpl.h>
#include <vespa/filedistribution/rpc/filedistributorrpc.h>
#include <vespa/filedistribution/common/exception.h>
#include <vespa/filedistribution/common/componentsdeleter.h>

namespace {
const char* programName = "filedistributor";
}

#include <vespa/log/log.h>
LOG_SETUP(programName);

namespace ll = boost::lambda;

using namespace filedistribution;
using cloud::config::ZookeepersConfig;
using cloud::config::filedistribution::FiledistributorConfig;
using cloud::config::filedistribution::FiledistributorrpcConfig;

class FileDistributor : public config::IFetcherCallback<ZookeepersConfig>,
                        public config::IFetcherCallback<FiledistributorConfig>,
                        public config::IFetcherCallback<FiledistributorrpcConfig>,
                        public config::IGenerationCallback,
                        boost::noncopyable
{
    class Components : boost::noncopyable {
        ComponentsDeleter _componentsDeleter;
    public:
        const boost::shared_ptr<ZKFacade> _zk;
        const boost::shared_ptr<FileDistributionModelImpl> _model;
        const boost::shared_ptr<FileDistributorTrackerImpl> _tracker;
        const boost::shared_ptr<FileDownloader> _downloader;
        const boost::shared_ptr<FileDownloaderManager> _manager;
        const boost::shared_ptr<FileDistributorRPC> _rpcHandler;
        const boost::shared_ptr<StateServerImpl> _stateServer;

    private:
        boost::thread _downloaderEventLoopThread;
        config::ConfigFetcher _configFetcher;

        template <class T>
        typename boost::shared_ptr<T> track(T* component) {
            return _componentsDeleter.track(component);
        }

    public:

        Components(const boost::shared_ptr<ExceptionRethrower>& exceptionRethrower,
                   const config::ConfigUri & configUri,
                   const ZookeepersConfig& zooKeepersConfig,
                   const FiledistributorConfig& fileDistributorConfig,
                   const FiledistributorrpcConfig& rpcConfig)
            :_zk(track(new ZKFacade(zooKeepersConfig.zookeeperserverlist, exceptionRethrower))),
             _model(track(new FileDistributionModelImpl(
                                     fileDistributorConfig.hostname,
                                     fileDistributorConfig.torrentport,
                                     _zk,
                                     exceptionRethrower))),
             _tracker(track(new FileDistributorTrackerImpl(_model, exceptionRethrower))),
             _downloader(track(new FileDownloader(
                                     _tracker,
                                     fileDistributorConfig.hostname,
                                     fileDistributorConfig.torrentport,
                                     boost::filesystem::path(fileDistributorConfig.filedbpath),
                                     exceptionRethrower))),
             _manager(track(new FileDownloaderManager(_downloader, _model))),
             _rpcHandler(track(new FileDistributorRPC(rpcConfig.connectionspec, _manager))),
             _stateServer(track(new StateServerImpl(fileDistributorConfig.stateport))),
             _downloaderEventLoopThread(
                    ll::bind(&FileDownloader::runEventLoop, _downloader.get())),
             _configFetcher(configUri.getContext())

        {
            _manager->start();
            _rpcHandler->start();

            _tracker->setDownloader(_downloader);
            _configFetcher.subscribe<FilereferencesConfig>(configUri.getConfigId(), _model.get());
            _configFetcher.start();
            updatedConfig(_configFetcher.getGeneration());
        }

        void updatedConfig(int64_t generation) {
            vespalib::ComponentConfigProducer::Config curr("filedistributor", generation);
            _stateServer->myComponents.addConfig(curr);
        }

        ~Components() {
            _configFetcher.close();
            //Do not waste time retrying zookeeper operations when going down.
            _zk->disableRetries();

            _downloaderEventLoopThread.interrupt();
            _downloaderEventLoopThread.join();
        }

    };

    typedef boost::lock_guard<boost::mutex> LockGuard;
    boost::mutex _configMutex;

    bool _completeReconfigurationNeeded;
    std::unique_ptr<ZookeepersConfig> _zooKeepersConfig;
    std::unique_ptr<FiledistributorConfig> _fileDistributorConfig;
    std::unique_ptr<FiledistributorrpcConfig> _rpcConfig;

    boost::shared_ptr<ExceptionRethrower> _exceptionRethrower;
    std::unique_ptr<Components> _components;
public:
    FileDistributor()
        : _configMutex(),
          _completeReconfigurationNeeded(false),
          _zooKeepersConfig(),
          _fileDistributorConfig(),
          _rpcConfig(),
          _exceptionRethrower(),
          _components()
    { }

    void notifyGenerationChange(int64_t generation) {
        if (_components && ! completeReconfigurationNeeded()) {
            _components->updatedConfig(generation);
        }
    }

    //configure overrides
    void configure(std::unique_ptr<ZookeepersConfig> config) {
        LockGuard guard(_configMutex);
        _zooKeepersConfig = std::move(config);
        _completeReconfigurationNeeded = true;
    }

    void configure(std::unique_ptr<FiledistributorConfig> config) {
        LockGuard guard(_configMutex);
        if (_fileDistributorConfig.get() != NULL &&
            (config->torrentport != _fileDistributorConfig->torrentport ||
             config->stateport   != _fileDistributorConfig->stateport ||
             config->hostname    != _fileDistributorConfig->hostname ||
             config->filedbpath  != _fileDistributorConfig->filedbpath))
        {
            _completeReconfigurationNeeded = true;
        } else if (_components.get()) {
            configureSpeedLimits(*config);
        }
        _fileDistributorConfig = std::move(config);

    }

    void configure(std::unique_ptr<FiledistributorrpcConfig> config) {
        LockGuard guard(_configMutex);
        _rpcConfig = std::move(config);
        _completeReconfigurationNeeded = true;
    }

    void run(const config::ConfigUri & configUri) {
        while (!askedToShutDown()) {
            clearReinitializeFlag();
            _exceptionRethrower.reset(new ExceptionRethrower());
            runImpl(configUri);

            if (_exceptionRethrower->exceptionStored())
                _exceptionRethrower->rethrow();
        }
    }

    static void ensureExceptionsStored(const boost::shared_ptr<ExceptionRethrower>& exceptionRethrower) {
        //TODO: this is somewhat hackish, refactor to eliminate this later.
        LOG(debug, "Waiting for shutdown");
        for (int i=0;
             i<50 && !exceptionRethrower.unique();
                ++i) {
            boost::this_thread::sleep(boost::posix_time::milliseconds(100));
        }
        LOG(debug, "Done waiting for shutdown");

        if (!exceptionRethrower.unique()) {
            EV_STOPPING(programName, "Forced termination");
            kill(getpid(), SIGKILL);
        }
    }

    void createComponents(const boost::shared_ptr<ExceptionRethrower>& exceptionRethrower, const config::ConfigUri & configUri) {
        LockGuard guard(_configMutex);
        _components.reset(
                new Components(exceptionRethrower,
                        configUri,
                        *_zooKeepersConfig,
                        *_fileDistributorConfig,
                        *_rpcConfig));

        configureSpeedLimits(*_fileDistributorConfig);
        _completeReconfigurationNeeded = false;
    }

    bool completeReconfigurationNeeded() {
        LockGuard guard(_configMutex);
        if (_completeReconfigurationNeeded) {
            LOG(debug, "Complete reconfiguration needed");
        }
        return _completeReconfigurationNeeded;
    }

    void configureSpeedLimits(const FiledistributorConfig& config) {
        FileDownloader& downloader = *_components->_downloader;
        downloader.setMaxDownloadSpeed(config.maxdownloadspeed);
        downloader.setMaxUploadSpeed(config.maxuploadspeed);
    }

    //avoid warning due to scope exit macro
#pragma GCC diagnostic ignored "-Wshadow"
    void runImpl(const config::ConfigUri & configUri) {

        BOOST_SCOPE_EXIT((&_components)(&_exceptionRethrower)) {
            _components.reset();
            //Ensures that any exception stored during destruction will be available when returning.
            ensureExceptionsStored(_exceptionRethrower);
        } BOOST_SCOPE_EXIT_END

        createComponents(_exceptionRethrower, configUri);

        // We do not want back to back reinitializing as it gives zero time for serving
        // some torrents.
        int postPoneAskedToReinitializedSecs = 50;

        while (!askedToShutDown() &&
	       (postPoneAskedToReinitializedSecs > 0 || !askedToReinitialize()) &&
	       !completeReconfigurationNeeded() &&
	       !_exceptionRethrower->exceptionStored()) {
	  postPoneAskedToReinitializedSecs--;
	  boost::this_thread::sleep(boost::posix_time::seconds(1));
        }
    }
};

//TODO: use pop in gcc 4.6
#pragma GCC diagnostic warning "-Wshadow"

class FileDistributorApplication : public FastOS_Application {
    const config::ConfigUri _configUri;
public:
    FileDistributorApplication(const config::ConfigUri & configUri);

    //overrides
    int Main();
};

namespace {

struct ProgramOptionException {
    std::string _msg;
    ProgramOptionException(const std::string & msg)
        : _msg(msg)
    {}
};

bool exists(const std::string& optionName, const boost::program_options::variables_map& map) {
    return map.find(optionName) != map.end();
}

void ensureExists(const std::string& optionName, const boost::program_options::variables_map& map \
                  ) {
    if (!exists(optionName, map)) {
        throw ProgramOptionException("Error: Missing option " + optionName);
    }
}

} //anonymous namespace

FileDistributorApplication::FileDistributorApplication(const config::ConfigUri & configUri)
    :_configUri(configUri) {
}

int
FileDistributorApplication::Main() {
    try {
        FileDistributor distributor;

        config::ConfigFetcher configFetcher(_configUri.getContext());
        configFetcher.subscribe<ZookeepersConfig>(_configUri.getConfigId(), &distributor);
        configFetcher.subscribe<FiledistributorConfig>(_configUri.getConfigId(), &distributor);
        configFetcher.subscribe<FiledistributorrpcConfig>(_configUri.getConfigId(), &distributor);
        configFetcher.subscribeGenerationChanges(&distributor);
        configFetcher.start();

        distributor.run(_configUri);

        EV_STOPPING(programName, "Clean exit");
        return 0;
    } catch(const FileDoesNotExistException & e) {
        std::string s = boost::diagnostic_information(e);
        EV_STOPPING(programName, s.c_str());
        return 1;
    } catch(const ZKNodeDoesNotExistsException & e) {
        std::string s = boost::diagnostic_information(e);
        EV_STOPPING(programName, s.c_str());
        return 2;
    } catch(const ZKSessionExpired & e) {
        std::string s = boost::diagnostic_information(e);
        EV_STOPPING(programName, s.c_str());
        return 3;
    } catch(const config::ConfigTimeoutException & e) {
        std::string s = boost::diagnostic_information(e);
        EV_STOPPING(programName, s.c_str());
        return 4;
    } catch(const FailedListeningException & e) {
        std::string s = boost::diagnostic_information(e);
        EV_STOPPING(programName, s.c_str());
        return 5;
    } catch(const ZKGenericException & e) {
        std::string s = boost::diagnostic_information(e);
        EV_STOPPING(programName, s.c_str());
        return 99;
    } catch(const boost::unknown_exception & e) {
        std::string s = boost::diagnostic_information(e);
        LOG(warning, "Caught '%s'", s.c_str());
        EV_STOPPING(programName, s.c_str());
        return 255;
#if 0
    /*
     These are kept hanging around for reference as to how it was when we just held our ears
     singing "na, na, na, na..." no matter if the sun was shining or if the world imploded.
    */
    } catch(const boost::exception& e) {
        std::string s = boost::diagnostic_information(e);
        LOG(error, "Caught '%s'", s.c_str());
        EV_STOPPING(programName, s.c_str());
        return -1;
    } catch(const std::string& msg) {
        std::string s = "Error: " + msg;
        LOG(error, "Caught '%s'", s.c_str());
        EV_STOPPING(programName, s.c_str());
        return -1;
#endif
    }
}

int
executeApplication(int argc, char** argv) {
    const char
        *configId("configid"),
        *help("help");

    namespace po = boost::program_options;
    po::options_description description;
    description.add_options()
        (configId, po::value<std::string > (), "id to request config for")
        (help, "help");

    try {
        po::variables_map values;
        po::store(
                po::parse_command_line(argc, argv, description),
                values);

        if (exists(help, values)) {
            std::cout <<description;
            return 0;
        }
        ensureExists(configId, values);

        FileDistributorApplication application(
                values[configId].as<std::string > ());
        return application.Entry(argc, argv);

    } catch(ProgramOptionException& e) {
        std::cerr <<e._msg <<std::endl;
        return -1;
    }
}

int
main(int argc, char** argv) {
    EV_STARTED(programName);
    initSignals();

    std::srand(std::time(0));
    filedistribution::setupZooKeeperLogging();

    return executeApplication(argc, argv);
}
<|endoftext|>


<commit_before>#include <criterion/criterion.h>
#include <criterion/redirect.h>
#include <iostream>

// set a timeout for I/O tests
TestSuite(redirect, .timeout = 0.1);

#if __GNUC__ >= 5
Test(redirect, mock) {
    auto fmock = criterion::mock_file();

    fmock << "Hello" << std::flush;
    fmock.seekg(0);

    std::string contents;
    fmock >> contents;

    cr_assert_eq(contents, "Hello");
}
#endif

Test(redirect, mock_c) {
    std::FILE* fmock = cr_mock_file_size(4096);

    std::fprintf(fmock, "Hello");
    std::fflush(fmock);
    std::rewind(fmock);

    char contents[sizeof ("Hello")] = {0};
    fgets(contents, sizeof (contents), fmock);

    cr_assert_str_eq(contents, "Hello");
}

Test(redirect, stdout_) {
    cr_redirect_stdout();

    std::cout << "Foo" << std::flush;

    cr_expect_stdout_eq_str("Foo");
    cr_expect_stdout_neq_str("Bar");
}

Test(redirect, stderr_) {
    cr_redirect_stderr();

    std::cerr << "Foo" << std::flush;

    cr_expect_stderr_eq_str("Foo");
    cr_expect_stderr_neq_str("Bar");
}

Test(redirect, stdin_) {
    auto& f_cin = criterion::get_redirected_cin();
    f_cin << "Foo";
    f_cin.close();

    std::string read;
    std::cin >> read;

    cr_expect_eq(read, "Foo");
    cr_expect_neq(read, "Bar");
}
<commit_msg>Added missing <string> include in redirect unit test<commit_after>#include <criterion/criterion.h>
#include <criterion/redirect.h>
#include <iostream>
#include <string>

// set a timeout for I/O tests
TestSuite(redirect, .timeout = 0.1);

#if __GNUC__ >= 5
Test(redirect, mock) {
    auto fmock = criterion::mock_file();

    fmock << "Hello" << std::flush;
    fmock.seekg(0);

    std::string contents;
    fmock >> contents;

    cr_assert_eq(contents, "Hello");
}
#endif

Test(redirect, mock_c) {
    std::FILE* fmock = cr_mock_file_size(4096);

    std::fprintf(fmock, "Hello");
    std::fflush(fmock);
    std::rewind(fmock);

    char contents[sizeof ("Hello")] = {0};
    fgets(contents, sizeof (contents), fmock);

    cr_assert_str_eq(contents, "Hello");
}

Test(redirect, stdout_) {
    cr_redirect_stdout();

    std::cout << "Foo" << std::flush;

    cr_expect_stdout_eq_str("Foo");
    cr_expect_stdout_neq_str("Bar");
}

Test(redirect, stderr_) {
    cr_redirect_stderr();

    std::cerr << "Foo" << std::flush;

    cr_expect_stderr_eq_str("Foo");
    cr_expect_stderr_neq_str("Bar");
}

Test(redirect, stdin_) {
    auto& f_cin = criterion::get_redirected_cin();
    f_cin << "Foo";
    f_cin.close();

    std::string read;
    std::cin >> read;

    cr_expect_eq(read, "Foo");
    cr_expect_neq(read, "Bar");
}
<|endoftext|>