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

#include "libcef/common/main_delegate.h"
#include "libcef/browser/content_browser_client.h"
#include "libcef/browser/context.h"
#include "libcef/common/cef_switches.h"
#include "libcef/common/command_line_impl.h"
#include "libcef/plugin/content_plugin_client.h"
#include "libcef/renderer/content_renderer_client.h"
#include "libcef/utility/content_utility_client.h"

#include "base/command_line.h"
#include "base/file_path.h"
#include "base/file_util.h"
#include "base/path_service.h"
#include "base/string_number_conversions.h"
#include "base/synchronization/waitable_event.h"
#include "base/threading/thread.h"
#include "content/public/browser/browser_main_runner.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/main_function_params.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/base/ui_base_paths.h"

#if defined(OS_WIN)
#include <Objbase.h>  // NOLINT(build/include_order)
#endif

#if defined(OS_MACOSX)
#include "base/mac/bundle_locations.h"
#include "base/mac/foundation_util.h"
#include "content/public/common/content_paths.h"
#endif

namespace {

#if defined(OS_MACOSX)

FilePath GetFrameworksPath() {
  // Start out with the path to the running executable.
  FilePath execPath;
  PathService::Get(base::FILE_EXE, &execPath);

  // Get the main bundle path.
  FilePath bundlePath = base::mac::GetAppBundlePath(execPath);

  // Go into the Contents/Frameworks directory.
  return bundlePath.Append(FILE_PATH_LITERAL("Contents"))
                   .Append(FILE_PATH_LITERAL("Frameworks"));
}

// The framework bundle path is used for loading resources, libraries, etc.
FilePath GetFrameworkBundlePath() {
  return GetFrameworksPath().Append(
      FILE_PATH_LITERAL("Chromium Embedded Framework.framework"));
}

FilePath GetDefaultPackPath() {
  return GetFrameworkBundlePath().Append(FILE_PATH_LITERAL("Resources"));
}

void OverrideFrameworkBundlePath() {
  base::mac::SetOverrideFrameworkBundlePath(GetFrameworkBundlePath());
}

void OverrideChildProcessPath() {
  // Retrieve the name of the running executable.
  FilePath path;
  PathService::Get(base::FILE_EXE, &path);

  std::string name = path.BaseName().value();

  FilePath helper_path = GetFrameworksPath()
      .Append(FILE_PATH_LITERAL(name+" Helper.app"))
      .Append(FILE_PATH_LITERAL("Contents"))
      .Append(FILE_PATH_LITERAL("MacOS"))
      .Append(FILE_PATH_LITERAL(name+" Helper"));

  PathService::Override(content::CHILD_PROCESS_EXE, helper_path);
}

#else  // !defined(OS_MACOSX)

FilePath GetDefaultPackPath() {
  FilePath pak_dir;
  PathService::Get(base::DIR_MODULE, &pak_dir);
  return pak_dir;
}

#endif  // !defined(OS_MACOSX)

// Used to run the UI on a separate thread.
class CefUIThread : public base::Thread {
 public:
  explicit CefUIThread(const content::MainFunctionParams& main_function_params)
    : base::Thread("CefUIThread"),
      main_function_params_(main_function_params) {
  }

  virtual void Init() OVERRIDE {
#if defined(OS_WIN)
    // Initializes the COM library on the current thread.
    CoInitialize(NULL);
#endif

    // Use our own browser process runner.
    browser_runner_.reset(content::BrowserMainRunner::Create());

    // Initialize browser process state. Results in a call to
    // CefBrowserMain::GetMainMessageLoop().
    int exit_code = browser_runner_->Initialize(main_function_params_);
    CHECK_EQ(exit_code, -1);
  }

  virtual void CleanUp() OVERRIDE {
    browser_runner_->Shutdown();
    browser_runner_.reset(NULL);

#if defined(OS_WIN)
    // Closes the COM library on the current thread. CoInitialize must
    // be balanced by a corresponding call to CoUninitialize.
    CoUninitialize();
#endif
  }

 protected:
  content::MainFunctionParams main_function_params_;
  scoped_ptr<content::BrowserMainRunner> browser_runner_;
};

}  // namespace

CefMainDelegate::CefMainDelegate(CefRefPtr<CefApp> application)
    : content_client_(application) {
}

CefMainDelegate::~CefMainDelegate() {
}

bool CefMainDelegate::BasicStartupComplete(int* exit_code) {
#if defined(OS_MACOSX)
  OverrideFrameworkBundlePath();
#endif

  CommandLine* command_line = CommandLine::ForCurrentProcess();
  std::string process_type =
      command_line->GetSwitchValueASCII(switches::kProcessType);

  if (process_type.empty()) {
    // In the browser process. Populate the global command-line object.
    const CefSettings& settings = _Context->settings();

    if (settings.command_line_args_disabled) {
      // Remove any existing command-line arguments.
      CommandLine::StringVector argv;
      argv.push_back(command_line->GetProgram().value());
      command_line->InitFromArgv(argv);

      const CommandLine::SwitchMap& map = command_line->GetSwitches();
      const_cast<CommandLine::SwitchMap*>(&map)->clear();
    }

    if (settings.single_process)
      command_line->AppendSwitch(switches::kSingleProcess);

    if (settings.browser_subprocess_path.length > 0) {
      FilePath file_path =
          FilePath(CefString(&settings.browser_subprocess_path));
      if (!file_path.empty()) {
        command_line->AppendSwitchPath(switches::kBrowserSubprocessPath,
                                       file_path);
      }
    }

    if (settings.user_agent.length > 0) {
      command_line->AppendSwitchASCII(switches::kUserAgent,
          CefString(&settings.user_agent));
    } else if (settings.product_version.length > 0) {
      command_line->AppendSwitchASCII(switches::kProductVersion,
          CefString(&settings.product_version));
    }

    if (settings.locale.length > 0) {
      command_line->AppendSwitchASCII(switches::kLocale,
          CefString(&settings.locale));
    }

    if (settings.pack_loading_disabled) {
      command_line->AppendSwitch(switches::kPackLoadingDisabled);
    } else {
      if (settings.pack_file_path.length > 0) {
        FilePath file_path = FilePath(CefString(&settings.pack_file_path));
        if (!file_path.empty())
          command_line->AppendSwitchPath(switches::kPackFilePath, file_path);
      }

      if (settings.locales_dir_path.length > 0) {
        FilePath file_path = FilePath(CefString(&settings.locales_dir_path));
        if (!file_path.empty())
          command_line->AppendSwitchPath(switches::kLocalesDirPath, file_path);
      }
    }

    if (settings.remote_debugging_port >= 1024 &&
        settings.remote_debugging_port <= 65535) {
      command_line->AppendSwitchASCII(switches::kRemoteDebuggingPort,
          base::IntToString(settings.remote_debugging_port));
    }

    // TODO(cef): Figure out how to support the sandbox.
    if (!command_line->HasSwitch(switches::kNoSandbox))
      command_line->AppendSwitch(switches::kNoSandbox);
  }

  if (content_client_.application().get()) {
    // Give the application a chance to view/modify the command line.
    CefRefPtr<CefCommandLineImpl> commandLinePtr(
        new CefCommandLineImpl(command_line, false, false));
    content_client_.application()->OnBeforeCommandLineProcessing(
        CefString(process_type), commandLinePtr.get());
    commandLinePtr->Detach(NULL);
  }

  content::SetContentClient(&content_client_);
  InitializeContentClient(process_type);

  return false;
}

void CefMainDelegate::PreSandboxStartup() {
#if defined(OS_MACOSX)
  OverrideChildProcessPath();
#endif

  const CommandLine& command_line = *CommandLine::ForCurrentProcess();
  if (command_line.HasSwitch(switches::kPackLoadingDisabled))
    content_client_.set_pack_loading_disabled(true);
  else
    InitializeResourceBundle();
}

void CefMainDelegate::SandboxInitialized(const std::string& process_type) {
}

int CefMainDelegate::RunProcess(
    const std::string& process_type,
    const content::MainFunctionParams& main_function_params) {
  if (process_type.empty()) {
    const CefSettings& settings = _Context->settings();
    if (!settings.multi_threaded_message_loop) {
      // Use our own browser process runner.
      browser_runner_.reset(content::BrowserMainRunner::Create());

      // Initialize browser process state. Results in a call to
      // CefBrowserMain::GetMainMessageLoop().
      int exit_code = browser_runner_->Initialize(main_function_params);
      if (exit_code >= 0)
        return exit_code;
    } else {
      // Run the UI on a separate thread.
      scoped_ptr<base::Thread> thread;
      thread.reset(new CefUIThread(main_function_params));
      base::Thread::Options options;
      options.message_loop_type = MessageLoop::TYPE_UI;
      if (!thread->StartWithOptions(options)) {
        NOTREACHED() << "failed to start UI thread";
        return 1;
      }
      ui_thread_.swap(thread);
    }

    return 0;
  }

  return -1;
}

void CefMainDelegate::ProcessExiting(const std::string& process_type) {
  if (!content_client_.pack_loading_disabled())
    ResourceBundle::CleanupSharedInstance();
}

#if defined(OS_MACOSX)
bool CefMainDelegate::ProcessRegistersWithSystemProcess(
    const std::string& process_type) {
  return false;
}

bool CefMainDelegate::ShouldSendMachPort(const std::string& process_type) {
  return false;
}

bool CefMainDelegate::DelaySandboxInitialization(
    const std::string& process_type) {
  return false;
}

#elif defined(OS_POSIX)
content::ZygoteForkDelegate* CefMainDelegate::ZygoteStarting() {
  return NULL;
}

void CefMainDelegate::ZygoteForked() {
  const CommandLine& command_line = *CommandLine::ForCurrentProcess();
  std::string process_type =
      command_line.GetSwitchValueASCII(switches::kProcessType);
  InitializeContentClient(process_type);
}
#endif  // OS_MACOSX

void CefMainDelegate::ShutdownBrowser() {
  if (browser_runner_.get()) {
    browser_runner_->Shutdown();
    browser_runner_.reset(NULL);
  }
  if (ui_thread_.get()) {
    // Blocks until the thread has stopped.
    ui_thread_->Stop();
    ui_thread_.reset();
  }
}

void CefMainDelegate::InitializeContentClient(
    const std::string& process_type) {
  if (process_type.empty()) {
    browser_client_.reset(new CefContentBrowserClient);
    content::GetContentClient()->set_browser(browser_client_.get());

    // Single-process is an unsupported and not fully tested mode.
    const CommandLine& command_line = *CommandLine::ForCurrentProcess();
    if (command_line.HasSwitch(switches::kSingleProcess)) {
      content::RenderProcessHost::set_run_renderer_in_process(true);
      renderer_client_.reset(new CefContentRendererClient);
      content::GetContentClient()->set_renderer(renderer_client_.get());
    }
  } else if (process_type == switches::kRendererProcess) {
    renderer_client_.reset(new CefContentRendererClient);
    content::GetContentClient()->set_renderer(renderer_client_.get());
  } else if (process_type == switches::kPluginProcess) {
    plugin_client_.reset(new CefContentPluginClient);
    content::GetContentClient()->set_plugin(plugin_client_.get());
  } else if (process_type == switches::kUtilityProcess) {
    utility_client_.reset(new CefContentUtilityClient);
    content::GetContentClient()->set_utility(utility_client_.get());
  }
}

void CefMainDelegate::InitializeResourceBundle() {
  const CommandLine& command_line = *CommandLine::ForCurrentProcess();

  FilePath pak_file, locales_dir;

  if (command_line.HasSwitch(switches::kPackFilePath))
    pak_file = command_line.GetSwitchValuePath(switches::kPackFilePath);

  if (pak_file.empty())
    pak_file = GetDefaultPackPath().Append(FILE_PATH_LITERAL("cef.pak"));

  if (command_line.HasSwitch(switches::kLocalesDirPath))
    locales_dir = command_line.GetSwitchValuePath(switches::kLocalesDirPath);

  if (!locales_dir.empty())
    PathService::Override(ui::DIR_LOCALES, locales_dir);

  std::string locale = command_line.GetSwitchValueASCII(switches::kLocale);
  if (locale.empty())
    locale = "en-US";

  const std::string loaded_locale =
      ui::ResourceBundle::InitSharedInstanceWithLocaleCef(locale);
  CHECK(!loaded_locale.empty()) << "Locale could not be found for " << locale;

  if (file_util::PathExists(pak_file))
    ResourceBundle::GetSharedInstance().AddDataPack(pak_file);
  else
    NOTREACHED() << "Could not load cef.pak";
}
<commit_msg>Fix compile error.<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "libcef/common/main_delegate.h"
#include "libcef/browser/content_browser_client.h"
#include "libcef/browser/context.h"
#include "libcef/common/cef_switches.h"
#include "libcef/common/command_line_impl.h"
#include "libcef/plugin/content_plugin_client.h"
#include "libcef/renderer/content_renderer_client.h"
#include "libcef/utility/content_utility_client.h"

#include "base/command_line.h"
#include "base/file_path.h"
#include "base/file_util.h"
#include "base/path_service.h"
#include "base/string_number_conversions.h"
#include "base/synchronization/waitable_event.h"
#include "base/threading/thread.h"
#include "content/public/browser/browser_main_runner.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/main_function_params.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/base/resource/resource_handle.h"
#include "ui/base/ui_base_paths.h"

