<commit_before>//@author A0097630B
#include "stdafx.h"
#include "exceptions/parse_error_exception.h"
#include "query_parser.h"

namespace You {
namespace NLP {

namespace spirit = boost::spirit;
namespace qi = spirit::qi;
namespace phoenix = boost::phoenix;

QUERY QueryParser::parse(const StringType& string) {
	QUERY result;

	if (parse(string, result)) {
		return result;
	} else {
		throw ParserException();
	}
}

bool QueryParser::parse(const StringType& string, QUERY& result) {
	try {
		return qi::parse(
			begin(string),
			end(string),
			QueryParser() > qi::omit[*ParserCharTraits::blank] > qi::eoi,
			result);
	} catch (ParserExpectationFailure&) {
		return false;
	}
}

QueryParser::QueryParser() : QueryParser::base_type(start) {
	start %= (
		(qi::lit('/') > explicitCommand) |
		addCommand
	);
	BOOST_SPIRIT_DEBUG_NODE(start);

	explicitCommand %= (
		(qi::lit("add") > space > addCommand) |
		((qi::lit("show") | qi::lit("find")) > *space > showCommand) |
		(qi::lit("edit") > space > editCommand) |
		(qi::lit("delete") > space > deleteCommand) |
		(qi::lit("undo") > *space > undoCommand)
	);
	BOOST_SPIRIT_DEBUG_NODE(explicitCommand);

	#pragma region Adding tasks
	addCommand = (
		addCommandDescription >
		-(*space >> qi::lit("->") > *space > addCommand) >
		-(*space >> qi::lit(':') > *space > addCommandSubtasks)
	)[qi::_val = phoenix::bind(
		&constructAddQuery,
		qi::_1,
		qi::_2,
		qi::_3)];
	BOOST_SPIRIT_DEBUG_NODE(addCommand);

	addCommandDescription %= (
		addCommandDescriptionQuoted |
		addCommandDescriptionUnquoted
	);
	BOOST_SPIRIT_DEBUG_NODE(addCommandDescription);

	addCommandDescriptionQuoted = (
		string > addCommandPriority
	)[qi::_val = phoenix::bind(
		static_cast<ADD_QUERY (*)(StringType, ADD_QUERY)>(
			&constructAddQueryFromDescription),
		qi::_1,
		qi::_2)];
	BOOST_SPIRIT_DEBUG_NODE(addCommandDescriptionQuoted);

	addCommandDescriptionUnquoted = (
		ParserCharTraits::char_ > addCommandDescriptionUnquotedTail
	)[qi::_val = phoenix::bind(
		static_cast<ADD_QUERY(*)(ParserCharEncoding::char_type, ADD_QUERY)>(
			&constructAddQueryFromDescription),
		qi::_1,
		qi::_2)];
	BOOST_SPIRIT_DEBUG_NODE(addCommandDescriptionUnquoted);

	addCommandDescriptionUnquotedTail %= (
		addCommandPriority |
		addCommandDescriptionUnquoted
	);
	BOOST_SPIRIT_DEBUG_NODE(addCommandDescriptionUnquotedTail);

	addCommandPriority %= (
		(*space >> qi::lit('!') >> addCommandTimeOptional)
			[qi::_val = phoenix::bind(&constructAddQueryWithPriority, qi::_1)] |
			addCommandTimeOptional
	);
	BOOST_SPIRIT_DEBUG_NODE(addCommandPriority);

	addCommandTime = (
#ifdef _DEBUG
		((addCommandTimeFrom || addCommandTimeTo)
		[qi::_val = phoenix::bind(&constructAddQueryWithTime, qi::_1, qi::_2)])
#else
		((addCommandTimeFrom >> -addCommandTimeTo)
		[qi::_val = phoenix::bind(&constructAddQueryWithTime,
			qi::_1,
			qi::_2)]) |
		((addCommandTimeTo)
		[qi::_val = phoenix::bind(&constructAddQueryWithTime,
			boost::none,
			qi::_1)])
#endif
		>> *space
	);
	BOOST_SPIRIT_DEBUG_NODE(addCommandTime);

	addCommandTimeFrom %= (
		space >> (qi::lit("from") | qi::lit("after")) >> space >> time);
	addCommandTimeTo %= (
		(space >> (qi::lit("by") | qi::lit("before") | qi::lit("to")) >>
			space >> time));

	addCommandTimeOptional = (
		addCommandTime || (
			*space >> &(qi::char_(":;") | qi::lit("->") | qi::eoi))
	)[qi::_val = phoenix::bind(&constructAddQueryWithOptionalTime, qi::_1)];
	BOOST_SPIRIT_DEBUG_NODE(addCommandTimeOptional);

	addCommandSubtasks %= (
		addCommand % (*space >> qi::lit(';') >> *space)
	);
	BOOST_SPIRIT_DEBUG_NODE(addCommandSubtasks);
	#pragma endregion

	#pragma region Showing tasks
	showCommand = (
		-showCommandFiltering >
		-(-space >> (qi::lit("sorted by") | qi::lit("order by")) > space >
		showCommandSorting)
	)[qi::_val = phoenix::bind(&constructShowQuery, qi::_1, qi::_2)];
	BOOST_SPIRIT_DEBUG_NODE(showCommand);

	showCommandFiltering %=
		showCommandFilteringColumn % (
			(-space >> qi::lit(',') >> -space) |
			(space >> qi::lit("and") >> space));
	BOOST_SPIRIT_DEBUG_NODE(showCommandFiltering);

	showCommandFilteringColumn = (
		showCommandFields >
		-space > showCommandFilteringPredicate > -space >
		value
	)[qi::_val = phoenix::bind(&constructShowQueryFilteringColumn,
		qi::_1,
		qi::_2,
		qi::_3)];
	BOOST_SPIRIT_DEBUG_NODE(showCommandFiltering);

	showCommandFilteringPredicate.add
		(L"=", SHOW_QUERY::Predicate::EQ)
		(L"~", SHOW_QUERY::Predicate::SIMILAR)
		(L"!=", SHOW_QUERY::Predicate::NOT_EQ)
		(L"<", SHOW_QUERY::Predicate::LESS_THAN)
		(L"<=", SHOW_QUERY::Predicate::LESS_THAN_EQ)
		(L">", SHOW_QUERY::Predicate::GREATER_THAN)
		(L">=", SHOW_QUERY::Predicate::GREATER_THAN_EQ);

	showCommandSorting %= (
		showCommandSortingColumn % (
			(-space >> qi::lit(",") >> -space) |
			(space >> qi::lit("then") >> space)));
	BOOST_SPIRIT_DEBUG_NODE(showCommandSorting);

	showCommandSortingColumn = (
		showCommandFields >> -(space >> showCommandSortingOrders)
	)[qi::_val = phoenix::bind(&constructShowQuerySortColumn, qi::_1, qi::_2)];
	BOOST_SPIRIT_DEBUG_NODE(showCommandSortingColumn);

	showCommandSortingOrders.add
		(L"asc", SHOW_QUERY::Order::ASCENDING)
		(L"ascending", SHOW_QUERY::Order::ASCENDING)
		(L"desc", SHOW_QUERY::Order::DESCENDING)
		(L"descending", SHOW_QUERY::Order::DESCENDING);

	showCommandFields.add
		(L"description", TaskField::DESCRIPTION)
		(L"start", TaskField::START)
		(L"deadline", TaskField::DEADLINE)
		(L"priority", TaskField::PRIORITY)
		(L"done", TaskField::COMPLETE)
		(L"complete", TaskField::COMPLETE)
		(L"completed", TaskField::COMPLETE);
	#pragma endregion

	#pragma region Editing tasks
	editCommand = (
		qi::uint_ > (
			(space >> qi::lit("set") > space > editCommandRule) |
			(*space >> qi::lit("!") > editSetHighPriority) |
			(editSetTimes) |
			(*space >> qi::lit(":") > *space > editSetSubtask) |
			(*space >> qi::lit("->") > *space > editSetDependent) |
			(space >> qi::lit("attach") > space >
				editAttachmentCommandRule(true)) |
			(space >> qi::lit("detach") > space >
				editAttachmentCommandRule(false)))
	)[qi::_val = phoenix::bind(&constructEditQuery,
		qi::_1, qi::_2)];
	BOOST_SPIRIT_DEBUG_NODE(editCommand);

	editCommandRule %= (
		editCommandRuleNullary |
		editCommandRuleUnary |
		editCommandRulePriorities
	);
	BOOST_SPIRIT_DEBUG_NODE(editCommandRule);

	editCommandRuleNullary = (
		editCommandFieldsNullary
	)[qi::_val = phoenix::bind(&constructEditQueryNullary, qi::_1)];
	BOOST_SPIRIT_DEBUG_NODE(editCommandRuleNullary);

	editCommandRuleUnary = (
		editCommandFieldsUnary >
		*space > qi::lit('=') > *space >
		value)
	[qi::_val = phoenix::bind(&constructEditQueryUnary, qi::_1, qi::_2)];
	BOOST_SPIRIT_DEBUG_NODE(editCommandRuleUnary);

	editCommandRulePriorities = (
		qi::lit("priority") >
		*space > qi::lit('=') > *space >
		taskPriority
	)[qi::_val = phoenix::bind(&constructEditQueryPriority, qi::_1)];
	BOOST_SPIRIT_DEBUG_NODE(editCommandRulePriorities);

	editCommandFieldsUnary.add
		(L"description", TaskField::DESCRIPTION)
		(L"start", TaskField::START)
		(L"deadline", TaskField::DEADLINE);

	editCommandFieldsNullary.add
		(L"done", TaskField::COMPLETE)
		(L"complete", TaskField::COMPLETE)
		(L"completed", TaskField::COMPLETE);

	editSetHighPriority = (
		qi::eps
	)[qi::_val = phoenix::bind(&constructEditQueryPriority,
		TaskPriority::HIGH)];
	BOOST_SPIRIT_DEBUG_NODE(editSetHighPriority);

	editSetTimes = (
#ifdef _DEBUG
		(editSetTimesFrom || editSetTimesTo)
		[qi::_val = phoenix::bind(&constructEditQueryTimes,
			qi::_1, qi::_2)]
#else
		// Equivalent code for release builds. VC++ generates the wrong program
		// with optimisations.
		(editSetTimesFrom > -editSetTimesTo)
		[qi::_val = phoenix::bind(&constructEditQueryTimes,
			qi::_1, qi::_2)] |
		(editSetTimesTo)
		[qi::_val = phoenix::bind(&constructEditQueryTimes,
			boost::none, qi::_1)]
#endif
	);
	BOOST_SPIRIT_DEBUG_NODE(editSetTimes);

	editSetTimesFrom %= (space >>
		(qi::lit("from") | qi::lit("after")) > space > time);
	editSetTimesTo %= (space >>
		(qi::lit("by") | qi::lit("before") | qi::lit("to")) > space >
		time);

	editSetSubtask = (
		qi::int_
	)[qi::_val = phoenix::bind(&constructEditQuerySubtask, qi::_1)];
	BOOST_SPIRIT_DEBUG_NODE(editSetSubtask);

	editSetDependent = (
		qi::int_
	)[qi::_val = phoenix::bind(&constructEditQueryDependent, qi::_1)];
	BOOST_SPIRIT_DEBUG_NODE(editSetDependent);

	editAttachmentCommandRule = (
		string
	)[qi::_val = phoenix::bind(&constructEditQueryAttachment, qi::_r1, qi::_1)];
	BOOST_SPIRIT_DEBUG_NODE(editAttachmentCommandRule);
	#pragma endregion

	#pragma region Deleting tasks
	deleteCommand = (
		qi::uint_
	)[qi::_val = phoenix::bind(&constructDeleteQuery, qi::_1)];
	BOOST_SPIRIT_DEBUG_NODE(deleteCommand);
	#pragma endregion

	#pragma region Undoing tasks
	undoCommand = (
		qi::eps
	)[qi::_val = phoenix::construct<UNDO_QUERY>()];
	BOOST_SPIRIT_DEBUG_NODE(undoCommand);
	#pragma endregion

	space = qi::omit[+ParserCharTraits::blank];

	value = (
		(qi::int_) |
		(qi::bool_) |
		taskPriority |
		string
	)[qi::_val = phoenix::bind(&constructValue, qi::_1)];

	taskPriority.add
		(L"normal", TaskPriority::NORMAL)
		(L"high", TaskPriority::HIGH);

	string %= qi::as_wstring[(
		qi::lit('\'') > *stringContents > qi::lit('\'')
	)];
	BOOST_SPIRIT_DEBUG_NODE(string);

	stringContents %= (
		qi::lit("\\'")[qi::_val = '\''] |
		qi::lit("\\\\")[qi::_val = '\\'] |
		(ParserCharTraits::char_ - qi::lit('\''))
	);
	BOOST_SPIRIT_DEBUG_NODE(stringContents);

	qi::on_error<qi::fail>(start,
		phoenix::bind(&onFailure, qi::_1, qi::_2, qi::_3, qi::_4));
}

void QueryParser::onFailure(
	ParserIteratorType /*begin*/,
	ParserIteratorType end,
	ParserIteratorType errorPos,
	const spirit::info& message) {
	StringType lexeme(errorPos, end);
	throw ParseErrorException(message, lexeme);
}

}  // namespace NLP
}  // namespace You
<commit_msg>Add another comment for where the workaround is used.<commit_after>//@author A0097630B
#include "stdafx.h"
#include "exceptions/parse_error_exception.h"
#include "query_parser.h"

