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

#include "chrome/app/google_update_client.h"

#include <shlobj.h>
#include <strsafe.h>

#include "chrome/app/client_util.h"
#include "chrome/installer/util/google_update_constants.h"
#include "chrome/installer/util/install_util.h"

namespace {
const wchar_t kEnvProductVersionKey[] = L"CHROME_VERSION";

// Allocates the out param on success.
bool GoogleUpdateEnvQueryStr(const wchar_t* key_name, wchar_t** out) {
  DWORD count = ::GetEnvironmentVariableW(key_name, NULL, 0);
  if (!count) {
    return false;
  }
  wchar_t* value = new wchar_t[count + 1];
  if (!::GetEnvironmentVariableW(key_name, value, count)) {
    delete[] value;
    return false;
  }
  *out = value;
  return true;
}
}  // anonymous namespace

namespace google_update {

GoogleUpdateClient::GoogleUpdateClient() : version_(NULL) {
}

GoogleUpdateClient::~GoogleUpdateClient() {
  delete[] version_;
}

std::wstring GoogleUpdateClient::GetDLLPath() {
  return client_util::GetDLLPath(dll_, dll_path_);
}

const wchar_t* GoogleUpdateClient::GetVersion() const {
  return version_;
}

bool GoogleUpdateClient::Launch(HINSTANCE instance,
                                sandbox::SandboxInterfaceInfo* sandbox,
                                wchar_t* command_line,
                                int show_command,
                                const char* entry_name,
                                int* ret) {
  if (client_util::FileExists(dll_path_)) {
    ::SetCurrentDirectory(dll_path_);
    // Setting the version on the environment block is a 'best effort' deal.
    // It enables Google Update running on a child to load the same DLL version.
    ::SetEnvironmentVariableW(kEnvProductVersionKey, version_);
  }

  // The dll can be in the exe's directory or in the current directory.
  // Use the alternate search path to be sure that it's not trying to load it
  // calling application's directory.
  HINSTANCE dll_handle = ::LoadLibraryEx(dll_.c_str(), NULL,
                                         LOAD_WITH_ALTERED_SEARCH_PATH);
  if (NULL == dll_handle) {
    unsigned long err = GetLastError();
    if (err) {
      WCHAR message[500] = {0};
      FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, 0,
                    reinterpret_cast<LPWSTR>(&message), 500, NULL);
      ::OutputDebugStringW(message);
    }
    return false;
  }

  bool did_launch = false;
  client_util::DLL_MAIN entry = reinterpret_cast<client_util::DLL_MAIN>(
      ::GetProcAddress(dll_handle, entry_name));
  if (NULL != entry) {
    // record did_run "dr" in client state
    std::wstring key_path = google_update::kRegPathClientState + guid_;
    HKEY reg_key;
    if (::RegOpenKeyEx(HKEY_CURRENT_USER, key_path.c_str(), 0,
                       KEY_WRITE, &reg_key) == ERROR_SUCCESS) {
      const wchar_t kVal[] = L"1";
      ::RegSetValueEx(reg_key, google_update::kRegDidRunField, 0, REG_SZ,
                      reinterpret_cast<const BYTE *>(kVal), sizeof(kVal));
      ::RegCloseKey(reg_key);
    }

    int rc = (entry)(instance, sandbox, command_line, show_command);
    if (ret) {
      *ret = rc;
    }
    did_launch = true;
  }
#ifdef PURIFY
  // We should never unload the dll. There is only risk and no gain from
  // doing so. The singleton dtors have been already run by AtExitManager.
  ::FreeLibrary(dll_handle);
#endif
  return did_launch;
}

bool GoogleUpdateClient::Init(const wchar_t* client_guid,
                              const wchar_t* client_dll) {
  client_util::GetExecutablePath(dll_path_);
  guid_.assign(client_guid);
  dll_.assign(client_dll);
  bool ret = false;
  if (!guid_.empty()) {
    if (GoogleUpdateEnvQueryStr(kEnvProductVersionKey, &version_)) {
      ret = true;
    } else {
      std::wstring key(google_update::kRegPathClients);
      key.append(guid_);
      if (client_util::GetChromiumVersion(dll_path_, key.c_str(), &version_))
        ret = true;
    }
  }

  if (version_) {
    ::StringCchCat(dll_path_, MAX_PATH, version_);
  }
  return ret;
}
}  // namespace google_update

<commit_msg>Fix Chrome do not launch problem.<commit_after>// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/app/google_update_client.h"

#include <shlobj.h>
#include <strsafe.h>

#include "chrome/app/client_util.h"
#include "chrome/installer/util/google_update_constants.h"
#include "chrome/installer/util/install_util.h"

namespace {
const wchar_t kEnvProductVersionKey[] = L"CHROME_VERSION";

// Allocates the out param on success.
bool GoogleUpdateEnvQueryStr(const wchar_t* key_name, wchar_t** out) {
  DWORD count = ::GetEnvironmentVariableW(key_name, NULL, 0);
  if (!count) {
    return false;
  }
  wchar_t* value = new wchar_t[count + 1];
  if (!::GetEnvironmentVariableW(key_name, value, count)) {
    delete[] value;
    return false;
  }
  *out = value;
  return true;
}
}  // anonymous namespace

namespace google_update {

GoogleUpdateClient::GoogleUpdateClient() : version_(NULL) {
}

GoogleUpdateClient::~GoogleUpdateClient() {
  delete[] version_;
}

std::wstring GoogleUpdateClient::GetDLLPath() {
  return client_util::GetDLLPath(dll_, dll_path_);
}

const wchar_t* GoogleUpdateClient::GetVersion() const {
  return version_;
}

bool GoogleUpdateClient::Launch(HINSTANCE instance,
                                sandbox::SandboxInterfaceInfo* sandbox,
                                wchar_t* command_line,
                                int show_command,
                                const char* entry_name,
                                int* ret) {
  if (client_util::FileExists(dll_path_)) {
    ::SetCurrentDirectory(dll_path_);
    // Setting the version on the environment block is a 'best effort' deal.
    // It enables Google Update running on a child to load the same DLL version.
    ::SetEnvironmentVariableW(kEnvProductVersionKey, version_);
  }

  // The dll can be in the exe's directory or in the current directory.
  // Use the alternate search path to be sure that it's not trying to load it
  // calling application's directory.
  HINSTANCE dll_handle = ::LoadLibraryEx(dll_.c_str(), NULL,
                                         LOAD_WITH_ALTERED_SEARCH_PATH);
  if (NULL == dll_handle) {
    unsigned long err = GetLastError();
    if (err) {
      WCHAR message[500] = {0};
      FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, 0,
                    reinterpret_cast<LPWSTR>(&message), 500, NULL);
      ::OutputDebugStringW(message);
    }
    return false;
  }

  bool did_launch = false;
  client_util::DLL_MAIN entry = reinterpret_cast<client_util::DLL_MAIN>(
      ::GetProcAddress(dll_handle, entry_name));
  if (NULL != entry) {
    // record did_run "dr" in client state
    std::wstring key_path(google_update::kRegPathClientState);
    key_path.append(L"\\" + guid_);
    HKEY reg_key;
    if (::RegOpenKeyEx(HKEY_CURRENT_USER, key_path.c_str(), 0,
                       KEY_WRITE, &reg_key) == ERROR_SUCCESS) {
      const wchar_t kVal[] = L"1";
      ::RegSetValueEx(reg_key, google_update::kRegDidRunField, 0, REG_SZ,
                      reinterpret_cast<const BYTE *>(kVal), sizeof(kVal));
      ::RegCloseKey(reg_key);
    }

    int rc = (entry)(instance, sandbox, command_line, show_command);
    if (ret) {
      *ret = rc;
    }
    did_launch = true;
  }
#ifdef PURIFY
  // We should never unload the dll. There is only risk and no gain from
  // doing so. The singleton dtors have been already run by AtExitManager.
  ::FreeLibrary(dll_handle);
#endif
  return did_launch;
}

bool GoogleUpdateClient::Init(const wchar_t* client_guid,
                              const wchar_t* client_dll) {
  client_util::GetExecutablePath(dll_path_);
  guid_.assign(client_guid);
  dll_.assign(client_dll);
  bool ret = false;
  if (!guid_.empty()) {
    if (GoogleUpdateEnvQueryStr(kEnvProductVersionKey, &version_)) {
      ret = true;
    } else {
      std::wstring key(google_update::kRegPathClients);
      key.append(L"\\");
      key.append(guid_);
      if (client_util::GetChromiumVersion(dll_path_, key.c_str(), &version_))
        ret = true;
    }
  }

  if (version_) {
    ::StringCchCat(dll_path_, MAX_PATH, version_);
  }
  return ret;
}
}  // namespace google_update

<|endoftext|>


<commit_before>#include "common.h"
#include "HumanPlayerController.h"
#include "EventManager.h"
#include "InputManager.h"
#include "World.h"
#include "PositionComponent.h"
#include "OrientationComponent.h"
#include "PlayerCameraComponent.h"
#include "BoundingComponent.h"

void HumanPlayerController::InitObject() {
	PlayerController::InitObject();
	engine->AddComponent<PlayerCameraComponent>(object);
	auto camera = engine->GetComponent<PlayerCameraComponent>(object);
	/* player model is 1.7f in height ranging from -0.85f to 0.85f
	 * and 0.75f in width, ranging from -0.375f to 0.375f
	 * so to position the camera in the middle of the model's face
	 * we offset the camera on the y-axis by (0.85f - 0.375f)
	 */
	camera->position = Point3(0.0f, 0.85f - 0.375f, 0.0f);
	//camera->distance = Point3(0.0f, 0.0f, 4.0f);
}