#if defined(OS_WIN)
#include <Objbase.h>  // NOLINT(build/include_order)
#endif

#if defined(OS_MACOSX)
#include "base/mac/bundle_locations.h"
#include "base/mac/foundation_util.h"
#include "content/public/common/content_paths.h"
#endif

namespace {

#if defined(OS_MACOSX)

FilePath GetFrameworksPath() {
  // Start out with the path to the running executable.
  FilePath execPath;
  PathService::Get(base::FILE_EXE, &execPath);

  // Get the main bundle path.
  FilePath bundlePath = base::mac::GetAppBundlePath(execPath);

  // Go into the Contents/Frameworks directory.
  return bundlePath.Append(FILE_PATH_LITERAL("Contents"))
                   .Append(FILE_PATH_LITERAL("Frameworks"));
}

// The framework bundle path is used for loading resources, libraries, etc.
FilePath GetFrameworkBundlePath() {
  return GetFrameworksPath().Append(
      FILE_PATH_LITERAL("Chromium Embedded Framework.framework"));
}

FilePath GetDefaultPackPath() {
  return GetFrameworkBundlePath().Append(FILE_PATH_LITERAL("Resources"));
}

void OverrideFrameworkBundlePath() {
  base::mac::SetOverrideFrameworkBundlePath(GetFrameworkBundlePath());
}

void OverrideChildProcessPath() {
  // Retrieve the name of the running executable.
  FilePath path;
  PathService::Get(base::FILE_EXE, &path);

  std::string name = path.BaseName().value();

  FilePath helper_path = GetFrameworksPath()
      .Append(FILE_PATH_LITERAL(name+" Helper.app"))
      .Append(FILE_PATH_LITERAL("Contents"))
      .Append(FILE_PATH_LITERAL("MacOS"))
      .Append(FILE_PATH_LITERAL(name+" Helper"));

  PathService::Override(content::CHILD_PROCESS_EXE, helper_path);
}

#else  // !defined(OS_MACOSX)

FilePath GetDefaultPackPath() {
  FilePath pak_dir;
  PathService::Get(base::DIR_MODULE, &pak_dir);
  return pak_dir;
}

#endif  // !defined(OS_MACOSX)

// Used to run the UI on a separate thread.
class CefUIThread : public base::Thread {
 public:
  explicit CefUIThread(const content::MainFunctionParams& main_function_params)
    : base::Thread("CefUIThread"),
      main_function_params_(main_function_params) {
  }

  virtual void Init() OVERRIDE {
#if defined(OS_WIN)
    // Initializes the COM library on the current thread.
    CoInitialize(NULL);
#endif

    // Use our own browser process runner.
    browser_runner_.reset(content::BrowserMainRunner::Create());

    // Initialize browser process state. Results in a call to
    // CefBrowserMain::GetMainMessageLoop().
    int exit_code = browser_runner_->Initialize(main_function_params_);
    CHECK_EQ(exit_code, -1);
  }

  virtual void CleanUp() OVERRIDE {
    browser_runner_->Shutdown();
    browser_runner_.reset(NULL);

#if defined(OS_WIN)
    // Closes the COM library on the current thread. CoInitialize must
    // be balanced by a corresponding call to CoUninitialize.
    CoUninitialize();
#endif
  }

 protected:
  content::MainFunctionParams main_function_params_;
  scoped_ptr<content::BrowserMainRunner> browser_runner_;
};

}  // namespace

CefMainDelegate::CefMainDelegate(CefRefPtr<CefApp> application)
    : content_client_(application) {
}

CefMainDelegate::~CefMainDelegate() {
}

bool CefMainDelegate::BasicStartupComplete(int* exit_code) {
#if defined(OS_MACOSX)
  OverrideFrameworkBundlePath();
#endif

  CommandLine* command_line = CommandLine::ForCurrentProcess();
  std::string process_type =
      command_line->GetSwitchValueASCII(switches::kProcessType);

  if (process_type.empty()) {
    // In the browser process. Populate the global command-line object.
    const CefSettings& settings = _Context->settings();

    if (settings.command_line_args_disabled) {
      // Remove any existing command-line arguments.
      CommandLine::StringVector argv;
      argv.push_back(command_line->GetProgram().value());
      command_line->InitFromArgv(argv);

      const CommandLine::SwitchMap& map = command_line->GetSwitches();
      const_cast<CommandLine::SwitchMap*>(&map)->clear();
    }

    if (settings.single_process)
      command_line->AppendSwitch(switches::kSingleProcess);

    if (settings.browser_subprocess_path.length > 0) {
      FilePath file_path =
          FilePath(CefString(&settings.browser_subprocess_path));
      if (!file_path.empty()) {
        command_line->AppendSwitchPath(switches::kBrowserSubprocessPath,
                                       file_path);
      }
    }

    if (settings.user_agent.length > 0) {
      command_line->AppendSwitchASCII(switches::kUserAgent,
          CefString(&settings.user_agent));
    } else if (settings.product_version.length > 0) {
      command_line->AppendSwitchASCII(switches::kProductVersion,
          CefString(&settings.product_version));
    }

    if (settings.locale.length > 0) {
      command_line->AppendSwitchASCII(switches::kLocale,
          CefString(&settings.locale));
    }

    if (settings.pack_loading_disabled) {
      command_line->AppendSwitch(switches::kPackLoadingDisabled);
    } else {
      if (settings.pack_file_path.length > 0) {
        FilePath file_path = FilePath(CefString(&settings.pack_file_path));
        if (!file_path.empty())
          command_line->AppendSwitchPath(switches::kPackFilePath, file_path);
      }

      if (settings.locales_dir_path.length > 0) {
        FilePath file_path = FilePath(CefString(&settings.locales_dir_path));
        if (!file_path.empty())
          command_line->AppendSwitchPath(switches::kLocalesDirPath, file_path);
      }
    }

    if (settings.remote_debugging_port >= 1024 &&
        settings.remote_debugging_port <= 65535) {
      command_line->AppendSwitchASCII(switches::kRemoteDebuggingPort,
          base::IntToString(settings.remote_debugging_port));
    }

    // TODO(cef): Figure out how to support the sandbox.
    if (!command_line->HasSwitch(switches::kNoSandbox))
      command_line->AppendSwitch(switches::kNoSandbox);
  }

  if (content_client_.application().get()) {
    // Give the application a chance to view/modify the command line.
    CefRefPtr<CefCommandLineImpl> commandLinePtr(
        new CefCommandLineImpl(command_line, false, false));
    content_client_.application()->OnBeforeCommandLineProcessing(
        CefString(process_type), commandLinePtr.get());
    commandLinePtr->Detach(NULL);
  }

  content::SetContentClient(&content_client_);
  InitializeContentClient(process_type);

  return false;
}

void CefMainDelegate::PreSandboxStartup() {
#if defined(OS_MACOSX)
  OverrideChildProcessPath();
#endif

  const CommandLine& command_line = *CommandLine::ForCurrentProcess();
  if (command_line.HasSwitch(switches::kPackLoadingDisabled))
    content_client_.set_pack_loading_disabled(true);
  else
    InitializeResourceBundle();
}

void CefMainDelegate::SandboxInitialized(const std::string& process_type) {
}

int CefMainDelegate::RunProcess(
    const std::string& process_type,
    const content::MainFunctionParams& main_function_params) {
  if (process_type.empty()) {
    const CefSettings& settings = _Context->settings();
    if (!settings.multi_threaded_message_loop) {
      // Use our own browser process runner.
      browser_runner_.reset(content::BrowserMainRunner::Create());

      // Initialize browser process state. Results in a call to
      // CefBrowserMain::GetMainMessageLoop().
      int exit_code = browser_runner_->Initialize(main_function_params);
      if (exit_code >= 0)
        return exit_code;
    } else {
      // Run the UI on a separate thread.
      scoped_ptr<base::Thread> thread;
      thread.reset(new CefUIThread(main_function_params));
      base::Thread::Options options;
      options.message_loop_type = MessageLoop::TYPE_UI;
      if (!thread->StartWithOptions(options)) {
        NOTREACHED() << "failed to start UI thread";
        return 1;
      }
      ui_thread_.swap(thread);
    }

    return 0;
  }

  return -1;
}

void CefMainDelegate::ProcessExiting(const std::string& process_type) {
  if (!content_client_.pack_loading_disabled())
    ResourceBundle::CleanupSharedInstance();
}

#if defined(OS_MACOSX)
bool CefMainDelegate::ProcessRegistersWithSystemProcess(
    const std::string& process_type) {
  return false;
}

bool CefMainDelegate::ShouldSendMachPort(const std::string& process_type) {
  return false;
}

bool CefMainDelegate::DelaySandboxInitialization(
    const std::string& process_type) {
  return false;
}

#elif defined(OS_POSIX)
content::ZygoteForkDelegate* CefMainDelegate::ZygoteStarting() {
  return NULL;
}

void CefMainDelegate::ZygoteForked() {
  const CommandLine& command_line = *CommandLine::ForCurrentProcess();
  std::string process_type =
      command_line.GetSwitchValueASCII(switches::kProcessType);
  InitializeContentClient(process_type);
}
#endif  // OS_MACOSX

void CefMainDelegate::ShutdownBrowser() {
  if (browser_runner_.get()) {
    browser_runner_->Shutdown();
    browser_runner_.reset(NULL);
  }
  if (ui_thread_.get()) {
    // Blocks until the thread has stopped.
    ui_thread_->Stop();
    ui_thread_.reset();
  }
}

void CefMainDelegate::InitializeContentClient(
    const std::string& process_type) {
  if (process_type.empty()) {
    browser_client_.reset(new CefContentBrowserClient);
    content::GetContentClient()->set_browser(browser_client_.get());

    // Single-process is an unsupported and not fully tested mode.
    const CommandLine& command_line = *CommandLine::ForCurrentProcess();
    if (command_line.HasSwitch(switches::kSingleProcess)) {
      content::RenderProcessHost::set_run_renderer_in_process(true);
      renderer_client_.reset(new CefContentRendererClient);
      content::GetContentClient()->set_renderer(renderer_client_.get());
    }
  } else if (process_type == switches::kRendererProcess) {
    renderer_client_.reset(new CefContentRendererClient);
    content::GetContentClient()->set_renderer(renderer_client_.get());
  } else if (process_type == switches::kPluginProcess) {
    plugin_client_.reset(new CefContentPluginClient);
    content::GetContentClient()->set_plugin(plugin_client_.get());
  } else if (process_type == switches::kUtilityProcess) {
    utility_client_.reset(new CefContentUtilityClient);
    content::GetContentClient()->set_utility(utility_client_.get());
  }
}

void CefMainDelegate::InitializeResourceBundle() {
  const CommandLine& command_line = *CommandLine::ForCurrentProcess();

  FilePath pak_file, locales_dir;

  if (command_line.HasSwitch(switches::kPackFilePath))
    pak_file = command_line.GetSwitchValuePath(switches::kPackFilePath);

  if (pak_file.empty())
    pak_file = GetDefaultPackPath().Append(FILE_PATH_LITERAL("cef.pak"));

  if (command_line.HasSwitch(switches::kLocalesDirPath))
    locales_dir = command_line.GetSwitchValuePath(switches::kLocalesDirPath);

  if (!locales_dir.empty())
    PathService::Override(ui::DIR_LOCALES, locales_dir);

  std::string locale = command_line.GetSwitchValueASCII(switches::kLocale);
  if (locale.empty())
    locale = "en-US";

  const std::string loaded_locale =
      ui::ResourceBundle::InitSharedInstanceWithLocaleCef(locale);
  CHECK(!loaded_locale.empty()) << "Locale could not be found for " << locale;

  if (file_util::PathExists(pak_file)) {
    ResourceBundle::GetSharedInstance().AddDataPack(
        pak_file, ui::ResourceHandle::kScaleFactor100x);
  } else {
    NOTREACHED() << "Could not load cef.pak";
  }
}
<|endoftext|>


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

#ifndef _LIBDNF_CONFIG_PRIVATE_HPP
#define _LIBDNF_CONFIG_PRIVATE_HPP

#include "Option.hpp"

namespace libdnf {

template<typename T>
static void optionTListAppend(T & option, Option::Priority priority, const std::string & value)
{
    if (value.empty()) {
        option.set(priority, value);
        return;
    }
    auto addPriority = priority < option.getPriority() ? option.getPriority() : priority;
    auto val = option.fromString(value);
    for (auto & item : val) {
        if (item.empty()) {
            option.set(priority, item);
        } else {
            auto origValue = option.getValue();
            origValue.push_back(item);
            option.set(addPriority, origValue);
        }
    }
}

}

