<commit_before>#include "cfilelistmodel.h"
#include "shell/cshell.h"
#include "ccontroller.h"
#include "../../../cmainwindow.h"
#include "../../columns.h"

DISABLE_COMPILER_WARNINGS
#include <QMimeData>
#include <QUrl>
RESTORE_COMPILER_WARNINGS

#include <set>

CFileListModel::CFileListModel(QTreeView * treeView, QObject *parent) :
	QStandardItemModel(0, NumberOfColumns, parent),
	_controller(CController::get()),
	_tree(treeView),
	_panel(UnknownPanel)
{
}

// Sets the position (left or right) of a panel that this model represents
void CFileListModel::setPanelPosition(Panel p)
{
	assert_r(_panel == UnknownPanel); // Doesn't make sense to call this method more than once
	_panel = p;
}

Panel CFileListModel::panelPosition() const
{
	return _panel;
}

QTreeView *CFileListModel::treeView() const
{
	return _tree;
}

QVariant CFileListModel::data(const QModelIndex & index, int role /*= Qt::DisplayRole*/) const
{
	if (role == Qt::ToolTipRole)
	{
		if (!index.isValid())
			return QString();

		const CFileSystemObject item = _controller.itemByHash(_panel, itemHash(index));
		return QString(item.fullName() % "\n\n" % QString::fromStdWString(CShell::toolTip(item.fullAbsolutePath().toStdWString())));
	}
	else if (role == Qt::EditRole)
	{
		return _controller.itemByHash(_panel, itemHash(index)).fullName();
	}
	else if (role == FullNameRole)
	{
		return _controller.itemByHash(_panel, itemHash(index)).fullName();
	}
	else
		return QStandardItemModel::data(index, role);
}

bool CFileListModel::setData(const QModelIndex & index, const QVariant & value, int role)
{
	if (role == Qt::EditRole)
	{
		const qulonglong hash = itemHash(index);
		emit itemEdited(hash, value.toString());
		return false;
	}
	else
		return QStandardItemModel::setData(index, value, role);
}

Qt::ItemFlags CFileListModel::flags(const QModelIndex & idx) const
{
	Qt::ItemFlags flags = QStandardItemModel::flags(idx);
	if (!idx.isValid())
		return flags;

	if (data(index(idx.row(), 0)) != "[..]")
		flags |= Qt::ItemIsEditable | Qt::ItemIsDragEnabled;

	const qulonglong hash = itemHash(idx);
	const CFileSystemObject item = _controller.itemByHash(_panel, hash);
	if (item.exists() && item.isDir())
		flags |= Qt::ItemIsDropEnabled;

	return  flags;
}

bool CFileListModel::canDropMimeData(const QMimeData * data, Qt::DropAction /*action*/, int row, int /*column*/, const QModelIndex & /*parent*/) const
{
	if (!data->hasUrls())
		return false;

	const QModelIndex idx = index(row, 0);
	return !idx.isValid() || _controller.itemByHash(_panel, itemHash(index(row, 0))).isDir();
}

QStringList CFileListModel::mimeTypes() const
{
	return QStringList("text/uri-list");
}

bool CFileListModel::dropMimeData(const QMimeData * data, Qt::DropAction action, int /*row*/, int /*column*/, const QModelIndex & parent)
{
	if (action == Qt::IgnoreAction)
		return true;
	else if (!data->hasUrls())
		return false;

	const CFileSystemObject dest = parent.isValid() ? _controller.itemByHash(_panel, itemHash(parent)) : CFileSystemObject(_controller.panel(_panel).currentDirPathNative());
	assert_and_return_r(dest.exists() && dest.isDir(), false);

	const QList<QUrl> urls = data->urls();
	std::vector<CFileSystemObject> objects;
	for(const QUrl& url: urls)
		objects.emplace_back(url.toLocalFile());

	if (objects.empty())
		return false;

	if (action == Qt::CopyAction)
		return CMainWindow::get()->copyFiles(objects, dest.fullAbsolutePath());
	else if (action == Qt::MoveAction)
		return CMainWindow::get()->moveFiles(objects, dest.fullAbsolutePath());
	else
		return false;
}

QMimeData *CFileListModel::mimeData(const QModelIndexList & indexes) const
{
	QMimeData * mime = new QMimeData();
	QList<QUrl> urls;
	std::set<int> rows;
	for(const auto& idx: indexes)
	{
		if (idx.isValid() && rows.count(idx.row()) == 0)
		{
			const QString path = _controller.itemByHash(_panel, itemHash(index(idx.row(), 0))).fullAbsolutePath();
			if (!path.isEmpty())
			{
				rows.insert(idx.row());
				urls.push_back(QUrl::fromLocalFile(path));
			}
		}
	}

	mime->setUrls(urls);
	return mime;
}

qulonglong CFileListModel::itemHash(const QModelIndex & index) const
{
	QStandardItem * itm = item(index.row(), 0);
	if (!itm)
		return 0;

	bool ok = false;
	const qulonglong hash = itm->data(Qt::UserRole).toULongLong(&ok);
	assert_r(ok);
	return ok ? hash : 0;
}
<commit_msg>Items can be dropped onto files as well as folders now<commit_after>#include "cfilelistmodel.h"
#include "shell/cshell.h"
#include "ccontroller.h"
#include "../../../cmainwindow.h"
#include "../../columns.h"

DISABLE_COMPILER_WARNINGS
#include <QMimeData>
#include <QUrl>
RESTORE_COMPILER_WARNINGS

#include <set>

CFileListModel::CFileListModel(QTreeView * treeView, QObject *parent) :
	QStandardItemModel(0, NumberOfColumns, parent),
	_controller(CController::get()),
	_tree(treeView),
	_panel(UnknownPanel)
{
}

// Sets the position (left or right) of a panel that this model represents
void CFileListModel::setPanelPosition(Panel p)
{
	assert_r(_panel == UnknownPanel); // Doesn't make sense to call this method more than once
	_panel = p;
}

Panel CFileListModel::panelPosition() const
{
	return _panel;
}

QTreeView *CFileListModel::treeView() const
{
	return _tree;
}

QVariant CFileListModel::data(const QModelIndex & index, int role /*= Qt::DisplayRole*/) const
{
	if (role == Qt::ToolTipRole)
	{
		if (!index.isValid())
			return QString();

		const CFileSystemObject item = _controller.itemByHash(_panel, itemHash(index));
		return QString(item.fullName() % "\n\n" % QString::fromStdWString(CShell::toolTip(item.fullAbsolutePath().toStdWString())));
	}
	else if (role == Qt::EditRole)
	{
		return _controller.itemByHash(_panel, itemHash(index)).fullName();
	}
	else if (role == FullNameRole)
	{
		return _controller.itemByHash(_panel, itemHash(index)).fullName();
	}
	else
		return QStandardItemModel::data(index, role);
}

bool CFileListModel::setData(const QModelIndex & index, const QVariant & value, int role)
{
	if (role == Qt::EditRole)
	{
		const qulonglong hash = itemHash(index);
		emit itemEdited(hash, value.toString());
		return false;
	}
	else
		return QStandardItemModel::setData(index, value, role);
}

Qt::ItemFlags CFileListModel::flags(const QModelIndex & idx) const
{
	const Qt::ItemFlags flags = QStandardItemModel::flags(idx);
	if (!idx.isValid())
		return flags;

	const qulonglong hash = itemHash(idx);
	const CFileSystemObject item = _controller.itemByHash(_panel, hash);
	return item.exists() ? flags | Qt::ItemIsEditable : flags;
}

bool CFileListModel::canDropMimeData(const QMimeData * data, Qt::DropAction /*action*/, int row, int /*column*/, const QModelIndex & /*parent*/) const
{
	return data->hasUrls();
}

QStringList CFileListModel::mimeTypes() const
{
	return QStringList("text/uri-list");
}

bool CFileListModel::dropMimeData(const QMimeData * data, Qt::DropAction action, int /*row*/, int /*column*/, const QModelIndex & parent)
{
	if (action == Qt::IgnoreAction)
		return true;
	else if (!data->hasUrls())
		return false;

	CFileSystemObject dest = parent.isValid() ? _controller.itemByHash(_panel, itemHash(parent)) : CFileSystemObject(_controller.panel(_panel).currentDirPathNative());
	if (dest.isFile())
		dest = CFileSystemObject(dest.parentDirPath());
	assert_and_return_r(dest.exists() && dest.isDir(), false);

	const QList<QUrl> urls = data->urls();
	std::vector<CFileSystemObject> objects;
	for(const QUrl& url: urls)
		objects.emplace_back(url.toLocalFile());

	if (objects.empty())
		return false;

	if (action == Qt::CopyAction)
		return CMainWindow::get()->copyFiles(objects, dest.fullAbsolutePath());
	else if (action == Qt::MoveAction)
		return CMainWindow::get()->moveFiles(objects, dest.fullAbsolutePath());
	else
		return false;
}

QMimeData *CFileListModel::mimeData(const QModelIndexList & indexes) const
{
	QMimeData * mime = new QMimeData();
	QList<QUrl> urls;
	std::set<int> rows;
	for(const auto& idx: indexes)
	{
		if (idx.isValid() && rows.count(idx.row()) == 0)
		{
			const QString path = _controller.itemByHash(_panel, itemHash(index(idx.row(), 0))).fullAbsolutePath();
			if (!path.isEmpty())
			{
				rows.insert(idx.row());
				urls.push_back(QUrl::fromLocalFile(path));
			}
		}
	}

	mime->setUrls(urls);
	return mime;
}

qulonglong CFileListModel::itemHash(const QModelIndex & index) const
{
	QStandardItem * itm = item(index.row(), 0);
	if (!itm)
		return 0;

	bool ok = false;
	const qulonglong hash = itm->data(Qt::UserRole).toULongLong(&ok);
	assert_r(ok);
	return ok ? hash : 0;
}
<|endoftext|>


<commit_before>#pragma once
//=====================================================================//
/*!	@file
	@brief	Graphics Library Core (glfw3)
	@author	平松邦仁 (hira@rvf-rc45.net)
*/
//=====================================================================//
#include <string>
#include <thread>
#include <future>
#include <unistd.h>
#include "utils/singleton_policy.hpp"
#include "core/device.hpp"
#include "gl_fw/glfonts.hpp"