namespace You {
namespace NLP {

namespace spirit = boost::spirit;
namespace qi = spirit::qi;
namespace phoenix = boost::phoenix;

QUERY QueryParser::parse(const StringType& string) {
	QUERY result;

	if (parse(string, result)) {
		return result;
	} else {
		throw ParserException();
	}
}

bool QueryParser::parse(const StringType& string, QUERY& result) {
	try {
		return qi::parse(
			begin(string),
			end(string),
			QueryParser() > qi::omit[*ParserCharTraits::blank] > qi::eoi,
			result);
	} catch (ParserExpectationFailure&) {
		return false;
	}
}

QueryParser::QueryParser() : QueryParser::base_type(start) {
	start %= (
		(qi::lit('/') > explicitCommand) |
		addCommand
	);
	BOOST_SPIRIT_DEBUG_NODE(start);

	explicitCommand %= (
		(qi::lit("add") > space > addCommand) |
		((qi::lit("show") | qi::lit("find")) > *space > showCommand) |
		(qi::lit("edit") > space > editCommand) |
		(qi::lit("delete") > space > deleteCommand) |
		(qi::lit("undo") > *space > undoCommand)
	);
	BOOST_SPIRIT_DEBUG_NODE(explicitCommand);

	#pragma region Adding tasks
	addCommand = (
		addCommandDescription >
		-(*space >> qi::lit("->") > *space > addCommand) >
		-(*space >> qi::lit(':') > *space > addCommandSubtasks)
	)[qi::_val = phoenix::bind(
		&constructAddQuery,
		qi::_1,
		qi::_2,
		qi::_3)];
	BOOST_SPIRIT_DEBUG_NODE(addCommand);

	addCommandDescription %= (
		addCommandDescriptionQuoted |
		addCommandDescriptionUnquoted
	);
	BOOST_SPIRIT_DEBUG_NODE(addCommandDescription);

	addCommandDescriptionQuoted = (
		string > addCommandPriority
	)[qi::_val = phoenix::bind(
		static_cast<ADD_QUERY (*)(StringType, ADD_QUERY)>(
			&constructAddQueryFromDescription),
		qi::_1,
		qi::_2)];
	BOOST_SPIRIT_DEBUG_NODE(addCommandDescriptionQuoted);

	addCommandDescriptionUnquoted = (
		ParserCharTraits::char_ > addCommandDescriptionUnquotedTail
	)[qi::_val = phoenix::bind(
		static_cast<ADD_QUERY(*)(ParserCharEncoding::char_type, ADD_QUERY)>(
			&constructAddQueryFromDescription),
		qi::_1,
		qi::_2)];
	BOOST_SPIRIT_DEBUG_NODE(addCommandDescriptionUnquoted);

	addCommandDescriptionUnquotedTail %= (
		addCommandPriority |
		addCommandDescriptionUnquoted
	);
	BOOST_SPIRIT_DEBUG_NODE(addCommandDescriptionUnquotedTail);

	addCommandPriority %= (
		(*space >> qi::lit('!') >> addCommandTimeOptional)
			[qi::_val = phoenix::bind(&constructAddQueryWithPriority, qi::_1)] |
			addCommandTimeOptional
	);
	BOOST_SPIRIT_DEBUG_NODE(addCommandPriority);

	addCommandTime = (
#ifdef _DEBUG
		((addCommandTimeFrom || addCommandTimeTo)
		[qi::_val = phoenix::bind(&constructAddQueryWithTime, qi::_1, qi::_2)])
#else
		// Equivalent code for release builds. VC++ generates the wrong program
		// with optimisations.
		((addCommandTimeFrom >> -addCommandTimeTo)
		[qi::_val = phoenix::bind(&constructAddQueryWithTime,
			qi::_1,
			qi::_2)]) |
		((addCommandTimeTo)
		[qi::_val = phoenix::bind(&constructAddQueryWithTime,
			boost::none,
			qi::_1)])
#endif
		>> *space
	);
	BOOST_SPIRIT_DEBUG_NODE(addCommandTime);

	addCommandTimeFrom %= (
		space >> (qi::lit("from") | qi::lit("after")) >> space >> time);
	addCommandTimeTo %= (
		(space >> (qi::lit("by") | qi::lit("before") | qi::lit("to")) >>
			space >> time));

	addCommandTimeOptional = (
		addCommandTime || (
			*space >> &(qi::char_(":;") | qi::lit("->") | qi::eoi))
	)[qi::_val = phoenix::bind(&constructAddQueryWithOptionalTime, qi::_1)];
	BOOST_SPIRIT_DEBUG_NODE(addCommandTimeOptional);

	addCommandSubtasks %= (
		addCommand % (*space >> qi::lit(';') >> *space)
	);
	BOOST_SPIRIT_DEBUG_NODE(addCommandSubtasks);
	#pragma endregion

	#pragma region Showing tasks
	showCommand = (
		-showCommandFiltering >
		-(-space >> (qi::lit("sorted by") | qi::lit("order by")) > space >
		showCommandSorting)
	)[qi::_val = phoenix::bind(&constructShowQuery, qi::_1, qi::_2)];
	BOOST_SPIRIT_DEBUG_NODE(showCommand);

	showCommandFiltering %=
		showCommandFilteringColumn % (
			(-space >> qi::lit(',') >> -space) |
			(space >> qi::lit("and") >> space));
	BOOST_SPIRIT_DEBUG_NODE(showCommandFiltering);

	showCommandFilteringColumn = (
		showCommandFields >
		-space > showCommandFilteringPredicate > -space >
		value
	)[qi::_val = phoenix::bind(&constructShowQueryFilteringColumn,
		qi::_1,
		qi::_2,
		qi::_3)];
	BOOST_SPIRIT_DEBUG_NODE(showCommandFiltering);

	showCommandFilteringPredicate.add
		(L"=", SHOW_QUERY::Predicate::EQ)
		(L"~", SHOW_QUERY::Predicate::SIMILAR)
		(L"!=", SHOW_QUERY::Predicate::NOT_EQ)
		(L"<", SHOW_QUERY::Predicate::LESS_THAN)
		(L"<=", SHOW_QUERY::Predicate::LESS_THAN_EQ)
		(L">", SHOW_QUERY::Predicate::GREATER_THAN)
		(L">=", SHOW_QUERY::Predicate::GREATER_THAN_EQ);

	showCommandSorting %= (
		showCommandSortingColumn % (
			(-space >> qi::lit(",") >> -space) |
			(space >> qi::lit("then") >> space)));
	BOOST_SPIRIT_DEBUG_NODE(showCommandSorting);

	showCommandSortingColumn = (
		showCommandFields >> -(space >> showCommandSortingOrders)
	)[qi::_val = phoenix::bind(&constructShowQuerySortColumn, qi::_1, qi::_2)];
	BOOST_SPIRIT_DEBUG_NODE(showCommandSortingColumn);

	showCommandSortingOrders.add
		(L"asc", SHOW_QUERY::Order::ASCENDING)
		(L"ascending", SHOW_QUERY::Order::ASCENDING)
		(L"desc", SHOW_QUERY::Order::DESCENDING)
		(L"descending", SHOW_QUERY::Order::DESCENDING);

	showCommandFields.add
		(L"description", TaskField::DESCRIPTION)
		(L"start", TaskField::START)
		(L"deadline", TaskField::DEADLINE)
		(L"priority", TaskField::PRIORITY)
		(L"done", TaskField::COMPLETE)
		(L"complete", TaskField::COMPLETE)
		(L"completed", TaskField::COMPLETE);
	#pragma endregion

	#pragma region Editing tasks
	editCommand = (
		qi::uint_ > (
			(space >> qi::lit("set") > space > editCommandRule) |
			(*space >> qi::lit("!") > editSetHighPriority) |
			(editSetTimes) |
			(*space >> qi::lit(":") > *space > editSetSubtask) |
			(*space >> qi::lit("->") > *space > editSetDependent) |
			(space >> qi::lit("attach") > space >
				editAttachmentCommandRule(true)) |
			(space >> qi::lit("detach") > space >
				editAttachmentCommandRule(false)))
	)[qi::_val = phoenix::bind(&constructEditQuery,
		qi::_1, qi::_2)];
	BOOST_SPIRIT_DEBUG_NODE(editCommand);

	editCommandRule %= (
		editCommandRuleNullary |
		editCommandRuleUnary |
		editCommandRulePriorities
	);
	BOOST_SPIRIT_DEBUG_NODE(editCommandRule);

	editCommandRuleNullary = (
		editCommandFieldsNullary
	)[qi::_val = phoenix::bind(&constructEditQueryNullary, qi::_1)];
	BOOST_SPIRIT_DEBUG_NODE(editCommandRuleNullary);

	editCommandRuleUnary = (
		editCommandFieldsUnary >
		*space > qi::lit('=') > *space >
		value)
	[qi::_val = phoenix::bind(&constructEditQueryUnary, qi::_1, qi::_2)];
	BOOST_SPIRIT_DEBUG_NODE(editCommandRuleUnary);

	editCommandRulePriorities = (
		qi::lit("priority") >
		*space > qi::lit('=') > *space >
		taskPriority
	)[qi::_val = phoenix::bind(&constructEditQueryPriority, qi::_1)];
	BOOST_SPIRIT_DEBUG_NODE(editCommandRulePriorities);

	editCommandFieldsUnary.add
		(L"description", TaskField::DESCRIPTION)
		(L"start", TaskField::START)
		(L"deadline", TaskField::DEADLINE);

	editCommandFieldsNullary.add
		(L"done", TaskField::COMPLETE)
		(L"complete", TaskField::COMPLETE)
		(L"completed", TaskField::COMPLETE);

	editSetHighPriority = (
		qi::eps
	)[qi::_val = phoenix::bind(&constructEditQueryPriority,
		TaskPriority::HIGH)];
	BOOST_SPIRIT_DEBUG_NODE(editSetHighPriority);

	editSetTimes = (
#ifdef _DEBUG
		(editSetTimesFrom || editSetTimesTo)
		[qi::_val = phoenix::bind(&constructEditQueryTimes,
			qi::_1, qi::_2)]
#else
		// Equivalent code for release builds. VC++ generates the wrong program
		// with optimisations.
		(editSetTimesFrom > -editSetTimesTo)
		[qi::_val = phoenix::bind(&constructEditQueryTimes,
			qi::_1, qi::_2)] |
		(editSetTimesTo)
		[qi::_val = phoenix::bind(&constructEditQueryTimes,
			boost::none, qi::_1)]
#endif
	);
	BOOST_SPIRIT_DEBUG_NODE(editSetTimes);

	editSetTimesFrom %= (space >>
		(qi::lit("from") | qi::lit("after")) > space > time);
	editSetTimesTo %= (space >>
		(qi::lit("by") | qi::lit("before") | qi::lit("to")) > space >
		time);

	editSetSubtask = (
		qi::int_
	)[qi::_val = phoenix::bind(&constructEditQuerySubtask, qi::_1)];
	BOOST_SPIRIT_DEBUG_NODE(editSetSubtask);

	editSetDependent = (
		qi::int_
	)[qi::_val = phoenix::bind(&constructEditQueryDependent, qi::_1)];
	BOOST_SPIRIT_DEBUG_NODE(editSetDependent);

	editAttachmentCommandRule = (
		string
	)[qi::_val = phoenix::bind(&constructEditQueryAttachment, qi::_r1, qi::_1)];
	BOOST_SPIRIT_DEBUG_NODE(editAttachmentCommandRule);
	#pragma endregion

	#pragma region Deleting tasks
	deleteCommand = (
		qi::uint_
	)[qi::_val = phoenix::bind(&constructDeleteQuery, qi::_1)];
	BOOST_SPIRIT_DEBUG_NODE(deleteCommand);
	#pragma endregion

	#pragma region Undoing tasks
	undoCommand = (
		qi::eps
	)[qi::_val = phoenix::construct<UNDO_QUERY>()];
	BOOST_SPIRIT_DEBUG_NODE(undoCommand);
	#pragma endregion

	space = qi::omit[+ParserCharTraits::blank];

	value = (
		(qi::int_) |
		(qi::bool_) |
		taskPriority |
		string
	)[qi::_val = phoenix::bind(&constructValue, qi::_1)];

	taskPriority.add
		(L"normal", TaskPriority::NORMAL)
		(L"high", TaskPriority::HIGH);

	string %= qi::as_wstring[(
		qi::lit('\'') > *stringContents > qi::lit('\'')
	)];
	BOOST_SPIRIT_DEBUG_NODE(string);

	stringContents %= (
		qi::lit("\\'")[qi::_val = '\''] |
		qi::lit("\\\\")[qi::_val = '\\'] |
		(ParserCharTraits::char_ - qi::lit('\''))
	);
	BOOST_SPIRIT_DEBUG_NODE(stringContents);

	qi::on_error<qi::fail>(start,
		phoenix::bind(&onFailure, qi::_1, qi::_2, qi::_3, qi::_4));
}

void QueryParser::onFailure(
	ParserIteratorType /*begin*/,
	ParserIteratorType end,
	ParserIteratorType errorPos,
	const spirit::info& message) {
	StringType lexeme(errorPos, end);
	throw ParseErrorException(message, lexeme);
}

}  // namespace NLP
}  // namespace You
<|endoftext|>