#endif
<commit_msg>Append option: only first empty value clears existing (RhBug:1788154)<commit_after>/*
 * Copyright (C) 2018 Red Hat, Inc.
 *
 * Licensed under the GNU Lesser General Public License Version 2.1
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

#ifndef _LIBDNF_CONFIG_PRIVATE_HPP
#define _LIBDNF_CONFIG_PRIVATE_HPP

#include "Option.hpp"

namespace libdnf {

template<typename T>
static void optionTListAppend(T & option, Option::Priority priority, const std::string & value)
{
    if (value.empty()) {
        option.set(priority, value);
        return;
    }
    auto addPriority = priority < option.getPriority() ? option.getPriority() : priority;
    auto val = option.fromString(value);
    bool first = true;
    for (auto & item : val) {
        if (item.empty()) {
            if (first) {
                option.set(priority, item);
            }
        } else {
            auto origValue = option.getValue();
            origValue.push_back(item);
            option.set(addPriority, origValue);
        }
        first = false;
    }
}

}

#endif
<|endoftext|>


<commit_before>#include "input/input_state.h"
#include "input/keycodes.h"
#include "ui/ui_screen.h"
#include "ui/ui_context.h"
#include "ui/screen.h"
#include "i18n/i18n.h"
#include "gfx_es2/draw_buffer.h"

UIScreen::UIScreen()
	: Screen(), root_(0), recreateViews_(true), hatDown_(0) {
}

UIScreen::~UIScreen() {
	delete root_;
}

void UIScreen::DoRecreateViews() {
	if (recreateViews_) {
		delete root_;
		root_ = 0;
		CreateViews();
		recreateViews_ = false;
	}
}

void UIScreen::update(InputState &input) {
	DoRecreateViews();

	if (root_) {
		UpdateViewHierarchy(input, root_);
	}
}

void UIScreen::render() {
	DoRecreateViews();

	if (root_) {
		UI::LayoutViewHierarchy(*screenManager()->getUIContext(), root_);

		screenManager()->getUIContext()->Begin();
		DrawBackground(*screenManager()->getUIContext());
		root_->Draw(*screenManager()->getUIContext());
		screenManager()->getUIContext()->End();
		screenManager()->getUIContext()->Flush();
	}
}

void UIScreen::touch(const TouchInput &touch) {
	if (root_) {
		UI::TouchEvent(touch, root_);
	}
}

void UIScreen::key(const KeyInput &key) {
	if (root_) {
		UI::KeyEvent(key, root_);
	}
}

void UIDialogScreen::key(const KeyInput &key) {
	if ((key.flags & KEY_DOWN) && UI::IsEscapeKeyCode(key.keyCode)) {
		if (finished_) {
			ELOG("Screen already finished");
		} else {
			finished_ = true;
			screenManager()->finishDialog(this, DR_BACK);
		}
	} else {
		UIScreen::key(key);
	}
}

void UIScreen::axis(const AxisInput &axis) {
	// Simple translation of hat to keys for Shield and other modern pads.
	// TODO: Use some variant of keymap?
	int flags = 0;
	if (axis.axisId == JOYSTICK_AXIS_HAT_X) {
		if (axis.value < -0.7f)
			flags |= PAD_BUTTON_LEFT;
		if (axis.value > 0.7f)
			flags |= PAD_BUTTON_RIGHT;
	}
	if (axis.axisId == JOYSTICK_AXIS_HAT_Y) {
		if (axis.value < -0.7f)
			flags |= PAD_BUTTON_UP;
		if (axis.value > 0.7f)
			flags |= PAD_BUTTON_DOWN;
	}

	// Yeah yeah, this should be table driven..
	int pressed = flags & ~hatDown_;
	int released = ~flags & hatDown_;
	if (pressed & PAD_BUTTON_LEFT) key(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_DPAD_LEFT, KEY_DOWN));
	if (pressed & PAD_BUTTON_RIGHT) key(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_DPAD_RIGHT, KEY_DOWN));
	if (pressed & PAD_BUTTON_UP) key(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_DPAD_UP, KEY_DOWN));
	if (pressed & PAD_BUTTON_DOWN) key(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_DPAD_DOWN, KEY_DOWN));
	if (released & PAD_BUTTON_LEFT) key(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_DPAD_LEFT, KEY_UP));
	if (released & PAD_BUTTON_RIGHT) key(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_DPAD_RIGHT, KEY_UP));
	if (released & PAD_BUTTON_UP) key(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_DPAD_UP, KEY_UP));
	if (released & PAD_BUTTON_DOWN) key(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_DPAD_DOWN, KEY_UP));
	hatDown_ = flags;
	if (root_) {
		UI::AxisEvent(axis, root_);
	}
}

UI::EventReturn UIScreen::OnBack(UI::EventParams &e) {
	screenManager()->finishDialog(this, DR_BACK);
	return UI::EVENT_DONE;
}

UI::EventReturn UIScreen::OnOK(UI::EventParams &e) {
	screenManager()->finishDialog(this, DR_OK);
	return UI::EVENT_DONE;
}

UI::EventReturn UIScreen::OnCancel(UI::EventParams &e) {
	screenManager()->finishDialog(this, DR_CANCEL);
	return UI::EVENT_DONE;
}

PopupScreen::PopupScreen(std::string title, std::string button1, std::string button2)
	: box_(0), title_(title) {
	I18NCategory *d = GetI18NCategory("Dialog");
	if (!button1.empty())
		button1_ = d->T(button1.c_str());
	if (!button2.empty())
		button2_ = d->T(button2.c_str());
}

void PopupScreen::touch(const TouchInput &touch) {
	if (!box_ || (touch.flags & TOUCH_DOWN) == 0 || touch.id != 0) {
		UIDialogScreen::touch(touch);
		return;
	}

	if (!box_->GetBounds().Contains(touch.x, touch.y))
		screenManager()->finishDialog(this, DR_BACK);

	UIDialogScreen::touch(touch);
}

void PopupScreen::CreateViews() {
	using namespace UI;

	root_ = new AnchorLayout(new LayoutParams(FILL_PARENT, FILL_PARENT));

	box_ = new LinearLayout(ORIENT_VERTICAL,
		new AnchorLayoutParams(550, FillVertical() ? dp_yres - 30 : WRAP_CONTENT, dp_xres / 2, dp_yres / 2, NONE, NONE, true));

	root_->Add(box_);
	box_->SetBG(UI::Drawable(0xFF303030));
	box_->SetHasDropShadow(true);

	View *title = new PopupHeader(title_);
	box_->Add(title);

	CreatePopupContents(box_);

	if (ShowButtons() && !button1_.empty()) {
		// And the two buttons at the bottom.
		LinearLayout *buttonRow = new LinearLayout(ORIENT_HORIZONTAL, new LinearLayoutParams(200, WRAP_CONTENT));
		buttonRow->SetSpacing(0);
		Margins buttonMargins(5, 5);

		// Adjust button order to the platform default.
#if defined(_WIN32)
		buttonRow->Add(new Button(button1_, new LinearLayoutParams(1.0f, buttonMargins)))->OnClick.Handle(this, &PopupScreen::OnOK);
		if (!button2_.empty())
			buttonRow->Add(new Button(button2_, new LinearLayoutParams(1.0f, buttonMargins)))->OnClick.Handle(this, &PopupScreen::OnCancel);
#else
		if (!button2_.empty())
			buttonRow->Add(new Button(button2_, new LinearLayoutParams(1.0f)))->OnClick.Handle(this, &PopupScreen::OnCancel);
		buttonRow->Add(new Button(button1_, new LinearLayoutParams(1.0f)))->OnClick.Handle(this, &PopupScreen::OnOK);
#endif

		box_->Add(buttonRow);
	}
}

void MessagePopupScreen::CreatePopupContents(UI::ViewGroup *parent) {
	parent->Add(new UI::TextView(message_));
}

UI::EventReturn PopupScreen::OnOK(UI::EventParams &e) {
	OnCompleted(DR_OK);
	screenManager()->finishDialog(this, DR_OK);
	return UI::EVENT_DONE;
}

UI::EventReturn PopupScreen::OnCancel(UI::EventParams &e) {
	OnCompleted(DR_CANCEL);
	screenManager()->finishDialog(this, DR_CANCEL);
	return UI::EVENT_DONE;
}

void ListPopupScreen::CreatePopupContents(UI::ViewGroup *parent) {
	using namespace UI;

	listView_ = parent->Add(new ListView(&adaptor_)); //, new LinearLayoutParams(1.0)));
	listView_->SetMaxHeight(dp_yres - 140);
	listView_->OnChoice.Handle(this, &ListPopupScreen::OnListChoice);
}

UI::EventReturn ListPopupScreen::OnListChoice(UI::EventParams &e) {
	adaptor_.SetSelected(e.a);
	if (callback_)
		callback_(adaptor_.GetSelected());
	screenManager()->finishDialog(this, DR_OK);
	OnCompleted(DR_OK);
	OnChoice.Dispatch(e);
	return UI::EVENT_DONE;
}

namespace UI {

UI::EventReturn PopupMultiChoice::HandleClick(UI::EventParams &e) {
	std::vector<std::string> choices;
	for (int i = 0; i < numChoices_; i++) {
		choices.push_back(category_ ? category_->T(choices_[i]) : choices_[i]);
	}

	Screen *popupScreen = new ListPopupScreen(text_, choices, *value_ - minVal_,
		std::bind(&PopupMultiChoice::ChoiceCallback, this, placeholder::_1));
	screenManager_->push(popupScreen);
	return UI::EVENT_DONE;
}

void PopupMultiChoice::UpdateText() {
	// Clamp the value to be safe.
	if (*value_ < minVal_ || *value_ > minVal_ + numChoices_ - 1) {
		valueText_ = "(invalid choice)";  // Shouldn't happen. Should be no need to translate this.
	} else {
		valueText_ = category_ ? category_->T(choices_[*value_ - minVal_]) : choices_[*value_ - minVal_];
	}
}

void PopupMultiChoice::ChoiceCallback(int num) {
	if (num != -1) {
		*value_ = num + minVal_;
		UpdateText();

		UI::EventParams e;
		e.v = this;
		e.a = num;
		OnChoice.Trigger(e);
	}
}

void PopupMultiChoice::Draw(UIContext &dc) {
	Choice::Draw(dc);
	int paddingX = 12;
	dc.SetFontStyle(dc.theme->uiFont);
	dc.DrawText(valueText_.c_str(), bounds_.x2() - paddingX, bounds_.centerY(), 0xFFFFFFFF, ALIGN_RIGHT | ALIGN_VCENTER);
}

PopupSliderChoice::PopupSliderChoice(int *value, int minValue, int maxValue, const std::string &text, ScreenManager *screenManager, LayoutParams *layoutParams)
	: Choice(text, "", false, layoutParams), value_(value), minValue_(minValue), maxValue_(maxValue), screenManager_(screenManager) {
	OnClick.Handle(this, &PopupSliderChoice::HandleClick);
}

PopupSliderChoiceFloat::PopupSliderChoiceFloat(float *value, float minValue, float maxValue, const std::string &text, ScreenManager *screenManager, LayoutParams *layoutParams)
	: Choice(text, "", false, layoutParams), value_(value), minValue_(minValue), maxValue_(maxValue), screenManager_(screenManager) {
	OnClick.Handle(this, &PopupSliderChoiceFloat::HandleClick);
}

EventReturn PopupSliderChoice::HandleClick(EventParams &e) {
	SliderPopupScreen *popupScreen = new SliderPopupScreen(value_, minValue_, maxValue_, text_);
	popupScreen->OnChange.Handle(this, &PopupSliderChoice::HandleChange);
	screenManager_->push(popupScreen);
	return EVENT_DONE;
}

EventReturn PopupSliderChoice::HandleChange(EventParams &e) {
	e.v = this;
	OnChange.Trigger(e);
	return EVENT_DONE;
}

void PopupSliderChoice::Draw(UIContext &dc) {
	Choice::Draw(dc);
	char temp[32];
	sprintf(temp, "%i", *value_);
	dc.SetFontStyle(dc.theme->uiFont);
	dc.DrawText(temp, bounds_.x2() - 12, bounds_.centerY(), 0xFFFFFFFF, ALIGN_RIGHT | ALIGN_VCENTER);
}

EventReturn PopupSliderChoiceFloat::HandleClick(EventParams &e) {
	SliderFloatPopupScreen *popupScreen = new SliderFloatPopupScreen(value_, minValue_, maxValue_, text_);
	popupScreen->OnChange.Handle(this, &PopupSliderChoiceFloat::HandleChange);
	screenManager_->push(popupScreen);
	return EVENT_DONE;
}

EventReturn PopupSliderChoiceFloat::HandleChange(EventParams &e) {
	e.v = this;
	OnChange.Trigger(e);
	return EVENT_DONE;
}

void PopupSliderChoiceFloat::Draw(UIContext &dc) {
	Choice::Draw(dc);
	char temp[32];
	sprintf(temp, "%2.2f", *value_);
	dc.SetFontStyle(dc.theme->uiFont);
	dc.DrawText(temp, bounds_.x2() - 12, bounds_.centerY(), 0xFFFFFFFF, ALIGN_RIGHT | ALIGN_VCENTER);
}

EventReturn SliderPopupScreen::OnDecrease(EventParams &params) {
	sliderValue_--;
	slider_->Clamp();
	return EVENT_DONE;
}

EventReturn SliderPopupScreen::OnIncrease(EventParams &params) {
	sliderValue_++;
	slider_->Clamp();
	return EVENT_DONE;
}

void SliderPopupScreen::CreatePopupContents(UI::ViewGroup *parent) {
	using namespace UI;
	sliderValue_ = *value_;
	LinearLayout *lin = parent->Add(new LinearLayout(ORIENT_HORIZONTAL, new LinearLayoutParams(UI::Margins(10, 5))));
	slider_ = new Slider(&sliderValue_, minValue_, maxValue_, new LinearLayoutParams(1.0f));
	lin->Add(slider_);
	lin->Add(new Button(" - "))->OnClick.Handle(this, &SliderPopupScreen::OnDecrease);
	lin->Add(new Button(" + "))->OnClick.Handle(this, &SliderPopupScreen::OnIncrease);

	UI::SetFocusedView(slider_);
}

void SliderFloatPopupScreen::CreatePopupContents(UI::ViewGroup *parent) {
	using namespace UI;
	sliderValue_ = *value_;
	slider_ = parent->Add(new SliderFloat(&sliderValue_, minValue_, maxValue_, new LinearLayoutParams(UI::Margins(10, 5))));
	UI::SetFocusedView(slider_);
}

void SliderPopupScreen::OnCompleted(DialogResult result) {
	if (result == DR_OK) {
		*value_ = sliderValue_;
		EventParams e;
		e.v = 0;
		e.a = *value_;
		OnChange.Trigger(e);
	}
}

void SliderFloatPopupScreen::OnCompleted(DialogResult result) {
	if (result == DR_OK) {
		*value_ = sliderValue_;
		EventParams e;
		e.v = 0;
		e.a = (int)*value_;
		e.f = *value_;
		OnChange.Trigger(e);
	}
}

}  // namespace UI
<commit_msg>Fix the disabled look of some views<commit_after>#include "input/input_state.h"
#include "input/keycodes.h"
#include "ui/ui_screen.h"
#include "ui/ui_context.h"
#include "ui/screen.h"
#include "i18n/i18n.h"
#include "gfx_es2/draw_buffer.h"

UIScreen::UIScreen()
	: Screen(), root_(0), recreateViews_(true), hatDown_(0) {
}

UIScreen::~UIScreen() {
	delete root_;
}

void UIScreen::DoRecreateViews() {
	if (recreateViews_) {
		delete root_;
		root_ = 0;
		CreateViews();
		recreateViews_ = false;
	}
}

void UIScreen::update(InputState &input) {
	DoRecreateViews();

	if (root_) {
		UpdateViewHierarchy(input, root_);
	}
}

void UIScreen::render() {
	DoRecreateViews();

	if (root_) {
		UI::LayoutViewHierarchy(*screenManager()->getUIContext(), root_);

		screenManager()->getUIContext()->Begin();
		DrawBackground(*screenManager()->getUIContext());
		root_->Draw(*screenManager()->getUIContext());
		screenManager()->getUIContext()->End();
		screenManager()->getUIContext()->Flush();
	}
}

void UIScreen::touch(const TouchInput &touch) {
	if (root_) {
		UI::TouchEvent(touch, root_);
	}
}

void UIScreen::key(const KeyInput &key) {
	if (root_) {
		UI::KeyEvent(key, root_);
	}
}

void UIDialogScreen::key(const KeyInput &key) {
	if ((key.flags & KEY_DOWN) && UI::IsEscapeKeyCode(key.keyCode)) {
		if (finished_) {
			ELOG("Screen already finished");
		} else {
			finished_ = true;
			screenManager()->finishDialog(this, DR_BACK);
		}
	} else {
		UIScreen::key(key);
	}
}

void UIScreen::axis(const AxisInput &axis) {
	// Simple translation of hat to keys for Shield and other modern pads.
	// TODO: Use some variant of keymap?
	int flags = 0;
	if (axis.axisId == JOYSTICK_AXIS_HAT_X) {
		if (axis.value < -0.7f)
			flags |= PAD_BUTTON_LEFT;
		if (axis.value > 0.7f)
			flags |= PAD_BUTTON_RIGHT;
	}
	if (axis.axisId == JOYSTICK_AXIS_HAT_Y) {
		if (axis.value < -0.7f)
			flags |= PAD_BUTTON_UP;
		if (axis.value > 0.7f)
			flags |= PAD_BUTTON_DOWN;
	}

	// Yeah yeah, this should be table driven..
	int pressed = flags & ~hatDown_;
	int released = ~flags & hatDown_;
	if (pressed & PAD_BUTTON_LEFT) key(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_DPAD_LEFT, KEY_DOWN));
	if (pressed & PAD_BUTTON_RIGHT) key(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_DPAD_RIGHT, KEY_DOWN));
	if (pressed & PAD_BUTTON_UP) key(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_DPAD_UP, KEY_DOWN));
	if (pressed & PAD_BUTTON_DOWN) key(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_DPAD_DOWN, KEY_DOWN));
	if (released & PAD_BUTTON_LEFT) key(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_DPAD_LEFT, KEY_UP));
	if (released & PAD_BUTTON_RIGHT) key(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_DPAD_RIGHT, KEY_UP));
	if (released & PAD_BUTTON_UP) key(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_DPAD_UP, KEY_UP));
	if (released & PAD_BUTTON_DOWN) key(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_DPAD_DOWN, KEY_UP));
	hatDown_ = flags;
	if (root_) {
		UI::AxisEvent(axis, root_);
	}
}

UI::EventReturn UIScreen::OnBack(UI::EventParams &e) {
	screenManager()->finishDialog(this, DR_BACK);
	return UI::EVENT_DONE;
}

UI::EventReturn UIScreen::OnOK(UI::EventParams &e) {
	screenManager()->finishDialog(this, DR_OK);
	return UI::EVENT_DONE;
}

UI::EventReturn UIScreen::OnCancel(UI::EventParams &e) {
	screenManager()->finishDialog(this, DR_CANCEL);
	return UI::EVENT_DONE;
}

PopupScreen::PopupScreen(std::string title, std::string button1, std::string button2)
	: box_(0), title_(title) {
	I18NCategory *d = GetI18NCategory("Dialog");
	if (!button1.empty())
		button1_ = d->T(button1.c_str());
	if (!button2.empty())
		button2_ = d->T(button2.c_str());
}

void PopupScreen::touch(const TouchInput &touch) {
	if (!box_ || (touch.flags & TOUCH_DOWN) == 0 || touch.id != 0) {
		UIDialogScreen::touch(touch);
		return;
	}

	if (!box_->GetBounds().Contains(touch.x, touch.y))
		screenManager()->finishDialog(this, DR_BACK);

	UIDialogScreen::touch(touch);
}

void PopupScreen::CreateViews() {
	using namespace UI;

	root_ = new AnchorLayout(new LayoutParams(FILL_PARENT, FILL_PARENT));

	box_ = new LinearLayout(ORIENT_VERTICAL,
		new AnchorLayoutParams(550, FillVertical() ? dp_yres - 30 : WRAP_CONTENT, dp_xres / 2, dp_yres / 2, NONE, NONE, true));

	root_->Add(box_);
	box_->SetBG(UI::Drawable(0xFF303030));
	box_->SetHasDropShadow(true);

	View *title = new PopupHeader(title_);
	box_->Add(title);

	CreatePopupContents(box_);

	if (ShowButtons() && !button1_.empty()) {
		// And the two buttons at the bottom.
		LinearLayout *buttonRow = new LinearLayout(ORIENT_HORIZONTAL, new LinearLayoutParams(200, WRAP_CONTENT));
		buttonRow->SetSpacing(0);
		Margins buttonMargins(5, 5);

		// Adjust button order to the platform default.
#if defined(_WIN32)
		buttonRow->Add(new Button(button1_, new LinearLayoutParams(1.0f, buttonMargins)))->OnClick.Handle(this, &PopupScreen::OnOK);
		if (!button2_.empty())
			buttonRow->Add(new Button(button2_, new LinearLayoutParams(1.0f, buttonMargins)))->OnClick.Handle(this, &PopupScreen::OnCancel);
#else
		if (!button2_.empty())
			buttonRow->Add(new Button(button2_, new LinearLayoutParams(1.0f)))->OnClick.Handle(this, &PopupScreen::OnCancel);
		buttonRow->Add(new Button(button1_, new LinearLayoutParams(1.0f)))->OnClick.Handle(this, &PopupScreen::OnOK);
#endif

		box_->Add(buttonRow);
	}
}

void MessagePopupScreen::CreatePopupContents(UI::ViewGroup *parent) {
	parent->Add(new UI::TextView(message_));
}

UI::EventReturn PopupScreen::OnOK(UI::EventParams &e) {
	OnCompleted(DR_OK);
	screenManager()->finishDialog(this, DR_OK);
	return UI::EVENT_DONE;
}

UI::EventReturn PopupScreen::OnCancel(UI::EventParams &e) {
	OnCompleted(DR_CANCEL);
	screenManager()->finishDialog(this, DR_CANCEL);
	return UI::EVENT_DONE;
}

void ListPopupScreen::CreatePopupContents(UI::ViewGroup *parent) {
	using namespace UI;

	listView_ = parent->Add(new ListView(&adaptor_)); //, new LinearLayoutParams(1.0)));
	listView_->SetMaxHeight(dp_yres - 140);
	listView_->OnChoice.Handle(this, &ListPopupScreen::OnListChoice);
}

UI::EventReturn ListPopupScreen::OnListChoice(UI::EventParams &e) {
	adaptor_.SetSelected(e.a);
	if (callback_)
		callback_(adaptor_.GetSelected());
	screenManager()->finishDialog(this, DR_OK);
	OnCompleted(DR_OK);
	OnChoice.Dispatch(e);
	return UI::EVENT_DONE;
}

namespace UI {

UI::EventReturn PopupMultiChoice::HandleClick(UI::EventParams &e) {
	std::vector<std::string> choices;
	for (int i = 0; i < numChoices_; i++) {
		choices.push_back(category_ ? category_->T(choices_[i]) : choices_[i]);
	}

	Screen *popupScreen = new ListPopupScreen(text_, choices, *value_ - minVal_,
		std::bind(&PopupMultiChoice::ChoiceCallback, this, placeholder::_1));
	screenManager_->push(popupScreen);
	return UI::EVENT_DONE;
}

void PopupMultiChoice::UpdateText() {
	// Clamp the value to be safe.
	if (*value_ < minVal_ || *value_ > minVal_ + numChoices_ - 1) {
		valueText_ = "(invalid choice)";  // Shouldn't happen. Should be no need to translate this.
	} else {
		valueText_ = category_ ? category_->T(choices_[*value_ - minVal_]) : choices_[*value_ - minVal_];
	}
}

void PopupMultiChoice::ChoiceCallback(int num) {
	if (num != -1) {
		*value_ = num + minVal_;
		UpdateText();

		UI::EventParams e;
		e.v = this;
		e.a = num;
		OnChoice.Trigger(e);
	}
}

void PopupMultiChoice::Draw(UIContext &dc) {
	Style style = dc.theme->itemStyle;
	if (!IsEnabled()) {
		style = dc.theme->itemDisabledStyle;
	}
	Choice::Draw(dc);
	int paddingX = 12;
	dc.SetFontStyle(dc.theme->uiFont);
	dc.DrawText(valueText_.c_str(), bounds_.x2() - paddingX, bounds_.centerY(), style.fgColor, ALIGN_RIGHT | ALIGN_VCENTER);
}

PopupSliderChoice::PopupSliderChoice(int *value, int minValue, int maxValue, const std::string &text, ScreenManager *screenManager, LayoutParams *layoutParams)
	: Choice(text, "", false, layoutParams), value_(value), minValue_(minValue), maxValue_(maxValue), screenManager_(screenManager) {
	OnClick.Handle(this, &PopupSliderChoice::HandleClick);
}

PopupSliderChoiceFloat::PopupSliderChoiceFloat(float *value, float minValue, float maxValue, const std::string &text, ScreenManager *screenManager, LayoutParams *layoutParams)
	: Choice(text, "", false, layoutParams), value_(value), minValue_(minValue), maxValue_(maxValue), screenManager_(screenManager) {
	OnClick.Handle(this, &PopupSliderChoiceFloat::HandleClick);
}

EventReturn PopupSliderChoice::HandleClick(EventParams &e) {
	SliderPopupScreen *popupScreen = new SliderPopupScreen(value_, minValue_, maxValue_, text_);
	popupScreen->OnChange.Handle(this, &PopupSliderChoice::HandleChange);
	screenManager_->push(popupScreen);
	return EVENT_DONE;
}

EventReturn PopupSliderChoice::HandleChange(EventParams &e) {
	e.v = this;
	OnChange.Trigger(e);
	return EVENT_DONE;
}

void PopupSliderChoice::Draw(UIContext &dc) {
	Style style = dc.theme->itemStyle;
	if (!IsEnabled()) {
		style = dc.theme->itemDisabledStyle;
	}
	Choice::Draw(dc);
	char temp[32];
	sprintf(temp, "%i", *value_);
	dc.SetFontStyle(dc.theme->uiFont);
	dc.DrawText(temp, bounds_.x2() - 12, bounds_.centerY(), style.fgColor, ALIGN_RIGHT | ALIGN_VCENTER);
}

EventReturn PopupSliderChoiceFloat::HandleClick(EventParams &e) {
	SliderFloatPopupScreen *popupScreen = new SliderFloatPopupScreen(value_, minValue_, maxValue_, text_);
	popupScreen->OnChange.Handle(this, &PopupSliderChoiceFloat::HandleChange);
	screenManager_->push(popupScreen);
	return EVENT_DONE;
}

EventReturn PopupSliderChoiceFloat::HandleChange(EventParams &e) {
	e.v = this;
	OnChange.Trigger(e);
	return EVENT_DONE;
}

void PopupSliderChoiceFloat::Draw(UIContext &dc) {
	Style style = dc.theme->itemStyle;
	if (!IsEnabled()) {
		style = dc.theme->itemDisabledStyle;
	}
	Choice::Draw(dc);
	char temp[32];
	sprintf(temp, "%2.2f", *value_);
	dc.SetFontStyle(dc.theme->uiFont);
	dc.DrawText(temp, bounds_.x2() - 12, bounds_.centerY(), style.fgColor, ALIGN_RIGHT | ALIGN_VCENTER);
}

EventReturn SliderPopupScreen::OnDecrease(EventParams &params) {
	sliderValue_--;
	slider_->Clamp();
	return EVENT_DONE;
}

EventReturn SliderPopupScreen::OnIncrease(EventParams &params) {
	sliderValue_++;
	slider_->Clamp();
	return EVENT_DONE;
}

void SliderPopupScreen::CreatePopupContents(UI::ViewGroup *parent) {
	using namespace UI;
	sliderValue_ = *value_;
	LinearLayout *lin = parent->Add(new LinearLayout(ORIENT_HORIZONTAL, new LinearLayoutParams(UI::Margins(10, 5))));
	slider_ = new Slider(&sliderValue_, minValue_, maxValue_, new LinearLayoutParams(1.0f));
	lin->Add(slider_);
	lin->Add(new Button(" - "))->OnClick.Handle(this, &SliderPopupScreen::OnDecrease);
	lin->Add(new Button(" + "))->OnClick.Handle(this, &SliderPopupScreen::OnIncrease);

	UI::SetFocusedView(slider_);
}

void SliderFloatPopupScreen::CreatePopupContents(UI::ViewGroup *parent) {
	using namespace UI;
	sliderValue_ = *value_;
	slider_ = parent->Add(new SliderFloat(&sliderValue_, minValue_, maxValue_, new LinearLayoutParams(UI::Margins(10, 5))));
	UI::SetFocusedView(slider_);
}

void SliderPopupScreen::OnCompleted(DialogResult result) {
	if (result == DR_OK) {
		*value_ = sliderValue_;
		EventParams e;
		e.v = 0;
		e.a = *value_;
		OnChange.Trigger(e);
	}
}

void SliderFloatPopupScreen::OnCompleted(DialogResult result) {
	if (result == DR_OK) {
		*value_ = sliderValue_;
		EventParams e;
		e.v = 0;
		e.a = (int)*value_;
		e.f = *value_;
		OnChange.Trigger(e);
	}
}

}  // namespace UI
<|endoftext|>


<commit_before>// Copyright 2015 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "breadboard/version.h"

namespace breadboard {

#define BREADBOARD_VERSION_MAJOR 1
#define BREADBOARD_VERSION_MINOR 0
#define BREADBOARD_VERSION_REVISION 1

// Turn X into a string literal.
#define BREADBOARD_STRING_EXPAND(X) #X
#define BREADBOARD_STRING(X) BREADBOARD_STRING_EXPAND(X)

/// @var kVersion
/// @brief String which identifies the current version of MathFu.
///
/// @ref kVersion is used by Google developers to identify which applications
/// uploaded to Google Play are using this library. This allows the development
/// team at Google to determine the popularity of the library.
/// How it works: Applications that are uploaded to the Google Play Store are
/// scanned for this version string. We track which applications are using it
/// to measure popularity. You are free to remove it (of course) but we would
/// appreciate if you left it in.
///
static const BreadboardVersion kVersion = {
  BREADBOARD_VERSION_MAJOR,
  BREADBOARD_VERSION_MINOR,
  BREADBOARD_VERSION_REVISION,
  "Breadboard "
  BREADBOARD_STRING(BREADBOARD_VERSION_MAJOR) "."
  BREADBOARD_STRING(BREADBOARD_VERSION_MINOR) "."
  BREADBOARD_STRING(BREADBOARD_VERSION_REVISION)
};

const BreadboardVersion& Version() { return kVersion; }

}  // namespace breadboard
<commit_msg>Update version numbers on all FPL projects. PiperOrigin-RevId: 148149051 Change-Id: I03745e7984cfcef4b00a38ea97a37f307d251a88<commit_after>// Copyright 2015 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "breadboard/version.h"

namespace breadboard {

#define BREADBOARD_VERSION_MAJOR 1
#define BREADBOARD_VERSION_MINOR 0
#define BREADBOARD_VERSION_REVISION 2

// Turn X into a string literal.
#define BREADBOARD_STRING_EXPAND(X) #X
#define BREADBOARD_STRING(X) BREADBOARD_STRING_EXPAND(X)

/// @var kVersion
/// @brief String which identifies the current version of MathFu.
///
/// @ref kVersion is used by Google developers to identify which applications
/// uploaded to Google Play are using this library. This allows the development
/// team at Google to determine the popularity of the library.
/// How it works: Applications that are uploaded to the Google Play Store are
/// scanned for this version string. We track which applications are using it
/// to measure popularity. You are free to remove it (of course) but we would
/// appreciate if you left it in.
///
static const BreadboardVersion kVersion = {
  BREADBOARD_VERSION_MAJOR,
  BREADBOARD_VERSION_MINOR,
  BREADBOARD_VERSION_REVISION,
  "Breadboard "
  BREADBOARD_STRING(BREADBOARD_VERSION_MAJOR) "."
  BREADBOARD_STRING(BREADBOARD_VERSION_MINOR) "."
  BREADBOARD_STRING(BREADBOARD_VERSION_REVISION)
};

const BreadboardVersion& Version() { return kVersion; }

}  // namespace breadboard
<|endoftext|>


<commit_before>// Copyright (c) 2020 by Robert Bosch GmbH, Apex.AI Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#
#include "iceoryx_posh/runtime/posh_runtime_single_process.hpp"
#include "iceoryx_posh/internal/roudi_environment/roudi_environment.hpp"

#include "test.hpp"

using namespace ::testing;
using namespace iox::runtime;
using namespace iox::roudi;

namespace iox
{
namespace test
{
/// @brief Test goal: This test suit verifies class posh_runtime_single_process

class PoshRuntimeSingleProcess_test : public Test
{
  public:
    PoshRuntimeSingleProcess_test()
    {
    }

    virtual ~PoshRuntimeSingleProcess_test()
    {
    }

    virtual void SetUp()
    {
    };

    virtual void TearDown()
    {
    };
};

TEST_F(PoshRuntimeSingleProcess_test, ConstructorPoshRuntimeSingleProcessIsSuccess)
{
  iox::RouDiConfig_t defaultRouDiConfig = iox::RouDiConfig_t().setDefaults();
  IceOryxRouDiComponents roudiComponents(defaultRouDiConfig);

  RouDi roudi(roudiComponents.m_rouDiMemoryManager,
                            roudiComponents.m_portManager,
                            RouDi::RoudiStartupParameters{iox::roudi::MonitoringMode::OFF, false});

  const ProcessName_t& m_runtimeName{"App"};
  PoshRuntimeSingleProcess m_runtimeSingleProcess(m_runtimeName);
}

TEST_F(PoshRuntimeSingleProcess_test, ConstructorPoshRuntimeSingleProcessMultipleProcessIsFound)
{
  RouDiEnvironment m_roudiEnv{iox::RouDiConfig_t().setDefaults()};

  const ProcessName_t& m_runtimeName{"App"};

  EXPECT_DEATH({PoshRuntimeSingleProcess m_runtimeSingleProcess(m_runtimeName);}, ".*");
}

} // namespace test
} // namespace iox
<commit_msg>iox-#496 change year file<commit_after>// Copyright (c) 2021 by Robert Bosch GmbH, Apex.AI Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#
#include "iceoryx_posh/runtime/posh_runtime_single_process.hpp"
#include "iceoryx_posh/internal/roudi_environment/roudi_environment.hpp"

#include "test.hpp"

using namespace ::testing;
using namespace iox::runtime;
using namespace iox::roudi;

namespace iox
{
namespace test
{
/// @brief Test goal: This test suit verifies class posh_runtime_single_process

class PoshRuntimeSingleProcess_test : public Test
{
  public:
    PoshRuntimeSingleProcess_test()
    {
    }

    virtual ~PoshRuntimeSingleProcess_test()
    {
    }

    virtual void SetUp()
    {
    };

    virtual void TearDown()
    {
    };
};

TEST_F(PoshRuntimeSingleProcess_test, ConstructorPoshRuntimeSingleProcessIsSuccess)
{
  iox::RouDiConfig_t defaultRouDiConfig = iox::RouDiConfig_t().setDefaults();
  IceOryxRouDiComponents roudiComponents(defaultRouDiConfig);

  RouDi roudi(roudiComponents.m_rouDiMemoryManager,
                            roudiComponents.m_portManager,
                            RouDi::RoudiStartupParameters{iox::roudi::MonitoringMode::OFF, false});

  const ProcessName_t& m_runtimeName{"App"};
  PoshRuntimeSingleProcess m_runtimeSingleProcess(m_runtimeName);
}

TEST_F(PoshRuntimeSingleProcess_test, ConstructorPoshRuntimeSingleProcessMultipleProcessIsFound)
{
  RouDiEnvironment m_roudiEnv{iox::RouDiConfig_t().setDefaults()};

  const ProcessName_t& m_runtimeName{"App"};

  EXPECT_DEATH({PoshRuntimeSingleProcess m_runtimeSingleProcess(m_runtimeName);}, ".*");
}

} // namespace test
} // namespace iox
<|endoftext|>


<commit_before>/// @file
/// @version 3.01
///
/// @section LICENSE
///
/// This program is free software; you can redistribute it and/or modify it under
/// the terms of the BSD license: http://opensource.org/licenses/BSD-3-Clause

#include <hltypes/harray.h>
#include <hltypes/hltypesUtil.h>
#include <hltypes/hstring.h>
#include <xal/AudioManager.h>
#include <xal/Player.h>

#include "Playlist.h"

namespace xal
{
	Playlist::Playlist(bool repeatAll) : enabled(true), playing(false), index(-1)
	{
		this->repeatAll = repeatAll;
	}

	Playlist::~Playlist()
	{
		this->clear();
	}

	bool Playlist::isPaused()
	{
		return (is_between_ie(this->index, 0, this->players.size()) && this->players[this->index]->isPaused());
	}

	harray<hstr> Playlist::getSoundNames()
	{
		harray<hstr> result;
		foreach (Player*, it, this->players)
		{
			result += (*it)->getName();
		}
		return result;
	}

	Player* Playlist::getCurrentPlayer()
	{
		return (this->isPlaying() ? this->players[this->index] : NULL);
	}

	void Playlist::update()
	{
		if (this->enabled)
		{
			if (this->players.size() == 0 || !this->playing || this->index < 0)
			{
				return;
			}
			if (this->repeatAll)
			{
				if (!this->players[this->index]->isPlaying())
				{
					this->index = (this->index + 1) % this->players.size();
					this->players[this->index]->play(0.0f, (this->players.size() == 1));
				}
			}
			else if (this->index < this->players.size())
			{
				if (!this->players[this->index]->isPlaying())
				{
					++this->index;
					if (this->index < this->players.size())
					{
						this->players[this->index]->play();
					}
					else
					{
						this->playing = false;
					}
				}
			}
			else
			{
				this->playing = false;
			}
		}
	}

	void Playlist::clear()
	{
		this->stop();
		foreach (Player*, it, this->players)
		{
			xal::mgr->destroyPlayer(*it);
		}
		this->players.clear();
		this->index = -1;
	}

	void Playlist::queueSound(chstr name)
	{
		this->players += xal::mgr->createPlayer(name);
		this->index = hmax(this->index, 0);
	}

	void Playlist::queueSounds(harray<hstr> names)
	{
		foreach (hstr, it, names)
		{
			this->players += xal::mgr->createPlayer(*it);
		}
		this->index = hmax(this->index, 0);
	}

	void Playlist::play(float fadeTime)
	{
		if (this->players.size() == 0 || this->playing)
		{
			return;
		}
		if (this->index >= this->players.size())
		{
			this->index = 0;
		}
		bool looping = (this->players.size() == 1 && this->repeatAll);
		this->players[this->index]->play(fadeTime, looping);
		if (this->enabled)
		{
			this->playing = true;
		}
	}

	void Playlist::stop(float fadeTime)
	{
		if (this->playing)
		{
			this->players[this->index]->stop(fadeTime);
		}
		this->playing = false;
	}

	void Playlist::pause(float fadeTime)
	{
		if (this->playing)
		{
			this->players[this->index]->pause(fadeTime);
		}
		this->playing = false;
	}

	void Playlist::shuffle()
	{
		if (!this->playing && this->players.size() > 1)
		{
			xal::Player* player = (this->index >= 0 && this->index < this->players.size() ? this->players[index] : NULL);
			this->players.randomize();
			if (player != NULL)
			{
				this->index = this->players.index_of(player);
			}
		}
	}

	void Playlist::reset()
	{
		this->stop();
		this->index = (this->enabled ? 0 : -1);
	}

}
<commit_msg>- hltypes update<commit_after>/// @file
/// @version 3.01
///
/// @section LICENSE
///
/// This program is free software; you can redistribute it and/or modify it under
/// the terms of the BSD license: http://opensource.org/licenses/BSD-3-Clause

#include <hltypes/harray.h>
#include <hltypes/hltypesUtil.h>
#include <hltypes/hstring.h>
#include <xal/AudioManager.h>
#include <xal/Player.h>

#include "Playlist.h"

namespace xal
{
	Playlist::Playlist(bool repeatAll) : enabled(true), playing(false), index(-1)
	{
		this->repeatAll = repeatAll;
	}

	Playlist::~Playlist()
	{
		this->clear();
	}

	bool Playlist::isPaused()
	{
		return (hbetweenIE(this->index, 0, this->players.size()) && this->players[this->index]->isPaused());
	}

	harray<hstr> Playlist::getSoundNames()
	{
		harray<hstr> result;
		foreach (Player*, it, this->players)
		{
			result += (*it)->getName();
		}
		return result;
	}

	Player* Playlist::getCurrentPlayer()
	{
		return (this->isPlaying() ? this->players[this->index] : NULL);
	}

	void Playlist::update()
	{
		if (this->enabled)
		{
			if (this->players.size() == 0 || !this->playing || this->index < 0)
			{
				return;
			}
			if (this->repeatAll)
			{
				if (!this->players[this->index]->isPlaying())
				{
					this->index = (this->index + 1) % this->players.size();
					this->players[this->index]->play(0.0f, (this->players.size() == 1));
				}
			}
			else if (this->index < this->players.size())
			{
				if (!this->players[this->index]->isPlaying())
				{
					++this->index;
					if (this->index < this->players.size())
					{
						this->players[this->index]->play();
					}
					else
					{
						this->playing = false;
					}
				}
			}
			else
			{
				this->playing = false;
			}
		}
	}

	void Playlist::clear()
	{
		this->stop();
		foreach (Player*, it, this->players)
		{
			xal::mgr->destroyPlayer(*it);
		}
		this->players.clear();
		this->index = -1;
	}

	void Playlist::queueSound(chstr name)
	{
		this->players += xal::mgr->createPlayer(name);
		this->index = hmax(this->index, 0);
	}

	void Playlist::queueSounds(harray<hstr> names)
	{
		foreach (hstr, it, names)
		{
			this->players += xal::mgr->createPlayer(*it);
		}
		this->index = hmax(this->index, 0);
	}

	void Playlist::play(float fadeTime)
	{
		if (this->players.size() == 0 || this->playing)
		{
			return;
		}
		if (this->index >= this->players.size())
		{
			this->index = 0;
		}
		bool looping = (this->players.size() == 1 && this->repeatAll);
		this->players[this->index]->play(fadeTime, looping);
		if (this->enabled)
		{
			this->playing = true;
		}
	}

	void Playlist::stop(float fadeTime)
	{
		if (this->playing)
		{
			this->players[this->index]->stop(fadeTime);
		}
		this->playing = false;
	}

	void Playlist::pause(float fadeTime)
	{
		if (this->playing)
		{
			this->players[this->index]->pause(fadeTime);
		}
		this->playing = false;
	}

	void Playlist::shuffle()
	{
		if (!this->playing && this->players.size() > 1)
		{
			xal::Player* player = (this->index >= 0 && this->index < this->players.size() ? this->players[index] : NULL);
			this->players.randomize();
			if (player != NULL)
			{
				this->index = this->players.index_of(player);
			}
		}
	}

	void Playlist::reset()
	{
		this->stop();
		this->index = (this->enabled ? 0 : -1);
	}

}
<|endoftext|>


<commit_before>/*
 * Copyright 2006-2008 The FLWOR Foundation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "api/fileimpl.h"
#include "api/zorbaimpl.h"
#include "zorba/default_error_handler.h"
#include "runtime/util/flowctl_exception.h"

#include "zorbaerrors/errors.h"
#include "zorbaerrors/error_manager.h"

#include <zorba/util/file.h>
#include "util/dir.h"

#include <fstream>

namespace zorba {

DirectoryIteratorImpl::DirectoryIteratorImpl(std::string const& aPath)
{
  theInternalDirIter = new dir_iterator(aPath);
}

DirectoryIteratorImpl::~DirectoryIteratorImpl()
{
  delete theInternalDirIter;
}

bool
DirectoryIteratorImpl::next(std::string& aPathStr) const
{
  if (theInternalDirIter->end()) {
    return false;
  }

  // get the current pointed entry
  aPathStr = *(*theInternalDirIter);

  // advance to the next entry
  ++(*theInternalDirIter);

  return true;
}

FileImpl::FileImpl(std::string const& path)
  : theErrorHandler(new DefaultErrorHandler())
{
  theInternalFile = new file(path
#ifdef WIN32
      , filesystem_path::CONVERT_SLASHES
#endif
    );
}

FileImpl::~FileImpl()
{
  delete theInternalFile;
  delete theErrorHandler;
}

File_t
File::createFile(const std::string& path) {
  return new FileImpl(path);
}

bool
FileImpl::isDirectory() const {
  bool lResult = false;

  ZORBA_TRY
    lResult = theInternalFile->is_directory() || theInternalFile->is_volume() || theInternalFile->is_root() ;
  ZORBA_CATCH

  return lResult;
};

bool
FileImpl::isFile() const
{
  bool lResult = false;

  ZORBA_TRY
    lResult = theInternalFile->is_file() || theInternalFile->is_link();
  ZORBA_CATCH

  return lResult;
}

bool
FileImpl::isLink() const
{
  bool lResult = false;

  ZORBA_TRY
    lResult = theInternalFile->is_link();
  ZORBA_CATCH

  return lResult;
}

bool
FileImpl::isVolume() const
{
  bool lResult = false;

  ZORBA_TRY
    lResult = theInternalFile->is_volume();
  ZORBA_CATCH

  return lResult;
}

bool
FileImpl::isInvalid() const
{
  bool lResult = false;

  ZORBA_TRY
    lResult = theInternalFile->is_invalid();
  ZORBA_CATCH

  return lResult;
}

bool
FileImpl::exists() const
{
  bool lResult = false;

  ZORBA_TRY
    lResult = theInternalFile->exists();
  ZORBA_CATCH

  return lResult;
}

bool
FileImpl::remove()
{
  bool lResult = false;

  ZORBA_TRY
    // if the file/dir does not exist, return false
    if (!theInternalFile->exists()) {
      return false;
    }

    if (theInternalFile->is_directory()) {
      theInternalFile->rmdir();
    } else {
      theInternalFile->remove();
    }

    // if the file/dir still exist, return false
    if (theInternalFile->exists()) {
      return false;
    }

    lResult = true;
  ZORBA_CATCH

  return lResult;
}

bool
FileImpl::create()
{
  bool lResult = false;

  ZORBA_TRY
    // if the file/dir exist, return false
    if (theInternalFile->exists()) {
      return false;
    }

    theInternalFile->create();

    // if the file does not exist, return false
    if (!theInternalFile->exists() || !theInternalFile->is_file()) {
      return false;
    }

    lResult = true;
  ZORBA_CATCH

  return lResult;
}

bool
FileImpl::rename(std::string const& newpath)
{
  bool lResult = false;

  ZORBA_TRY
    // if the file/dir does not exist, return false
    if (!theInternalFile->exists()) {
      return false;
    }
    // if the new path is already used, return false
    file lNewFile(newpath);
    if (lNewFile.exists()) {
      return false;
    }

    theInternalFile->rename(newpath);

    // if the file does not exist, return false
    if (!lNewFile.exists()) {
      return false;
    }

    lResult = true;
  ZORBA_CATCH

  return lResult;
}

File::FileSize_t
FileImpl::getSize() const
{
  ZORBA_TRY
    return theInternalFile->get_size();
  ZORBA_CATCH
  assert(false);
  return -1;
}

bool
FileImpl::mkdir()
{
  bool lResult = false;

  ZORBA_TRY
    // if the dir/file already exists, return false
    if (theInternalFile->exists()) {
      return false;
    }

    theInternalFile->mkdir();

    lResult = true;
  ZORBA_CATCH

  return lResult;
}

bool
FileImpl::mkdirs()
{
  bool lResult = false;

  ZORBA_TRY
    // if the dir/file already exists, return false
    if (theInternalFile->exists()) {
      return false;
    }

    theInternalFile->deep_mkdir();
    lResult = true;
  ZORBA_CATCH

  return lResult;
}

DirectoryIterator_t
FileImpl::files() const
{
  return new DirectoryIteratorImpl(theInternalFile->get_path());
}

void
FileImpl::openInputStream(std::ifstream& aInStream) const
{
  ZORBA_TRY
    std::string lPath(theInternalFile->get_path());

    if (!theInternalFile->exists()) {
      ZORBA_ERROR_DESC_OSS(FODC0002, "File not found: " << lPath);
    }
    if (!theInternalFile->is_file()) {
      ZORBA_ERROR_DESC_OSS(FODC0002, "\"" << lPath << "\" is not a file");
    }
    aInStream.open(lPath.c_str(), std::ifstream::in);
    if (aInStream.is_open() == false) {
      ZORBA_ERROR_DESC_OSS(FODC0002, "File not accessible: " << lPath);
    }
  ZORBA_CATCH
}

void
FileImpl::openOutputStream(std::ofstream& aOutStream, bool append) const
{
  ZORBA_TRY
    std::string lPath(theInternalFile->get_path());

    if (theInternalFile->exists() && !theInternalFile->is_file()) {
      ZORBA_ERROR_DESC_OSS(FODC0002, "\"" << lPath << "\" is not a file");
    }

    std::ofstream::open_mode lMode = append ? std::ofstream::app :
        (std::ofstream::out | std::ofstream::trunc);

    aOutStream.open(lPath.c_str(), lMode);
    if (aOutStream.is_open() == false) {
      ZORBA_ERROR_DESC_OSS(FODC0002, "File not accessible: " << lPath);
    }
  ZORBA_CATCH
}

time_t
FileImpl::lastModified() const
{
  return theInternalFile->lastModified();
}

} /* namespace zorba */
<commit_msg>Fixed build on linux.<commit_after>/*
 * Copyright 2006-2008 The FLWOR Foundation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "api/fileimpl.h"
#include "api/zorbaimpl.h"
#include "zorba/default_error_handler.h"
#include "runtime/util/flowctl_exception.h"

#include "zorbaerrors/errors.h"
#include "zorbaerrors/error_manager.h"

#include <zorba/util/file.h>
#include "util/dir.h"

#include <fstream>

namespace zorba {

DirectoryIteratorImpl::DirectoryIteratorImpl(std::string const& aPath)
{
  theInternalDirIter = new dir_iterator(aPath);
}

DirectoryIteratorImpl::~DirectoryIteratorImpl()
{
  delete theInternalDirIter;
}

bool
DirectoryIteratorImpl::next(std::string& aPathStr) const
{
  if (theInternalDirIter->end()) {
    return false;
  }

  // get the current pointed entry
  aPathStr = *(*theInternalDirIter);

  // advance to the next entry
  ++(*theInternalDirIter);

  return true;
}

FileImpl::FileImpl(std::string const& path)
  : theErrorHandler(new DefaultErrorHandler())
{
  theInternalFile = new file(path
#ifdef WIN32
      , filesystem_path::CONVERT_SLASHES
#endif
    );
}

FileImpl::~FileImpl()
{
  delete theInternalFile;
  delete theErrorHandler;
}

File_t
File::createFile(const std::string& path) {
  return new FileImpl(path);
}

bool
FileImpl::isDirectory() const {
  bool lResult = false;

  ZORBA_TRY
    lResult = theInternalFile->is_directory() || theInternalFile->is_volume() || theInternalFile->is_root() ;
  ZORBA_CATCH

  return lResult;
};

bool
FileImpl::isFile() const
{
  bool lResult = false;

  ZORBA_TRY
    lResult = theInternalFile->is_file() || theInternalFile->is_link();
  ZORBA_CATCH

  return lResult;
}

bool
FileImpl::isLink() const
{
  bool lResult = false;

  ZORBA_TRY
    lResult = theInternalFile->is_link();
  ZORBA_CATCH

  return lResult;
}

bool
FileImpl::isVolume() const
{
  bool lResult = false;

  ZORBA_TRY
    lResult = theInternalFile->is_volume();
  ZORBA_CATCH

  return lResult;
}

bool
FileImpl::isInvalid() const
{
  bool lResult = false;

  ZORBA_TRY
    lResult = theInternalFile->is_invalid();
  ZORBA_CATCH

  return lResult;
}

bool
FileImpl::exists() const
{
  bool lResult = false;

  ZORBA_TRY
    lResult = theInternalFile->exists();
  ZORBA_CATCH

  return lResult;
}

bool
FileImpl::remove()
{
  bool lResult = false;

  ZORBA_TRY
    // if the file/dir does not exist, return false
    if (!theInternalFile->exists()) {
      return false;
    }

    if (theInternalFile->is_directory()) {
      theInternalFile->rmdir();
    } else {
      theInternalFile->remove();
    }

    // if the file/dir still exist, return false
    if (theInternalFile->exists()) {
      return false;
    }

    lResult = true;
  ZORBA_CATCH

  return lResult;
}

bool
FileImpl::create()
{
  bool lResult = false;

  ZORBA_TRY
    // if the file/dir exist, return false
    if (theInternalFile->exists()) {
      return false;
    }

    theInternalFile->create();

    // if the file does not exist, return false
    if (!theInternalFile->exists() || !theInternalFile->is_file()) {
      return false;
    }

    lResult = true;
  ZORBA_CATCH

  return lResult;
}

bool
FileImpl::rename(std::string const& newpath)
{
  bool lResult = false;

  ZORBA_TRY
    // if the file/dir does not exist, return false
    if (!theInternalFile->exists()) {
      return false;
    }
    // if the new path is already used, return false
    file lNewFile(newpath);
    if (lNewFile.exists()) {
      return false;
    }

    theInternalFile->rename(newpath);

    // if the file does not exist, return false
    if (!lNewFile.exists()) {
      return false;
    }

    lResult = true;
  ZORBA_CATCH

  return lResult;
}

File::FileSize_t
FileImpl::getSize() const
{
  ZORBA_TRY
    return theInternalFile->get_size();
  ZORBA_CATCH
  assert(false);
  return -1;
}

bool
FileImpl::mkdir()
{
  bool lResult = false;

  ZORBA_TRY
    // if the dir/file already exists, return false
    if (theInternalFile->exists()) {
      return false;
    }

    theInternalFile->mkdir();

    lResult = true;
  ZORBA_CATCH

  return lResult;
}

bool
FileImpl::mkdirs()
{
  bool lResult = false;

  ZORBA_TRY
    // if the dir/file already exists, return false
    if (theInternalFile->exists()) {
      return false;
    }

    theInternalFile->deep_mkdir();
    lResult = true;
  ZORBA_CATCH

  return lResult;
}

DirectoryIterator_t
FileImpl::files() const
{
  return new DirectoryIteratorImpl(theInternalFile->get_path());
}

void
FileImpl::openInputStream(std::ifstream& aInStream) const
{
  ZORBA_TRY
    std::string lPath(theInternalFile->get_path());

    if (!theInternalFile->exists()) {
      ZORBA_ERROR_DESC_OSS(FODC0002, "File not found: " << lPath);
    }
    if (!theInternalFile->is_file()) {
      ZORBA_ERROR_DESC_OSS(FODC0002, "\"" << lPath << "\" is not a file");
    }
    aInStream.open(lPath.c_str(), std::ifstream::in);
    if (aInStream.is_open() == false) {
      ZORBA_ERROR_DESC_OSS(FODC0002, "File not accessible: " << lPath);
    }
  ZORBA_CATCH
}

void
FileImpl::openOutputStream(std::ofstream& aOutStream, bool append) const
{
  ZORBA_TRY
    std::string lPath(theInternalFile->get_path());

    if (theInternalFile->exists() && !theInternalFile->is_file()) {
      ZORBA_ERROR_DESC_OSS(FODC0002, "\"" << lPath << "\" is not a file");
    }

    std::ios_base::openmode lMode = append ? std::ios_base::app :
        (std::ios_base::out | std::ios_base::trunc);

    aOutStream.open(lPath.c_str(), lMode);
    if (aOutStream.is_open() == false) {
      ZORBA_ERROR_DESC_OSS(FODC0002, "File not accessible: " << lPath);
    }
  ZORBA_CATCH
}

time_t
FileImpl::lastModified() const
{
  return theInternalFile->lastModified();
}

} /* namespace zorba */
<|endoftext|>