namespace gl {

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief	Graphics Core (glfw3) Library クラス@n
				※ハードウェアー依存の操作を扱う部分を集積したクラス。
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	class core : public utils::singleton_policy<core> {

		friend struct utils::singleton_policy<core>;

	public:
		static device::bitsets	bitsets_;
		static device::locator	locator_;

	private:
		std::string		current_path_;
		std::string		exec_path_;

		device			device_;

		fonts			fonts_;

		GLFWwindow*		window_;

		vtx::spos		best_size_;
		vtx::spos		limit_size_;
		vtx::spos		size_;
		vtx::srect		rect_;

		int				recv_file_id_;
		utils::strings	recv_file_path_;

		std::string		title_;

		std::future<uint32_t>	v_sync_wait_;
		uint32_t	sync_count_;

		uint32_t	frame_count_;
		double		frame_time_;
		double		machine_cycle_;
		double		cpu_ghz_;
		bool		cpu_spd_enable_;
		bool		swap_ctrl_;

		bool		exit_signal_;
		bool		full_screen_;

		bool		keyboard_jp_;

		static uint32_t sync_wait_task_(uint32_t in) {
			usleep(16000);	// 16ms
			++in;
			return in;
		}

		void start_sync_() {
			v_sync_wait_ = std::async(std::launch::async, sync_wait_task_, sync_count_);
		}

		void wait_sync_() {
			sync_count_ = v_sync_wait_.get();
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	コンストラクター
		*/
		//-----------------------------------------------------------------//
		core() : window_(0),
				 best_size_(0), limit_size_(0), size_(0), rect_(0),
				 recv_file_id_(0),
				 title_(),
				 sync_count_(0),
				 frame_count_(0), frame_time_(0.0),
				 machine_cycle_(0.0), cpu_ghz_(0.0),
				 cpu_spd_enable_(false), swap_ctrl_(false),
				 exit_signal_(false), full_screen_(false), keyboard_jp_(false) { }

		core(const core& rhs);
		core& operator = (const core& rhs);

	public:
		//-----------------------------------------------------------------//
		/*!
			@brief	デストラクター
		*/
		//-----------------------------------------------------------------//
		virtual ~core() { destroy(); }

		//-----------------------------------------------------------------//
		/*!
			@brief	初期化プロセス
			@param[in]	cmd_path	コマンドパス
			@return 正常終了したら「true」
		*/
		//-----------------------------------------------------------------//
		bool initialize(const std::string& cmd_path);

		//-----------------------------------------------------------------//
		/*!
			@brief	最大解像度を返す
			@return	最大解像度
		*/
		//-----------------------------------------------------------------//
		const vtx::spos& get_best_size() const { return best_size_; }

		//-----------------------------------------------------------------//
		/*!
			@brief	最小解像度を設定
			@param[in]	size	最小解像度
		*/
		//-----------------------------------------------------------------//
		void set_limit_size(const vtx::spos& size) { limit_size_ = size; }

		//-----------------------------------------------------------------//
		/*!
			@brief	最小解像度を返す
			@return	最小解像度
		*/
		//-----------------------------------------------------------------//
		const vtx::spos& get_limit_size() const { return limit_size_; }

		//-----------------------------------------------------------------//
		/*!
			@brief	解像度を返す（実際の大きさ）
			@return	解像度
		*/
		//-----------------------------------------------------------------//
		const vtx::spos& get_size() const { return size_; }

		//-----------------------------------------------------------------//
		/*!
			@brief	スクリーン位置、サイズを返す（論理的な大きさ）
			@return	配置
		*/
		//-----------------------------------------------------------------//
		const vtx::srect& get_rect() const { return rect_; }

		//-----------------------------------------------------------------//
		/*!
			@brief	ファイル受信 ID の取得
			@return	ファイル受信 ID
		*/
		//-----------------------------------------------------------------//
		int get_recv_file_id() const { return recv_file_id_; }

		//-----------------------------------------------------------------//
		/*!
			@brief	ファイル受信 path の取得
			@return	ファイル受信 path
		*/
		//-----------------------------------------------------------------//
		const utils::strings& get_recv_file_path() const { return recv_file_path_; }

		//-----------------------------------------------------------------//
		/*!
			@brief	平均フレームレートを得る（標準60Hz）
			@return	平均フレームレート
		*/
		//-----------------------------------------------------------------//
		float get_frame_rate() const { return (1.0 / frame_time_); }

		//-----------------------------------------------------------------//
		/*!
			@brief	平均 CPU のクロックを得る。
			@return	平均 CPU クロック(GHz)
		*/
		//-----------------------------------------------------------------//
		float get_cpu_clock() const { return cpu_ghz_; }

		//-----------------------------------------------------------------//
		/*!
			@brief	終了シグナルの受取
			@return	「true」の場合、終了
		*/
		//-----------------------------------------------------------------//
		bool get_exit_signal() const { return exit_signal_; }

		//-----------------------------------------------------------------//
		/*!
			@brief	セットアップ・プロセス
			@param[in]	rect	描画領域と位置
			@param[in]	title	タイトルの設定
			@param[in]	fullscreen	全画面の場合は「ture」
			@return 正常終了したら「true」
		*/
		//-----------------------------------------------------------------//
		bool setup(const vtx::srect& rect, const std::string& title, bool fullscreen);

		//-----------------------------------------------------------------//
		/*!
			@brief	タイトルの登録
			@param[in]	title	タイトル文字列
		*/
		//-----------------------------------------------------------------//
		void set_title(const std::string& title);

		//-----------------------------------------------------------------//
		/*!
			@brief	カーソル（マウスポインター）の設定
			@param[in]	cursortype	カーソル・タイプ
		*/
		//-----------------------------------------------------------------//
///		void set_cursor(cursor cursortype) { ::glutSetCursor(cursortype); }

		//-----------------------------------------------------------------//
		/*!
			@brief	全画面の設定
			@param[in]	flag	全画面の場合「true」
		*/
		//-----------------------------------------------------------------//
		void full_screen(bool flag = true);

		//-----------------------------------------------------------------//
		/*!
			@brief	全画面の設定
			@return 全画面なら「true」
		*/
		//-----------------------------------------------------------------//
		bool is_full_screen() const { return full_screen_; }

		//-----------------------------------------------------------------//
		/*!
			@brief	実行パスを取得
			@return ファイル・パス
		*/
		//-----------------------------------------------------------------//
		const std::string& get_exec_path() const { return exec_path_; }

		//-----------------------------------------------------------------//
		/*!
			@brief	カレントパスを取得
			@return ファイル・パス
		*/
		//-----------------------------------------------------------------//
		const std::string& get_current_path() const { return current_path_; }

		//-----------------------------------------------------------------//
		/*!
			@brief	フレーム・サービス
		*/
		//-----------------------------------------------------------------//
		void service();

		//-----------------------------------------------------------------//
		/*!
			@brief	フレーム・フリップ
		*/
		//-----------------------------------------------------------------//
		void flip_frame();

		//-----------------------------------------------------------------//
		/*!
			@brief	廃棄プロセス
		*/
		//-----------------------------------------------------------------//
		void destroy();

		//-----------------------------------------------------------------//
		/*!
			@brief	デバイス・クラスを受け取る。
			@return デバイス・クラス（const）
		*/
		//-----------------------------------------------------------------//
		const device& get_device() const { return device_; }

		//-----------------------------------------------------------------//
		/*!
			@brief	デバイス・クラスを参照
			@return デバイス・クラス
		*/
		//-----------------------------------------------------------------//
		device& at_device() { return device_; }

		//-----------------------------------------------------------------//
		/*!
			@brief	デバイス・クラスを参照
			@return デバイス・クラス
		*/
		//-----------------------------------------------------------------//
		fonts& at_fonts() { return fonts_; }

		//-----------------------------------------------------------------//
		/*!
			@brief	日本語キーボードか検査
			@return 日本語キーボードの場合「true」が返る
		*/
		//-----------------------------------------------------------------//
		bool keyboard_japan() const { return keyboard_jp_; }

	};
}

<commit_msg>wait thread<commit_after>#pragma once
//=====================================================================//
/*!	@file
	@brief	Graphics Library Core (glfw3)
	@author	平松邦仁 (hira@rvf-rc45.net)
*/
//=====================================================================//
#include <string>
#include <thread>
#include <future>
#include <unistd.h>
#include "utils/singleton_policy.hpp"
#include "core/device.hpp"
#include "gl_fw/glfonts.hpp"

namespace gl {

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief	Graphics Core (glfw3) Library クラス@n
				※ハードウェアー依存の操作を扱う部分を集積したクラス。
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	class core : public utils::singleton_policy<core> {

		friend struct utils::singleton_policy<core>;

	public:
		static device::bitsets	bitsets_;
		static device::locator	locator_;

	private:
		std::string		current_path_;
		std::string		exec_path_;

		device			device_;

		fonts			fonts_;

		GLFWwindow*		window_;

		vtx::spos		best_size_;
		vtx::spos		limit_size_;
		vtx::spos		size_;
		vtx::srect		rect_;

		int				recv_file_id_;
		utils::strings	recv_file_path_;

		std::string		title_;

		std::future<uint32_t>	v_sync_wait_;
		uint32_t	sync_count_;

		uint32_t	frame_count_;
		double		frame_time_;
		double		machine_cycle_;
		double		cpu_ghz_;
		bool		cpu_spd_enable_;
		bool		swap_ctrl_;

		bool		exit_signal_;
		bool		full_screen_;

		bool		keyboard_jp_;

		static uint32_t wait_sync_task_(uint32_t in) {
			++in;
			usleep(16000);	// 16ms
			return in;
		}

		void start_sync_() {
			v_sync_wait_ = std::async(std::launch::async,
									  wait_sync_task_,
									  sync_count_);
		}

		void wait_sync_() { sync_count_ = v_sync_wait_.get(); }

		//-----------------------------------------------------------------//
		/*!
			@brief	コンストラクター
		*/
		//-----------------------------------------------------------------//
		core() : window_(0),
				 best_size_(0), limit_size_(0), size_(0), rect_(0),
				 recv_file_id_(0),
				 title_(),
				 sync_count_(0),
				 frame_count_(0), frame_time_(0.0),
				 machine_cycle_(0.0), cpu_ghz_(0.0),
				 cpu_spd_enable_(false), swap_ctrl_(false),
				 exit_signal_(false), full_screen_(false), keyboard_jp_(false) { }

		core(const core& rhs);
		core& operator = (const core& rhs);

	public:
		//-----------------------------------------------------------------//
		/*!
			@brief	デストラクター
		*/
		//-----------------------------------------------------------------//
		virtual ~core() { destroy(); }

		//-----------------------------------------------------------------//
		/*!
			@brief	初期化プロセス
			@param[in]	cmd_path	コマンドパス
			@return 正常終了したら「true」
		*/
		//-----------------------------------------------------------------//
		bool initialize(const std::string& cmd_path);

		//-----------------------------------------------------------------//
		/*!
			@brief	最大解像度を返す
			@return	最大解像度
		*/
		//-----------------------------------------------------------------//
		const vtx::spos& get_best_size() const { return best_size_; }

		//-----------------------------------------------------------------//
		/*!
			@brief	最小解像度を設定
			@param[in]	size	最小解像度
		*/
		//-----------------------------------------------------------------//
		void set_limit_size(const vtx::spos& size) { limit_size_ = size; }

		//-----------------------------------------------------------------//
		/*!
			@brief	最小解像度を返す
			@return	最小解像度
		*/
		//-----------------------------------------------------------------//
		const vtx::spos& get_limit_size() const { return limit_size_; }

		//-----------------------------------------------------------------//
		/*!
			@brief	解像度を返す（実際の大きさ）
			@return	解像度
		*/
		//-----------------------------------------------------------------//
		const vtx::spos& get_size() const { return size_; }

		//-----------------------------------------------------------------//
		/*!
			@brief	スクリーン位置、サイズを返す（論理的な大きさ）
			@return	配置
		*/
		//-----------------------------------------------------------------//
		const vtx::srect& get_rect() const { return rect_; }

		//-----------------------------------------------------------------//
		/*!
			@brief	ファイル受信 ID の取得
			@return	ファイル受信 ID
		*/
		//-----------------------------------------------------------------//
		int get_recv_file_id() const { return recv_file_id_; }

		//-----------------------------------------------------------------//
		/*!
			@brief	ファイル受信 path の取得
			@return	ファイル受信 path
		*/
		//-----------------------------------------------------------------//
		const utils::strings& get_recv_file_path() const { return recv_file_path_; }

		//-----------------------------------------------------------------//
		/*!
			@brief	平均フレームレートを得る（標準60Hz）
			@return	平均フレームレート
		*/
		//-----------------------------------------------------------------//
		float get_frame_rate() const { return (1.0 / frame_time_); }

		//-----------------------------------------------------------------//
		/*!
			@brief	平均 CPU のクロックを得る。
			@return	平均 CPU クロック(GHz)
		*/
		//-----------------------------------------------------------------//
		float get_cpu_clock() const { return cpu_ghz_; }

		//-----------------------------------------------------------------//
		/*!
			@brief	終了シグナルの受取
			@return	「true」の場合、終了
		*/
		//-----------------------------------------------------------------//
		bool get_exit_signal() const { return exit_signal_; }

		//-----------------------------------------------------------------//
		/*!
			@brief	セットアップ・プロセス
			@param[in]	rect	描画領域と位置
			@param[in]	title	タイトルの設定
			@param[in]	fullscreen	全画面の場合は「ture」
			@return 正常終了したら「true」
		*/
		//-----------------------------------------------------------------//
		bool setup(const vtx::srect& rect, const std::string& title, bool fullscreen);

		//-----------------------------------------------------------------//
		/*!
			@brief	タイトルの登録
			@param[in]	title	タイトル文字列
		*/
		//-----------------------------------------------------------------//
		void set_title(const std::string& title);

		//-----------------------------------------------------------------//
		/*!
			@brief	カーソル（マウスポインター）の設定
			@param[in]	cursortype	カーソル・タイプ
		*/
		//-----------------------------------------------------------------//
///		void set_cursor(cursor cursortype) { ::glutSetCursor(cursortype); }

		//-----------------------------------------------------------------//
		/*!
			@brief	全画面の設定
			@param[in]	flag	全画面の場合「true」
		*/
		//-----------------------------------------------------------------//
		void full_screen(bool flag = true);

		//-----------------------------------------------------------------//
		/*!
			@brief	全画面の設定
			@return 全画面なら「true」
		*/
		//-----------------------------------------------------------------//
		bool is_full_screen() const { return full_screen_; }

		//-----------------------------------------------------------------//
		/*!
			@brief	実行パスを取得
			@return ファイル・パス
		*/
		//-----------------------------------------------------------------//
		const std::string& get_exec_path() const { return exec_path_; }

		//-----------------------------------------------------------------//
		/*!
			@brief	カレントパスを取得
			@return ファイル・パス
		*/
		//-----------------------------------------------------------------//
		const std::string& get_current_path() const { return current_path_; }

		//-----------------------------------------------------------------//
		/*!
			@brief	フレーム・サービス
		*/
		//-----------------------------------------------------------------//
		void service();

		//-----------------------------------------------------------------//
		/*!
			@brief	フレーム・フリップ
		*/
		//-----------------------------------------------------------------//
		void flip_frame();

		//-----------------------------------------------------------------//
		/*!
			@brief	廃棄プロセス
		*/
		//-----------------------------------------------------------------//
		void destroy();

		//-----------------------------------------------------------------//
		/*!
			@brief	デバイス・クラスを受け取る。
			@return デバイス・クラス（const）
		*/
		//-----------------------------------------------------------------//
		const device& get_device() const { return device_; }

		//-----------------------------------------------------------------//
		/*!
			@brief	デバイス・クラスを参照
			@return デバイス・クラス
		*/
		//-----------------------------------------------------------------//
		device& at_device() { return device_; }

		//-----------------------------------------------------------------//
		/*!
			@brief	デバイス・クラスを参照
			@return デバイス・クラス
		*/
		//-----------------------------------------------------------------//
		fonts& at_fonts() { return fonts_; }

		//-----------------------------------------------------------------//
		/*!
			@brief	日本語キーボードか検査
			@return 日本語キーボードの場合「true」が返る
		*/
		//-----------------------------------------------------------------//
		bool keyboard_japan() const { return keyboard_jp_; }

	};
}

<|endoftext|>


<commit_before>// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

#include "pending_notify_remove_done.h"
#include <vespa/searchcore/proton/reference/i_gid_to_lid_change_handler.h>
#include <cassert>

namespace proton
{

PendingNotifyRemoveDone::PendingNotifyRemoveDone()
    : _gidToLidChangeHandler(nullptr),
      _gid(),
      _serialNum(0),
      _pending(false)
{
}

PendingNotifyRemoveDone::PendingNotifyRemoveDone(PendingNotifyRemoveDone &&rhs)
    : _gidToLidChangeHandler(rhs._gidToLidChangeHandler),
      _gid(rhs._gid),
      _serialNum(rhs._serialNum),
      _pending(rhs._pending)
{
    rhs._pending = false;
}

PendingNotifyRemoveDone::~PendingNotifyRemoveDone()
{
    assert(!_pending); // Fail if notifyRemoveDone is still pending
}

void
PendingNotifyRemoveDone::setup(IGidToLidChangeHandler &gidToLidChangeHandler, document::GlobalId gid, search::SerialNum serialNum) {
    _gidToLidChangeHandler = &gidToLidChangeHandler;
    _gid = gid;
    _serialNum = serialNum;
    _pending = true;
}

void
PendingNotifyRemoveDone::invoke()
{
    if (_pending) {
        _gidToLidChangeHandler->notifyRemoveDone(_gid, _serialNum);
        _pending = false;
    }
}

}  // namespace proton
<commit_msg>Add newline.<commit_after>// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

#include "pending_notify_remove_done.h"
#include <vespa/searchcore/proton/reference/i_gid_to_lid_change_handler.h>
#include <cassert>

namespace proton
{

PendingNotifyRemoveDone::PendingNotifyRemoveDone()
    : _gidToLidChangeHandler(nullptr),
      _gid(),
      _serialNum(0),
      _pending(false)
{
}

PendingNotifyRemoveDone::PendingNotifyRemoveDone(PendingNotifyRemoveDone &&rhs)
    : _gidToLidChangeHandler(rhs._gidToLidChangeHandler),
      _gid(rhs._gid),
      _serialNum(rhs._serialNum),
      _pending(rhs._pending)
{
    rhs._pending = false;
}

PendingNotifyRemoveDone::~PendingNotifyRemoveDone()
{
    assert(!_pending); // Fail if notifyRemoveDone is still pending
}

void
PendingNotifyRemoveDone::setup(IGidToLidChangeHandler &gidToLidChangeHandler, document::GlobalId gid, search::SerialNum serialNum)
{
    _gidToLidChangeHandler = &gidToLidChangeHandler;
    _gid = gid;
    _serialNum = serialNum;
    _pending = true;
}

void
PendingNotifyRemoveDone::invoke()
{
    if (_pending) {
        _gidToLidChangeHandler->notifyRemoveDone(_gid, _serialNum);
        _pending = false;
    }
}

}  // namespace proton
<|endoftext|>


<commit_before>#pragma once
//=====================================================================//
/*! @file
    @brief  input クラス @n
			数値、文字列などの入力クラス @n
			%b ---> ２進の数値 @n
			%o ---> ８進の数値 @n
			%d ---> １０進の数値 @n
			%x ---> １６進の数値 @n
			%f ---> 浮動小数点数（float、double） @n
			%c ---> １文字のキャラクター @n
			%% ---> '%' のキャラクター
    @author 平松邦仁 (hira@rvf-rc45.net)
	@copyright	Copyright (C) 2017, 2018 Kunihito Hiramatsu @n
				Released under the MIT license @n
				https://github.com/hirakuni45/glfw_app/blob/master/LICENSE
*/
//=====================================================================//
#include <type_traits>
#include <unistd.h>
#include <cmath>

namespace utils {

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief  標準入力ファンクタ
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	class def_chainp {
		const char* str_;
		char		last_;
		bool		unget_;
	public:
		//-----------------------------------------------------------------//
		/*!
			@brief  コンストラクター
			@param[in]	str		入力文字列（省力された場合「sci_getch」を使う）
		*/
		//-----------------------------------------------------------------//
		def_chainp(const char* str = nullptr) : str_(str), last_(0), unget_(false) { }

		//-----------------------------------------------------------------//
		/*!
			@brief  １文字戻す
		*/
		//-----------------------------------------------------------------//
		void unget() {
			unget_ = true;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  ファンクタ（文字取得）
			@return 文字
		*/
		//-----------------------------------------------------------------//
		char operator() () {
			if(unget_) {
				unget_ = false;
			} else {
				if(str_ == nullptr) {
					char ch;
					if(read(0, &ch, 1) == 1) {
						if(ch == '\n') ch = 0;
						last_ = ch;
					} else {
						last_ = 0;
					}
				} else {
					last_ = *str_;
					if(last_ != 0) { ++str_; }
				}
			}
			return last_;
		}
	};

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief  汎用入力クラス
		@param[in]	INP	文字入力クラス
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	template <class INP>
	class basic_input {
	public:

		//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
		/*!
			@brief  エラー種別
		*/
		//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
		enum class error : uint8_t {
			none,			///< エラー無し
			cha_sets,		///< 文字セットの不一致
			partition,		///< 仕切りキャラクターの不一致
			input_type,		///< 無効な入力タイプ
			not_integer,	///< 整数の不一致
			not_float,		///< 浮動小数点の不一致
			terminate,		///< 終端文字の不一致
		};

	private:
		const char*	form_;

		INP			inp_;

		enum class mode : uint8_t {
			NONE,
			BIN,
			OCT,
			DEC,
			HEX,
			REAL,
			CHA,
		};
		mode	mode_;
		error	error_;
		int		num_;

		uint32_t bin_() {
			uint32_t a = 0;
			char ch;
			while((ch = inp_()) != 0 && ch >= '0' && ch <= '1') {
				a <<= 1;
				a += ch - '0';
			}
			return a;
		}

		uint32_t oct_() {
			uint32_t a = 0;
			char ch;
			while((ch = inp_()) != 0 && ch >= '0' && ch <= '7') {
				a <<= 3;
				a += ch - '0';
			}
			return a;
		}

		uint32_t dec_() {
			uint32_t a = 0;
			char ch;
			while((ch = inp_()) != 0 && ch >= '0' && ch <= '9') {
				a *= 10;
				a += ch - '0';
			}
			return a;
		}

		uint32_t hex_() {
			uint32_t a = 0;
			char ch;
			while((ch = inp_()) != 0) {
				if(ch >= '0' && ch <= '9') {
					a <<= 4;
					a += ch - '0';
				} else if(ch >= 'A' && ch <= 'F') {
					a <<= 4;
					a += ch - 'A' + 10;
				} else if(ch >= 'a' && ch <= 'f') {
					a <<= 4;
					a += ch - 'a' + 10;
				} else {
					break;
				}
			}
			return a;
		}

		template<typename T>
		T real_() {

			struct real_t {
				uint32_t	a;
				uint32_t	b;
				uint32_t	c;
				bool		p;

				real_t() : a(0), b(0), c(1), p(false) { }

				void add(uint32_t v) {
					a *= 10;
					a += v;
					c *= 10;
				}

				void point() {
					b = a;
					a = 0;
					c = 1;
					p = true;
				}

				T get() const {
					if(p) {
						return static_cast<T>(b) + static_cast<T>(a) / static_cast<T>(c);
					} else {
						return static_cast<T>(a);
					}
				}
			};

			real_t base;
			real_t exp;
			char ch;
			bool expf = false;
			while((ch = inp_()) != 0) {
				if(ch >= '0' && ch <= '9') {
					if(expf) {
						exp.add(ch - '0');
					} else {
						base.add(ch - '0');
					}
				} else if(ch == '.') {
					if(expf) {
						if(exp.p) break;
						exp.point();
					} else {
						if(base.p) break;
						base.point();
					}
				} else if(ch == 'e' || ch == 'E') {
					if(expf) break;
					expf = true;
				} else {
					break;
				}
			}

			if(expf) {
				return base.get() * pow(static_cast<T>(10), exp.get());
			} else {
				return base.get();
			}
		}

		void next_()
		{
			enum class fmm : uint8_t {
				none,
				type,
			};
			fmm cm = fmm::none;

			char ch;
			while((ch = *form_++) != 0) {
				switch(cm) {
				case fmm::none:
					if(ch == '[') {
						auto a = inp_();
						const char* p = form_;
						bool ok = false;
						while((ch = *p++) != 0 && ch != ']') {
							if(ch == a) ok = true;
						}
						form_ = p;
						if(!ok) {
							error_ = error::cha_sets;
							return;
						}
					} else if(ch == '%' && *form_ != '%') {
						cm = fmm::type;
					} else if(ch != inp_()) {
						error_ = error::partition;
						return;
					}
					break;

				case fmm::type:
					switch(ch) {
					case 'b':
						mode_ = mode::BIN;
						break;
					case 'o':
						mode_ = mode::OCT;
						break;
					case 'd':
						mode_ = mode::DEC;
						break;
					case 'x':
						mode_ = mode::HEX;
						break;
					case 'f':
						mode_ = mode::REAL;
						break;
					case 'c':
						mode_ = mode::CHA;
						break;
					default:
						error_ = error::input_type;
						break;
					}
					return;
				}
			}
			if(ch == 0 && inp_() == 0) ;
			else {
				error_ = error::terminate;
			}
		}

		bool neg_() {
			bool neg = false;
			auto s = inp_();
			if(s == '-') { neg = true; }
			else if(s == '+') { neg = false; }
			else inp_.unget();
			return neg;
		}

		int32_t nb_int_(bool sign = true)
		{
			auto neg = neg_();

			uint32_t v = 0;
			switch(mode_) {
			case mode::BIN:
				v = bin_();
				break;
			case mode::OCT:
				v = oct_();
				break;
			case mode::DEC:
				v = dec_();
				break;
			case mode::HEX:
				v = hex_();
				break;
			default:
				error_ = error::not_integer;
				break;
			}
			if(error_ == error::none) {
				inp_.unget();
				next_();
				if(error_ == error::none) ++num_;
			}
			if(sign && neg) return -static_cast<int32_t>(v);
			else return static_cast<int32_t>(v);
		}

		template <typename T>
		T nb_real_()
		{
			bool neg = neg_();

			T v = 0.0f;
			switch(mode_) {
			case mode::REAL:
				v = real_<T>();
				break;
			default:
				error_ = error::not_float;
				break;
			}
			if(error_ == error::none) {
				inp_.unget();
				next_();
				if(error_ == error::none) ++num_;
			}
			if(neg) return -v;
			else return v;
		}

	public:
		//-----------------------------------------------------------------//
		/*!
			@brief  コンストラクター
			@param[in]	form	フォーマット式
			@param[in]	inp		変換文字列（nullptrの場合、sci_getch で取得）
		*/
		//-----------------------------------------------------------------//
		basic_input(const char* form, const char* inp = nullptr) noexcept : form_(form), inp_(inp),
			mode_(mode::NONE), error_(error::none), num_(0)
		{
			next_();
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  エラー種別を返す
			@return エラー
		*/
		//-----------------------------------------------------------------//
		error get_error() const noexcept { return error_; }

		//-----------------------------------------------------------------//
		/*!
			@brief  変換ステータスを返す
			@return 変換が全て正常なら「true」
		*/
		//-----------------------------------------------------------------//
		bool status() const noexcept { return error_ == error::none; }

		//-----------------------------------------------------------------//
		/*!
			@brief  正常変換数を取得
			@return 正常変換数
		*/
		//-----------------------------------------------------------------//
		int num() const noexcept { return num_; }

		//-----------------------------------------------------------------//
		/*!
			@brief  テンプレート・オペレーター「%」
			@param[in]	val	整数型
			@return	自分の参照
		*/
		//-----------------------------------------------------------------//
		template <typename T>
		basic_input& operator % (T& val) noexcept
		{
			if(error_ != error::none) return *this;

			if(std::is_floating_point<T>::value) {
				val = nb_real_<T>();
			} else {
				if(mode_ == mode::CHA) {
					val = inp_();
					next_();
				} else {
					val = nb_int_(std::is_signed<T>::value);
				}
			}
			return *this;
		}
	};

	typedef basic_input<def_chainp> input;
}
<commit_msg>update format null check<commit_after>#pragma once
//=====================================================================//
/*! @file
    @brief  input クラス @n
			数値、文字列などの入力クラス @n
			%b ---> ２進の数値 @n
			%o ---> ８進の数値 @n
			%d ---> １０進の数値 @n
			%x ---> １６進の数値 @n
			%f ---> 浮動小数点数（float、double） @n
			%c ---> １文字のキャラクター @n
			%% ---> '%' のキャラクター
    @author 平松邦仁 (hira@rvf-rc45.net)
	@copyright	Copyright (C) 2017, 2018 Kunihito Hiramatsu @n
				Released under the MIT license @n
				https://github.com/hirakuni45/glfw_app/blob/master/LICENSE
*/
//=====================================================================//
#include <type_traits>
#include <unistd.h>
#include <cmath>

namespace utils {

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief  標準入力ファンクタ
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	class def_chainp {
		const char* str_;
		char		last_;
		bool		unget_;
	public:
		//-----------------------------------------------------------------//
		/*!
			@brief  コンストラクター
			@param[in]	str		入力文字列（省力された場合「sci_getch」を使う）
		*/
		//-----------------------------------------------------------------//
		def_chainp(const char* str = nullptr) : str_(str), last_(0), unget_(false) { }

		//-----------------------------------------------------------------//
		/*!
			@brief  １文字戻す
		*/
		//-----------------------------------------------------------------//
		void unget() {
			unget_ = true;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  ファンクタ（文字取得）
			@return 文字
		*/
		//-----------------------------------------------------------------//
		char operator() () {
			if(unget_) {
				unget_ = false;
			} else {
				if(str_ == nullptr) {
					char ch;
					if(read(0, &ch, 1) == 1) {
						if(ch == '\n') ch = 0;
						last_ = ch;
					} else {
						last_ = 0;
					}
				} else {
					last_ = *str_;
					if(last_ != 0) { ++str_; }
				}
			}
			return last_;
		}
	};

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief  汎用入力クラス
		@param[in]	INP	文字入力クラス
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	template <class INP>
	class basic_input {
	public:

		//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
		/*!
			@brief  エラー種別
		*/
		//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
		enum class error : uint8_t {
			none,			///< エラー無し
			null_form,		///< フォーマットが null
			cha_sets,		///< 文字セットの不一致
			partition,		///< 仕切りキャラクターの不一致
			input_type,		///< 無効な入力タイプ
			not_integer,	///< 整数の不一致
			not_float,		///< 浮動小数点の不一致
			terminate,		///< 終端文字の不一致
		};

	private:
		const char*	form_;

		INP			inp_;

		enum class mode : uint8_t {
			NONE,
			BIN,
			OCT,
			DEC,
			HEX,
			REAL,
			CHA,
		};
		mode	mode_;
		error	error_;
		int		num_;

		uint32_t bin_() {
			uint32_t a = 0;
			char ch;
			while((ch = inp_()) != 0 && ch >= '0' && ch <= '1') {
				a <<= 1;
				a += ch - '0';
			}
			return a;
		}

		uint32_t oct_() {
			uint32_t a = 0;
			char ch;
			while((ch = inp_()) != 0 && ch >= '0' && ch <= '7') {
				a <<= 3;
				a += ch - '0';
			}
			return a;
		}

		uint32_t dec_() {
			uint32_t a = 0;
			char ch;
			while((ch = inp_()) != 0 && ch >= '0' && ch <= '9') {
				a *= 10;
				a += ch - '0';
			}
			return a;
		}

		uint32_t hex_() {
			uint32_t a = 0;
			char ch;
			while((ch = inp_()) != 0) {
				if(ch >= '0' && ch <= '9') {
					a <<= 4;
					a += ch - '0';
				} else if(ch >= 'A' && ch <= 'F') {
					a <<= 4;
					a += ch - 'A' + 10;
				} else if(ch >= 'a' && ch <= 'f') {
					a <<= 4;
					a += ch - 'a' + 10;
				} else {
					break;
				}
			}
			return a;
		}

		template<typename T>
		T real_() {

			struct real_t {
				uint32_t	a;
				uint32_t	b;
				uint32_t	c;
				bool		p;

				real_t() : a(0), b(0), c(1), p(false) { }

				void add(uint32_t v) {
					a *= 10;
					a += v;
					c *= 10;
				}

				void point() {
					b = a;
					a = 0;
					c = 1;
					p = true;
				}

				T get() const {
					if(p) {
						return static_cast<T>(b) + static_cast<T>(a) / static_cast<T>(c);
					} else {
						return static_cast<T>(a);
					}
				}
			};

			real_t base;
			real_t exp;
			char ch;
			bool expf = false;
			while((ch = inp_()) != 0) {
				if(ch >= '0' && ch <= '9') {
					if(expf) {
						exp.add(ch - '0');
					} else {
						base.add(ch - '0');
					}
				} else if(ch == '.') {
					if(expf) {
						if(exp.p) break;
						exp.point();
					} else {
						if(base.p) break;
						base.point();
					}
				} else if(ch == 'e' || ch == 'E') {
					if(expf) break;
					expf = true;
				} else {
					break;
				}
			}

			if(expf) {
				return base.get() * pow(static_cast<T>(10), exp.get());
			} else {
				return base.get();
			}
		}

		void next_()
		{
			enum class fmm : uint8_t {
				none,
				type,
			};
			fmm cm = fmm::none;

			char ch;
			while((ch = *form_++) != 0) {
				switch(cm) {
				case fmm::none:
					if(ch == '[') {
						auto a = inp_();
						const char* p = form_;
						bool ok = false;
						while((ch = *p++) != 0 && ch != ']') {
							if(ch == a) ok = true;
						}
						form_ = p;
						if(!ok) {
							error_ = error::cha_sets;
							return;
						}
					} else if(ch == '%' && *form_ != '%') {
						cm = fmm::type;
					} else if(ch != inp_()) {
						error_ = error::partition;
						return;
					}
					break;

				case fmm::type:
					switch(ch) {
					case 'b':
						mode_ = mode::BIN;
						break;
					case 'o':
						mode_ = mode::OCT;
						break;
					case 'd':
						mode_ = mode::DEC;
						break;
					case 'x':
						mode_ = mode::HEX;
						break;
					case 'f':
						mode_ = mode::REAL;
						break;
					case 'c':
						mode_ = mode::CHA;
						break;
					default:
						error_ = error::input_type;
						break;
					}
					return;
				}
			}
			if(ch == 0 && inp_() == 0) ;
			else {
				error_ = error::terminate;
			}
		}

		bool neg_() {
			bool neg = false;
			auto s = inp_();
			if(s == '-') { neg = true; }
			else if(s == '+') { neg = false; }
			else inp_.unget();
			return neg;
		}

		int32_t nb_int_(bool sign = true)
		{
			auto neg = neg_();

			uint32_t v = 0;
			switch(mode_) {
			case mode::BIN:
				v = bin_();
				break;
			case mode::OCT:
				v = oct_();
				break;
			case mode::DEC:
				v = dec_();
				break;
			case mode::HEX:
				v = hex_();
				break;
			default:
				error_ = error::not_integer;
				break;
			}
			if(error_ == error::none) {
				inp_.unget();
				next_();
				if(error_ == error::none) ++num_;
			}
			if(sign && neg) return -static_cast<int32_t>(v);
			else return static_cast<int32_t>(v);
		}

		template <typename T>
		T nb_real_()
		{
			bool neg = neg_();

			T v = 0.0f;
			switch(mode_) {
			case mode::REAL:
				v = real_<T>();
				break;
			default:
				error_ = error::not_float;
				break;
			}
			if(error_ == error::none) {
				inp_.unget();
				next_();
				if(error_ == error::none) ++num_;
			}
			if(neg) return -v;
			else return v;
		}

	public:
		//-----------------------------------------------------------------//
		/*!
			@brief  コンストラクター
			@param[in]	form	フォーマット式
			@param[in]	inp		変換文字列（nullptrの場合、sci_getch で取得）
		*/
		//-----------------------------------------------------------------//
		basic_input(const char* form, const char* inp = nullptr) noexcept : form_(form), inp_(inp),
			mode_(mode::NONE), error_(error::none), num_(0)
		{
			if(form_ == nullptr) {
				error_ = error::null_form;
			} else {
				next_();
			}
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  エラー種別を返す
			@return エラー
		*/
		//-----------------------------------------------------------------//
		error get_error() const noexcept { return error_; }

		//-----------------------------------------------------------------//
		/*!
			@brief  変換ステータスを返す
			@return 変換が全て正常なら「true」
		*/
		//-----------------------------------------------------------------//
		bool status() const noexcept { return error_ == error::none; }

		//-----------------------------------------------------------------//
		/*!
			@brief  正常変換数を取得
			@return 正常変換数
		*/
		//-----------------------------------------------------------------//
		int num() const noexcept { return num_; }

		//-----------------------------------------------------------------//
		/*!
			@brief  テンプレート・オペレーター「%」
			@param[in]	val	整数型
			@return	自分の参照
		*/
		//-----------------------------------------------------------------//
		template <typename T>
		basic_input& operator % (T& val) noexcept
		{
			if(error_ != error::none) return *this;

			if(std::is_floating_point<T>::value) {
				val = nb_real_<T>();
			} else {
				if(mode_ == mode::CHA) {
					val = inp_();
					next_();
				} else {
					val = nb_int_(std::is_signed<T>::value);
				}
			}
			return *this;
		}
	};

	typedef basic_input<def_chainp> input;
}
<|endoftext|>


<commit_before>/*!
    \file binlogread.cpp
    \brief Binary logs reader definition
    \author Ivan Shynkarenka
    \date 16.09.2015
    \copyright MIT License
*/

#include <stdio.h>

#include "version.h"
#include "logging/record.h"
#include "logging/layouts/text_layout.h"

#include <iostream>
#include <vector>

#include <OptionParser.h>

using namespace CppLogging;

bool InputRecord(FILE* input, Record& record)
{
    static std::vector<uint8_t> raw(4096);

    uint32_t size;
    if (fread(&size, sizeof(uint32_t), 1, input) != 1)
        return false;

    raw.resize(size);

    if (fread(raw.data(), 1, size, input) != size)
    {
        std::cerr << "Failed to read from the input file!" << std::endl;
        return false;
    }

    // Get the buffer start position
    const uint8_t* buffer = raw.data();

    // Deserialize logging record
    std::memcpy(&record.timestamp, buffer, sizeof(uint64_t));
    buffer += sizeof(uint64_t);
    std::memcpy(&record.thread, buffer, sizeof(uint64_t));
    buffer += sizeof(uint64_t);
    std::memcpy(&record.level, buffer, sizeof(Level));
    buffer += sizeof(Level);

    uint8_t logger_size;
    std::memcpy(&logger_size, buffer, sizeof(uint8_t));
    buffer += sizeof(uint8_t);
    record.logger.clear();
    record.logger.insert(record.logger.begin(), buffer, buffer + logger_size);
    buffer += logger_size;

    uint16_t message_size;
    std::memcpy(&message_size, buffer, sizeof(uint16_t));
    buffer += sizeof(uint16_t);
    record.message.clear();
    record.message.insert(record.message.begin(), buffer, buffer + message_size);
    buffer += message_size;

    uint32_t buffer_size;
    std::memcpy(&buffer_size, buffer, sizeof(uint32_t));
    buffer += sizeof(uint32_t);
    record.buffer.clear();
    record.buffer.insert(record.buffer.begin(), buffer, buffer + buffer_size);
    buffer += buffer_size;

    // Skip the last zero byte
    ++buffer;

    return true;
}

bool OutputRecord(FILE* output, Record& record)
{
    TextLayout layout;
    layout.LayoutRecord(record);

    if (fwrite(record.raw.data(), 1, record.raw.size() - 1, output) != (record.raw.size() - 1))
    {
        std::cerr << "Failed to write into the output file!" << std::endl;
        return false;
    }

    return true;
}

int main(int argc, char** argv)
{
    auto parser = optparse::OptionParser().version(version);

    parser.add_option("-h", "--help").help("Show help");
    parser.add_option("-i", "--input").help("Input file name");
    parser.add_option("-o", "--output").help("Output file name");

    optparse::Values options = parser.parse_args(argc, argv);

    // Print help
    if (options.get("help"))
    {
        parser.print_help();
        parser.exit();
    }

    // Open the input file or stdin
    FILE* input_file = options.is_set("input") ? fopen(options.get("input"), "rb") : stdin;
    if (input_file == nullptr)
    {
        std::cerr << "Failed to open the input file!" << std::endl;
        return -1;
    }

    // Open the output file or stdout
    FILE* output_file = options.is_set("output") ? fopen(options.get("input"), "wb") : stdout;
    if (output_file == nullptr)
    {
        std::cerr << "Failed to open the output file!" << std::endl;
        return -1;
    }

    // Process all logging record
    Record record;
    while (InputRecord(input_file, record))
        if (!OutputRecord(output_file, record))
            break;

    // Close the input file
    if (options.is_set("input"))
    {
        if (fclose(input_file) != 0)
        {
            std::cerr << "Failed to close the input file!" << std::endl;
            return -1;
        }
    }

    // Close the output file
    if (options.is_set("output"))
    {
        if (fclose(output_file) != 0)
        {
            std::cerr << "Failed to close the output file!" << std::endl;
            return -1;
        }
    }

    return 0;
}
<commit_msg>Fix linux build<commit_after>/*!
    \file binlogread.cpp
    \brief Binary logs reader definition
    \author Ivan Shynkarenka
    \date 16.09.2015
    \copyright MIT License
*/

#include <stdio.h>

#include "version.h"
#include "logging/record.h"
#include "logging/layouts/text_layout.h"

#include <cstring>
#include <iostream>
#include <vector>

#include <OptionParser.h>

using namespace CppLogging;

bool InputRecord(FILE* input, Record& record)
{
    static std::vector<uint8_t> raw(4096);

    uint32_t size;
    if (fread(&size, sizeof(uint32_t), 1, input) != 1)
        return false;

    raw.resize(size);

    if (fread(raw.data(), 1, size, input) != size)
    {
        std::cerr << "Failed to read from the input file!" << std::endl;
        return false;
    }

    // Get the buffer start position
    const uint8_t* buffer = raw.data();

    // Deserialize logging record
    std::memcpy(&record.timestamp, buffer, sizeof(uint64_t));
    buffer += sizeof(uint64_t);
    std::memcpy(&record.thread, buffer, sizeof(uint64_t));
    buffer += sizeof(uint64_t);
    std::memcpy(&record.level, buffer, sizeof(Level));
    buffer += sizeof(Level);

    uint8_t logger_size;
    std::memcpy(&logger_size, buffer, sizeof(uint8_t));
    buffer += sizeof(uint8_t);
    record.logger.clear();
    record.logger.insert(record.logger.begin(), buffer, buffer + logger_size);
    buffer += logger_size;

    uint16_t message_size;
    std::memcpy(&message_size, buffer, sizeof(uint16_t));
    buffer += sizeof(uint16_t);
    record.message.clear();
    record.message.insert(record.message.begin(), buffer, buffer + message_size);
    buffer += message_size;

    uint32_t buffer_size;
    std::memcpy(&buffer_size, buffer, sizeof(uint32_t));
    buffer += sizeof(uint32_t);
    record.buffer.clear();
    record.buffer.insert(record.buffer.begin(), buffer, buffer + buffer_size);
    buffer += buffer_size;

    // Skip the last zero byte
    ++buffer;

    return true;
}

bool OutputRecord(FILE* output, Record& record)
{
    TextLayout layout;
    layout.LayoutRecord(record);

    if (fwrite(record.raw.data(), 1, record.raw.size() - 1, output) != (record.raw.size() - 1))
    {
        std::cerr << "Failed to write into the output file!" << std::endl;
        return false;
    }

    return true;
}

int main(int argc, char** argv)
{
    auto parser = optparse::OptionParser().version(version);

    parser.add_option("-h", "--help").help("Show help");
    parser.add_option("-i", "--input").help("Input file name");
    parser.add_option("-o", "--output").help("Output file name");

    optparse::Values options = parser.parse_args(argc, argv);

    // Print help
    if (options.get("help"))
    {
        parser.print_help();
        parser.exit();
    }

    // Open the input file or stdin
    FILE* input_file = options.is_set("input") ? fopen(options.get("input"), "rb") : stdin;
    if (input_file == nullptr)
    {
        std::cerr << "Failed to open the input file!" << std::endl;
        return -1;
    }

    // Open the output file or stdout
    FILE* output_file = options.is_set("output") ? fopen(options.get("input"), "wb") : stdout;
    if (output_file == nullptr)
    {
        std::cerr << "Failed to open the output file!" << std::endl;
        return -1;
    }

    // Process all logging record
    Record record;
    while (InputRecord(input_file, record))
        if (!OutputRecord(output_file, record))
            break;

    // Close the input file
    if (options.is_set("input"))
    {
        if (fclose(input_file) != 0)
        {
            std::cerr << "Failed to close the input file!" << std::endl;
            return -1;
        }
    }

    // Close the output file
    if (options.is_set("output"))
    {
        if (fclose(output_file) != 0)
        {
            std::cerr << "Failed to close the output file!" << std::endl;
            return -1;
        }
    }

    return 0;
}
<|endoftext|>


<commit_before>//=============================================================================
// ■ RenderBuffer.cpp
//-----------------------------------------------------------------------------
//   VMDE中渲染对象缓冲
//=============================================================================

#include "global.hpp"

RenderBuffer::RenderBuffer(int w, int h, int mrt, const GLuint* type) {
	log("Creating Render Buffer of %d x %d", w, h);

	glGenFramebuffers(1, &framebuffer);
	glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);

	mrtcount = mrt;
	texture_buffer = new Res::Texture*[mrt + 1];
	// Always reserve the last space for depth
	for (int i = 0; i < mrt; i++) {
		texture_buffer[i] = new Res::Texture();
		glGenTextures(1, &(texture_buffer[i]->texture));
		VMSC::ChangeTexture2D(texture_buffer[i]->texture);
		glTexImage2D(GL_TEXTURE_2D, 0, type[i], w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
		texture_buffer[i]->width = w; texture_buffer[i]->height = h;
		glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, texture_buffer[i]->texture, 0);

		texture_buffer[i]->parameter = &Res::LinearTextureParameters;
	}
	//glBindTexture(GL_TEXTURE_2D, 0);

	// Generate depth tex
	{
		texture_buffer[mrt] = new Res::Texture();
		glGenTextures(1, &(texture_buffer[mrt]->texture));
		VMSC::ChangeTexture2D(texture_buffer[mrt]->texture);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
		glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, w, h, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);
		texture_buffer[mrt]->width = w; texture_buffer[mrt]->height = h;
		glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, texture_buffer[mrt]->texture, 0);
		texture_buffer[mrt]->parameter = &Res::LinearTextureParameters;
	}
	glGenRenderbuffers(1, &rbo);
	glBindRenderbuffer(GL_RENDERBUFFER, rbo);
	glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX, w, h);
	glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo);
	// Check errors
	if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
		error("Framebuffer creation failed. Framebuffer is not complete");
	check_gl_error;
	glBindFramebuffer(GL_FRAMEBUFFER, 0);
}

