<commit_before>#include <QFile>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlRecord>
#include <QVariant>
#include "commands/sql-worker.h"
#include "catch.h"
#include "raii-helpers.h"

TEST_CASE("SqlWorkerTest")
{
	FileDeleter removeFile("test_sql_worker.db", true);

	SECTION("Connect works")
	{
		SqlWorker worker("QSQLITE", "", "", "", "test_sql_worker.db", nullptr);

		REQUIRE(worker.connect());
		REQUIRE(worker.connect());
	}

	SECTION("Connect fails")
	{
		SqlWorker worker("NOT_EXISTING_SQL_DRIVER", "1", "2", "3", "4", nullptr);

		REQUIRE(!worker.connect());
		REQUIRE(!worker.connect());
	}

	SECTION("Connect disabled")
	{
		SqlWorker worker("IGNORED_BECAUSE_DISABLED", "", "", "", "", nullptr);

		REQUIRE(worker.connect());
		REQUIRE(worker.connect());
	}

	SECTION("EscapeInteger")
	{
		SqlWorker worker("QSQLITE", "", "", "", "test_sql_worker.db", nullptr);

		REQUIRE(worker.escape(-3) == QString("-3"));
		REQUIRE(worker.escape(0) == QString("0"));
		REQUIRE(worker.escape(21) == QString("21"));
		REQUIRE(worker.escape(12345) == QString("12345"));
	}

	SECTION("Escape string")
	{
		SqlWorker worker("QSQLITE", "", "", "", "test_sql_worker.db", nullptr);

		REQUIRE(worker.escape("test") == QString("'test'"));
		REQUIRE(worker.escape("test'ed") == QString("'test''ed'"));
	}

	SECTION("Exec create and insert")
	{
		SqlWorker worker("QSQLITE", "", "", "", "test_sql_worker.db", nullptr);

		REQUIRE(worker.execute("CREATE TABLE IF NOT EXISTS test_table (some_value INT);"));
		REQUIRE(worker.execute("INSERT INTO test_table (some_value) VALUES (1), (3), (21);"));

		QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", "SQL worker test database");
		db.setDatabaseName("test_sql_worker.db");
		REQUIRE(db.open());

		QSqlQuery query = db.exec("SELECT some_value FROM test_table");
		int idVal = query.record().indexOf("some_value");
		QList<int> values;
		while (query.next()) {
			values.append(query.value(idVal).toInt());
		}

		REQUIRE(values == QList<int>() << 1 << 3 << 21);
	}
}
<commit_msg>Fix tests following dry run change<commit_after>#include <QFile>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlRecord>
#include <QVariant>
#include "commands/sql-worker.h"
#include "catch.h"
#include "raii-helpers.h"

TEST_CASE("SqlWorkerTest")
{
	FileDeleter removeFile("test_sql_worker.db", true);

	SECTION("Connect works")
	{
		SqlWorker worker("QSQLITE", "", "", "", "test_sql_worker.db", false, nullptr);

		REQUIRE(worker.connect());
		REQUIRE(worker.connect());
	}

	SECTION("Connect fails")
	{
		SqlWorker worker("NOT_EXISTING_SQL_DRIVER", "1", "2", "3", "4", false, nullptr);

		REQUIRE(!worker.connect());
		REQUIRE(!worker.connect());
	}

	SECTION("Connect disabled")
	{
		SqlWorker worker("IGNORED_BECAUSE_DISABLED", "", "", "", "", false, nullptr);

		REQUIRE(worker.connect());
		REQUIRE(worker.connect());
	}

	SECTION("EscapeInteger")
	{
		SqlWorker worker("QSQLITE", "", "", "", "test_sql_worker.db", false, nullptr);

		REQUIRE(worker.escape(-3) == QString("-3"));
		REQUIRE(worker.escape(0) == QString("0"));
		REQUIRE(worker.escape(21) == QString("21"));
		REQUIRE(worker.escape(12345) == QString("12345"));
	}

	SECTION("Escape string")
	{
		SqlWorker worker("QSQLITE", "", "", "", "test_sql_worker.db", false, nullptr);

		REQUIRE(worker.escape("test") == QString("'test'"));
		REQUIRE(worker.escape("test'ed") == QString("'test''ed'"));
	}

	SECTION("Exec create and insert")
	{
		SqlWorker worker("QSQLITE", "", "", "", "test_sql_worker.db", false, nullptr);

		REQUIRE(worker.execute("CREATE TABLE IF NOT EXISTS test_table (some_value INT);"));
		REQUIRE(worker.execute("INSERT INTO test_table (some_value) VALUES (1), (3), (21);"));

		QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", "SQL worker test database");
		db.setDatabaseName("test_sql_worker.db");
		REQUIRE(db.open());

		QSqlQuery query = db.exec("SELECT some_value FROM test_table");
		int idVal = query.record().indexOf("some_value");
		QList<int> values;
		while (query.next()) {
			values.append(query.value(idVal).toInt());
		}

		REQUIRE(values == QList<int>() << 1 << 3 << 21);
	}
}
<|endoftext|>


<commit_before>// This file is part of Eigen, a lightweight C++ template library
// for linear algebra. Eigen itself is part of the KDE project.
//
// Copyright (C) 2009 Hauke Heibel <hauke.heibel@gmail.com>
//
// Eigen 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 3 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or1 FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.

#include "main.h"

#include <Eigen/Core>
#include <Eigen/Array>

using namespace Eigen;

template <typename Scalar, int Storage>
void run_matrix_tests()
{
  typedef Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic, Storage> MatrixType;

  MatrixType m, n;

  // boundary cases ...
  m = n = MatrixType::Random(50,50);
  m.conservativeResize(1,50);
  VERIFY_IS_APPROX(m, n.block(0,0,1,50));

  m = n = MatrixType::Random(50,50);
  m.conservativeResize(50,1);
  VERIFY_IS_APPROX(m, n.block(0,0,50,1));

  m = n = MatrixType::Random(50,50);
  m.conservativeResize(50,50);
  VERIFY_IS_APPROX(m, n.block(0,0,50,50));

  // random shrinking ...
  for (int i=0; i<25; ++i)
  {
    const int rows = ei_random<int>(1,50);
    const int cols = ei_random<int>(1,50);
    m = n = MatrixType::Random(50,50);
    m.conservativeResize(rows,cols);
    VERIFY_IS_APPROX(m, n.block(0,0,rows,cols));
  }

  // random growing with zeroing ...
  for (int i=0; i<25; ++i)
  {
    const int rows = ei_random<int>(50,75);
    const int cols = ei_random<int>(50,75);
    m = n = MatrixType::Random(50,50);
    m.conservativeResize(rows,cols,true);
    VERIFY_IS_APPROX(m.block(0,0,n.rows(),n.cols()), n);
    VERIFY( rows<=50 || m.block(50,0,rows-50,cols).sum() == Scalar(0) );
    VERIFY( cols<=50 || m.block(0,50,rows,cols-50).sum() == Scalar(0) );
  }
}

template <typename Scalar>
void run_vector_tests()
{
  typedef Matrix<Scalar, 1, Eigen::Dynamic> MatrixType;

  MatrixType m, n;

  // boundary cases ...
  m = n = MatrixType::Random(50);
  m.conservativeResize(1);
  VERIFY_IS_APPROX(m, n.segment(0,1));

  m = n = MatrixType::Random(50);
  m.conservativeResize(50);
  VERIFY_IS_APPROX(m, n.segment(0,50));

  // random shrinking ...
  for (int i=0; i<50; ++i)
  {
    const int size = ei_random<int>(1,50);
    m = n = MatrixType::Random(50);
    m.conservativeResize(size);
    VERIFY_IS_APPROX(m, n.segment(0,size));
  }

  // random growing with zeroing ...
  for (int i=0; i<50; ++i)
  {
    const int size = ei_random<int>(50,100);
    m = n = MatrixType::Random(50);
    m.conservativeResize(size,true);
    VERIFY_IS_APPROX(m.segment(0,50), n);
    VERIFY( size<=50 || m.segment(50,size-50).sum() == Scalar(0) );
  }
}

template <typename Scalar, int Storage>
void run_resize_like_tests()
{
  typedef Matrix<Scalar, Eigen::Dynamic, 1, Storage> MatrixType;

  MatrixType m;

  m = MatrixType::Random(5);
  m.conservativeResizeLike( MatrixType::Ones(2) );
  std::cout << m << std::endl;
}

void test_conservative_resize()
{
  run_resize_like_tests<int, Eigen::RowMajor>();

  //run_matrix_tests<int, Eigen::RowMajor>();
  //run_matrix_tests<int, Eigen::ColMajor>();
  //run_matrix_tests<float, Eigen::RowMajor>();
  //run_matrix_tests<float, Eigen::ColMajor>();
  //run_matrix_tests<double, Eigen::RowMajor>();
  //run_matrix_tests<double, Eigen::ColMajor>();
  //run_matrix_tests<std::complex<float>, Eigen::RowMajor>();
  //run_matrix_tests<std::complex<float>, Eigen::ColMajor>();
  //run_matrix_tests<std::complex<double>, Eigen::RowMajor>();
  //run_matrix_tests<std::complex<double>, Eigen::ColMajor>();

  //run_vector_tests<int>();
  //run_vector_tests<float>();
  //run_vector_tests<double>();
  //run_vector_tests<std::complex<float> >();
  //run_vector_tests<std::complex<double> >();
}
<commit_msg>Ups - that was not intended to be part of the commit.<commit_after>// This file is part of Eigen, a lightweight C++ template library
// for linear algebra. Eigen itself is part of the KDE project.
//
// Copyright (C) 2009 Hauke Heibel <hauke.heibel@gmail.com>
//
// Eigen 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 3 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or1 FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.

#include "main.h"

#include <Eigen/Core>
#include <Eigen/Array>

using namespace Eigen;

template <typename Scalar, int Storage>
void run_matrix_tests()
{
  typedef Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic, Storage> MatrixType;

  MatrixType m, n;

  // boundary cases ...
  m = n = MatrixType::Random(50,50);
  m.conservativeResize(1,50);
  VERIFY_IS_APPROX(m, n.block(0,0,1,50));

  m = n = MatrixType::Random(50,50);
  m.conservativeResize(50,1);
  VERIFY_IS_APPROX(m, n.block(0,0,50,1));

  m = n = MatrixType::Random(50,50);
  m.conservativeResize(50,50);
  VERIFY_IS_APPROX(m, n.block(0,0,50,50));

  // random shrinking ...
  for (int i=0; i<25; ++i)
  {
    const int rows = ei_random<int>(1,50);
    const int cols = ei_random<int>(1,50);
    m = n = MatrixType::Random(50,50);
    m.conservativeResize(rows,cols);
    VERIFY_IS_APPROX(m, n.block(0,0,rows,cols));
  }

  // random growing with zeroing ...
  for (int i=0; i<25; ++i)
  {
    const int rows = ei_random<int>(50,75);
    const int cols = ei_random<int>(50,75);
    m = n = MatrixType::Random(50,50);
    m.conservativeResize(rows,cols,true);
    VERIFY_IS_APPROX(m.block(0,0,n.rows(),n.cols()), n);
    VERIFY( rows<=50 || m.block(50,0,rows-50,cols).sum() == Scalar(0) );
    VERIFY( cols<=50 || m.block(0,50,rows,cols-50).sum() == Scalar(0) );
  }
}

