<commit_before>/**
 * @file llchatitemscontainer.cpp
 * @brief chat history scrolling panel implementation
 *
 * $LicenseInfo:firstyear=2009&license=viewerlgpl$
 * Second Life Viewer Source Code
 * Copyright (C) 2010, Linden Research, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation;
 * version 2.1 of the License only.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 * $/LicenseInfo$
 */

#include "llviewerprecompiledheaders.h"

#include "llchatitemscontainerctrl.h"
#include "lltextbox.h"

#include "llchatmsgbox.h"
#include "llavatariconctrl.h"
#include "llcommandhandler.h"
#include "llfloaterreg.h"
#include "lllocalcliprect.h"
#include "lltrans.h"
#include "llfloaterimnearbychat.h"

#include "llviewercontrol.h"
#include "llagentdata.h"

#include "llslurl.h"

static const S32 msg_left_offset = 10;
static const S32 msg_right_offset = 10;
static const S32 msg_height_pad = 5;

//*******************************************************************************************************************
// LLObjectHandler
//*******************************************************************************************************************

// handle secondlife:///app/object/<ID>/inspect SLURLs
class LLObjectHandler : public LLCommandHandler
{
public:
	LLObjectHandler() : LLCommandHandler("object", UNTRUSTED_BLOCK) { }

	bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web)
	{
		if (params.size() < 2) return false;

		LLUUID object_id;
		if (!object_id.set(params[0], FALSE))
		{
			return false;
		}

		const std::string verb = params[1].asString();

		if (verb == "inspect")
		{
			LLFloaterReg::showInstance("inspect_object", LLSD().with("object_id", object_id));
			return true;
		}

		return false;
	}
};

LLObjectHandler gObjectHandler;

//*******************************************************************************************************************
//LLFloaterIMNearbyChatToastPanel
//*******************************************************************************************************************

LLFloaterIMNearbyChatToastPanel* LLFloaterIMNearbyChatToastPanel::createInstance()
{
	LLFloaterIMNearbyChatToastPanel* item = new LLFloaterIMNearbyChatToastPanel();
	item->buildFromFile("panel_chat_item.xml");
	item->setFollows(FOLLOWS_NONE);
	return item;
}

void	LLFloaterIMNearbyChatToastPanel::reshape		(S32 width, S32 height, BOOL called_from_parent )
{
	LLPanel::reshape(width, height,called_from_parent);

	// reshape() may be called from LLView::initFromParams() before the children are created.
	// We call findChild() instead of getChild() here to avoid creating dummy controls.
	LLUICtrl* msg_text = findChild<LLUICtrl>("msg_text", false);
	LLUICtrl* icon = findChild<LLUICtrl>("avatar_icon", false);

	if (!msg_text || !icon)
	{
		return;
	}

	LLRect msg_text_rect = msg_text->getRect();
	LLRect avatar_rect = icon->getRect();

	avatar_rect.setLeftTopAndSize(2,height-2,avatar_rect.getWidth(),avatar_rect.getHeight());
	icon->setRect(avatar_rect);

	msg_text_rect.setLeftTopAndSize( avatar_rect.mRight + msg_left_offset,
		height - msg_height_pad,
		width - avatar_rect.mRight  - msg_left_offset - msg_right_offset,
		height - 2*msg_height_pad);
	msg_text->reshape( msg_text_rect.getWidth(), msg_text_rect.getHeight(), 1);
	msg_text->setRect(msg_text_rect);
}

BOOL LLFloaterIMNearbyChatToastPanel::postBuild()
{
	return LLPanel::postBuild();
}

void LLFloaterIMNearbyChatToastPanel::addMessage(LLSD& notification)
{
	std::string		messageText = notification["message"].asString();		// UTF-8 line of text

	LLChatMsgBox* msg_text = getChild<LLChatMsgBox>("msg_text", false);

	std::string color_name = notification["text_color"].asString();

	LLColor4 textColor = LLUIColorTable::instance().getColor(color_name);
	textColor.mV[VALPHA] =notification["color_alpha"].asReal();

	S32 font_size = notification["font_size"].asInteger();

	LLFontGL*       messageFont;
	switch(font_size)
	{
		case 0:	messageFont = LLFontGL::getFontSansSerifSmall(); break;
		default:
		case 1: messageFont = LLFontGL::getFontSansSerif();	    break;
		case 2:	messageFont = LLFontGL::getFontSansSerifBig();	break;
	}

	//append text
	{
		LLStyle::Params style_params;
		style_params.color(textColor);
		std::string font_name = LLFontGL::nameFromFont(messageFont);
		std::string font_style_size = LLFontGL::sizeFromFont(messageFont);
		style_params.font.name(font_name);
		style_params.font.size(font_style_size);

		int chat_type = notification["chat_type"].asInteger();

		if(notification["chat_style"].asInteger()== CHAT_STYLE_IRC)
		{
			style_params.font.style = "ITALIC";
		}
		else if( chat_type == CHAT_TYPE_SHOUT)
		{
			style_params.font.style = "BOLD";
		}
		else if( chat_type == CHAT_TYPE_WHISPER)
		{
			style_params.font.style = "ITALIC";
		}
		msg_text->appendText(messageText, TRUE, style_params);
	}

	snapToMessageHeight();

}

void LLFloaterIMNearbyChatToastPanel::init(LLSD& notification)
{
	std::string		messageText = notification["message"].asString();		// UTF-8 line of text
	std::string		fromName = notification["from"].asString();	// agent or object name
	mFromID = notification["from_id"].asUUID();		// agent id or object id
	mFromName = fromName;

	int sType = notification["source"].asInteger();
    mSourceType = (EChatSourceType)sType;

	std::string color_name = notification["text_color"].asString();

	LLColor4 textColor = LLUIColorTable::instance().getColor(color_name);
	textColor.mV[VALPHA] =notification["color_alpha"].asReal();

	S32 font_size = notification["font_size"].asInteger();

	LLFontGL*       messageFont;
	switch(font_size)
	{
		case 0:	messageFont = LLFontGL::getFontSansSerifSmall(); break;
		default:
		case 1: messageFont = LLFontGL::getFontSansSerif();	    break;
		case 2:	messageFont = LLFontGL::getFontSansSerifBig();	break;
	}

	LLChatMsgBox* msg_text = getChild<LLChatMsgBox>("msg_text", false);

	msg_text->setText(std::string(""));

	if ( notification["chat_style"].asInteger() != CHAT_STYLE_IRC )
	{
		std::string str_sender;

		str_sender = fromName;

		str_sender+=" ";

		//append sender name
		if (mSourceType == CHAT_SOURCE_AGENT || mSourceType == CHAT_SOURCE_OBJECT)
		{
			LLStyle::Params style_params_name;

			LLColor4 user_name_color = LLUIColorTable::instance().getColor("HTMLLinkColor");
			style_params_name.color(user_name_color);

			std::string font_name = LLFontGL::nameFromFont(messageFont);
			std::string font_style_size = LLFontGL::sizeFromFont(messageFont);
			style_params_name.font.name(font_name);
			style_params_name.font.size(font_style_size);

			style_params_name.link_href = notification["sender_slurl"].asString();
			style_params_name.is_link = true;

			msg_text->appendText(str_sender, FALSE, style_params_name);

		}
		else
		{
			msg_text->appendText(str_sender, false);
		}
	}

	//append text
	{
		LLStyle::Params style_params;
		style_params.color(textColor);
		std::string font_name = LLFontGL::nameFromFont(messageFont);
		std::string font_style_size = LLFontGL::sizeFromFont(messageFont);
		style_params.font.name(font_name);
		style_params.font.size(font_style_size);

		int chat_type = notification["chat_type"].asInteger();

		if(notification["chat_style"].asInteger()== CHAT_STYLE_IRC)
		{
			style_params.font.style = "ITALIC";
		}
		else if( chat_type == CHAT_TYPE_SHOUT)
		{
			style_params.font.style = "BOLD";
		}
		else if( chat_type == CHAT_TYPE_WHISPER)
		{
			style_params.font.style = "ITALIC";
		}
		msg_text->appendText(messageText, FALSE, style_params);
	}

	snapToMessageHeight();

	mIsDirty = true;//will set Avatar Icon in draw
}

void	LLFloaterIMNearbyChatToastPanel::snapToMessageHeight	()
{
	LLChatMsgBox* text_box = getChild<LLChatMsgBox>("msg_text", false);
	S32 new_height = llmax (text_box->getTextPixelHeight() + 2*text_box->getVPad() + 2*msg_height_pad, 25);

	LLRect panel_rect = getRect();

	panel_rect.setLeftTopAndSize( panel_rect.mLeft, panel_rect.mTop, panel_rect.getWidth(), new_height);

	reshape( getRect().getWidth(), getRect().getHeight(), 1);

	setRect(panel_rect);

}

void LLFloaterIMNearbyChatToastPanel::onMouseLeave			(S32 x, S32 y, MASK mask)
{

}
void LLFloaterIMNearbyChatToastPanel::onMouseEnter				(S32 x, S32 y, MASK mask)
{
	if(mSourceType != CHAT_SOURCE_AGENT)
		return;
}

BOOL	LLFloaterIMNearbyChatToastPanel::handleMouseDown	(S32 x, S32 y, MASK mask)
{
	return LLPanel::handleMouseDown(x,y,mask);
}

