<commit_before>#include "stdafx.h"
#include "BrowserHandlers.h"
#include <wrapper/cef_helpers.h>
#include <base/cef_bind.h>

//TID_UI ̡߳߳ӦóڵõCefInitialize()ʱCefSettings.multi_threaded_message_loop = false߳ҲӦó̡߳
//TID_IO ߳ҪIPCϢԼͨš
//TID_FILE ̸߳ļϵͳ

// 1.  User clicks the window close button which sends an OS close
//     notification (e.g. WM_CLOSE on Windows, performClose: on OS-X and
//     "delete_event" on Linux).
// 2.  Application's top-level window receives the close notification and:
//     A. Calls CefBrowserHost::CloseBrowser(false).
//     B. Cancels the window close.
// 3.  JavaScript 'onbeforeunload' handler executes and shows the close
//     confirmation dialog (which can be overridden via
//     CefJSDialogHandler::OnBeforeUnloadDialog()).
// 4.  User approves the close.
// 5.  JavaScript 'onunload' handler executes.
// 6.  Application's DoClose() handler is called. Application will:
//     A. Set a flag to indicate that the next close attempt will be allowed.
//     B. Return false.
// 7.  CEF sends an OS close notification.
// 8.  Application's top-level window receives the OS close notification and
//     allows the window to close based on the flag from #6B.
// 9.  Browser OS window is destroyed.
// 10. Application's CefLifeSpanHandler::OnBeforeClose() handler is called and
//     the browser object is destroyed.
// 11. Application exits by calling CefQuitMessageLoop() if no other browsers
//     exist.
///

CCefClientHandler::CCefClientHandler() :hWnd_(NULL), is_closing_(false)
{
}

CCefClientHandler::~CCefClientHandler()
{

}

// CefClient methods:
CefRefPtr<CefDisplayHandler> CCefClientHandler::GetDisplayHandler()
{
	return this;
}
CefRefPtr<CefLifeSpanHandler> CCefClientHandler::GetLifeSpanHandler()
{
	return this;
}
CefRefPtr<CefLoadHandler> CCefClientHandler::GetLoadHandler()
{
	return this;
}

CefRefPtr<CefRequestHandler> CCefClientHandler::GetRequestHandler()
{
	return this;
}

// һָbrowser
void CCefClientHandler::OnAfterCreated(CefRefPtr<CefBrowser> browser)
{
	// Add to the list of existing browsers.
	browser_list_.push_back(browser);

	int nID = browser->GetIdentifier();

	::PostMessage(hWnd_, UM_CEF_AFTERCREATED, nID, 0);

}

bool CCefClientHandler::DoClose(CefRefPtr<CefBrowser> browser)
{
	//TID_UI ̡߳߳
	CEF_REQUIRE_UI_THREAD();
//	AutoLock lock_scope(this);

	lock_.Acquire();

	// Remove from the list of existing browsers.
	BrowserList::iterator bit = browser_list_.begin();

	for (; bit != browser_list_.end(); bit++)
	{
		if ((*bit)->IsSame(browser))
		{
			browser_list_.erase(bit);
			browser = NULL;
			break;
		}
	}

	lock_.Release();

	if (browser_list_.size() == 0) {
		// Set a flag to indicate that the window close should be allowed.
		is_closing_ = true;

		::PostMessage(hWnd_, UM_CEF_POSTQUITMESSAGE, 0, 0);
	}

	return false;
}

void CCefClientHandler::OnBeforeClose(CefRefPtr<CefBrowser> browser)
{
	CEF_REQUIRE_UI_THREAD();

	AutoLock lock_scope(this);
//	lock_.Acquire();

	BrowserList::iterator bit = browser_list_.begin();

	for (; bit != browser_list_.end(); bit++)
	{
		if ((*bit)->IsSame(browser))
		{
			browser_list_.erase(bit);
			browser = NULL;
			break;
		}
	}

	if (browser_list_.empty())
	{
		is_closing_ = true;
		::PostMessage(hWnd_, UM_CEF_POSTQUITMESSAGE, 0, 0);
		// All browser windows have closed. Quit the application message loop.
		//CefQuitMessageLoop();
		//PostQuitMessage(0l);
	}

//	lock_.Release();
}

void CCefClientHandler::OnLoadStart(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame)
{
	CEF_REQUIRE_UI_THREAD();

	CefString* strTmpURL = new CefString(browser->GetMainFrame()->GetURL());
	int nID = browser->GetIdentifier();
	::PostMessage(hWnd_, UM_CEF_WEBLOADSTART, nID, (LPARAM)strTmpURL);

	//return __super::OnLoadStart(browser, frame);
}
void CCefClientHandler::OnLoadEnd(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, int httpStatusCode)
{
	CEF_REQUIRE_UI_THREAD();

	CefString* strTmpURL = new CefString(browser->GetMainFrame()->GetURL());
	int nID = browser->GetIdentifier();
	::PostMessage(hWnd_, UM_CEF_WEBLOADEND, nID, (LPARAM)strTmpURL);

}

void CCefClientHandler::OnLoadError(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, ErrorCode errorCode, const CefString& errorText, const CefString& failedUrl)
{
	CEF_REQUIRE_UI_THREAD();

	// Don't display an error for downloaded files.
	if (errorCode == ERR_ABORTED)
		return;

	// Display a load error message.
	std::stringstream ss;
	ss << ""
		"
Failed to load URL " << std::string(failedUrl) <<
		" with error " << std::string(errorText) << " (" << errorCode <<
		").
";
	frame->LoadString(ss.str(), failedUrl);
}

void CCefClientHandler::OnTitleChange(CefRefPtr<CefBrowser> browser, const CefString& title)
{
	CEF_REQUIRE_UI_THREAD();

	// globally unique identifier for this browser
	int nID=browser->GetIdentifier();

	CefString* strTitle = new CefString(title);
	::PostMessage(hWnd_, UM_CEF_WEBTITLECHANGE, nID, (LPARAM)strTitle);
}

bool CCefClientHandler::OnBeforePopup(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, const CefString& target_url, const CefString& target_frame_name, CefLifeSpanHandler::WindowOpenDisposition target_disposition,
	bool user_gesture, const CefPopupFeatures& popupFeatures, CefWindowInfo& windowInfo, CefRefPtr<CefClient>& client, CefBrowserSettings& settings, bool* no_javascript_access)
{

	//ϢǵdeleteַԴ
	CefString* strTargetURL = new CefString(target_url);
	::PostMessage(hWnd_, UM_CEF_WEBLOADPOPUP, (WPARAM)0, (LPARAM)strTargetURL);
	return true;

}

#define MENU_ID_USER_OPENLINK  MENU_ID_USER_FIRST+200

void CCefClientHandler::OnBeforeContextMenu(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame,CefRefPtr<CefContextMenuParams> params, CefRefPtr<CefMenuModel> model)
{
	//ԼҪĲ˵
	cef_context_menu_type_flags_t flag = params->GetTypeFlags();

	if (flag&CM_TYPEFLAG_LINK)
	{
		model->Clear(); //в˵

		model->AddItem(MENU_ID_USER_OPENLINK, L"±ǩҳд(&T)...");//Ӳ˵
		model->AddSeparator(); //ӷָ
		model->AddItem(MENU_ID_COPY, L"");//Ӳ˵
		//model->SetEnabled(MENU_ID_USER_OPENLINK, false); //ò˵
		return;
	}

	if (flag & CM_TYPEFLAG_PAGE)
	{//ͨҳҼϢ
		model->SetLabel(MENU_ID_BACK, L"");
		model->SetLabel(MENU_ID_FORWARD, L"ǰ");
		model->SetLabel(MENU_ID_VIEW_SOURCE, L"鿴Դ");
		model->SetLabel(MENU_ID_PRINT, L"ӡ");
		model->SetLabel(MENU_ID_RELOAD, L"ˢ");
		model->SetLabel(MENU_ID_RELOAD_NOCACHE, L"ǿˢ");
		model->SetLabel(MENU_ID_STOPLOAD, L"ֹͣ");
		model->SetLabel(MENU_ID_REDO, L"ظ");

	}
	if (flag & CM_TYPEFLAG_EDITABLE)
	{//༭ҼϢ
		model->SetLabel(MENU_ID_UNDO, L"");
		model->SetLabel(MENU_ID_REDO, L"");
		model->SetLabel(MENU_ID_CUT, L"");
		model->SetLabel(MENU_ID_COPY, L"");
		model->SetLabel(MENU_ID_PASTE, L"ճ");
		model->SetLabel(MENU_ID_DELETE, L"ɾ");
		model->SetLabel(MENU_ID_SELECT_ALL, L"ȫѡ");
	}

}

bool CCefClientHandler::OnContextMenuCommand(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame,CefRefPtr<CefContextMenuParams> params, int command_id, EventFlags event_flags)
{
	CefString strLinkURL;
	CefString strURLLink;
	CefString* strTargetURL = nullptr;

	switch (command_id)
	{

	case MENU_ID_USER_OPENLINK:

		strTargetURL = new CefString(params->GetLinkUrl());
		::PostMessage(hWnd_, UM_CEF_WEBLOADPOPUP, (WPARAM)0, (LPARAM)strTargetURL);

		//strLinkURL = params->GetLinkUrl();
		//strURLLink = params->GetUnfilteredLinkUrl();
		break;
	default:
		break;
	}

	return false;
}

void CCefClientHandler::CloseHostBrowser(CefRefPtr<CefBrowser>browser, bool force_close)
{

	if (!CefCurrentlyOn(TID_UI))
	{
		// Execute on the UI thread.
		CefPostTask(TID_UI, base::Bind(&CCefClientHandler::CloseHostBrowser, this,browser, force_close));
		return;
	}

	int nID = browser->GetIdentifier();

	::PostMessage(hWnd_, UM_CEF_BROWSERCLOSE, nID, 0);

	browser->GetHost()->CloseBrowser(force_close);
}

void CCefClientHandler::CloseAllBrowsers(bool force_close)
{
	//if (!CefCurrentlyOn(TID_UI))
	//{
	//	// Execute on the UI thread.
	//	CefPostTask(TID_UI, base::Bind(&CCefClientHandler::CloseAllBrowsers, this, force_close));
	//	return;
	//}

	lock_.Acquire();

	if (browser_list_.empty())
		return;

	BrowserList::const_iterator it = browser_list_.begin();
	for (; it != browser_list_.end(); ++it)
	{
		(*it)->GetHost()->CloseBrowser(force_close);

	}

	lock_.Release();

}

bool CCefClientHandler::IsClosing() const
{
	return is_closing_;
}

<commit_msg>增加右键复制链接到剪切板功能<commit_after>#include "stdafx.h"
#include "BrowserHandlers.h"
#include <wrapper/cef_helpers.h>
#include <base/cef_bind.h>

//TID_UI ̡߳߳ӦóڵõCefInitialize()ʱCefSettings.multi_threaded_message_loop = false߳ҲӦó̡߳
//TID_IO ߳ҪIPCϢԼͨš
//TID_FILE ̸߳ļϵͳ

// 1.  User clicks the window close button which sends an OS close
//     notification (e.g. WM_CLOSE on Windows, performClose: on OS-X and
//     "delete_event" on Linux).
// 2.  Application's top-level window receives the close notification and:
//     A. Calls CefBrowserHost::CloseBrowser(false).
//     B. Cancels the window close.
// 3.  JavaScript 'onbeforeunload' handler executes and shows the close
//     confirmation dialog (which can be overridden via
//     CefJSDialogHandler::OnBeforeUnloadDialog()).
// 4.  User approves the close.
// 5.  JavaScript 'onunload' handler executes.
// 6.  Application's DoClose() handler is called. Application will:
//     A. Set a flag to indicate that the next close attempt will be allowed.
//     B. Return false.
// 7.  CEF sends an OS close notification.
// 8.  Application's top-level window receives the OS close notification and
//     allows the window to close based on the flag from #6B.
// 9.  Browser OS window is destroyed.
// 10. Application's CefLifeSpanHandler::OnBeforeClose() handler is called and
//     the browser object is destroyed.
// 11. Application exits by calling CefQuitMessageLoop() if no other browsers
//     exist.
///

CCefClientHandler::CCefClientHandler() :hWnd_(NULL), is_closing_(false)
{
}

CCefClientHandler::~CCefClientHandler()
{

}

// CefClient methods:
CefRefPtr<CefDisplayHandler> CCefClientHandler::GetDisplayHandler()
{
	return this;
}
CefRefPtr<CefLifeSpanHandler> CCefClientHandler::GetLifeSpanHandler()
{
	return this;
}
CefRefPtr<CefLoadHandler> CCefClientHandler::GetLoadHandler()
{
	return this;
}

CefRefPtr<CefRequestHandler> CCefClientHandler::GetRequestHandler()
{
	return this;
}

// һָbrowser
void CCefClientHandler::OnAfterCreated(CefRefPtr<CefBrowser> browser)
{
	// Add to the list of existing browsers.
	browser_list_.push_back(browser);

	int nID = browser->GetIdentifier();

	::PostMessage(hWnd_, UM_CEF_AFTERCREATED, nID, 0);

}