template <typename Scalar>
void run_vector_tests()
{
  typedef Matrix<Scalar, 1, Eigen::Dynamic> MatrixType;

  MatrixType m, n;

  // boundary cases ...
  m = n = MatrixType::Random(50);
  m.conservativeResize(1);
  VERIFY_IS_APPROX(m, n.segment(0,1));

  m = n = MatrixType::Random(50);
  m.conservativeResize(50);
  VERIFY_IS_APPROX(m, n.segment(0,50));

  // random shrinking ...
  for (int i=0; i<50; ++i)
  {
    const int size = ei_random<int>(1,50);
    m = n = MatrixType::Random(50);
    m.conservativeResize(size);
    VERIFY_IS_APPROX(m, n.segment(0,size));
  }

  // random growing with zeroing ...
  for (int i=0; i<50; ++i)
  {
    const int size = ei_random<int>(50,100);
    m = n = MatrixType::Random(50);
    m.conservativeResize(size,true);
    VERIFY_IS_APPROX(m.segment(0,50), n);
    VERIFY( size<=50 || m.segment(50,size-50).sum() == Scalar(0) );
  }
}

void test_conservative_resize()
{
  run_matrix_tests<int, Eigen::RowMajor>();
  run_matrix_tests<int, Eigen::ColMajor>();
  run_matrix_tests<float, Eigen::RowMajor>();
  run_matrix_tests<float, Eigen::ColMajor>();
  run_matrix_tests<double, Eigen::RowMajor>();
  run_matrix_tests<double, Eigen::ColMajor>();
  run_matrix_tests<std::complex<float>, Eigen::RowMajor>();
  run_matrix_tests<std::complex<float>, Eigen::ColMajor>();
  run_matrix_tests<std::complex<double>, Eigen::RowMajor>();
  run_matrix_tests<std::complex<double>, Eigen::ColMajor>();

  run_vector_tests<int>();
  run_vector_tests<float>();
  run_vector_tests<double>();
  run_vector_tests<std::complex<float> >();
  run_vector_tests<std::complex<double> >();
}
<|endoftext|>


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

#include "chrome/browser/chromeos/main_menu.h"

#include "app/gfx/insets.h"
#include "app/resource_bundle.h"
#include "base/message_loop.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/browser/renderer_host/render_view_host_factory.h"
#include "chrome/browser/renderer_host/render_widget_host_view.h"
#include "chrome/browser/renderer_host/render_widget_host_view_gtk.h"
#include "chrome/browser/renderer_host/site_instance.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/tab_contents/render_view_host_delegate_helper.h"
#include "grit/app_resources.h"
#include "grit/generated_resources.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "views/background.h"
#include "views/painter.h"
#include "views/widget/root_view.h"
#include "views/widget/widget_gtk.h"

// Initial size of the renderer. This is contained within a window whose size
// is set to the size of the image IDR_MAIN_MENU_BUTTON_DROP_DOWN.
static const int kRendererX = 0;
static const int kRendererY = 25;
static const int kRendererWidth = 250;
static const int kRendererHeight = 400;

// Insets defining the regions that are stretched and titled to create the
// background of the popup. These constants are fed into
// Painter::CreateImagePainter as the insets, see it for details.
static const int kBackgroundImageTop = 27;
static const int kBackgroundImageLeft = 85;
static const int kBackgroundImageBottom = 10;
static const int kBackgroundImageRight = 8;

// URL of the page to load.
static const char kMenuURL[] = "http://goto.ext.google.com/crux-menu";

// static
void MainMenu::Show(Browser* browser) {
  (new MainMenu(browser))->ShowImpl();
}

MainMenu::~MainMenu() {
  popup_->Close();
  menu_rvh_->Shutdown();
}

MainMenu::MainMenu(Browser* browser)
    : browser_(browser),
      popup_(NULL),
      site_instance_(NULL),
      menu_rvh_(NULL),
      rwhv_(NULL),
      ALLOW_THIS_IN_INITIALIZER_LIST(tab_contents_delegate_(this)) {
}

void MainMenu::ShowImpl() {
  SkBitmap* drop_down_image = ResourceBundle::GetSharedInstance().
      GetBitmapNamed(IDR_MAIN_MENU_BUTTON_DROP_DOWN);

  views::WidgetGtk* menu_popup =
      new views::WidgetGtk(views::WidgetGtk::TYPE_POPUP);
  popup_ = menu_popup;
  // The background image has transparency, so we make the window transparent.
  menu_popup->MakeTransparent();
  menu_popup->Init(NULL, gfx::Rect(0, 0, drop_down_image->width(),
                                   drop_down_image->height()));

  views::Painter* painter = views::Painter::CreateImagePainter(
      *drop_down_image,
      gfx::Insets(kBackgroundImageTop, kBackgroundImageLeft,
                  kBackgroundImageBottom, kBackgroundImageRight));
  menu_popup->GetRootView()->set_background(
      views::Background::CreateBackgroundPainter(true, painter));

  GURL menu_url(kMenuURL);
  site_instance_ = SiteInstance::CreateSiteInstanceForURL(browser_->profile(),
                                                          menu_url);
  menu_rvh_ = new RenderViewHost(site_instance_, this, MSG_ROUTING_NONE);

  rwhv_ = new RenderWidgetHostViewGtk(menu_rvh_);
  rwhv_->InitAsChild();
  menu_rvh_->CreateRenderView();
  menu_popup->AddChild(rwhv_->GetNativeView());
  menu_popup->PositionChild(rwhv_->GetNativeView(), kRendererX, kRendererY,
                            kRendererWidth, kRendererHeight);
  rwhv_->SetSize(gfx::Size(kRendererWidth, kRendererHeight));
  menu_rvh_->NavigateToURL(menu_url);
  menu_popup->Show();

  GtkWidget* rwhv_widget = rwhv_->GetNativeView();
  gtk_widget_realize(rwhv_widget);
  g_signal_connect(rwhv_widget, "button-press-event",
                   G_CALLBACK(CallButtonPressEvent), this);
  // Do a mouse grab on the renderer widget host view's widget so that we can
  // close the popup if the user clicks anywhere else. And do a keyboard
  // grab so that we get all key events.
  gdk_pointer_grab(rwhv_widget->window, FALSE,
                   static_cast<GdkEventMask>(
                         GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
                         GDK_POINTER_MOTION_MASK),
                   NULL, NULL, GDK_CURRENT_TIME);
  gdk_keyboard_grab(rwhv_widget->window, FALSE, GDK_CURRENT_TIME);
}

void MainMenu::Delete(bool now) {
  gdk_keyboard_ungrab(GDK_CURRENT_TIME);
  gdk_pointer_ungrab(GDK_CURRENT_TIME);
  // Hide the popup immediately. We don't close it as it contains the
  // renderwidgethostview, which hasn't been shutdown yet.
  popup_->Hide();
  if (now)
    delete this;
  else
    MessageLoop::current()->DeleteSoon(FROM_HERE, this);
}

// static
gboolean MainMenu::CallButtonPressEvent(GtkWidget* widget,
                                        GdkEventButton* event,
                                        MainMenu* menu) {
  return menu->OnButtonPressEvent(widget, event);
}

gboolean MainMenu::OnButtonPressEvent(GtkWidget* widget,
                                      GdkEventButton* event) {
  if (event->x < 0 || event->y < 0 ||
      event->x >= widget->allocation.width ||
      event->y >= widget->allocation.height) {
    // The user clicked outside the bounds of the menu, delete the main which
    // results in closing it.
    Delete(true);
  }
  return FALSE;
}

void MainMenu::RequestMove(const gfx::Rect& new_bounds) {
  SkBitmap* drop_down_image = ResourceBundle::GetSharedInstance().
      GetBitmapNamed(IDR_MAIN_MENU_BUTTON_DROP_DOWN);
  int new_w = drop_down_image->width() + (new_bounds.width() - kRendererWidth);
  int new_h = drop_down_image->height() +
              (new_bounds.height() - kRendererHeight);
  // Invoking PositionChild results in a gtk signal that triggers attempting to
  // to resize the window. We need to set the size request so that it resizes
  // correctly when this happens.
  gtk_widget_set_size_request(popup_->GetNativeView(), new_w, new_h);
  popup_->PositionChild(rwhv_->GetNativeView(), kRendererX, kRendererY,
                        new_bounds.width(), new_bounds.height());
  popup_->SetBounds(gfx::Rect(0, 0, new_w, new_h));
  rwhv_->SetSize(new_bounds.size());
}

void MainMenu::CreateNewWindow(int route_id) {
  if (pending_contents_.get()) {
    NOTREACHED();
    return;
  }

  helper_.CreateNewWindow(route_id, browser_->profile(), site_instance_,
                          DOMUIFactory::GetDOMUIType(GURL(kMenuURL)), NULL);
  pending_contents_.reset(helper_.GetCreatedWindow(route_id));
  pending_contents_->set_delegate(&tab_contents_delegate_);
}

void MainMenu::ShowCreatedWindow(int route_id,
                                 WindowOpenDisposition disposition,
                                 const gfx::Rect& initial_pos,
                                 bool user_gesture,
                                 const GURL& creator_url) {
  if (disposition == NEW_POPUP) {
    pending_contents_->set_delegate(NULL);
    browser_->GetSelectedTabContents()->AddNewContents(
        pending_contents_.release(), disposition, initial_pos, user_gesture,
        creator_url);
    Delete(false);
  }
}

void MainMenu::TabContentsDelegateImpl::OpenURLFromTab(
    TabContents* source,
    const GURL& url,
    const GURL& referrer,
    WindowOpenDisposition disposition,
    PageTransition::Type transition) {
  menu_->browser_->OpenURL(url, referrer, NEW_FOREGROUND_TAB,
                           PageTransition::LINK);
  menu_->Delete(true);
}
<commit_msg>Adds the ability for script to move the menu.<commit_after>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/chromeos/main_menu.h"

#include "app/gfx/insets.h"
#include "app/resource_bundle.h"
#include "base/message_loop.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/browser/renderer_host/render_view_host_factory.h"
#include "chrome/browser/renderer_host/render_widget_host_view.h"
#include "chrome/browser/renderer_host/render_widget_host_view_gtk.h"
#include "chrome/browser/renderer_host/site_instance.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/tab_contents/render_view_host_delegate_helper.h"
#include "grit/app_resources.h"
#include "grit/generated_resources.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "views/background.h"
#include "views/painter.h"
#include "views/widget/root_view.h"
#include "views/widget/widget_gtk.h"

// Initial size of the renderer. This is contained within a window whose size
// is set to the size of the image IDR_MAIN_MENU_BUTTON_DROP_DOWN.
static const int kRendererX = 0;
static const int kRendererY = 25;
static const int kRendererWidth = 250;
static const int kRendererHeight = 400;

// Insets defining the regions that are stretched and titled to create the
// background of the popup. These constants are fed into
// Painter::CreateImagePainter as the insets, see it for details.
static const int kBackgroundImageTop = 27;
static const int kBackgroundImageLeft = 85;
static const int kBackgroundImageBottom = 10;
static const int kBackgroundImageRight = 8;

// URL of the page to load.
static const char kMenuURL[] = "http://goto.ext.google.com/crux-menu";

// static
void MainMenu::Show(Browser* browser) {
  (new MainMenu(browser))->ShowImpl();
}

MainMenu::~MainMenu() {
  popup_->Close();
  menu_rvh_->Shutdown();
}

MainMenu::MainMenu(Browser* browser)
    : browser_(browser),
      popup_(NULL),
      site_instance_(NULL),
      menu_rvh_(NULL),
      rwhv_(NULL),
      ALLOW_THIS_IN_INITIALIZER_LIST(tab_contents_delegate_(this)) {
}