<commit_before>#include "xchainer/python/error.h"

#include "xchainer/error.h"

#include "xchainer/python/common.h"

namespace xchainer {
namespace python {
namespace internal {

namespace py = pybind11;  // standard convention

void InitXchainerError(pybind11::module& m) {
    py::register_exception<XchainerError>(m, "XchainerError");
    py::register_exception<ContextError>(m, "ContextError");
    py::register_exception<BackendError>(m, "BackendError");
    py::register_exception<DeviceError>(m, "DeviceError");
    py::register_exception<DtypeError>(m, "DtypeError");
    py::register_exception<DimensionError>(m, "DimensionError");
    py::register_exception<GradientCheckError>(m, "GradientCheckError");
}

}  // namespace internal
}  // namespace python
}  // namespace xchainer
<commit_msg>Add error and reorder according to definitions<commit_after>#include "xchainer/python/error.h"

#include "xchainer/error.h"

#include "xchainer/python/common.h"

namespace xchainer {
namespace python {
namespace internal {

namespace py = pybind11;  // standard convention

void InitXchainerError(pybind11::module& m) {
    py::register_exception<XchainerError>(m, "XchainerError");
    py::register_exception<ContextError>(m, "ContextError");
    py::register_exception<BackendError>(m, "BackendError");
    py::register_exception<DeviceError>(m, "DeviceError");
    py::register_exception<DimensionError>(m, "DimensionError");
    py::register_exception<DtypeError>(m, "DtypeError");
    py::register_exception<NotImplementedError>(m, "NotImplementedError");
    py::register_exception<GradientCheckError>(m, "GradientCheckError");
}

}  // namespace internal
}  // namespace python
}  // namespace xchainer
<|endoftext|>