void HumanPlayerController::Init() {
	PlayerController::Init();

	auto inputM = engine->systems.Get<InputManager>().lock();
	auto pos = engine->GetComponent<PositionComponent>(object);
	auto orient = engine->GetComponent<OrientationComponent>(object);
	auto camera = engine->GetComponent<PlayerCameraComponent>(object);

	dtors.emplace_back(inputM->On(Key::W, [this] (Key) { moveForward = true; }));
	dtors.emplace_back(inputM->On(Key::S, [this] (Key) { moveBackward = true; }));
	dtors.emplace_back(inputM->On(Key::A, [this] (Key) { moveLeft = true; }));
	dtors.emplace_back(inputM->On(Key::D, [this] (Key) { moveRight = true; }));
	dtors.emplace_back(inputM->After(Key::W, [this] (Key) { moveForward = false; }));
	dtors.emplace_back(inputM->After(Key::S, [this] (Key) { moveBackward = false; }));
	dtors.emplace_back(inputM->After(Key::A, [this] (Key) { moveLeft = false; }));
	dtors.emplace_back(inputM->After(Key::D, [this] (Key) { moveRight = false; }));

	dtors.emplace_back(inputM->On(Key::Space, [pos] (Key) {
		pos->position.Derivative()->y = 9.8f / 2;
	}));

	dtors.emplace_back(inputM->OnMouseMove([this] (const Point2 &delta) {
		orientVel.y += glm::radians(0.02f) * delta.x;
		orientVel.x += glm::radians(0.02f) * delta.y;
	}));

	/* reverse camera view */

	dtors.emplace_back(inputM->On(Key::Z, [this, camera] (Key) {
		rearView = true;
		camera->distance = Point3(0.0f, 0.0f, 4.0f);
	}));

	dtors.emplace_back(inputM->After(Key::Z, [this, camera] (Key) {
		rearView = false;
		camera->distance = Point3(0.0f, 0.0f, 0.0f);
	}));

	dtors.emplace_back(inputM->On(Key::E, [this, pos, orient, camera] (Key) {
		auto origin = pos->position.Get() + camera->position.Get();
		auto direction = Point3(glm::toMat3(orient->orientation * camera->orientation) * Point3(0.0f, 0.0f, 1.0f));
		direction.z = -direction.z;

		float entryTime = std::numeric_limits<float>::infinity();
		IDType soonestId = 0;
		Point3 soonestPos = Point3(0.0f);

		auto pair = engine->objects.right.equal_range(&typeid(BoundingComponent));
		for(auto it = pair.first; it != pair.second; ++it) {
			auto id = it->get_left();

			/* don't check against self */
			if(id == object) { continue; }

			auto objPos = engine->GetComponent<PositionComponent>(id);
			if(objPos != nullptr) {
				auto objBounds = engine->GetComponent<BoundingComponent>(id);
				if(objBounds != nullptr) {
					auto r = objBounds->box.TestRay(origin, direction, 8.0f, objPos->position.Get());
					if(std::get<0>(r) && std::get<1>(r) < entryTime) {
						std::tie(std::ignore, entryTime, soonestPos) = r;
						soonestId = id;
					}
				}
			}
		}

		if(soonestId != 0) {
			auto world = engine->systems.Get<World>().lock();
			world->SetBlock(world->BlockCoordForPos(soonestPos), false);
		}
	}));
}

void HumanPlayerController::Update(DeltaTicks &dt) {
	PlayerController::Update(dt);

	auto orient = engine->GetComponent<OrientationComponent>(object);
	auto camera = engine->GetComponent<PlayerCameraComponent>(object);

	orientRot += orientVel;
	orientVel *= 1 - 12 * dt.Seconds();

	/* scale to range of -360 to 360 degrees */
	const float r360 = glm::radians(360.0f);
	if(orientRot.x >  r360) { orientRot.x -= r360; }
	if(orientRot.x < -r360) { orientRot.x += r360; }
	if(orientRot.y >  r360) { orientRot.y -= r360; }
	if(orientRot.y < -r360) { orientRot.y += r360; }

	/* clamp x to range of -viewingAngle to viewingAngle */
	const float viewingAngle = glm::radians(90.0f);
	if(orientRot.x >  viewingAngle) { orientRot.x = viewingAngle; }
	if(orientRot.x < -viewingAngle) { orientRot.x = -viewingAngle; }

	const float r180 = glm::radians(180.0f);
	orient->orientation = glm::quat(Point3(0.0f, orientRot.y, 0.0f));
	camera->orientation = glm::quat(Point3(orientRot.x, rearView ? r180 : 0.0f, 0.0f));

	/* walking head bobbing */

	const float bobInterval = 0.4f;
	const float bobHalfFreq = r180 / bobInterval;
	const float bobDropAngle = glm::radians(0.9f);
	const float bobRollAngle = glm::radians(0.2f);
	static float bobCounter = 0.0f;

	/* increment if moving */
	if(moveForward | moveBackward | moveLeft | moveRight) {
		bobCounter += dt.Seconds() * bobHalfFreq;
	}
	/* increment until center if not centered */
	else if(bobCounter != 0.0f) {
		/* calculate new counter value and scale to range of 0 to 360 degrees */
		auto newCounter = bobCounter + dt.Seconds() * bobHalfFreq;
		if(newCounter >= r360) { newCounter -= r360; }

		/* if scaled new counter is no longer greater than old counter */
		if(newCounter <= bobCounter) { newCounter = 0.0f; }
		bobCounter = newCounter;
	}

	/* scale to range of 0 to 360 degrees */
	if(bobCounter >= r360) { bobCounter -= r360; }

	float bobDrop = glm::cos(bobCounter);
	float bobRoll = glm::sin(bobCounter);

	camera->orientation = glm::quat(Point3(-glm::abs(bobDrop) * bobDropAngle, 0.0f, 0.0f)) * camera->orientation;
	camera->orientation = glm::quat(Point3(0.0f, 0.0f, glm::clamp(bobRoll * bobRollAngle * 1.25f, -bobRollAngle, bobRollAngle))) * camera->orientation;
}
<commit_msg>Add comments<commit_after>#include "common.h"
#include "HumanPlayerController.h"
#include "EventManager.h"
#include "InputManager.h"
#include "World.h"
#include "PositionComponent.h"
#include "OrientationComponent.h"
#include "PlayerCameraComponent.h"
#include "BoundingComponent.h"

void HumanPlayerController::InitObject() {
	PlayerController::InitObject();
	engine->AddComponent<PlayerCameraComponent>(object);
	auto camera = engine->GetComponent<PlayerCameraComponent>(object);
	/* player model is 1.7f in height ranging from -0.85f to 0.85f
	 * and 0.75f in width, ranging from -0.375f to 0.375f
	 * so to position the camera in the middle of the model's face
	 * we offset the camera on the y-axis by (0.85f - 0.375f)
	 */
	camera->position = Point3(0.0f, 0.85f - 0.375f, 0.0f);
	//camera->distance = Point3(0.0f, 0.0f, 4.0f);
}

void HumanPlayerController::Init() {
	PlayerController::Init();

	auto inputM = engine->systems.Get<InputManager>().lock();
	auto pos = engine->GetComponent<PositionComponent>(object);
	auto orient = engine->GetComponent<OrientationComponent>(object);
	auto camera = engine->GetComponent<PlayerCameraComponent>(object);

	/* movement */
	dtors.emplace_back(inputM->On(Key::W, [this] (Key) { moveForward = true; }));
	dtors.emplace_back(inputM->On(Key::S, [this] (Key) { moveBackward = true; }));
	dtors.emplace_back(inputM->On(Key::A, [this] (Key) { moveLeft = true; }));
	dtors.emplace_back(inputM->On(Key::D, [this] (Key) { moveRight = true; }));
	dtors.emplace_back(inputM->After(Key::W, [this] (Key) { moveForward = false; }));
	dtors.emplace_back(inputM->After(Key::S, [this] (Key) { moveBackward = false; }));
	dtors.emplace_back(inputM->After(Key::A, [this] (Key) { moveLeft = false; }));
	dtors.emplace_back(inputM->After(Key::D, [this] (Key) { moveRight = false; }));

	/* jump */
	dtors.emplace_back(inputM->On(Key::Space, [pos] (Key) {
		pos->position.Derivative()->y = 9.8f / 2;
	}));

	/* mouse look */
	dtors.emplace_back(inputM->OnMouseMove([this] (const Point2 &delta) {
		orientVel.y += glm::radians(0.02f) * delta.x;
		orientVel.x += glm::radians(0.02f) * delta.y;
	}));

	/* reverse camera view */
	dtors.emplace_back(inputM->On(Key::Z, [this, camera] (Key) {
		rearView = true;
		camera->distance = Point3(0.0f, 0.0f, 4.0f);
	}));
	dtors.emplace_back(inputM->After(Key::Z, [this, camera] (Key) {
		rearView = false;
		camera->distance = Point3(0.0f, 0.0f, 0.0f);
	}));

	/* destroy block */
	dtors.emplace_back(inputM->On(Key::E, [this, pos, orient, camera] (Key) {
		auto origin = pos->position.Get() + camera->position.Get();
		auto direction = Point3(glm::toMat3(orient->orientation * camera->orientation) * Point3(0.0f, 0.0f, 1.0f));
		direction.z = -direction.z;

		float entryTime = std::numeric_limits<float>::infinity();
		IDType soonestId = 0;
		Point3 soonestPos = Point3(0.0f);

		auto pair = engine->objects.right.equal_range(&typeid(BoundingComponent));
		for(auto it = pair.first; it != pair.second; ++it) {
			auto id = it->get_left();

			/* don't check against self */
			if(id == object) { continue; }

			auto objPos = engine->GetComponent<PositionComponent>(id);
			if(objPos != nullptr) {
				auto objBounds = engine->GetComponent<BoundingComponent>(id);
				if(objBounds != nullptr) {
					auto r = objBounds->box.TestRay(origin, direction, 8.0f, objPos->position.Get());
					if(std::get<0>(r) && std::get<1>(r) < entryTime) {
						std::tie(std::ignore, entryTime, soonestPos) = r;
						soonestId = id;
					}
				}
			}
		}

		if(soonestId != 0) {
			auto world = engine->systems.Get<World>().lock();
			world->SetBlock(world->BlockCoordForPos(soonestPos), false);
		}
	}));
}