void MainMenu::ShowImpl() {
  SkBitmap* drop_down_image = ResourceBundle::GetSharedInstance().
      GetBitmapNamed(IDR_MAIN_MENU_BUTTON_DROP_DOWN);

  views::WidgetGtk* menu_popup =
      new views::WidgetGtk(views::WidgetGtk::TYPE_POPUP);
  popup_ = menu_popup;
  // The background image has transparency, so we make the window transparent.
  menu_popup->MakeTransparent();
  menu_popup->Init(NULL, gfx::Rect(0, 0, drop_down_image->width(),
                                   drop_down_image->height()));

  views::Painter* painter = views::Painter::CreateImagePainter(
      *drop_down_image,
      gfx::Insets(kBackgroundImageTop, kBackgroundImageLeft,
                  kBackgroundImageBottom, kBackgroundImageRight));
  menu_popup->GetRootView()->set_background(
      views::Background::CreateBackgroundPainter(true, painter));

  GURL menu_url(kMenuURL);
  site_instance_ = SiteInstance::CreateSiteInstanceForURL(browser_->profile(),
                                                          menu_url);
  menu_rvh_ = new RenderViewHost(site_instance_, this, MSG_ROUTING_NONE);

  rwhv_ = new RenderWidgetHostViewGtk(menu_rvh_);
  rwhv_->InitAsChild();
  menu_rvh_->CreateRenderView();
  menu_popup->AddChild(rwhv_->GetNativeView());
  menu_popup->PositionChild(rwhv_->GetNativeView(), kRendererX, kRendererY,
                            kRendererWidth, kRendererHeight);
  rwhv_->SetSize(gfx::Size(kRendererWidth, kRendererHeight));
  menu_rvh_->NavigateToURL(menu_url);
  menu_popup->Show();

  GtkWidget* rwhv_widget = rwhv_->GetNativeView();
  gtk_widget_realize(rwhv_widget);
  g_signal_connect(rwhv_widget, "button-press-event",
                   G_CALLBACK(CallButtonPressEvent), this);
  // Do a mouse grab on the renderer widget host view's widget so that we can
  // close the popup if the user clicks anywhere else. And do a keyboard
  // grab so that we get all key events.
  gdk_pointer_grab(rwhv_widget->window, FALSE,
                   static_cast<GdkEventMask>(
                         GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
                         GDK_POINTER_MOTION_MASK),
                   NULL, NULL, GDK_CURRENT_TIME);
  gdk_keyboard_grab(rwhv_widget->window, FALSE, GDK_CURRENT_TIME);
}

void MainMenu::Delete(bool now) {
  gdk_keyboard_ungrab(GDK_CURRENT_TIME);
  gdk_pointer_ungrab(GDK_CURRENT_TIME);
  // Hide the popup immediately. We don't close it as it contains the
  // renderwidgethostview, which hasn't been shutdown yet.
  popup_->Hide();
  if (now)
    delete this;
  else
    MessageLoop::current()->DeleteSoon(FROM_HERE, this);
}

// static
gboolean MainMenu::CallButtonPressEvent(GtkWidget* widget,
                                        GdkEventButton* event,
                                        MainMenu* menu) {
  return menu->OnButtonPressEvent(widget, event);
}

gboolean MainMenu::OnButtonPressEvent(GtkWidget* widget,
                                      GdkEventButton* event) {
  if (event->x < 0 || event->y < 0 ||
      event->x >= widget->allocation.width ||
      event->y >= widget->allocation.height) {
    // The user clicked outside the bounds of the menu, delete the main which
    // results in closing it.
    Delete(true);
  }
  return FALSE;
}

void MainMenu::RequestMove(const gfx::Rect& new_bounds) {
  SkBitmap* drop_down_image = ResourceBundle::GetSharedInstance().
      GetBitmapNamed(IDR_MAIN_MENU_BUTTON_DROP_DOWN);
  int new_w = drop_down_image->width() + (new_bounds.width() - kRendererWidth);
  int new_h = drop_down_image->height() +
              (new_bounds.height() - kRendererHeight);
  // Invoking PositionChild results in a gtk signal that triggers attempting to
  // to resize the window. We need to set the size request so that it resizes
  // correctly when this happens.
  gtk_widget_set_size_request(popup_->GetNativeView(), new_w, new_h);
  popup_->PositionChild(rwhv_->GetNativeView(), kRendererX, kRendererY,
                        new_bounds.width(), new_bounds.height());
  popup_->SetBounds(gfx::Rect(new_bounds.x(), new_bounds.y(), new_w, new_h));
  rwhv_->SetSize(new_bounds.size());
}

void MainMenu::CreateNewWindow(int route_id) {
  if (pending_contents_.get()) {
    NOTREACHED();
    return;
  }

  helper_.CreateNewWindow(route_id, browser_->profile(), site_instance_,
                          DOMUIFactory::GetDOMUIType(GURL(kMenuURL)), NULL);
  pending_contents_.reset(helper_.GetCreatedWindow(route_id));
  pending_contents_->set_delegate(&tab_contents_delegate_);
}

void MainMenu::ShowCreatedWindow(int route_id,
                                 WindowOpenDisposition disposition,
                                 const gfx::Rect& initial_pos,
                                 bool user_gesture,
                                 const GURL& creator_url) {
  if (disposition == NEW_POPUP) {
    pending_contents_->set_delegate(NULL);
    browser_->GetSelectedTabContents()->AddNewContents(
        pending_contents_.release(), disposition, initial_pos, user_gesture,
        creator_url);
    Delete(false);
  }
}

void MainMenu::TabContentsDelegateImpl::OpenURLFromTab(
    TabContents* source,
    const GURL& url,
    const GURL& referrer,
    WindowOpenDisposition disposition,
    PageTransition::Type transition) {
  menu_->browser_->OpenURL(url, referrer, NEW_FOREGROUND_TAB,
                           PageTransition::LINK);
  menu_->Delete(true);
}
<|endoftext|>