bool CCefClientHandler::DoClose(CefRefPtr<CefBrowser> browser)
{
	//TID_UI ̡߳߳
	CEF_REQUIRE_UI_THREAD();
//	AutoLock lock_scope(this);

	lock_.Acquire();

	// Remove from the list of existing browsers.
	BrowserList::iterator bit = browser_list_.begin();

	for (; bit != browser_list_.end(); bit++)
	{
		if ((*bit)->IsSame(browser))
		{
			browser_list_.erase(bit);
			browser = NULL;
			break;
		}
	}

	lock_.Release();

	if (browser_list_.size() == 0) {
		// Set a flag to indicate that the window close should be allowed.
		is_closing_ = true;

		::PostMessage(hWnd_, UM_CEF_POSTQUITMESSAGE, 0, 0);
	}

	return false;
}

void CCefClientHandler::OnBeforeClose(CefRefPtr<CefBrowser> browser)
{
	CEF_REQUIRE_UI_THREAD();

	AutoLock lock_scope(this);
//	lock_.Acquire();

	BrowserList::iterator bit = browser_list_.begin();

	for (; bit != browser_list_.end(); bit++)
	{
		if ((*bit)->IsSame(browser))
		{
			browser_list_.erase(bit);
			browser = NULL;
			break;
		}
	}

	if (browser_list_.empty())
	{
		is_closing_ = true;
		::PostMessage(hWnd_, UM_CEF_POSTQUITMESSAGE, 0, 0);
		// All browser windows have closed. Quit the application message loop.
		//CefQuitMessageLoop();
		//PostQuitMessage(0l);
	}

//	lock_.Release();
}

void CCefClientHandler::OnLoadStart(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame)
{
	CEF_REQUIRE_UI_THREAD();

	CefString* strTmpURL = new CefString(browser->GetMainFrame()->GetURL());
	int nID = browser->GetIdentifier();
	::PostMessage(hWnd_, UM_CEF_WEBLOADSTART, nID, (LPARAM)strTmpURL);

	//return __super::OnLoadStart(browser, frame);
}
void CCefClientHandler::OnLoadEnd(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, int httpStatusCode)
{
	CEF_REQUIRE_UI_THREAD();

	CefString* strTmpURL = new CefString(browser->GetMainFrame()->GetURL());
	int nID = browser->GetIdentifier();
	::PostMessage(hWnd_, UM_CEF_WEBLOADEND, nID, (LPARAM)strTmpURL);

}

void CCefClientHandler::OnLoadError(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, ErrorCode errorCode, const CefString& errorText, const CefString& failedUrl)
{
	CEF_REQUIRE_UI_THREAD();

	// Don't display an error for downloaded files.
	if (errorCode == ERR_ABORTED)
		return;

	// Display a load error message.
	std::stringstream ss;
	ss << ""
		"
Failed to load URL " << std::string(failedUrl) <<
		" with error " << std::string(errorText) << " (" << errorCode <<
		").
";
	frame->LoadString(ss.str(), failedUrl);
}

void CCefClientHandler::OnTitleChange(CefRefPtr<CefBrowser> browser, const CefString& title)
{
	CEF_REQUIRE_UI_THREAD();

	// globally unique identifier for this browser
	int nID=browser->GetIdentifier();

	CefString* strTitle = new CefString(title);
	::PostMessage(hWnd_, UM_CEF_WEBTITLECHANGE, nID, (LPARAM)strTitle);
}

bool CCefClientHandler::OnBeforePopup(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, const CefString& target_url, const CefString& target_frame_name, CefLifeSpanHandler::WindowOpenDisposition target_disposition,
	bool user_gesture, const CefPopupFeatures& popupFeatures, CefWindowInfo& windowInfo, CefRefPtr<CefClient>& client, CefBrowserSettings& settings, bool* no_javascript_access)
{

	//ϢǵdeleteַԴ
	CefString* strTargetURL = new CefString(target_url);
	::PostMessage(hWnd_, UM_CEF_WEBLOADPOPUP, (WPARAM)0, (LPARAM)strTargetURL);
	return true;

}

#define MENU_ID_USER_OPENLINK  MENU_ID_USER_FIRST+200
#define MENU_ID_USER_COPYLINK  MENU_ID_USER_FIRST+201

void CCefClientHandler::OnBeforeContextMenu(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame,CefRefPtr<CefContextMenuParams> params, CefRefPtr<CefMenuModel> model)
{
	//ԼҪĲ˵
	cef_context_menu_type_flags_t flag = params->GetTypeFlags();

	if (flag&CM_TYPEFLAG_LINK)
	{
		model->Clear(); //в˵

		model->AddItem(MENU_ID_USER_OPENLINK, L"±ǩҳд(&T)");//Ӳ˵
		model->AddSeparator(); //ӷָ
		model->AddItem(MENU_ID_USER_COPYLINK, L"ӵַ(&C)");//Ӳ˵
		//model->SetEnabled(MENU_ID_USER_OPENLINK, false); //ò˵
		return;
	}

	if (flag & CM_TYPEFLAG_PAGE)
	{//ͨҳҼϢ

		model->SetLabel(MENU_ID_BACK, L"");
		model->SetLabel(MENU_ID_FORWARD, L"ǰ");
		model->SetLabel(MENU_ID_VIEW_SOURCE, L"鿴Դ");
		model->SetLabel(MENU_ID_PRINT, L"ӡ");
		model->AddItem(MENU_ID_RELOAD, L"ˢ");
		model->AddItem(MENU_ID_RELOAD_NOCACHE, L"ǿˢ");
		model->AddItem(MENU_ID_STOPLOAD, L"ֹͣ");
		model->SetLabel(MENU_ID_REDO, L"ظ");

	}
	if (flag & CM_TYPEFLAG_EDITABLE)
	{//༭ҼϢ
		model->SetLabel(MENU_ID_UNDO, L"");
		model->SetLabel(MENU_ID_REDO, L"");
		model->SetLabel(MENU_ID_CUT, L"");
		model->SetLabel(MENU_ID_COPY, L"");
		model->SetLabel(MENU_ID_PASTE, L"ճ");
		model->SetLabel(MENU_ID_DELETE, L"ɾ");
		model->SetLabel(MENU_ID_SELECT_ALL, L"ȫѡ");
	}

}

bool CCefClientHandler::OnContextMenuCommand(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame,CefRefPtr<CefContextMenuParams> params, int command_id, EventFlags event_flags)
{
	//CefString strLinkURL;
	CefString strURLLink;
	CefString* strTargetURL = nullptr;
	HGLOBAL hglbCopy;
	LPTSTR  lptstrCopy;
	int nBuffLength = 0;

	switch (command_id)
	{

	case MENU_ID_USER_OPENLINK:

		strTargetURL = new CefString(params->GetLinkUrl());
		::PostMessage(hWnd_, UM_CEF_WEBLOADPOPUP, (WPARAM)0, (LPARAM)strTargetURL);
		break;
	case MENU_ID_USER_COPYLINK:

		if (!OpenClipboard(frame->GetBrowser().get()->GetHost().get()->GetWindowHandle()))
		{
			return FALSE;
		}

		EmptyClipboard();

		// Allocate a global memory object for the text.

		strURLLink = params->GetUnfilteredLinkUrl();

		if (strURLLink.length()!=0)
		{
			nBuffLength = (strURLLink.length() + 1) * sizeof(TCHAR);

			hglbCopy = GlobalAlloc(GMEM_MOVEABLE, nBuffLength);

			if (hglbCopy == NULL)
			{
				CloseClipboard();
				return FALSE;
			}

			// Lock the handle and copy the text to the buffer.

			lptstrCopy = (LPTSTR)::GlobalLock(hglbCopy);
			memset(lptstrCopy, '\0', nBuffLength);
			memcpy(lptstrCopy, strURLLink.c_str(), nBuffLength- sizeof(TCHAR));

			GlobalUnlock(hglbCopy); //
			// Place the handle on the clipboard.

			//SetClipboardData(CF_TEXT, hglbCopy);
			SetClipboardData(CF_UNICODETEXT, hglbCopy);// CF_UNICODETEXTΪUnicode

		}

		CloseClipboard();

		break;
	default:
		break;
	}

	return false;
}

void CCefClientHandler::CloseHostBrowser(CefRefPtr<CefBrowser>browser, bool force_close)
{

	if (!CefCurrentlyOn(TID_UI))
	{
		// Execute on the UI thread.
		CefPostTask(TID_UI, base::Bind(&CCefClientHandler::CloseHostBrowser, this,browser, force_close));
		return;
	}

	int nID = browser->GetIdentifier();

	::PostMessage(hWnd_, UM_CEF_BROWSERCLOSE, nID, 0);

	browser->GetHost()->CloseBrowser(force_close);
}

void CCefClientHandler::CloseAllBrowsers(bool force_close)
{
	//if (!CefCurrentlyOn(TID_UI))
	//{
	//	// Execute on the UI thread.
	//	CefPostTask(TID_UI, base::Bind(&CCefClientHandler::CloseAllBrowsers, this, force_close));
	//	return;
	//}

	lock_.Acquire();

	if (browser_list_.empty())
		return;

	BrowserList::const_iterator it = browser_list_.begin();
	for (; it != browser_list_.end(); ++it)
	{
		(*it)->GetHost()->CloseBrowser(force_close);

	}

	lock_.Release();

}

bool CCefClientHandler::IsClosing() const
{
	return is_closing_;
}

<|endoftext|>


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

#include "ui/views/bubble/bubble_delegate.h"

#include "ui/base/accessibility/accessible_view_state.h"
#include "ui/gfx/animation/slide_animation.h"
#include "ui/gfx/color_utils.h"
#include "ui/gfx/rect.h"
#include "ui/native_theme/native_theme.h"
#include "ui/views/bubble/bubble_frame_view.h"
#include "ui/views/focus/view_storage.h"
#include "ui/views/widget/widget.h"
#include "ui/views/widget/widget_observer.h"

#if defined(OS_WIN)
#include "ui/base/win/shell.h"
#endif

// The duration of the fade animation in milliseconds.
static const int kHideFadeDurationMS = 200;

// The defaut margin between the content and the inside border, in pixels.
static const int kDefaultMargin = 6;

namespace views {

namespace {

// Create a widget to host the bubble.
Widget* CreateBubbleWidget(BubbleDelegateView* bubble) {
  Widget* bubble_widget = new Widget();
  Widget::InitParams bubble_params(Widget::InitParams::TYPE_BUBBLE);
  bubble_params.delegate = bubble;
  bubble_params.opacity = Widget::InitParams::TRANSLUCENT_WINDOW;
  bubble_params.accept_events = bubble->accept_events();
  if (bubble->parent_window())
    bubble_params.parent = bubble->parent_window();
  else if (bubble->anchor_widget())
    bubble_params.parent = bubble->anchor_widget()->GetNativeView();
  bubble_params.can_activate = bubble->CanActivate();
  bubble->OnBeforeBubbleWidgetInit(&bubble_params, bubble_widget);
  bubble_widget->Init(bubble_params);
  return bubble_widget;
}

}  // namespace

BubbleDelegateView::BubbleDelegateView()
    : close_on_esc_(true),
      close_on_deactivate_(true),
      anchor_view_storage_id_(ViewStorage::GetInstance()->CreateStorageID()),
      anchor_widget_(NULL),
      move_with_anchor_(false),
      arrow_(BubbleBorder::TOP_LEFT),
      shadow_(BubbleBorder::SMALL_SHADOW),
      color_explicitly_set_(false),
      margins_(kDefaultMargin, kDefaultMargin, kDefaultMargin, kDefaultMargin),
      original_opacity_(255),
      use_focusless_(false),
      accept_events_(true),
      border_accepts_events_(true),
      adjust_if_offscreen_(true),
      parent_window_(NULL) {
  AddAccelerator(ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_NONE));
  UpdateColorsFromTheme(GetNativeTheme());
}

BubbleDelegateView::BubbleDelegateView(
    View* anchor_view,
    BubbleBorder::Arrow arrow)
    : close_on_esc_(true),
      close_on_deactivate_(true),
      anchor_view_storage_id_(ViewStorage::GetInstance()->CreateStorageID()),
      anchor_widget_(NULL),
      move_with_anchor_(false),
      arrow_(arrow),
      shadow_(BubbleBorder::SMALL_SHADOW),
      color_explicitly_set_(false),
      margins_(kDefaultMargin, kDefaultMargin, kDefaultMargin, kDefaultMargin),
      original_opacity_(255),
      use_focusless_(false),
      accept_events_(true),
      border_accepts_events_(true),
      adjust_if_offscreen_(true),
      parent_window_(NULL) {
  SetAnchorView(anchor_view);
  AddAccelerator(ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_NONE));
  UpdateColorsFromTheme(GetNativeTheme());
}

BubbleDelegateView::~BubbleDelegateView() {
  SetLayoutManager(NULL);
  SetAnchorView(NULL);
}