void HumanPlayerController::Update(DeltaTicks &dt) {
	PlayerController::Update(dt);

	auto orient = engine->GetComponent<OrientationComponent>(object);
	auto camera = engine->GetComponent<PlayerCameraComponent>(object);

	orientRot += orientVel;
	orientVel *= 1 - 12 * dt.Seconds();

	/* scale to range of -360 to 360 degrees */
	const float r360 = glm::radians(360.0f);
	if(orientRot.x >  r360) { orientRot.x -= r360; }
	if(orientRot.x < -r360) { orientRot.x += r360; }
	if(orientRot.y >  r360) { orientRot.y -= r360; }
	if(orientRot.y < -r360) { orientRot.y += r360; }

	/* clamp x to range of -viewingAngle to viewingAngle */
	const float viewingAngle = glm::radians(90.0f);
	if(orientRot.x >  viewingAngle) { orientRot.x = viewingAngle; }
	if(orientRot.x < -viewingAngle) { orientRot.x = -viewingAngle; }

	const float r180 = glm::radians(180.0f);
	orient->orientation = glm::quat(Point3(0.0f, orientRot.y, 0.0f));
	camera->orientation = glm::quat(Point3(orientRot.x, rearView ? r180 : 0.0f, 0.0f));

	/* walking head bobbing */

	const float bobInterval = 0.4f;
	const float bobHalfFreq = r180 / bobInterval;
	const float bobDropAngle = glm::radians(0.9f);
	const float bobRollAngle = glm::radians(0.2f);
	static float bobCounter = 0.0f;

	/* increment if moving */
	if(moveForward | moveBackward | moveLeft | moveRight) {
		bobCounter += dt.Seconds() * bobHalfFreq;
	}
	/* increment until center if not centered */
	else if(bobCounter != 0.0f) {
		/* calculate new counter value and scale to range of 0 to 360 degrees */
		auto newCounter = bobCounter + dt.Seconds() * bobHalfFreq;
		if(newCounter >= r360) { newCounter -= r360; }

		/* if scaled new counter is no longer greater than old counter */
		if(newCounter <= bobCounter) { newCounter = 0.0f; }
		bobCounter = newCounter;
	}

	/* scale to range of 0 to 360 degrees */
	if(bobCounter >= r360) { bobCounter -= r360; }

	float bobDrop = glm::cos(bobCounter);
	float bobRoll = glm::sin(bobCounter);

	camera->orientation = glm::quat(Point3(-glm::abs(bobDrop) * bobDropAngle, 0.0f, 0.0f)) * camera->orientation;
	camera->orientation = glm::quat(Point3(0.0f, 0.0f, glm::clamp(bobRoll * bobRollAngle * 1.25f, -bobRollAngle, bobRollAngle))) * camera->orientation;
}
<|endoftext|>


<commit_before>// Copyright (c) 2010 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/plugin_installer.h"

#include "base/string_util.h"
#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "grit/generated_resources.h"
#include "grit/locale_settings.h"
#include "grit/theme_resources.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
#include "webkit/plugins/npapi/default_plugin_shared.h"

// The URL for the "Problems installing" page for the Plugins infobar.
static const char kLearnMorePluginInstallerUrl[] =
    "http://www.google.com/support/chrome/bin/answer.py?answer=95697&topic=14687";

PluginInstaller::PluginInstaller(TabContents* tab_contents)
    : ConfirmInfoBarDelegate(tab_contents),
      tab_contents_(tab_contents) {
}

PluginInstaller::~PluginInstaller() {
  // Remove any InfoBars we may be showing.
  tab_contents_->RemoveInfoBar(this);
}

void PluginInstaller::OnMissingPluginStatus(int status) {
  switch (status) {
    case webkit::npapi::default_plugin::MISSING_PLUGIN_AVAILABLE: {
      tab_contents_->AddInfoBar(this);
      break;
    }
    case webkit::npapi::default_plugin::MISSING_PLUGIN_USER_STARTED_DOWNLOAD: {
      // Hide the InfoBar if user already started download/install of the
      // missing plugin.
      tab_contents_->RemoveInfoBar(this);
      break;
    }
    default: {
      NOTREACHED();
      break;
    }
  }
}

string16 PluginInstaller::GetMessageText() const {
  return l10n_util::GetStringUTF16(IDS_PLUGININSTALLER_MISSINGPLUGIN_PROMPT);
}

SkBitmap* PluginInstaller::GetIcon() const {
  return ResourceBundle::GetSharedInstance().GetBitmapNamed(
      IDR_INFOBAR_PLUGIN_INSTALL);
}

int PluginInstaller::GetButtons() const {
  return BUTTON_OK;
}

string16 PluginInstaller::GetButtonLabel(InfoBarButton button) const {
  if (button == BUTTON_OK)
    return l10n_util::GetStringUTF16(IDS_PLUGININSTALLER_INSTALLPLUGIN_BUTTON);
  return ConfirmInfoBarDelegate::GetButtonLabel(button);
}

bool PluginInstaller::Accept() {
  tab_contents_->render_view_host()->InstallMissingPlugin();
  return true;
}

string16 PluginInstaller::GetLinkText() {
  return l10n_util::GetStringUTF16(IDS_PLUGININSTALLER_PROBLEMSINSTALLING);
}

bool PluginInstaller::LinkClicked(WindowOpenDisposition disposition) {
  // Ignore the click dispostion and always open in a new top level tab.
  tab_contents_->OpenURL(GURL(kLearnMorePluginInstallerUrl), GURL(),
                         NEW_FOREGROUND_TAB, PageTransition::LINK);
  return false;  // Do not dismiss the info bar.
}
<commit_msg>Re-delete this file that was erroneously re-added in r72227.<commit_after><|endoftext|>


<commit_before><commit_msg>planning: minor change on CREEP obstacle id<commit_after><|endoftext|>


<commit_before>// Copyright (c) 2010 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.

// Tests for the top plugins to catch regressions in our plugin host code, as
// well as in the out of process code.  Currently this tests:
//  Flash
//  Real
//  QuickTime
//  Windows Media Player
//    -this includes both WMP plugins.  npdsplay.dll is the older one that
//     comes with XP.  np-mswmp.dll can be downloaded from Microsoft and
//     needs SP2 or Vista.

#include "build/build_config.h"

#if defined(OS_WIN)
#include <windows.h>
#include <shellapi.h>
#include <shlobj.h>
#include <comutil.h>
#endif

#include <stdlib.h>
#include <string.h>
#include <memory.h>

#include <string>

#include "base/file_path.h"
#include "base/file_util.h"
#include "base/path_service.h"
#include "chrome/browser/net/url_request_mock_http_job.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/test/automation/tab_proxy.h"
#include "chrome/test/ui/ui_test.h"
#include "net/base/net_util.h"
#include "third_party/npapi/bindings/npapi.h"
#include "webkit/glue/plugins/plugin_constants_win.h"
#include "webkit/glue/plugins/plugin_list.h"

#if defined(OS_WIN)
#include "base/registry.h"
// TODO(port) ?
#include "webkit/default_plugin/plugin_impl.h"
#endif

class PluginTest : public UITest {
 protected:
#if defined(OS_WIN)
  virtual void SetUp() {
    const testing::TestInfo* const test_info =
        testing::UnitTest::GetInstance()->current_test_info();
    if (strcmp(test_info->name(), "MediaPlayerNew") == 0) {
      // The installer adds our process names to the registry key below.  Since
      // the installer might not have run on this machine, add it manually.
      RegKey regkey;
      if (regkey.Open(HKEY_LOCAL_MACHINE,
                      L"Software\\Microsoft\\MediaPlayer\\ShimInclusionList",
                      KEY_WRITE)) {
        regkey.CreateKey(L"CHROME.EXE", KEY_READ);
      }
    } else if (strcmp(test_info->name(), "MediaPlayerOld") == 0) {
      // When testing the old WMP plugin, we need to force Chrome to not load
      // the new plugin.
      launch_arguments_.AppendSwitch(kUseOldWMPPluginSwitch);
    } else if (strcmp(test_info->name(), "FlashSecurity") == 0) {
      launch_arguments_.AppendSwitchWithValue(switches::kTestSandbox,
                                              L"security_tests.dll");
    }

    UITest::SetUp();
  }
#endif  // defined(OS_WIN)

  void TestPlugin(const std::string& test_case,
                  int timeout,
                  bool mock_http) {
    GURL url = GetTestUrl(test_case, mock_http);
    NavigateToURL(url);
    WaitForFinish(timeout, mock_http);
  }

  // Generate the URL for testing a particular test.
  // HTML for the tests is all located in test_directory\plugin\<testcase>
  // Set |mock_http| to true to use mock HTTP server.
  GURL GetTestUrl(const std::string &test_case, bool mock_http) {
    static const FilePath::CharType kPluginPath[] = FILE_PATH_LITERAL("plugin");
    if (mock_http) {
      FilePath plugin_path = FilePath(kPluginPath).AppendASCII(test_case);
      return URLRequestMockHTTPJob::GetMockUrl(plugin_path);
    }

    FilePath path;
    PathService::Get(chrome::DIR_TEST_DATA, &path);
    path = path.Append(kPluginPath).AppendASCII(test_case);
    return net::FilePathToFileURL(path);
  }