<commit_before>/*

Copyright (c) 2008, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#include "test.hpp"
#include "setup_transfer.hpp"
#include "libtorrent/socket.hpp"
#include "libtorrent/io.hpp"
#include <cstring>
#include <boost/bind.hpp>
#include <iostream>

using namespace libtorrent;

int read_message(stream_socket& s, char* buffer)
{
	using namespace libtorrent::detail;
	error_code ec;
	libtorrent::asio::read(s, libtorrent::asio::buffer(buffer, 4)
		, libtorrent::asio::transfer_all(), ec);
	if (ec)
	{
		std::cout << time_now_string() << ": " << ec.message() << std::endl;
		exit(1);
	}
	char* ptr = buffer;
	int length = read_int32(ptr);

	libtorrent::asio::read(s, libtorrent::asio::buffer(buffer, length)
		, libtorrent::asio::transfer_all(), ec);
	if (ec)
	{
		std::cout << time_now_string() << ": " << ec.message() << std::endl;
		exit(1);
	}
	return length;
}

void print_message(char const* buffer, int len)
{
	char const* message_name[] = {"choke", "unchoke", "interested", "not_interested"
		, "have", "bitfield", "request", "piece", "cancel", "dht_port", "", "", ""
		, "suggest_piece", "have_all", "have_none", "reject_request", "allowed_fast"};

	char message[50];
	char extra[300];
	extra[0] = 0;
	if (len == 0)
	{
		strcpy(message, "keepalive");
	}
	else
	{
		int msg = buffer[0];
		if (msg >= 0 && msg < int(sizeof(message_name)/sizeof(message_name[0])))
			strcpy(message, message_name[msg]);
		else
			snprintf(message, sizeof(message), "unknown[%d]", msg);

		if (msg == 0x6 && len == 13)
		{
			peer_request r;
			const char* ptr = buffer + 1;
			r.piece = detail::read_int32(ptr);
			r.start = detail::read_int32(ptr);
			r.length = detail::read_int32(ptr);
			snprintf(extra, sizeof(extra), "p: %d s: %d l: %d", r.piece, r.start, r.length);
		}
		else if (msg == 0x11 && len == 5)
		{
			const char* ptr = buffer + 1;
			int index = detail::read_int32(ptr);
			snprintf(extra, sizeof(extra), "p: %d", index);
		}
	}

	fprintf(stderr, "%s <== %s %s\n", time_now_string(), message, extra);
}

void send_allow_fast(stream_socket& s, int piece)
{
	std::cout << time_now_string() << " ==> allow fast: " << piece << std::endl;
	using namespace libtorrent::detail;
	char msg[] = "\0\0\0\x05\x11\0\0\0\0";
	char* ptr = msg + 5;
	write_int32(piece, ptr);
	error_code ec;
	libtorrent::asio::write(s, libtorrent::asio::buffer(msg, 9)
		, libtorrent::asio::transfer_all(), ec);
}

void send_suggest_piece(stream_socket& s, int piece)
{
	std::cout << time_now_string() << " ==> suggest piece: " << piece << std::endl;
	using namespace libtorrent::detail;
	char msg[] = "\0\0\0\x05\x0d\0\0\0\0";
	char* ptr = msg + 5;
	write_int32(piece, ptr);
	error_code ec;
	libtorrent::asio::write(s, libtorrent::asio::buffer(msg, 9)
		, libtorrent::asio::transfer_all(), ec);
}

void send_keepalive(stream_socket& s)
{
	std::cout << time_now_string() << " ==> keepalive" << std::endl;
	char msg[] = "\0\0\0\0";
	error_code ec;
	libtorrent::asio::write(s, libtorrent::asio::buffer(msg, 4)
		, libtorrent::asio::transfer_all(), ec);
}

void send_unchoke(stream_socket& s)
{
	std::cout << time_now_string() << " ==> unchoke" << std::endl;
	char msg[] = "\0\0\0\x01\x01";
	error_code ec;
	libtorrent::asio::write(s, libtorrent::asio::buffer(msg, 5)
		, libtorrent::asio::transfer_all(), ec);
}

void do_handshake(stream_socket& s, sha1_hash const& ih, char* buffer)
{
	char handshake[] = "\x13" "BitTorrent protocol\0\0\0\0\0\0\0\x04"
		"                    " // space for info-hash
		"aaaaaaaaaaaaaaaaaaaa" // peer-id
		"\0\0\0\x01\x0e"; // have_all
	std::cout << time_now_string() << " ==> handshake" << std::endl;
	std::cout << time_now_string() << " ==> have_all" << std::endl;
	error_code ec;
	std::memcpy(handshake + 28, ih.begin(), 20);
	libtorrent::asio::write(s, libtorrent::asio::buffer(handshake, sizeof(handshake) - 1)
		, libtorrent::asio::transfer_all(), ec);

	// read handshake
	libtorrent::asio::read(s, libtorrent::asio::buffer(buffer, 68)
		, libtorrent::asio::transfer_all(), ec);
	if (ec)
	{
		std::cout << time_now_string() << ": " << ec.message() << std::endl;
		exit(1);
	}
	std::cout << time_now_string() << " <== handshake" << std::endl;

	TEST_CHECK(buffer[0] == 19);
	TEST_CHECK(std::memcmp(buffer + 1, "BitTorrent protocol", 19) == 0);

	char* extensions = buffer + 20;
	// check for fast extension support
	TEST_CHECK(extensions[7] & 0x4);

#ifndef TORRENT_DISABLE_EXTENSIONS
	// check for extension protocol support
	TEST_CHECK(extensions[5] & 0x10);
#endif

#ifndef TORRENT_DISABLE_DHT
	// check for DHT support
	TEST_CHECK(extensions[7] & 0x1);
#endif

	TEST_CHECK(std::memcmp(buffer + 28, ih.begin(), 20) == 0);
}

// makes sure that pieces that are allowed and then
// rejected aren't requested again
void test_reject_fast()
{
	std::cerr << " === test reject ===" << std::endl;

	boost::intrusive_ptr<torrent_info> t = ::create_torrent();
	sha1_hash ih = t->info_hash();
	session ses1(fingerprint("LT", 0, 1, 0, 0), std::make_pair(48900, 49000), "0.0.0.0", 0);
	error_code ec;
	add_torrent_params p;
	p.ti = t;
	p.save_path = "./tmp1_fast";
	ses1.add_torrent(p, ec);

	test_sleep(2000);

	io_service ios;
	stream_socket s(ios);
	s.connect(tcp::endpoint(address::from_string("127.0.0.1", ec), ses1.listen_port()), ec);

	char recv_buffer[1000];
	do_handshake(s, ih, recv_buffer);

	std::vector<int> allowed_fast;
	allowed_fast.push_back(0);
	allowed_fast.push_back(1);
	allowed_fast.push_back(2);
	allowed_fast.push_back(3);

	std::for_each(allowed_fast.begin(), allowed_fast.end()
		, boost::bind(&send_allow_fast, boost::ref(s), _1));

	while (!allowed_fast.empty())
	{
		int len = read_message(s, recv_buffer);
		print_message(recv_buffer, len);
		int msg = recv_buffer[0];
		if (msg != 0x6) continue;

		using namespace libtorrent::detail;
		char* ptr = recv_buffer + 1;
		int piece = read_int32(ptr);

		std::vector<int>::iterator i = std::find(allowed_fast.begin()
			, allowed_fast.end(), piece);
		TEST_CHECK(i != allowed_fast.end());
		if (i != allowed_fast.end())
			allowed_fast.erase(i);
		// send reject request
		recv_buffer[0] = 0x10;
		error_code ec;
		std::cerr << time_now_string() << " ==> reject" << std::endl;
		libtorrent::asio::write(s, libtorrent::asio::buffer("\0\0\0\x0d", 4)
			, libtorrent::asio::transfer_all(), ec);
		libtorrent::asio::write(s, libtorrent::asio::buffer(recv_buffer, 13)
			, libtorrent::asio::transfer_all(), ec);
	}
}

void test_respect_suggest()
{
	std::cerr << " === test suggest ===" << std::endl;
	boost::intrusive_ptr<torrent_info> t = ::create_torrent();
	sha1_hash ih = t->info_hash();
	session ses1(fingerprint("LT", 0, 1, 0, 0), std::make_pair(48900, 49000), "0.0.0.0", 0);

	error_code ec;
	add_torrent_params p;
	p.ti = t;
	p.save_path = "./tmp1_fast";
	ses1.add_torrent(p, ec);

	test_sleep(2000);

	io_service ios;
	stream_socket s(ios);
	s.connect(tcp::endpoint(address::from_string("127.0.0.1", ec), ses1.listen_port()), ec);

	char recv_buffer[1000];
	do_handshake(s, ih, recv_buffer);

	std::vector<int> suggested;
	suggested.push_back(0);
	suggested.push_back(1);
	suggested.push_back(2);
	suggested.push_back(3);

	std::for_each(suggested.begin(), suggested.end()
		, boost::bind(&send_suggest_piece, boost::ref(s), _1));

	send_unchoke(s);

	send_keepalive(s);

	int fail_counter = 100;
	while (!suggested.empty() && fail_counter > 0)
	{
		int len = read_message(s, recv_buffer);
		print_message(recv_buffer, len);
		int msg = recv_buffer[0];
		fail_counter--;
		if (msg != 0x6) continue;

		using namespace libtorrent::detail;
		char* ptr = recv_buffer + 1;
		int piece = read_int32(ptr);

		std::vector<int>::iterator i = std::find(suggested.begin()
			, suggested.end(), piece);
		TEST_CHECK(i != suggested.end());
		if (i != suggested.end())
			suggested.erase(i);
		// send reject request
		recv_buffer[0] = 0x10;
		error_code ec;
		std::cerr << time_now_string() << " ==> reject" << std::endl;
		libtorrent::asio::write(s, libtorrent::asio::buffer("\0\0\0\x0d", 4)
			, libtorrent::asio::transfer_all(), ec);
		libtorrent::asio::write(s, libtorrent::asio::buffer(recv_buffer, 13)
			, libtorrent::asio::transfer_all(), ec);
	}
	TEST_CHECK(fail_counter > 0);
}

int test_main()
{
	test_reject_fast();
	test_respect_suggest();
	return 0;
}

<commit_msg>fix test_fast_extension<commit_after>/*

Copyright (c) 2008, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#include "test.hpp"
#include "setup_transfer.hpp"
#include "libtorrent/socket.hpp"
#include "libtorrent/io.hpp"
#include <cstring>
#include <boost/bind.hpp>
#include <iostream>

using namespace libtorrent;

int read_message(stream_socket& s, char* buffer)
{
	using namespace libtorrent::detail;
	error_code ec;
	libtorrent::asio::read(s, libtorrent::asio::buffer(buffer, 4)
		, libtorrent::asio::transfer_all(), ec);
	if (ec)
	{
		std::cout << time_now_string() << ": " << ec.message() << std::endl;
		exit(1);
	}
	char* ptr = buffer;
	int length = read_int32(ptr);

	libtorrent::asio::read(s, libtorrent::asio::buffer(buffer, length)
		, libtorrent::asio::transfer_all(), ec);
	if (ec)
	{
		std::cout << time_now_string() << ": " << ec.message() << std::endl;
		exit(1);
	}
	return length;
}

void print_message(char const* buffer, int len)
{
	char const* message_name[] = {"choke", "unchoke", "interested", "not_interested"
		, "have", "bitfield", "request", "piece", "cancel", "dht_port", "", "", ""
		, "suggest_piece", "have_all", "have_none", "reject_request", "allowed_fast"};

	char message[50];
	char extra[300];
	extra[0] = 0;
	if (len == 0)
	{
		strcpy(message, "keepalive");
	}
	else
	{
		int msg = buffer[0];
		if (msg >= 0 && msg < int(sizeof(message_name)/sizeof(message_name[0])))
			strcpy(message, message_name[msg]);
		else
			snprintf(message, sizeof(message), "unknown[%d]", msg);

		if (msg == 0x6 && len == 13)
		{
			peer_request r;
			const char* ptr = buffer + 1;
			r.piece = detail::read_int32(ptr);
			r.start = detail::read_int32(ptr);
			r.length = detail::read_int32(ptr);
			snprintf(extra, sizeof(extra), "p: %d s: %d l: %d", r.piece, r.start, r.length);
		}
		else if (msg == 0x11 && len == 5)
		{
			const char* ptr = buffer + 1;
			int index = detail::read_int32(ptr);
			snprintf(extra, sizeof(extra), "p: %d", index);
		}
	}

	fprintf(stderr, "%s <== %s %s\n", time_now_string(), message, extra);
}

void send_allow_fast(stream_socket& s, int piece)
{
	std::cout << time_now_string() << " ==> allow fast: " << piece << std::endl;
	using namespace libtorrent::detail;
	char msg[] = "\0\0\0\x05\x11\0\0\0\0";
	char* ptr = msg + 5;
	write_int32(piece, ptr);
	error_code ec;
	libtorrent::asio::write(s, libtorrent::asio::buffer(msg, 9)
		, libtorrent::asio::transfer_all(), ec);
}

void send_suggest_piece(stream_socket& s, int piece)
{
	std::cout << time_now_string() << " ==> suggest piece: " << piece << std::endl;
	using namespace libtorrent::detail;
	char msg[] = "\0\0\0\x05\x0d\0\0\0\0";
	char* ptr = msg + 5;
	write_int32(piece, ptr);
	error_code ec;
	libtorrent::asio::write(s, libtorrent::asio::buffer(msg, 9)
		, libtorrent::asio::transfer_all(), ec);
}

void send_keepalive(stream_socket& s)
{
	std::cout << time_now_string() << " ==> keepalive" << std::endl;
	char msg[] = "\0\0\0\0";
	error_code ec;
	libtorrent::asio::write(s, libtorrent::asio::buffer(msg, 4)
		, libtorrent::asio::transfer_all(), ec);
}

void send_unchoke(stream_socket& s)
{
	std::cout << time_now_string() << " ==> unchoke" << std::endl;
	char msg[] = "\0\0\0\x01\x01";
	error_code ec;
	libtorrent::asio::write(s, libtorrent::asio::buffer(msg, 5)
		, libtorrent::asio::transfer_all(), ec);
}

void do_handshake(stream_socket& s, sha1_hash const& ih, char* buffer)
{
	char handshake[] = "\x13" "BitTorrent protocol\0\0\0\0\0\0\0\x04"
		"                    " // space for info-hash
		"aaaaaaaaaaaaaaaaaaaa" // peer-id
		"\0\0\0\x01\x0e"; // have_all
	std::cout << time_now_string() << " ==> handshake" << std::endl;
	std::cout << time_now_string() << " ==> have_all" << std::endl;
	error_code ec;
	std::memcpy(handshake + 28, ih.begin(), 20);
	libtorrent::asio::write(s, libtorrent::asio::buffer(handshake, sizeof(handshake) - 1)
		, libtorrent::asio::transfer_all(), ec);

	// read handshake
	libtorrent::asio::read(s, libtorrent::asio::buffer(buffer, 68)
		, libtorrent::asio::transfer_all(), ec);
	if (ec)
	{
		std::cout << time_now_string() << ": " << ec.message() << std::endl;
		exit(1);
	}
	std::cout << time_now_string() << " <== handshake" << std::endl;

	TEST_CHECK(buffer[0] == 19);
	TEST_CHECK(std::memcmp(buffer + 1, "BitTorrent protocol", 19) == 0);

	char* extensions = buffer + 20;
	// check for fast extension support
	TEST_CHECK(extensions[7] & 0x4);

#ifndef TORRENT_DISABLE_EXTENSIONS
	// check for extension protocol support
	TEST_CHECK(extensions[5] & 0x10);
#endif

#ifndef TORRENT_DISABLE_DHT
	// check for DHT support
	TEST_CHECK(extensions[7] & 0x1);
#endif

	TEST_CHECK(std::memcmp(buffer + 28, ih.begin(), 20) == 0);
}

// makes sure that pieces that are allowed and then
// rejected aren't requested again
void test_reject_fast()
{
	std::cerr << " === test reject ===" << std::endl;

	boost::intrusive_ptr<torrent_info> t = ::create_torrent();
	sha1_hash ih = t->info_hash();
	session ses1(fingerprint("LT", 0, 1, 0, 0), std::make_pair(48900, 49000), "0.0.0.0", 0);
	error_code ec;
	add_torrent_params p;
	p.ti = t;
	p.save_path = "./tmp1_fast";

	remove("./tmp1_fast/temporary", ec);
	if (ec) fprintf(stderr, "remove(): %s\n", ec.message().c_str());
	ec.clear();
	ses1.add_torrent(p, ec);

	test_sleep(2000);

	io_service ios;
	stream_socket s(ios);
	s.connect(tcp::endpoint(address::from_string("127.0.0.1", ec), ses1.listen_port()), ec);

	char recv_buffer[1000];
	do_handshake(s, ih, recv_buffer);

	std::vector<int> allowed_fast;
	allowed_fast.push_back(0);
	allowed_fast.push_back(1);
	allowed_fast.push_back(2);
	allowed_fast.push_back(3);

	std::for_each(allowed_fast.begin(), allowed_fast.end()
		, boost::bind(&send_allow_fast, boost::ref(s), _1));

	while (!allowed_fast.empty())
	{
		int len = read_message(s, recv_buffer);
		print_message(recv_buffer, len);
		int msg = recv_buffer[0];
		if (msg != 0x6) continue;

		using namespace libtorrent::detail;
		char* ptr = recv_buffer + 1;
		int piece = read_int32(ptr);

		std::vector<int>::iterator i = std::find(allowed_fast.begin()
			, allowed_fast.end(), piece);
		TEST_CHECK(i != allowed_fast.end());
		if (i != allowed_fast.end())
			allowed_fast.erase(i);
		// send reject request
		recv_buffer[0] = 0x10;
		error_code ec;
		std::cerr << time_now_string() << " ==> reject" << std::endl;
		libtorrent::asio::write(s, libtorrent::asio::buffer("\0\0\0\x0d", 4)
			, libtorrent::asio::transfer_all(), ec);
		libtorrent::asio::write(s, libtorrent::asio::buffer(recv_buffer, 13)
			, libtorrent::asio::transfer_all(), ec);
	}
}

void test_respect_suggest()
{
	std::cerr << " === test suggest ===" << std::endl;
	boost::intrusive_ptr<torrent_info> t = ::create_torrent();
	sha1_hash ih = t->info_hash();
	session ses1(fingerprint("LT", 0, 1, 0, 0), std::make_pair(48900, 49000), "0.0.0.0", 0);

	error_code ec;
	add_torrent_params p;
	p.ti = t;
	p.save_path = "./tmp1_fast";

	remove("./tmp1_fast/temporary", ec);
	if (ec) fprintf(stderr, "remove(): %s\n", ec.message().c_str());
	ec.clear();
	ses1.add_torrent(p, ec);

	test_sleep(2000);

	io_service ios;
	stream_socket s(ios);
	s.connect(tcp::endpoint(address::from_string("127.0.0.1", ec), ses1.listen_port()), ec);

	char recv_buffer[1000];
	do_handshake(s, ih, recv_buffer);

	std::vector<int> suggested;
	suggested.push_back(0);
	suggested.push_back(1);
	suggested.push_back(2);
	suggested.push_back(3);

	std::for_each(suggested.begin(), suggested.end()
		, boost::bind(&send_suggest_piece, boost::ref(s), _1));

	send_unchoke(s);

	send_keepalive(s);

	int fail_counter = 100;
	while (!suggested.empty() && fail_counter > 0)
	{
		int len = read_message(s, recv_buffer);
		print_message(recv_buffer, len);
		int msg = recv_buffer[0];
		fail_counter--;
		if (msg != 0x6) continue;

		using namespace libtorrent::detail;
		char* ptr = recv_buffer + 1;
		int piece = read_int32(ptr);

		std::vector<int>::iterator i = std::find(suggested.begin()
			, suggested.end(), piece);
		TEST_CHECK(i != suggested.end());
		if (i != suggested.end())
			suggested.erase(i);
		// send reject request
		recv_buffer[0] = 0x10;
		error_code ec;
		std::cerr << time_now_string() << " ==> reject" << std::endl;
		libtorrent::asio::write(s, libtorrent::asio::buffer("\0\0\0\x0d", 4)
			, libtorrent::asio::transfer_all(), ec);
		libtorrent::asio::write(s, libtorrent::asio::buffer(recv_buffer, 13)
			, libtorrent::asio::transfer_all(), ec);
	}
	TEST_CHECK(fail_counter > 0);
}

int test_main()
{
	test_reject_fast();
	test_respect_suggest();
	return 0;
}

<|endoftext|>


<commit_before>#pragma once

#include <exception>

namespace sdbusplus
{

namespace exception
{

/** Base exception class for all sdbusplus exceptions, including those created
 *  by the bindings. */