// static
Widget* BubbleDelegateView::CreateBubble(BubbleDelegateView* bubble_delegate) {
  bubble_delegate->Init();
  // Get the latest anchor widget from the anchor view at bubble creation time.
  bubble_delegate->SetAnchorView(bubble_delegate->GetAnchorView());
  Widget* bubble_widget = CreateBubbleWidget(bubble_delegate);

#if defined(OS_WIN)
  // If glass is enabled, the bubble is allowed to extend outside the bounds of
  // the parent frame and let DWM handle compositing.  If not, then we don't
  // want to allow the bubble to extend the frame because it will be clipped.
  bubble_delegate->set_adjust_if_offscreen(ui::win::IsAeroGlassEnabled());
#endif

  bubble_delegate->SizeToContents();
  bubble_widget->AddObserver(bubble_delegate);
  return bubble_widget;
}

BubbleDelegateView* BubbleDelegateView::AsBubbleDelegate() {
  return this;
}

bool BubbleDelegateView::CanActivate() const {
  return !use_focusless();
}

bool BubbleDelegateView::ShouldShowCloseButton() const {
  return false;
}

View* BubbleDelegateView::GetContentsView() {
  return this;
}

NonClientFrameView* BubbleDelegateView::CreateNonClientFrameView(
    Widget* widget) {
  BubbleFrameView* frame = new BubbleFrameView(margins());
  BubbleBorder::Arrow adjusted_arrow = arrow();
  if (base::i18n::IsRTL())
    adjusted_arrow = BubbleBorder::horizontal_mirror(adjusted_arrow);
  frame->SetBubbleBorder(scoped_ptr<BubbleBorder>(
      new BubbleBorder(adjusted_arrow, shadow(), color())));
  return frame;
}

void BubbleDelegateView::GetAccessibleState(ui::AccessibleViewState* state) {
  state->role = ui::AccessibilityTypes::ROLE_DIALOG;
}

void BubbleDelegateView::OnWidgetDestroying(Widget* widget) {
  if (anchor_widget() == widget)
    SetAnchorView(NULL);
}

void BubbleDelegateView::OnWidgetVisibilityChanging(Widget* widget,
                                                    bool visible) {
#if defined(OS_WIN)
  // On Windows we need to handle this before the bubble is visible or hidden.
  // Please see the comment on the OnWidgetVisibilityChanging function. On
  // other platforms it is fine to handle it after the bubble is shown/hidden.
  HandleVisibilityChanged(widget, visible);
#endif
}

void BubbleDelegateView::OnWidgetVisibilityChanged(Widget* widget,
                                                   bool visible) {
#if !defined(OS_WIN)
  HandleVisibilityChanged(widget, visible);
#endif
}

void BubbleDelegateView::OnWidgetActivationChanged(Widget* widget,
                                                   bool active) {
  if (close_on_deactivate() && widget == GetWidget() && !active)
    GetWidget()->Close();
}

void BubbleDelegateView::OnWidgetBoundsChanged(Widget* widget,
                                               const gfx::Rect& new_bounds) {
  if (anchor_widget() == widget) {
    if (move_with_anchor())
      SizeToContents();
    else
      GetWidget()->Close();
  }
}

View* BubbleDelegateView::GetAnchorView() const {
  return ViewStorage::GetInstance()->RetrieveView(anchor_view_storage_id_);
}

gfx::Rect BubbleDelegateView::GetAnchorRect() {
  if (!GetAnchorView())
    return anchor_rect_;

  anchor_rect_ = GetAnchorView()->GetBoundsInScreen();
  anchor_rect_.Inset(anchor_view_insets_);
  return anchor_rect_;
}

void BubbleDelegateView::OnBeforeBubbleWidgetInit(Widget::InitParams* params,
                                                  Widget* widget) const {
}

void BubbleDelegateView::StartFade(bool fade_in) {
#if defined(USE_AURA)
  // Use AURA's window layer animation instead of fading. This ensures that
  // hosts which rely on the layer animation callbacks to close the window
  // work correctly.
  if (fade_in)
    GetWidget()->Show();
  else
    GetWidget()->Close();
#else
  fade_animation_.reset(new gfx::SlideAnimation(this));
  fade_animation_->SetSlideDuration(GetFadeDuration());
  fade_animation_->Reset(fade_in ? 0.0 : 1.0);
  if (fade_in) {
    original_opacity_ = 0;
    GetWidget()->SetOpacity(original_opacity_);
    GetWidget()->Show();
    fade_animation_->Show();
  } else {
    original_opacity_ = 255;
    fade_animation_->Hide();
  }
#endif
}

void BubbleDelegateView::ResetFade() {
  fade_animation_.reset();
  GetWidget()->SetOpacity(original_opacity_);
}

void BubbleDelegateView::SetAlignment(BubbleBorder::BubbleAlignment alignment) {
  GetBubbleFrameView()->bubble_border()->set_alignment(alignment);
  SizeToContents();
}

void BubbleDelegateView::SetArrowPaintType(
    BubbleBorder::ArrowPaintType paint_type) {
  GetBubbleFrameView()->bubble_border()->set_paint_arrow(paint_type);
  SizeToContents();
}

void BubbleDelegateView::OnAnchorBoundsChanged() {
  SizeToContents();
}

bool BubbleDelegateView::AcceleratorPressed(
    const ui::Accelerator& accelerator) {
  if (!close_on_esc() || accelerator.key_code() != ui::VKEY_ESCAPE)
    return false;
  if (fade_animation_.get())
    fade_animation_->Reset();
  GetWidget()->Close();
  return true;
}

void BubbleDelegateView::OnNativeThemeChanged(const ui::NativeTheme* theme) {
  UpdateColorsFromTheme(theme);
}

void BubbleDelegateView::AnimationEnded(const gfx::Animation* animation) {
  if (animation != fade_animation_.get())
    return;
  bool closed = fade_animation_->GetCurrentValue() == 0;
  fade_animation_->Reset();
  if (closed)
    GetWidget()->Close();
}

void BubbleDelegateView::AnimationProgressed(const gfx::Animation* animation) {
  if (animation != fade_animation_.get())
    return;
  DCHECK(fade_animation_->is_animating());
  GetWidget()->SetOpacity(fade_animation_->GetCurrentValue() * 255);
}

void BubbleDelegateView::Init() {}

void BubbleDelegateView::SetAnchorView(View* anchor_view) {
  // When the anchor view gets set the associated anchor widget might
  // change as well.
  if (!anchor_view || anchor_widget() != anchor_view->GetWidget()) {
    if (anchor_widget()) {
      anchor_widget_->RemoveObserver(this);
      anchor_widget_ = NULL;
    }
    if (anchor_view) {
      anchor_widget_ = anchor_view->GetWidget();
      if (anchor_widget_)
        anchor_widget_->AddObserver(this);
    }
  }

  // Remove the old storage item and set the new (if there is one).
  ViewStorage* view_storage = ViewStorage::GetInstance();
  if (view_storage->RetrieveView(anchor_view_storage_id_))
    view_storage->RemoveView(anchor_view_storage_id_);
  if (anchor_view)
    view_storage->StoreView(anchor_view_storage_id_, anchor_view);

  if (GetWidget())
    OnAnchorBoundsChanged();
}

void BubbleDelegateView::SetAnchorRect(const gfx::Rect& rect) {
  anchor_rect_ = rect;
  if (GetWidget())
    OnAnchorBoundsChanged();
}

void BubbleDelegateView::SizeToContents() {
  GetWidget()->SetBounds(GetBubbleBounds());
}

BubbleFrameView* BubbleDelegateView::GetBubbleFrameView() const {
  const NonClientView* view =
      GetWidget() ? GetWidget()->non_client_view() : NULL;
  return view ? static_cast<BubbleFrameView*>(view->frame_view()) : NULL;
}

gfx::Rect BubbleDelegateView::GetBubbleBounds() {
  // The argument rect has its origin at the bubble's arrow anchor point;
  // its size is the preferred size of the bubble's client view (this view).
  return GetBubbleFrameView()->GetUpdatedWindowBounds(GetAnchorRect(),
      GetPreferredSize(), adjust_if_offscreen_);
}

int BubbleDelegateView::GetFadeDuration() {
  return kHideFadeDurationMS;
}

void BubbleDelegateView::UpdateColorsFromTheme(const ui::NativeTheme* theme) {
  if (!color_explicitly_set_) {
    color_ = GetNativeTheme()->GetSystemColor(
        ui::NativeTheme::kColorId_WindowBackground);
  }
  set_background(Background::CreateSolidBackground(color()));
  BubbleFrameView* frame_view = GetBubbleFrameView();
  if (frame_view)
    frame_view->bubble_border()->set_background_color(color());
}

void BubbleDelegateView::HandleVisibilityChanged(Widget* widget, bool visible) {
  if (widget == GetWidget() && visible && anchor_widget() &&
      anchor_widget()->GetTopLevelWidget()) {
    anchor_widget()->GetTopLevelWidget()->DisableInactiveRendering();
  }
}

}  // namespace views
<commit_msg>linux_aura: Bubbles should release their lock on disable_inactive_rendering.<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ui/views/bubble/bubble_delegate.h"

#include "ui/base/accessibility/accessible_view_state.h"
#include "ui/gfx/animation/slide_animation.h"
#include "ui/gfx/color_utils.h"
#include "ui/gfx/rect.h"
#include "ui/native_theme/native_theme.h"
#include "ui/views/bubble/bubble_frame_view.h"
#include "ui/views/focus/view_storage.h"
#include "ui/views/widget/widget.h"
#include "ui/views/widget/widget_observer.h"

#if defined(OS_WIN)
#include "ui/base/win/shell.h"
#endif

// The duration of the fade animation in milliseconds.
static const int kHideFadeDurationMS = 200;

// The defaut margin between the content and the inside border, in pixels.
static const int kDefaultMargin = 6;

namespace views {

namespace {

// Create a widget to host the bubble.
Widget* CreateBubbleWidget(BubbleDelegateView* bubble) {
  Widget* bubble_widget = new Widget();
  Widget::InitParams bubble_params(Widget::InitParams::TYPE_BUBBLE);
  bubble_params.delegate = bubble;
  bubble_params.opacity = Widget::InitParams::TRANSLUCENT_WINDOW;
  bubble_params.accept_events = bubble->accept_events();
  if (bubble->parent_window())
    bubble_params.parent = bubble->parent_window();
  else if (bubble->anchor_widget())
    bubble_params.parent = bubble->anchor_widget()->GetNativeView();
  bubble_params.can_activate = bubble->CanActivate();
  bubble->OnBeforeBubbleWidgetInit(&bubble_params, bubble_widget);
  bubble_widget->Init(bubble_params);
  return bubble_widget;
}

}  // namespace

BubbleDelegateView::BubbleDelegateView()
    : close_on_esc_(true),
      close_on_deactivate_(true),
      anchor_view_storage_id_(ViewStorage::GetInstance()->CreateStorageID()),
      anchor_widget_(NULL),
      move_with_anchor_(false),
      arrow_(BubbleBorder::TOP_LEFT),
      shadow_(BubbleBorder::SMALL_SHADOW),
      color_explicitly_set_(false),
      margins_(kDefaultMargin, kDefaultMargin, kDefaultMargin, kDefaultMargin),
      original_opacity_(255),
      use_focusless_(false),
      accept_events_(true),
      border_accepts_events_(true),
      adjust_if_offscreen_(true),
      parent_window_(NULL) {
  AddAccelerator(ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_NONE));
  UpdateColorsFromTheme(GetNativeTheme());
}

BubbleDelegateView::BubbleDelegateView(
    View* anchor_view,
    BubbleBorder::Arrow arrow)
    : close_on_esc_(true),
      close_on_deactivate_(true),
      anchor_view_storage_id_(ViewStorage::GetInstance()->CreateStorageID()),
      anchor_widget_(NULL),
      move_with_anchor_(false),
      arrow_(arrow),
      shadow_(BubbleBorder::SMALL_SHADOW),
      color_explicitly_set_(false),
      margins_(kDefaultMargin, kDefaultMargin, kDefaultMargin, kDefaultMargin),
      original_opacity_(255),
      use_focusless_(false),
      accept_events_(true),
      border_accepts_events_(true),
      adjust_if_offscreen_(true),
      parent_window_(NULL) {
  SetAnchorView(anchor_view);
  AddAccelerator(ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_NONE));
  UpdateColorsFromTheme(GetNativeTheme());
}

BubbleDelegateView::~BubbleDelegateView() {
  SetLayoutManager(NULL);
  SetAnchorView(NULL);
}

// static
Widget* BubbleDelegateView::CreateBubble(BubbleDelegateView* bubble_delegate) {
  bubble_delegate->Init();
  // Get the latest anchor widget from the anchor view at bubble creation time.
  bubble_delegate->SetAnchorView(bubble_delegate->GetAnchorView());
  Widget* bubble_widget = CreateBubbleWidget(bubble_delegate);

#if defined(OS_WIN)
  // If glass is enabled, the bubble is allowed to extend outside the bounds of
  // the parent frame and let DWM handle compositing.  If not, then we don't
  // want to allow the bubble to extend the frame because it will be clipped.
  bubble_delegate->set_adjust_if_offscreen(ui::win::IsAeroGlassEnabled());
#endif

  bubble_delegate->SizeToContents();
  bubble_widget->AddObserver(bubble_delegate);
  return bubble_widget;
}