<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/memory/p9_mss_bulk_pwr_throttles.H $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2015,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* 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.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */

///
/// @file p9_mss_bulk_pwr_throttles.H
/// @brief Set the throttle attributes based on a power limit for the dimms on the channel pair
///
// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
// *HWP HWP Backup: Brian Silver <bsilver@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 1
// *HWP Consumed by: FSP:HB

#ifndef __P9_MSS_BULK_PWR_THROTTLES__
#define __P9_MSS_BULK_PWR_THROTTLES__

#include <fapi2.H>

typedef fapi2::ReturnCode (*p9_mss_bulk_pwr_throttles_FP_t) (const fapi2::Target<fapi2::TARGET_TYPE_MCS>&);

extern "C"
{
///
/// @brief Set the throttle attributes based on a power limit for the dimms on the channel pair
/// @param[in] i_target controller target
/// @return FAPI2_RC_SUCCESS iff ok
///
    fapi2::ReturnCode p9_mss_bulk_pwr_throttles( const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target );
}

#endif
<commit_msg>Modifying ATTRs for memory power thermal<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/memory/p9_mss_bulk_pwr_throttles.H $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2015,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* 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.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */

///
/// @file p9_mss_bulk_pwr_throttles.H
/// @brief Set the throttle attributes based on a power limit for the dimms on the channel pair
///
// *HWP HWP Owner: Jacob Harvey <jlharvey@us.ibm.com>
// *HWP HWP Backup: Brian Silver <bsilver@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 1
// *HWP Consumed by: FSP:HB

#ifndef __P9_MSS_BULK_PWR_THROTTLES__
#define __P9_MSS_BULK_PWR_THROTTLES__

#include <fapi2.H>
#include <vector>
typedef fapi2::ReturnCode (*p9_mss_bulk_pwr_throttles_FP_t) (const
        std::vector< fapi2::Target< fapi2::TARGET_TYPE_MCS>>&);

extern "C"
{

    enum throttle_type : size_t
    {
        POWER = 0,
        THERMAL = 1,
    };

///
/// @brief Set ATTR_MSS_PORT_MAXPOWER, ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_SLOT, ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_PORT
/// @param[in] i_targets vector of MCS's on the same VDDR domain
/// @param[in] thermal boolean to determine whether to calculate throttles based on the power regulator or thermal limits
/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
/// @note Called in p9_mss_bulk_pwr_throttles
/// @note determines the throttle levels based off of the port's power curve,
/// sets the slot throttles to the same
/// @note Enums are POWER for power egulator throttles and THERMAL for thermal throttles
/// @note equalizes the throttles to the lowest of runtime and the lowest slot-throttle value
///

    fapi2::ReturnCode p9_mss_bulk_pwr_throttles (const std::vector < fapi2::Target< fapi2::TARGET_TYPE_MCS>>& i_targets,
            throttle_type t );
}

#endif
<|endoftext|>


<commit_before>#include "np-divs/np_divs.hpp"
#include "np-divs/matrix_io.hpp"
#include "np-divs/div-funcs/div_func.hpp"
#include "np-divs/div_func_from_str.hpp"

#include <iostream>
#include <fstream>
#include <string>

#include <boost/program_options.hpp>
#include <boost/ptr_container/ptr_vector.hpp>

#include <flann/util/matrix.h>

using namespace NPDivs;
using namespace std;
using namespace boost;
namespace po = boost::program_options;

typedef struct s_popts {
    string x_bags_file;
    string y_bags_file;
    string results_file;

    ptr_vector<DivFunc> div_funcs;

    size_t k;
    size_t num_threads;

    flann::IndexParams index_params;
    flann::SearchParams search_params;
} ProgOpts;

bool parse_args(int argc, const char ** argv, ProgOpts& opts);