<commit_before>#ifndef ARCH_IO_DISK_POOL_HPP_
#define ARCH_IO_DISK_POOL_HPP_

#include "arch/runtime/event_queue.hpp"
#include "arch/io/blocker_pool.hpp"
#include "concurrency/queue/passive_producer.hpp"

#include "errors.hpp"
#include <boost/function.hpp>

/* The pool disk manager uses a thread pool in conjunction with synchronous
(blocking) IO calls to asynchronously run IO requests. */

class pool_diskmgr_t : private availability_callback_t, public home_thread_mixin_t {
public:
    struct action_t : private blocker_pool_t::job_t, public home_thread_mixin_t {

        void make_write(fd_t f, const void *b, size_t c, off_t o) {
            is_read = false;
            fd = f;
            buf = const_cast<void*>(b);
            count = c;
            offset = o;
        }
        void make_read(fd_t f, void *b, size_t c, off_t o) {
            is_read = true;
            fd = f;
            buf = b;
            count = c;
            offset = o;
        }

        bool get_is_write() const { return !is_read; }
        bool get_is_read() const { return is_read; }
        fd_t get_fd() const { return fd; }
        void *get_buf() const { return buf; }
        size_t get_count() const { return count; }
        off_t get_offset() const { return offset; }

    private:
        friend class pool_diskmgr_t;
        pool_diskmgr_t *parent;