BubbleDelegateView* BubbleDelegateView::AsBubbleDelegate() {
  return this;
}

bool BubbleDelegateView::CanActivate() const {
  return !use_focusless();
}

bool BubbleDelegateView::ShouldShowCloseButton() const {
  return false;
}

View* BubbleDelegateView::GetContentsView() {
  return this;
}

NonClientFrameView* BubbleDelegateView::CreateNonClientFrameView(
    Widget* widget) {
  BubbleFrameView* frame = new BubbleFrameView(margins());
  BubbleBorder::Arrow adjusted_arrow = arrow();
  if (base::i18n::IsRTL())
    adjusted_arrow = BubbleBorder::horizontal_mirror(adjusted_arrow);
  frame->SetBubbleBorder(scoped_ptr<BubbleBorder>(
      new BubbleBorder(adjusted_arrow, shadow(), color())));
  return frame;
}

void BubbleDelegateView::GetAccessibleState(ui::AccessibleViewState* state) {
  state->role = ui::AccessibilityTypes::ROLE_DIALOG;
}

void BubbleDelegateView::OnWidgetDestroying(Widget* widget) {
  if (anchor_widget() == widget)
    SetAnchorView(NULL);
}

void BubbleDelegateView::OnWidgetVisibilityChanging(Widget* widget,
                                                    bool visible) {
#if defined(OS_WIN)
  // On Windows we need to handle this before the bubble is visible or hidden.
  // Please see the comment on the OnWidgetVisibilityChanging function. On
  // other platforms it is fine to handle it after the bubble is shown/hidden.
  HandleVisibilityChanged(widget, visible);
#endif
}

void BubbleDelegateView::OnWidgetVisibilityChanged(Widget* widget,
                                                   bool visible) {
#if !defined(OS_WIN)
  HandleVisibilityChanged(widget, visible);
#endif
}

void BubbleDelegateView::OnWidgetActivationChanged(Widget* widget,
                                                   bool active) {
  if (close_on_deactivate() && widget == GetWidget() && !active)
    GetWidget()->Close();
}

void BubbleDelegateView::OnWidgetBoundsChanged(Widget* widget,
                                               const gfx::Rect& new_bounds) {
  if (anchor_widget() == widget) {
    if (move_with_anchor())
      SizeToContents();
    else
      GetWidget()->Close();
  }
}

View* BubbleDelegateView::GetAnchorView() const {
  return ViewStorage::GetInstance()->RetrieveView(anchor_view_storage_id_);
}

gfx::Rect BubbleDelegateView::GetAnchorRect() {
  if (!GetAnchorView())
    return anchor_rect_;

  anchor_rect_ = GetAnchorView()->GetBoundsInScreen();
  anchor_rect_.Inset(anchor_view_insets_);
  return anchor_rect_;
}

void BubbleDelegateView::OnBeforeBubbleWidgetInit(Widget::InitParams* params,
                                                  Widget* widget) const {
}

void BubbleDelegateView::StartFade(bool fade_in) {
#if defined(USE_AURA)
  // Use AURA's window layer animation instead of fading. This ensures that
  // hosts which rely on the layer animation callbacks to close the window
  // work correctly.
  if (fade_in)
    GetWidget()->Show();
  else
    GetWidget()->Close();
#else
  fade_animation_.reset(new gfx::SlideAnimation(this));
  fade_animation_->SetSlideDuration(GetFadeDuration());
  fade_animation_->Reset(fade_in ? 0.0 : 1.0);
  if (fade_in) {
    original_opacity_ = 0;
    GetWidget()->SetOpacity(original_opacity_);
    GetWidget()->Show();
    fade_animation_->Show();
  } else {
    original_opacity_ = 255;
    fade_animation_->Hide();
  }
#endif
}

void BubbleDelegateView::ResetFade() {
  fade_animation_.reset();
  GetWidget()->SetOpacity(original_opacity_);
}

void BubbleDelegateView::SetAlignment(BubbleBorder::BubbleAlignment alignment) {
  GetBubbleFrameView()->bubble_border()->set_alignment(alignment);
  SizeToContents();
}

void BubbleDelegateView::SetArrowPaintType(
    BubbleBorder::ArrowPaintType paint_type) {
  GetBubbleFrameView()->bubble_border()->set_paint_arrow(paint_type);
  SizeToContents();
}

void BubbleDelegateView::OnAnchorBoundsChanged() {
  SizeToContents();
}

bool BubbleDelegateView::AcceleratorPressed(
    const ui::Accelerator& accelerator) {
  if (!close_on_esc() || accelerator.key_code() != ui::VKEY_ESCAPE)
    return false;
  if (fade_animation_.get())
    fade_animation_->Reset();
  GetWidget()->Close();
  return true;
}

void BubbleDelegateView::OnNativeThemeChanged(const ui::NativeTheme* theme) {
  UpdateColorsFromTheme(theme);
}

void BubbleDelegateView::AnimationEnded(const gfx::Animation* animation) {
  if (animation != fade_animation_.get())
    return;
  bool closed = fade_animation_->GetCurrentValue() == 0;
  fade_animation_->Reset();
  if (closed)
    GetWidget()->Close();
}

void BubbleDelegateView::AnimationProgressed(const gfx::Animation* animation) {
  if (animation != fade_animation_.get())
    return;
  DCHECK(fade_animation_->is_animating());
  GetWidget()->SetOpacity(fade_animation_->GetCurrentValue() * 255);
}

void BubbleDelegateView::Init() {}

void BubbleDelegateView::SetAnchorView(View* anchor_view) {
  // When the anchor view gets set the associated anchor widget might
  // change as well.
  if (!anchor_view || anchor_widget() != anchor_view->GetWidget()) {
    if (anchor_widget()) {
      anchor_widget_->RemoveObserver(this);
      anchor_widget_ = NULL;
    }
    if (anchor_view) {
      anchor_widget_ = anchor_view->GetWidget();
      if (anchor_widget_)
        anchor_widget_->AddObserver(this);
    }
  }

  // Remove the old storage item and set the new (if there is one).
  ViewStorage* view_storage = ViewStorage::GetInstance();
  if (view_storage->RetrieveView(anchor_view_storage_id_))
    view_storage->RemoveView(anchor_view_storage_id_);
  if (anchor_view)
    view_storage->StoreView(anchor_view_storage_id_, anchor_view);

  if (GetWidget())
    OnAnchorBoundsChanged();
}

void BubbleDelegateView::SetAnchorRect(const gfx::Rect& rect) {
  anchor_rect_ = rect;
  if (GetWidget())
    OnAnchorBoundsChanged();
}

void BubbleDelegateView::SizeToContents() {
  GetWidget()->SetBounds(GetBubbleBounds());
}

BubbleFrameView* BubbleDelegateView::GetBubbleFrameView() const {
  const NonClientView* view =
      GetWidget() ? GetWidget()->non_client_view() : NULL;
  return view ? static_cast<BubbleFrameView*>(view->frame_view()) : NULL;
}

gfx::Rect BubbleDelegateView::GetBubbleBounds() {
  // The argument rect has its origin at the bubble's arrow anchor point;
  // its size is the preferred size of the bubble's client view (this view).
  return GetBubbleFrameView()->GetUpdatedWindowBounds(GetAnchorRect(),
      GetPreferredSize(), adjust_if_offscreen_);
}

int BubbleDelegateView::GetFadeDuration() {
  return kHideFadeDurationMS;
}

void BubbleDelegateView::UpdateColorsFromTheme(const ui::NativeTheme* theme) {
  if (!color_explicitly_set_) {
    color_ = GetNativeTheme()->GetSystemColor(
        ui::NativeTheme::kColorId_WindowBackground);
  }
  set_background(Background::CreateSolidBackground(color()));
  BubbleFrameView* frame_view = GetBubbleFrameView();
  if (frame_view)
    frame_view->bubble_border()->set_background_color(color());
}

void BubbleDelegateView::HandleVisibilityChanged(Widget* widget, bool visible) {
  if (widget == GetWidget() && anchor_widget() &&
      anchor_widget()->GetTopLevelWidget()) {
    if (visible)
      anchor_widget()->GetTopLevelWidget()->DisableInactiveRendering();
    else
      anchor_widget()->GetTopLevelWidget()->EnableInactiveRendering();
  }
}

}  // namespace views
<|endoftext|>


<commit_before>//
//  main.cpp
//  wotstats
//
//  Created by Jan Temmerman on 14/05/12.
//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//

#include <iostream>
#include <string>

#include <boost/asio.hpp>

#include "HttpClient.h"

int main(int argc, const char * argv[])
{

    boost::asio::io_service io_service;
    HttpClient httpClient(io_service);
    httpClient.get("http://localhost/");
    return 0;
}

<commit_msg>processing WoT replay files: 	- extracting data blocks 	- decoding + extracting replay data block<commit_after>//
//  main.cpp
//  wotstats
//
//  Created by Jan Temmerman on 14/05/12.
//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//

#include <iostream>
#include <fstream>
#include <vector>
#include <cmath>

#include <boost/range/iterator_range.hpp>

#include <openssl/blowfish.h>
#include <zlib.h>

using std::ifstream;
using std::ofstream;
using std::ios;
using std::endl;
using std::cout;
using std::vector;
using std::ostream_iterator;
using boost::iterator_range;

typedef vector<char> buffer_t;
typedef iterator_range<buffer_t::iterator> data_block_t;

ios::pos_type get_size(std::istream& is) {
    is.seekg(0, ios::end);
    ios::pos_type size = is.tellg();
    is.seekg(0, ios::beg);
    return size;
}

void read(std::istream& is, buffer_t &buffer) {
    ios::pos_type size = get_size(is);
    buffer.resize(size);
    is.read(&buffer[0], size);
}

uint32_t number_of_data_blocks(buffer_t &buffer) {
    // number of data blocks is contained in an 'unsigned long' (4 bytes)
    // with an offset of 4 bytes from the beginning of te file
    const size_t offset = 4;
    uint32_t *nr_data_blocks = reinterpret_cast<uint32_t*>(&buffer[0] + offset);
    return *nr_data_blocks;
}

void get_data_blocks(buffer_t &buffer, vector<data_block_t> &data_blocks) {
    // determine number of data blocks
    uint32_t nr_data_blocks = number_of_data_blocks(buffer);

    // reserve enough place in data_blocks vector
    data_blocks.reserve(nr_data_blocks);

    // try to create a data block reference for each data block
    uint32_t data_block_sz_offset = 8;
    for (uint32_t ix = 0; ix < nr_data_blocks; ++ix) {
        // create data block
        uint32_t *block_size = reinterpret_cast<uint32_t*>(&buffer[0] + data_block_sz_offset);
        size_t data_block_offset = data_block_sz_offset + sizeof(uint32_t);
        auto data_block_beg = buffer.begin() + data_block_offset;
        auto data_block_end = data_block_beg + *block_size;
        data_blocks.emplace_back(data_block_beg, data_block_end);

        // modify offset for next data block
        data_block_sz_offset = data_block_offset + *block_size;
    }
}