int main(int argc, const char ** argv) {
    typedef flann::Matrix<double> Matrix;

    ProgOpts opts;
    opts.index_params = flann::KDTreeSingleIndexParams();
    opts.search_params = flann::SearchParams(64);
    if (!parse_args(argc, argv, opts))
        return 1;

    size_t num_df = opts.div_funcs.size();

    // load input bags
    // TODO - gracefully handle nonexisting files
    size_t num_x;
    Matrix* x_bags;
    if (opts.x_bags_file == "-") {
        x_bags = matrices_from_csv(cin, num_x);
    } else {
        ifstream ifs(opts.x_bags_file.c_str(), ifstream::in);
        x_bags = matrices_from_csv(ifs, num_x);
    }

    size_t num_y;
    Matrix* y_bags;
    if (opts.y_bags_file.empty()) {
        y_bags = NULL;
        num_y = num_x;
    } else if (opts.y_bags_file == "-") {
        y_bags = matrices_from_csv(cin, num_y);
    } else {
        ifstream ifs(opts.y_bags_file.c_str(), ifstream::in);
        y_bags = matrices_from_csv(ifs, num_y);
    }

    Matrix* results = alloc_matrix_array<double>(num_df, num_x, num_y);

    try {
        np_divs(x_bags, num_x, y_bags, num_y, opts.div_funcs, results, opts.k,
                opts.index_params, opts.search_params, opts.num_threads);
    } catch (std::exception e) {
        cerr << "Error: " << e.what() << endl;
        exit(1);
    }

    if (opts.results_file == "-") {
        matrix_array_to_csv(cout, results, num_df);
    } else {
        ofstream ofs(opts.results_file.c_str());
        matrix_array_to_csv(ofs, results, num_df);
    }

    free_matrix_array(results, num_df);

    return 0;
}

void parse_div_funcs(ProgOpts &opts, const vector<string> &names) {
    for (size_t i = 0; i < names.size(); i++) {
        opts.div_funcs.push_back(div_func_from_str(names[i]));
    }
}

// TODO nicer handling of matrix inputs
// TODO optionally support HDF5 inputs
// TODO positional arguments for x_bags, y_bags
// TODO support setting {index,search}_params
bool parse_args(int argc, const char ** argv, ProgOpts& opts) {
    po::options_description desc("Allowed options");
    desc.add_options()
        ("help,h", "Produce this help message.")
        ("x-bags,x",
            po::value<string>(&opts.x_bags_file)->default_value("-"),
            "CSV-style file containing matrices separated by blank lines; "
            "- means stdin.")
        ("y-bags,y",
            po::value<string>(&opts.y_bags_file),
            "CSV-style file containing matrices separated by blank lines. "
            "If passed, divergences are calculated between the x bags (rows "
            "in the output matrix) and the y bags (columns); if not passed, "
            "divergences are calculated from the x bags to themselves. Pass "
            "- to use stdin; if both x and y are from stdin, x is read first "
            "and the two groups must be separated by exactly two blank lines. ")
        ("results,r",
            po::value<string>(&opts.results_file)->default_value("-"),
            "Where to write CSV-style matrix of results, where m[i,j] = "
            "div(x_i, y_j). Use - for stdout.")
        ("div-func,f",
            po::value< vector<string> >()->composing()->required()
               ->notifier(boost::bind(&parse_div_funcs, boost::ref(opts), _1)),
            "Divergence functions to use; can be specified more than once. At "
            "least one is required. Format is name:arg1:arg2:..., where argN "
            "refers to the Nth argument to the corresponding DivFunc's "
            "constructor. Some support a first argument specifying a "
            "parameter: renyi:.99 means the Renyi-.99 divergence. All support "
            "a last parameter, which determines the way that large values are "
            "normalized: l2:.95 or renyi:.99:.95 means certain calculated "
            "intermediate values above the 95th percentile are cut down; 1 "
            "means not to do this; default is .99. All extra arguments are "
            "optional.")
        ("num-threads",
            po::value<size_t>(&opts.num_threads)->default_value(0),
            "Number of threads to use for calculations. 0 means one per core.")
        ("k",
            po::value<size_t>(&opts.k)->default_value(3),
            "The k for k-nearest-neighbor calculations.")
    ;

    po::variables_map vm;
    try {
        po::store(po::command_line_parser(argc, argv).options(desc).run(), vm);

        if (vm.count("help")) {
            std::cout << desc << "\n";
            exit(0);
        }

        po::notify(vm);

    } catch (std::exception &e) {
        cerr << "Error: " << e.what() << endl;
        return false;
    }

    return true;
}
<commit_msg>CLI: simple options to choose index type<commit_after>#include "np-divs/np_divs.hpp"
#include "np-divs/matrix_io.hpp"
#include "np-divs/div-funcs/div_func.hpp"
#include "np-divs/div_func_from_str.hpp"

#include <iostream>
#include <fstream>
#include <string>

#include <boost/program_options.hpp>
#include <boost/ptr_container/ptr_vector.hpp>
#include <boost/utility.hpp>

#include <flann/util/matrix.h>

using namespace NPDivs;
using namespace std;
using namespace boost;
namespace po = boost::program_options;

typedef struct s_popts : noncopyable {
    string x_bags_file;
    string y_bags_file;
    string results_file;

    ptr_vector<DivFunc> div_funcs;

    size_t k;
    size_t num_threads;

    flann::IndexParams index_params;
    flann::SearchParams search_params;

    void parse_div_funcs(const vector<string> &names) {
        for (size_t i = 0; i < names.size(); i++) {
            div_funcs.push_back(div_func_from_str(names[i]));
        }
    }

    void parse_index(const string name) {
        // TODO: more index types, support arguments
        if (name == "linear" || name == "brute") {
            index_params = flann::LinearIndexParams();

        } else if (name == "kdtree" || name == "kd") {
            index_params = flann::KDTreeSingleIndexParams();

        } else {
            throw domain_error((format("unknown index type %s") % name).str());
        }
    }
} ProgOpts;

bool parse_args(int argc, const char ** argv, ProgOpts& opts);

int main(int argc, const char ** argv) {
    typedef flann::Matrix<double> Matrix;

    ProgOpts opts;
    opts.search_params = flann::SearchParams(64);
    if (!parse_args(argc, argv, opts))
        return 1;

    size_t num_df = opts.div_funcs.size();

    // load input bags
    // TODO - gracefully handle nonexisting files
    size_t num_x;
    Matrix* x_bags;
    if (opts.x_bags_file == "-") {
        x_bags = matrices_from_csv(cin, num_x);
    } else {
        ifstream ifs(opts.x_bags_file.c_str(), ifstream::in);
        x_bags = matrices_from_csv(ifs, num_x);
    }

    size_t num_y;
    Matrix* y_bags;
    if (opts.y_bags_file.empty()) {
        y_bags = NULL;
        num_y = num_x;
    } else if (opts.y_bags_file == "-") {
        y_bags = matrices_from_csv(cin, num_y);
    } else {
        ifstream ifs(opts.y_bags_file.c_str(), ifstream::in);
        y_bags = matrices_from_csv(ifs, num_y);
    }

    Matrix* results = alloc_matrix_array<double>(num_df, num_x, num_y);

    try {
        np_divs(x_bags, num_x, y_bags, num_y, opts.div_funcs, results, opts.k,
                opts.index_params, opts.search_params, opts.num_threads);
    } catch (std::exception e) {
        cerr << "Error: " << e.what() << endl;
        exit(1);
    }

    if (opts.results_file == "-") {
        matrix_array_to_csv(cout, results, num_df);
    } else {
        ofstream ofs(opts.results_file.c_str());
        matrix_array_to_csv(ofs, results, num_df);
    }

    free_matrix_array(results, num_df);

    return 0;
}