  // Waits for the test case to finish.
  void WaitForFinish(const int wait_time, bool mock_http) {
    static const char kTestCompleteCookie[] = "status";
    static const char kTestCompleteSuccess[] = "OK";

    GURL url = GetTestUrl("done", mock_http);
    scoped_refptr<TabProxy> tab(GetActiveTab());

    const std::string result =
        WaitUntilCookieNonEmpty(tab, url, kTestCompleteCookie, wait_time);
    ASSERT_EQ(kTestCompleteSuccess, result);
  }
};

TEST_F(PluginTest, Flash) {
  // Note: This does not work with the npwrapper on 64-bit Linux. Install the
  // native 64-bit Flash to run the test.
  // TODO(thestig) Update this list if we decide to only test against internal
  // Flash plugin in the future?
  std::string kFlashQuery =
#if defined(OS_WIN)
      "npswf32.dll"
#elif defined(OS_MACOSX)
      "Flash Player.plugin"
#elif defined(OS_POSIX)
      "libflashplayer.so"
#endif
      ;
  TestPlugin("flash.html?" + kFlashQuery, action_max_timeout_ms(), false);
}

#if defined(OS_WIN)
// Windows only test
TEST_F(PluginTest, FlashSecurity) {
  TestPlugin("flash.html", action_max_timeout_ms(), false);
}
#endif  // defined(OS_WIN)

#if defined(OS_WIN)
// TODO(port) Port the following tests to platforms that have the required
// plugins.
TEST_F(PluginTest, Quicktime) {
  TestPlugin("quicktime.html", action_max_timeout_ms(), false);
}

TEST_F(PluginTest, DISABLED_MediaPlayerNew) {
  TestPlugin("wmp_new.html", action_max_timeout_ms(), false);
}

// http://crbug.com/4809
TEST_F(PluginTest, DISABLED_MediaPlayerOld) {
  TestPlugin("wmp_old.html", action_max_timeout_ms(), false);
}

TEST_F(PluginTest, Real) {
  TestPlugin("real.html", action_max_timeout_ms(), false);
}

TEST_F(PluginTest, FlashOctetStream) {
  TestPlugin("flash-octet-stream.html", action_max_timeout_ms(), false);
}

// http://crbug.com/16114
TEST_F(PluginTest, FlashLayoutWhilePainting) {
  TestPlugin("flash-layout-while-painting.html", action_max_timeout_ms(), true);
}

// http://crbug.com/8690
TEST_F(PluginTest, DISABLED_Java) {
  TestPlugin("Java.html", action_max_timeout_ms(), false);
}

TEST_F(PluginTest, Silverlight) {
  TestPlugin("silverlight.html", action_max_timeout_ms(), false);
}
#endif  // defined(OS_WIN)
<commit_msg>Make PluginTest.Real amd PluginTest.MediaPlayerNew only run on Debug Perf Bot. When we enabled them on the Release Perf Bots, they didn't work as expected.<commit_after>// Copyright (c) 2010 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.

// Tests for the top plugins to catch regressions in our plugin host code, as
// well as in the out of process code.  Currently this tests:
//  Flash
//  Real
//  QuickTime
//  Windows Media Player
//    -this includes both WMP plugins.  npdsplay.dll is the older one that
//     comes with XP.  np-mswmp.dll can be downloaded from Microsoft and
//     needs SP2 or Vista.

#include "build/build_config.h"

#if defined(OS_WIN)
#include <windows.h>
#include <shellapi.h>
#include <shlobj.h>
#include <comutil.h>
#endif

#include <stdlib.h>
#include <string.h>
#include <memory.h>

#include <string>

#include "base/file_path.h"
#include "base/file_util.h"
#include "base/path_service.h"
#include "chrome/browser/net/url_request_mock_http_job.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/test/automation/tab_proxy.h"
#include "chrome/test/ui/ui_test.h"
#include "net/base/net_util.h"
#include "third_party/npapi/bindings/npapi.h"
#include "webkit/glue/plugins/plugin_constants_win.h"
#include "webkit/glue/plugins/plugin_list.h"

#if defined(OS_WIN)
#include "base/registry.h"
// TODO(port) ?
#include "webkit/default_plugin/plugin_impl.h"
#endif

class PluginTest : public UITest {
 protected:
#if defined(OS_WIN)
  virtual void SetUp() {
    const testing::TestInfo* const test_info =
        testing::UnitTest::GetInstance()->current_test_info();
    if (strcmp(test_info->name(), "MediaPlayerNew") == 0) {
      // The installer adds our process names to the registry key below.  Since
      // the installer might not have run on this machine, add it manually.
      RegKey regkey;
      if (regkey.Open(HKEY_LOCAL_MACHINE,
                      L"Software\\Microsoft\\MediaPlayer\\ShimInclusionList",
                      KEY_WRITE)) {
        regkey.CreateKey(L"CHROME.EXE", KEY_READ);
      }
    } else if (strcmp(test_info->name(), "MediaPlayerOld") == 0) {
      // When testing the old WMP plugin, we need to force Chrome to not load
      // the new plugin.
      launch_arguments_.AppendSwitch(kUseOldWMPPluginSwitch);
    } else if (strcmp(test_info->name(), "FlashSecurity") == 0) {
      launch_arguments_.AppendSwitchWithValue(switches::kTestSandbox,
                                              L"security_tests.dll");
    }

    UITest::SetUp();
  }
#endif  // defined(OS_WIN)

  void TestPlugin(const std::string& test_case,
                  int timeout,
                  bool mock_http) {
    GURL url = GetTestUrl(test_case, mock_http);
    NavigateToURL(url);
    WaitForFinish(timeout, mock_http);
  }

  // Generate the URL for testing a particular test.
  // HTML for the tests is all located in test_directory\plugin\<testcase>
  // Set |mock_http| to true to use mock HTTP server.
  GURL GetTestUrl(const std::string &test_case, bool mock_http) {
    static const FilePath::CharType kPluginPath[] = FILE_PATH_LITERAL("plugin");
    if (mock_http) {
      FilePath plugin_path = FilePath(kPluginPath).AppendASCII(test_case);
      return URLRequestMockHTTPJob::GetMockUrl(plugin_path);
    }

    FilePath path;
    PathService::Get(chrome::DIR_TEST_DATA, &path);
    path = path.Append(kPluginPath).AppendASCII(test_case);
    return net::FilePathToFileURL(path);
  }

  // Waits for the test case to finish.
  void WaitForFinish(const int wait_time, bool mock_http) {
    static const char kTestCompleteCookie[] = "status";
    static const char kTestCompleteSuccess[] = "OK";

    GURL url = GetTestUrl("done", mock_http);
    scoped_refptr<TabProxy> tab(GetActiveTab());

    const std::string result =
        WaitUntilCookieNonEmpty(tab, url, kTestCompleteCookie, wait_time);
    ASSERT_EQ(kTestCompleteSuccess, result);
  }
};

TEST_F(PluginTest, Flash) {
  // Note: This does not work with the npwrapper on 64-bit Linux. Install the
  // native 64-bit Flash to run the test.
  // TODO(thestig) Update this list if we decide to only test against internal
  // Flash plugin in the future?
  std::string kFlashQuery =
#if defined(OS_WIN)
      "npswf32.dll"
#elif defined(OS_MACOSX)
      "Flash Player.plugin"
#elif defined(OS_POSIX)
      "libflashplayer.so"
#endif
      ;
  TestPlugin("flash.html?" + kFlashQuery, action_max_timeout_ms(), false);
}

#if defined(OS_WIN)
// Windows only test
TEST_F(PluginTest, FlashSecurity) {
  TestPlugin("flash.html", action_max_timeout_ms(), false);
}
#endif  // defined(OS_WIN)

#if defined(OS_WIN)
// TODO(port) Port the following tests to platforms that have the required
// plugins.
TEST_F(PluginTest, Quicktime) {
  TestPlugin("quicktime.html", action_max_timeout_ms(), false);
}

// Disabled on Release bots - http://crbug.com/44662
#if !defined(NDEBUG)
#define MediaPlayerNew DISABLED_MediaPlayerNew
#endif
TEST_F(PluginTest, MediaPlayerNew) {
  TestPlugin("wmp_new.html", action_max_timeout_ms(), false);
}

// http://crbug.com/4809
TEST_F(PluginTest, DISABLED_MediaPlayerOld) {
  TestPlugin("wmp_old.html", action_max_timeout_ms(), false);
}

#if !defined(NDEBUG)
#define Real DISABLED_Real
#endif
// Disabled on Release bots - http://crbug.com/44673
TEST_F(PluginTest, Real) {
  TestPlugin("real.html", action_max_timeout_ms(), false);
}

TEST_F(PluginTest, FlashOctetStream) {
  TestPlugin("flash-octet-stream.html", action_max_timeout_ms(), false);
}

// http://crbug.com/16114
TEST_F(PluginTest, FlashLayoutWhilePainting) {
  TestPlugin("flash-layout-while-painting.html", action_max_timeout_ms(), true);
}

// http://crbug.com/8690
TEST_F(PluginTest, DISABLED_Java) {
  TestPlugin("Java.html", action_max_timeout_ms(), false);
}

TEST_F(PluginTest, Silverlight) {
  TestPlugin("silverlight.html", action_max_timeout_ms(), false);
}
#endif  // defined(OS_WIN)
<|endoftext|>


<commit_before>// Copyright 2008, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//    * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//    * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//    * Neither the name of Google Inc. 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.

// Tests for the top plugins to catch regressions in our plugin host code, as
// well as in the out of process code.  Currently this tests:
//  Flash
//  Real
//  QuickTime
//  Windows Media Player
//    -this includes both WMP plugins.  npdsplay.dll is the older one that
//     comes with XP.  np-mswmp.dll can be downloaded from Microsoft and
//     needs SP2 or Vista.

#include <windows.h>
#include <shellapi.h>
#include <shlobj.h>
#include <atlbase.h>
#include <comutil.h>