int main(int argc, const char * argv[])
{
    std::string replay_file_name("/Users/jantemmerman/wotreplays/20120628_2039_germany-E-75_siegfried_line.wotreplay");
    cout << "Reading replay file: " << replay_file_name << "\n";

    // 0. read replay file fully into buffer
    ifstream is(replay_file_name, std::ios::binary);
    buffer_t buffer;
    read(is, buffer);
    is.close();

    // 1. determine number of data blocks
    uint32_t nr_data_blocks = number_of_data_blocks(buffer);
    std::cout << "Number of data blocks in replay file: " << nr_data_blocks << "\n";

    // 2. split the replay buffer into data blocks
    vector<data_block_t> data_blocks;
    get_data_blocks(buffer, data_blocks);

    cout << "\n";
    for (auto it = data_blocks.begin(); it != data_blocks.end(); ++it) {
        cout << "Block Index: " << (it - data_blocks.begin()) << "\n";
        cout << "Block Size: " << it->size() << "\n";
        cout << "Block Content:\n";
        std::copy(it->begin(), it->end(), ostream_iterator<char>(cout));
        cout << "\n\n";
    }

    // 3. rest is the replay data, encrypted + compressed
    auto &last_data_block = data_blocks.back();
    data_block_t replay_data = boost::make_iterator_range(last_data_block.end() + 8, buffer.end());

    ofstream os("/Users/jantemmerman/wotreplays/replay.dat", ios::binary | ios::ate);
    std::copy(replay_data.begin(), replay_data.end(), ostream_iterator<unsigned char>(os));
    cout << "Replay data size: " << replay_data.size() << "\n";
    os.close();

    ofstream decoded("/Users/jantemmerman/wotreplays/replay.decoded.dat", ios::binary | ios::ate);
    BF_KEY key;
    const unsigned char key_data[] = { 0xDE, 0x72, 0xBE, 0xA0, 0xDE, 0x04, 0xBE, 0xB1, 0xDE, 0xFE, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF};
    BF_set_key(&key, 16, reinterpret_cast<const unsigned char *>(&key_data));

    // TODO: make sure replay data's size is divisible by 8
    const int block_size = 8;
    unsigned char previous[block_size] = {0};
    for (auto it = replay_data.begin(); it != replay_data.end(); it += block_size) {
        unsigned char decrypted[block_size] = { 0 };
        BF_ecb_encrypt(reinterpret_cast<unsigned char*>(&(*it)), decrypted, &key, BF_DECRYPT);
        std::transform(previous, previous + block_size, decrypted, decrypted, std::bit_xor<unsigned char>());
        std::copy_n(decrypted, block_size, previous);
        std::copy_n(decrypted, block_size, reinterpret_cast<unsigned char*>(&(*it)));
    }

    std::copy(replay_data.begin(), replay_data.end(), ostream_iterator<unsigned char>(decoded));

    decoded.close();

    // 4. unzip this file
    z_stream strm = {
        .next_in = reinterpret_cast<unsigned char*>(&(replay_data[0])),
        .avail_in = static_cast<uInt>(replay_data.size())
    };

    int ret = inflateInit(&strm);

    if (ret != Z_OK) {
        std::cerr << "inflateInit() failed!\n";
        std::exit(1);
    }

    const int chunk = 16384;
    unsigned char out[chunk];

    vector<char> uncompressed_replay;

    do {
        strm.avail_out = chunk;
        strm.next_out = out;
        ret = inflate(&strm, Z_NO_FLUSH);

        assert(ret != Z_STREAM_ERROR);  /* state not clobbered */
        switch (ret) {
            case Z_NEED_DICT:
                ret = Z_DATA_ERROR;     /* and fall through */
            case Z_DATA_ERROR:
            case Z_MEM_ERROR:
                (void)inflateEnd(&strm);
                return ret;
        }

        int have = chunk - strm.avail_out;
        uncompressed_replay.resize(uncompressed_replay.size() + have);
        std::copy_n(out, have, uncompressed_replay.end() - have);

    } while (strm.avail_out == 0);

    (void)inflateEnd(&strm);

    if ( (ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR) == Z_OK )
        std::cout << "We're still OK!\n";

    ofstream uncompressed("/Users/jantemmerman/wotreplays/replay.uncompressed.decoded.dat", ios::binary | ios::ate);
    std::copy(uncompressed_replay.begin(), uncompressed_replay.end(), ostream_iterator<char>(uncompressed));
    uncompressed.close();

    return 0;
}

<|endoftext|>


<commit_before>#include <iostream>
#include <fstream>
#include <sstream>

#include <signal.h>

#include <llvm/ADT/OwningPtr.h>
#include <llvm/ADT/StringExtras.h>
#include <llvm/Support/CommandLine.h>
#include <llvm/System/Signals.h>

#include "Console.h"
#include "RemoteConsole.h"
#include "EditLineReader.h"

using std::string;
using ccons::Console;
using ccons::IConsole;
using ccons::RemoteConsole;
using ccons::LineReader;
using ccons::EditLineReader;
using ccons::StdInLineReader;
using ccons::SerializedConsoleOutput;

static llvm::cl::opt<bool>
	DebugMode("ccons-debug",
						llvm::cl::desc("Print debugging information"));
static llvm::cl::opt<bool>
	UseStdIo("ccons-use-std-io",
	         llvm::cl::desc("Use standard IO for input and output"));
static llvm::cl::opt<bool>
	SerializedOutput("ccons-serialized-output",
	                 llvm::cl::desc("Output will be serialized"));
static llvm::cl::opt<bool>
	MultiProcess("ccons-multi-process",
							 llvm::cl::desc("Run in multi-process mode"));

static std::stringstream ss_out;
static std::stringstream ss_err;

static IConsole * createConsole()
{
	if (MultiProcess)
		return new RemoteConsole;
	else if (SerializedOutput)
		return new Console(DebugMode, ss_out, ss_err);
	else
		return new Console(DebugMode);
}

static LineReader * createReader()
{
	if (UseStdIo)
		return new StdInLineReader;
	else
		return new EditLineReader;
}

void gotsig(int signo)
{
	string str;

	if (signo == SIGBUS) {
		str = "Bus error\n";
	} else if (signo == SIGSEGV) {
		str = "Segmentation fault\n";
	} else if (signo == SIGABRT) {
		str = "Abort trap\n";
	}

	SerializedConsoleOutput sco("", str, "", "");
	sco.writeToString(&str);
	std::cout << str;
	std::cout.flush();
	exit(-1);
}

void goodbye(void)
{
	string str;
	SerializedConsoleOutput sco("", "", "", "");
	sco.writeToString(&str);
	std::cout << str;
	std::cout.flush();
}

int main(const int argc, char **argv)
{
	llvm::cl::ParseCommandLineOptions(argc, argv, "ccons Interactive C Console\n",
	                                  false/*, "ccons-"*/);
	// TODO SetVersionPrinter()

/*
	TODO:
	Loading of external lib:
	#include <llvm/System/DynamicLibrary.h>
	char *libz = "/usr/lib/libz.dylib";
	llvm::sys::Path path(libz);
	if (path.isDynamicLibrary()) {
		std::string errMsg;
		llvm::sys::DynamicLibrary::LoadLibraryPermanently(libz, &errMsg);
	}
*/

	if (DebugMode) {
		std::cerr << "NOTE: Debugging information will be displayed.\n";
		llvm::sys::PrintStackTraceOnErrorSignal();
	} else if (SerializedOutput) {
		signal(SIGBUS, gotsig);
		signal(SIGSEGV, gotsig);
		signal(SIGABRT, gotsig);
		atexit(goodbye);
	} else if (MultiProcess) {
		signal(SIGCHLD, SIG_IGN);
	}

	llvm::OwningPtr<IConsole> console(createConsole());
	llvm::OwningPtr<LineReader> reader(createReader());

	const char *line = reader->readLine(console->prompt(), console->input());
	while (line) {
		console->process(line);
		if (SerializedOutput) {
			string str;
			SerializedConsoleOutput sco(ss_out.str(), ss_err.str(),
																	console->prompt(), console->input());
      sco.writeToString(&str);
			std::cout << str;
			std::cout.flush();
			ss_out.str("");
			ss_err.str("");
		}
		line = reader->readLine(console->prompt(), console->input());
	}

	return 0;
}

<commit_msg>more signal stuff<commit_after>#include <iostream>
#include <fstream>
#include <sstream>

#include <signal.h>

#include <llvm/ADT/OwningPtr.h>
#include <llvm/ADT/StringExtras.h>
#include <llvm/Support/CommandLine.h>
#include <llvm/System/Signals.h>

#include "Console.h"
#include "RemoteConsole.h"
#include "EditLineReader.h"

using std::string;
using ccons::Console;
using ccons::IConsole;
using ccons::RemoteConsole;
using ccons::LineReader;
using ccons::EditLineReader;
using ccons::StdInLineReader;
using ccons::SerializedConsoleOutput;

static llvm::cl::opt<bool>
	DebugMode("ccons-debug",
						llvm::cl::desc("Print debugging information"));
static llvm::cl::opt<bool>
	UseStdIo("ccons-use-std-io",
	         llvm::cl::desc("Use standard IO for input and output"));
static llvm::cl::opt<bool>
	SerializedOutput("ccons-serialized-output",
	                 llvm::cl::desc("Output will be serialized"));
static llvm::cl::opt<bool>
	MultiProcess("ccons-multi-process",
							 llvm::cl::desc("Run in multi-process mode"));

static std::stringstream ss_out;
static std::stringstream ss_err;

static IConsole * createConsole()
{
	if (MultiProcess)
		return new RemoteConsole;
	else if (SerializedOutput)
		return new Console(DebugMode, ss_out, ss_err);
	else
		return new Console(DebugMode);
}

static LineReader * createReader()
{
	if (UseStdIo)
		return new StdInLineReader;
	else
		return new EditLineReader;
}

void gotsig(int signo)
{
	string str = strsignal(signo);
	str += "\n";
	SerializedConsoleOutput sco("", str, "", "");
	sco.writeToString(&str);
	std::cout << str;
	std::cout.flush();
	exit(-1);
}

void goodbye(void)
{
	string str;
	SerializedConsoleOutput sco("", "", "", "");
	sco.writeToString(&str);
	std::cout << str;
	std::cout.flush();
}

int main(const int argc, char **argv)
{
	llvm::cl::ParseCommandLineOptions(argc, argv, "ccons Interactive C Console\n",
	                                  false/*, "ccons-"*/);
	// TODO SetVersionPrinter()

/*
	TODO:
	Loading of external lib:
	#include <llvm/System/DynamicLibrary.h>
	char *libz = "/usr/lib/libz.dylib";
	llvm::sys::Path path(libz);
	if (path.isDynamicLibrary()) {
		std::string errMsg;
		llvm::sys::DynamicLibrary::LoadLibraryPermanently(libz, &errMsg);
	}
*/

	if (DebugMode) {
		std::cerr << "NOTE: Debugging information will be displayed.\n";
		llvm::sys::PrintStackTraceOnErrorSignal();
	} else if (SerializedOutput) {
		signal(SIGBUS, gotsig);
		signal(SIGSEGV, gotsig);
		signal(SIGABRT, gotsig);
		signal(SIGTRAP, gotsig);
		signal(SIGILL, gotsig);
		signal(SIGFPE, gotsig);
		signal(SIGSYS, gotsig);
		signal(SIGXCPU, gotsig);
		signal(SIGXFSZ, gotsig);
		atexit(goodbye);
	} else if (MultiProcess) {
		signal(SIGCHLD, SIG_IGN);
	}

	llvm::OwningPtr<IConsole> console(createConsole());
	llvm::OwningPtr<LineReader> reader(createReader());

	const char *line = reader->readLine(console->prompt(), console->input());
	while (line) {
		console->process(line);
		if (SerializedOutput) {
			string str;
			SerializedConsoleOutput sco(ss_out.str(), ss_err.str(),
																	console->prompt(), console->input());
      sco.writeToString(&str);
			std::cout << str;
			std::cout.flush();
			ss_out.str("");
			ss_err.str("");
		}
		line = reader->readLine(console->prompt(), console->input());
	}

	return 0;
}

<|endoftext|>


<commit_before>#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <omp.h>

#define PAD 2*sizeof(double)

using namespace std;

double** createMatrix(int dim, bool zeroes){
    double **matrix = (double**) malloc(dim * sizeof(double*) * PAD);

    for (int i = 0; i < dim; i++){
        *(matrix + i) = (double*) malloc(dim * sizeof(double) + PAD);

        for (int j = 0; j < dim; j++)
            *(*(matrix + i) + j) = (zeroes)? 0.0 : (10.0*rand()/(RAND_MAX+1.0));
    }

    return matrix;
}

double** createMatrixWithZeroes(int dim){
    return createMatrix(dim, 1);
}

int printMatrix(double **matrix, int dim){

    for (int i = 0; i < dim; i++){

        for (int j = 0; j < dim; j++)
            printf("%.2f ", *(*(matrix + i) + j));

        printf("\n");
    }
    printf("\n");
}

double ** createRandomMatrix(int dim){
    return createMatrix(dim, 0);
}

void freeMatrix(double ***matrix, int dim){

    for (int i = 0; i < dim; i++)
        free(*(*matrix + i));

    free(*matrix);
}

double** multiplyMatrix(double **matrixA, double **matrixB, double **matrixC, int dim, int threads){
    double **answer = matrixC;

	#pragma omp parallel num_threads(threads)
    {
        #pragma omp parallel for schedule(dynamic)
        for (int i = 0; i < dim; i++){

            for (int j = 0; j < dim; j++){
                double cell = 0.0;

                for (int n = 0; n < dim; n++)
                    cell += *(*(matrixA + i) + n) * *(*(matrixB + j) + n);

                *(*(answer + i) + j) = cell;
            }
        }
    }

    return answer;
}

int main(){
    int dim = 32;
    int threads = 1;
    printf("\n---------------------------------------------\n");

    while (dim <= 1024){
        double **matrixA = createRandomMatrix(dim);
        double **matrixB = createRandomMatrix(dim);
        double **matrixC = createMatrixWithZeroes(dim);
        struct timeval start_time;
        struct timeval end_time;
        gettimeofday(&start_time, NULL);
        matrixC = multiplyMatrix(matrixA, matrixB, matrixC, dim, threads);
        gettimeofday(&end_time, NULL);
        double seconds = (((1000.0*end_time.tv_sec) + (end_time.tv_usec/1000.0)) -
                         ((1000.0*start_time.tv_sec) + (start_time.tv_usec/1000.0)))/1000.0;
        //printf("\n");
        //printf("matrix a\n");
        //printMatrix(matrixA, dim);
        //printf("matrix b\n");
        //printMatrix(matrixB, dim);
        //printf("matrix c\n");
        //printMatrix(matrixC, dim);

        printf("Taken time for a matrix of %dX%d with %d threads: %.5fs\n", dim, dim, threads, seconds);
        freeMatrix(&matrixA, dim);
        freeMatrix(&matrixB, dim);
        freeMatrix(&matrixC, dim);

        threads *= 2;

        if (threads > 64){
            printf("---------------------------------------------\n\n");
            printf("---------------------------------------------\n");
            threads = 1;
            dim *= 2;
        }

    }
	return 0;
}<commit_msg>increased test range<commit_after>#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <omp.h>