        bool is_read;
        fd_t fd;
        void *buf;
        size_t count;
        off_t offset;

        void run();
        void done();
    };

    /* The `pool_diskmgr_t` will draw actions to run from `source`. It will call `done_fun`
    on each one when it's done. */
    pool_diskmgr_t(linux_event_queue_t *queue, passive_producer_t<action_t *> *source);
    boost::function<void(action_t *)> done_fun;
    ~pool_diskmgr_t();

private:
    passive_producer_t<action_t *> *source;
    blocker_pool_t blocker_pool;

    void on_source_availability_changed();
    int n_pending;
    void pump();

    DISABLE_COPYING(pool_diskmgr_t);
};

#endif /* ARCH_IO_DISK_POOL_HPP_ */
<commit_msg>Changed pool.hpp ordering.<commit_after>#ifndef ARCH_IO_DISK_POOL_HPP_
#define ARCH_IO_DISK_POOL_HPP_

#include "errors.hpp"
#include <boost/function.hpp>

#include "arch/runtime/event_queue.hpp"
#include "arch/io/blocker_pool.hpp"
#include "concurrency/queue/passive_producer.hpp"

/* The pool disk manager uses a thread pool in conjunction with synchronous
(blocking) IO calls to asynchronously run IO requests. */

class pool_diskmgr_t : private availability_callback_t, public home_thread_mixin_t {
public:
    struct action_t : private blocker_pool_t::job_t, public home_thread_mixin_t {