#include <stdlib.h>
#include <string.h>
#include <memory.h>

#include "base/file_util.h"
#include "base/registry.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/test/automation/tab_proxy.h"
#include "chrome/test/ui/ui_test.h"
#include "net/base/net_util.h"
#include "webkit/glue/plugins/plugin_constants_win.h"
#include "webkit/glue/plugins/plugin_list.h"

const char kTestCompleteCookie[] = "status";
const char kTestCompleteSuccess[] = "OK";
const int kShortWaitTimeout = 10 * 1000;
const int kLongWaitTimeout  = 30 * 1000;

class PluginTest : public UITest {
 protected:
  virtual void SetUp() {
    const testing::TestInfo* const test_info =
        testing::UnitTest::GetInstance()->current_test_info();
    if (strcmp(test_info->name(), "MediaPlayerNew") == 0) {
      // The installer adds our process names to the registry key below.  Since
      // the installer might not have run on this machine, add it manually.
      RegKey regkey;
      if (regkey.Open(HKEY_LOCAL_MACHINE,
                      L"Software\\Microsoft\\MediaPlayer\\ShimInclusionList",
                      KEY_WRITE)) {
        regkey.CreateKey(L"CHROME.EXE", KEY_READ);
      }
      launch_arguments_.AppendSwitch(kNoNativeActiveXShimSwitch);

    } else if (strcmp(test_info->name(), "MediaPlayerOld") == 0) {
      // When testing the old WMP plugin, we need to force Chrome to not load
      // the new plugin.
      launch_arguments_.AppendSwitch(kUseOldWMPPluginSwitch);
      launch_arguments_.AppendSwitch(kNoNativeActiveXShimSwitch);
    } else if (strcmp(test_info->name(), "FlashSecurity") == 0) {
      launch_arguments_.AppendSwitchWithValue(switches::kTestSandbox,
                                              L"security_tests.dll");
    }

    UITest::SetUp();
  }

  void TestPlugin(const std::wstring& test_case, int timeout) {
    GURL url = GetTestUrl(test_case);
    NavigateToURL(url);
    WaitForFinish(timeout);
  }

  // Generate the URL for testing a particular test.
  // HTML for the tests is all located in test_directory\plugin\<testcase>
  GURL GetTestUrl(const std::wstring &test_case) {
    std::wstring path;
    PathService::Get(chrome::DIR_TEST_DATA, &path);
    file_util::AppendToPath(&path, L"plugin");
    file_util::AppendToPath(&path, test_case);
    return net::FilePathToFileURL(path);
  }

  // Waits for the test case to finish.
  void WaitForFinish(const int wait_time) {
    const int kSleepTime = 500;      // 2 times per second
    const int kMaxIntervals = wait_time / kSleepTime;

    GURL url = GetTestUrl(L"done");
    scoped_ptr<TabProxy> tab(GetActiveTab());

    std::string done_str;
    for (int i = 0; i < kMaxIntervals; ++i) {
      Sleep(kSleepTime);

      // The webpage being tested has javascript which sets a cookie
      // which signals completion of the test.
      std::string cookieName = kTestCompleteCookie;
      tab->GetCookieByName(url, cookieName, &done_str);
      if (!done_str.empty())
        break;
    }

    EXPECT_EQ(kTestCompleteSuccess, done_str);
  }
};

// Disabling all tests to make buildbot green. See -
// http://code.google.com/p/chromium/issues/detail?id=7983
TEST_F(PluginTest, DISABLED_Quicktime) {
  TestPlugin(L"quicktime.html", kShortWaitTimeout);
}

TEST_F(PluginTest, DISABLED_MediaPlayerNew) {
  TestPlugin(L"wmp_new.html", kShortWaitTimeout);
}

// http://crbug.com/4809
TEST_F(PluginTest, DISABLED_MediaPlayerOld) {
  TestPlugin(L"wmp_old.html", kLongWaitTimeout);
}

TEST_F(PluginTest, DISABLED_Real) {
  TestPlugin(L"real.html", kShortWaitTimeout);
}

TEST_F(PluginTest, DISABLED_Flash) {
  TestPlugin(L"flash.html", kShortWaitTimeout);
}

TEST_F(PluginTest, DISABLED_FlashOctetStream) {
  TestPlugin(L"flash-octet-stream.html", kShortWaitTimeout);
}

TEST_F(PluginTest, DISABLED_FlashSecurity) {
  TestPlugin(L"flash.html", kShortWaitTimeout);
}

TEST_F(PluginTest, DISABLED_Java) {
  TestPlugin(L"Java.html", kShortWaitTimeout);
}

TEST_F(PluginTest, DISABLED_Silverlight) {
  TestPlugin(L"silverlight.html", kShortWaitTimeout);
}

typedef HRESULT (__stdcall* DllRegUnregServerFunc)();

class ActiveXTest : public PluginTest {
 public:
  ActiveXTest() {
    dll_registered = false;
  }
 protected:
  void TestActiveX(const std::wstring& test_case, int timeout, bool reg_dll) {
    if (reg_dll) {
      RegisterTestControl(true);
      dll_registered = true;
    }
    TestPlugin(test_case, timeout);
  }
  virtual void TearDown() {
    PluginTest::TearDown();
    if (dll_registered)
      RegisterTestControl(false);
  }
  void RegisterTestControl(bool register_server) {
    std::wstring test_control_path = browser_directory_ +
        L"\\activex_test_control.dll";
    HMODULE h = LoadLibrary(test_control_path.c_str());
    ASSERT_TRUE(h != NULL) << "Failed to load activex_test_control.dll";
    const char* func_name = register_server ?
                                "DllRegisterServer" : "DllUnregisterServer";
    DllRegUnregServerFunc func = reinterpret_cast<DllRegUnregServerFunc>(
        GetProcAddress(h, func_name));
    // This should never happen actually.
    ASSERT_TRUE(func != NULL) << "Failed to find reg/unreg function.";
    HRESULT hr = func();
    const char* error_message = register_server ? "Failed to register dll."
                                                : "Failed to unregister dll";
    ASSERT_TRUE(SUCCEEDED(hr)) << error_message;
    FreeLibrary(h);
  }
 private:
  bool dll_registered;
};

TEST_F(ActiveXTest, DISABLED_EmbeddedWMP) {
  TestActiveX(L"activex_embedded_wmp.html", kLongWaitTimeout, false);
}

TEST_F(ActiveXTest, DISABLED_WMP) {
  TestActiveX(L"activex_wmp.html", kLongWaitTimeout, false);
}

TEST_F(ActiveXTest, DISABLED_CustomScripting) {
  TestActiveX(L"activex_custom_scripting.html", kShortWaitTimeout, true);
}

<commit_msg>Revert "Disabling tests that are failing."<commit_after>// Copyright 2008, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//    * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//    * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//    * Neither the name of Google Inc. 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.

// Tests for the top plugins to catch regressions in our plugin host code, as
// well as in the out of process code.  Currently this tests:
//  Flash
//  Real
//  QuickTime
//  Windows Media Player
//    -this includes both WMP plugins.  npdsplay.dll is the older one that
//     comes with XP.  np-mswmp.dll can be downloaded from Microsoft and
//     needs SP2 or Vista.

#include <windows.h>
#include <shellapi.h>
#include <shlobj.h>
#include <atlbase.h>
#include <comutil.h>

#include <stdlib.h>
#include <string.h>
#include <memory.h>

#include "base/file_util.h"
#include "base/registry.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/test/automation/tab_proxy.h"
#include "chrome/test/ui/ui_test.h"
#include "net/base/net_util.h"
#include "webkit/glue/plugins/plugin_constants_win.h"
#include "webkit/glue/plugins/plugin_list.h"

const char kTestCompleteCookie[] = "status";
const char kTestCompleteSuccess[] = "OK";
const int kShortWaitTimeout = 10 * 1000;
const int kLongWaitTimeout  = 30 * 1000;

class PluginTest : public UITest {
 protected:
  virtual void SetUp() {
    const testing::TestInfo* const test_info =
        testing::UnitTest::GetInstance()->current_test_info();
    if (strcmp(test_info->name(), "MediaPlayerNew") == 0) {
      // The installer adds our process names to the registry key below.  Since
      // the installer might not have run on this machine, add it manually.
      RegKey regkey;
      if (regkey.Open(HKEY_LOCAL_MACHINE,
                      L"Software\\Microsoft\\MediaPlayer\\ShimInclusionList",
                      KEY_WRITE)) {
        regkey.CreateKey(L"CHROME.EXE", KEY_READ);
      }
      launch_arguments_.AppendSwitch(kNoNativeActiveXShimSwitch);

    } else if (strcmp(test_info->name(), "MediaPlayerOld") == 0) {
      // When testing the old WMP plugin, we need to force Chrome to not load
      // the new plugin.
      launch_arguments_.AppendSwitch(kUseOldWMPPluginSwitch);
      launch_arguments_.AppendSwitch(kNoNativeActiveXShimSwitch);
    } else if (strcmp(test_info->name(), "FlashSecurity") == 0) {
      launch_arguments_.AppendSwitchWithValue(switches::kTestSandbox,
                                              L"security_tests.dll");
    }

    UITest::SetUp();
  }

  void TestPlugin(const std::wstring& test_case, int timeout) {
    GURL url = GetTestUrl(test_case);
    NavigateToURL(url);
    WaitForFinish(timeout);
  }

  // Generate the URL for testing a particular test.
  // HTML for the tests is all located in test_directory\plugin\<testcase>
  GURL GetTestUrl(const std::wstring &test_case) {
    std::wstring path;
    PathService::Get(chrome::DIR_TEST_DATA, &path);
    file_util::AppendToPath(&path, L"plugin");
    file_util::AppendToPath(&path, test_case);
    return net::FilePathToFileURL(path);
  }