#define PAD 2*sizeof(double)

using namespace std;

double** createMatrix(int dim, bool zeroes){
    double **matrix = (double**) malloc(dim * sizeof(double*) * PAD);

    for (int i = 0; i < dim; i++){
        *(matrix + i) = (double*) malloc(dim * sizeof(double) + PAD);

        for (int j = 0; j < dim; j++)
            *(*(matrix + i) + j) = (zeroes)? 0.0 : (10.0*rand()/(RAND_MAX+1.0));
    }

    return matrix;
}

double** createMatrixWithZeroes(int dim){
    return createMatrix(dim, 1);
}

int printMatrix(double **matrix, int dim){

    for (int i = 0; i < dim; i++){

        for (int j = 0; j < dim; j++)
            printf("%.2f ", *(*(matrix + i) + j));

        printf("\n");
    }
    printf("\n");
}

double ** createRandomMatrix(int dim){
    return createMatrix(dim, 0);
}

void freeMatrix(double ***matrix, int dim){

    for (int i = 0; i < dim; i++)
        free(*(*matrix + i));

    free(*matrix);
}

double** multiplyMatrix(double **matrixA, double **matrixB, double **matrixC, int dim, int threads){
    double **answer = matrixC;

	#pragma omp parallel num_threads(threads)
    {
        #pragma omp parallel for schedule(dynamic)
        for (int i = 0; i < dim; i++){

            for (int j = 0; j < dim; j++){
                double cell = 0.0;

                for (int n = 0; n < dim; n++)
                    cell += *(*(matrixA + i) + n) * *(*(matrixB + j) + n);

                *(*(answer + i) + j) = cell;
            }
        }
    }

    return answer;
}

int main(){
    int dim = 32;
    int threads = 1;
    printf("\n---------------------------------------------\n");

    while (dim <= 2048){
        double **matrixA = createRandomMatrix(dim);
        double **matrixB = createRandomMatrix(dim);
        double **matrixC = createMatrixWithZeroes(dim);
        struct timeval start_time;
        struct timeval end_time;
        gettimeofday(&start_time, NULL);
        matrixC = multiplyMatrix(matrixA, matrixB, matrixC, dim, threads);
        gettimeofday(&end_time, NULL);
        double seconds = (((1000.0*end_time.tv_sec) + (end_time.tv_usec/1000.0)) -
                         ((1000.0*start_time.tv_sec) + (start_time.tv_usec/1000.0)))/1000.0;
        //printf("\n");
        //printf("matrix a\n");
        //printMatrix(matrixA, dim);
        //printf("matrix b\n");
        //printMatrix(matrixB, dim);
        //printf("matrix c\n");
        //printMatrix(matrixC, dim);

        printf("Taken time for a matrix of %dX%d with %d threads: %.5fs\n", dim, dim, threads, seconds);
        freeMatrix(&matrixA, dim);
        freeMatrix(&matrixB, dim);
        freeMatrix(&matrixC, dim);

        threads *= 2;

        if (threads > 64){
            printf("---------------------------------------------\n\n");
            printf("---------------------------------------------\n");
            threads = 1;
            dim *= 2;
        }

    }
	return 0;
}
<|endoftext|>


<commit_before>#ifndef PATTERNS_HPP
#define PATTERNS_HPP

#include "functions_pathing.hpp"
#include "path_definition.hpp"

#include <glm/glm.hpp>
#include <glm/vec2.hpp>
#include <vector>
#include <functional>

/*
 *
 */

struct LayerCompound
{
    LayerCompound(std::vector<Path_Def> paths,
                std::vector<unsigned int> number_of_shots,
                std::vector<float> offset);
    unsigned int m_number_of_paths;
    unsigned int m_number_of_shots_done = 0;
    std::vector<Path_Def> m_paths;
    std::vector<unsigned int> m_number_of_shots;
    std::vector<float> m_offset;

    static LayerCompound SIN_TWO_SHOTS()
    {
        return {{Path_Def(sin_path)}, {2}, {0.f}};
    }

    static LayerCompound SIN_FOUR_SHOTS()
    {
        return {{Path_Def(sin_path)}, {4}, {0.f}};
    }

    static LayerCompound SIN_SCYTHE_FOUR_TWO()
    {
        return {{Path_Def(sin_path), Path_Def(scythe_path)},{4,4},{0,0.f}};
    }

    static LayerCompound SPIRAL_ONE()
    {
        return {{Path_Def(spiral_path)},{1},{0.f}};
    }

    static LayerCompound LINEAR_TWO()
    {
        return {{Path_Def(linear_path)},{2},{0.f}};
    }

    };
struct Stage
{
    Stage(std::vector<LayerCompound> stages, std::vector<unsigned int> repititions,float cooldown);
    std::vector<LayerCompound> m_path_layers;
    std::vector<unsigned int> m_repititions;
    float m_cooldown;
    unsigned int m_current_repition = 0;
    LayerCompound get_current_repitition();

    bool is_at_end();
    void next();

    static Stage SSFT_SIX_STS_FOUR()
    {
        return {{LayerCompound::SIN_SCYTHE_FOUR_TWO(),LayerCompound::SIN_TWO_SHOTS()},{2,2},1.f};
    }

    static Stage STS_ONE()
    {
        return {{LayerCompound::SIN_TWO_SHOTS()},{1},1.f};
    }

    static Stage SPIRAL_ONE()
    {
        return{{LayerCompound::SPIRAL_ONE()},{4},1.f};
    }

    static Stage LINEAR_TWO()
    {
        return {{LayerCompound::LINEAR_TWO()},{4},1.f};
    }

};

struct Level
{
    Level(std::vector<Stage> m_stages,  unsigned int orbs_to_next_level);
    unsigned int m_number_of_stages;
    std::vector<Stage> m_stages;
    unsigned int m_orbs_to_next_level;
    unsigned int m_current_stage = 0;

    Stage get_current_stage();

    bool is_at_end();
    void next();

    static Level LEVEL_ONE()
    {
        return{{Stage::SSFT_SIX_STS_FOUR(),Stage::LINEAR_TWO()},5};
    }

    static Level LEVEL_TWO()
    {
        return{{Stage::SPIRAL_ONE()},5};
    }

};

/*
   class PatternPart {
   public:
   PatternPart(std::vector<Path_Def> shot_types,
   std::vector<int> shots_per_cooldown, std::vector<float> offset,
   std::vector<unsigned int> pattern_parts_lengths);

   std::vector<Path_Def> m_shot_type;
   std::vector<int> m_shots_per_cooldown;
   std::vector<float> m_offset;
   std::vector<unsigned int> m_pattern_parts_lengths;

   static PatternPart SIN_TWO_SHOTS() {
   return {{Path_Def(sin_path)},{2},{0.f},{3}};
   }

   static PatternPart SCYTHE_FOUR_SHOT() {
   return {{Path_Def(scythe_path)},{4},{0.f},{4}};
   }

   static PatternPart SCYTHE_FOUR_SHOT_SIN_TWO_SHOTS() {
   return {{Path_Def(scythe_path), Path_Def(sin_path)},{4,2},{0,45.f},{5,2}};
   }

   };

   class Pattern {
   public:
   Pattern(float cooldown, float rotation_speed,
   std::vector<PatternPart> pattern_parts, int orbs_needed);

   static Pattern level1() {
   return {1.f,20.f,{PatternPart::SIN_TWO_SHOTS()},2};
   }
   static Pattern level2() {
   return {1.f,20.f,{PatternPart::SCYTHE_FOUR_SHOT()},2};
   }
   static Pattern level3() {
   return {1.f,40.f,{PatternPart::SCYTHE_FOUR_SHOT_SIN_TWO_SHOTS(),PatternPart::SCYTHE_FOUR_SHOT()},10};
   }

   float m_cooldown;
   float m_rotation_speed;
   std::vector<PatternPart> m_pattern_parts;
   int m_orbs_needed;
   };
   */
#endif
<commit_msg>added  comments for pattern, level and stage creation<commit_after>#ifndef PATTERNS_HPP
#define PATTERNS_HPP

#include "functions_pathing.hpp"
#include "path_definition.hpp"

#include <glm/glm.hpp>
#include <glm/vec2.hpp>
#include <vector>
#include <functional>

/*
 *
 */

struct LayerCompound
{
    LayerCompound(std::vector<Path_Def> paths,
                std::vector<unsigned int> number_of_shots,
                std::vector<float> offset);
    unsigned int m_number_of_paths;
    unsigned int m_number_of_shots_done = 0;
    std::vector<Path_Def> m_paths;
    std::vector<unsigned int> m_number_of_shots;
    std::vector<float> m_offset;

    static LayerCompound SIN_TWO_SHOTS()
    {
        return {{Path_Def(sin_path)}, {2}, {0.f}};
    }

    static LayerCompound SIN_FOUR_SHOTS()
    {
        return {{Path_Def(sin_path)}, {4}, {0.f}};
    }

    /*
     *  Parameter 1:
     *      vetcor von path funtionen die zusammen das Compound ergeben
     *  Parameter 2:
     *      vector von unsigned ints. Fuer jede funtion von vorherigen
     *      element wird hier die anzahl von schuessen festgelegt
     *  Parameter 3:
     *      vector von offsets. geben an wie weit die path funktion
     *      verschobnen wird.
     * */
    static LayerCompound SIN_SCYTHE_FOUR_TWO()
    {
        return {{Path_Def(sin_path), Path_Def(scythe_path)},{4,4},{0,0.f}};
    }

    static LayerCompound SPIRAL_ONE()
    {
        return {{Path_Def(spiral_path)},{1},{0.f}};
    }

    static LayerCompound LINEAR_TWO()
    {
        return {{Path_Def(linear_path)},{2},{0.f}};
    }

    };
struct Stage
{
    Stage(std::vector<LayerCompound> stages, std::vector<unsigned int> repititions,float cooldown);
    std::vector<LayerCompound> m_path_layers;
    std::vector<unsigned int> m_repititions;
    float m_cooldown;
    unsigned int m_current_repition = 0;
    LayerCompound get_current_repitition();

    bool is_at_end();
    void next();

    static Stage SSFT_SIX_STS_FOUR()
    {
        /*
         *  parameter 1: vektor von Compunds die nacheinander
         *      ausgefuehrt werden
         *  Parameter 2:
         *      fuer jedes Compound wird hier angegeben wie oft
         *      es ausgefuehrt werden soll bevor das naechste
         *      ausgefuehrt wirf
         *  Parameter 3:
         *      allgemeiner cooldown. wie schnell werden die schuesse
         *      abgegeben
         * */
        return {{LayerCompound::SIN_SCYTHE_FOUR_TWO(),LayerCompound::SIN_TWO_SHOTS()},{2,2},1.f};
    }

    static Stage STS_ONE()
    {
        return {{LayerCompound::SIN_TWO_SHOTS()},{1},1.f};
    }

    static Stage SPIRAL_ONE()
    {
        return{{LayerCompound::SPIRAL_ONE()},{4},1.f};
    }

    static Stage LINEAR_TWO()
    {
        return {{LayerCompound::LINEAR_TWO()},{4},1.f};
    }

};

struct Level
{
    Level(std::vector<Stage> m_stages,  unsigned int orbs_to_next_level);
    unsigned int m_number_of_stages;
    std::vector<Stage> m_stages;
    unsigned int m_orbs_to_next_level;
    unsigned int m_current_stage = 0;

    Stage get_current_stage();

    bool is_at_end();
    void next();

    static Level LEVEL_ONE()
    {
        /*
         * Parameter 1:
         *      vektor von Stages die nacheinander ausgefuehrt werden
         *  Parameter 2:
         *      anzahl von orbs die eingesammelt werden muessen um den
         *      level abzuschlieszen.
         * */
        return{{Stage::SSFT_SIX_STS_FOUR(),Stage::LINEAR_TWO()},5};
    }

    static Level LEVEL_TWO()
    {
        return{{Stage::SPIRAL_ONE()},5};
    }

};
#endif
<|endoftext|>


<commit_before>#include <kognac/disklz4reader.h>
#include <boost/filesystem.hpp>

namespace fs = boost::filesystem;

DiskLZ4Reader::DiskLZ4Reader(string inputfile, int npartitions, int nbuffersPerFile) {
    //Init data structures
    for (int i = 0; i < npartitions; ++i) {
        for (int j = 0; j < nbuffersPerFile; ++j)
            diskbufferpool.push_back(new char [SIZE_DISK_BUFFER]);
        supportstringbuffers.push_back(std::unique_ptr<char[]>(new char[MAX_TERM_SIZE + 2]));
    }
    for (int i = 0; i < npartitions; ++i) {
        FileInfo inf;
        inf.buffer = new char[SIZE_SEG];
        inf.sizebuffer = 0;
        inf.pivot = 0;
        this->files.push_back(inf);
    }
    compressedbuffers = new std::list<BlockToRead>[files.size()];
    m_files = new std::mutex[files.size()];
    cond_files = new std::condition_variable[files.size()];
    time_files = new boost::chrono::duration<double>[files.size()];
    time_diskbufferpool = boost::chrono::duration<double>::zero();
    time_rawreading = boost::chrono::duration<double>::zero();

    //Open all files
    reader.open(inputfile);
    //readers = new ifstream[files.size()];
    for (int i = 0; i < files.size(); ++i) {
        //readers[i].open(files[i]);
        time_files[i] = boost::chrono::duration<double>::zero();
    }

    //Launch reading thread
    currentthread = std::thread(std::bind(&DiskLZ4Reader::run, this));
}