        void make_write(fd_t f, const void *b, size_t c, off_t o) {
            is_read = false;
            fd = f;
            buf = const_cast<void*>(b);
            count = c;
            offset = o;
        }
        void make_read(fd_t f, void *b, size_t c, off_t o) {
            is_read = true;
            fd = f;
            buf = b;
            count = c;
            offset = o;
        }

        bool get_is_write() const { return !is_read; }
        bool get_is_read() const { return is_read; }
        fd_t get_fd() const { return fd; }
        void *get_buf() const { return buf; }
        size_t get_count() const { return count; }
        off_t get_offset() const { return offset; }

    private:
        friend class pool_diskmgr_t;
        pool_diskmgr_t *parent;

        bool is_read;
        fd_t fd;
        void *buf;
        size_t count;
        off_t offset;

        void run();
        void done();
    };

    /* The `pool_diskmgr_t` will draw actions to run from `source`. It will call `done_fun`
    on each one when it's done. */
    pool_diskmgr_t(linux_event_queue_t *queue, passive_producer_t<action_t *> *source);
    boost::function<void(action_t *)> done_fun;
    ~pool_diskmgr_t();

private:
    passive_producer_t<action_t *> *source;
    blocker_pool_t blocker_pool;

    void on_source_availability_changed();
    int n_pending;
    void pump();

    DISABLE_COPYING(pool_diskmgr_t);
};

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


<commit_before>#include <sys/stat.h>
#include <sys/types.h>

#include <boost/bind.hpp>
#include <boost/function.hpp>

#include <libport/cstdio>
#include <libport/fd-stream.hh>
#include <libport/thread.hh>
#include <libport/unit-test.hh>
#include <libport/windows.hh>

using boost::bind;
using libport::FdStream;
using libport::test_suite;

static void
ctor(int write, int read)
{
  BOOST_CHECK_NO_THROW(FdStream(write, read));
}

static void
own(bool own)
{
  int fd[2];
  struct stat stat;

  BOOST_CHECK(!pipe(fd));
  BOOST_CHECK(!fstat(fd[0], &stat));
  BOOST_CHECK(!fstat(fd[1], &stat));

  {
    FdStream s(fd[1], fd[0]);
    s.own_fd(own);
  }
  if (own)
  {
#ifndef WIN32
    // Fstat on a closed fd implodes under WIN32
    BOOST_CHECK(fstat(fd[0], &stat));
    BOOST_CHECK(fstat(fd[1], &stat));
#endif
  }
  else
  {
    BOOST_CHECK(!fstat(fd[0], &stat));
    BOOST_CHECK(!fstat(fd[1], &stat));
    BOOST_CHECK(!close(fd[0]));
    BOOST_CHECK(!close(fd[1]));
  }
}

static void
fd_get()
{
  FdStream s(42, 51);
  BOOST_CHECK_EQUAL(s.fd_write(), 42);
  BOOST_CHECK_EQUAL(s.fd_read(), 51);
}

static void
put(const std::string& str, int fd)
{
  BOOST_CHECK_EQUAL(write(fd, str.c_str(), str.length()), str.length());
}

static void
put(char c, int fd)
{
  std::string s;
  s += c;
  put(s, fd);
}

static std::string
get(int fd)
{
  char buf[BUFSIZ + 1];
  int c;

  c = read(fd, buf, sizeof (buf) - 1);
  buf[c] = 0;
  return buf;
}

static void
fd_read_string(FdStream*& stream, int fd)
{
  put("test", fd);
  BOOST_CHECK(!close(fd));

  std::string test;
  *stream >> test;
  BOOST_CHECK_EQUAL(test, "test");
}

static void
fd_write_string(FdStream*& stream, int fd)
{
  static const std::string test = "test";

  *stream << test;
  stream->sync();
  BOOST_CHECK_EQUAL(get(fd), test);
}

static void
fd_read_ints(FdStream*& stream, int fd)
{
  // Write
  put("42 ", fd);
  int test;
  *stream >> test;
  BOOST_CHECK_EQUAL(test, 42);
  put("51 69", fd);
  BOOST_CHECK(!close(fd));
  *stream >> test;
  BOOST_CHECK_EQUAL(test, 51);
  *stream >> test;
  BOOST_CHECK_EQUAL(test, 69);
}

static void
fd_write_ints(FdStream*& stream, int fd)
{
  static const std::string test = "test";

  *stream << std::hex << 42 << ' ';
  *stream << std::oct << 42;
  delete stream;
  stream = 0;
  BOOST_CHECK_EQUAL(get(fd), "2a 52");
}

static void thread_write(int fd, int size)
{
  for (int i = 0; i < size; ++i)
    // This might fail if the pipe isn't large enough ...
    put(i % 256, fd);
  BOOST_CHECK(!close(fd));
}