  // Waits for the test case to finish.
  void WaitForFinish(const int wait_time) {
    const int kSleepTime = 500;      // 2 times per second
    const int kMaxIntervals = wait_time / kSleepTime;

    GURL url = GetTestUrl(L"done");
    scoped_ptr<TabProxy> tab(GetActiveTab());

    std::string done_str;
    for (int i = 0; i < kMaxIntervals; ++i) {
      Sleep(kSleepTime);

      // The webpage being tested has javascript which sets a cookie
      // which signals completion of the test.
      std::string cookieName = kTestCompleteCookie;
      tab->GetCookieByName(url, cookieName, &done_str);
      if (!done_str.empty())
        break;
    }

    EXPECT_EQ(kTestCompleteSuccess, done_str);
  }
};

TEST_F(PluginTest, Quicktime) {
  TestPlugin(L"quicktime.html", kShortWaitTimeout);
}

TEST_F(PluginTest, MediaPlayerNew) {
  TestPlugin(L"wmp_new.html", kShortWaitTimeout);
}

// http://crbug.com/4809
TEST_F(PluginTest, DISABLED_MediaPlayerOld) {
  TestPlugin(L"wmp_old.html", kLongWaitTimeout);
}

TEST_F(PluginTest, Real) {
  TestPlugin(L"real.html", kShortWaitTimeout);
}

TEST_F(PluginTest, Flash) {
  TestPlugin(L"flash.html", kShortWaitTimeout);
}

TEST_F(PluginTest, FlashOctetStream) {
  TestPlugin(L"flash-octet-stream.html", kShortWaitTimeout);
}

TEST_F(PluginTest, FlashSecurity) {
  TestPlugin(L"flash.html", kShortWaitTimeout);
}

TEST_F(PluginTest, Java) {
  TestPlugin(L"Java.html", kShortWaitTimeout);
}

TEST_F(PluginTest, Silverlight) {
  TestPlugin(L"silverlight.html", kShortWaitTimeout);
}

typedef HRESULT (__stdcall* DllRegUnregServerFunc)();

class ActiveXTest : public PluginTest {
 public:
  ActiveXTest() {
    dll_registered = false;
  }
 protected:
  void TestActiveX(const std::wstring& test_case, int timeout, bool reg_dll) {
    if (reg_dll) {
      RegisterTestControl(true);
      dll_registered = true;
    }
    TestPlugin(test_case, timeout);
  }
  virtual void TearDown() {
    PluginTest::TearDown();
    if (dll_registered)
      RegisterTestControl(false);
  }
  void RegisterTestControl(bool register_server) {
    std::wstring test_control_path = browser_directory_ +
        L"\\activex_test_control.dll";
    HMODULE h = LoadLibrary(test_control_path.c_str());
    ASSERT_TRUE(h != NULL) << "Failed to load activex_test_control.dll";
    const char* func_name = register_server ?
                                "DllRegisterServer" : "DllUnregisterServer";
    DllRegUnregServerFunc func = reinterpret_cast<DllRegUnregServerFunc>(
        GetProcAddress(h, func_name));
    // This should never happen actually.
    ASSERT_TRUE(func != NULL) << "Failed to find reg/unreg function.";
    HRESULT hr = func();
    const char* error_message = register_server ? "Failed to register dll."
                                                : "Failed to unregister dll";
    ASSERT_TRUE(SUCCEEDED(hr)) << error_message;
    FreeLibrary(h);
  }
 private:
  bool dll_registered;
};

TEST_F(ActiveXTest, EmbeddedWMP) {
  TestActiveX(L"activex_embedded_wmp.html", kLongWaitTimeout, false);
}

TEST_F(ActiveXTest, WMP) {
  TestActiveX(L"activex_wmp.html", kLongWaitTimeout, false);
}

TEST_F(ActiveXTest, CustomScripting) {
  TestActiveX(L"activex_custom_scripting.html", kShortWaitTimeout, true);
}

<|endoftext|>