bool DiskLZ4Reader::availableDiskBuffer() {
    return !diskbufferpool.empty();
}

bool DiskLZ4Reader::areNewBuffers(const int id) {
    return !compressedbuffers[id].empty() || reader.eof();
}

void DiskLZ4Reader::run() {
    size_t totalsize = 0;
    char tmpbuffer[4];
    reader.read(tmpbuffer, 4);
    int currentFileIdx = Utils::decode_int(tmpbuffer);

    while (!reader.eof()) {
        //Read from each file in a round-robin fashion until all files are read
        //if (neofs == files.size()) {
        //    break;
        //}

        //Move to the next file
        //currentFileIdx = (currentFileIdx + 1) % files.size();
        //if (files[currentFileIdx].eof)
        //    continue;

        //Get a disk buffer
        boost::chrono::system_clock::time_point start = boost::chrono::system_clock::now();
        std::unique_lock<std::mutex> l(m_diskbufferpool);
        cond_diskbufferpool.wait(l, std::bind(&DiskLZ4Reader::availableDiskBuffer, this));
        time_diskbufferpool += boost::chrono::system_clock::now() - start;

        char *buffer = diskbufferpool.back();
        diskbufferpool.pop_back();
        l.unlock();

        //Read the file and put the content in the disk buffer
        start = boost::chrono::system_clock::now();
        reader.read(tmpbuffer, 4);
        size_t sizeToBeRead = Utils::decode_int(tmpbuffer);
        totalsize += sizeToBeRead + 8;
        reader.read(buffer, sizeToBeRead);
        time_rawreading += boost::chrono::system_clock::now() - start;

        //Put the content of the disk buffer in the blockToRead container
        assert(sizeToBeRead > 0);
        start = boost::chrono::system_clock::now();
        std::unique_lock<std::mutex> lk2(m_files[currentFileIdx]);
        time_files[currentFileIdx] += boost::chrono::system_clock::now() - start;

        BlockToRead b;
        b.buffer = buffer;
        b.sizebuffer = sizeToBeRead;
        b.pivot = 0;
        compressedbuffers[currentFileIdx].push_back(b);
        lk2.unlock();
        cond_files[currentFileIdx].notify_one();

        reader.read(tmpbuffer, 4);
        currentFileIdx = Utils::decode_int(tmpbuffer);
    }
    reader.close();
    BOOST_LOG_TRIVIAL(debug) << "Finished reading the input file";
}

bool DiskLZ4Reader::getNewCompressedBuffer(std::unique_lock<std::mutex> &lk,
        const int id) {
    //Here I have already a lock. First I release the buffer at the front
    if (!compressedbuffers[id].empty()) {
        BlockToRead b = compressedbuffers[id].front();
        compressedbuffers[id].pop_front();

        boost::chrono::system_clock::time_point start = boost::chrono::system_clock::now();
        std::unique_lock<std::mutex> lk2(m_diskbufferpool);
        time_diskbufferpool += boost::chrono::system_clock::now() - start;

        diskbufferpool.push_back(b.buffer);
        lk2.unlock();
        cond_diskbufferpool.notify_one();
    }

    //Then I wait until a new one is available
    cond_files[id].wait(lk, std::bind(&DiskLZ4Reader::areNewBuffers, this, id));
    return !compressedbuffers[id].empty();
}

bool DiskLZ4Reader::uncompressBuffer(const int id) {
    //Get a lock
    boost::chrono::system_clock::time_point start = boost::chrono::system_clock::now();
    std::unique_lock<std::mutex> lk(m_files[id]);
    //Make sure you wait until there is a new block
    cond_files[id].wait(lk, std::bind(&DiskLZ4Reader::areNewBuffers, this, id));
    time_files[id] += boost::chrono::system_clock::now() - start;

    if (compressedbuffers[id].empty())
        return false;

    if (compressedbuffers[id].front().pivot ==
            compressedbuffers[id].front().sizebuffer) {
        if (!getNewCompressedBuffer(lk, id))
            return false;
    }

    //Init vars
    size_t sizecomprbuffer = compressedbuffers[id].front().sizebuffer;
    char *comprb = compressedbuffers[id].front().buffer;
    size_t pivot = compressedbuffers[id].front().pivot;
    assert(comprb != NULL);

    //First I need to read the first 21 bytes to read the header
    int token;
    int compressionMethod;
    int compressedLen;
    int uncompressedLen = -1;
    if (pivot + 21 <= sizecomprbuffer) {
        token = comprb[pivot + 8] & 0xFF;
        compressedLen = Utils::decode_intLE(comprb, pivot + 9);
        uncompressedLen = Utils::decode_intLE(comprb, pivot + 13);
        pivot += 21;
    } else {
        char header[21];
        int remsize = sizecomprbuffer - pivot;
        memcpy(header, comprb + pivot, remsize);

        if (!getNewCompressedBuffer(lk, id))
            throw 10;

        sizecomprbuffer = compressedbuffers[id].front().sizebuffer;
        comprb = compressedbuffers[id].front().buffer;
        pivot = 0;

        //Get the remaining
        memcpy(header + remsize, comprb, 21 - remsize);
        pivot += 21 - remsize;
        token = header[8] & 0xFF;
        compressedLen = Utils::decode_intLE(header, 9);
        uncompressedLen = Utils::decode_intLE(header, 13);
    }
    compressionMethod = token & 0xF0;

    //Uncompress chunk
    FileInfo &f = files[id];

    std::unique_ptr<char[]> tmpbuffer;
    char *startb;

    if (pivot + compressedLen <= sizecomprbuffer) {
        startb = comprb + pivot;
        pivot += compressedLen;
    } else {
        tmpbuffer = std::unique_ptr<char[]>(new char[SIZE_SEG]);
        int copiedSize = sizecomprbuffer - pivot;
        memcpy(tmpbuffer.get(), comprb + pivot, copiedSize);

        //Get a new buffer
        if (!getNewCompressedBuffer(lk, id)) {
            throw 10;
        }

        sizecomprbuffer = compressedbuffers[id].front().sizebuffer;
        comprb = compressedbuffers[id].front().buffer;
        pivot = 0;

        memcpy(tmpbuffer.get() + copiedSize, comprb, compressedLen - copiedSize);
        pivot = compressedLen - copiedSize;
        startb = tmpbuffer.get();

    }
    compressedbuffers[id].front().pivot = pivot;
    lk.unlock();

    switch (compressionMethod) {
    case 16:
        //Not compressed. I just copy the buffer
        memcpy(f.buffer, startb, uncompressedLen);
        break;
    case 32:
        if (!LZ4_decompress_fast(startb, f.buffer, uncompressedLen)) {
            BOOST_LOG_TRIVIAL(error) << "Error in the decompression.";
            throw 10;
        }
        break;
    default:
        throw 10;
    }
    f.sizebuffer = uncompressedLen;
    f.pivot = 0;
    return true;
}

bool DiskLZ4Reader::isEOF(const int id) {
    if (files[id].pivot < files[id].sizebuffer)
        return false;
    bool resp = uncompressBuffer(id);
    return !resp;
}

int DiskLZ4Reader::readByte(const int id) {
    assert(id < files.size());
    if (files[id].pivot >= files[id].sizebuffer) {
        bool resp = uncompressBuffer(id);
        assert(resp);
    }
    return files[id].buffer[files[id].pivot++];
}

long DiskLZ4Reader::readLong(const int id) {
    if (files[id].pivot + 8 <= files[id].sizebuffer) {
        long n = Utils::decode_long(files[id].buffer + files[id].pivot);
        files[id].pivot += 8;
        return n;
    } else {
        char header[8];
        int copiedBytes = files[id].sizebuffer - files[id].pivot;
        memcpy(header, files[id].buffer + files[id].pivot, copiedBytes);
        bool resp = uncompressBuffer(id);
        assert(resp);
        memcpy(header + copiedBytes, files[id].buffer, 8 - copiedBytes);
        files[id].pivot = 8 - copiedBytes;
        return Utils::decode_long(header);
    }
}

long DiskLZ4Reader::readVLong(const int id) {
    int shift = 7;
    char b = readByte(id);
    long n = b & 127;
    while (b < 0) {
        b = readByte(id);
        n += (long) (b & 127) << shift;
        shift += 7;
    }
    return n;
}

const char *DiskLZ4Reader::readString(const int id, int &size) {
    size = readVLong(id);

    if (files[id].pivot + size <= files[id].sizebuffer) {
        memcpy(supportstringbuffers[id].get(), files[id].buffer + files[id].pivot, size);
        files[id].pivot += size;
    } else {
        int remSize = files[id].sizebuffer - files[id].pivot;
        memcpy(supportstringbuffers[id].get(), files[id].buffer + files[id].pivot, remSize);
        bool resp = uncompressBuffer(id);
        assert(resp);
        memcpy(supportstringbuffers[id].get() + remSize, files[id].buffer , size - remSize);
        files[id].pivot += size - remSize;
    }
    supportstringbuffers[id][size] = '\0';

    return supportstringbuffers[id].get();
}

DiskLZ4Reader::~DiskLZ4Reader() {
    currentthread.join();

    BOOST_LOG_TRIVIAL(debug) << "Time reading all data from disk " << time_rawreading.count()  << "sec.";
    BOOST_LOG_TRIVIAL(debug) << "Time waiting lock m_diskbufferpool " << time_diskbufferpool.count() << "sec.";
    double avg = 0;
    for (int i = 0; i < files.size(); ++i) {
        avg += time_files[i].count();
    }
    BOOST_LOG_TRIVIAL(debug) << "Time (avg) waiting locks files " << avg / files.size() << "sec.";

    delete[] compressedbuffers;
    for (int i = 0; i < diskbufferpool.size(); ++i)
        delete[] diskbufferpool[i];
    //delete[] readers;
    for (int i = 0; i < files.size(); ++i)
        delete[] files[i].buffer;
    delete[] m_files;
    delete[] cond_files;
    delete[] time_files;
}
<commit_msg>fixed deadlocks<commit_after>#include <kognac/disklz4reader.h>
#include <boost/filesystem.hpp>

namespace fs = boost::filesystem;

DiskLZ4Reader::DiskLZ4Reader(string inputfile, int npartitions, int nbuffersPerFile) {
    //Init data structures
    for (int i = 0; i < npartitions; ++i) {
        for (int j = 0; j < nbuffersPerFile; ++j)
            diskbufferpool.push_back(new char [SIZE_DISK_BUFFER]);
        supportstringbuffers.push_back(std::unique_ptr<char[]>(new char[MAX_TERM_SIZE + 2]));
    }
    for (int i = 0; i < npartitions; ++i) {
        FileInfo inf;
        inf.buffer = new char[SIZE_SEG];
        inf.sizebuffer = 0;
        inf.pivot = 0;
        this->files.push_back(inf);
    }
    compressedbuffers = new std::list<BlockToRead>[files.size()];
    m_files = new std::mutex[files.size()];
    cond_files = new std::condition_variable[files.size()];
    time_files = new boost::chrono::duration<double>[files.size()];
    time_diskbufferpool = boost::chrono::duration<double>::zero();
    time_rawreading = boost::chrono::duration<double>::zero();

    //Open all files
    reader.open(inputfile);
    //readers = new ifstream[files.size()];
    for (int i = 0; i < files.size(); ++i) {
        //readers[i].open(files[i]);
        time_files[i] = boost::chrono::duration<double>::zero();
    }

    //Launch reading thread
    currentthread = std::thread(std::bind(&DiskLZ4Reader::run, this));
}

bool DiskLZ4Reader::availableDiskBuffer() {
    return !diskbufferpool.empty();
}

bool DiskLZ4Reader::areNewBuffers(const int id) {
    return !compressedbuffers[id].empty() || reader.eof();
}