static void
fd_read_jumbo(FdStream*& stream, int fd)
{
  static const int size = BUFSIZ * 3 / 2;

  void* thread = libport::startThread(boost::bind(thread_write, fd, size));

  char c;
  int count = 0;
  for (count = 0; stream->get(c); ++count)
    BOOST_CHECK_EQUAL(c, (char)(count % 256));
  BOOST_CHECK_EQUAL(count, size);
  libport::joinThread(thread);
}

static void
thread_write_stream(FdStream* stream, int size)
{
  for (int i = 0; i < size; ++i)
    *stream << (char) (i % 256);
  delete stream;
}

static void
fd_write_jumbo(FdStream*& stream, int fd)
{
  static const int size = BUFSIZ * 3 / 2;

  stream->own_fd(true);
  void* thread = libport::startThread
    (boost::bind(thread_write_stream, stream, size));
  stream = 0;
  char c;
  for (int i = 0; i < size; ++i)
  {
    BOOST_CHECK_EQUAL(read(fd, &c, 1), 1);
    BOOST_CHECK_EQUAL(c, (char)i % 256);
  }
  BOOST_CHECK_EQUAL(read(fd, &c, 1), 0);
}

typedef boost::function2<void, FdStream*&, int> f_type;

static void
fd_read(f_type action)
{
  int fd[2];
  BOOST_CHECK(!pipe(fd));

  FdStream* stream = new FdStream(STDOUT_FILENO, fd[0]);
  action(stream, fd[1]);

  BOOST_CHECK(!close(fd[0]));
  delete stream;
}

static void
fd_write(f_type action, bool close_p)
{
  int fd[2];
  BOOST_CHECK(!pipe(fd));

  FdStream* stream = new FdStream(fd[1], STDIN_FILENO);
  action(stream, fd[0]);

  // Don't close twice the fd, it throws on Windows.  In the
  // fd_write_jumbo case, the stream closes this fd.  The others
  // don't.  There is no simple means to guarantee a single close for
  // each case, so just don't close at all.
  if (close_p)
    BOOST_CHECK(!close(fd[1]));
  delete stream;
}

test_suite*
init_test_suite()
{
  test_suite* suite = BOOST_TEST_SUITE("libport::FdStream test suite");
  test_suite* current;

#define SUITE(Desc)                             \
  current = BOOST_TEST_SUITE(Desc);             \
  suite->add(current);

#define TEST(Args)                                      \
  current->add(BOOST_TEST_CASE(boost::bind Args));

  SUITE("Construction test suite");
  TEST((ctor, 0, 0));

  SUITE("fd_own test suite");
  TEST((own, true));
  TEST((own, false));

  SUITE("fd_write and fd_read test suite");
  TEST((fd_get));

  SUITE("read test suite");
  TEST((fd_read, fd_read_string));
  TEST((fd_read, fd_read_ints));
  TEST((fd_read, fd_read_jumbo));

  SUITE("write test suite");
  TEST((fd_write, fd_write_string, true));
  TEST((fd_write, fd_write_ints, true));
  TEST((fd_write, fd_write_jumbo, false));

  return suite;
}
<commit_msg>More BOOST_CHECK.<commit_after>#include <sys/stat.h>
#include <sys/types.h>

#include <boost/bind.hpp>
#include <boost/function.hpp>

#include <libport/cstdio>
#include <libport/fd-stream.hh>
#include <libport/thread.hh>
#include <libport/unit-test.hh>
#include <libport/windows.hh>

using boost::bind;
using libport::FdStream;
using libport::test_suite;

static void
ctor(int write, int read)
{
  BOOST_CHECK_NO_THROW(FdStream(write, read));
}

static void
own(bool own)
{
  int fd[2];
  struct stat stat;

  BOOST_CHECK(!pipe(fd));
  BOOST_CHECK(!fstat(fd[0], &stat));
  BOOST_CHECK(!fstat(fd[1], &stat));

  {
    FdStream s(fd[1], fd[0]);
    s.own_fd(own);
  }
  if (own)
  {
#ifndef WIN32
    // Fstat on a closed fd implodes under WIN32
    BOOST_CHECK(fstat(fd[0], &stat));
    BOOST_CHECK(fstat(fd[1], &stat));
#endif
  }
  else
  {
    BOOST_CHECK(!fstat(fd[0], &stat));
    BOOST_CHECK(!fstat(fd[1], &stat));
    BOOST_CHECK(!close(fd[0]));
    BOOST_CHECK(!close(fd[1]));
  }
}

static void
fd_get()
{
  FdStream s(42, 51);
  BOOST_CHECK_EQUAL(s.fd_write(), 42);
  BOOST_CHECK_EQUAL(s.fd_read(), 51);
}

static void
put(const std::string& str, int fd)
{
  BOOST_CHECK_EQUAL(write(fd, str.c_str(), str.length()), str.length());
}

static void
put(char c, int fd)
{
  std::string s;
  s += c;
  put(s, fd);
}

static std::string
get(int fd)
{
  char buf[BUFSIZ];
  return std::string(buf, read(fd, buf, sizeof buf));
}

static void
fd_read_string(FdStream*& stream, int fd)
{
  put("test", fd);
  BOOST_CHECK(!close(fd));

  std::string test;
  *stream >> test;
  BOOST_CHECK_EQUAL(test, "test");
}

static void
fd_write_string(FdStream*& stream, int fd)
{
  const std::string test = "test";

  *stream << test;
  stream->sync();
  BOOST_CHECK_EQUAL(get(fd), test);
}

static void
fd_read_ints(FdStream*& stream, int fd)
{
  // Write
  put("42 ", fd);
  int test;
  *stream >> test;
  BOOST_CHECK_EQUAL(test, 42);
  put("51 69", fd);
  BOOST_CHECK(!close(fd));
  *stream >> test;
  BOOST_CHECK_EQUAL(test, 51);
  *stream >> test;
  BOOST_CHECK_EQUAL(test, 69);
}

static void
fd_write_ints(FdStream*& stream, int fd)
{
  const std::string test = "test";

  *stream << std::hex << 42 << ' ';
  *stream << std::oct << 42;
  delete stream;
  stream = 0;
  BOOST_CHECK_EQUAL(get(fd), "2a 52");
}

static void thread_write(int fd, int size)
{
  for (int i = 0; i < size; ++i)
    // This might fail if the pipe isn't large enough ...
    put(i % 256, fd);
  BOOST_CHECK(!close(fd));
}

static void
fd_read_jumbo(FdStream*& stream, int fd)
{
  static const int size = BUFSIZ * 3 / 2;

  void* thread = libport::startThread(boost::bind(thread_write, fd, size));

  char c;
  int count = 0;
  for (count = 0; stream->get(c); ++count)
    BOOST_CHECK_EQUAL(c, (char)(count % 256));
  BOOST_CHECK(stream->eof());
  BOOST_CHECK_EQUAL(count, size);
  libport::joinThread(thread);
}

static void
thread_write_stream(FdStream* stream, int size)
{
  for (int i = 0; i < size; ++i)
    *stream << (char) (i % 256);
  delete stream;
}

static void
fd_write_jumbo(FdStream*& stream, int fd)
{
  static const int size = BUFSIZ * 3 / 2;

  stream->own_fd(true);
  void* thread = libport::startThread
    (boost::bind(thread_write_stream, stream, size));
  stream = 0;
  char c;
  for (int i = 0; i < size; ++i)
  {
    BOOST_CHECK_EQUAL(read(fd, &c, 1), 1);
    BOOST_CHECK_EQUAL(c, (char)i % 256);
  }
  BOOST_CHECK_EQUAL(read(fd, &c, 1), 0);
}

typedef boost::function2<void, FdStream*&, int> f_type;

static void
fd_read(f_type action)
{
  int fd[2];
  BOOST_CHECK(!pipe(fd));

  FdStream* stream = new FdStream(STDOUT_FILENO, fd[0]);
  action(stream, fd[1]);

  BOOST_CHECK(!close(fd[0]));
  delete stream;
}

static void
fd_write(f_type action, bool close_p)
{
  int fd[2];
  BOOST_CHECK(!pipe(fd));

  FdStream* stream = new FdStream(fd[1], STDIN_FILENO);
  action(stream, fd[0]);

  // Don't close twice the fd, it throws on Windows.  In the
  // fd_write_jumbo case, the stream closes this fd.  The others
  // don't.  There is no simple means to guarantee a single close for
  // each case, so just don't close at all.
  if (close_p)
    BOOST_CHECK(!close(fd[1]));
  delete stream;
}

test_suite*
init_test_suite()
{
  test_suite* suite = BOOST_TEST_SUITE("libport::FdStream test suite");
  test_suite* current;

#define SUITE(Desc)                             \
  current = BOOST_TEST_SUITE(Desc);             \
  suite->add(current);

#define TEST(Args)                                      \
  current->add(BOOST_TEST_CASE(boost::bind Args));

  SUITE("Construction test suite");
  TEST((ctor, 0, 0));

  SUITE("fd_own test suite");
  TEST((own, true));
  TEST((own, false));

  SUITE("fd_write and fd_read test suite");
  TEST((fd_get));

  SUITE("read test suite");
  TEST((fd_read, fd_read_string));
  TEST((fd_read, fd_read_ints));
  TEST((fd_read, fd_read_jumbo));

  SUITE("write test suite");
  TEST((fd_write, fd_write_string, true));
  TEST((fd_write, fd_write_ints, true));
  TEST((fd_write, fd_write_jumbo, false));

  return suite;
}
<|endoftext|>


<commit_before>/* bzflag
 * Copyright (c) 1993-2011 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named COPYING that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

// object that creates and contains a spawn position

/* interface header */
#include "SpawnPosition.h"

/* implementation headers */
// uncomment to test - #include "RandomSpawnPolicy.h"

/* no policy by default? */
SpawnPolicy *SpawnPosition::policy = (SpawnPolicy*)0;

SpawnPosition::SpawnPosition(int playerId, bool onGroundOnly, bool notNearEdges)
{
  /* if a spawn policy hasn't been set yet, just go with the default */
  if (!SpawnPosition::policy) {
    // uncomment to test - SpawnPosition::policy = new RandomSpawnPolicy();
    SpawnPosition::policy = new SpawnPolicy();
  }

  SpawnPosition::policy->getPosition(pos, playerId, onGroundOnly, notNearEdges);
  SpawnPosition::policy->getAzimuth(azimuth);
}

SpawnPosition::~SpawnPosition()
{
}

void SpawnPosition::setSpawnPolicy(SpawnPolicy *_policy)
{
  if (SpawnPosition::policy) {
    delete SpawnPosition::policy;
  }
  SpawnPosition::policy = _policy;
}

// Local Variables: ***
// mode:C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8
<commit_msg>(warning) Member variables 'SpawnPosition::...' are not initialized in the constructor.<commit_after>/* bzflag
 * Copyright (c) 1993-2011 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named COPYING that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

// object that creates and contains a spawn position

/* interface header */
#include "SpawnPosition.h"

/* implementation headers */
// uncomment to test - #include "RandomSpawnPolicy.h"

/* no policy by default? */
SpawnPolicy *SpawnPosition::policy = (SpawnPolicy*)0;

SpawnPosition::SpawnPosition(int playerId, bool onGroundOnly, bool notNearEdges): azimuth(0.0), pos()
{
  /* if a spawn policy hasn't been set yet, just go with the default */
  if (!SpawnPosition::policy) {
    // uncomment to test - SpawnPosition::policy = new RandomSpawnPolicy();
    SpawnPosition::policy = new SpawnPolicy();
  }

  SpawnPosition::policy->getPosition(pos, playerId, onGroundOnly, notNearEdges);
  SpawnPosition::policy->getAzimuth(azimuth);
}

SpawnPosition::~SpawnPosition()
{
}

void SpawnPosition::setSpawnPolicy(SpawnPolicy *_policy)
{
  if (SpawnPosition::policy) {
    delete SpawnPosition::policy;
  }
  SpawnPosition::policy = _policy;
}

// Local Variables: ***
// mode:C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8
<|endoftext|>


<commit_before>#include "../singleheader/simdjson.h"
#include <iostream>

int main() {
  const char *filename = JSON_TEST_PATH;
  padded_string p = get_corpus(filename);
  ParsedJson pj = build_parsed_json(p); // do the parsing
  if (!pj.isValid()) {
    return EXIT_FAILURE;
  }
  if (!pj.allocateCapacity(p.size())) {
    return EXIT_FAILURE;
  }
  const int res = json_parse(p, pj);
  if (res) {
    std::cerr << simdjson::errorMsg(res) << std::endl;
    return EXIT_FAILURE;
  }
  return EXIT_SUCCESS;
}
<commit_msg>Attemp to solve some singleheader's problems<commit_after>#include "../singleheader/simdjson.h"
#include <iostream>

using namespace simdjson;

int main() {
  const char *filename = JSON_TEST_PATH;
  padded_string p = get_corpus(filename);
  ParsedJson pj = build_parsed_json(p); // do the parsing
  if (!pj.isValid()) {
    return EXIT_FAILURE;
  }
  if (!pj.allocateCapacity(p.size())) {
    return EXIT_FAILURE;
  }
  const int res = json_parse(p, pj);
  if (res) {
    std::cerr << errorMsg(res) << std::endl;
    return EXIT_FAILURE;
  }
  return EXIT_SUCCESS;
}
<|endoftext|>