<commit_before>/*
 *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "receiver_tests.h"
#include "video_coding.h"
#include "rtp_rtcp.h"
#include "trace.h"
#include "thread_wrapper.h"
#include "../source/event.h"
#include "tick_time.h"
#include "test_macros.h"
#include "rtp_player.h"

#include <string.h>

using namespace webrtc;

bool ProcessingThread(void* obj)
{
    SharedState* state = static_cast<SharedState*>(obj);
    if (state->_vcm.TimeUntilNextProcess() <= 0)
    {
        if (state->_vcm.Process() < 0)
        {
            return false;
        }
    }
    return true;
}

bool RtpReaderThread(void* obj)
{
    SharedState* state = static_cast<SharedState*>(obj);
    EventWrapper& waitEvent = *EventWrapper::Create();
    // RTP stream main loop
    WebRtc_Word64 nowMs = VCMTickTime::MillisecondTimestamp();
    if (state->_rtpPlayer.NextPacket(nowMs) < 0)
    {
        return false;
    }
    waitEvent.Wait(state->_rtpPlayer.TimeUntilNextPacket());
    delete &waitEvent;
    return true;
}

bool DecodeThread(void* obj)
{
    SharedState* state = static_cast<SharedState*>(obj);
    WebRtc_Word32 ret = state->_vcm.Decode(10000);
    TEST(ret == VCM_OK || ret == VCM_UNINITIALIZED || ret == VCM_NO_CODEC_REGISTERED);
    while (state->_vcm.DecodeDualFrame(0) == 1);
    return true;
}

int RtpPlayMT(CmdArgs& args, int releaseTestNo, webrtc::VideoCodecType releaseTestVideoType)
{
    // Don't run these tests with debug time
#if defined(TICK_TIME_DEBUG) || defined(EVENT_DEBUG)
    return -1;
#endif

    // BEGIN Settings

    bool protectionEnabled = true;
    VCMVideoProtection protection = kProtectionDualDecoder;
    WebRtc_UWord8 rttMS = 50;
    float lossRate = 0.05f;
    WebRtc_UWord32 renderDelayMs = 0;
    WebRtc_UWord32 minPlayoutDelayMs = 0;
    const WebRtc_Word64 MAX_RUNTIME_MS = 10000;
    std::string outFilename = args.outputFile;
    if (outFilename == "")
        outFilename = "RtpPlayMT_decoded.yuv";

    bool nackEnabled = (protectionEnabled &&
                (protection == kProtectionDualDecoder ||
                protection == kProtectionNack ||
                kProtectionNackFEC));
    VideoCodingModule* vcm =
            VideoCodingModule::Create(1);
    RtpDataCallback dataCallback(vcm);
    std::string rtpFilename;
    rtpFilename = args.inputFile;
    if (releaseTestNo > 0)
    {
        // Setup a release test
        switch (releaseTestVideoType)
        {
        case webrtc::kVideoCodecVP8:
            rtpFilename = args.inputFile;
            outFilename = "MTReceiveTest_VP8";
            break;
        default:
            return -1;
        }
        switch (releaseTestNo)
        {
        case 1:
            // Normal execution
            protectionEnabled = false;
            nackEnabled = false;
            rttMS = 0;
            lossRate = 0.0f;
            outFilename += "_Normal.yuv";
            break;
        case 2:
            // Packet loss
            protectionEnabled = false;
            nackEnabled = false;
            rttMS = 0;
            lossRate = 0.05f;
            outFilename += "_0.05.yuv";
            break;
        case 3:
            // Packet loss and NACK
            protection = kProtectionNack;
            nackEnabled = true;
            protectionEnabled = true;
            rttMS = 100;
            lossRate = 0.05f;
            outFilename += "_0.05_NACK_100ms.yuv";
            break;
        case 4:
            // Packet loss and dual decoder
            // Not implemented
            return 0;
            break;
        default:
            return -1;
        }
        printf("Watch %s to verify that the output is reasonable\n", outFilename.c_str());
    }
    RTPPlayer rtpStream(rtpFilename.c_str(), &dataCallback);
    ListWrapper payloadTypes;
    payloadTypes.PushFront(new PayloadCodecTuple(VCM_VP8_PAYLOAD_TYPE,
                                                 "VP8", kVideoCodecVP8));

    Trace::CreateTrace();
    Trace::SetTraceFile("receiverTestTrace.txt");
    Trace::SetLevelFilter(webrtc::kTraceAll);

    // END Settings

    // Set up

    SharedState mtState(*vcm, rtpStream);

    if (rtpStream.Initialize(payloadTypes) < 0)
    {
        return -1;
    }
    rtpStream.SimulatePacketLoss(lossRate, nackEnabled, rttMS);

    WebRtc_Word32 ret = vcm->InitializeReceiver();
    if (ret < 0)
    {
        return -1;
    }

    // Create and start all threads
    ThreadWrapper* processingThread = ThreadWrapper::CreateThread(ProcessingThread,
            &mtState, kNormalPriority, "ProcessingThread");
    ThreadWrapper* rtpReaderThread = ThreadWrapper::CreateThread(RtpReaderThread,
            &mtState, kNormalPriority, "RtpReaderThread");
    ThreadWrapper* decodeThread = ThreadWrapper::CreateThread(DecodeThread,
            &mtState, kNormalPriority, "DecodeThread");

    // Register receive codecs in VCM
    ListItem* item = payloadTypes.First();
    while (item != NULL)
    {
        PayloadCodecTuple* payloadType = static_cast<PayloadCodecTuple*>(item->GetItem());
        if (payloadType != NULL)
        {
            VideoCodec codec;
            VideoCodingModule::Codec(payloadType->codecType, &codec);
            codec.plType = payloadType->payloadType;
            if (vcm->RegisterReceiveCodec(&codec, 1) < 0)
            {
                return -1;
            }
        }
        item = payloadTypes.Next(item);
    }

    if (processingThread != NULL)
    {
        unsigned int tid;
        processingThread->Start(tid);
    }
    else
    {
        printf("Unable to start processing thread\n");
        return -1;
    }
    if (rtpReaderThread != NULL)
    {
        unsigned int tid;
        rtpReaderThread->Start(tid);
    }
    else
    {
        printf("Unable to start RTP reader thread\n");
        return -1;
    }
    if (decodeThread != NULL)
    {
        unsigned int tid;
        decodeThread->Start(tid);
    }
    else
    {
        printf("Unable to start decode thread\n");
        return -1;
    }

    FrameReceiveCallback receiveCallback(outFilename);
    vcm->RegisterReceiveCallback(&receiveCallback);
    vcm->RegisterPacketRequestCallback(&rtpStream);

    vcm->SetChannelParameters(0, 0, rttMS);
    vcm->SetVideoProtection(protection, protectionEnabled);
    vcm->SetRenderDelay(renderDelayMs);
    vcm->SetMinimumPlayoutDelay(minPlayoutDelayMs);

    EventWrapper& waitEvent = *EventWrapper::Create();

    // Decode for 10 seconds and then tear down and exit.
    waitEvent.Wait(MAX_RUNTIME_MS);

    // Tear down
    item = payloadTypes.First();
    while (item != NULL)
    {
        PayloadCodecTuple* payloadType = static_cast<PayloadCodecTuple*>(item->GetItem());
        if (payloadType != NULL)
        {
            delete payloadType;
        }
        ListItem* itemToRemove = item;
        item = payloadTypes.Next(item);
        payloadTypes.Erase(itemToRemove);
    }
    while (!processingThread->Stop())
    {
        ;
    }
    while (!rtpReaderThread->Stop())
    {
        ;
    }
    while (!decodeThread->Stop())
    {
        ;
    }
    VideoCodingModule::Destroy(vcm);
    vcm = NULL;
    delete &waitEvent;
    delete processingThread;
    delete decodeThread;
    delete rtpReaderThread;
    rtpStream.Print();
    Trace::ReturnTrace();
    return 0;
}
<commit_msg>Remove a test case that only causes problems due to badly synchronized test. The test is as useful without this test case. Review URL: http://webrtc-codereview.appspot.com/47003<commit_after>/*
 *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "receiver_tests.h"
#include "video_coding.h"
#include "rtp_rtcp.h"
#include "trace.h"
#include "thread_wrapper.h"
#include "../source/event.h"
#include "tick_time.h"
#include "test_macros.h"
#include "rtp_player.h"

#include <string.h>

using namespace webrtc;

bool ProcessingThread(void* obj)
{
    SharedState* state = static_cast<SharedState*>(obj);
    if (state->_vcm.TimeUntilNextProcess() <= 0)
    {
        if (state->_vcm.Process() < 0)
        {
            return false;
        }
    }
    return true;
}

bool RtpReaderThread(void* obj)
{
    SharedState* state = static_cast<SharedState*>(obj);
    EventWrapper& waitEvent = *EventWrapper::Create();
    // RTP stream main loop
    WebRtc_Word64 nowMs = VCMTickTime::MillisecondTimestamp();
    if (state->_rtpPlayer.NextPacket(nowMs) < 0)
    {
        return false;
    }
    waitEvent.Wait(state->_rtpPlayer.TimeUntilNextPacket());
    delete &waitEvent;
    return true;
}

bool DecodeThread(void* obj)
{
    SharedState* state = static_cast<SharedState*>(obj);
    WebRtc_Word32 ret = state->_vcm.Decode(10000);
    while (state->_vcm.DecodeDualFrame(0) == 1);
    return true;
}

int RtpPlayMT(CmdArgs& args, int releaseTestNo, webrtc::VideoCodecType releaseTestVideoType)
{
    // Don't run these tests with debug time
#if defined(TICK_TIME_DEBUG) || defined(EVENT_DEBUG)
    return -1;
#endif

    // BEGIN Settings

    bool protectionEnabled = true;
    VCMVideoProtection protection = kProtectionDualDecoder;
    WebRtc_UWord8 rttMS = 50;
    float lossRate = 0.05f;
    WebRtc_UWord32 renderDelayMs = 0;
    WebRtc_UWord32 minPlayoutDelayMs = 0;
    const WebRtc_Word64 MAX_RUNTIME_MS = 10000;
    std::string outFilename = args.outputFile;
    if (outFilename == "")
        outFilename = "RtpPlayMT_decoded.yuv";

    bool nackEnabled = (protectionEnabled &&
                (protection == kProtectionDualDecoder ||
                protection == kProtectionNack ||
                kProtectionNackFEC));
    VideoCodingModule* vcm =
            VideoCodingModule::Create(1);
    RtpDataCallback dataCallback(vcm);
    std::string rtpFilename;
    rtpFilename = args.inputFile;
    if (releaseTestNo > 0)
    {
        // Setup a release test
        switch (releaseTestVideoType)
        {
        case webrtc::kVideoCodecVP8:
            rtpFilename = args.inputFile;
            outFilename = "MTReceiveTest_VP8";
            break;
        default:
            return -1;
        }
        switch (releaseTestNo)
        {
        case 1:
            // Normal execution
            protectionEnabled = false;
            nackEnabled = false;
            rttMS = 0;
            lossRate = 0.0f;
            outFilename += "_Normal.yuv";
            break;
        case 2:
            // Packet loss
            protectionEnabled = false;
            nackEnabled = false;
            rttMS = 0;
            lossRate = 0.05f;
            outFilename += "_0.05.yuv";
            break;
        case 3:
            // Packet loss and NACK
            protection = kProtectionNack;
            nackEnabled = true;
            protectionEnabled = true;
            rttMS = 100;
            lossRate = 0.05f;
            outFilename += "_0.05_NACK_100ms.yuv";
            break;
        case 4:
            // Packet loss and dual decoder
            // Not implemented
            return 0;
            break;
        default:
            return -1;
        }
        printf("Watch %s to verify that the output is reasonable\n", outFilename.c_str());
    }
    RTPPlayer rtpStream(rtpFilename.c_str(), &dataCallback);
    ListWrapper payloadTypes;
    payloadTypes.PushFront(new PayloadCodecTuple(VCM_VP8_PAYLOAD_TYPE,
                                                 "VP8", kVideoCodecVP8));

    Trace::CreateTrace();
    Trace::SetTraceFile("receiverTestTrace.txt");
    Trace::SetLevelFilter(webrtc::kTraceAll);

    // END Settings

    // Set up

    SharedState mtState(*vcm, rtpStream);

    if (rtpStream.Initialize(payloadTypes) < 0)
    {
        return -1;
    }
    rtpStream.SimulatePacketLoss(lossRate, nackEnabled, rttMS);

    WebRtc_Word32 ret = vcm->InitializeReceiver();
    if (ret < 0)
    {
        return -1;
    }

    // Create and start all threads
    ThreadWrapper* processingThread = ThreadWrapper::CreateThread(ProcessingThread,
            &mtState, kNormalPriority, "ProcessingThread");
    ThreadWrapper* rtpReaderThread = ThreadWrapper::CreateThread(RtpReaderThread,
            &mtState, kNormalPriority, "RtpReaderThread");
    ThreadWrapper* decodeThread = ThreadWrapper::CreateThread(DecodeThread,
            &mtState, kNormalPriority, "DecodeThread");

    // Register receive codecs in VCM
    ListItem* item = payloadTypes.First();
    while (item != NULL)
    {
        PayloadCodecTuple* payloadType = static_cast<PayloadCodecTuple*>(item->GetItem());
        if (payloadType != NULL)
        {
            VideoCodec codec;
            VideoCodingModule::Codec(payloadType->codecType, &codec);
            codec.plType = payloadType->payloadType;
            if (vcm->RegisterReceiveCodec(&codec, 1) < 0)
            {
                return -1;
            }
        }
        item = payloadTypes.Next(item);
    }

    if (processingThread != NULL)
    {
        unsigned int tid;
        processingThread->Start(tid);
    }
    else
    {
        printf("Unable to start processing thread\n");
        return -1;
    }
    if (rtpReaderThread != NULL)
    {
        unsigned int tid;
        rtpReaderThread->Start(tid);
    }
    else
    {
        printf("Unable to start RTP reader thread\n");
        return -1;
    }
    if (decodeThread != NULL)
    {
        unsigned int tid;
        decodeThread->Start(tid);
    }
    else
    {
        printf("Unable to start decode thread\n");
        return -1;
    }

    FrameReceiveCallback receiveCallback(outFilename);
    vcm->RegisterReceiveCallback(&receiveCallback);
    vcm->RegisterPacketRequestCallback(&rtpStream);

    vcm->SetChannelParameters(0, 0, rttMS);
    vcm->SetVideoProtection(protection, protectionEnabled);
    vcm->SetRenderDelay(renderDelayMs);
    vcm->SetMinimumPlayoutDelay(minPlayoutDelayMs);

    EventWrapper& waitEvent = *EventWrapper::Create();

    // Decode for 10 seconds and then tear down and exit.
    waitEvent.Wait(MAX_RUNTIME_MS);

    // Tear down
    item = payloadTypes.First();
    while (item != NULL)
    {
        PayloadCodecTuple* payloadType = static_cast<PayloadCodecTuple*>(item->GetItem());
        if (payloadType != NULL)
        {
            delete payloadType;
        }
        ListItem* itemToRemove = item;
        item = payloadTypes.Next(item);
        payloadTypes.Erase(itemToRemove);
    }
    while (!processingThread->Stop())
    {
        ;
    }
    while (!rtpReaderThread->Stop())
    {
        ;
    }
    while (!decodeThread->Stop())
    {
        ;
    }
    VideoCodingModule::Destroy(vcm);
    vcm = NULL;
    delete &waitEvent;
    delete processingThread;
    delete decodeThread;
    delete rtpReaderThread;
    rtpStream.Print();
    Trace::ReturnTrace();
    return 0;
}
<|endoftext|>


<commit_before>/** \file make_marc_xml.cc
 *  \brief Converts XML blobs downloaded from the BSZ into proper MARC-XML records.
 *  \author Dr. Johannes Ruscheinski (johannes.ruscheinski@uni-tuebingen.de)
 *
 *  \copyright 2016 Universitätsbiblothek Tübingen.  All rights reserved.
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Affero General Public License as
 *  published by the Free Software Foundation, either version 3 of the
 *  License, or (at your option) any later version.
 *
 *  This program 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 Affero General Public License for more details.
 *
 *  You should have received a copy of the GNU Affero General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#include <iostream>
#include <unordered_map>
#include "Compiler.h"
#include "FileUtil.h"
#include "util.h"

void Usage() {
    std::cerr << "usage: " << progname << " [--append] input_blob output_marc_xml\n";
    std::exit(EXIT_FAILURE);
}

const std::unordered_map<std::string, std::string> from_to{
    { "<record>", "<marc:record>" },
    { "</record>", "</marc:record>" },
    { "<leader>", "<marc:leader>" },
    { "</leader>", "</marc:leader>" },
    { "<controlfield", "<marc:controlfield" },
    { "</controlfield>", "</marc:controlfield>" },
    { "<datafield", "<marc:datafield" },
    { "</datafield>", "</marc:datafield>" },
    { "<subfield", "<marc:subfield" },
    { "</subfield>", "</marc:subfield>" },
};

std::string GetNextToken(File * const input) {
    std::string token;

    const int first_ch(input->get());
    if (first_ch == EOF)
        return token; // Empty string signal EOF.

    token += static_cast<char>(first_ch);
    if (likely(first_ch != '<'))
        return token;

    int ch;
    while ((ch = input->get()) != EOF and (islower(ch) or ch == '>' or ch == '/'))
        token += static_cast<char>(ch);
    if (likely(ch != EOF))
        input->putback(static_cast<char>(ch));

    return token;
}

void Convert(File * const input, File * const output) {
    bool converting(false);

    std::string token(GetNextToken(input));
    bool leader_open_seen(false); // We only like to see one of these.
    while (not token.empty()) {
        if (token == "<record>")
            converting = true;

        if (converting) {
            if (token == "</record>")
                converting = false;
            if (token == "<leader>") {
                if (leader_open_seen) {
                    (*output) << "</marc:record>\n";
                    return;
                }
                leader_open_seen = true;
            }
            const auto pair(from_to.find(token));
            (*output) << (pair == from_to.cend() ? token : pair->second);
        }

        token = GetNextToken(input);
    }
}

int main(int argc, char *argv[]) {
    ::progname = argv[0];

    if (argc < 2)
        Usage();

    bool append(false);
    if (std::strcmp("--append", argv[1]) == 0) {
        append = true;
        --argc, ++argv;
    }

    if (argc != 3)
        Usage();

    const std::unique_ptr<File> input(FileUtil::OpenInputFileOrDie(argv[1]));
    const std::unique_ptr<File> output(append ? FileUtil::OpenForAppeningOrDie(argv[2])
                                              : FileUtil::OpenOutputFileOrDie(argv[2]));

    try {
        Convert(input.get(), output.get());
    } catch (const std::exception &x) {
        Error("caught exception: " + std::string(x.what()));
    }
}

<commit_msg>We now try to fix up some common XML errors before feeding it to the wolves (a.k.a. xmllint).<commit_after>/** \file make_marc_xml.cc
 *  \brief Converts XML blobs downloaded from the BSZ into proper MARC-XML records.
 *  \author Dr. Johannes Ruscheinski (johannes.ruscheinski@uni-tuebingen.de)
 *
 *  \copyright 2016 Universitätsbiblothek Tübingen.  All rights reserved.
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Affero General Public License as
 *  published by the Free Software Foundation, either version 3 of the
 *  License, or (at your option) any later version.
 *
 *  This program 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 Affero General Public License for more details.
 *
 *  You should have received a copy of the GNU Affero General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#include <iostream>
#include <unordered_map>
#include "Compiler.h"
#include "FileUtil.h"
#include "RegexMatcher.h"
#include "StringUtil.h"
#include "util.h"

void Usage() {
    std::cerr << "usage: " << progname << " [--append] input_blob output_marc_xml\n";
    std::exit(EXIT_FAILURE);
}

const std::unordered_map<std::string, std::string> from_to{
    { "<record>", "<marc:record>" },
    { "</record>", "</marc:record>" },
    { "<leader>", "<marc:leader>" },
    { "</leader>", "</marc:leader>" },
    { "<controlfield", "<marc:controlfield" },
    { "</controlfield>", "</marc:controlfield>" },
    { "<datafield", "<marc:datafield" },
    { "</datafield>", "</marc:datafield>" },
    { "<subfield", "<marc:subfield" },
    { "</subfield>", "</marc:subfield>" },
};

std::string GetNextToken(File * const input) {
    std::string token;

    const int first_ch(input->get());
    if (first_ch == EOF)
        return ""; // Empty string signal EOF.

    token += static_cast<char>(first_ch);
    if (likely(first_ch != '<'))
        return token;

    int ch;
    while ((ch = input->get()) != EOF) {
        token += static_cast<char>(ch);
        if (ch == '>')
            return token;
    }

    return token;
}

class XMLComponent {
    std::string text_;
public:
    explicit XMLComponent(const std::string &text);
    std::string toString() const;
    bool operator<(const XMLComponent &rhs) const { return getTag() < rhs.getTag(); }
private:
    std::string getTag() const;
};

XMLComponent::XMLComponent(const std::string &text)
    : text_(text)
{
    if (StringUtil::StartsWith(text_, "<datafield")) {
        static const RegexMatcher * const matcher(RegexMatcher::RegexMatcherFactory(
            "(tag=\"...\")( +ind1=\".\")?( +ind2=\".\")?"));
        if (matcher->matched(text_) and matcher->getLastMatchCount() != 4) {
            const size_t first_closing_angle_bracket_pos(text_.find('>'));
            text_ = "<datafield " + (*matcher)[1] + " ind1=\" \" ind2=\" \""
                    + text_.substr(first_closing_angle_bracket_pos);
        }
    }
}

std::string XMLComponent::getTag() const {
    if (StringUtil::StartsWith(text_, "<record>"))
        return "\1\1\1";
    if (StringUtil::StartsWith(text_, "<leader>"))
        return "\2\2\2";
    if (StringUtil::EndsWith(text_, "</record>"))
        return "\255\255\255";
    static const RegexMatcher * const matcher(RegexMatcher::RegexMatcherFactory(" tag=\"(...)\""));
    return matcher->matched(text_) ? (*matcher)[1] : "";
}

std::string XMLComponent::toString() const {
    std::string converted_text;

    // 1. Process opening tags:
    for (const auto original_and_replacement : from_to) {
        if (StringUtil::StartsWith(text_, original_and_replacement.first)) {
            converted_text = original_and_replacement.second + text_.substr(original_and_replacement.first.length());
            break;
        }
    }
    if (converted_text.empty())
        converted_text = text_;

    // 2. Process closing tags:
    for (const auto original_and_replacement : from_to) {
        if (StringUtil::EndsWith(converted_text, original_and_replacement.first)) {
            converted_text = converted_text.substr(0, converted_text.length()
                                                   - original_and_replacement.first.length())
                             + original_and_replacement.second;
            break;
        }
    }

    // 3. Process subfields tags:
    StringUtil::ReplaceString("<subfield", "<marc:subfield", &converted_text);
    StringUtil::ReplaceString("</subfield", "</marc:subfield", &converted_text);

    return converted_text;
}

void Convert(File * const input, File * const output) {
    bool converting(false);

    std::vector<XMLComponent> xml_components;
    std::string token(GetNextToken(input));
    bool leader_open_seen(false); // We only like to see one of these.
    std::string component_text;
    const RegexMatcher * const open_tag_matcher(RegexMatcher::RegexMatcherFactory("^<controlfield|^<datafield"));
    const RegexMatcher * const close_tag_matcher(
        RegexMatcher::RegexMatcherFactory("</controlfield>|</datafield>|</leader>"));
    while (not token.empty()) {
        if (token == "<record>") {
            xml_components.emplace_back(token);
            converting = true;
        } else if (converting) {
            if (token == "</record>") {
                converting = false;
                xml_components.emplace_back(token);
                break;
            } else if (token == "<leader>") { // If we get a 2nd <leader> we close our <record> and quit.
                if (leader_open_seen) {
                    xml_components.emplace_back("</record>");
                    break;
                } else {
                    leader_open_seen = true;
                    component_text = token;
                }
            } else {
                if (open_tag_matcher->matched(token))
                    component_text = token;
                else if (close_tag_matcher->matched(token))
                    xml_components.emplace_back(component_text + token);
                else
                    component_text += token;
            }
        }

        token = GetNextToken(input);
    }

    std::sort(xml_components.begin(), xml_components.end());
    for (const auto &component : xml_components)
        (*output) << component.toString() << '\n';
}

int main(int argc, char *argv[]) {
    ::progname = argv[0];

    if (argc < 2)
        Usage();

    bool append(false);
    if (std::strcmp("--append", argv[1]) == 0) {
        append = true;
        --argc, ++argv;
    }

    if (argc != 3)
        Usage();

    const std::unique_ptr<File> input(FileUtil::OpenInputFileOrDie(argv[1]));
    const std::unique_ptr<File> output(append ? FileUtil::OpenForAppeningOrDie(argv[2])
                                              : FileUtil::OpenOutputFileOrDie(argv[2]));

    try {
        Convert(input.get(), output.get());
    } catch (const std::exception &x) {
        Error("caught exception: " + std::string(x.what()));
    }
}

<|endoftext|>