void DiskLZ4Reader::run() {
    size_t totalsize = 0;
    char tmpbuffer[4];
    reader.read(tmpbuffer, 4);
    int currentFileIdx = Utils::decode_int(tmpbuffer);

    while (!reader.eof()) {
        //Read from each file in a round-robin fashion until all files are read
        //if (neofs == files.size()) {
        //    break;
        //}

        //Move to the next file
        //currentFileIdx = (currentFileIdx + 1) % files.size();
        //if (files[currentFileIdx].eof)
        //    continue;

        //Get a disk buffer
        boost::chrono::system_clock::time_point start = boost::chrono::system_clock::now();
        std::unique_lock<std::mutex> l(m_diskbufferpool);
        cond_diskbufferpool.wait(l, std::bind(&DiskLZ4Reader::availableDiskBuffer, this));
        time_diskbufferpool += boost::chrono::system_clock::now() - start;

        char *buffer = diskbufferpool.back();
        diskbufferpool.pop_back();
        l.unlock();

        //Read the file and put the content in the disk buffer
        start = boost::chrono::system_clock::now();
        reader.read(tmpbuffer, 4);
        size_t sizeToBeRead = Utils::decode_int(tmpbuffer);
        totalsize += sizeToBeRead + 8;
        reader.read(buffer, sizeToBeRead);
        time_rawreading += boost::chrono::system_clock::now() - start;

        //Put the content of the disk buffer in the blockToRead container
        assert(sizeToBeRead > 0);
        start = boost::chrono::system_clock::now();
        std::unique_lock<std::mutex> lk2(m_files[currentFileIdx]);
        time_files[currentFileIdx] += boost::chrono::system_clock::now() - start;

        BlockToRead b;
        b.buffer = buffer;
        b.sizebuffer = sizeToBeRead;
        b.pivot = 0;
        compressedbuffers[currentFileIdx].push_back(b);
        lk2.unlock();
        cond_files[currentFileIdx].notify_one();

        reader.read(tmpbuffer, 4);
        currentFileIdx = Utils::decode_int(tmpbuffer);
    }
    reader.close();
    BOOST_LOG_TRIVIAL(debug) << "Finished reading the input file";

    //Notify all attached files that might be waiting that there is nothing else to read
    for(int i = 0; i < files.size(); ++i)
        cond_files[i].notify_one();
}

bool DiskLZ4Reader::getNewCompressedBuffer(std::unique_lock<std::mutex> &lk,
        const int id) {
    //Here I have already a lock. First I release the buffer at the front
    if (!compressedbuffers[id].empty()) {
        BlockToRead b = compressedbuffers[id].front();
        compressedbuffers[id].pop_front();

        boost::chrono::system_clock::time_point start = boost::chrono::system_clock::now();
        std::unique_lock<std::mutex> lk2(m_diskbufferpool);
        time_diskbufferpool += boost::chrono::system_clock::now() - start;

        diskbufferpool.push_back(b.buffer);
        lk2.unlock();
        cond_diskbufferpool.notify_one();
    }

    //Then I wait until a new one is available
    cond_files[id].wait(lk, std::bind(&DiskLZ4Reader::areNewBuffers, this, id));
    return !compressedbuffers[id].empty();
}

bool DiskLZ4Reader::uncompressBuffer(const int id) {
    //Get a lock
    boost::chrono::system_clock::time_point start = boost::chrono::system_clock::now();
    std::unique_lock<std::mutex> lk(m_files[id]);
    //Make sure you wait until there is a new block
    cond_files[id].wait(lk, std::bind(&DiskLZ4Reader::areNewBuffers, this, id));
    time_files[id] += boost::chrono::system_clock::now() - start;

    if (compressedbuffers[id].empty())
        return false;

    if (compressedbuffers[id].front().pivot ==
            compressedbuffers[id].front().sizebuffer) {
        if (!getNewCompressedBuffer(lk, id))
            return false;
    }

    //Init vars
    size_t sizecomprbuffer = compressedbuffers[id].front().sizebuffer;
    char *comprb = compressedbuffers[id].front().buffer;
    size_t pivot = compressedbuffers[id].front().pivot;
    assert(comprb != NULL);

    //First I need to read the first 21 bytes to read the header
    int token;
    int compressionMethod;
    int compressedLen;
    int uncompressedLen = -1;
    if (pivot + 21 <= sizecomprbuffer) {
        token = comprb[pivot + 8] & 0xFF;
        compressedLen = Utils::decode_intLE(comprb, pivot + 9);
        uncompressedLen = Utils::decode_intLE(comprb, pivot + 13);
        pivot += 21;
    } else {
        char header[21];
        int remsize = sizecomprbuffer - pivot;
        memcpy(header, comprb + pivot, remsize);

        if (!getNewCompressedBuffer(lk, id))
            throw 10;

        sizecomprbuffer = compressedbuffers[id].front().sizebuffer;
        comprb = compressedbuffers[id].front().buffer;
        pivot = 0;

        //Get the remaining
        memcpy(header + remsize, comprb, 21 - remsize);
        pivot += 21 - remsize;
        token = header[8] & 0xFF;
        compressedLen = Utils::decode_intLE(header, 9);
        uncompressedLen = Utils::decode_intLE(header, 13);
    }
    compressionMethod = token & 0xF0;

    //Uncompress chunk
    FileInfo &f = files[id];

    std::unique_ptr<char[]> tmpbuffer;
    char *startb;

    if (pivot + compressedLen <= sizecomprbuffer) {
        startb = comprb + pivot;
        pivot += compressedLen;
    } else {
        tmpbuffer = std::unique_ptr<char[]>(new char[SIZE_SEG]);
        int copiedSize = sizecomprbuffer - pivot;
        memcpy(tmpbuffer.get(), comprb + pivot, copiedSize);

        //Get a new buffer
        if (!getNewCompressedBuffer(lk, id)) {
            throw 10;
        }

        sizecomprbuffer = compressedbuffers[id].front().sizebuffer;
        comprb = compressedbuffers[id].front().buffer;
        pivot = 0;

        memcpy(tmpbuffer.get() + copiedSize, comprb, compressedLen - copiedSize);
        pivot = compressedLen - copiedSize;
        startb = tmpbuffer.get();

    }
    compressedbuffers[id].front().pivot = pivot;
    lk.unlock();

    switch (compressionMethod) {
    case 16:
        //Not compressed. I just copy the buffer
        memcpy(f.buffer, startb, uncompressedLen);
        break;
    case 32:
        if (!LZ4_decompress_fast(startb, f.buffer, uncompressedLen)) {
            BOOST_LOG_TRIVIAL(error) << "Error in the decompression.";
            throw 10;
        }
        break;
    default:
        throw 10;
    }
    f.sizebuffer = uncompressedLen;
    f.pivot = 0;
    return true;
}

bool DiskLZ4Reader::isEOF(const int id) {
    if (files[id].pivot < files[id].sizebuffer)
        return false;
    bool resp = uncompressBuffer(id);
    return !resp;
}

int DiskLZ4Reader::readByte(const int id) {
    assert(id < files.size());
    if (files[id].pivot >= files[id].sizebuffer) {
        bool resp = uncompressBuffer(id);
        assert(resp);
    }
    return files[id].buffer[files[id].pivot++];
}

long DiskLZ4Reader::readLong(const int id) {
    if (files[id].pivot + 8 <= files[id].sizebuffer) {
        long n = Utils::decode_long(files[id].buffer + files[id].pivot);
        files[id].pivot += 8;
        return n;
    } else {
        char header[8];
        int copiedBytes = files[id].sizebuffer - files[id].pivot;
        memcpy(header, files[id].buffer + files[id].pivot, copiedBytes);
        bool resp = uncompressBuffer(id);
        assert(resp);
        memcpy(header + copiedBytes, files[id].buffer, 8 - copiedBytes);
        files[id].pivot = 8 - copiedBytes;
        return Utils::decode_long(header);
    }
}

long DiskLZ4Reader::readVLong(const int id) {
    int shift = 7;
    char b = readByte(id);
    long n = b & 127;
    while (b < 0) {
        b = readByte(id);
        n += (long) (b & 127) << shift;
        shift += 7;
    }
    return n;
}

const char *DiskLZ4Reader::readString(const int id, int &size) {
    size = readVLong(id);

    if (files[id].pivot + size <= files[id].sizebuffer) {
        memcpy(supportstringbuffers[id].get(), files[id].buffer + files[id].pivot, size);
        files[id].pivot += size;
    } else {
        int remSize = files[id].sizebuffer - files[id].pivot;
        memcpy(supportstringbuffers[id].get(), files[id].buffer + files[id].pivot, remSize);
        bool resp = uncompressBuffer(id);
        assert(resp);
        memcpy(supportstringbuffers[id].get() + remSize, files[id].buffer , size - remSize);
        files[id].pivot += size - remSize;
    }
    supportstringbuffers[id][size] = '\0';

    return supportstringbuffers[id].get();
}

DiskLZ4Reader::~DiskLZ4Reader() {
    currentthread.join();

    BOOST_LOG_TRIVIAL(debug) << "Time reading all data from disk " << time_rawreading.count()  << "sec.";
    BOOST_LOG_TRIVIAL(debug) << "Time waiting lock m_diskbufferpool " << time_diskbufferpool.count() << "sec.";
    double avg = 0;
    for (int i = 0; i < files.size(); ++i) {
        avg += time_files[i].count();
    }
    BOOST_LOG_TRIVIAL(debug) << "Time (avg) waiting locks files " << avg / files.size() << "sec.";

    delete[] compressedbuffers;
    for (int i = 0; i < diskbufferpool.size(); ++i)
        delete[] diskbufferpool[i];
    //delete[] readers;
    for (int i = 0; i < files.size(); ++i)
        delete[] files[i].buffer;
    delete[] m_files;
    delete[] cond_files;
    delete[] time_files;
}
<|endoftext|>


<commit_before>#pragma once

#include "twisted-spirit/core/parser_core.hpp"
#include "twisted-spirit/rules/space.hpp"

#include <vector>
#include <string>

namespace WretchedCss
{
    struct IntermediateRule
    {
        std::string selector;
        std::vector <std::string> declarations;
    };

    using namespace TwistedSpirit;

    template GRAMMAR_TEMPLATE_SIGNATURE
    struct rule_set_grammar : qi::grammar <Iterator, std::vector <IntermediateRule>()>
    {
        using grammar_result = std::vector <IntermediateRule>;

        rule_set_grammar() : rule_set_grammar::base_type(main, "rule_set")
        {
            using namespace common_usings;
            INSTALL_ERROR_HANDLER;
            INSTALL_WARNING_HANDLER;

            selector %=
                *(qi::char_ - qi::char_('{'))
            ;

            declaration %=
                    *(qi::char_ - qi::char_(";{}"))
                >>  ';'
            ;

            declarations =
               +(
                        declaration                 [phoenix::push_back(_val, qi::_1)]
                    >> *qi::space
                )
            ;

            rule =
                   *blank
                >>  selector                        [at_c <0> (_val) = qi::_1]
                >> *blank
                >>  qi::char_('{')
                >> *qi::space
                >>  declarations                    [at_c <1> (_val) = qi::_1]
                >>  qi::char_('}')
            ;

            main %=
               +rule
            ;

            HANDLE_QI_ERROR(main, 1);
            HANDLE_QI_WARNING(main, 1);
        }

        // Rules
        qi::rule <Iterator, grammar_result()> main;
        qi::rule <Iterator, IntermediateRule()> rule;
        qi::rule <Iterator, std::string()> selector;
        qi::rule <Iterator, std::string()> declaration;
        qi::rule <Iterator, std::vector <std::string>()> declarations;
    };
} // namespace WretchedCss

BOOST_FUSION_ADAPT_STRUCT
(
    WretchedCss::IntermediateRule,
    selector, declarations
)
<commit_msg>A rule set (that is a css file) can now be generated back from the values.<commit_after>#pragma once

#include "twisted-spirit/core/parser_core.hpp"
#include "twisted-spirit/rules/space.hpp"

#include <vector>
#include <string>

namespace WretchedCss
{
    struct IntermediateRule
    {
        std::string selector;
        std::vector <std::string> declarations;
    };

    using namespace TwistedSpirit;

    template GRAMMAR_TEMPLATE_SIGNATURE
    struct rule_set_grammar : qi::grammar <Iterator, std::vector <IntermediateRule>()>
    {
        using grammar_result = std::vector <IntermediateRule>;

        rule_set_grammar() : rule_set_grammar::base_type(main, "rule_set")
        {
            using namespace common_usings;
            INSTALL_ERROR_HANDLER;
            INSTALL_WARNING_HANDLER;

            selector %=
                *(qi::char_ - qi::char_('{') - blank)
            ;

            declaration %=
                    *(qi::char_ - qi::char_(";{}"))
                >>  ';'
            ;

            declarations =
               +(
                        declaration                 [phoenix::push_back(_val, qi::_1)]
                    >> *qi::space
                )
            ;

            rule =
                   *blank
                >>  selector                        [at_c <0> (_val) = qi::_1]
                >> *blank
                >>  qi::char_('{')
                >> *qi::space
                >>  declarations                    [at_c <1> (_val) = qi::_1]
                >>  qi::char_('}')
            ;

            main %=
               +rule
            ;

            HANDLE_QI_ERROR(main, 1);
            HANDLE_QI_WARNING(main, 1);
        }

        // Rules
        qi::rule <Iterator, grammar_result()> main;
        qi::rule <Iterator, IntermediateRule()> rule;
        qi::rule <Iterator, std::string()> selector;
        qi::rule <Iterator, std::string()> declaration;
        qi::rule <Iterator, std::vector <std::string>()> declarations;
    };
} // namespace WretchedCss

BOOST_FUSION_ADAPT_STRUCT
(
    WretchedCss::IntermediateRule,
    selector, declarations
)
<|endoftext|>