void RenderBuffer::bind() {
	 glBindFramebuffer(GL_FRAMEBUFFER, this->framebuffer);
}

void RenderBuffer::set_draw_buffers() {
	GLuint attachments[mrtcount];
	for (int i = 0; i < mrtcount; i++) attachments[i] = GL_COLOR_ATTACHMENT0 + i;
	glDrawBuffers(mrtcount, attachments);
}

RenderBuffer::~RenderBuffer () {
	log("Delete Buffer %d", framebuffer);

	for (int i = 0; i < mrtcount + 1; i++) XE(delete, texture_buffer[i]);
	XE(delete, texture_buffer);

	glDeleteRenderbuffers(1, &rbo);
	glDeleteFramebuffers(1, &framebuffer);
}

GDrawable* PostProcessingManager::QuadScreen;

void PostProcessingManager::init() {
	Vertex* vtx = new Vertex[4] {
		{{-1.0, -1.0, 0.0},{1.0, 1.0, 1.0, 1.0},{0.0,0.0},{0.0, 0.0, 0.0}},
		{{-1.0,  1.0, 0.0},{1.0, 1.0, 1.0, 1.0},{0.0,1.0},{0.0, 0.0, 0.0}},
		{{ 1.0,  1.0, 0.0},{1.0, 1.0, 1.0, 1.0},{1.0,1.0},{0.0, 0.0, 0.0}},
		{{ 1.0, -1.0, 0.0},{1.0, 1.0, 1.0, 1.0},{1.0,0.0},{0.0, 0.0, 0.0}},
	};
	GLuint* itx = new GLuint[6] { 0,1,3, 1,2,3 };

	QuadScreen = new GDrawable(NULL, NULL);
	QuadScreen->data.vtx_c = 4;
	QuadScreen->data.ind_c = 6;
	QuadScreen->data.vertices = (GLuint*)vtx;
	QuadScreen->data.indices = itx;
	QuadScreen->data.mat_c = 0;
	QuadScreen->data.mat = NULL;
	QuadScreen->fbind();
}