BOOL	LLFloaterIMNearbyChatToastPanel::handleMouseUp	(S32 x, S32 y, MASK mask)
{
	/*
	fix for request  EXT-4780
	leaving this commented since I don't remember why ew block those messages...
	if(mSourceType != CHAT_SOURCE_AGENT)
		return LLPanel::handleMouseUp(x,y,mask);
    */

	LLChatMsgBox* text_box = getChild<LLChatMsgBox>("msg_text", false);
	S32 local_x = x - text_box->getRect().mLeft;
	S32 local_y = y - text_box->getRect().mBottom;

	//if text_box process mouse up (ussually this is click on url) - we didn't show nearby_chat.
	if (text_box->pointInView(local_x, local_y) )
	{
		if (text_box->handleMouseUp(local_x,local_y,mask) == TRUE)
			return TRUE;
		else
		{
			(LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat"))->showHistory();
			return FALSE;
		}
	}

	(LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat"))->showHistory();
	return LLPanel::handleMouseUp(x,y,mask);
}

void	LLFloaterIMNearbyChatToastPanel::setHeaderVisibility(EShowItemHeader e)
{
	LLUICtrl* icon = getChild<LLUICtrl>("avatar_icon", false);
	if(icon)
		icon->setVisible(e == CHATITEMHEADER_SHOW_ONLY_ICON || e==CHATITEMHEADER_SHOW_BOTH);

}

bool	LLFloaterIMNearbyChatToastPanel::canAddText	()
{
	LLChatMsgBox* msg_text = findChild<LLChatMsgBox>("msg_text");
	if(!msg_text)
		return false;
	return msg_text->getLineCount()<10;
}

BOOL	LLFloaterIMNearbyChatToastPanel::handleRightMouseDown(S32 x, S32 y, MASK mask)
{
	LLUICtrl* avatar_icon = getChild<LLUICtrl>("avatar_icon", false);

	S32 local_x = x - avatar_icon->getRect().mLeft;
	S32 local_y = y - avatar_icon->getRect().mBottom;

	//eat message for avatar icon if msg was from object
	if(avatar_icon->pointInView(local_x, local_y) && mSourceType != CHAT_SOURCE_AGENT)
		return TRUE;
	return LLPanel::handleRightMouseDown(x,y,mask);
}
void LLFloaterIMNearbyChatToastPanel::draw()
{
	LLPanel::draw();

	if(mIsDirty)
	{
		LLAvatarIconCtrl* icon = getChild<LLAvatarIconCtrl>("avatar_icon", false);
		if(icon)
		{
			icon->setDrawTooltip(mSourceType == CHAT_SOURCE_AGENT);
			if(mSourceType == CHAT_SOURCE_OBJECT)
				icon->setValue(LLSD("OBJECT_Icon"));
			else if(mSourceType == CHAT_SOURCE_SYSTEM)
				icon->setValue(LLSD("SL_Logo"));
			else if(mSourceType == CHAT_SOURCE_AGENT)
				icon->setValue(mFromID);
			else if(!mFromID.isNull())
				icon->setValue(mFromID);
		}
		mIsDirty = false;
	}
}

<commit_msg>CHUI-976 FIXED Correct way to show Nearby chat is used now.<commit_after>/**
 * @file llchatitemscontainer.cpp
 * @brief chat history scrolling panel implementation
 *
 * $LicenseInfo:firstyear=2009&license=viewerlgpl$
 * Second Life Viewer Source Code
 * Copyright (C) 2010, Linden Research, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation;
 * version 2.1 of the License only.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 * $/LicenseInfo$
 */

#include "llviewerprecompiledheaders.h"

#include "llchatitemscontainerctrl.h"
#include "lltextbox.h"

#include "llchatmsgbox.h"
#include "llavatariconctrl.h"
#include "llcommandhandler.h"
#include "llfloaterreg.h"
#include "lllocalcliprect.h"
#include "lltrans.h"
#include "llfloaterimnearbychat.h"

#include "llviewercontrol.h"
#include "llagentdata.h"

#include "llslurl.h"

static const S32 msg_left_offset = 10;
static const S32 msg_right_offset = 10;
static const S32 msg_height_pad = 5;

//*******************************************************************************************************************
// LLObjectHandler
//*******************************************************************************************************************

// handle secondlife:///app/object/<ID>/inspect SLURLs
class LLObjectHandler : public LLCommandHandler
{
public:
	LLObjectHandler() : LLCommandHandler("object", UNTRUSTED_BLOCK) { }

	bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web)
	{
		if (params.size() < 2) return false;

		LLUUID object_id;
		if (!object_id.set(params[0], FALSE))
		{
			return false;
		}

		const std::string verb = params[1].asString();

		if (verb == "inspect")
		{
			LLFloaterReg::showInstance("inspect_object", LLSD().with("object_id", object_id));
			return true;
		}

		return false;
	}
};

LLObjectHandler gObjectHandler;

//*******************************************************************************************************************
//LLFloaterIMNearbyChatToastPanel
//*******************************************************************************************************************

LLFloaterIMNearbyChatToastPanel* LLFloaterIMNearbyChatToastPanel::createInstance()
{
	LLFloaterIMNearbyChatToastPanel* item = new LLFloaterIMNearbyChatToastPanel();
	item->buildFromFile("panel_chat_item.xml");
	item->setFollows(FOLLOWS_NONE);
	return item;
}

void	LLFloaterIMNearbyChatToastPanel::reshape		(S32 width, S32 height, BOOL called_from_parent )
{
	LLPanel::reshape(width, height,called_from_parent);

	// reshape() may be called from LLView::initFromParams() before the children are created.
	// We call findChild() instead of getChild() here to avoid creating dummy controls.
	LLUICtrl* msg_text = findChild<LLUICtrl>("msg_text", false);
	LLUICtrl* icon = findChild<LLUICtrl>("avatar_icon", false);

	if (!msg_text || !icon)
	{
		return;
	}

	LLRect msg_text_rect = msg_text->getRect();
	LLRect avatar_rect = icon->getRect();

	avatar_rect.setLeftTopAndSize(2,height-2,avatar_rect.getWidth(),avatar_rect.getHeight());
	icon->setRect(avatar_rect);

	msg_text_rect.setLeftTopAndSize( avatar_rect.mRight + msg_left_offset,
		height - msg_height_pad,
		width - avatar_rect.mRight  - msg_left_offset - msg_right_offset,
		height - 2*msg_height_pad);
	msg_text->reshape( msg_text_rect.getWidth(), msg_text_rect.getHeight(), 1);
	msg_text->setRect(msg_text_rect);
}

BOOL LLFloaterIMNearbyChatToastPanel::postBuild()
{
	return LLPanel::postBuild();
}

void LLFloaterIMNearbyChatToastPanel::addMessage(LLSD& notification)
{
	std::string		messageText = notification["message"].asString();		// UTF-8 line of text

	LLChatMsgBox* msg_text = getChild<LLChatMsgBox>("msg_text", false);

	std::string color_name = notification["text_color"].asString();

	LLColor4 textColor = LLUIColorTable::instance().getColor(color_name);
	textColor.mV[VALPHA] =notification["color_alpha"].asReal();

	S32 font_size = notification["font_size"].asInteger();

	LLFontGL*       messageFont;
	switch(font_size)
	{
		case 0:	messageFont = LLFontGL::getFontSansSerifSmall(); break;
		default:
		case 1: messageFont = LLFontGL::getFontSansSerif();	    break;
		case 2:	messageFont = LLFontGL::getFontSansSerifBig();	break;
	}

	//append text
	{
		LLStyle::Params style_params;
		style_params.color(textColor);
		std::string font_name = LLFontGL::nameFromFont(messageFont);
		std::string font_style_size = LLFontGL::sizeFromFont(messageFont);
		style_params.font.name(font_name);
		style_params.font.size(font_style_size);

		int chat_type = notification["chat_type"].asInteger();

		if(notification["chat_style"].asInteger()== CHAT_STYLE_IRC)
		{
			style_params.font.style = "ITALIC";
		}
		else if( chat_type == CHAT_TYPE_SHOUT)
		{
			style_params.font.style = "BOLD";
		}
		else if( chat_type == CHAT_TYPE_WHISPER)
		{
			style_params.font.style = "ITALIC";
		}
		msg_text->appendText(messageText, TRUE, style_params);
	}

	snapToMessageHeight();

}

void LLFloaterIMNearbyChatToastPanel::init(LLSD& notification)
{
	std::string		messageText = notification["message"].asString();		// UTF-8 line of text
	std::string		fromName = notification["from"].asString();	// agent or object name
	mFromID = notification["from_id"].asUUID();		// agent id or object id
	mFromName = fromName;

	int sType = notification["source"].asInteger();
    mSourceType = (EChatSourceType)sType;

	std::string color_name = notification["text_color"].asString();

	LLColor4 textColor = LLUIColorTable::instance().getColor(color_name);
	textColor.mV[VALPHA] =notification["color_alpha"].asReal();

	S32 font_size = notification["font_size"].asInteger();

	LLFontGL*       messageFont;
	switch(font_size)
	{
		case 0:	messageFont = LLFontGL::getFontSansSerifSmall(); break;
		default:
		case 1: messageFont = LLFontGL::getFontSansSerif();	    break;
		case 2:	messageFont = LLFontGL::getFontSansSerifBig();	break;
	}

	LLChatMsgBox* msg_text = getChild<LLChatMsgBox>("msg_text", false);

	msg_text->setText(std::string(""));

	if ( notification["chat_style"].asInteger() != CHAT_STYLE_IRC )
	{
		std::string str_sender;

		str_sender = fromName;

		str_sender+=" ";

		//append sender name
		if (mSourceType == CHAT_SOURCE_AGENT || mSourceType == CHAT_SOURCE_OBJECT)
		{
			LLStyle::Params style_params_name;

			LLColor4 user_name_color = LLUIColorTable::instance().getColor("HTMLLinkColor");
			style_params_name.color(user_name_color);

			std::string font_name = LLFontGL::nameFromFont(messageFont);
			std::string font_style_size = LLFontGL::sizeFromFont(messageFont);
			style_params_name.font.name(font_name);
			style_params_name.font.size(font_style_size);

			style_params_name.link_href = notification["sender_slurl"].asString();
			style_params_name.is_link = true;

			msg_text->appendText(str_sender, FALSE, style_params_name);

		}
		else
		{
			msg_text->appendText(str_sender, false);
		}
	}

	//append text
	{
		LLStyle::Params style_params;
		style_params.color(textColor);
		std::string font_name = LLFontGL::nameFromFont(messageFont);
		std::string font_style_size = LLFontGL::sizeFromFont(messageFont);
		style_params.font.name(font_name);
		style_params.font.size(font_style_size);

		int chat_type = notification["chat_type"].asInteger();

		if(notification["chat_style"].asInteger()== CHAT_STYLE_IRC)
		{
			style_params.font.style = "ITALIC";
		}
		else if( chat_type == CHAT_TYPE_SHOUT)
		{
			style_params.font.style = "BOLD";
		}
		else if( chat_type == CHAT_TYPE_WHISPER)
		{
			style_params.font.style = "ITALIC";
		}
		msg_text->appendText(messageText, FALSE, style_params);
	}

	snapToMessageHeight();

	mIsDirty = true;//will set Avatar Icon in draw
}

void	LLFloaterIMNearbyChatToastPanel::snapToMessageHeight	()
{
	LLChatMsgBox* text_box = getChild<LLChatMsgBox>("msg_text", false);
	S32 new_height = llmax (text_box->getTextPixelHeight() + 2*text_box->getVPad() + 2*msg_height_pad, 25);

	LLRect panel_rect = getRect();

	panel_rect.setLeftTopAndSize( panel_rect.mLeft, panel_rect.mTop, panel_rect.getWidth(), new_height);

	reshape( getRect().getWidth(), getRect().getHeight(), 1);

	setRect(panel_rect);

}

void LLFloaterIMNearbyChatToastPanel::onMouseLeave			(S32 x, S32 y, MASK mask)
{

}
void LLFloaterIMNearbyChatToastPanel::onMouseEnter				(S32 x, S32 y, MASK mask)
{
	if(mSourceType != CHAT_SOURCE_AGENT)
		return;
}

BOOL	LLFloaterIMNearbyChatToastPanel::handleMouseDown	(S32 x, S32 y, MASK mask)
{
	return LLPanel::handleMouseDown(x,y,mask);
}

BOOL	LLFloaterIMNearbyChatToastPanel::handleMouseUp	(S32 x, S32 y, MASK mask)
{
	/*
	fix for request  EXT-4780
	leaving this commented since I don't remember why ew block those messages...
	if(mSourceType != CHAT_SOURCE_AGENT)
		return LLPanel::handleMouseUp(x,y,mask);
    */

	LLChatMsgBox* text_box = getChild<LLChatMsgBox>("msg_text", false);
	S32 local_x = x - text_box->getRect().mLeft;
	S32 local_y = y - text_box->getRect().mBottom;

	//if text_box process mouse up (ussually this is click on url) - we didn't show nearby_chat.
	if (text_box->pointInView(local_x, local_y) )
	{
		if (text_box->handleMouseUp(local_x,local_y,mask) == TRUE)
			return TRUE;
		else
		{
			LLFloaterReg::toggleInstanceOrBringToFront("nearby_chat");
			return FALSE;
		}
	}

	LLFloaterReg::toggleInstanceOrBringToFront("nearby_chat");
	return LLPanel::handleMouseUp(x,y,mask);
}

void	LLFloaterIMNearbyChatToastPanel::setHeaderVisibility(EShowItemHeader e)
{
	LLUICtrl* icon = getChild<LLUICtrl>("avatar_icon", false);
	if(icon)
		icon->setVisible(e == CHATITEMHEADER_SHOW_ONLY_ICON || e==CHATITEMHEADER_SHOW_BOTH);

}

bool	LLFloaterIMNearbyChatToastPanel::canAddText	()
{
	LLChatMsgBox* msg_text = findChild<LLChatMsgBox>("msg_text");
	if(!msg_text)
		return false;
	return msg_text->getLineCount()<10;
}

BOOL	LLFloaterIMNearbyChatToastPanel::handleRightMouseDown(S32 x, S32 y, MASK mask)
{
	LLUICtrl* avatar_icon = getChild<LLUICtrl>("avatar_icon", false);

	S32 local_x = x - avatar_icon->getRect().mLeft;
	S32 local_y = y - avatar_icon->getRect().mBottom;

	//eat message for avatar icon if msg was from object
	if(avatar_icon->pointInView(local_x, local_y) && mSourceType != CHAT_SOURCE_AGENT)
		return TRUE;
	return LLPanel::handleRightMouseDown(x,y,mask);
}
void LLFloaterIMNearbyChatToastPanel::draw()
{
	LLPanel::draw();

	if(mIsDirty)
	{
		LLAvatarIconCtrl* icon = getChild<LLAvatarIconCtrl>("avatar_icon", false);
		if(icon)
		{
			icon->setDrawTooltip(mSourceType == CHAT_SOURCE_AGENT);
			if(mSourceType == CHAT_SOURCE_OBJECT)
				icon->setValue(LLSD("OBJECT_Icon"));
			else if(mSourceType == CHAT_SOURCE_SYSTEM)
				icon->setValue(LLSD("SL_Logo"));
			else if(mSourceType == CHAT_SOURCE_AGENT)
				icon->setValue(mFromID);
			else if(!mFromID.isNull())
				icon->setValue(mFromID);
		}
		mIsDirty = false;
	}
}

<|endoftext|>


<commit_before>#include <cmath>
#include <iostream>
#include <ale_interface.hpp>
#include <glog/logging.h>
#include <gflags/gflags.h>
#include "prettyprint.hpp"
#include "dqn.hpp"

DEFINE_bool(gpu, true, "Use GPU to brew Caffe");
DEFINE_bool(gui, false, "Open a GUI window");
DEFINE_string(rom, "roms/pong.bin", "Atari 2600 ROM to play");
DEFINE_int32(memory, 400000, "Capacity of replay memory");
DEFINE_int32(explore, 1000000, "Number of iterations needed for epsilon to reach given value.");
DEFINE_double(epsilon, 0.05, "Value of epsilon reached after explore iterations.");
DEFINE_double(gamma, 0.95, "Discount factor of future rewards (0,1]");
DEFINE_int32(memory_threshold, 100, "Enough amount of transitions to start learning");
DEFINE_int32(skip_frame, 3, "Number of frames skipped");
DEFINE_bool(show_frame, false, "Show the current frame in CUI");
DEFINE_string(save_screen, "", "File prefix in to save frames");
DEFINE_string(save_binary_screen, "", "File prefix in to save binary frames");
DEFINE_string(weights, "", "The pretrained weights load (*.caffemodel).");
DEFINE_string(snapshot, "", "The solver state to load (*.solverstate).");
DEFINE_bool(evaluate, false, "Evaluation mode: only playing a game, no updates");
DEFINE_double(evaluate_with_epsilon, 0.05, "Epsilon value to be used in evaluation mode");
DEFINE_double(repeat_games, 10, "Number of games played in evaluation mode");
// Solver Parameters
DEFINE_string(solver, "", "Solver parameter file (*.prototxt)");
DEFINE_string(model, "dqn.prototxt", "The model definition (*.prototxt).");
DEFINE_double(momentum, 0.95, "Solver momentum");
DEFINE_double(base_lr, 0.1, "Solver base learning rate");
DEFINE_string(lr_policy, "step", "Solver lr policy");
DEFINE_double(solver_gamma, 0.1, "Solver gamma");
DEFINE_int32(stepsize, 10000000, "Solver stepsize");
DEFINE_int32(max_iter, 10000000, "Maximum number of iterations");
DEFINE_int32(snapshot_frequency, 1000000, "Snapshot frequency in iterations");
DEFINE_int32(display, 10000, "Display frequency in iterations");
DEFINE_string(snapshot_prefix, "state/dqn", "Prefix for saving snapshots");

double CalculateEpsilon(const int iter) {
  if (iter < FLAGS_explore) {
    return 1.0 - (1.0 - FLAGS_epsilon) * (static_cast<double>(iter) / FLAGS_explore);
  } else {
    return FLAGS_epsilon;
  }
}

void SaveScreen(const ALEScreen& screen, const ALEInterface& ale,
                const string filename) {
  IntMatrix screen_matrix;
  for (auto row = 0; row < screen.height(); row++) {
    IntVect row_vec;
    for (auto col = 0; col < screen.width(); col++) {
      int pixel = screen.get(row, col);
      row_vec.emplace_back(pixel);
    }
    screen_matrix.emplace_back(row_vec);
  }
  ale.theOSystem->p_export_screen->save_png(&screen_matrix, filename);
}

void SaveInputFrames(const dqn::InputFrames& frames, const string filename) {
  std::ofstream ofs;
  ofs.open(filename, ios::out | ios::binary);
  for (int i = 0; i < dqn::kInputFrameCount; ++i) {
    const dqn::FrameData& frame = *frames[i];
    for (int j = 0; j < dqn::kCroppedFrameDataSize; ++j) {
      ofs.write((char*) &frame[j], sizeof(uint8_t));
    }
  }
  ofs.close();
}

/**
 * Play one episode and return the total score
 */
double PlayOneEpisode(ALEInterface& ale, dqn::DQN& dqn, const double epsilon,
                      const bool update) {
  CHECK(!ale.game_over());
  std::deque<dqn::FrameDataSp> past_frames;
  auto total_score = 0.0;
  for (auto frame = 0; !ale.game_over(); ++frame) {
    const ALEScreen& screen = ale.getScreen();
    const auto current_frame = dqn::PreprocessScreen(screen);
    if (FLAGS_show_frame) {
      std::cout << dqn::DrawFrame(*current_frame) << std::endl;
    }
    if (!FLAGS_save_screen.empty()) {
      std::stringstream ss;
      ss << FLAGS_save_screen << setfill('0') << setw(5) <<
          std::to_string(frame) << ".png";
      SaveScreen(screen, ale, ss.str());
    }
    past_frames.push_back(current_frame);
    if (past_frames.size() < dqn::kInputFrameCount) {
      // If there are not past frames enough for DQN input, just select NOOP
      for (auto i = 0; i < FLAGS_skip_frame + 1 && !ale.game_over(); ++i) {
        total_score += ale.act(PLAYER_A_NOOP);
      }
    } else {
      while (past_frames.size() > dqn::kInputFrameCount) {
        past_frames.pop_front();
      }
      dqn::InputFrames input_frames;
      std::copy(past_frames.begin(), past_frames.end(), input_frames.begin());
      if (!FLAGS_save_binary_screen.empty()) {
        static int binary_save_num = 0;
        string fname = FLAGS_save_binary_screen +
            std::to_string(binary_save_num++) + ".bin";
        SaveInputFrames(input_frames, fname);
      }
      const auto action = dqn.SelectAction(input_frames, epsilon);
      auto immediate_score = 0.0;
      for (auto i = 0; i < FLAGS_skip_frame + 1 && !ale.game_over(); ++i) {
        // Last action is repeated on skipped frames
        immediate_score += ale.act(action);
      }
      total_score += immediate_score;
      // Rewards for DQN are normalized as follows:
      // 1 for any positive score, -1 for any negative score, otherwise 0
      const auto reward =
          immediate_score == 0 ?
              0 :
              immediate_score /= std::abs(immediate_score);
      if (update) {
        // Add the current transition to replay memory
        const auto transition = ale.game_over() ?
            dqn::Transition(input_frames, action, reward, boost::none) :
            dqn::Transition(
                input_frames,
                action,
                reward,
                dqn::PreprocessScreen(ale.getScreen()));
        dqn.AddTransition(transition);
        // If the size of replay memory is enough, update DQN
        if (dqn.memory_size() > FLAGS_memory_threshold) {
          dqn.Update();
        }
      }
    }
  }
  ale.reset_game();
  return total_score;
}

/**
 * Evaluate the current player
 */
void Evaluate(ALEInterface& ale, dqn::DQN& dqn) {
  auto total_score = 0.0;
  std::stringstream ss;
  for (auto i = 0; i < FLAGS_repeat_games; ++i) {
    const auto score =
        PlayOneEpisode(ale, dqn, FLAGS_evaluate_with_epsilon, false);
    ss << score << " ";
    total_score += score;
  }
  LOG(INFO) << "Evaluation scores: " << ss.str();
  LOG(INFO) << "Average score: " <<
      total_score / static_cast<double>(FLAGS_repeat_games) << std::endl;
}

int main(int argc, char** argv) {
  gflags::ParseCommandLineFlags(&argc, &argv, true);
  google::InitGoogleLogging(argv[0]);
  google::InstallFailureSignalHandler();
  google::LogToStderr();

  if (FLAGS_gpu) {
    caffe::Caffe::set_mode(caffe::Caffe::GPU);
  } else {
    caffe::Caffe::set_mode(caffe::Caffe::CPU);
  }

  ALEInterface ale;
  ale.set("display_screen", FLAGS_gui);
  ale.set("disable_color_averaging", true);

  // Load the ROM file
  ale.loadROM(FLAGS_rom);

  // Get the vector of legal actions
  const auto legal_actions = ale.getMinimalActionSet();

  CHECK(FLAGS_snapshot.empty() || FLAGS_weights.empty())
      << "Give a snapshot to resume training or weights to finetune "
      "but not both.";

  // Construct the solver either from file or params
  caffe::SolverParameter solver_param;
  if (!FLAGS_solver.empty()) {
    LOG(INFO) << "Reading solver prototxt from " << FLAGS_solver;
    caffe::ReadProtoFromTextFileOrDie(FLAGS_solver, &solver_param);
  } else {
    LOG(INFO) << "Creating solver from scratch.";
    solver_param.set_net(FLAGS_model);
    solver_param.set_solver_type(::caffe::SolverParameter_SolverType::
                                 SolverParameter_SolverType_ADADELTA);
    solver_param.set_momentum(FLAGS_momentum);
    solver_param.set_base_lr(FLAGS_base_lr);
    solver_param.set_lr_policy(FLAGS_lr_policy);
    solver_param.set_gamma(FLAGS_solver_gamma);
    solver_param.set_stepsize(FLAGS_stepsize);
    solver_param.set_max_iter(FLAGS_max_iter);
    solver_param.set_display(FLAGS_display);
    solver_param.set_snapshot(FLAGS_snapshot_frequency);
    solver_param.set_snapshot_prefix(FLAGS_snapshot_prefix);
  }

  dqn::DQN dqn(legal_actions, solver_param, FLAGS_memory, FLAGS_gamma);
  dqn.Initialize();

  if (!FLAGS_save_screen.empty()) {
    LOG(INFO) << "Saving screens to: " << FLAGS_save_screen;
  }

  if (!FLAGS_snapshot.empty()) {
    LOG(INFO) << "Resuming from " << FLAGS_snapshot;
    dqn.RestoreSolver(FLAGS_snapshot);
  } else if (!FLAGS_weights.empty()) {
    LOG(INFO) << "Finetuning from " << FLAGS_weights;
    dqn.LoadTrainedModel(FLAGS_weights);
  }

  if (FLAGS_evaluate) {
    Evaluate(ale, dqn);
    return 0;
  }

  auto episode = 0;
  while (dqn.current_iteration() < solver_param.max_iter()) {
    const auto epsilon = CalculateEpsilon(dqn.current_iteration());
    const auto score = PlayOneEpisode(ale, dqn, epsilon, true);
    LOG(INFO) << "Episode " << episode << ", score = " << score
              << ", epsilon = " << epsilon << ", iter = "
              << dqn.current_iteration();
    episode++;
  }
  Evaluate(ale, dqn);
};
<commit_msg>Added an argument to specify the solver type.<commit_after>#include <cmath>
#include <iostream>
#include <ale_interface.hpp>
#include <glog/logging.h>
#include <gflags/gflags.h>
#include "prettyprint.hpp"
#include "dqn.hpp"

// DQN Parameters
DEFINE_bool(gpu, true, "Use GPU to brew Caffe");
DEFINE_bool(gui, false, "Open a GUI window");
DEFINE_string(rom, "roms/pong.bin", "Atari 2600 ROM to play");
DEFINE_int32(memory, 400000, "Capacity of replay memory");
DEFINE_int32(explore, 1000000, "Number of iterations needed for epsilon to reach given value.");
DEFINE_double(epsilon, 0.05, "Value of epsilon reached after explore iterations.");
DEFINE_double(gamma, 0.95, "Discount factor of future rewards (0,1]");
DEFINE_int32(memory_threshold, 100, "Enough amount of transitions to start learning");
DEFINE_int32(skip_frame, 3, "Number of frames skipped");
DEFINE_bool(show_frame, false, "Show the current frame in CUI");
DEFINE_string(save_screen, "", "File prefix in to save frames");
DEFINE_string(save_binary_screen, "", "File prefix in to save binary frames");
DEFINE_string(weights, "", "The pretrained weights load (*.caffemodel).");
DEFINE_string(snapshot, "", "The solver state to load (*.solverstate).");
DEFINE_bool(evaluate, false, "Evaluation mode: only playing a game, no updates");
DEFINE_double(evaluate_with_epsilon, 0.05, "Epsilon value to be used in evaluation mode");
DEFINE_double(repeat_games, 10, "Number of games played in evaluation mode");
// Solver Parameters
DEFINE_string(solver, "", "Solver parameter file (*.prototxt)");
DEFINE_string(solver_type, "ADADELTA", "Type of solver.");
DEFINE_string(model, "dqn.prototxt", "The model definition (*.prototxt).");
DEFINE_double(momentum, 0.95, "Solver momentum");
DEFINE_double(base_lr, 0.1, "Solver base learning rate");
DEFINE_string(lr_policy, "step", "Solver lr policy");
DEFINE_double(solver_gamma, 0.1, "Solver gamma");
DEFINE_int32(stepsize, 10000000, "Solver stepsize");
DEFINE_int32(max_iter, 10000000, "Maximum number of iterations");
DEFINE_int32(snapshot_frequency, 1000000, "Snapshot frequency in iterations");
DEFINE_int32(display, 10000, "Display frequency in iterations");
DEFINE_string(snapshot_prefix, "state/dqn", "Prefix for saving snapshots");

double CalculateEpsilon(const int iter) {
  if (iter < FLAGS_explore) {
    return 1.0 - (1.0 - FLAGS_epsilon) * (static_cast<double>(iter) / FLAGS_explore);
  } else {
    return FLAGS_epsilon;
  }
}

void SaveScreen(const ALEScreen& screen, const ALEInterface& ale,
                const string filename) {
  IntMatrix screen_matrix;
  for (auto row = 0; row < screen.height(); row++) {
    IntVect row_vec;
    for (auto col = 0; col < screen.width(); col++) {
      int pixel = screen.get(row, col);
      row_vec.emplace_back(pixel);
    }
    screen_matrix.emplace_back(row_vec);
  }
  ale.theOSystem->p_export_screen->save_png(&screen_matrix, filename);
}

void SaveInputFrames(const dqn::InputFrames& frames, const string filename) {
  std::ofstream ofs;
  ofs.open(filename, ios::out | ios::binary);
  for (int i = 0; i < dqn::kInputFrameCount; ++i) {
    const dqn::FrameData& frame = *frames[i];
    for (int j = 0; j < dqn::kCroppedFrameDataSize; ++j) {
      ofs.write((char*) &frame[j], sizeof(uint8_t));
    }
  }
  ofs.close();
}

/**
 * Play one episode and return the total score
 */
double PlayOneEpisode(ALEInterface& ale, dqn::DQN& dqn, const double epsilon,
                      const bool update) {
  CHECK(!ale.game_over());
  std::deque<dqn::FrameDataSp> past_frames;
  auto total_score = 0.0;
  for (auto frame = 0; !ale.game_over(); ++frame) {
    const ALEScreen& screen = ale.getScreen();
    const auto current_frame = dqn::PreprocessScreen(screen);
    if (FLAGS_show_frame) {
      std::cout << dqn::DrawFrame(*current_frame) << std::endl;
    }
    if (!FLAGS_save_screen.empty()) {
      std::stringstream ss;
      ss << FLAGS_save_screen << setfill('0') << setw(5) <<
          std::to_string(frame) << ".png";
      SaveScreen(screen, ale, ss.str());
    }
    past_frames.push_back(current_frame);
    if (past_frames.size() < dqn::kInputFrameCount) {
      // If there are not past frames enough for DQN input, just select NOOP
      for (auto i = 0; i < FLAGS_skip_frame + 1 && !ale.game_over(); ++i) {
        total_score += ale.act(PLAYER_A_NOOP);
      }
    } else {
      while (past_frames.size() > dqn::kInputFrameCount) {
        past_frames.pop_front();
      }
      dqn::InputFrames input_frames;
      std::copy(past_frames.begin(), past_frames.end(), input_frames.begin());
      if (!FLAGS_save_binary_screen.empty()) {
        static int binary_save_num = 0;
        string fname = FLAGS_save_binary_screen +
            std::to_string(binary_save_num++) + ".bin";
        SaveInputFrames(input_frames, fname);
      }
      const auto action = dqn.SelectAction(input_frames, epsilon);
      auto immediate_score = 0.0;
      for (auto i = 0; i < FLAGS_skip_frame + 1 && !ale.game_over(); ++i) {
        // Last action is repeated on skipped frames
        immediate_score += ale.act(action);
      }
      total_score += immediate_score;
      // Rewards for DQN are normalized as follows:
      // 1 for any positive score, -1 for any negative score, otherwise 0
      const auto reward =
          immediate_score == 0 ?
              0 :
              immediate_score /= std::abs(immediate_score);
      if (update) {
        // Add the current transition to replay memory
        const auto transition = ale.game_over() ?
            dqn::Transition(input_frames, action, reward, boost::none) :
            dqn::Transition(
                input_frames,
                action,
                reward,
                dqn::PreprocessScreen(ale.getScreen()));
        dqn.AddTransition(transition);
        // If the size of replay memory is enough, update DQN
        if (dqn.memory_size() > FLAGS_memory_threshold) {
          dqn.Update();
        }
      }
    }
  }
  ale.reset_game();
  return total_score;
}

/**
 * Evaluate the current player
 */
void Evaluate(ALEInterface& ale, dqn::DQN& dqn) {
  auto total_score = 0.0;
  std::stringstream ss;
  for (auto i = 0; i < FLAGS_repeat_games; ++i) {
    const auto score =
        PlayOneEpisode(ale, dqn, FLAGS_evaluate_with_epsilon, false);
    ss << score << " ";
    total_score += score;
  }
  LOG(INFO) << "Evaluation scores: " << ss.str();
  LOG(INFO) << "Average score: " <<
      total_score / static_cast<double>(FLAGS_repeat_games) << std::endl;
}

int main(int argc, char** argv) {
  gflags::ParseCommandLineFlags(&argc, &argv, true);
  google::InitGoogleLogging(argv[0]);
  google::InstallFailureSignalHandler();
  google::LogToStderr();

  if (FLAGS_gpu) {
    caffe::Caffe::set_mode(caffe::Caffe::GPU);
  } else {
    caffe::Caffe::set_mode(caffe::Caffe::CPU);
  }

  ALEInterface ale;
  ale.set("display_screen", FLAGS_gui);
  ale.set("disable_color_averaging", true);

  // Load the ROM file
  ale.loadROM(FLAGS_rom);

  // Get the vector of legal actions
  const auto legal_actions = ale.getMinimalActionSet();

  CHECK(FLAGS_snapshot.empty() || FLAGS_weights.empty())
      << "Give a snapshot to resume training or weights to finetune "
      "but not both.";

  // Construct the solver either from file or params
  caffe::SolverParameter solver_param;
  if (!FLAGS_solver.empty()) {
    LOG(INFO) << "Reading solver prototxt from " << FLAGS_solver;
    caffe::ReadProtoFromTextFileOrDie(FLAGS_solver, &solver_param);
  } else {
    LOG(INFO) << "Creating solver from scratch.";
    solver_param.set_net(FLAGS_model);
    ::caffe::SolverParameter_SolverType solver_type;
    CHECK(::caffe::SolverParameter_SolverType_Parse(FLAGS_solver_type, &solver_type))
        << "Invalid Solver Type " << FLAGS_solver_type;
    solver_param.set_solver_type(solver_type);
    solver_param.set_momentum(FLAGS_momentum);
    solver_param.set_base_lr(FLAGS_base_lr);
    solver_param.set_lr_policy(FLAGS_lr_policy);
    solver_param.set_gamma(FLAGS_solver_gamma);
    solver_param.set_stepsize(FLAGS_stepsize);
    solver_param.set_max_iter(FLAGS_max_iter);
    solver_param.set_display(FLAGS_display);
    solver_param.set_snapshot(FLAGS_snapshot_frequency);
    solver_param.set_snapshot_prefix(FLAGS_snapshot_prefix);
  }

  dqn::DQN dqn(legal_actions, solver_param, FLAGS_memory, FLAGS_gamma);
  dqn.Initialize();

  if (!FLAGS_save_screen.empty()) {
    LOG(INFO) << "Saving screens to: " << FLAGS_save_screen;
  }

  if (!FLAGS_snapshot.empty()) {
    LOG(INFO) << "Resuming from " << FLAGS_snapshot;
    dqn.RestoreSolver(FLAGS_snapshot);
  } else if (!FLAGS_weights.empty()) {
    LOG(INFO) << "Finetuning from " << FLAGS_weights;
    dqn.LoadTrainedModel(FLAGS_weights);
  }

  if (FLAGS_evaluate) {
    Evaluate(ale, dqn);
    return 0;
  }

  auto episode = 0;
  while (dqn.current_iteration() < solver_param.max_iter()) {
    const auto epsilon = CalculateEpsilon(dqn.current_iteration());
    const auto score = PlayOneEpisode(ale, dqn, epsilon, true);
    LOG(INFO) << "Episode " << episode << ", score = " << score
              << ", epsilon = " << epsilon << ", iter = "
              << dqn.current_iteration();
    episode++;
  }
  Evaluate(ale, dqn);
};
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: PColumn.hxx,v $
 *
 *  $Revision: 1.13 $
 *
 *  last change: $Author: hr $ $Date: 2006-06-20 00:59:16 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef _CONNECTIVITY_PCOLUMN_HXX_
#define _CONNECTIVITY_PCOLUMN_HXX_

#ifndef _CONNECTIVITY_SDBCX_COLUMN_HXX_
#include "connectivity/sdbcx/VColumn.hxx"
#endif

#ifndef _COMPHELPER_PROPERTY_ARRAY_HELPER_HXX_
#include <comphelper/proparrhlp.hxx>
#endif

namespace connectivity
{
    namespace parse
    {
        class OParseColumn;

        typedef sdbcx::OColumn OParseColumn_BASE;
        typedef ::comphelper::OPropertyArrayUsageHelper<OParseColumn> OParseColumn_PROP;

        class OParseColumn :    public OParseColumn_BASE,
                                public OParseColumn_PROP
        {
            ::rtl::OUString m_aRealName;
            ::rtl::OUString m_aTableName;
            sal_Bool        m_bFunction;
            sal_Bool        m_bDbasePrecisionChanged;
            sal_Bool        m_bAggregateFunction;
        protected:
            virtual ::cppu::IPropertyArrayHelper* createArrayHelper() const;
            virtual ::cppu::IPropertyArrayHelper & SAL_CALL getInfoHelper();

            virtual ~OParseColumn();
        public:
            OParseColumn(const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet>& _xColumn,sal_Bool _bCase);
            OParseColumn(const ::rtl::OUString& _Name,
                    const ::rtl::OUString& _TypeName,
                    const ::rtl::OUString& _DefaultValue,
                    sal_Int32       _IsNullable,
                    sal_Int32       _Precision,
                    sal_Int32       _Scale,
                    sal_Int32       _Type,
                    sal_Bool        _IsAutoIncrement,
                    sal_Bool        _IsCurrency,
                    sal_Bool        _bCase);

            virtual void construct();

            void setRealName(const ::rtl::OUString& _rName)  { m_aRealName  = _rName; }
            void setTableName(const ::rtl::OUString& _rName) { m_aTableName = _rName; }
            void setFunction(sal_Bool _bFunction)            { m_bFunction  = _bFunction; }
            void setAggregateFunction(sal_Bool _bFunction)   { m_bAggregateFunction = _bFunction; }
            void setDbasePrecisionChanged(sal_Bool _bDbasePrecisionChanged) { m_bDbasePrecisionChanged = _bDbasePrecisionChanged; }

            ::rtl::OUString getRealName() const { return  m_aRealName; }
            ::rtl::OUString getTableName() const { return  m_aTableName; }
            sal_Bool        getFunction() const { return  m_bFunction; }
            sal_Bool        getDbasePrecisionChanged()  const { return  m_bDbasePrecisionChanged; }
        private:
            using OParseColumn_BASE::createArrayHelper;
        };

        class OOrderColumn;

        typedef sdbcx::OColumn OOrderColumn_BASE;
        typedef ::comphelper::OPropertyArrayUsageHelper<OOrderColumn> OOrderColumn_PROP;

        class OOrderColumn :    public OOrderColumn_BASE,
                                public OOrderColumn_PROP
        {
            sal_Bool        m_bAscending;
            sal_Bool        m_bOrder;
        protected:
            virtual ::cppu::IPropertyArrayHelper* createArrayHelper() const;
            virtual ::cppu::IPropertyArrayHelper & SAL_CALL getInfoHelper();

            virtual ~OOrderColumn();
        public:
            OOrderColumn(const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet>& _xColumn,sal_Bool _bCase,sal_Bool _bAscending);
            OOrderColumn(const ::rtl::OUString& _Name,
                    const ::rtl::OUString& _TypeName,
                    const ::rtl::OUString& _DefaultValue,
                    sal_Int32       _IsNullable,
                    sal_Int32       _Precision,
                    sal_Int32       _Scale,
                    sal_Int32       _Type,
                    sal_Bool        _IsAutoIncrement,
                    sal_Bool        _IsCurrency,
                    sal_Bool        _bCase
                    ,sal_Bool _bAscending);

            virtual void construct();

            virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames(  ) throw(::com::sun::star::uno::RuntimeException);
        private:
            using OOrderColumn_BASE::createArrayHelper;
        };
    }
}

#endif //_CONNECTIVITY_PCOLUMN_HXX_

<commit_msg>INTEGRATION: CWS qiq (1.12.104); FILE MERGED 2006/06/27 13:51:11 fs 1.12.104.2: RESYNC: (1.12-1.13); FILE MERGED 2006/06/06 13:57:23 fs 1.12.104.1: #i51143# +createColumnsForResultSet / +createColumnForResultSet<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: PColumn.hxx,v $
 *
 *  $Revision: 1.14 $
 *
 *  last change: $Author: obo $ $Date: 2006-07-10 14:15:02 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef _CONNECTIVITY_PCOLUMN_HXX_
#define _CONNECTIVITY_PCOLUMN_HXX_

#ifndef _CONNECTIVITY_SDBCX_COLUMN_HXX_
#include "connectivity/sdbcx/VColumn.hxx"
#endif

#ifndef _CONNECTIVITY_COMMONTOOLS_HXX_
#include "connectivity/CommonTools.hxx"
#endif
#ifndef _VOS_REF_HXX_
#include <vos/ref.hxx>
#endif

#ifndef _COM_SUN_STAR_SDBC_XRESULTSETMETADATA_HPP_
#include <com/sun/star/sdbc/XResultSetMetaData.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBC_XDATABASEMETADATA_HPP_
#include <com/sun/star/sdbc/XDatabaseMetaData.hpp>
#endif

#ifndef _COMPHELPER_PROPERTY_ARRAY_HELPER_HXX_
#include <comphelper/proparrhlp.hxx>
#endif

namespace connectivity
{
    namespace parse
    {
        class OParseColumn;

        typedef sdbcx::OColumn OParseColumn_BASE;
        typedef ::comphelper::OPropertyArrayUsageHelper<OParseColumn> OParseColumn_PROP;

        class OParseColumn :    public OParseColumn_BASE,
                                public OParseColumn_PROP
        {
            ::rtl::OUString m_aRealName;
            ::rtl::OUString m_aTableName;
            sal_Bool        m_bFunction;
            sal_Bool        m_bDbasePrecisionChanged;
            sal_Bool        m_bAggregateFunction;
        protected:
            virtual ::cppu::IPropertyArrayHelper* createArrayHelper() const;
            virtual ::cppu::IPropertyArrayHelper & SAL_CALL getInfoHelper();

            virtual ~OParseColumn();
        public:
            OParseColumn(const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet>& _xColumn,sal_Bool _bCase);
            OParseColumn(const ::rtl::OUString& _Name,
                    const ::rtl::OUString& _TypeName,
                    const ::rtl::OUString& _DefaultValue,
                    sal_Int32       _IsNullable,
                    sal_Int32       _Precision,
                    sal_Int32       _Scale,
                    sal_Int32       _Type,
                    sal_Bool        _IsAutoIncrement,
                    sal_Bool        _IsCurrency,
                    sal_Bool        _bCase);

            virtual void construct();

            void setRealName(const ::rtl::OUString& _rName)  { m_aRealName  = _rName; }
            void setTableName(const ::rtl::OUString& _rName) { m_aTableName = _rName; }
            void setFunction(sal_Bool _bFunction)            { m_bFunction  = _bFunction; }
            void setAggregateFunction(sal_Bool _bFunction)   { m_bAggregateFunction = _bFunction; }
            void setDbasePrecisionChanged(sal_Bool _bDbasePrecisionChanged) { m_bDbasePrecisionChanged = _bDbasePrecisionChanged; }

            ::rtl::OUString getRealName() const { return  m_aRealName; }
            ::rtl::OUString getTableName() const { return  m_aTableName; }
            sal_Bool        getFunction() const { return  m_bFunction; }
            sal_Bool        getDbasePrecisionChanged()  const { return  m_bDbasePrecisionChanged; }

        public:
            /** creates a collection of OParseColumn, as described by a result set meta data instance.
            */
            static ::vos::ORef< OSQLColumns >
                createColumnsForResultSet(
                    const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSetMetaData >& _rxResMetaData,
                    const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XDatabaseMetaData >& _rxDBMetaData
                );

            /** creates a single OParseColumn, as described by a result set meta data instance
            */
            static OParseColumn*
                createColumnForResultSet(
                    const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSetMetaData >& _rxResMetaData,
                    const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XDatabaseMetaData >& _rxDBMetaData,
                    sal_Int32 _nColumnPos
                );

        private:
            using OParseColumn_BASE::createArrayHelper;
        };

        class OOrderColumn;

        typedef sdbcx::OColumn OOrderColumn_BASE;
        typedef ::comphelper::OPropertyArrayUsageHelper<OOrderColumn> OOrderColumn_PROP;

        class OOrderColumn :    public OOrderColumn_BASE,
                                public OOrderColumn_PROP
        {
            sal_Bool        m_bAscending;
            sal_Bool        m_bOrder;
        protected:
            virtual ::cppu::IPropertyArrayHelper* createArrayHelper() const;
            virtual ::cppu::IPropertyArrayHelper & SAL_CALL getInfoHelper();

            virtual ~OOrderColumn();
        public:
            OOrderColumn(const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet>& _xColumn,sal_Bool _bCase,sal_Bool _bAscending);
            OOrderColumn(const ::rtl::OUString& _Name,
                    const ::rtl::OUString& _TypeName,
                    const ::rtl::OUString& _DefaultValue,
                    sal_Int32       _IsNullable,
                    sal_Int32       _Precision,
                    sal_Int32       _Scale,
                    sal_Int32       _Type,
                    sal_Bool        _IsAutoIncrement,
                    sal_Bool        _IsCurrency,
                    sal_Bool        _bCase
                    ,sal_Bool _bAscending);

            virtual void construct();

            virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames(  ) throw(::com::sun::star::uno::RuntimeException);
        private:
            using OOrderColumn_BASE::createArrayHelper;
        };
    }
}

#endif //_CONNECTIVITY_PCOLUMN_HXX_

<|endoftext|>


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

#include "tink/util/file_output_stream.h"

#include "gtest/gtest.h"
#include "absl/memory/memory.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "tink/subtle/random.h"
#include "tink/util/test_util.h"

namespace crypto {
namespace tink {
namespace {

// Writes 'contents' the specified 'output_stream', and closes the stream.
// Returns the status of output_stream->Close()-operation, or a non-OK status
// of a prior output_stream->Next()-operation, if any.
util::Status WriteToStream(util::FileOutputStream* output_stream,
                           absl::string_view contents) {
  void* buffer;
  int pos = 0;
  int remaining = contents.length();
  int available_space;
  int available_bytes;
  while (remaining > 0) {
    auto next_result = output_stream->Next(&buffer);
    if (!next_result.ok()) return next_result.status();
    available_space = next_result.ValueOrDie();
    available_bytes = std::min(available_space, remaining);
    memcpy(buffer, contents.data() + pos, available_bytes);
    remaining -= available_bytes;
    pos += available_bytes;
  }
  if (available_space > available_bytes) {
    output_stream->BackUp(available_space - available_bytes);
  }
  return output_stream->Close();
}

class FileOutputStreamTest : public ::testing::Test {
};

TEST_F(FileOutputStreamTest, WritingStreams) {
  for (auto stream_size : {0, 10, 100, 1000, 10000, 100000, 1000000}) {
    SCOPED_TRACE(absl::StrCat("stream_size = ", stream_size));
    std::string stream_contents = subtle::Random::GetRandomBytes(stream_size);
    std::string filename = absl::StrCat(stream_size, "_writing_test.bin");
    int output_fd = test::GetTestFileDescriptor(filename);
    auto output_stream = absl::make_unique<util::FileOutputStream>(output_fd);
    auto status = WriteToStream(output_stream.get(), stream_contents);
    EXPECT_TRUE(status.ok()) << status;
    std::string file_contents = test::ReadTestFile(filename);
    EXPECT_EQ(stream_size, file_contents.size());
    EXPECT_EQ(stream_contents, file_contents);
  }
}

TEST_F(FileOutputStreamTest, CustomBufferSizes) {
  int stream_size = 1024 * 1024;
  std::string stream_contents = subtle::Random::GetRandomBytes(stream_size);
  for (auto buffer_size : {1, 10, 100, 1000, 10000, 100000, 1000000}) {
    SCOPED_TRACE(absl::StrCat("buffer_size = ", buffer_size));
    std::string filename = absl::StrCat(buffer_size, "_buffer_size_test.bin");
    int output_fd = test::GetTestFileDescriptor(filename);
    auto output_stream =
        absl::make_unique<util::FileOutputStream>(output_fd, buffer_size);
    void* buffer;
    auto next_result = output_stream->Next(&buffer);
    EXPECT_TRUE(next_result.ok()) << next_result.status();
    EXPECT_EQ(buffer_size, next_result.ValueOrDie());
    output_stream->BackUp(buffer_size);
    auto status = WriteToStream(output_stream.get(), stream_contents);
    EXPECT_TRUE(status.ok()) << status;
    std::string file_contents = test::ReadTestFile(filename);
    EXPECT_EQ(stream_size, file_contents.size());
    EXPECT_EQ(stream_contents, file_contents);
  }
}

TEST_F(FileOutputStreamTest, BackupAndPosition) {
  int stream_size = 1024 * 1024;
  int buffer_size = 1234;
  void* buffer;
  std::string stream_contents = subtle::Random::GetRandomBytes(stream_size);
  std::string filename = absl::StrCat(buffer_size, "_backup_test.bin");
  int output_fd = test::GetTestFileDescriptor(filename);

  // Prepare the stream and do the first call to Next().
  auto output_stream =
      absl::make_unique<util::FileOutputStream>(output_fd, buffer_size);
  EXPECT_EQ(0, output_stream->Position());
  auto next_result = output_stream->Next(&buffer);
  EXPECT_TRUE(next_result.ok()) << next_result.status();
  EXPECT_EQ(buffer_size, next_result.ValueOrDie());
  EXPECT_EQ(buffer_size, output_stream->Position());
  std::memcpy(buffer, stream_contents.data(), buffer_size);

  // BackUp several times, but in total fewer bytes than returned by Next().
  int total_backup_size = 0;
  for (auto backup_size : {0, 1, 5, 0, 10, 100, -42, 400, 20, -100}) {
    SCOPED_TRACE(absl::StrCat("backup_size = ", backup_size));
    output_stream->BackUp(backup_size);
    total_backup_size += std::max(0, backup_size);
    EXPECT_EQ(buffer_size - total_backup_size, output_stream->Position());
  }
  EXPECT_LT(total_backup_size, next_result.ValueOrDie());

  // Call Next(), it should succeed.
  next_result = output_stream->Next(&buffer);
  EXPECT_TRUE(next_result.ok()) << next_result.status();

  // BackUp() some bytes, again fewer than returned by Next().
  total_backup_size = 0;
  for (auto backup_size : {0, 72, -94, 37, 82}) {
    SCOPED_TRACE(absl::StrCat("backup_size = ", backup_size));
    output_stream->BackUp(backup_size);
    total_backup_size += std::max(0, backup_size);
    EXPECT_EQ(buffer_size - total_backup_size, output_stream->Position());
  }
  EXPECT_LT(total_backup_size, next_result.ValueOrDie());

  // Call Next(), it should succeed;
  next_result = output_stream->Next(&buffer);
  EXPECT_TRUE(next_result.ok()) << next_result.status();

  // Call Next() again, it should return a full block.
  auto prev_position = output_stream->Position();
  next_result = output_stream->Next(&buffer);
  EXPECT_TRUE(next_result.ok()) << next_result.status();
  EXPECT_EQ(buffer_size, next_result.ValueOrDie());
  EXPECT_EQ(prev_position + buffer_size, output_stream->Position());
  std::memcpy(buffer, stream_contents.data() + buffer_size, buffer_size);

  // BackUp a few times, with total over the returned buffer_size.
  total_backup_size = 0;
  for (auto backup_size :
           {0, 72, -100, buffer_size / 2, 200, -25, buffer_size / 2, 42}) {
    SCOPED_TRACE(absl::StrCat("backup_size = ", backup_size));
    output_stream->BackUp(backup_size);
    total_backup_size = std::min(buffer_size,
                                 total_backup_size + std::max(0, backup_size));
    EXPECT_EQ(prev_position + buffer_size - total_backup_size,
              output_stream->Position());
  }
  EXPECT_EQ(total_backup_size, buffer_size);
  EXPECT_EQ(prev_position, output_stream->Position());

  // Call Next() again, it should return a full block.
  next_result = output_stream->Next(&buffer);
  EXPECT_TRUE(next_result.ok()) << next_result.status();
  EXPECT_EQ(buffer_size, next_result.ValueOrDie());
  EXPECT_EQ(prev_position + buffer_size, output_stream->Position());
  std::memcpy(buffer, stream_contents.data() + buffer_size, buffer_size);

  // Write the remaining stream contents to stream.
  auto status = WriteToStream(
      output_stream.get(), stream_contents.substr(output_stream->Position()));
  EXPECT_TRUE(status.ok()) << status;
  std::string file_contents = test::ReadTestFile(filename);
  EXPECT_EQ(stream_size, file_contents.size());
  EXPECT_EQ(stream_contents, file_contents);
}

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

#include "tink/util/file_output_stream.h"

#include "gtest/gtest.h"
#include "absl/memory/memory.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "tink/subtle/random.h"
#include "tink/util/test_util.h"

namespace crypto {
namespace tink {
namespace {

// Writes 'contents' the specified 'output_stream', and closes the stream.
// Returns the status of output_stream->Close()-operation, or a non-OK status
// of a prior output_stream->Next()-operation, if any.
util::Status WriteToStream(util::FileOutputStream* output_stream,
                           absl::string_view contents) {
  void* buffer;
  int pos = 0;
  int remaining = contents.length();
  int available_space = 0;
  int available_bytes = 0;
  while (remaining > 0) {
    auto next_result = output_stream->Next(&buffer);
    if (!next_result.ok()) return next_result.status();
    available_space = next_result.ValueOrDie();
    available_bytes = std::min(available_space, remaining);
    memcpy(buffer, contents.data() + pos, available_bytes);
    remaining -= available_bytes;
    pos += available_bytes;
  }
  if (available_space > available_bytes) {
    output_stream->BackUp(available_space - available_bytes);
  }
  return output_stream->Close();
}

class FileOutputStreamTest : public ::testing::Test {
};

TEST_F(FileOutputStreamTest, WritingStreams) {
  for (auto stream_size : {0, 10, 100, 1000, 10000, 100000, 1000000}) {
    SCOPED_TRACE(absl::StrCat("stream_size = ", stream_size));
    std::string stream_contents = subtle::Random::GetRandomBytes(stream_size);
    std::string filename = absl::StrCat(stream_size, "_writing_test.bin");
    int output_fd = test::GetTestFileDescriptor(filename);
    auto output_stream = absl::make_unique<util::FileOutputStream>(output_fd);
    auto status = WriteToStream(output_stream.get(), stream_contents);
    EXPECT_TRUE(status.ok()) << status;
    std::string file_contents = test::ReadTestFile(filename);
    EXPECT_EQ(stream_size, file_contents.size());
    EXPECT_EQ(stream_contents, file_contents);
  }
}

TEST_F(FileOutputStreamTest, CustomBufferSizes) {
  int stream_size = 1024 * 1024;
  std::string stream_contents = subtle::Random::GetRandomBytes(stream_size);
  for (auto buffer_size : {1, 10, 100, 1000, 10000, 100000, 1000000}) {
    SCOPED_TRACE(absl::StrCat("buffer_size = ", buffer_size));
    std::string filename = absl::StrCat(buffer_size, "_buffer_size_test.bin");
    int output_fd = test::GetTestFileDescriptor(filename);
    auto output_stream =
        absl::make_unique<util::FileOutputStream>(output_fd, buffer_size);
    void* buffer;
    auto next_result = output_stream->Next(&buffer);
    EXPECT_TRUE(next_result.ok()) << next_result.status();
    EXPECT_EQ(buffer_size, next_result.ValueOrDie());
    output_stream->BackUp(buffer_size);
    auto status = WriteToStream(output_stream.get(), stream_contents);
    EXPECT_TRUE(status.ok()) << status;
    std::string file_contents = test::ReadTestFile(filename);
    EXPECT_EQ(stream_size, file_contents.size());
    EXPECT_EQ(stream_contents, file_contents);
  }
}

TEST_F(FileOutputStreamTest, BackupAndPosition) {
  int stream_size = 1024 * 1024;
  int buffer_size = 1234;
  void* buffer;
  std::string stream_contents = subtle::Random::GetRandomBytes(stream_size);
  std::string filename = absl::StrCat(buffer_size, "_backup_test.bin");
  int output_fd = test::GetTestFileDescriptor(filename);

  // Prepare the stream and do the first call to Next().
  auto output_stream =
      absl::make_unique<util::FileOutputStream>(output_fd, buffer_size);
  EXPECT_EQ(0, output_stream->Position());
  auto next_result = output_stream->Next(&buffer);
  EXPECT_TRUE(next_result.ok()) << next_result.status();
  EXPECT_EQ(buffer_size, next_result.ValueOrDie());
  EXPECT_EQ(buffer_size, output_stream->Position());
  std::memcpy(buffer, stream_contents.data(), buffer_size);

  // BackUp several times, but in total fewer bytes than returned by Next().
  int total_backup_size = 0;
  for (auto backup_size : {0, 1, 5, 0, 10, 100, -42, 400, 20, -100}) {
    SCOPED_TRACE(absl::StrCat("backup_size = ", backup_size));
    output_stream->BackUp(backup_size);
    total_backup_size += std::max(0, backup_size);
    EXPECT_EQ(buffer_size - total_backup_size, output_stream->Position());
  }
  EXPECT_LT(total_backup_size, next_result.ValueOrDie());

  // Call Next(), it should succeed.
  next_result = output_stream->Next(&buffer);
  EXPECT_TRUE(next_result.ok()) << next_result.status();

  // BackUp() some bytes, again fewer than returned by Next().
  total_backup_size = 0;
  for (auto backup_size : {0, 72, -94, 37, 82}) {
    SCOPED_TRACE(absl::StrCat("backup_size = ", backup_size));
    output_stream->BackUp(backup_size);
    total_backup_size += std::max(0, backup_size);
    EXPECT_EQ(buffer_size - total_backup_size, output_stream->Position());
  }
  EXPECT_LT(total_backup_size, next_result.ValueOrDie());

  // Call Next(), it should succeed;
  next_result = output_stream->Next(&buffer);
  EXPECT_TRUE(next_result.ok()) << next_result.status();

  // Call Next() again, it should return a full block.
  auto prev_position = output_stream->Position();
  next_result = output_stream->Next(&buffer);
  EXPECT_TRUE(next_result.ok()) << next_result.status();
  EXPECT_EQ(buffer_size, next_result.ValueOrDie());
  EXPECT_EQ(prev_position + buffer_size, output_stream->Position());
  std::memcpy(buffer, stream_contents.data() + buffer_size, buffer_size);

  // BackUp a few times, with total over the returned buffer_size.
  total_backup_size = 0;
  for (auto backup_size :
           {0, 72, -100, buffer_size / 2, 200, -25, buffer_size / 2, 42}) {
    SCOPED_TRACE(absl::StrCat("backup_size = ", backup_size));
    output_stream->BackUp(backup_size);
    total_backup_size = std::min(buffer_size,
                                 total_backup_size + std::max(0, backup_size));
    EXPECT_EQ(prev_position + buffer_size - total_backup_size,
              output_stream->Position());
  }
  EXPECT_EQ(total_backup_size, buffer_size);
  EXPECT_EQ(prev_position, output_stream->Position());

  // Call Next() again, it should return a full block.
  next_result = output_stream->Next(&buffer);
  EXPECT_TRUE(next_result.ok()) << next_result.status();
  EXPECT_EQ(buffer_size, next_result.ValueOrDie());
  EXPECT_EQ(prev_position + buffer_size, output_stream->Position());
  std::memcpy(buffer, stream_contents.data() + buffer_size, buffer_size);

  // Write the remaining stream contents to stream.
  auto status = WriteToStream(
      output_stream.get(), stream_contents.substr(output_stream->Position()));
  EXPECT_TRUE(status.ok()) << status;
  std::string file_contents = test::ReadTestFile(filename);
  EXPECT_EQ(stream_size, file_contents.size());
  EXPECT_EQ(stream_contents, file_contents);
}

}  // namespace
}  // namespace tink
}  // namespace crypto
<|endoftext|>


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

#include "RJSArray.hpp"
#include "RJSObject.hpp"
#include "RJSUtil.hpp"
#include "object_accessor.hpp"

using namespace realm;

size_t ObjectArray::size() {
    return link_view->size();
}

Row ObjectArray::get(std::size_t row_ndx) {
    if (row_ndx >= link_view->size()) {
        throw std::range_error(std::string("Index ") + std::to_string(row_ndx) + " is outside of range 0..." +
                               std::to_string(link_view->size()) + ".");
    }
    return link_view->get(row_ndx);
}

void ObjectArray::verify_attached() {
    if (!link_view->is_attached()) {
        throw std::runtime_error("Tableview is not attached");
    }
    link_view->sync_if_needed();
}

static inline ObjectArray * RJSVerifiedArray(JSObjectRef object) {
    ObjectArray *array = RJSGetInternal<ObjectArray *>(object);
    array->verify_attached();
    return array;
}

JSValueRef ArrayGetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef* jsException) {
    try {
        // index subscripting
        ObjectArray *array = RJSVerifiedArray(object);
        size_t size = array->size();

        std::string indexStr = RJSStringForJSString(propertyName);
        if (indexStr == "length") {
            return JSValueMakeNumber(ctx, size);
        }

        return RJSObjectCreate(ctx, Object(array->realm, array->object_schema, array->get(std::stol(indexStr))));
    }
    catch (std::invalid_argument &exp) {
        // for stol failure this could be another property that is handled externally, so ignore
        return NULL;
    }
    catch (std::exception &exp) {
        if (jsException) {
            *jsException = RJSMakeError(ctx, exp);
        }
        return NULL;
    }
}

void ArrayPropertyNames(JSContextRef ctx, JSObjectRef object, JSPropertyNameAccumulatorRef propertyNames) {
    ObjectArray *array = RJSGetInternal<ObjectArray *>(object);
    size_t size = array->size();

    char str[32];
    for (size_t i = 0; i < size; i++) {
        sprintf(str, "%zu", i);
        JSStringRef name = JSStringCreateWithUTF8CString(str);
        JSPropertyNameAccumulatorAddName(propertyNames, name);
        JSStringRelease(name);
    }
}

JSValueRef ArrayPush(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* jsException) {
    try {
        ObjectArray *array = RJSVerifiedArray(thisObject);
        RJSValidateArgumentCountIsAtLeast(argumentCount, 1);
        for (size_t i = 0; i < argumentCount; i++) {
            array->link_view->add(RJSAccessor::to_object_index(ctx, array->realm, const_cast<JSValueRef &>(arguments[i]), array->object_schema.name, false));
        }
        return JSValueMakeNumber(ctx, array->link_view->size());
    }
    catch (std::exception &exp) {
        if (jsException) {
            *jsException = RJSMakeError(ctx, exp);
        }
    }
    return NULL;
}

JSValueRef ArrayPop(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* jsException) {
    try {
        ObjectArray *array = RJSVerifiedArray(thisObject);
        RJSValidateArgumentCount(argumentCount, 0);

        size_t size = array->size();
        if (size == 0) {
            return JSValueMakeUndefined(ctx);
        }
        size_t index = size - 1;
        JSValueRef obj = RJSObjectCreate(ctx, Object(array->realm, array->object_schema, array->get(index)));
        array->link_view->remove(index);
        return obj;
    }
    catch (std::exception &exp) {
        if (jsException) {
            *jsException = RJSMakeError(ctx, exp);
        }
    }
    return NULL;
}

JSValueRef ArrayUnshift(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* jsException) {
    try {
        ObjectArray *array = RJSVerifiedArray(thisObject);
        RJSValidateArgumentCountIsAtLeast(argumentCount, 1);
        for (size_t i = 0; i < argumentCount; i++) {
            array->link_view->insert(i, RJSAccessor::to_object_index(ctx, array->realm, const_cast<JSValueRef &>(arguments[i]), array->object_schema.name, false));
        }
        return JSValueMakeNumber(ctx, array->link_view->size());
    }
    catch (std::exception &exp) {
        if (jsException) {
            *jsException = RJSMakeError(ctx, exp);
        }
    }
    return NULL;
}

JSValueRef ArrayShift(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* jsException) {
    try {
        ObjectArray *array = RJSVerifiedArray(thisObject);
        RJSValidateArgumentCount(argumentCount, 0);
        if (array->size() == 0) {
            return JSValueMakeUndefined(ctx);
        }
        JSValueRef obj = RJSObjectCreate(ctx, Object(array->realm, array->object_schema, array->get(0)));
        array->link_view->remove(0);
        return obj;
    }
    catch (std::exception &exp) {
        if (jsException) {
            *jsException = RJSMakeError(ctx, exp);
        }
    }
    return NULL;
}

JSValueRef ArraySplice(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* jsException) {
    try {
        ObjectArray *array = RJSVerifiedArray(thisObject);
        size_t size = array->size();

        RJSValidateArgumentCountIsAtLeast(argumentCount, 2);
        long index = std::min<long>(RJSValidatedValueToNumber(ctx, arguments[0]), size);
        if (index < 0) {
            index = std::max<long>(size + index, 0);
        }

        long remove = std::max<long>(RJSValidatedValueToNumber(ctx, arguments[1]), 0);
        if (index + remove > size) {
            remove = size - index;
        }

        std::vector<JSObjectRef> removedObjects(remove);
        for (size_t i = 0; i < remove; i++) {
            removedObjects[i] = RJSObjectCreate(ctx, Object(array->realm, array->object_schema, array->get(index)));
            array->link_view->remove(index);
        }
        for (size_t i = 2; i < argumentCount; i++) {
            array->link_view->insert(index + i - 2, RJSAccessor::to_object_index(ctx, array->realm, const_cast<JSValueRef &>(arguments[i]), array->object_schema.name, false));
        }
        return JSObjectMakeArray(ctx, remove, removedObjects.data(), jsException);
    }
    catch (std::exception &exp) {
        if (jsException) {
            *jsException = RJSMakeError(ctx, exp);
        }
    }
    return NULL;
}

JSObjectRef RJSArrayCreate(JSContextRef ctx, realm::ObjectArray *array) {
    return RJSWrapObject<ObjectArray *>(ctx, RJSArrayClass(), array);
}

JSClassRef RJSArrayClass() {
    const JSStaticFunction arrayFuncs[] = {
        {"push", ArrayPush, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
        {"pop", ArrayPop, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
        {"shift", ArrayShift, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
        {"unshift", ArrayUnshift, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
        {"splice", ArraySplice, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
        {NULL, NULL},
    };
    static JSClassRef s_arrayClass = RJSCreateWrapperClass<Object>("RealmArray", ArrayGetProperty, NULL, arrayFuncs, NULL, ArrayPropertyNames);
    return s_arrayClass;
}
<commit_msg>Use RJSVerifiedArray inside ArrayPropertyNames<commit_after>////////////////////////////////////////////////////////////////////////////
//
// Copyright 2015 Realm Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
////////////////////////////////////////////////////////////////////////////

#include "RJSArray.hpp"
#include "RJSObject.hpp"
#include "RJSUtil.hpp"
#include "object_accessor.hpp"

using namespace realm;

size_t ObjectArray::size() {
    return link_view->size();
}

Row ObjectArray::get(std::size_t row_ndx) {
    if (row_ndx >= link_view->size()) {
        throw std::range_error(std::string("Index ") + std::to_string(row_ndx) + " is outside of range 0..." +
                               std::to_string(link_view->size()) + ".");
    }
    return link_view->get(row_ndx);
}

void ObjectArray::verify_attached() {
    if (!link_view->is_attached()) {
        throw std::runtime_error("Tableview is not attached");
    }
    link_view->sync_if_needed();
}

static inline ObjectArray * RJSVerifiedArray(JSObjectRef object) {
    ObjectArray *array = RJSGetInternal<ObjectArray *>(object);
    array->verify_attached();
    return array;
}

JSValueRef ArrayGetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef* jsException) {
    try {
        // index subscripting
        ObjectArray *array = RJSVerifiedArray(object);
        size_t size = array->size();

        std::string indexStr = RJSStringForJSString(propertyName);
        if (indexStr == "length") {
            return JSValueMakeNumber(ctx, size);
        }

        return RJSObjectCreate(ctx, Object(array->realm, array->object_schema, array->get(std::stol(indexStr))));
    }
    catch (std::invalid_argument &exp) {
        // for stol failure this could be another property that is handled externally, so ignore
        return NULL;
    }
    catch (std::exception &exp) {
        if (jsException) {
            *jsException = RJSMakeError(ctx, exp);
        }
        return NULL;
    }
}

void ArrayPropertyNames(JSContextRef ctx, JSObjectRef object, JSPropertyNameAccumulatorRef propertyNames) {
    ObjectArray *array = RJSVerifiedArray(object);
    size_t size = array->size();

    char str[32];
    for (size_t i = 0; i < size; i++) {
        sprintf(str, "%zu", i);
        JSStringRef name = JSStringCreateWithUTF8CString(str);
        JSPropertyNameAccumulatorAddName(propertyNames, name);
        JSStringRelease(name);
    }
}

JSValueRef ArrayPush(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* jsException) {
    try {
        ObjectArray *array = RJSVerifiedArray(thisObject);
        RJSValidateArgumentCountIsAtLeast(argumentCount, 1);
        for (size_t i = 0; i < argumentCount; i++) {
            array->link_view->add(RJSAccessor::to_object_index(ctx, array->realm, const_cast<JSValueRef &>(arguments[i]), array->object_schema.name, false));
        }
        return JSValueMakeNumber(ctx, array->link_view->size());
    }
    catch (std::exception &exp) {
        if (jsException) {
            *jsException = RJSMakeError(ctx, exp);
        }
    }
    return NULL;
}

JSValueRef ArrayPop(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* jsException) {
    try {
        ObjectArray *array = RJSVerifiedArray(thisObject);
        RJSValidateArgumentCount(argumentCount, 0);

        size_t size = array->size();
        if (size == 0) {
            return JSValueMakeUndefined(ctx);
        }
        size_t index = size - 1;
        JSValueRef obj = RJSObjectCreate(ctx, Object(array->realm, array->object_schema, array->get(index)));
        array->link_view->remove(index);
        return obj;
    }
    catch (std::exception &exp) {
        if (jsException) {
            *jsException = RJSMakeError(ctx, exp);
        }
    }
    return NULL;
}

JSValueRef ArrayUnshift(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* jsException) {
    try {
        ObjectArray *array = RJSVerifiedArray(thisObject);
        RJSValidateArgumentCountIsAtLeast(argumentCount, 1);
        for (size_t i = 0; i < argumentCount; i++) {
            array->link_view->insert(i, RJSAccessor::to_object_index(ctx, array->realm, const_cast<JSValueRef &>(arguments[i]), array->object_schema.name, false));
        }
        return JSValueMakeNumber(ctx, array->link_view->size());
    }
    catch (std::exception &exp) {
        if (jsException) {
            *jsException = RJSMakeError(ctx, exp);
        }
    }
    return NULL;
}

JSValueRef ArrayShift(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* jsException) {
    try {
        ObjectArray *array = RJSVerifiedArray(thisObject);
        RJSValidateArgumentCount(argumentCount, 0);
        if (array->size() == 0) {
            return JSValueMakeUndefined(ctx);
        }
        JSValueRef obj = RJSObjectCreate(ctx, Object(array->realm, array->object_schema, array->get(0)));
        array->link_view->remove(0);
        return obj;
    }
    catch (std::exception &exp) {
        if (jsException) {
            *jsException = RJSMakeError(ctx, exp);
        }
    }
    return NULL;
}

JSValueRef ArraySplice(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* jsException) {
    try {
        ObjectArray *array = RJSVerifiedArray(thisObject);
        size_t size = array->size();

        RJSValidateArgumentCountIsAtLeast(argumentCount, 2);
        long index = std::min<long>(RJSValidatedValueToNumber(ctx, arguments[0]), size);
        if (index < 0) {
            index = std::max<long>(size + index, 0);
        }

        long remove = std::max<long>(RJSValidatedValueToNumber(ctx, arguments[1]), 0);
        if (index + remove > size) {
            remove = size - index;
        }

        std::vector<JSObjectRef> removedObjects(remove);
        for (size_t i = 0; i < remove; i++) {
            removedObjects[i] = RJSObjectCreate(ctx, Object(array->realm, array->object_schema, array->get(index)));
            array->link_view->remove(index);
        }
        for (size_t i = 2; i < argumentCount; i++) {
            array->link_view->insert(index + i - 2, RJSAccessor::to_object_index(ctx, array->realm, const_cast<JSValueRef &>(arguments[i]), array->object_schema.name, false));
        }
        return JSObjectMakeArray(ctx, remove, removedObjects.data(), jsException);
    }
    catch (std::exception &exp) {
        if (jsException) {
            *jsException = RJSMakeError(ctx, exp);
        }
    }
    return NULL;
}

JSObjectRef RJSArrayCreate(JSContextRef ctx, realm::ObjectArray *array) {
    return RJSWrapObject<ObjectArray *>(ctx, RJSArrayClass(), array);
}

JSClassRef RJSArrayClass() {
    const JSStaticFunction arrayFuncs[] = {
        {"push", ArrayPush, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
        {"pop", ArrayPop, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
        {"shift", ArrayShift, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
        {"unshift", ArrayUnshift, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
        {"splice", ArraySplice, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
        {NULL, NULL},
    };
    static JSClassRef s_arrayClass = RJSCreateWrapperClass<Object>("RealmArray", ArrayGetProperty, NULL, arrayFuncs, NULL, ArrayPropertyNames);
    return s_arrayClass;
}
<|endoftext|>


<commit_before>/*
 * Renderer.cpp
 *
 * Renders the box2d content
 */

#ifndef PINBALL_BOT_RENDERER
#define PINBALL_BOT_RENDERER

#include <Box2D/Box2D.h>

#include <SDL2/SDL.h>
#include <SDL2/SDL_main.h>

#include <SDL2/SDL2_gfxPrimitives.h>

#include <iostream>

#ifdef __APPLE__
#include <OpenGL/gl.h>
#include <OpenGL/glu.h>
#else
#ifdef _WIN32
  #include <windows.h>
#endif
#include <GL/gl.h>
#include <GL/glu.h>
#endif

class Renderer : public b2Draw{

	private:

		const float NUMERATOR			= 7.0f;
		const float DENOMINATOR			= 9.0f;

		const float SCALING				= NUMERATOR / DENOMINATOR;
		const float PADDING_PERCENT		= (DENOMINATOR - NUMERATOR) / DENOMINATOR;

		int		width;
		int		height;

		int		oneMeterInPX;

		SDL_Window*		window;
		SDL_Renderer*	renderer;

		/**
		 * Converts Box2D meters into screen pixels
		 * @param	meters		float		The amount of meters to convert
		 * @return				int			The rounded amount of corresponding screen pixels
		 */
		int metersToPixels(float meters){
			return round(meters * oneMeterInPX);
		}

		/**
		 * Converts a Box2D vector into screen coordinates using metersToPixels()
		 * @param	position	b2Vec2		The Box2D vector to convert
		 * @return				b2vec2		The converted Box2D vector
		 */
		b2Vec2 toScreenCoords(b2Vec2 position){
			return b2Vec2 (
					round(width * PADDING_PERCENT) + metersToPixels(position.x),
					round(height * PADDING_PERCENT) + metersToPixels(position.y)
			);
		}

	public:

		/**
		 * Inits all required values based on the given window width/height and the DPI
		 */
		Renderer(int width, int height) : width(width), height(height){

			SDL_Init( /*SDL_INIT_EVERYTHING*/SDL_INIT_VIDEO );

			window = SDL_CreateWindow(
				"PinballBot",						// window title
				0,									// initial x position
				0,									// initial y position
				this->width,						// width, in pixels
				this->height,						// height, in pixels
				SDL_WINDOW_OPENGL | SDL_WINDOW_ALLOW_HIGHDPI //enables retina support
			);

			if (window == nullptr) {
				printf("Could not create window: %s\n", SDL_GetError());
				SDL_Quit();
				return;
			}

			//updates the width and height if there's a high DPI and calc other vars afterwards
			SDL_GL_GetDrawableSize(window, &width, &height);

			oneMeterInPX = SCALING * height; /* one meter is equal to half of the width of the window */

			renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
			SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_ADD);

			SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); //white background
			SDL_RenderClear(renderer);
		}

		/**
		 * Uses SDL functions to remove objects
		 */
		~Renderer(){
			SDL_DestroyWindow(window);
			SDL_Quit();
		}

		/**
		 * Redraws the scene onto the window
		 * @return	void
		 */
		void redraw(){

			//filledCircleColor(renderer, 320, 91, 10, createRGBA(255,0,0,255));

			SDL_RenderPresent(renderer);

			SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
			SDL_RenderClear(renderer);
		}

		/**
		 * Draws a polygon
		 * @param	vertices		b2Vec2		The vertices of the polygon
		 * @param	vertexCount		int32		The amount of vertices
		 * @param	red				Uint8		The amount of red	in the color
		 * @param	green			Uint8		The amount of green	in the color
		 * @param	blue			Uint8		The amount of blue	in the color
		 * @param	alpha			Uint8		The opacity of the color
		 * @param	filled			bool		Draw a filled polygon or just the outlines?
		 * @return	void
		 */
		void dPolygon(const b2Vec2* vertices, int32 vertexCount, Uint8 red, Uint8 green, Uint8 blue, Uint8 alpha, bool filled){
			short x[vertexCount];
			short y[vertexCount];

			for(int i=0;i<vertexCount;i++){
				b2Vec2 vec = toScreenCoords(vertices[i]);

				x[i] = vec.x;
				y[i] = vec.y;
			}

			if(filled){
				filledPolygonRGBA(renderer, x, y, vertexCount, red, green, blue, alpha);
			}else{
				polygonRGBA(renderer, x, y, vertexCount, red, green, blue, alpha);
			}
		}

		/**
		 * Draws a circle
		 * @param	center			b2Vec2		The coordinates of the center of the circle
		 * @param	radius			float32		The radius of the circle
		 * @param	red				Uint8		The amount of red	in the color
		 * @param	green			Uint8		The amount of green	in the color
		 * @param	blue			Uint8		The amount of blue	in the color
		 * @param	alpha			Uint8		The opacity of the color
		 * @param	filled			bool		Draw a filled polygon or just the outlines?
		 * @return	void
		 */
		void dCircle(const b2Vec2& center, float32 radius, Uint8 red, Uint8 green, Uint8 blue, Uint8 alpha, bool filled){
			b2Vec2 coords = toScreenCoords(center);

			if(filled){
				filledCircleRGBA(renderer, coords.x, coords.y, metersToPixels(radius), red, green, blue, alpha);
			}else{
				circleRGBA(renderer, coords.x, coords.y, metersToPixels(radius), red, green, blue, alpha);
			}
		}

		/**
		 * Implements the b2Draw functions
		 */
			void DrawPolygon(const b2Vec2* vertices, int32 vertexCount, const b2Color& color) {
				dPolygon(vertices, vertexCount, 0, 0, 0, 255, false);
			}
			void DrawSolidPolygon(const b2Vec2* vertices, int32 vertexCount, const b2Color& color) {
				dPolygon(vertices, vertexCount, 0, 0, 0, 255, true);
			}

			void DrawCircle(const b2Vec2& center, float32 radius, const b2Color& color) {
				dCircle(center, radius, 0, 0, 0, 255, false);
			}
			void DrawSolidCircle(const b2Vec2& center, float32 radius, const b2Vec2& axis, const b2Color& color) {
				dCircle(center, radius, 0, 0, 0, 255, true);
			}

			void DrawSegment(const b2Vec2& p1, const b2Vec2& p2, const b2Color& color) {
				lineRGBA(renderer, p1.x, p1.y, p2.x, p2.y, 0, 0, 0, 255);
			}
			void DrawTransform(const b2Transform& xf) {

			}

};

#endif /* PINBALL_BOT_RENDERER */
<commit_msg>(Hopefully) fixed the issue with constant array sizes<commit_after>/*
 * Renderer.cpp
 *
 * Renders the box2d content
 */

#ifndef PINBALL_BOT_RENDERER
#define PINBALL_BOT_RENDERER

#include <Box2D/Box2D.h>

#include <SDL2/SDL.h>
#include <SDL2/SDL_main.h>

#include <SDL2/SDL2_gfxPrimitives.h>

#include <iostream>
#include <vector>

#ifdef __APPLE__
#include <OpenGL/gl.h>
#include <OpenGL/glu.h>
#else
#ifdef _WIN32
  #include <windows.h>
#endif
#include <GL/gl.h>
#include <GL/glu.h>
#endif

class Renderer : public b2Draw{

	private:

		const float NUMERATOR			= 7.0f;
		const float DENOMINATOR			= 9.0f;

		const float SCALING				= NUMERATOR / DENOMINATOR;
		const float PADDING_PERCENT		= (DENOMINATOR - NUMERATOR) / DENOMINATOR;

		int		width;
		int		height;

		int		oneMeterInPX;

		SDL_Window*		window;
		SDL_Renderer*	renderer;

		/**
		 * Converts Box2D meters into screen pixels
		 * @param	meters		float		The amount of meters to convert
		 * @return				int			The rounded amount of corresponding screen pixels
		 */
		int metersToPixels(float meters){
			return round(meters * oneMeterInPX);
		}

		/**
		 * Converts a Box2D vector into screen coordinates using metersToPixels()
		 * @param	position	b2Vec2		The Box2D vector to convert
		 * @return				b2vec2		The converted Box2D vector
		 */
		b2Vec2 toScreenCoords(b2Vec2 position){
			return b2Vec2 (
					round(width * PADDING_PERCENT) + metersToPixels(position.x),
					round(height * PADDING_PERCENT) + metersToPixels(position.y)
			);
		}

	public:

		/**
		 * Inits all required values based on the given window width/height and the DPI
		 */
		Renderer(int width, int height) : width(width), height(height){

			SDL_Init( /*SDL_INIT_EVERYTHING*/SDL_INIT_VIDEO );

			window = SDL_CreateWindow(
				"PinballBot",						// window title
				0,									// initial x position
				0,									// initial y position
				this->width,						// width, in pixels
				this->height,						// height, in pixels
				SDL_WINDOW_OPENGL | SDL_WINDOW_ALLOW_HIGHDPI //enables retina support
			);

			if (window == nullptr) {
				printf("Could not create window: %s\n", SDL_GetError());
				SDL_Quit();
				return;
			}

			//updates the width and height if there's a high DPI and calc other vars afterwards
			SDL_GL_GetDrawableSize(window, &width, &height);

			oneMeterInPX = SCALING * height; /* one meter is equal to half of the width of the window */

			renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
			SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_ADD);

			SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); //white background
			SDL_RenderClear(renderer);
		}

		/**
		 * Uses SDL functions to remove objects
		 */
		~Renderer(){
			SDL_DestroyWindow(window);
			SDL_Quit();
		}

		/**
		 * Redraws the scene onto the window
		 * @return	void
		 */
		void redraw(){

			//filledCircleColor(renderer, 320, 91, 10, createRGBA(255,0,0,255));

			SDL_RenderPresent(renderer);

			SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
			SDL_RenderClear(renderer);
		}

		/**
		 * Draws a polygon
		 * @param	vertices		b2Vec2		The vertices of the polygon
		 * @param	vertexCount		int32		The amount of vertices
		 * @param	red				Uint8		The amount of red	in the color
		 * @param	green			Uint8		The amount of green	in the color
		 * @param	blue			Uint8		The amount of blue	in the color
		 * @param	alpha			Uint8		The opacity of the color
		 * @param	filled			bool		Draw a filled polygon or just the outlines?
		 * @return	void
		 */
		void dPolygon(const b2Vec2* vertices, int32 vertexCount, Uint8 red, Uint8 green, Uint8 blue, Uint8 alpha, bool filled){
			std::vector<short> x(vertexCount);
			std::vector<short> y(vertexCount);

			for(int i=0;i<vertexCount;i++){
				b2Vec2 vec = toScreenCoords(vertices[i]);

				x[i] = vec.x;
				y[i] = vec.y;
			}

			if(filled){
				filledPolygonRGBA(renderer, x.data(), y.data(), vertexCount, red, green, blue, alpha);
			}else{
				polygonRGBA(renderer, x.data(), y.data(), vertexCount, red, green, blue, alpha);
			}
		}

		/**
		 * Draws a circle
		 * @param	center			b2Vec2		The coordinates of the center of the circle
		 * @param	radius			float32		The radius of the circle
		 * @param	red				Uint8		The amount of red	in the color
		 * @param	green			Uint8		The amount of green	in the color
		 * @param	blue			Uint8		The amount of blue	in the color
		 * @param	alpha			Uint8		The opacity of the color
		 * @param	filled			bool		Draw a filled polygon or just the outlines?
		 * @return	void
		 */
		void dCircle(const b2Vec2& center, float32 radius, Uint8 red, Uint8 green, Uint8 blue, Uint8 alpha, bool filled){
			b2Vec2 coords = toScreenCoords(center);

			if(filled){
				filledCircleRGBA(renderer, coords.x, coords.y, metersToPixels(radius), red, green, blue, alpha);
			}else{
				circleRGBA(renderer, coords.x, coords.y, metersToPixels(radius), red, green, blue, alpha);
			}
		}

		/**
		 * Implements the b2Draw functions
		 */
			void DrawPolygon(const b2Vec2* vertices, int32 vertexCount, const b2Color& color) {
				dPolygon(vertices, vertexCount, 0, 0, 0, 255, false);
			}
			void DrawSolidPolygon(const b2Vec2* vertices, int32 vertexCount, const b2Color& color) {
				dPolygon(vertices, vertexCount, 0, 0, 0, 255, true);
			}

			void DrawCircle(const b2Vec2& center, float32 radius, const b2Color& color) {
				dCircle(center, radius, 0, 0, 0, 255, false);
			}
			void DrawSolidCircle(const b2Vec2& center, float32 radius, const b2Vec2& axis, const b2Color& color) {
				dCircle(center, radius, 0, 0, 0, 255, true);
			}

			void DrawSegment(const b2Vec2& p1, const b2Vec2& p2, const b2Color& color) {
				lineRGBA(renderer, p1.x, p1.y, p2.x, p2.y, 0, 0, 0, 255);
			}
			void DrawTransform(const b2Transform& xf) {

			}

};

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


<commit_before>#include <Runnable.h>
#include <Logger.h>

#include <PlatformThread.h>

#include <exception>

using namespace std;

Logger &
Runnable::getLogger() {
  if (!logger.get()) {
    auto thread = getThreadPtr();
    if (thread) {
      logger = thread->createLogger(getName());
    } else {
      logger = make_shared<DummyLogger>();
    }
  }
  return *logger;
}

std::string
Runnable::getName() const {
  return typeid(*this).name();
}

void
Runnable::start(std::shared_ptr<PlatformThread> _thread) {
  try {
    initialize(_thread);
    run();
  } catch (std::exception & e) {
    getLogger().println("exception: " + std::string(e.what()));
  }
}

bool
Runnable::testDestroy() {
  auto ptr = getThreadPtr();
  if (ptr.get()) {
    return ptr->testDestroy();
  } else {
    return true;
  }
}
<commit_msg>update debug print<commit_after>#include <Runnable.h>
#include <Logger.h>

#include <PlatformThread.h>

#include <exception>

using namespace std;

Logger &
Runnable::getLogger() {
  if (!logger.get()) {
    auto thread = getThreadPtr();
    if (thread) {
      logger = thread->createLogger(getName());
    } else {
      logger = make_shared<DummyLogger>();
    }
  }
  return *logger;
}

std::string
Runnable::getName() const {
  return typeid(*this).name();
}

void
Runnable::start(std::shared_ptr<PlatformThread> _thread) {
  try {
    initialize(_thread);
    run();
  } catch (std::exception & e) {
    getLogger().println("exception(Runnable): " + std::string(e.what()));
  }
}

bool
Runnable::testDestroy() {
  auto ptr = getThreadPtr();
  if (ptr.get()) {
    return ptr->testDestroy();
  } else {
    return true;
  }
}
<|endoftext|>


<commit_before><commit_msg>List searches.<commit_after><|endoftext|>