struct exception : public std::exception
{
    virtual const char* name() const noexcept = 0;
    virtual const char* description() const noexcept = 0;
};

/** base exception class for all errors generated by sdbusplus itself. */
struct internal_exception : public exception
{
};

} // namespace exception

using exception_t = exception::exception;
using internal_exception_t = exception::internal_exception;

} // namespace sdbusplus
<commit_msg>exception: add InvalidEnumString error<commit_after>#pragma once

#include <exception>

namespace sdbusplus
{

namespace exception
{

/** Base exception class for all sdbusplus exceptions, including those created
 *  by the bindings. */
struct exception : public std::exception
{
    virtual const char* name() const noexcept = 0;
    virtual const char* description() const noexcept = 0;
};

/** base exception class for all errors generated by sdbusplus itself. */
struct internal_exception : public exception
{
};

/** Exception for when an invalid conversion from string to enum is
 *  attempted. */
struct InvalidEnumString final : public internal_exception
{
    static constexpr auto errName =
        "org.openbmc_project.sdbusplus.Error.InvalidEnumString";
    static constexpr auto errDesc =
        "An enumeration mapping was attempted for which no valid enumeration "
        "value exists.";
    static constexpr auto errWhat =
        "org.openbmc_project.sdbusplus.Error.InvalidEnumString: "
        "An enumeration mapping was attempted for which no valid enumeration "
        "value exists.";

    const char* name() const noexcept override
    {
        return errName;
    }

    const char* description() const noexcept override
    {
        return errDesc;
    }

    const char* what() const noexcept override
    {
        return errWhat;
    }
};

} // namespace exception

using exception_t = exception::exception;
using internal_exception_t = exception::internal_exception;

} // namespace sdbusplus
<|endoftext|>


<commit_before>/*******************************************************************************
* Copyright 2017-2018 Intel Corporation
*
* 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.
*******************************************************************************/

#pragma once

#include <memory>

#include "ngraph/shape.hpp"

namespace ngraph
{
    class Node;
    class TensorViewType;

    namespace descriptor
    {
        namespace layout
        {
            class Tensor;
            class TensorViewLayout;
        }

        class Tensor;
        class TensorView;

        /// @brief Compile-time descriptor of a first-class value that is a view of a tensor.
        class TensorView
        {
            TensorView(const TensorView&) = delete;
            TensorView& operator=(const TensorView&) = delete;

        protected:
            TensorView(const std::shared_ptr<const TensorViewType>& tensor_view_type)
                : m_tensor_view_type(tensor_view_type)
            {
            }

        public:
            virtual ~TensorView() {}
            virtual const Tensor& get_tensor() const = 0;
            virtual Tensor& get_tensor() = 0;

            virtual std::shared_ptr<const TensorViewType> get_value_type() const;

            const std::string& get_name() const { return m_name; }
            std::shared_ptr<const TensorViewType> get_tensor_view_type() const
            {
                return m_tensor_view_type;
            }

            const std::shared_ptr<layout::TensorViewLayout>& get_tensor_view_layout() const
            {
                return m_tensor_view_layout;
            }

            void set_tensor_view_layout(
                const std::shared_ptr<layout::TensorViewLayout>& tensor_view_layout)
            {
                m_tensor_view_layout = tensor_view_layout;
            }

            virtual void collect_tensor_views(std::vector<std::shared_ptr<TensorView>>& views,
                                              const std::shared_ptr<TensorView>& value) const
            {
                views.push_back(value);
            }

        protected:
            std::shared_ptr<const TensorViewType> m_tensor_view_type;
            std::shared_ptr<layout::TensorViewLayout> m_tensor_view_layout;
            std::string m_name;
        };