void PostProcessingManager::Blit2D() {
	VMSC::disable_depth_test();
	VMSC::disable_cullface();
	QuadScreen->renderOnce();
	VMSC::enable_depth_test();
	VMSC::enable_cullface();
}
<commit_msg>Change to depth 24 stencil 8<commit_after>//=============================================================================
// ■ RenderBuffer.cpp
//-----------------------------------------------------------------------------
//   VMDE中渲染对象缓冲
//=============================================================================

#include "global.hpp"

RenderBuffer::RenderBuffer(int w, int h, int mrt, const GLuint* type) {
	log("Creating Render Buffer of %d x %d", w, h);

	glGenFramebuffers(1, &framebuffer);
	glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);

	mrtcount = mrt;
	texture_buffer = new Res::Texture*[mrt + 1];
	// Always reserve the last space for depth
	for (int i = 0; i < mrt; i++) {
		texture_buffer[i] = new Res::Texture();
		glGenTextures(1, &(texture_buffer[i]->texture));
		VMSC::ChangeTexture2D(texture_buffer[i]->texture);
		glTexImage2D(GL_TEXTURE_2D, 0, type[i], w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
		texture_buffer[i]->width = w; texture_buffer[i]->height = h;
		glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, texture_buffer[i]->texture, 0);

		texture_buffer[i]->parameter = &Res::LinearTextureParameters;
	}
	//glBindTexture(GL_TEXTURE_2D, 0);

	// Generate depth tex
	{
		texture_buffer[mrt] = new Res::Texture();
		glGenTextures(1, &(texture_buffer[mrt]->texture));
		VMSC::ChangeTexture2D(texture_buffer[mrt]->texture);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
		glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, w, h, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);
		texture_buffer[mrt]->width = w; texture_buffer[mrt]->height = h;
		glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, texture_buffer[mrt]->texture, 0);
		texture_buffer[mrt]->parameter = &Res::LinearTextureParameters;
	}

	// We use stencil 24 depth 8 internal format
	//glGenRenderbuffers(1, &rbo);
	//glBindRenderbuffer(GL_RENDERBUFFER, rbo);
	//glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX, w, h);
	//glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo);

	// Check errors
	if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
		error("Framebuffer creation failed. Framebuffer is not complete");
	check_gl_error;
	glBindFramebuffer(GL_FRAMEBUFFER, 0);
}