// TODO nicer handling of matrix inputs
// TODO optionally support HDF5 inputs
// TODO positional arguments for x_bags, y_bags
// TODO support setting {index,search}_params
bool parse_args(int argc, const char ** argv, ProgOpts& opts) {
    po::options_description desc("Allowed options");
    desc.add_options()
        ("help,h", "Produce this help message.")
        ("x-bags,x",
            po::value<string>(&opts.x_bags_file)->default_value("-"),
            "CSV-style file containing matrices separated by blank lines; "
            "- means stdin.")
        ("y-bags,y",
            po::value<string>(&opts.y_bags_file),
            "CSV-style file containing matrices separated by blank lines. "
            "If passed, divergences are calculated between the x bags (rows "
            "in the output matrix) and the y bags (columns); if not passed, "
            "divergences are calculated from the x bags to themselves. Pass "
            "- to use stdin; if both x and y are from stdin, x is read first "
            "and the two groups must be separated by exactly two blank lines. ")
        ("results,r",
            po::value<string>(&opts.results_file)->default_value("-"),
            "Where to write CSV-style matrix of results, where m[i,j] = "
            "div(x_i, y_j). Use - for stdout.")
        ("div-func,f",
            po::value< vector<string> >()->composing()->required()
               ->notifier(bind(&ProgOpts::parse_div_funcs, ref(opts), _1)),
            "Divergence functions to use; can be specified more than once. At "
            "least one is required. Format is name:arg1:arg2:..., where argN "
            "refers to the Nth argument to the corresponding DivFunc's "
            "constructor. Some support a first argument specifying a "
            "parameter: renyi:.99 means the Renyi-.99 divergence. All support "
            "a last parameter, which determines the way that large values are "
            "normalized: l2:.95 or renyi:.99:.95 means certain calculated "
            "intermediate values above the 95th percentile are cut down; 1 "
            "means not to do this; default is .99. All extra arguments are "
            "optional.")
        ("num-threads",
            po::value<size_t>(&opts.num_threads)->default_value(0),
            "Number of threads to use for calculations. 0 means one per core.")
        ("k",
            po::value<size_t>(&opts.k)->default_value(3),
            "The k for k-nearest-neighbor calculations.")
        ("index,i",
            po::value<string>()->default_value("kdtree")
                ->notifier(bind(&ProgOpts::parse_index, ref(opts), _1)),
            "The nearest-neighbor index to use. Options: linear, kdtree.")
    ;

    po::variables_map vm;
    try {
        po::store(po::command_line_parser(argc, argv).options(desc).run(), vm);

        if (vm.count("help")) {
            std::cout << desc << "\n";
            exit(0);
        }

        po::notify(vm);

    } catch (std::exception &e) {
        cerr << "Error: " << e.what() << endl;
        return false;
    }

    return true;
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2015 Oleg Morozenkov
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#include "tgbot/Api.h"

#include "tgbot/TgTypeParser.h"
#include "tgbot/TgException.h"
#include "tgbot/net/HttpClient.h"

using namespace std;
using namespace boost::property_tree;

namespace TgBot {

Api::Api(const string& token) : _token(token) {
}

User::Ptr Api::getMe() const {
	return TgTypeParser::getInstance().parseJsonAndGetUser(sendRequest("getMe"));
}

Message::Ptr Api::sendMessage(int32_t chatId, const string& text, bool disableWebPagePreview, int32_t replyToMessageId, const GenericReply::Ptr& replyMarkup) const {
	vector<HttpReqArg> args;
	args.push_back(HttpReqArg("chat_id", chatId));
	args.push_back(HttpReqArg("text", text));
	if (disableWebPagePreview) {
		args.push_back(HttpReqArg("disable_web_page_preview", disableWebPagePreview));
	}
	if (replyToMessageId) {
		args.push_back(HttpReqArg("reply_to_message_id", replyToMessageId));
	}
	if (replyMarkup) {
		args.push_back(HttpReqArg("reply_markup", TgTypeParser::getInstance().parseGenericReply(replyMarkup)));
	}
	return TgTypeParser::getInstance().parseJsonAndGetMessage(sendRequest("sendMessage", args));
}

Message::Ptr Api::forwardMessage(int32_t chatId, int32_t fromChatId, int32_t messageId) const {
	vector<HttpReqArg> args;
	args.push_back(HttpReqArg("chat_id", chatId));
	args.push_back(HttpReqArg("from_chat_id", fromChatId));
	args.push_back(HttpReqArg("message_id", messageId));
	return TgTypeParser::getInstance().parseJsonAndGetMessage(sendRequest("forwardMessage", args));
}

Message::Ptr Api::sendPhoto(int32_t chatId, const InputFile::Ptr& photo, const string& caption, int32_t replyToMessageId, const GenericReply::Ptr& replyMarkup) const {
	vector<HttpReqArg> args;
	args.push_back(HttpReqArg("chat_id", chatId));
	args.push_back(HttpReqArg("photo", photo->data, true, photo->mimeType));
	if (!caption.empty()) {
		args.push_back(HttpReqArg("caption", caption));
	}
	if (replyToMessageId) {
		args.push_back(HttpReqArg("reply_to_message_id", replyToMessageId));
	}
	if (replyMarkup) {
		args.push_back(HttpReqArg("reply_markup", TgTypeParser::getInstance().parseGenericReply(replyMarkup)));
	}
	return TgTypeParser::getInstance().parseJsonAndGetMessage(sendRequest("sendPhoto", args));
}

Message::Ptr Api::sendPhoto(int32_t chatId, const string& photo, const string& caption, int32_t replyToMessageId, const GenericReply::Ptr& replyMarkup) const {
	vector<HttpReqArg> args;
	args.push_back(HttpReqArg("chat_id", chatId));
	args.push_back(HttpReqArg("photo", photo));
	if (!caption.empty()) {
		args.push_back(HttpReqArg("caption", caption));
	}
	if (replyToMessageId) {
		args.push_back(HttpReqArg("reply_to_message_id", replyToMessageId));
	}
	if (replyMarkup) {
		args.push_back(HttpReqArg("reply_markup", TgTypeParser::getInstance().parseGenericReply(replyMarkup)));
	}
	return TgTypeParser::getInstance().parseJsonAndGetMessage(sendRequest("sendPhoto", args));
}

Message::Ptr Api::sendAudio(int32_t chatId, const InputFile::Ptr& audio, int32_t duration, int32_t replyToMessageId, const GenericReply::Ptr& replyMarkup) const {
	vector<HttpReqArg> args;
	args.push_back(HttpReqArg("chat_id", chatId));
	args.push_back(HttpReqArg("audio", audio->data, true, audio->mimeType));
	if (duration) {
		args.push_back(HttpReqArg("duration", duration));
	}
	if (replyToMessageId) {
		args.push_back(HttpReqArg("reply_to_message_id", replyToMessageId));
	}
	if (replyMarkup) {
		args.push_back(HttpReqArg("reply_markup", TgTypeParser::getInstance().parseGenericReply(replyMarkup)));
	}
	return TgTypeParser::getInstance().parseJsonAndGetMessage(sendRequest("sendAudio", args));
}

Message::Ptr Api::sendAudio(int32_t chatId, const string& audio, int32_t duration, int32_t replyToMessageId, const GenericReply::Ptr& replyMarkup) const {
	vector<HttpReqArg> args;
	args.push_back(HttpReqArg("chat_id", chatId));
	args.push_back(HttpReqArg("audio", audio));
	if (duration) {
		args.push_back(HttpReqArg("duration", duration));
	}
	if (replyToMessageId) {
		args.push_back(HttpReqArg("reply_to_message_id", replyToMessageId));
	}
	if (replyMarkup) {
		args.push_back(HttpReqArg("reply_markup", TgTypeParser::getInstance().parseGenericReply(replyMarkup)));
	}
	return TgTypeParser::getInstance().parseJsonAndGetMessage(sendRequest("sendAudio", args));
}

Message::Ptr Api::sendDocument(int32_t chatId, const InputFile::Ptr& document, int32_t replyToMessageId, const GenericReply::Ptr& replyMarkup) const {
	vector<HttpReqArg> args;
	args.push_back(HttpReqArg("chat_id", chatId));
	args.push_back(HttpReqArg("document", document->data, true, document->mimeType));
	if (replyToMessageId) {
		args.push_back(HttpReqArg("reply_to_message_id", replyToMessageId));
	}
	if (replyMarkup) {
		args.push_back(HttpReqArg("reply_markup", TgTypeParser::getInstance().parseGenericReply(replyMarkup)));
	}
	return TgTypeParser::getInstance().parseJsonAndGetMessage(sendRequest("sendDocument", args));
}

Message::Ptr Api::sendDocument(int32_t chatId, const string& document, int32_t replyToMessageId, const GenericReply::Ptr& replyMarkup) const {
	vector<HttpReqArg> args;
	args.push_back(HttpReqArg("chat_id", chatId));
	args.push_back(HttpReqArg("document", document));
	if (replyToMessageId) {
		args.push_back(HttpReqArg("reply_to_message_id", replyToMessageId));
	}
	if (replyMarkup) {
		args.push_back(HttpReqArg("reply_markup", TgTypeParser::getInstance().parseGenericReply(replyMarkup)));
	}
	return TgTypeParser::getInstance().parseJsonAndGetMessage(sendRequest("sendDocument", args));
}

Message::Ptr Api::sendSticker(int32_t chatId, const InputFile::Ptr& sticker, int32_t replyToMessageId, const GenericReply::Ptr& replyMarkup) const {
	vector<HttpReqArg> args;
	args.push_back(HttpReqArg("chat_id", chatId));
	args.push_back(HttpReqArg("sticker", sticker->data, true, sticker->mimeType));
	if (replyToMessageId) {
		args.push_back(HttpReqArg("reply_to_message_id", replyToMessageId));
	}
	if (replyMarkup) {
		args.push_back(HttpReqArg("reply_markup", TgTypeParser::getInstance().parseGenericReply(replyMarkup)));
	}
	return TgTypeParser::getInstance().parseJsonAndGetMessage(sendRequest("sendSticker", args));
}

Message::Ptr Api::sendSticker(int32_t chatId, const string& sticker, int32_t replyToMessageId, const GenericReply::Ptr& replyMarkup) const {
	vector<HttpReqArg> args;
	args.push_back(HttpReqArg("chat_id", chatId));
	args.push_back(HttpReqArg("sticker", sticker));
	if (replyToMessageId) {
		args.push_back(HttpReqArg("reply_to_message_id", replyToMessageId));
	}
	if (replyMarkup) {
		args.push_back(HttpReqArg("reply_markup", TgTypeParser::getInstance().parseGenericReply(replyMarkup)));
	}
	return TgTypeParser::getInstance().parseJsonAndGetMessage(sendRequest("sendSticker", args));
}

Message::Ptr Api::sendVideo(int32_t chatId, const InputFile::Ptr& video, int32_t replyToMessageId, const GenericReply::Ptr& replyMarkup) const {
	vector<HttpReqArg> args;
	args.push_back(HttpReqArg("chat_id", chatId));
	args.push_back(HttpReqArg("video", video->data, true, video->mimeType));
	if (replyToMessageId) {
		args.push_back(HttpReqArg("reply_to_message_id", replyToMessageId));
	}
	if (replyMarkup) {
		args.push_back(HttpReqArg("reply_markup", TgTypeParser::getInstance().parseGenericReply(replyMarkup)));
	}
	return TgTypeParser::getInstance().parseJsonAndGetMessage(sendRequest("sendVideo", args));
}

Message::Ptr Api::sendVideo(int32_t chatId, const string& video, int32_t replyToMessageId, const GenericReply::Ptr& replyMarkup) const {
	vector<HttpReqArg> args;
	args.push_back(HttpReqArg("chat_id", chatId));
	args.push_back(HttpReqArg("video", video));
	if (replyToMessageId) {
		args.push_back(HttpReqArg("reply_to_message_id", replyToMessageId));
	}
	if (replyMarkup) {
		args.push_back(HttpReqArg("reply_markup", TgTypeParser::getInstance().parseGenericReply(replyMarkup)));
	}
	return TgTypeParser::getInstance().parseJsonAndGetMessage(sendRequest("sendVideo", args));
}

Message::Ptr Api::sendLocation(int32_t chatId, float latitude, float longitude, int32_t replyToMessageId, const GenericReply::Ptr& replyMarkup) const {
	vector<HttpReqArg> args;
	args.push_back(HttpReqArg("chat_id", chatId));
	args.push_back(HttpReqArg("latitude", latitude));
	args.push_back(HttpReqArg("longitude", longitude));
	if (replyToMessageId) {
		args.push_back(HttpReqArg("reply_to_message_id", replyToMessageId));
	}
	if (replyMarkup) {
		args.push_back(HttpReqArg("reply_markup", TgTypeParser::getInstance().parseGenericReply(replyMarkup)));
	}
	return TgTypeParser::getInstance().parseJsonAndGetMessage(sendRequest("sendLocation", args));
}

void Api::sendChatAction(int32_t chatId, const string& action) const {
	vector<HttpReqArg> args;
	args.push_back(HttpReqArg("chat_id", chatId));
	args.push_back(HttpReqArg("action", action));
	sendRequest("sendChatAction", args);
}

UserProfilePhotos::Ptr Api::getUserProfilePhotos(int32_t userId, int32_t offset, int32_t limit) const {
	vector<HttpReqArg> args;
	args.push_back(HttpReqArg("user_id", userId));
	if (offset) {
		args.push_back(HttpReqArg("offset", offset));
	}
	limit = max(1, min(100, limit));
	args.push_back(HttpReqArg("limit", limit));
	return TgTypeParser::getInstance().parseJsonAndGetUserProfilePhotos(sendRequest("getUserProfilePhotos", args));
}

vector<Update::Ptr> Api::getUpdates(int32_t offset, int32_t limit, int32_t timeout) const {
	vector<HttpReqArg> args;
	if (offset) {
		args.push_back(HttpReqArg("offset", offset));
	}
	limit = max(1, min(100, limit));
	args.push_back(HttpReqArg("limit", limit));
	if (timeout) {
		args.push_back(HttpReqArg("timeout", timeout));
	}
	return TgTypeParser::getInstance().parseJsonAndGetArray<Update>(&TgTypeParser::parseJsonAndGetUpdate, sendRequest("getUpdates", args), "result");
}

void Api::setWebhook(const string& url) const {
	vector<HttpReqArg> args;
	args.push_back(HttpReqArg("url", url));
	sendRequest("setWebhook", args);
}

ptree Api::sendRequest(const string& method, const vector<HttpReqArg>& args) const {
	string url = "https://api.telegram.org/bot";
	url += _token;
	url += "/";
	url += method;
	string serverResponse = HttpClient::getInstance().makeRequest(url, args);
	if (serverResponse.find("<html>") != serverResponse.npos) {
		throw TgException("Bad request");
	}
	ptree result = TgTypeParser::getInstance().parseJson(serverResponse);
	try {
		if (result.get<bool>("ok")) {
			return result.find("result")->second;
		} else {
			throw TgException(result.get("description", ""));
		}
	} catch (boost::property_tree::ptree_error& e) {
		throw TgException("");
	}
}

}
<commit_msg>Bug fix: now bot can parse messages correctly<commit_after>/*
 * Copyright (c) 2015 Oleg Morozenkov
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#include "tgbot/Api.h"

#include "tgbot/TgTypeParser.h"
#include "tgbot/TgException.h"
#include "tgbot/net/HttpClient.h"

using namespace std;
using namespace boost::property_tree;

namespace TgBot {

Api::Api(const string& token) : _token(token) {
}

User::Ptr Api::getMe() const {
	return TgTypeParser::getInstance().parseJsonAndGetUser(sendRequest("getMe"));
}

Message::Ptr Api::sendMessage(int32_t chatId, const string& text, bool disableWebPagePreview, int32_t replyToMessageId, const GenericReply::Ptr& replyMarkup) const {
	vector<HttpReqArg> args;
	args.push_back(HttpReqArg("chat_id", chatId));
	args.push_back(HttpReqArg("text", text));
	if (disableWebPagePreview) {
		args.push_back(HttpReqArg("disable_web_page_preview", disableWebPagePreview));
	}
	if (replyToMessageId) {
		args.push_back(HttpReqArg("reply_to_message_id", replyToMessageId));
	}
	if (replyMarkup) {
		args.push_back(HttpReqArg("reply_markup", TgTypeParser::getInstance().parseGenericReply(replyMarkup)));
	}
	return TgTypeParser::getInstance().parseJsonAndGetMessage(sendRequest("sendMessage", args));
}

Message::Ptr Api::forwardMessage(int32_t chatId, int32_t fromChatId, int32_t messageId) const {
	vector<HttpReqArg> args;
	args.push_back(HttpReqArg("chat_id", chatId));
	args.push_back(HttpReqArg("from_chat_id", fromChatId));
	args.push_back(HttpReqArg("message_id", messageId));
	return TgTypeParser::getInstance().parseJsonAndGetMessage(sendRequest("forwardMessage", args));
}

Message::Ptr Api::sendPhoto(int32_t chatId, const InputFile::Ptr& photo, const string& caption, int32_t replyToMessageId, const GenericReply::Ptr& replyMarkup) const {
	vector<HttpReqArg> args;
	args.push_back(HttpReqArg("chat_id", chatId));
	args.push_back(HttpReqArg("photo", photo->data, true, photo->mimeType));
	if (!caption.empty()) {
		args.push_back(HttpReqArg("caption", caption));
	}
	if (replyToMessageId) {
		args.push_back(HttpReqArg("reply_to_message_id", replyToMessageId));
	}
	if (replyMarkup) {
		args.push_back(HttpReqArg("reply_markup", TgTypeParser::getInstance().parseGenericReply(replyMarkup)));
	}
	return TgTypeParser::getInstance().parseJsonAndGetMessage(sendRequest("sendPhoto", args));
}

Message::Ptr Api::sendPhoto(int32_t chatId, const string& photo, const string& caption, int32_t replyToMessageId, const GenericReply::Ptr& replyMarkup) const {
	vector<HttpReqArg> args;
	args.push_back(HttpReqArg("chat_id", chatId));
	args.push_back(HttpReqArg("photo", photo));
	if (!caption.empty()) {
		args.push_back(HttpReqArg("caption", caption));
	}
	if (replyToMessageId) {
		args.push_back(HttpReqArg("reply_to_message_id", replyToMessageId));
	}
	if (replyMarkup) {
		args.push_back(HttpReqArg("reply_markup", TgTypeParser::getInstance().parseGenericReply(replyMarkup)));
	}
	return TgTypeParser::getInstance().parseJsonAndGetMessage(sendRequest("sendPhoto", args));
}

Message::Ptr Api::sendAudio(int32_t chatId, const InputFile::Ptr& audio, int32_t duration, int32_t replyToMessageId, const GenericReply::Ptr& replyMarkup) const {
	vector<HttpReqArg> args;
	args.push_back(HttpReqArg("chat_id", chatId));
	args.push_back(HttpReqArg("audio", audio->data, true, audio->mimeType));
	if (duration) {
		args.push_back(HttpReqArg("duration", duration));
	}
	if (replyToMessageId) {
		args.push_back(HttpReqArg("reply_to_message_id", replyToMessageId));
	}
	if (replyMarkup) {
		args.push_back(HttpReqArg("reply_markup", TgTypeParser::getInstance().parseGenericReply(replyMarkup)));
	}
	return TgTypeParser::getInstance().parseJsonAndGetMessage(sendRequest("sendAudio", args));
}

Message::Ptr Api::sendAudio(int32_t chatId, const string& audio, int32_t duration, int32_t replyToMessageId, const GenericReply::Ptr& replyMarkup) const {
	vector<HttpReqArg> args;
	args.push_back(HttpReqArg("chat_id", chatId));
	args.push_back(HttpReqArg("audio", audio));
	if (duration) {
		args.push_back(HttpReqArg("duration", duration));
	}
	if (replyToMessageId) {
		args.push_back(HttpReqArg("reply_to_message_id", replyToMessageId));
	}
	if (replyMarkup) {
		args.push_back(HttpReqArg("reply_markup", TgTypeParser::getInstance().parseGenericReply(replyMarkup)));
	}
	return TgTypeParser::getInstance().parseJsonAndGetMessage(sendRequest("sendAudio", args));
}

Message::Ptr Api::sendDocument(int32_t chatId, const InputFile::Ptr& document, int32_t replyToMessageId, const GenericReply::Ptr& replyMarkup) const {
	vector<HttpReqArg> args;
	args.push_back(HttpReqArg("chat_id", chatId));
	args.push_back(HttpReqArg("document", document->data, true, document->mimeType));
	if (replyToMessageId) {
		args.push_back(HttpReqArg("reply_to_message_id", replyToMessageId));
	}
	if (replyMarkup) {
		args.push_back(HttpReqArg("reply_markup", TgTypeParser::getInstance().parseGenericReply(replyMarkup)));
	}
	return TgTypeParser::getInstance().parseJsonAndGetMessage(sendRequest("sendDocument", args));
}

Message::Ptr Api::sendDocument(int32_t chatId, const string& document, int32_t replyToMessageId, const GenericReply::Ptr& replyMarkup) const {
	vector<HttpReqArg> args;
	args.push_back(HttpReqArg("chat_id", chatId));
	args.push_back(HttpReqArg("document", document));
	if (replyToMessageId) {
		args.push_back(HttpReqArg("reply_to_message_id", replyToMessageId));
	}
	if (replyMarkup) {
		args.push_back(HttpReqArg("reply_markup", TgTypeParser::getInstance().parseGenericReply(replyMarkup)));
	}
	return TgTypeParser::getInstance().parseJsonAndGetMessage(sendRequest("sendDocument", args));
}

Message::Ptr Api::sendSticker(int32_t chatId, const InputFile::Ptr& sticker, int32_t replyToMessageId, const GenericReply::Ptr& replyMarkup) const {
	vector<HttpReqArg> args;
	args.push_back(HttpReqArg("chat_id", chatId));
	args.push_back(HttpReqArg("sticker", sticker->data, true, sticker->mimeType));
	if (replyToMessageId) {
		args.push_back(HttpReqArg("reply_to_message_id", replyToMessageId));
	}
	if (replyMarkup) {
		args.push_back(HttpReqArg("reply_markup", TgTypeParser::getInstance().parseGenericReply(replyMarkup)));
	}
	return TgTypeParser::getInstance().parseJsonAndGetMessage(sendRequest("sendSticker", args));
}

Message::Ptr Api::sendSticker(int32_t chatId, const string& sticker, int32_t replyToMessageId, const GenericReply::Ptr& replyMarkup) const {
	vector<HttpReqArg> args;
	args.push_back(HttpReqArg("chat_id", chatId));
	args.push_back(HttpReqArg("sticker", sticker));
	if (replyToMessageId) {
		args.push_back(HttpReqArg("reply_to_message_id", replyToMessageId));
	}
	if (replyMarkup) {
		args.push_back(HttpReqArg("reply_markup", TgTypeParser::getInstance().parseGenericReply(replyMarkup)));
	}
	return TgTypeParser::getInstance().parseJsonAndGetMessage(sendRequest("sendSticker", args));
}

Message::Ptr Api::sendVideo(int32_t chatId, const InputFile::Ptr& video, int32_t replyToMessageId, const GenericReply::Ptr& replyMarkup) const {
	vector<HttpReqArg> args;
	args.push_back(HttpReqArg("chat_id", chatId));
	args.push_back(HttpReqArg("video", video->data, true, video->mimeType));
	if (replyToMessageId) {
		args.push_back(HttpReqArg("reply_to_message_id", replyToMessageId));
	}
	if (replyMarkup) {
		args.push_back(HttpReqArg("reply_markup", TgTypeParser::getInstance().parseGenericReply(replyMarkup)));
	}
	return TgTypeParser::getInstance().parseJsonAndGetMessage(sendRequest("sendVideo", args));
}

Message::Ptr Api::sendVideo(int32_t chatId, const string& video, int32_t replyToMessageId, const GenericReply::Ptr& replyMarkup) const {
	vector<HttpReqArg> args;
	args.push_back(HttpReqArg("chat_id", chatId));
	args.push_back(HttpReqArg("video", video));
	if (replyToMessageId) {
		args.push_back(HttpReqArg("reply_to_message_id", replyToMessageId));
	}
	if (replyMarkup) {
		args.push_back(HttpReqArg("reply_markup", TgTypeParser::getInstance().parseGenericReply(replyMarkup)));
	}
	return TgTypeParser::getInstance().parseJsonAndGetMessage(sendRequest("sendVideo", args));
}

Message::Ptr Api::sendLocation(int32_t chatId, float latitude, float longitude, int32_t replyToMessageId, const GenericReply::Ptr& replyMarkup) const {
	vector<HttpReqArg> args;
	args.push_back(HttpReqArg("chat_id", chatId));
	args.push_back(HttpReqArg("latitude", latitude));
	args.push_back(HttpReqArg("longitude", longitude));
	if (replyToMessageId) {
		args.push_back(HttpReqArg("reply_to_message_id", replyToMessageId));
	}
	if (replyMarkup) {
		args.push_back(HttpReqArg("reply_markup", TgTypeParser::getInstance().parseGenericReply(replyMarkup)));
	}
	return TgTypeParser::getInstance().parseJsonAndGetMessage(sendRequest("sendLocation", args));
}

void Api::sendChatAction(int32_t chatId, const string& action) const {
	vector<HttpReqArg> args;
	args.push_back(HttpReqArg("chat_id", chatId));
	args.push_back(HttpReqArg("action", action));
	sendRequest("sendChatAction", args);
}

UserProfilePhotos::Ptr Api::getUserProfilePhotos(int32_t userId, int32_t offset, int32_t limit) const {
	vector<HttpReqArg> args;
	args.push_back(HttpReqArg("user_id", userId));
	if (offset) {
		args.push_back(HttpReqArg("offset", offset));
	}
	limit = max(1, min(100, limit));
	args.push_back(HttpReqArg("limit", limit));
	return TgTypeParser::getInstance().parseJsonAndGetUserProfilePhotos(sendRequest("getUserProfilePhotos", args));
}

vector<Update::Ptr> Api::getUpdates(int32_t offset, int32_t limit, int32_t timeout) const {
	vector<HttpReqArg> args;
	if (offset) {
		args.push_back(HttpReqArg("offset", offset));
	}
	limit = max(1, min(100, limit));
	args.push_back(HttpReqArg("limit", limit));
	if (timeout) {
		args.push_back(HttpReqArg("timeout", timeout));
	}
	return TgTypeParser::getInstance().parseJsonAndGetArray<Update>(&TgTypeParser::parseJsonAndGetUpdate, sendRequest("getUpdates", args), "result");
}

void Api::setWebhook(const string& url) const {
	vector<HttpReqArg> args;
	args.push_back(HttpReqArg("url", url));
	sendRequest("setWebhook", args);
}

ptree Api::sendRequest(const string& method, const vector<HttpReqArg>& args) const {
	string url = "https://api.telegram.org/bot";
	url += _token;
	url += "/";
	url += method;
	string serverResponse = HttpClient::getInstance().makeRequest(url, args);
	if (serverResponse.find("<html>") != serverResponse.npos) {
		throw TgException("Bad request");
	}
	ptree result = TgTypeParser::getInstance().parseJson(serverResponse);
	try {
		if (result.get<bool>("ok")) {
            if(method != "getMe" && method != "sendMessage")
                return result;
            else
                return result.find("result")->second;
		} else {
			throw TgException(result.get("description", ""));
		}
	} catch (boost::property_tree::ptree_error& e) {
		throw TgException("");
	}
}

}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: out_node.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: vg $ $Date: 2007-09-18 14:04:03 $
 *
 *  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
 *
 ************************************************************************/

#include <precomp.h>
#include <toolkit/out_node.hxx>

// NOT FULLY DEFINED SERVICES
#include <algorithm>

namespace output
{

namespace
{

struct Less_NodePtr
{
    bool                operator()(
                            Node *              p1,
                            Node *              p2 ) const
                        { return p1->Name() < p2->Name(); }
};

struct Less_NodePtr     C_Less_NodePtr;

Node  C_aNullNode(Node::null_object);

}   // namepace anonymous

//**********************        Node        ***************************//

Node::Node()
    :   sName(),
          pParent(0),
          aChildren(),
          nDepth(0),
          nNameRoomId(0)
{
}

Node::Node( E_NullObject )
    :   sName(),
          pParent(0),
          aChildren(),
          nDepth(-1),
          nNameRoomId(0)
{
}

Node::Node( const String &  i_name,
            Node &          i_parent )
    :   sName(i_name),
        pParent(&i_parent),
        aChildren(),
        nDepth(i_parent.Depth()+1),
          nNameRoomId(0)
{
}

Node::~Node()
{
    for ( List::iterator it = aChildren.begin();
          it != aChildren.end();
          ++it )
    {
        delete *it;
    }
}

Node &
Node::Provide_Child( const String & i_name )
{
    Node * ret = find_Child(i_name);
    if (ret != 0)
        return *ret;
    return add_Child(i_name);
}

void
Node::Get_Path( StreamStr &         o_result,
                intt                i_maxDepth ) const
{
    // Intentionally 'i_maxDepth != 0', so max_Depth == -1 sets no limit:
    if (i_maxDepth != 0)
    {
        if (pParent != 0)
            pParent->Get_Path(o_result, i_maxDepth-1);
        o_result << sName << '/';
    }
}

void
Node::Get_Chain( StringVector & o_result,
                 intt           i_maxDepth ) const
{
    if (i_maxDepth != 0)
    {
        // This is called also for the toplevel Node,
        //   but there happens nothing:
        if (pParent != 0)
        {
            pParent->Get_Chain(o_result, i_maxDepth-1);
            o_result.push_back(sName);
        }
    }
}

Node *
Node::find_Child( const String & i_name )
{
    // Trying to optimise search in a vector:

    uintt nSize = aChildren.size();
    if ( nSize > 0 AND nSize < 20 )
    {
        List::const_iterator it = aChildren.begin();
        List::const_iterator itMiddle = it + nSize/2;
        int comp = 0;

        if ( i_name < (*itMiddle)->Name() )
        {
            for ( ;
                  it != itMiddle
                        ? (comp = csv::compare(i_name, (*it)->Name())) <= 0
                        : false;
                  ++it )
            {
                if ( comp == 0 )
                    return *it;
            }   // end for
        }
        else
        {
            List::const_iterator itEnd = aChildren.end();
            for ( it = itMiddle;
                  it != itEnd
                        ? (comp = csv::compare(i_name, (*it)->Name())) <= 0
                        : false;
                  ++it )
            {
                if ( comp == 0 )
                    return *it;
            }   // end for
        }
    }
    else if (nSize > 0)
    {
        Node aSearch;
        aSearch.sName = i_name;

        List::const_iterator
            ret = std::lower_bound( aChildren.begin(),
                                    aChildren.end(),
                                    &aSearch,
                                    C_Less_NodePtr );
        if ( ret != aChildren.end() ? (*ret)->Name() == i_name : false )
            return *ret;
    }

    return 0;
}

Node &
Node::add_Child( const String & i_name )
{
    DYN Node * pNew = new Node(i_name,*this);
    aChildren.insert( std::upper_bound( aChildren.begin(),
                                        aChildren.end(),
                                        pNew,
                                        C_Less_NodePtr ),
                      pNew );
    return *pNew;
}

Node &
Node::provide_Child( StringVector::const_iterator i_next,
                       StringVector::const_iterator i_end )
{
    if (i_next == i_end)
        return *this;
    return Provide_Child(*i_next).provide_Child(i_next+1,i_end);
}

Node &
Node::Null_()
{
    return C_aNullNode;
}

}   // namespace output
<commit_msg>INTEGRATION: CWS adc18 (1.5.2); FILE MERGED 2007/10/18 15:23:15 np 1.5.2.1: #i81775#<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: out_node.cxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: hr $ $Date: 2007-11-02 16:42:12 $
 *
 *  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
 *
 ************************************************************************/

#include <precomp.h>
#include <toolkit/out_node.hxx>

// NOT FULLY DEFINED SERVICES
#include <algorithm>

namespace output
{

namespace
{

struct Less_NodePtr
{
    bool                operator()(
                            Node *              p1,
                            Node *              p2 ) const
                        { return p1->Name() < p2->Name(); }
};

struct Less_NodePtr     C_Less_NodePtr;

Node  C_aNullNode(Node::null_object);

}   // namepace anonymous

//**********************        Node        ***************************//

Node::Node()
    :   sName(),
          pParent(0),
          aChildren(),
          nDepth(0),
          nNameRoomId(0)
{
}

Node::Node( E_NullObject )
    :   sName(),
          pParent(0),
          aChildren(),
          nDepth(-1),
          nNameRoomId(0)
{
}

Node::Node( const String &  i_name,
            Node &          i_parent )
    :   sName(i_name),
        pParent(&i_parent),
        aChildren(),
        nDepth(i_parent.Depth()+1),
          nNameRoomId(0)
{
}

Node::~Node()
{
    for ( List::iterator it = aChildren.begin();
          it != aChildren.end();
          ++it )
    {
        delete *it;
    }
}

Node &
Node::Provide_Child( const String & i_name )
{
    Node *
        ret = find_Child(i_name);
    if (ret != 0)
        return *ret;
    return add_Child(i_name);
}

void
Node::Get_Path( StreamStr &         o_result,
                intt                i_maxDepth ) const
{
    // Intentionally 'i_maxDepth != 0', so max_Depth == -1 sets no limit:
    if (i_maxDepth != 0)
    {
        if (pParent != 0)
            pParent->Get_Path(o_result, i_maxDepth-1);
        o_result << sName << '/';
    }
}

void
Node::Get_Chain( StringVector & o_result,
                 intt           i_maxDepth ) const
{
    if (i_maxDepth != 0)
    {
        // This is called also for the toplevel Node,
        //   but there happens nothing:
        if (pParent != 0)
        {
            pParent->Get_Chain(o_result, i_maxDepth-1);
            o_result.push_back(sName);
        }
    }
}

Node *
Node::find_Child( const String & i_name )
{
    Node aSearch;
    aSearch.sName = i_name;

    List::const_iterator
        ret = std::lower_bound( aChildren.begin(),
                                aChildren.end(),
                                &aSearch,
                                C_Less_NodePtr );
    if ( ret != aChildren.end() ? (*ret)->Name() == i_name : false )
        return *ret;

    return 0;
}

Node &
Node::add_Child( const String & i_name )
{
    DYN Node *
        pNew = new Node(i_name,*this);
    aChildren.insert( std::lower_bound( aChildren.begin(),
                                        aChildren.end(),
                                        pNew,
                                        C_Less_NodePtr ),
                      pNew );
    return *pNew;
}

Node &
Node::provide_Child( StringVector::const_iterator i_next,
                       StringVector::const_iterator i_end )
{
    if (i_next == i_end)
        return *this;
    return Provide_Child(*i_next).provide_Child(i_next+1,i_end);
}

Node &
Node::Null_()
{
    return C_aNullNode;
}

}   // namespace output
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: expop2.cxx,v $
 *
 *  $Revision: 1.25 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 18:57:15 $
 *
 *  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
 *
 ************************************************************************/

#ifdef PCH
#include "filt_pch.hxx"
#endif

#pragma hdrstop

//------------------------------------------------------------------------

#include <svtools/fltrcfg.hxx>

#include <sfx2/objsh.hxx>
#include <sfx2/docinf.hxx>
#include <svx/svxmsbas.hxx>

#include "scerrors.hxx"
#include "scextopt.hxx"

#include "root.hxx"
#include "exp_op.hxx"
#include "excdoc.hxx"

#include "xcl97esc.hxx"

#include "document.hxx"
#include "rangenam.hxx"
#include "filtopt.hxx"

#ifndef SC_XLTOOLS_HXX
#include "xltools.hxx"
#endif
#ifndef SC_XELINK_HXX
#include "xelink.hxx"
#endif

ExportBiff5::ExportBiff5( XclExpRootData& rExpData ):
    ExportTyp( rExpData.mrBookStrm, &rExpData.mrDoc, rExpData.meCharSet ),
    XclExpRoot( rExpData )
{
    // nur Teil der Root-Daten gebraucht
    pExcRoot = &GetOldRoot();
    pExcRoot->pER = this;   // ExcRoot -> XclExpRoot
    pExcRoot->eDateiTyp = Biff5;
    pExcDoc = new ExcDocument( *this );
}

ExportBiff5::~ExportBiff5()
{
    delete pExcDoc;
}

FltError ExportBiff5::Write()
{
    FltError                eRet = eERR_OK;

    SfxObjectShell* pDocShell = GetDocShell();
    DBG_ASSERT( pDocShell, "ExportBiff5::Write - no document shell" );

    SotStorageRef xRootStrg = GetRootStorage();
    DBG_ASSERT( xRootStrg.Is(), "ExportBiff5::Write - no root storage" );

    bool bWriteBasicCode = false;
    bool bWriteBasicStrg = false;
    if( GetBiff() == EXC_BIFF8 )
    {
        if( SvtFilterOptions* pFilterOpt = SvtFilterOptions::Get() )
        {
            bWriteBasicCode = pFilterOpt->IsLoadExcelBasicCode();
            bWriteBasicStrg = pFilterOpt->IsLoadExcelBasicStorage();
        }
    }

    if( pDocShell && xRootStrg.Is() && bWriteBasicStrg )
    {
        SvxImportMSVBasic aBasicImport( *pDocShell, *xRootStrg, bWriteBasicCode, bWriteBasicStrg );
        ULONG nErr = aBasicImport.SaveOrDelMSVBAStorage( TRUE, EXC_STORAGE_VBA_PROJECT );
        if( nErr != ERRCODE_NONE )
            pDocShell->SetError( nErr );
    }

    pExcDoc->ReadDoc();         // ScDoc -> ExcDoc
    pExcDoc->Write( aOut );     // wechstreamen

    if( pDocShell && xRootStrg.Is() )
    {
        SfxDocumentInfo& rInfo = pDocShell->GetDocInfo();
        rInfo.SavePropertySet( xRootStrg );
    }

    //! TODO: separate warnings for columns and sheets
    const XclExpAddressConverter& rAddrConv = GetAddressConverter();
    if( rAddrConv.IsColTruncated() || rAddrConv.IsRowTruncated() || rAddrConv.IsTabTruncated() )
        return SCWARN_EXPORT_MAXROW;

    return eERR_OK;
}

ExportBiff8::ExportBiff8( XclExpRootData& rExpData ) :
    ExportBiff5( rExpData )
{
    pExcRoot->eDateiTyp = Biff8;
    pExcRoot->pEscher = new XclEscher( GetDoc().GetTableCount(), *pExcRoot );
}

ExportBiff8::~ExportBiff8()
{
    delete pExcRoot->pEscher;
    pExcRoot->pEscher = NULL;
}

<commit_msg>INTEGRATION: CWS dr46 (1.25.106); FILE MERGED 2006/02/16 12:55:24 dr 1.25.106.1: new file dumper, remove unused member mrBookStrm from root data<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: expop2.cxx,v $
 *
 *  $Revision: 1.26 $
 *
 *  last change: $Author: obo $ $Date: 2006-03-22 12:00:04 $
 *
 *  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
 *
 ************************************************************************/

#ifdef PCH
#include "filt_pch.hxx"
#endif

#pragma hdrstop

//------------------------------------------------------------------------

#include <svtools/fltrcfg.hxx>

#include <sfx2/objsh.hxx>
#include <sfx2/docinf.hxx>
#include <svx/svxmsbas.hxx>

#include "scerrors.hxx"
#include "scextopt.hxx"

#include "root.hxx"
#include "exp_op.hxx"
#include "excdoc.hxx"

#include "xcl97esc.hxx"

#include "document.hxx"
#include "rangenam.hxx"
#include "filtopt.hxx"

#ifndef SC_XLTOOLS_HXX
#include "xltools.hxx"
#endif
#ifndef SC_XELINK_HXX
#include "xelink.hxx"
#endif

ExportBiff5::ExportBiff5( XclExpRootData& rExpData, SvStream& rStrm ):
    ExportTyp( rStrm, &rExpData.mrDoc, rExpData.meCharSet ),
    XclExpRoot( rExpData )
{
    // nur Teil der Root-Daten gebraucht
    pExcRoot = &GetOldRoot();
    pExcRoot->pER = this;   // ExcRoot -> XclExpRoot
    pExcRoot->eDateiTyp = Biff5;
    pExcDoc = new ExcDocument( *this );
}

ExportBiff5::~ExportBiff5()
{
    delete pExcDoc;
}

FltError ExportBiff5::Write()
{
    FltError                eRet = eERR_OK;

    SfxObjectShell* pDocShell = GetDocShell();
    DBG_ASSERT( pDocShell, "ExportBiff5::Write - no document shell" );

    SotStorageRef xRootStrg = GetRootStorage();
    DBG_ASSERT( xRootStrg.Is(), "ExportBiff5::Write - no root storage" );

    bool bWriteBasicCode = false;
    bool bWriteBasicStrg = false;
    if( GetBiff() == EXC_BIFF8 )
    {
        if( SvtFilterOptions* pFilterOpt = SvtFilterOptions::Get() )
        {
            bWriteBasicCode = pFilterOpt->IsLoadExcelBasicCode();
            bWriteBasicStrg = pFilterOpt->IsLoadExcelBasicStorage();
        }
    }

    if( pDocShell && xRootStrg.Is() && bWriteBasicStrg )
    {
        SvxImportMSVBasic aBasicImport( *pDocShell, *xRootStrg, bWriteBasicCode, bWriteBasicStrg );
        ULONG nErr = aBasicImport.SaveOrDelMSVBAStorage( TRUE, EXC_STORAGE_VBA_PROJECT );
        if( nErr != ERRCODE_NONE )
            pDocShell->SetError( nErr );
    }

    pExcDoc->ReadDoc();         // ScDoc -> ExcDoc
    pExcDoc->Write( aOut );     // wechstreamen

    if( pDocShell && xRootStrg.Is() )
    {
        SfxDocumentInfo& rInfo = pDocShell->GetDocInfo();
        rInfo.SavePropertySet( xRootStrg );
    }

    //! TODO: separate warnings for columns and sheets
    const XclExpAddressConverter& rAddrConv = GetAddressConverter();
    if( rAddrConv.IsColTruncated() || rAddrConv.IsRowTruncated() || rAddrConv.IsTabTruncated() )
        return SCWARN_EXPORT_MAXROW;

    return eERR_OK;
}

ExportBiff8::ExportBiff8( XclExpRootData& rExpData, SvStream& rStrm ) :
    ExportBiff5( rExpData, rStrm )
{
    pExcRoot->eDateiTyp = Biff8;
    pExcRoot->pEscher = new XclEscher( GetDoc().GetTableCount(), *pExcRoot );
}

ExportBiff8::~ExportBiff8()
{
    delete pExcRoot->pEscher;
    pExcRoot->pEscher = NULL;
}

<|endoftext|>