        using TensorViewPtrs = std::vector<std::shared_ptr<TensorView>>;
    }
}
<commit_msg>Missing include (#586)<commit_after>/*******************************************************************************
* Copyright 2017-2018 Intel Corporation
*
* 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.
*******************************************************************************/

#pragma once

#include <memory>
#include <string>

#include "ngraph/shape.hpp"

namespace ngraph
{
    class Node;
    class TensorViewType;

    namespace descriptor
    {
        namespace layout
        {
            class Tensor;
            class TensorViewLayout;
        }

        class Tensor;
        class TensorView;

        /// @brief Compile-time descriptor of a first-class value that is a view of a tensor.
        class TensorView
        {
            TensorView(const TensorView&) = delete;
            TensorView& operator=(const TensorView&) = delete;

        protected:
            TensorView(const std::shared_ptr<const TensorViewType>& tensor_view_type)
                : m_tensor_view_type(tensor_view_type)
            {
            }

        public:
            virtual ~TensorView() {}
            virtual const Tensor& get_tensor() const = 0;
            virtual Tensor& get_tensor() = 0;

            virtual std::shared_ptr<const TensorViewType> get_value_type() const;

            const std::string& get_name() const { return m_name; }
            std::shared_ptr<const TensorViewType> get_tensor_view_type() const
            {
                return m_tensor_view_type;
            }

            const std::shared_ptr<layout::TensorViewLayout>& get_tensor_view_layout() const
            {
                return m_tensor_view_layout;
            }

            void set_tensor_view_layout(
                const std::shared_ptr<layout::TensorViewLayout>& tensor_view_layout)
            {
                m_tensor_view_layout = tensor_view_layout;
            }

            virtual void collect_tensor_views(std::vector<std::shared_ptr<TensorView>>& views,
                                              const std::shared_ptr<TensorView>& value) const
            {
                views.push_back(value);
            }

        protected:
            std::shared_ptr<const TensorViewType> m_tensor_view_type;
            std::shared_ptr<layout::TensorViewLayout> m_tensor_view_layout;
            std::string m_name;
        };

        using TensorViewPtrs = std::vector<std::shared_ptr<TensorView>>;
    }
}
<|endoftext|>


<commit_before>/**
  * Touhou Community Reliant Automatic Patcher
  * Tasogare Frontier support plugin
  *
  * ----
  *
  * Plugin breakpoints and hooks for th135+.
  */

#include <thcrap.h>
#include <vfs.h>
#include "thcrap_tasofro.h"
#include "th135.h"
#include "pl.h"
#include "tfcs.h"
#include "act-nut.h"
#include "spellcards_generator.h"
#include "bgm.h"
#include "plugin.h"
#include "crypt.h"

// TODO: read the file names list in JSON format
int th135_init()
{
	const char *crypt = json_object_get_string(runconfig_get(), "crypt");
	if (game_id >= TH145) {
		ICrypt::instance = new CryptTh145();
	}
	else {
		ICrypt::instance = new CryptTh135();
	}

	patchhook_register("*/stage*.pl", patch_pl, nullptr);
	patchhook_register("*/ed*.pl", patch_pl, nullptr);
	patchhook_register("*.csv", patch_tfcs, get_tfcs_size);
	patchhook_register("*.dll", patch_dll, [](const char*, json_t*, size_t) -> size_t { return 0; });
	patchhook_register("*.act", patch_act, nullptr);
	patchhook_register("*.nut", patch_nut, nullptr);
	patchhook_register("*.txt", patch_plaintext, nullptr);

	jsonvfs_game_add("data/csv/story/*/stage*.csv.jdiff",						{ "spells.js" }, spell_story_generator);
	if (game_id >= TH145) {
		jsonvfs_game_add("data/csv/spellcard/*.csv.jdiff",						{ "spells.js" }, spell_player_generator);
		jsonvfs_game_add("data/system/char_select3/*/equip/*/000.png.csv.jdiff",{ "spells.js" }, spell_char_select_generator);
	}
	else {
		jsonvfs_game_add("data/csv/Item*.csv.jdiff",							{ "spells.js" }, spell_player_generator);
	}

	char *bgm_pattern_fn = fn_for_game("data/bgm/bgm.csv.jdiff");
	char *musiccmt_fn = fn_for_game("musiccmt.js");
	jsonvfs_add(bgm_pattern_fn, { "themes.js", musiccmt_fn }, bgm_generator);
	SAFE_FREE(musiccmt_fn);
	SAFE_FREE(bgm_pattern_fn);

	json_t *fileslist = stack_game_json_resolve("fileslist.js", nullptr);
	LoadFileNameListFromJson(fileslist);
	json_decref(fileslist);
	return 0;
}

file_rep_t *call_file_header(x86_reg_t *regs, json_t *bp_info, const char *filename)
{
	json_t *new_bp_info = json_copy(bp_info);
	json_object_set_new(new_bp_info, "file_name", json_integer((json_int_t)filename));
	BP_file_header(regs, new_bp_info);
	json_decref(new_bp_info);

	file_rep_t *fr = file_rep_get(filename);
	if (fr && (fr->rep_buffer || fr->patch)) {
		return fr;
	}
	return nullptr;
}

int BP_th135_file_header(x86_reg_t *regs, json_t *bp_info)
{
	// Parameters
	// ----------
	DWORD hash = json_object_get_immediate(bp_info, regs, "file_hash");
	DWORD *key = (DWORD*)json_object_get_immediate(bp_info, regs, "file_key");
	// ----------

	if (!hash || !key)
		return 1;

	struct FileHeader *header = hash_to_file_header(hash);
	if (!header) {
		return 1;
	}

	file_rep_t *fr = call_file_header(regs, bp_info, header->path);

	// If the game loads a DDS file and we have no corresponding DDS file, try to replace it with a PNG file (the game will deal with it)
	if (!fr && strcmp(PathFindExtensionA(header->path), ".dds") == 0) {
		char png_path[MAX_PATH];
		strcpy(png_path, header->path);
		strcpy(PathFindExtensionA(png_path), ".png");
		register_filename(png_path);
		file_rep_t *fr_png = call_file_header(regs, bp_info, png_path);

		if (fr_png) {
			fr = file_rep_get(header->path);
			file_rep_clear(fr);
			memcpy(fr, fr_png, sizeof(*fr));
			memset(fr_png, 0, sizeof(*fr_png));
			file_rep_clear(fr_png);
			SAFE_FREE(fr->name);
			fr->name = EnsureUTF8(header->path, strlen(header->path) + 1);
		}
		else {
			fr = nullptr;
		}
	}

	if (fr) {
		header->hash = hash;
		memcpy(header->key, key, 4 * sizeof(DWORD));
		ICrypt::instance->convertKey(header->key);
		fr->object = header;
	}
	header->fr = fr;

	return 1;
}
int BP_th135_file_name(x86_reg_t *regs, json_t *bp_info)
{
	// Parameters
	// ----------
	const char *filename = (const char*)json_object_get_immediate(bp_info, regs, "file_name");
	// ----------

	if (filename) {
		register_filename(filename);
	}
	return 1;
}

static void post_read(const file_rep_t *fr, BYTE *buffer, size_t size)
{
	const FileHeader *header = (const FileHeader*)fr->object;
	if (header) {
		ICrypt::instance->uncryptBlock(buffer, size, header->key);
	}
}

static void post_patch(const file_rep_t *fr, BYTE *buffer, size_t size)
{
	const FileHeader *header = (const FileHeader*)fr->object;
	if (header) {
		ICrypt::instance->cryptBlock(buffer, size, header->key);
	}
}

/**
  * Replace file, 3rd attempt - hopefully I won't have to write a 4th one.
  * This breakpoint takes care of patching the files.
  * It takes place in the game's file reader, right after it calls its ReadFile caller.
  * At this point, we have the game's file structure in ESI, and so the filename's hash - we can't
  * read the wrong file.
  * In th145, the game's file structure have the following fields:
  * void* vtable;
  * HANDLE hFile;
  * BYTE buffer[0x10000];
  * DWORD LastReadFileSize; // Last value returned in lpNumberOfBytesRead in ReadFile
  * DWORD Offset; // Offset for the reader. I don't know what happens to it when it's bigger than 0x10000
  * DWORD LastReadSize; // Last read size asked to the reader
  * DWORD unknown1;
  * DWORD FileSize;
  * DWORD FileNameHash;
  * DWORD unknown2;
  * DWORD XorOffset; // Offset used by the XOR function
  * DWORD Key[5]; // 32-bytes encryption key used for XORing. The 5th DWORD is a copy of the 1st DWORD.
  * DWORD Aux; // Contains the last DWORD read from the file. Used during XORing.
  * We use hFile (file_struct + 4), buffer (file_struct + 8) and FileNameHash (file_struct + 0x1001c).
  * All the other fields are listed for documentation.
  */
int BP_th135_read_file(x86_reg_t *regs, json_t *bp_info)
{
	// Parameters
	// ----------
	DWORD newHash = json_object_get_immediate(bp_info, regs, "hash");
	// ----------

	static DWORD hash = 0;

	if (newHash) {
		hash = newHash;
	}
	if (!hash) {
		return 1;
	}

	struct FileHeader *header = hash_to_file_header(hash);
	if (!header || !header->fr || (!header->fr->rep_buffer && !header->fr->patch)) {
		// Nothing to patch.
		return 1;
	}

	json_t *new_bp_info = json_copy(bp_info);
	json_object_set_new(new_bp_info, "file_name",  json_integer((json_int_t)header->fr->name));
	json_object_set_new(new_bp_info, "post_read",  json_integer((json_int_t)post_read));
	json_object_set_new(new_bp_info, "post_patch", json_integer((json_int_t)post_patch));
	int ret = BP_fragmented_read_file(regs, new_bp_info);
	json_decref(new_bp_info);
	return ret;
}
<commit_msg>thcrap_tasofro: add spellcards hooks for th155<commit_after>/**
  * Touhou Community Reliant Automatic Patcher
  * Tasogare Frontier support plugin
  *
  * ----
  *
  * Plugin breakpoints and hooks for th135+.
  */

#include <thcrap.h>
#include <vfs.h>
#include "thcrap_tasofro.h"
#include "th135.h"
#include "pl.h"
#include "tfcs.h"
#include "act-nut.h"
#include "spellcards_generator.h"
#include "bgm.h"
#include "plugin.h"
#include "crypt.h"

// TODO: read the file names list in JSON format
int th135_init()
{
	const char *crypt = json_object_get_string(runconfig_get(), "crypt");
	if (game_id >= TH145) {
		ICrypt::instance = new CryptTh145();
	}
	else {
		ICrypt::instance = new CryptTh135();
	}

	patchhook_register("*/stage*.pl", patch_pl, nullptr);
	patchhook_register("*/ed*.pl", patch_pl, nullptr);
	patchhook_register("*.csv", patch_tfcs, get_tfcs_size);
	patchhook_register("*.dll", patch_dll, [](const char*, json_t*, size_t) -> size_t { return 0; });
	patchhook_register("*.act", patch_act, nullptr);
	patchhook_register("*.nut", patch_nut, nullptr);
	patchhook_register("*.txt", patch_plaintext, nullptr);

	if (game_id >= TH155) {
		jsonvfs_game_add_map("data/spell/*.csv.jdiff",							  "spells.js");
		jsonvfs_game_add_map("data/story/spell_list/*.csv.jdiff",				  "spells.js");
	}
	else if (game_id >= TH145) {
		jsonvfs_game_add("data/csv/story/*/stage*.csv.jdiff",					{ "spells.js" }, spell_story_generator);
		jsonvfs_game_add("data/csv/spellcard/*.csv.jdiff",						{ "spells.js" }, spell_player_generator);
		jsonvfs_game_add("data/system/char_select3/*/equip/*/000.png.csv.jdiff",{ "spells.js" }, spell_char_select_generator);
	}
	else {
		jsonvfs_game_add("data/csv/story/*/stage*.csv.jdiff",					{ "spells.js" }, spell_story_generator);
		jsonvfs_game_add("data/csv/Item*.csv.jdiff",							{ "spells.js" }, spell_player_generator);
	}

	char *bgm_pattern_fn = fn_for_game("data/bgm/bgm.csv.jdiff");
	char *musiccmt_fn = fn_for_game("musiccmt.js");
	jsonvfs_add(bgm_pattern_fn, { "themes.js", musiccmt_fn }, bgm_generator);
	SAFE_FREE(musiccmt_fn);
	SAFE_FREE(bgm_pattern_fn);

	json_t *fileslist = stack_game_json_resolve("fileslist.js", nullptr);
	LoadFileNameListFromJson(fileslist);
	json_decref(fileslist);
	return 0;
}

file_rep_t *call_file_header(x86_reg_t *regs, json_t *bp_info, const char *filename)
{
	json_t *new_bp_info = json_copy(bp_info);
	json_object_set_new(new_bp_info, "file_name", json_integer((json_int_t)filename));
	BP_file_header(regs, new_bp_info);
	json_decref(new_bp_info);

	file_rep_t *fr = file_rep_get(filename);
	if (fr && (fr->rep_buffer || fr->patch)) {
		return fr;
	}
	return nullptr;
}

int BP_th135_file_header(x86_reg_t *regs, json_t *bp_info)
{
	// Parameters
	// ----------
	DWORD hash = json_object_get_immediate(bp_info, regs, "file_hash");
	DWORD *key = (DWORD*)json_object_get_immediate(bp_info, regs, "file_key");
	// ----------

	if (!hash || !key)
		return 1;

	struct FileHeader *header = hash_to_file_header(hash);
	if (!header) {
		return 1;
	}

	file_rep_t *fr = call_file_header(regs, bp_info, header->path);

	// If the game loads a DDS file and we have no corresponding DDS file, try to replace it with a PNG file (the game will deal with it)
	if (!fr && strcmp(PathFindExtensionA(header->path), ".dds") == 0) {
		char png_path[MAX_PATH];
		strcpy(png_path, header->path);
		strcpy(PathFindExtensionA(png_path), ".png");
		register_filename(png_path);
		file_rep_t *fr_png = call_file_header(regs, bp_info, png_path);

		if (fr_png) {
			fr = file_rep_get(header->path);
			file_rep_clear(fr);
			memcpy(fr, fr_png, sizeof(*fr));
			memset(fr_png, 0, sizeof(*fr_png));
			file_rep_clear(fr_png);
			SAFE_FREE(fr->name);
			fr->name = EnsureUTF8(header->path, strlen(header->path) + 1);
		}
		else {
			fr = nullptr;
		}
	}

	if (fr) {
		header->hash = hash;
		memcpy(header->key, key, 4 * sizeof(DWORD));
		ICrypt::instance->convertKey(header->key);
		fr->object = header;
	}
	header->fr = fr;

	return 1;
}
int BP_th135_file_name(x86_reg_t *regs, json_t *bp_info)
{
	// Parameters
	// ----------
	const char *filename = (const char*)json_object_get_immediate(bp_info, regs, "file_name");
	// ----------

	if (filename) {
		register_filename(filename);
	}
	return 1;
}

static void post_read(const file_rep_t *fr, BYTE *buffer, size_t size)
{
	const FileHeader *header = (const FileHeader*)fr->object;
	if (header) {
		ICrypt::instance->uncryptBlock(buffer, size, header->key);
	}
}

static void post_patch(const file_rep_t *fr, BYTE *buffer, size_t size)
{
	const FileHeader *header = (const FileHeader*)fr->object;
	if (header) {
		ICrypt::instance->cryptBlock(buffer, size, header->key);
	}
}

/**
  * Replace file, 3rd attempt - hopefully I won't have to write a 4th one.
  * This breakpoint takes care of patching the files.
  * It takes place in the game's file reader, right after it calls its ReadFile caller.
  * At this point, we have the game's file structure in ESI, and so the filename's hash - we can't
  * read the wrong file.
  * In th145, the game's file structure have the following fields:
  * void* vtable;
  * HANDLE hFile;
  * BYTE buffer[0x10000];
  * DWORD LastReadFileSize; // Last value returned in lpNumberOfBytesRead in ReadFile
  * DWORD Offset; // Offset for the reader. I don't know what happens to it when it's bigger than 0x10000
  * DWORD LastReadSize; // Last read size asked to the reader
  * DWORD unknown1;
  * DWORD FileSize;
  * DWORD FileNameHash;
  * DWORD unknown2;
  * DWORD XorOffset; // Offset used by the XOR function
  * DWORD Key[5]; // 32-bytes encryption key used for XORing. The 5th DWORD is a copy of the 1st DWORD.
  * DWORD Aux; // Contains the last DWORD read from the file. Used during XORing.
  * We use hFile (file_struct + 4), buffer (file_struct + 8) and FileNameHash (file_struct + 0x1001c).
  * All the other fields are listed for documentation.
  */
int BP_th135_read_file(x86_reg_t *regs, json_t *bp_info)
{
	// Parameters
	// ----------
	DWORD newHash = json_object_get_immediate(bp_info, regs, "hash");
	// ----------

	static DWORD hash = 0;

	if (newHash) {
		hash = newHash;
	}
	if (!hash) {
		return 1;
	}

	struct FileHeader *header = hash_to_file_header(hash);
	if (!header || !header->fr || (!header->fr->rep_buffer && !header->fr->patch)) {
		// Nothing to patch.
		return 1;
	}

	json_t *new_bp_info = json_copy(bp_info);
	json_object_set_new(new_bp_info, "file_name",  json_integer((json_int_t)header->fr->name));
	json_object_set_new(new_bp_info, "post_read",  json_integer((json_int_t)post_read));
	json_object_set_new(new_bp_info, "post_patch", json_integer((json_int_t)post_patch));
	int ret = BP_fragmented_read_file(regs, new_bp_info);
	json_decref(new_bp_info);
	return ret;
}
<|endoftext|>


<commit_before>#include "RDom.h"
#include "Util.h"
#include "IROperator.h"
#include "IRPrinter.h"

namespace Halide {

using namespace Internal;

using std::string;
using std::vector;

RVar::operator Expr() const {
    if (!min().defined() || !extent().defined()) {
        user_error << "Use of undefined RDom dimension: " <<
            (name().empty() ? "<unknown>" : name()) << "\n";
    }
    return Variable::make(Int(32), name(), domain());
}

Expr RVar::min() const {
    if (_domain.defined()) {
        return _var().min;
    } else {
        return Expr();
    }
}

Expr RVar::extent() const {
    if (_domain.defined()) {
        return _var().extent;
    } else {
        return Expr();
    }
}

const std::string &RVar::name() const {
    if (_domain.defined()) {
        return _var().var;
    } else {
        return _name;
    }
}

template <int N>
ReductionDomain build_domain(ReductionVariable (&vars)[N]) {
    vector<ReductionVariable> d(&vars[0], &vars[N]);
    ReductionDomain dom(d);
    return dom;
}

// This just initializes the predefined x, y, z, w members of RDom.
void RDom::init_vars(string name) {
    static string var_names[] = { "x", "y", "z", "w" };

    const std::vector<ReductionVariable> &dom_vars = dom.domain();
    RVar *vars[] = { &x, &y, &z, &w };

    for (size_t i = 0; i < sizeof(vars)/sizeof(vars[0]); i++) {
        if (i < dom_vars.size()) {
            *(vars[i]) = RVar(dom, i);
        } else {
            *(vars[i]) = RVar(name + "." + var_names[i]);
        }
    }
}

RDom::RDom(ReductionDomain d) : dom(d) {
    if (d.defined()) {
        init_vars("");
    }
}

namespace {
class CheckRDomBounds : public IRGraphVisitor {

    using IRGraphVisitor::visit;

    void visit(const Call *op) {
        IRGraphVisitor::visit(op);
        if (op->call_type == Call::Halide) {
            offending_func = op->name;
        }
    }

    void visit(const Variable *op) {
        if (!op->param.defined() && !op->image.defined()) {
            offending_free_var = op->name;
        }
    }
public:
    string offending_func;
    string offending_free_var;
};
}

void RDom::initialize_from_ranges(const std::vector<std::pair<Expr, Expr>> &ranges, string name) {
    if (name.empty()) {
        name = make_entity_name(this, "Halide::RDom", 'r');
    }

    std::vector<ReductionVariable> vars;
    for (size_t i = 0; i < ranges.size(); i++) {
        CheckRDomBounds checker;
        ranges[i].first.accept(&checker);
        ranges[i].second.accept(&checker);
        user_assert(checker.offending_func.empty())
            << "The bounds of the RDom " << name
            << " in dimension " << i
            << " are:\n"
            << "  " << ranges[i].first << " ... " << ranges[i].second << "\n"
            << "These depend on a call to the Func " << checker.offending_func << ".\n"
            << "The bounds of an RDom may not depend on a call to a Func.\n";
        user_assert(checker.offending_free_var.empty())
            << "The bounds of the RDom " << name
            << " in dimension " << i
            << " are:\n"
            << "  " << ranges[i].first << " ... " << ranges[i].second << "\n"
            << "These depend on the variable " << checker.offending_free_var << ".\n"
            << "The bounds of an RDom may not depend on a free variable.\n";

        std::string rvar_uniquifier;
        switch (i) {
            case 0: rvar_uniquifier = "x"; break;
            case 1: rvar_uniquifier = "y"; break;
            case 2: rvar_uniquifier = "z"; break;
            case 3: rvar_uniquifier = "w"; break;
            default: rvar_uniquifier = std::to_string(i); break;
        }
        ReductionVariable rv;
        rv.var = name + "." + rvar_uniquifier + "$r";
        rv.min = cast<int32_t>(ranges[i].first);
        rv.extent = cast<int32_t>(ranges[i].second);
        vars.push_back(rv);
    }
    dom = ReductionDomain(vars);
    init_vars(name);
}

RDom::RDom(Buffer b) {
    static string var_names[] = {"x$r", "y$r", "z$r", "w$r"};
    std::vector<ReductionVariable> vars;
    for (int i = 0; i < b.dimensions(); i++) {
        ReductionVariable var = {
            b.name() + "." + var_names[i],
            b.min(i),
            b.extent(i)
        };
        vars.push_back(var);
    }

    dom = ReductionDomain(vars);
    init_vars(b.name());
}

RDom::RDom(ImageParam p) {
    static string var_names[] = {"x$r", "y$r", "z$r", "w$r"};
    std::vector<ReductionVariable> vars;
    for (int i = 0; i < p.dimensions(); i++) {
        ReductionVariable var = {
            p.name() + "." + var_names[i],
            p.min(i),
            p.extent(i)
        };
        vars.push_back(var);
    }

    dom = ReductionDomain(vars);
    init_vars(p.name());
}

int RDom::dimensions() const {
    return (int)dom.domain().size();
}

RVar RDom::operator[](int i) const {
    if (i == 0) return x;
    if (i == 1) return y;
    if (i == 2) return z;
    if (i == 3) return w;
    if (i < dimensions()) {
        return RVar(dom, i);
    }
    user_error << "Reduction domain index out of bounds: " << i << "\n";
    return x; // Keep the compiler happy
}

RDom::operator Expr() const {
    if (dimensions() != 1) {
        user_error << "Error: Can't treat this multidimensional RDom as an Expr:\n"
                   << (*this) << "\n"
                   << "Only single-dimensional RDoms can be cast to Expr.\n";
    }
    return Expr(x);
}

RDom::operator RVar() const {
    if (dimensions() != 1) {
        user_error << "Error: Can't treat this multidimensional RDom as an RVar:\n"
                   << (*this) << "\n"
                   << "Only single-dimensional RDoms can be cast to RVar.\n";
    }
    return x;
}

void RDom::where(Expr predicate) {
    user_assert(!dom.frozen())
        << (*this) << " cannot be given a new predicate, because it has already"
        << " been used in the update definition of some function.\n";
    if (!dom.defined()) {
        user_error << "Error: Can't add predicate to undefined RDom.\n";
    }
    dom.where(predicate);
}

/** Emit an RVar in a human-readable form */
std::ostream &operator<<(std::ostream &stream, RVar v) {
    stream << v.name() << "(" << v.min() << ", " << v.extent() << ")";
    return stream;
}

/** Emit an RDom in a human-readable form. */
std::ostream &operator<<(std::ostream &stream, RDom dom) {
    stream << "RDom(\n";
    for (int i = 0; i < dom.dimensions(); i++) {
        stream << "  " << dom[i] << "\n";
    }
    stream << ")";
    const auto &predicates = dom.domain().predicates();
    if (!predicates.empty()) {
        stream << " where (\n";
        for (const auto &pred : predicates) {
            stream << "  " << pred << "\n";
        }
        stream << ")";
    }
    stream << "\n";
    return stream;
}

}
<commit_msg>fixed assert msg in RDom<commit_after>#include "RDom.h"
#include "Util.h"
#include "IROperator.h"
#include "IRPrinter.h"

namespace Halide {

using namespace Internal;

using std::string;
using std::vector;

RVar::operator Expr() const {
    if (!min().defined() || !extent().defined()) {
        user_error << "Use of undefined RDom dimension: " <<
            (name().empty() ? "<unknown>" : name()) << "\n";
    }
    return Variable::make(Int(32), name(), domain());
}

Expr RVar::min() const {
    if (_domain.defined()) {
        return _var().min;
    } else {
        return Expr();
    }
}

Expr RVar::extent() const {
    if (_domain.defined()) {
        return _var().extent;
    } else {
        return Expr();
    }
}

const std::string &RVar::name() const {
    if (_domain.defined()) {
        return _var().var;
    } else {
        return _name;
    }
}

template <int N>
ReductionDomain build_domain(ReductionVariable (&vars)[N]) {
    vector<ReductionVariable> d(&vars[0], &vars[N]);
    ReductionDomain dom(d);
    return dom;
}

// This just initializes the predefined x, y, z, w members of RDom.
void RDom::init_vars(string name) {
    static string var_names[] = { "x", "y", "z", "w" };

    const std::vector<ReductionVariable> &dom_vars = dom.domain();
    RVar *vars[] = { &x, &y, &z, &w };

    for (size_t i = 0; i < sizeof(vars)/sizeof(vars[0]); i++) {
        if (i < dom_vars.size()) {
            *(vars[i]) = RVar(dom, i);
        } else {
            *(vars[i]) = RVar(name + "." + var_names[i]);
        }
    }
}

RDom::RDom(ReductionDomain d) : dom(d) {
    if (d.defined()) {
        init_vars("");
    }
}

namespace {
class CheckRDomBounds : public IRGraphVisitor {

    using IRGraphVisitor::visit;

    void visit(const Call *op) {
        IRGraphVisitor::visit(op);
        if (op->call_type == Call::Halide) {
            offending_func = op->name;
        }
    }

    void visit(const Variable *op) {
        if (!op->param.defined() && !op->image.defined()) {
            offending_free_var = op->name;
        }
    }
public:
    string offending_func;
    string offending_free_var;
};
}

void RDom::initialize_from_ranges(const std::vector<std::pair<Expr, Expr>> &ranges, string name) {
    if (name.empty()) {
        name = make_entity_name(this, "Halide::RDom", 'r');
    }

    std::vector<ReductionVariable> vars;
    for (size_t i = 0; i < ranges.size(); i++) {
        CheckRDomBounds checker;
        ranges[i].first.accept(&checker);
        ranges[i].second.accept(&checker);
        user_assert(checker.offending_func.empty())
            << "The bounds of the RDom " << name
            << " in dimension " << i
            << " are:\n"
            << "  " << ranges[i].first << " ... " << ranges[i].second << "\n"
            << "These depend on a call to the Func " << checker.offending_func << ".\n"
            << "The bounds of an RDom may not depend on a call to a Func.\n";
        user_assert(checker.offending_free_var.empty())
            << "The bounds of the RDom " << name
            << " in dimension " << i
            << " are:\n"
            << "  " << ranges[i].first << " ... " << ranges[i].second << "\n"
            << "These depend on the variable " << checker.offending_free_var << ".\n"
            << "The bounds of an RDom may not depend on a free variable.\n";

        std::string rvar_uniquifier;
        switch (i) {
            case 0: rvar_uniquifier = "x"; break;
            case 1: rvar_uniquifier = "y"; break;
            case 2: rvar_uniquifier = "z"; break;
            case 3: rvar_uniquifier = "w"; break;
            default: rvar_uniquifier = std::to_string(i); break;
        }
        ReductionVariable rv;
        rv.var = name + "." + rvar_uniquifier + "$r";
        rv.min = cast<int32_t>(ranges[i].first);
        rv.extent = cast<int32_t>(ranges[i].second);
        vars.push_back(rv);
    }
    dom = ReductionDomain(vars);
    init_vars(name);
}

RDom::RDom(Buffer b) {
    static string var_names[] = {"x$r", "y$r", "z$r", "w$r"};
    std::vector<ReductionVariable> vars;
    for (int i = 0; i < b.dimensions(); i++) {
        ReductionVariable var = {
            b.name() + "." + var_names[i],
            b.min(i),
            b.extent(i)
        };
        vars.push_back(var);
    }

    dom = ReductionDomain(vars);
    init_vars(b.name());
}

RDom::RDom(ImageParam p) {
    static string var_names[] = {"x$r", "y$r", "z$r", "w$r"};
    std::vector<ReductionVariable> vars;
    for (int i = 0; i < p.dimensions(); i++) {
        ReductionVariable var = {
            p.name() + "." + var_names[i],
            p.min(i),
            p.extent(i)
        };
        vars.push_back(var);
    }

    dom = ReductionDomain(vars);
    init_vars(p.name());
}

int RDom::dimensions() const {
    return (int)dom.domain().size();
}

RVar RDom::operator[](int i) const {
    if (i == 0) return x;
    if (i == 1) return y;
    if (i == 2) return z;
    if (i == 3) return w;
    if (i < dimensions()) {
        return RVar(dom, i);
    }
    user_error << "Reduction domain index out of bounds: " << i << "\n";
    return x; // Keep the compiler happy
}

RDom::operator Expr() const {
    if (dimensions() != 1) {
        user_error << "Error: Can't treat this multidimensional RDom as an Expr:\n"
                   << (*this) << "\n"
                   << "Only single-dimensional RDoms can be cast to Expr.\n";
    }
    return Expr(x);
}

RDom::operator RVar() const {
    if (dimensions() != 1) {
        user_error << "Error: Can't treat this multidimensional RDom as an RVar:\n"
                   << (*this) << "\n"
                   << "Only single-dimensional RDoms can be cast to RVar.\n";
    }
    return x;
}

void RDom::where(Expr predicate) {
    user_assert(!dom.frozen())
        << (*this) << " cannot be given a new predicate, because it has already"
        << " been used in the update definition of some function.\n";
    user_assert(dom.defined()) << "Error: Can't add predicate to undefined RDom.\n"
    dom.where(predicate);
}

/** Emit an RVar in a human-readable form */
std::ostream &operator<<(std::ostream &stream, RVar v) {
    stream << v.name() << "(" << v.min() << ", " << v.extent() << ")";
    return stream;
}

/** Emit an RDom in a human-readable form. */
std::ostream &operator<<(std::ostream &stream, RDom dom) {
    stream << "RDom(\n";
    for (int i = 0; i < dom.dimensions(); i++) {
        stream << "  " << dom[i] << "\n";
    }
    stream << ")";
    const auto &predicates = dom.domain().predicates();
    if (!predicates.empty()) {
        stream << " where (\n";
        for (const auto &pred : predicates) {
            stream << "  " << pred << "\n";
        }
        stream << ")";
    }
    stream << "\n";
    return stream;
}

}
<|endoftext|>


<commit_before>// This file is part of the dune-gdt project:
//   http://users.dune-project.org/projects/dune-gdt
// Copyright holders: Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_GDT_SPACES_DG_HH
#define DUNE_GDT_SPACES_DG_HH

#include <memory>

#if HAVE_DUNE_GRID_MULTISCALE
# include <dune/grid/multiscale/provider/interface.hh>
#endif

#include <dune/stuff/common/type_utils.hh>
#include <dune/stuff/grid/layers.hh>
#include <dune/stuff/grid/provider/interface.hh>

#include "interface.hh"
#include "../playground/spaces/dg/fem.hh"
#include "../playground/spaces/dg/pdelab.hh"

namespace Dune {
namespace GDT {
namespace Spaces {

template< class GridType, Stuff::Grid::ChooseLayer layer_type, ChooseSpaceBackend backend_type,
          int polOrder, class RangeFieldType, int dimRange, int dimRangeCols = 1 >
class DiscontinuousLagrangeProvider
{
  static const Stuff::Grid::ChoosePartView part_view_type = ChooseGridPartView< backend_type >::type;
public:
  typedef typename Stuff::Grid::Layer< GridType, layer_type, part_view_type >::Type GridLayerType;

private:
  template< class G, int p, class R, int r, int rC, GDT::ChooseSpaceBackend b >
  struct SpaceChooser
  {
    static_assert(AlwaysFalse< G >::value, "No space available for this backend!");
  };

  template< class G, int p, class R, int r, int rC >
  struct SpaceChooser< G, p, R, r, rC, GDT::ChooseSpaceBackend::fem >
  {
    typedef GDT::Spaces::DG::FemBased< GridLayerType, p, R, r > Type;
  };

  template< class G, int p, class R, int r, int rC >
  struct SpaceChooser< G, p, R, r, rC, GDT::ChooseSpaceBackend::pdelab >
  {
    typedef GDT::Spaces::DG::PdelabBased< GridLayerType, p, R, r > Type;
  };

  typedef Stuff::Grid::ProviderInterface< GridType > GridProviderType;
#if HAVE_DUNE_GRID_MULTISCALE
  typedef grid::Multiscale::ProviderInterface< GridType > MsGridProviderType;
#endif

public:
  typedef typename SpaceChooser< GridType, polOrder, RangeFieldType, dimRange, dimRangeCols, backend_type >::Type Type;

  static Type create(GridLayerType grid_layer)
  {
    return Type(grid_layer);
  }

  static Type create(GridProviderType& grid_provider, const int level = 0)
  {
    return Type(grid_provider.template layer< layer_type, part_view_type >(level));
  }

#if HAVE_DUNE_GRID_MULTISCALE
  static Type create(const MsGridProviderType& grid_provider, const int level_or_subdomain = 0)
  {
    return Type(grid_provider.template layer< layer_type, part_view_type >(level_or_subdomain));
  }
#endif // HAVE_DUNE_GRID_MULTISCALE
}; // class DiscontinuousLagrangeProvider

} // namespace Spaces
} // namespace GDT
} // namespace Dune

#endif // DUNE_GDT_SPACES_DG_HH
<commit_msg>[spaces.dg] rename DiscontinuousLagrangeProvider -> DGProvider<commit_after>// This file is part of the dune-gdt project:
//   http://users.dune-project.org/projects/dune-gdt
// Copyright holders: Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_GDT_SPACES_DG_HH
#define DUNE_GDT_SPACES_DG_HH

#include <memory>

#include <dune/common/deprecated.hh>

#if HAVE_DUNE_GRID_MULTISCALE
# include <dune/grid/multiscale/provider/interface.hh>
#endif

#include <dune/stuff/common/type_utils.hh>
#include <dune/stuff/grid/layers.hh>
#include <dune/stuff/grid/provider/interface.hh>

#include "interface.hh"
#include "../playground/spaces/dg/fem.hh"
#include "../playground/spaces/dg/pdelab.hh"

namespace Dune {
namespace GDT {
namespace Spaces {

template< class GridType, Stuff::Grid::ChooseLayer layer_type, ChooseSpaceBackend backend_type,
          int polOrder, class RangeFieldType, int dimRange, int dimRangeCols = 1 >
class DGProvider
{
  static const Stuff::Grid::ChoosePartView part_view_type = ChooseGridPartView< backend_type >::type;
public:
  typedef typename Stuff::Grid::Layer< GridType, layer_type, part_view_type >::Type GridLayerType;

private:
  template< class G, int p, class R, int r, int rC, GDT::ChooseSpaceBackend b >
  struct SpaceChooser
  {
    static_assert(AlwaysFalse< G >::value, "No space available for this backend!");
  };

  template< class G, int p, class R, int r, int rC >
  struct SpaceChooser< G, p, R, r, rC, GDT::ChooseSpaceBackend::fem >
  {
    typedef GDT::Spaces::DG::FemBased< GridLayerType, p, R, r > Type;
  };

  template< class G, int p, class R, int r, int rC >
  struct SpaceChooser< G, p, R, r, rC, GDT::ChooseSpaceBackend::pdelab >
  {
    typedef GDT::Spaces::DG::PdelabBased< GridLayerType, p, R, r > Type;
  };

  typedef Stuff::Grid::ProviderInterface< GridType > GridProviderType;
#if HAVE_DUNE_GRID_MULTISCALE
  typedef grid::Multiscale::ProviderInterface< GridType > MsGridProviderType;
#endif

public:
  typedef typename SpaceChooser< GridType, polOrder, RangeFieldType, dimRange, dimRangeCols, backend_type >::Type Type;

  static Type create(GridLayerType grid_layer)
  {
    return Type(grid_layer);
  }

  static Type create(GridProviderType& grid_provider, const int level = 0)
  {
    return Type(grid_provider.template layer< layer_type, part_view_type >(level));
  }

#if HAVE_DUNE_GRID_MULTISCALE
  static Type create(const MsGridProviderType& grid_provider, const int level_or_subdomain = 0)
  {
    return Type(grid_provider.template layer< layer_type, part_view_type >(level_or_subdomain));
  }
#endif // HAVE_DUNE_GRID_MULTISCALE
}; // class DGProvider

template< class GridType, Stuff::Grid::ChooseLayer layer_type, ChooseSpaceBackend backend_type,
          int polOrder, class RangeFieldType, int dimRange, int dimRangeCols = 1 >
class
    DUNE_DEPRECATED_MSG("Use DGProvider instead (02.02.2015)!")
      DiscontinuousLagrangeProvider
  : public DGProvider< GridType, layer_type, backend_type, polOrder, RangeFieldType, dimRange, dimRangeCols >
{};

} // namespace Spaces
} // namespace GDT
} // namespace Dune

#endif // DUNE_GDT_SPACES_DG_HH
<|endoftext|>