void RenderBuffer::bind() {
	 glBindFramebuffer(GL_FRAMEBUFFER, this->framebuffer);
}

void RenderBuffer::set_draw_buffers() {
	GLuint attachments[mrtcount];
	for (int i = 0; i < mrtcount; i++) attachments[i] = GL_COLOR_ATTACHMENT0 + i;
	glDrawBuffers(mrtcount, attachments);
}

RenderBuffer::~RenderBuffer () {
	log("Delete Buffer %d", framebuffer);

	for (int i = 0; i < mrtcount + 1; i++) XE(delete, texture_buffer[i]);
	XE(delete, texture_buffer);

	glDeleteRenderbuffers(1, &rbo);
	glDeleteFramebuffers(1, &framebuffer);
}

GDrawable* PostProcessingManager::QuadScreen;

void PostProcessingManager::init() {
	Vertex* vtx = new Vertex[4] {
		{{-1.0, -1.0, 0.0},{1.0, 1.0, 1.0, 1.0},{0.0,0.0},{0.0, 0.0, 0.0}},
		{{-1.0,  1.0, 0.0},{1.0, 1.0, 1.0, 1.0},{0.0,1.0},{0.0, 0.0, 0.0}},
		{{ 1.0,  1.0, 0.0},{1.0, 1.0, 1.0, 1.0},{1.0,1.0},{0.0, 0.0, 0.0}},
		{{ 1.0, -1.0, 0.0},{1.0, 1.0, 1.0, 1.0},{1.0,0.0},{0.0, 0.0, 0.0}},
	};
	GLuint* itx = new GLuint[6] { 0,1,3, 1,2,3 };

	QuadScreen = new GDrawable(NULL, NULL);
	QuadScreen->data.vtx_c = 4;
	QuadScreen->data.ind_c = 6;
	QuadScreen->data.vertices = (GLuint*)vtx;
	QuadScreen->data.indices = itx;
	QuadScreen->data.mat_c = 0;
	QuadScreen->data.mat = NULL;
	QuadScreen->fbind();
}

void PostProcessingManager::Blit2D() {
	VMSC::disable_depth_test();
	VMSC::disable_cullface();
	QuadScreen->renderOnce();
	VMSC::enable_depth_test();
	VMSC::enable_cullface();
}
<|endoftext|>


<commit_before>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <systemlib/err.h>
#include <drivers/drv_hrt.h>
#include <rc/st24.h>
#include "../../src/systemcmds/tests/tests.h"

int main(int argc, char *argv[]) {
	warnx("ST24 test started");

	if (argc < 2)
		errx(1, "Need a filename for the input file");

	warnx("loading data from: %s", argv[1]);

	FILE *fp;

	fp = fopen(argv[1],"rt");

	if (!fp)
		errx(1, "failed opening file");

	float f;
	unsigned x;
	int ret;

	// Trash the first 20 lines
	for (unsigned i = 0; i < 20; i++) {
		char buf[200];
		(void)fgets(buf, sizeof(buf), fp);
	}

	float last_time = 0;

	while (EOF != (ret = fscanf(fp, "%f,%x,,", &f, &x))) {
		if (((f - last_time) * 1000 * 1000) > 3000) {
			//warnx("FRAME RESET\n\n");
		}

		uint8_t b = static_cast<uint8_t>(x);

		last_time = f;

		// Pipe the data into the parser
		hrt_abstime now = hrt_absolute_time();

		uint8_t rssi;
		uint8_t rx_count;
		uint16_t channel_count;
		int16_t channels[20];

		if (!st24_decode(b, &rssi, &rx_count, &channel_count, channels, sizeof(channels) / sizeof(channels[0])))
		{
			//warnx("decoded: %u channels", (unsigned)channel_count);
			for (unsigned i = 0; i < channel_count; i++) {

				int16_t val = channels[i];
				// if (i == 6)
					warnx("channel %u: %d 0x%03X", i, static_cast<int>(val), static_cast<int>(val));
			}
			// unsigned chan = 1;
			// warnx("channel %u: %d", chan, static_cast<int>(channels[chan]));
		}

		//warnx("%f: 0x%02x >> RSSI: %u #: %u", (double)f, x, static_cast<unsigned>(rssi), static_cast<unsigned>(rx_count));
	}

	if (ret == EOF) {
		warnx("Test finished, reached end of file");
	} else {
		warnx("Test aborted, errno: %d", ret);
	}

}
<commit_msg>Formatted ST24 test code<commit_after>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <systemlib/err.h>
#include <drivers/drv_hrt.h>
#include <rc/st24.h>
#include "../../src/systemcmds/tests/tests.h"

int main(int argc, char *argv[])
{
	warnx("ST24 test started");

	if (argc < 2) {
		errx(1, "Need a filename for the input file");
	}

	warnx("loading data from: %s", argv[1]);

	FILE *fp;

	fp = fopen(argv[1], "rt");

	if (!fp) {
		errx(1, "failed opening file");
	}

	float f;
	unsigned x;
	int ret;

	// Trash the first 20 lines
	for (unsigned i = 0; i < 20; i++) {
		char buf[200];
		(void)fgets(buf, sizeof(buf), fp);
	}

	float last_time = 0;

	while (EOF != (ret = fscanf(fp, "%f,%x,,", &f, &x))) {
		if (((f - last_time) * 1000 * 1000) > 3000) {
			// warnx("FRAME RESET\n\n");
		}

		uint8_t b = static_cast<uint8_t>(x);

		last_time = f;

		// Pipe the data into the parser
		hrt_abstime now = hrt_absolute_time();

		uint8_t rssi;
		uint8_t rx_count;
		uint16_t channel_count;
		uint16_t channels[20];

		if (!st24_decode(b, &rssi, &rx_count, &channel_count, channels, sizeof(channels) / sizeof(channels[0]))) {
			warnx("decoded: %u channels (converted to PPM range)", (unsigned)channel_count);

			for (unsigned i = 0; i < channel_count; i++) {

				int16_t val = channels[i];
				warnx("channel %u: %d 0x%03X", i, static_cast<int>(val), static_cast<int>(val));
			}
		}
	}

	if (ret == EOF) {
		warnx("Test finished, reached end of file");

	} else {
		warnx("Test aborted, errno: %d", ret);
	}

}
<|endoftext|>


<commit_before>/*********************************************************************************
- Contact:    Brigitte Cheynis     b.cheynis@ipnl.in2p3.fr
- Link:
- Raw data test file :
- Reference run number : 137366
- Run Type:   PHYSICS
- DA Type:    MON
- Number of events needed: >=2000
- Input Files:  argument list
- Output Files: FXS file     V0_EqualizationFactors.dat (Channel equalization factors)
- Trigger types used: PHYSICS_EVENT
**********************************************************************************/

/**********************************************************************************
*                                                                                *
* VZERO Detector Algorithm for extracting channel equalization factors for Pb-Pb  *
*                                                                                *
*                                                                                *
***********************************************************************************/

// DATE
#include "event.h"
#include "monitor.h"
#include "daqDA.h"

//AliRoot
#include <AliVZERORawStream.h>
#include <AliRawReaderDate.h>
#include <AliRawReader.h>
#include <AliDAQ.h>

// standard
#include <stdio.h>
#include <stdlib.h>

//ROOT
#include "TROOT.h"
#include "TPluginManager.h"
#include <TFile.h>
#include <TH1F.h>
#include <TMath.h>

Int_t GetOfflineChannel(Int_t channel);

/* Main routine --- Arguments: monitoring data source */

int main(int argc, char **argv) {

/* magic line from Cvetan */
  gROOT->GetPluginManager()->AddHandler("TVirtualStreamerInfo",
                    "*",
                    "TStreamerInfo",
                    "RIO",
                    "TStreamerInfo()");
  int status;
  if (argc!=2) {
     printf("Wrong number of arguments\n");
     return -1;
  }

//___________________________________________________
// Get parameters from V00DAEqualFactors.config file

  Int_t    kStartClock = 9;  // First clock in the search for max adc
  Int_t    kEndClock = 11;   // Last clock in the search for max adc
  Int_t    kNPreClocks = 6;  // Number of clock before max used in the charge sum
  Int_t    kNPostClocks = 1; // Number of clock after max used in the charge sum

  UShort_t    kTriggerAcc = 64;    // Trigger mask for accepted events (64 = CTA1 & CTC1)
  UShort_t    kTriggerRej = 256;   // Trigger mask for rejected events (256 = CTA2 & CTC2)

  Int_t    kNBins = 10000;
  Float_t  kRange = 0.1;

  status = daqDA_DB_getFile("V00DAEqualFactors.config","./V00DAEqualFactors.config");
  if (status) {
    printf("Failed to get Config file (V00DAEqualFactors.config) from DAQ DB, status=%d\n", status);
    printf("Take default values of parameters for pedestal calculation \n");
  } else {
    /* open the config file and retrieve cuts */
    FILE *fpConfig = fopen("V00DAEqualFactors.config","r");
    int res = fscanf(fpConfig,"%d %d %d %d %hu %hu %d %f",
		     &kStartClock,&kEndClock,&kNPreClocks,&kNPostClocks,&kTriggerAcc,&kTriggerRej,&kNBins,&kRange);
    if(res!=8) {
      printf("Failed to get values from Config file (V00DAEqualFactors.config): wrong file format - 7 integers and 1 float are expected - \n");
    }
    fclose(fpConfig);
  }

  printf("First LHC Clock = %d; Last LHC Clock = %d; N Pre Clock = %d ; N Post Clock = %d; Trigger mask for accepted events = %u; Trigger mask for rejected events = %u; Number of histogram bins = %d; Histogram range = %.3f\n",
	 kStartClock, kEndClock, kNPreClocks, kNPostClocks, kTriggerAcc, kTriggerRej, kNBins, kRange);

  TH1D *fMedian[64];
  for(Int_t j = 0; j < 64; ++j) fMedian[j] = new TH1D(Form("fMedian_%d",j),"Slopes weighted median, channel par channel",kNBins,0,kRange);

  Bool_t fFirst = kTRUE;
  Float_t fPrevTotCharge = 0;
  Float_t fPrevadc[64];
  for(Int_t j = 0; j < 64; ++j) fPrevadc[j] = 0;

//___________________________________________________

  /* define data source : this is argument 1 */
  status=monitorSetDataSource( argv[1] );
  if (status!=0) {
     printf("monitorSetDataSource() failed : %s\n",monitorDecodeError(status));
     return -1;
  }

  /* declare monitoring program */
  status=monitorDeclareMp( __FILE__ );
  if (status!=0) {
    printf("monitorDeclareMp() failed : %s\n",monitorDecodeError(status));
    return -1;
  }

  /* define wait event timeout - 1s max */
  monitorSetNowait();
  monitorSetNoWaitNetworkTimeout(1000);

  /* init counters on events */
  int neventsPhysics=0;
  int neventsTotal=0;

  /* loop on events (infinite) */
  for(;;) {
      struct eventHeaderStruct *event;
      eventTypeType eventT;

      /* check shutdown condition */
      if (daqDA_checkShutdown()) {break;}

      /* get next event (blocking call until timeout) */
      status=monitorGetEventDynamic((void **)&event);
      if (status==MON_ERR_EOF) {
          printf ("End of File detected\n");
      break; /* end of monitoring file has been reached */
      }

      if (status!=0) {
           printf("monitorGetEventDynamic() failed : %s\n",monitorDecodeError(status));
      break;
      }

      /* retry if got no event */
      if (event==NULL) continue;

      /* decode event */
      eventT=event->eventType;

      switch (event->eventType){

      case START_OF_RUN:
           break;

      case END_OF_RUN:
           printf("End Of Run detected\n");
           break;

      case PHYSICS_EVENT:

	   AliRawReader *rawReader = new AliRawReaderDate((void*)event);

	   AliVZERORawStream* rawStream  = new AliVZERORawStream(rawReader);
	   if (rawStream->Next()) {
	     UShort_t triggers = rawStream->GetTriggerInputs();
	     if (((triggers & kTriggerAcc) == kTriggerAcc) &&  // Check if the requested trigger(s) is fired
		 ((triggers & kTriggerRej) == 0)) { // Check if the requested trigger(s) is NOT fired
	       neventsPhysics++;

	       Float_t adc[64];
	       Float_t totCharge = 0.;
	       for(Int_t i = 0; i < 64; ++i) {
		 adc[i] = 0.;
		 Float_t maxadc=0.;
		 Int_t imax=-1;
		 for(Int_t j = kStartClock; j <= kEndClock; ++j) {
		   Float_t charge = (Float_t)(rawStream->GetPedestal(i,j));
		   if(charge > maxadc){
		     maxadc = charge;
		     imax   = j;
		   }
		 }

		 if (imax != -1) {
		   Int_t start = imax - kNPreClocks;
		   if (start < 0) start = 0;
		   Int_t end = imax + kNPostClocks;
		   if (end > 20) end = 20;
		   for(Int_t iClock = start; iClock <= end; iClock++) {
		     adc[i] += (Float_t)(rawStream->GetPedestal(i,iClock));
		   }
		 }
		 totCharge += adc[i];
	       }

	       if (fFirst) {
		 fFirst = kFALSE;
		 fPrevTotCharge = totCharge;
		 for(int i = 0; i < 64; ++i) fPrevadc[i] = adc[i];
	       }
	       else {
		 fFirst = kTRUE;
		 Float_t deltaTotCharge = totCharge - fPrevTotCharge;
		 Float_t weight = deltaTotCharge*deltaTotCharge;
		 if (weight > 1) {
		   for(int i = 0; i < 64; ++i) {
		     fMedian[i]->Fill((adc[i]-fPrevadc[i])/deltaTotCharge,weight);
		   }
		 }
	       }

	     }
	   }   // End : if rawstream
           delete rawStream;
           rawStream = 0x0;
           delete rawReader;
           rawReader = 0x0;
      } // end of switch on event type

      neventsTotal++;
      /* free resources */
      free(event);

      /* exit when last event received, no need to wait for TERM signal */
      if (eventT==END_OF_RUN) {
	printf("End Of Run event detected\n");
	break;
      }

  }  // loop over events

  printf("%d physics events processed\n",neventsPhysics);

//___________________________________________________________________________
//  Computes regression parameters
// charge_i = p0 + charge_tot * p1

  if(neventsPhysics>2000){
    /* open result file to be exported to FES */
    FILE *fp=NULL;
    fp=fopen("./V0_EqualizationFactors.dat","w");
    if (fp==NULL) {
      printf("Failed to open local result file\n");
      return -1;}

    Double_t beta[64];
    Double_t q = 0.5;
    for(int i = 0; i < 64; ++i) fMedian[i]->GetQuantiles(1,&beta[i],&q);

    for(Int_t i=0; i<64; i++) {
      fprintf(fp," %d %.3f\n",GetOfflineChannel(i), beta[i]*64.);
      printf(" %d %.3f\n",GetOfflineChannel(i), beta[i]*64.);
    }

    /* close local result file and FXS result file*/
    fclose(fp);
  }

//________________________________________________________________________

  /* export result file to FES */
  status=daqDA_FES_storeFile("./V0_EqualizationFactors.dat","V00DAEqualFactors");
  if (status)    {
    printf("Failed to export file : %d\n",status);
    return -1; }

  /* store result file into Online DB */
  status=daqDA_DB_storeFile("./V0_EqualizationFactors.dat","V00DAEqualFactors");
  if (status)    {
    printf("Failed to store file into Online DB: %d\n",status);
    return -1; }

  return status;
}

 Int_t GetOfflineChannel(Int_t channel) {

// Channel mapping Online - Offline:

 Int_t fOfflineChannel[64] = {39, 38, 37, 36, 35, 34, 33, 32,
                              47, 46, 45, 44, 43, 42, 41, 40,
			      55, 54, 53, 52, 51, 50, 49, 48,
			      63, 62, 61, 60, 59, 58, 57, 56,
			       7,  6,  5,  4,  3,  2,  1,  0,
			      15, 14, 13, 12, 11, 10,  9,  8,
			      23, 22, 21, 20, 19, 18, 17, 16,
			      31, 30, 29, 28, 27, 26, 25, 24};
 return	fOfflineChannel[channel];
}
<commit_msg>Since the trigger bits are not available in the V0 raw-data header, we replace the trigger selection by a cut on the minimum number of TDC flags present.<commit_after>/*********************************************************************************
- Contact:    Brigitte Cheynis     b.cheynis@ipnl.in2p3.fr
- Link:
- Raw data test file :
- Reference run number : 137366
- Run Type:   PHYSICS
- DA Type:    MON
- Number of events needed: >=2000
- Input Files:  argument list
- Output Files: FXS file     V0_EqualizationFactors.dat (Channel equalization factors)
- Trigger types used: PHYSICS_EVENT
**********************************************************************************/

/**********************************************************************************
*                                                                                *
* VZERO Detector Algorithm for extracting channel equalization factors for Pb-Pb  *
*                                                                                *
*                                                                                *
***********************************************************************************/

// DATE
#include "event.h"
#include "monitor.h"
#include "daqDA.h"

//AliRoot
#include <AliVZERORawStream.h>
#include <AliRawReaderDate.h>
#include <AliRawReader.h>
#include <AliDAQ.h>

// standard
#include <stdio.h>
#include <stdlib.h>

//ROOT
#include "TROOT.h"
#include "TPluginManager.h"
#include <TFile.h>
#include <TH1F.h>
#include <TMath.h>

Int_t GetOfflineChannel(Int_t channel);

/* Main routine --- Arguments: monitoring data source */

int main(int argc, char **argv) {

/* magic line from Cvetan */
  gROOT->GetPluginManager()->AddHandler("TVirtualStreamerInfo",
                    "*",
                    "TStreamerInfo",
                    "RIO",
                    "TStreamerInfo()");
  int status;
  if (argc!=2) {
     printf("Wrong number of arguments\n");
     return -1;
  }

//___________________________________________________
// Get parameters from V00DAEqualFactors.config file

  Int_t    kStartClock = 9;  // First clock in the search for max adc
  Int_t    kEndClock = 11;   // Last clock in the search for max adc
  Int_t    kNPreClocks = 6;  // Number of clock before max used in the charge sum
  Int_t    kNPostClocks = 1; // Number of clock after max used in the charge sum

  UChar_t  kNFlagsCut   = 63;// Minimum number of TDC flags requested, replaces the trigger selection

  Int_t    kNBins = 10000;
  Float_t  kRange = 0.1;

  status = daqDA_DB_getFile("V00DAEqualFactors.config","./V00DAEqualFactors.config");
  if (status) {
    printf("Failed to get Config file (V00DAEqualFactors.config) from DAQ DB, status=%d\n", status);
    printf("Take default values of parameters for pedestal calculation \n");
  } else {
    /* open the config file and retrieve cuts */
    FILE *fpConfig = fopen("V00DAEqualFactors.config","r");
    int res = fscanf(fpConfig,"%d %d %d %d %hhu %d %f",
		     &kStartClock,&kEndClock,&kNPreClocks,&kNPostClocks,&kNFlagsCut,&kNBins,&kRange);
    if(res!=7) {
      printf("Failed to get values from Config file (V00DAEqualFactors.config): wrong file format - 6 integers and 1 float are expected - \n");
    }
    fclose(fpConfig);
  }

  printf("First LHC Clock = %d; Last LHC Clock = %d; N Pre Clock = %d ; N Post Clock = %d; Minimum number of TDC flags = %hhu; Number of histogram bins = %d; Histogram range = %.3f\n",
	 kStartClock, kEndClock, kNPreClocks, kNPostClocks, kNFlagsCut, kNBins, kRange);

  TH1D *fMedian[64];
  for(Int_t j = 0; j < 64; ++j) fMedian[j] = new TH1D(Form("fMedian_%d",j),"Slopes weighted median, channel par channel",kNBins,0,kRange);

  Bool_t fFirst = kTRUE;
  Float_t fPrevTotCharge = 0;
  Float_t fPrevadc[64];
  for(Int_t j = 0; j < 64; ++j) fPrevadc[j] = 0;

//___________________________________________________

  /* define data source : this is argument 1 */
  status=monitorSetDataSource( argv[1] );
  if (status!=0) {
     printf("monitorSetDataSource() failed : %s\n",monitorDecodeError(status));
     return -1;
  }

  /* declare monitoring program */
  status=monitorDeclareMp( __FILE__ );
  if (status!=0) {
    printf("monitorDeclareMp() failed : %s\n",monitorDecodeError(status));
    return -1;
  }

  /* define wait event timeout - 1s max */
  monitorSetNowait();
  monitorSetNoWaitNetworkTimeout(1000);

  /* init counters on events */
  int neventsPhysics=0;
  int neventsTotal=0;

  /* loop on events (infinite) */
  for(;;) {
      struct eventHeaderStruct *event;
      eventTypeType eventT;

      /* check shutdown condition */
      if (daqDA_checkShutdown()) {break;}

      /* get next event (blocking call until timeout) */
      status=monitorGetEventDynamic((void **)&event);
      if (status==MON_ERR_EOF) {
          printf ("End of File detected\n");
      break; /* end of monitoring file has been reached */
      }

      if (status!=0) {
           printf("monitorGetEventDynamic() failed : %s\n",monitorDecodeError(status));
      break;
      }

      /* retry if got no event */
      if (event==NULL) continue;

      /* decode event */
      eventT=event->eventType;

      switch (event->eventType){

      case START_OF_RUN:
           break;

      case END_OF_RUN:
           printf("End Of Run detected\n");
           break;

      case PHYSICS_EVENT:

	   AliRawReader *rawReader = new AliRawReaderDate((void*)event);

	   AliVZERORawStream* rawStream  = new AliVZERORawStream(rawReader);
	   if (rawStream->Next()) {
	     UShort_t triggers = rawStream->GetTriggerInputs();
	     UChar_t nFlags = 0;
	     for(Int_t i = 0; i < 64; ++i) {
	       if (rawStream->GetBBFlag(i,10)) nFlags++;
	     }
	     if (nFlags >= kNFlagsCut) { // Check if the number of minimum number of TDC flags is reached (trigger selection)

	       neventsPhysics++;

	       Float_t adc[64];
	       Float_t totCharge = 0.;
	       for(Int_t i = 0; i < 64; ++i) {
		 adc[i] = 0.;
		 Float_t maxadc=0.;
		 Int_t imax=-1;
		 for(Int_t j = kStartClock; j <= kEndClock; ++j) {
		   Float_t charge = (Float_t)(rawStream->GetPedestal(i,j));
		   if(charge > maxadc){
		     maxadc = charge;
		     imax   = j;
		   }
		 }

		 if (imax != -1) {
		   Int_t start = imax - kNPreClocks;
		   if (start < 0) start = 0;
		   Int_t end = imax + kNPostClocks;
		   if (end > 20) end = 20;
		   for(Int_t iClock = start; iClock <= end; iClock++) {
		     adc[i] += (Float_t)(rawStream->GetPedestal(i,iClock));
		   }
		 }
		 totCharge += adc[i];
	       }

	       if (fFirst) {
		 fFirst = kFALSE;
		 fPrevTotCharge = totCharge;
		 for(int i = 0; i < 64; ++i) fPrevadc[i] = adc[i];
	       }
	       else {
		 fFirst = kTRUE;
		 Float_t deltaTotCharge = totCharge - fPrevTotCharge;
		 Float_t weight = deltaTotCharge*deltaTotCharge;
		 if (weight > 1) {
		   for(int i = 0; i < 64; ++i) {
		     fMedian[i]->Fill((adc[i]-fPrevadc[i])/deltaTotCharge,weight);
		   }
		 }
	       }

	     }
	   }   // End : if rawstream
           delete rawStream;
           rawStream = 0x0;
           delete rawReader;
           rawReader = 0x0;
      } // end of switch on event type

      neventsTotal++;
      /* free resources */
      free(event);

      /* exit when last event received, no need to wait for TERM signal */
      if (eventT==END_OF_RUN) {
	printf("End Of Run event detected\n");
	break;
      }

  }  // loop over events

  printf("%d physics events processed\n",neventsPhysics);

//___________________________________________________________________________
//  Computes regression parameters
// charge_i = p0 + charge_tot * p1

  if(neventsPhysics>2000){
    /* open result file to be exported to FES */
    FILE *fp=NULL;
    fp=fopen("./V0_EqualizationFactors.dat","w");
    if (fp==NULL) {
      printf("Failed to open local result file\n");
      return -1;}

    Double_t beta[64];
    Double_t q = 0.5;
    for(int i = 0; i < 64; ++i) fMedian[i]->GetQuantiles(1,&beta[i],&q);

    for(Int_t i=0; i<64; i++) {
      fprintf(fp," %d %.3f\n",GetOfflineChannel(i), beta[i]*64.);
      printf(" %d %.3f\n",GetOfflineChannel(i), beta[i]*64.);
    }

    /* close local result file and FXS result file*/
    fclose(fp);
  }

//________________________________________________________________________

  /* export result file to FES */
  status=daqDA_FES_storeFile("./V0_EqualizationFactors.dat","V00DAEqualFactors");
  if (status)    {
    printf("Failed to export file : %d\n",status);
    return -1; }

  /* store result file into Online DB */
  status=daqDA_DB_storeFile("./V0_EqualizationFactors.dat","V00DAEqualFactors");
  if (status)    {
    printf("Failed to store file into Online DB: %d\n",status);
    return -1; }

  return status;
}

 Int_t GetOfflineChannel(Int_t channel) {

// Channel mapping Online - Offline:

 Int_t fOfflineChannel[64] = {39, 38, 37, 36, 35, 34, 33, 32,
                              47, 46, 45, 44, 43, 42, 41, 40,
			      55, 54, 53, 52, 51, 50, 49, 48,
			      63, 62, 61, 60, 59, 58, 57, 56,
			       7,  6,  5,  4,  3,  2,  1,  0,
			      15, 14, 13, 12, 11, 10,  9,  8,
			      23, 22, 21, 20, 19, 18, 17, 16,
			      31, 30, 29, 28, 27, 26, 25, 24};
 return	fOfflineChannel[channel];
}
<|endoftext|>


<commit_before>/*
 * udev_unit.cpp
 *
 *  Created on: Feb 26, 2015
 *      Author: ddz
 */

#include "udev_unit.h"

#include <assert.h>

struct udev_device *find_device(struct udev *udev, const char *id)
{

        assert(udev);
        assert(id);

        if (startswith(id, "/dev/")) {
                struct stat statbuf;
                char type;

                if (stat(id, &statbuf) < 0)
                        return NULL;

                if (S_ISBLK(statbuf.st_mode))
                        type = 'b';
                else if (S_ISCHR(statbuf.st_mode))
                        type = 'c';
                else
                        return NULL;

                return udev_device_new_from_devnum(udev, type, statbuf.st_rdev);
        } else if (startswith(id, "/sys/"))
                return udev_device_new_from_syspath(udev, id);
        else
                return NULL;
}

//static void print_record(struct udev_device *device) {
//        const char *str;
//        int i;
//        struct udev_list_entry *list_entry;
//
//        printf("P: %s\n", udev_device_get_devpath(device));
//
//        str = udev_device_get_devnode(device);
//        if (str != NULL)
//                printf("N: %s\n", str + strlen("/dev/"));
//
//        i = udev_device_get_devlink_priority(device);
//        if (i != 0)
//                printf("L: %i\n", i);
//
//        udev_list_entry_foreach(list_entry, udev_device_get_devlinks_list_entry(device))
//                printf("S: %s\n", udev_list_entry_get_name(list_entry) + strlen("/dev/"));
//
//        udev_list_entry_foreach(list_entry, udev_device_get_properties_list_entry(device))
//                printf("E: %s=%s\n",
//                       udev_list_entry_get_name(list_entry),
//                       udev_list_entry_get_value(list_entry));
//        printf("\n");
//}

std::string getDeviceSerialNumber(const char *device)
{
	std::string output = "";

	struct udev *udev_obj;
	struct udev_device *udev_dev;

	udev_obj = udev_new();
	if(!udev_obj)
	{
		//printf("Can't create udev\n");
		return "";
	}

	udev_dev = find_device(udev_obj, device);

	if(!udev_dev)
	{
		//printf("Can't find udev device = %s\n", device);
		return "";
	}

	struct udev_list_entry *list_entry;

	udev_list_entry_foreach(list_entry, udev_device_get_properties_list_entry(udev_dev))
	{
		if(strncmp(udev_list_entry_get_name(list_entry), "ID_SERIAL_SHORT", strlen("ID_SERIAL_SHORT")) == 0)
		{
			output = udev_list_entry_get_value(list_entry);
			break;
		}
	}

	udev_device_unref(udev_dev);
	udev_unref(udev_obj);

	return output;
}
<commit_msg>Add missing header in udev_unit.cpp<commit_after>/*
 * udev_unit.cpp
 *
 *  Created on: Feb 26, 2015
 *      Author: ddz
 */

#include "udev_unit.h"

#include <assert.h>
#include <sys/stat.h>

struct udev_device *find_device(struct udev *udev, const char *id)
{

        assert(udev);
        assert(id);

        if (startswith(id, "/dev/")) {
                struct stat statbuf;
                char type;

                if (stat(id, &statbuf) < 0)
                        return NULL;

                if (S_ISBLK(statbuf.st_mode))
                        type = 'b';
                else if (S_ISCHR(statbuf.st_mode))
                        type = 'c';
                else
                        return NULL;

                return udev_device_new_from_devnum(udev, type, statbuf.st_rdev);
        } else if (startswith(id, "/sys/"))
                return udev_device_new_from_syspath(udev, id);
        else
                return NULL;
}

//static void print_record(struct udev_device *device) {
//        const char *str;
//        int i;
//        struct udev_list_entry *list_entry;
//
//        printf("P: %s\n", udev_device_get_devpath(device));
//
//        str = udev_device_get_devnode(device);
//        if (str != NULL)
//                printf("N: %s\n", str + strlen("/dev/"));
//
//        i = udev_device_get_devlink_priority(device);
//        if (i != 0)
//                printf("L: %i\n", i);
//
//        udev_list_entry_foreach(list_entry, udev_device_get_devlinks_list_entry(device))
//                printf("S: %s\n", udev_list_entry_get_name(list_entry) + strlen("/dev/"));
//
//        udev_list_entry_foreach(list_entry, udev_device_get_properties_list_entry(device))
//                printf("E: %s=%s\n",
//                       udev_list_entry_get_name(list_entry),
//                       udev_list_entry_get_value(list_entry));
//        printf("\n");
//}

std::string getDeviceSerialNumber(const char *device)
{
	std::string output = "";

	struct udev *udev_obj;
	struct udev_device *udev_dev;

	udev_obj = udev_new();
	if(!udev_obj)
	{
		//printf("Can't create udev\n");
		return "";
	}

	udev_dev = find_device(udev_obj, device);

	if(!udev_dev)
	{
		//printf("Can't find udev device = %s\n", device);
		return "";
	}

	struct udev_list_entry *list_entry;

	udev_list_entry_foreach(list_entry, udev_device_get_properties_list_entry(udev_dev))
	{
		if(strncmp(udev_list_entry_get_name(list_entry), "ID_SERIAL_SHORT", strlen("ID_SERIAL_SHORT")) == 0)
		{
			output = udev_list_entry_get_value(list_entry);
			break;
		}
	}

	udev_device_unref(udev_dev);
	udev_unref(udev_obj);

	return output;
}
<|endoftext|>


<commit_before>
#include <sstream>
#include <algorithm>

#include "src/database/database.h"

#include "mongo/client/dbclient.h"
#include "mongo/bson/bson.h"

#include "include/container/tokenizer.h"

using namespace std;
using namespace stoke;
using namespace x64asm;
using namespace mongo;
using namespace cpputil;

void Database::insert(x64asm::Code code, std::string tag) {

  stringstream code_ss;
  code_ss << code;

  string db = database_ + "." + tag;

  try {
    /* Either add this code to the database with
       count 1, or update the existing count */
    connection_.ensureIndex(db, fromjson("{code:1}"));
    connection_.update(db,
             BSON( "code" << code_ss.str() ),
             BSON( "$inc" << BSON( "count" << 1 ) ),
             true);

  } catch (const DBException &e) {
    cerr << "caught " << e.what() << endl;
  }

}

uint64_t Database::lookup(x64asm::Code code, string tag) {

  stringstream code_ss;
  code_ss << code;

  string db = database_ + "." + tag;

  try {
    /* Lookup the count corresponding to this
       code/tag pair */
    DBClientCursor *cursor =
      connection_.query(db, QUERY("code" << code_ss.str())).release();

    uint64_t sum = 0;
    while (cursor->more()) {
      BSONObj p = cursor->next();
      sum += p.getIntField("count");
    }

    return sum;

  } catch (const DBException &e) {
    cerr << "caught " << e.what() << endl;
    return 0;
  }

}

Database::Database(string hostname, uint16_t port, string database) {

  //TODO use the port :)
  connection_.connect(hostname);
  database_ = database;

  // Wipe out anything that's ready there
  connection_.eval(database, "db.dropDatabase();");

}
<commit_msg>fixed the huge memory leak<commit_after>
#include <sstream>
#include <algorithm>

#include "src/database/database.h"

#include "mongo/client/dbclient.h"
#include "mongo/bson/bson.h"

#include "include/container/tokenizer.h"

using namespace std;
using namespace stoke;
using namespace x64asm;
using namespace mongo;
using namespace cpputil;

void Database::insert(x64asm::Code code, std::string tag) {

  stringstream code_ss;
  code_ss << code;

  stringstream db_ss;
  db_ss << database_ << "." << tag;
  string db = db_ss.str();

  try {
    /* Either add this code to the database with
       count 1, or update the existing count */
    connection_.ensureIndex(db, fromjson("{code:1}"));
    connection_.update(db,
             BSON( "code" << code_ss.str() ),
             BSON( "$inc" << BSON( "count" << 1 ) ),
             true);

  } catch (const DBException &e) {
    cerr << "caught " << e.what() << endl;
  }

}

uint64_t Database::lookup(x64asm::Code code, string tag) {

  stringstream code_ss;
  code_ss << code;

  stringstream db_ss;
  db_ss << database_ << "." << tag;
  string db = db_ss.str();

  try {
    /* Lookup the count corresponding to this
       code/tag pair */
    DBClientCursor *cursor =
      connection_.query(db, QUERY("code" << code_ss.str())).release();

    uint64_t sum = 0;
    while (cursor->more()) {
      BSONObj p = cursor->next();
      sum += p.getIntField("count");
    }

    delete cursor;

    return sum;

  } catch (const DBException &e) {
    cerr << "caught " << e.what() << endl;
    return 0;
  }

}

Database::Database(string hostname, uint16_t port, string database) {

  //TODO use the port :)
  connection_.connect(hostname);
  database_ = database;

  // Wipe out anything that's ready there
  connection_.eval(database, "db.dropDatabase();");

}
<|endoftext|>