<commit_before>/*******************************
Copyright (C) 2013-2015 gregoire ANGERAND

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
**********************************/

#include "RenderQueue.h"
#include <iostream>

namespace n {
namespace graphics {

uint exp(float f) {
	void *p = &f;
	return (*(uint *)p) >> 23;
}

RenderQueue::RenderQueue() {
}

void RenderQueue::insert(const core::Functor<void(RenderFlag)> &f) {
	funcs.append(f);
}

void RenderQueue::insert(const core::Functor<void()> &f) {
	funcs.append([=](RenderFlag) {
		f();
	});
}

void RenderQueue::insert(const math::Matrix4<> &t, const MeshInstance &m) {
	for(SubMeshInstance *base : m) {
		insert(RenderBatch(t, base));
	}
}

void RenderQueue::insert(const RenderBatch &b) {
	(b.isDepthSorted() ? sortable : notSortable).append(b);
}

void RenderQueue::prepare(math::Vec3 cpos, float max) {
	uint size = exp(max + 1) - exp(1);
	core::Array<RenderBatch> *buckets = new core::Array<RenderBatch>[size];

	for(const RenderBatch &b : sortable) {
		math::Vec3 v = (b.getMatrix() * math::Vec4(0, 0, 0, 1)).sub(3);
		float dist = std::max((cpos - v).length() - b.getVertexArrayObject().getRadius(), 0.0f);
		buckets[exp(dist + 1) - exp(1)].append(b);
	}
	sortable.makeEmpty();
	for(uint i = 0; i != size; i++) {
		buckets[i].sort();
		sortable.append(buckets[i]);
	}
	delete[] buckets;
	notSortable.sort();
}

void RenderQueue::operator()(RenderFlag flags) {
	for(const RenderBatch &b : sortable) {
		b(flags);
	}
	for(const RenderBatch &b : notSortable) {
		b(flags);
	}
	for(const core::Functor<void(RenderFlag)> &f : funcs) {
		f(flags);
	}
}

}
}
<commit_msg>Fixed a crash when leaving the scene.<commit_after>/*******************************
Copyright (C) 2013-2015 gregoire ANGERAND

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
**********************************/

#include "RenderQueue.h"
#include <iostream>

namespace n {
namespace graphics {

uint exp(float f) {
	void *p = &f;
	return (*(uint *)p) >> 23;
}

RenderQueue::RenderQueue() {
}

void RenderQueue::insert(const core::Functor<void(RenderFlag)> &f) {
	funcs.append(f);
}

void RenderQueue::insert(const core::Functor<void()> &f) {
	funcs.append([=](RenderFlag) {
		f();
	});
}

void RenderQueue::insert(const math::Matrix4<> &t, const MeshInstance &m) {
	for(SubMeshInstance *base : m) {
		insert(RenderBatch(t, base));
	}
}

void RenderQueue::insert(const RenderBatch &b) {
	(b.isDepthSorted() ? sortable : notSortable).append(b);
}

void RenderQueue::prepare(math::Vec3 cpos, float max) {
	uint size = exp(max + 1) - exp(1);
	core::Array<RenderBatch> *buckets = new core::Array<RenderBatch>[size];

	for(const RenderBatch &b : sortable) {
		math::Vec3 v = (b.getMatrix() * math::Vec4(0, 0, 0, 1)).sub(3);
		float dist = std::max((cpos - v).length() - b.getVertexArrayObject().getRadius(), 0.0f);
		uint index = exp(dist + 1) - exp(1);
		if(index < size) {
			buckets[index].append(b);
		}
	}
	sortable.makeEmpty();
	for(uint i = 0; i != size; i++) {
		buckets[i].sort();
		sortable.append(buckets[i]);
	}
	delete[] buckets;
	notSortable.sort();
}

void RenderQueue::operator()(RenderFlag flags) {
	for(const RenderBatch &b : sortable) {
		b(flags);
	}
	for(const RenderBatch &b : notSortable) {
		b(flags);
	}
	for(const core::Functor<void(RenderFlag)> &f : funcs) {
		f(flags);
	}
}

}
}
<|endoftext|>


<commit_before>#include <iostream>
#include <ctime>
using namespace std;
const int N = 20;
inline void findConflicts(int queenStates[], int addValues[], int subtractValues[], int& conflicts) {
	//int conflicts = 0;
	conflicts = 0;
	static int i;
	static int j;
	for (i = 0; i < N; i++) {
		for (j = 0; j < N; j++) {
			if (i == j) continue;
			if (queenStates[i] == queenStates[j])
				conflicts++;
			if (addValues[i] == addValues[j])
				conflicts++;
			if (subtractValues[i] == subtractValues[j])
				conflicts++;
		}
	}
	//return conflicts;
}

int main() {

	srand(time(NULL));
	int currentQueenStates[N], tempQueens[N];
	int currentConflicts, tempConflicts;
	int addValues[N];
	int subtractValues[N];
	int col, row;
	bool generateRandomState = true; // do we have to restart climbing with another randomly generated initial QueenPositions
	unsigned long count = 0;
	int i;
	while (generateRandomState) {
		count++;
		cout << count << "\t";
		for (col = 0; col < N; col++) {
			currentQueenStates[col] = rand() % N;
			addValues[col] = currentQueenStates[col] + col;
			subtractValues[col] = currentQueenStates[col] - col;
		}

		findConflicts(currentQueenStates, addValues, subtractValues, currentConflicts);
		for (i = 0; i < N; i++) {
			tempQueens[i] = currentQueenStates[i];
			addValues[i] = tempQueens[i] + i;
			subtractValues[i] = tempQueens[i] - i;
		}
		while (currentConflicts > 0) {
			bool newState = false;
			for (col = 0; col < N; col++) {
				for (row = 0; row < N; row++) {

					if (currentQueenStates[col] != row) {
						tempQueens[col] = row;
						addValues[col] = tempQueens[col] + col;
						subtractValues[col] = tempQueens[col] - col;
						findConflicts(tempQueens, addValues, subtractValues, tempConflicts);
						if (tempConflicts < currentConflicts) {
							//	for (i = 0; i < N; i++) {
							//	currentQueenStates[i] = tempQueens[i];
							//}
							currentQueenStates[col] = row;
							newState = true;
							break;
						}
						else {
							tempQueens[col] = currentQueenStates[col];
							addValues[col] = tempQueens[col] + col;
							subtractValues[col] = tempQueens[col] - col;
						}
					}
				}
				if (newState)
					break;
			}
			if (!newState) {
				//count++;
				//cout << count << "\t";
				//cout << "Stuck in Local minimum(for cost). Every move of a single queen increases conflicts.\n"
				//	<< "State space with local minimum is given below:" << endl;
				break;
			}
			findConflicts(currentQueenStates, addValues, subtractValues, currentConflicts);
		}
		if (currentConflicts == 0)
			generateRandomState = false;

	}

	//char *board[N] = { "----",  "----", "----", "----" };
	int queenPositions[N];
	for (col = 0; col < N; col++) {
		queenPositions[currentQueenStates[col]] = col;
	}
	cout << endl;
	for (row = 0; row < N; row++) {
		for (col = 0; col < queenPositions[row]; col++) {
			cout << "-";
		}
		cout << "+";
		for (col = queenPositions[row]+1; col < N; col++) {
			cout << "-";
		}
		cout << endl;
	}

	//cout << rand() % 10 << "  "<< rand() % 10 << endl;
	cout << endl;
	system("pause");
	return 0;
}<commit_msg>Dynamic allocation with new opr applied and value of N from user.<commit_after>#include <iostream>
#include <ctime>
using namespace std;

inline void findConflicts(int queenStates[], int addValues[], int subtractValues[], int& conflicts, int& noOfQueens) {
	//int conflicts = 0;
	conflicts = 0;
	static int i;
	static int j;
	for (i = 0; i < noOfQueens; i++) {
		for (j = 0; j < noOfQueens; j++) {
			if (i == j) continue;
			if (queenStates[i] == queenStates[j])
				conflicts++;
			if (addValues[i] == addValues[j])
				conflicts++;
			if (subtractValues[i] == subtractValues[j])
				conflicts++;
		}
	}
	//return conflicts;
}

int main() {
	int col, row;
	srand(time(NULL));
	bool generateRandomState = true; // do we have to restart climbing with another randomly generated initial QueenPositions
	unsigned long count = 0;
	int i;
	int currentConflicts, tempConflicts;
	int N = 0;

	do {
		cout << "Enter No. of queen(n) for solution of n-queen problem: ";
		cin >> N;
		if (N < 4) {
			cout << "\nEnter value of N greater than 3." << endl;
		}
	} while (N < 4);

	int* currentQueenStates = new int[N];
	int* tempQueens = new int[N];
	int* addValues = new int[N];
	int* subtractValues = new int[N];

	while (generateRandomState) {
		count++;
		cout << count << "\t";
		for (col = 0; col < N; col++) {
			currentQueenStates[col] = rand() % N;
			addValues[col] = currentQueenStates[col] + col;
			subtractValues[col] = currentQueenStates[col] - col;
		}

		findConflicts(currentQueenStates, addValues, subtractValues, currentConflicts, N);
		for (i = 0; i < N; i++) {
			tempQueens[i] = currentQueenStates[i];
			addValues[i] = tempQueens[i] + i;
			subtractValues[i] = tempQueens[i] - i;
		}
		while (currentConflicts > 0) {
			bool newState = false;
			for (col = 0; col < N; col++) {
				for (row = 0; row < N; row++) {

					if (currentQueenStates[col] != row) {
						tempQueens[col] = row;
						addValues[col] = tempQueens[col] + col;
						subtractValues[col] = tempQueens[col] - col;
						findConflicts(tempQueens, addValues, subtractValues, tempConflicts, N);
						if (tempConflicts < currentConflicts) {
							//	for (i = 0; i < N; i++) {
							//	currentQueenStates[i] = tempQueens[i];
							//}
							currentQueenStates[col] = row;
							newState = true;
							break;
						}
						else {
							tempQueens[col] = currentQueenStates[col];
							addValues[col] = tempQueens[col] + col;
							subtractValues[col] = tempQueens[col] - col;
						}
					}
				}
				if (newState)
					break;
			}
			if (!newState) {
				//count++;
				//cout << count << "\t";
				//cout << "Stuck in Local minimum(for cost). Every move of a single queen increases conflicts.\n"
				//	<< "State space with local minimum is given below:" << endl;
				break;
			}
			findConflicts(currentQueenStates, addValues, subtractValues, currentConflicts, N);
		}
		if (currentConflicts == 0)
			generateRandomState = false;

	}

	//char *board[N] = { "----",  "----", "----", "----" };
	int* queenPositions = new int[N];
	for (col = 0; col < N; col++) {
		queenPositions[currentQueenStates[col]] = col;
	}
	cout << endl;
	for (row = 0; row < N; row++) {
		for (col = 0; col < queenPositions[row]; col++) {
			cout << "-";
		}
		cout << "+";
		for (col = queenPositions[row]+1; col < N; col++) {
			cout << "-";
		}
		cout << endl;
	}

	//cout << rand() % 10 << "  "<< rand() % 10 << endl;
	cout << endl;
	system("pause");
	return 0;
}<|endoftext|>


<commit_before>/*
	This file is part of solidity.

	solidity is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	solidity 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 General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with solidity.  If not, see <http://www.gnu.org/licenses/>.
*/
/**
 * @author Christian <c@ethdev.com>
 * @date 2015
 * Tests for high level features like import.
 */

#include <string>
#include <boost/test/unit_test.hpp>
#include <libsolidity/interface/Exceptions.h>
#include <libsolidity/interface/CompilerStack.h>

using namespace std;

namespace dev
{
namespace solidity
{
namespace test
{

BOOST_AUTO_TEST_SUITE(SolidityImports)

BOOST_AUTO_TEST_CASE(smoke_test)
{
	CompilerStack c;
	c.addSource("a", "contract C {} pragma solidity >=0.0;");
	BOOST_CHECK(c.compile());
}

BOOST_AUTO_TEST_CASE(regular_import)
{
	CompilerStack c;
	c.addSource("a", "contract C {} pragma solidity >=0.0;");
	c.addSource("b", "import \"a\"; contract D is C {} pragma solidity >=0.0;");
	BOOST_CHECK(c.compile());
}

BOOST_AUTO_TEST_CASE(import_does_not_clutter_importee)
{
	CompilerStack c;
	c.addSource("a", "contract C { D d; } pragma solidity >=0.0;");
	c.addSource("b", "import \"a\"; contract D is C {} pragma solidity >=0.0;");
	BOOST_CHECK(!c.compile());
}

BOOST_AUTO_TEST_CASE(import_is_transitive)
{
	CompilerStack c;
	c.addSource("a", "contract C { } pragma solidity >=0.0;");
	c.addSource("b", "import \"a\"; pragma solidity >=0.0;");
	c.addSource("c", "import \"b\"; contract D is C {} pragma solidity >=0.0;");
	BOOST_CHECK(c.compile());
}

BOOST_AUTO_TEST_CASE(circular_import)
{
	CompilerStack c;
	c.addSource("a", "import \"b\"; contract C { D d; } pragma solidity >=0.0;");
	c.addSource("b", "import \"a\"; contract D { C c; } pragma solidity >=0.0;");
	BOOST_CHECK(c.compile());
}

BOOST_AUTO_TEST_CASE(relative_import)
{
	CompilerStack c;
	c.addSource("a", "import \"./dir/b\"; contract A is B {} pragma solidity >=0.0;");
	c.addSource("dir/b", "contract B {} pragma solidity >=0.0;");
	c.addSource("dir/c", "import \"../a\"; contract C is A {} pragma solidity >=0.0;");
	BOOST_CHECK(c.compile());
}

BOOST_AUTO_TEST_CASE(relative_import_multiplex)
{
	CompilerStack c;
	c.addSource("a", "contract A {} pragma solidity >=0.0;");
	c.addSource("dir/a/b/c", "import \"../../.././a\"; contract B is A {} pragma solidity >=0.0;");
	BOOST_CHECK(c.compile());
}

BOOST_AUTO_TEST_CASE(simple_alias)
{
	CompilerStack c;
	c.addSource("a", "contract A {} pragma solidity >=0.0;");
	c.addSource("dir/a/b/c", "import \"../../.././a\" as x; contract B is x.A { function() { x.A r = x.A(20); } } pragma solidity >=0.0;");
	BOOST_CHECK(c.compile());
}

BOOST_AUTO_TEST_CASE(library_name_clash)
{
	CompilerStack c;
	c.addSource("a", "library A {} pragma solidity >=0.0;");
	c.addSource("b", "library A {} pragma solidity >=0.0;");
	BOOST_CHECK(!c.compile());
}

BOOST_AUTO_TEST_CASE(library_name_clash_with_contract)
{
	CompilerStack c;
	c.addSource("a", "contract A {} pragma solidity >=0.0;");
	c.addSource("b", "library A {} pragma solidity >=0.0;");
	BOOST_CHECK(c.compile());
}

BOOST_AUTO_TEST_CASE(complex_import)
{
	CompilerStack c;
	c.addSource("a", "contract A {} contract B {} contract C { struct S { uint a; } } pragma solidity >=0.0;");
	c.addSource("b", "import \"a\" as x; import {B as b, C as c, C} from \"a\"; "
				"contract D is b { function f(c.S var1, x.C.S var2, C.S var3) internal {} } pragma solidity >=0.0;");
	BOOST_CHECK(c.compile());
}

BOOST_AUTO_TEST_CASE(name_clash_in_import)
{
	CompilerStack c;
	c.addSource("a", "contract A {} pragma solidity >=0.0;");
	c.addSource("b", "import \"a\"; contract A {} pragma solidity >=0.0;");
	BOOST_CHECK(!c.compile());
	c.addSource("b", "import \"a\" as A; contract A {} pragma solidity >=0.0;");
	BOOST_CHECK(!c.compile());
	c.addSource("b", "import {A as b} from \"a\"; contract b {} pragma solidity >=0.0;");
	BOOST_CHECK(!c.compile());
	c.addSource("b", "import {A} from \"a\"; contract A {} pragma solidity >=0.0;");
	BOOST_CHECK(!c.compile());
	c.addSource("b", "import {A} from \"a\"; contract B {} pragma solidity >=0.0;");
	BOOST_CHECK(c.compile());
}

BOOST_AUTO_TEST_CASE(remappings)
{
	CompilerStack c;
	c.setRemappings(vector<string>{"s=s_1.4.6", "t=Tee"});
	c.addSource("a", "import \"s/s.sol\"; contract A is S {} pragma solidity >=0.0;");
	c.addSource("b", "import \"t/tee.sol\"; contract A is Tee {} pragma solidity >=0.0;");
	c.addSource("s_1.4.6/s.sol", "contract S {} pragma solidity >=0.0;");
	c.addSource("Tee/tee.sol", "contract Tee {} pragma solidity >=0.0;");
	BOOST_CHECK(c.compile());
}

BOOST_AUTO_TEST_CASE(context_dependent_remappings)
{
	CompilerStack c;
	c.setRemappings(vector<string>{"a:s=s_1.4.6", "b:s=s_1.4.7"});
	c.addSource("a/a.sol", "import \"s/s.sol\"; contract A is SSix {} pragma solidity >=0.0;");
	c.addSource("b/b.sol", "import \"s/s.sol\"; contract B is SSeven {} pragma solidity >=0.0;");
	c.addSource("s_1.4.6/s.sol", "contract SSix {} pragma solidity >=0.0;");
	c.addSource("s_1.4.7/s.sol", "contract SSeven {} pragma solidity >=0.0;");
	BOOST_CHECK(c.compile());
}

BOOST_AUTO_TEST_SUITE_END()

}
}
} // end namespaces
<commit_msg>test: add a test importing a file name starting with a period<commit_after>/*
	This file is part of solidity.

	solidity is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	solidity 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 General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with solidity.  If not, see <http://www.gnu.org/licenses/>.
*/
/**
 * @author Christian <c@ethdev.com>
 * @date 2015
 * Tests for high level features like import.
 */

#include <string>
#include <boost/test/unit_test.hpp>
#include <libsolidity/interface/Exceptions.h>
#include <libsolidity/interface/CompilerStack.h>

using namespace std;

namespace dev
{
namespace solidity
{
namespace test
{

BOOST_AUTO_TEST_SUITE(SolidityImports)

BOOST_AUTO_TEST_CASE(smoke_test)
{
	CompilerStack c;
	c.addSource("a", "contract C {} pragma solidity >=0.0;");
	BOOST_CHECK(c.compile());
}

BOOST_AUTO_TEST_CASE(regular_import)
{
	CompilerStack c;
	c.addSource("a", "contract C {} pragma solidity >=0.0;");
	c.addSource("b", "import \"a\"; contract D is C {} pragma solidity >=0.0;");
	BOOST_CHECK(c.compile());
}

BOOST_AUTO_TEST_CASE(import_does_not_clutter_importee)
{
	CompilerStack c;
	c.addSource("a", "contract C { D d; } pragma solidity >=0.0;");
	c.addSource("b", "import \"a\"; contract D is C {} pragma solidity >=0.0;");
	BOOST_CHECK(!c.compile());
}

BOOST_AUTO_TEST_CASE(import_is_transitive)
{
	CompilerStack c;
	c.addSource("a", "contract C { } pragma solidity >=0.0;");
	c.addSource("b", "import \"a\"; pragma solidity >=0.0;");
	c.addSource("c", "import \"b\"; contract D is C {} pragma solidity >=0.0;");
	BOOST_CHECK(c.compile());
}

BOOST_AUTO_TEST_CASE(circular_import)
{
	CompilerStack c;
	c.addSource("a", "import \"b\"; contract C { D d; } pragma solidity >=0.0;");
	c.addSource("b", "import \"a\"; contract D { C c; } pragma solidity >=0.0;");
	BOOST_CHECK(c.compile());
}

BOOST_AUTO_TEST_CASE(relative_import)
{
	CompilerStack c;
	c.addSource("a", "import \"./dir/b\"; contract A is B {} pragma solidity >=0.0;");
	c.addSource("dir/b", "contract B {} pragma solidity >=0.0;");
	c.addSource("dir/c", "import \"../a\"; contract C is A {} pragma solidity >=0.0;");
	BOOST_CHECK(c.compile());
}

BOOST_AUTO_TEST_CASE(relative_import_multiplex)
{
	CompilerStack c;
	c.addSource("a", "contract A {} pragma solidity >=0.0;");
	c.addSource("dir/a/b/c", "import \"../../.././a\"; contract B is A {} pragma solidity >=0.0;");
	BOOST_CHECK(c.compile());
}

BOOST_AUTO_TEST_CASE(simple_alias)
{
	CompilerStack c;
	c.addSource("a", "contract A {} pragma solidity >=0.0;");
	c.addSource("dir/a/b/c", "import \"../../.././a\" as x; contract B is x.A { function() { x.A r = x.A(20); } } pragma solidity >=0.0;");
	BOOST_CHECK(c.compile());
}

BOOST_AUTO_TEST_CASE(library_name_clash)
{
	CompilerStack c;
	c.addSource("a", "library A {} pragma solidity >=0.0;");
	c.addSource("b", "library A {} pragma solidity >=0.0;");
	BOOST_CHECK(!c.compile());
}

BOOST_AUTO_TEST_CASE(library_name_clash_with_contract)
{
	CompilerStack c;
	c.addSource("a", "contract A {} pragma solidity >=0.0;");
	c.addSource("b", "library A {} pragma solidity >=0.0;");
	BOOST_CHECK(c.compile());
}

BOOST_AUTO_TEST_CASE(complex_import)
{
	CompilerStack c;
	c.addSource("a", "contract A {} contract B {} contract C { struct S { uint a; } } pragma solidity >=0.0;");
	c.addSource("b", "import \"a\" as x; import {B as b, C as c, C} from \"a\"; "
				"contract D is b { function f(c.S var1, x.C.S var2, C.S var3) internal {} } pragma solidity >=0.0;");
	BOOST_CHECK(c.compile());
}

BOOST_AUTO_TEST_CASE(name_clash_in_import)
{
	CompilerStack c;
	c.addSource("a", "contract A {} pragma solidity >=0.0;");
	c.addSource("b", "import \"a\"; contract A {} pragma solidity >=0.0;");
	BOOST_CHECK(!c.compile());
	c.addSource("b", "import \"a\" as A; contract A {} pragma solidity >=0.0;");
	BOOST_CHECK(!c.compile());
	c.addSource("b", "import {A as b} from \"a\"; contract b {} pragma solidity >=0.0;");
	BOOST_CHECK(!c.compile());
	c.addSource("b", "import {A} from \"a\"; contract A {} pragma solidity >=0.0;");
	BOOST_CHECK(!c.compile());
	c.addSource("b", "import {A} from \"a\"; contract B {} pragma solidity >=0.0;");
	BOOST_CHECK(c.compile());
}

BOOST_AUTO_TEST_CASE(remappings)
{
	CompilerStack c;
	c.setRemappings(vector<string>{"s=s_1.4.6", "t=Tee"});
	c.addSource("a", "import \"s/s.sol\"; contract A is S {} pragma solidity >=0.0;");
	c.addSource("b", "import \"t/tee.sol\"; contract A is Tee {} pragma solidity >=0.0;");
	c.addSource("s_1.4.6/s.sol", "contract S {} pragma solidity >=0.0;");
	c.addSource("Tee/tee.sol", "contract Tee {} pragma solidity >=0.0;");
	BOOST_CHECK(c.compile());
}

BOOST_AUTO_TEST_CASE(context_dependent_remappings)
{
	CompilerStack c;
	c.setRemappings(vector<string>{"a:s=s_1.4.6", "b:s=s_1.4.7"});
	c.addSource("a/a.sol", "import \"s/s.sol\"; contract A is SSix {} pragma solidity >=0.0;");
	c.addSource("b/b.sol", "import \"s/s.sol\"; contract B is SSeven {} pragma solidity >=0.0;");
	c.addSource("s_1.4.6/s.sol", "contract SSix {} pragma solidity >=0.0;");
	c.addSource("s_1.4.7/s.sol", "contract SSeven {} pragma solidity >=0.0;");
	BOOST_CHECK(c.compile());
}

BOOST_AUTO_TEST_CASE(filename_with_period)
{
	CompilerStack c;
	c.addSource("a/a.sol", "import \".b.sol\"; contract A is B {} pragma solidity >=0.0;");
	c.addSource("a/.b.sol", "contract B {} pragma solidity >=0.0;");
	BOOST_CHECK(!c.compile());
}

BOOST_AUTO_TEST_SUITE_END()

}
}
} // end namespaces
<|endoftext|>


<commit_before>
#include "net/ActivatingObjCheck.h"
#include <vector>

namespace net {

ActivatingObjCheck* ActivatingObjCheck::m_inst = nullptr;

ActivatingObjCheck::ActivatingObjCheck()
{
    m_activatingObjs = new std::set<intptr_t>();
    ::InitializeCriticalSection(&m_mutex);
}

ActivatingObjCheck::~ActivatingObjCheck()
{
    ::DeleteCriticalSection(&m_mutex);
}

ActivatingObjCheck* ActivatingObjCheck::inst()
{
    if (!m_inst)
        m_inst = new ActivatingObjCheck();
    return m_inst;
}

void ActivatingObjCheck::destroy()
{
    delete m_activatingObjs;
    m_activatingObjs = nullptr;

    if (m_inst)
        delete m_inst;
}

void ActivatingObjCheck::add(intptr_t loader)
{
    ::EnterCriticalSection(&m_mutex);
    m_activatingObjs->insert(loader);
    ::LeaveCriticalSection(&m_mutex);
}

void ActivatingObjCheck::remove(intptr_t loader)
{
    ::EnterCriticalSection(&m_mutex);
    m_activatingObjs->erase(loader);
    ::LeaveCriticalSection(&m_mutex);
}

bool ActivatingObjCheck::isActivating(intptr_t loader)
{
    ::EnterCriticalSection(&m_mutex);
    bool isActivating = m_activatingObjs->find(loader) != m_activatingObjs->end();
    ::LeaveCriticalSection(&m_mutex);
    return isActivating;
}

int ActivatingObjCheck::genId()
{
    InterlockedIncrement((long *)&m_newestId);
    return m_newestId;
}

void ActivatingObjCheck::testPrint()
{
#ifdef _DEBUG
    std::set<intptr_t>::iterator it = m_activatingObjs->begin();
    for (; it != m_activatingObjs->end(); ++it) {
        char* output = (char*)malloc(0x100);
        sprintf(output, "ActivatingObjCheck::testPrint %p\n", (void*)(*it));
        OutputDebugStringA(output);
        free(output);
    }
#endif
}

void ActivatingObjCheck::doGarbageCollected(bool forceGC)
{
    if (!forceGC) {
        ::EnterCriticalSection(&m_mutex);
        if (m_activatingObjs->size() < 10)
            return;
        ::LeaveCriticalSection(&m_mutex);
    }

    ::EnterCriticalSection(&m_mutex);
    std::vector<intptr_t> activatingLoaders;
    activatingLoaders.resize(m_activatingObjs->size());

    std::set<intptr_t>::iterator setIt = m_activatingObjs->begin();
    std::set<intptr_t>::iterator end = m_activatingObjs->end();
    for (unsigned i = 0; setIt != end; ++setIt, ++i)
        activatingLoaders[i] = *setIt;

    ::LeaveCriticalSection(&m_mutex);

//     std::vector<intptr_t>::iterator it = activatingLoaders.begin();
//     for (; it != activatingLoaders.end(); ++it) {
//         intptr_t loader = *it;
//         double time = WTF::currentTimeMS();
//         if (time - loader->startTime() > 10000 || forceGC) {
//             loader->onTimeout();
//         }
//     }
}

void ActivatingObjCheck::shutdown()
{
    doGarbageCollected(true);
}

} // net<commit_msg>* ActivatingObjCheck::doGarbageCollected(bool forceGC)里少了个leave<commit_after>
#include "net/ActivatingObjCheck.h"
#include <vector>

namespace net {

ActivatingObjCheck* ActivatingObjCheck::m_inst = nullptr;

ActivatingObjCheck::ActivatingObjCheck()
{
    m_activatingObjs = new std::set<intptr_t>();
    ::InitializeCriticalSection(&m_mutex);
}

ActivatingObjCheck::~ActivatingObjCheck()
{
    ::DeleteCriticalSection(&m_mutex);
}

ActivatingObjCheck* ActivatingObjCheck::inst()
{
    if (!m_inst)
        m_inst = new ActivatingObjCheck();
    return m_inst;
}

void ActivatingObjCheck::destroy()
{
    delete m_activatingObjs;
    m_activatingObjs = nullptr;

    if (m_inst)
        delete m_inst;
}

void ActivatingObjCheck::add(intptr_t loader)
{
    ::EnterCriticalSection(&m_mutex);
    m_activatingObjs->insert(loader);
    ::LeaveCriticalSection(&m_mutex);
}

void ActivatingObjCheck::remove(intptr_t loader)
{
    ::EnterCriticalSection(&m_mutex);
    m_activatingObjs->erase(loader);
    ::LeaveCriticalSection(&m_mutex);
}

bool ActivatingObjCheck::isActivating(intptr_t loader)
{
    ::EnterCriticalSection(&m_mutex);
    bool isActivating = m_activatingObjs->find(loader) != m_activatingObjs->end();
    ::LeaveCriticalSection(&m_mutex);
    return isActivating;
}

int ActivatingObjCheck::genId()
{
    InterlockedIncrement((long *)&m_newestId);
    return m_newestId;
}

void ActivatingObjCheck::testPrint()
{
#ifdef _DEBUG
    std::set<intptr_t>::iterator it = m_activatingObjs->begin();
    for (; it != m_activatingObjs->end(); ++it) {
        char* output = (char*)malloc(0x100);
        sprintf(output, "ActivatingObjCheck::testPrint %p\n", (void*)(*it));
        OutputDebugStringA(output);
        free(output);
    }
#endif
}

void ActivatingObjCheck::doGarbageCollected(bool forceGC)
{
    if (!forceGC) {
        ::EnterCriticalSection(&m_mutex);
        int size = m_activatingObjs->size();
        ::LeaveCriticalSection(&m_mutex);
        if (size < 10)
            return;
    }

    ::EnterCriticalSection(&m_mutex);
    std::vector<intptr_t> activatingLoaders;
    activatingLoaders.resize(m_activatingObjs->size());

    std::set<intptr_t>::iterator setIt = m_activatingObjs->begin();
    std::set<intptr_t>::iterator end = m_activatingObjs->end();
    for (unsigned i = 0; setIt != end; ++setIt, ++i)
        activatingLoaders[i] = *setIt;

    ::LeaveCriticalSection(&m_mutex);

//     std::vector<intptr_t>::iterator it = activatingLoaders.begin();
//     for (; it != activatingLoaders.end(); ++it) {
//         intptr_t loader = *it;
//         double time = WTF::currentTimeMS();
//         if (time - loader->startTime() > 10000 || forceGC) {
//             loader->onTimeout();
//         }
//     }
}

void ActivatingObjCheck::shutdown()
{
    doGarbageCollected(true);
}

} // net<|endoftext|>


<commit_before>// This file is part of the dune-gdt project:
//   http://users.dune-project.org/projects/dune-gdt
// Copyright holders: Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_GDT_EVALUATION_INTERFACE_HH
#define DUNE_GDT_EVALUATION_INTERFACE_HH

#include <memory>

#include <dune/stuff/common/disable_warnings.hh>
#include <dune/common/dynmatrix.hh>
#include <dune/common/fvector.hh>
#include <dune/stuff/common/reenable_warnings.hh>

#include <dune/stuff/functions/interfaces.hh>
#include <dune/stuff/common/crtp.hh>

namespace Dune {
namespace GDT {
namespace LocalEvaluation {

/**
 *  \brief  Interface for local evaluations that depend on a codim 0 entity.
 *  \tparam numArguments  The number of local bases.
 *  \note   All evaluations have to be copyable!
 */
template <class Traits, int numArguments>
class Codim0Interface
{
  static_assert(AlwaysFalse<Traits>::value, "There is no interface for this numArguments!");
};

/**
 *  \brief  Interface for unary codim 0 evaluations.
 */
template <class Traits>
class Codim0Interface<Traits, 1> : public Stuff::CRTPInterface<Codim0Interface<Traits, 1>, Traits>
{
public:
  typedef typename Traits::derived_type derived_type;
  typedef typename Traits::EntityType EntityType;
  typedef typename Traits::LocalfunctionTupleType LocalfunctionTupleType;
  typedef typename Traits::DomainFieldType DomainFieldType;
  static const unsigned int dimDomain = Traits::dimDomain;

  LocalfunctionTupleType localFunctions(const EntityType& entity) const
  {
    CHECK_CRTP(this->as_imp(*this).localFunctions(entity));
    return this->as_imp(*this).localFunctions(entity);
  }

  /**
   *  \brief  Computes the needed integration order.
   *  \tparam R   RangeFieldType
   *  \tparam r   dimRange of the testBase
   *  \tparam rC  dimRangeRows of the testBase
   */
  template <class R, int r, int rC>
  size_t order(const LocalfunctionTupleType& localFunctions,
               const Stuff::LocalfunctionSetInterface<EntityType, DomainFieldType, dimDomain, R, r, rC>& testBase) const
  {
    CHECK_CRTP(this->as_imp(*this).order(localFunctions, testBase));
    return this->as_imp(*this).order(localFunctions, testBase);
  }

  /**
   *  \brief  Computes a unary codim 0 evaluation.
   *  \tparam R   RangeFieldType
   *  \tparam r   dimRange of the testBase
   *  \tparam rC  dimRangeRows of the testBase
   *  \attention ret is assumed to be zero!
   */
  template <class R, int r, int rC>
  void evaluate(const LocalfunctionTupleType& localFunctions,
                const Stuff::LocalfunctionSetInterface<EntityType, DomainFieldType, dimDomain, R, r, rC>& testBase,
                const Dune::FieldVector<DomainFieldType, dimDomain>& localPoint, Dune::DynamicVector<R>& ret) const
  {
    CHECK_AND_CALL_CRTP(this->as_imp(*this).evaluate(localFunctions, testBase, localPoint, ret));
  }
}; // class Codim0Interface< Traits, 1 >

/**
 *  \brief  Interface for binary codim 0 evaluations.
 **/
template <class Traits>
class Codim0Interface<Traits, 2> : public Stuff::CRTPInterface<Codim0Interface<Traits, 2>, Traits>
{
public:
  typedef typename Traits::derived_type derived_type;
  typedef typename Traits::EntityType EntityType;
  typedef typename Traits::LocalfunctionTupleType LocalfunctionTupleType;
  typedef typename Traits::DomainFieldType DomainFieldType;
  static const unsigned int dimDomain = Traits::dimDomain;

  /**
   *  \brief  Computes the needed integration order.
   *  \tparam R       RangeFieldType
   *  \tparam r{T,A}  dimRange of the {testBase,ansatzBase}
   *  \tparam rC{T,A} dimRangeRows of the {testBase,ansatzBase}
   */
  template <class R, int rT, int rCT, int rA, int rCA>
  size_t
  order(const LocalfunctionTupleType& localFunctions,
        const Stuff::LocalfunctionSetInterface<EntityType, DomainFieldType, dimDomain, R, rT, rCT>& testBase,
        const Stuff::LocalfunctionSetInterface<EntityType, DomainFieldType, dimDomain, R, rA, rCA>& ansatzBase) const
  {
    CHECK_CRTP(this->as_imp(*this).order(localFunctions, testBase, ansatzBase));
    return this->as_imp(*this).order(localFunctions, testBase, ansatzBase);
  }

  /**
   *  \brief  Computes a binary codim 0 evaluation.
   *  \tparam R         RangeFieldType
   *  \tparam r{L,T,A}  dimRange of the {localFunction,testBase,ansatzBase}
   *  \tparam rC{L,T,A} dimRangeRows of the {localFunction,testBase,ansatzBase}
   *  \attention ret is assumed to be zero!
   */
  template <class R, int rT, int rCT, int rA, int rCA>
  void evaluate(const LocalfunctionTupleType& localFunctions,
                const Stuff::LocalfunctionSetInterface<EntityType, DomainFieldType, dimDomain, R, rT, rCT>& testBase,
                const Stuff::LocalfunctionSetInterface<EntityType, DomainFieldType, dimDomain, R, rA, rCA>& ansatzBase,
                const Dune::FieldVector<DomainFieldType, dimDomain>& localPoint, Dune::DynamicMatrix<R>& ret) const
  {
    CHECK_AND_CALL_CRTP(this->as_imp(*this).evaluate(localFunctions, testBase, ansatzBase, localPoint, ret));
  }
}; // class Codim0Interface< Traits, 2 >

/**
 *  \brief  Interface for local evaluations that depend on an intersection.
 *  \tparam numArguments  The number of local bases.
 *  \note   All evaluations have to be copyable!
 */
template <class Traits, int numArguments>
class Codim1Interface
{
  static_assert(AlwaysFalse<Traits>::value, "There is no interface for this numArguments!");
};

/**
 *  \brief  Interface for unary codim 1 evaluations.
 */
template <class Traits>
class Codim1Interface<Traits, 1> : public Stuff::CRTPInterface<Codim1Interface<Traits, 1>, Traits>
{
public:
  typedef typename Traits::derived_type derived_type;
  typedef typename Traits::EntityType EntityType;
  typedef typename Traits::LocalfunctionTupleType LocalfunctionTupleType;
  typedef typename Traits::DomainFieldType DomainFieldType;
  static const unsigned int dimDomain = Traits::dimDomain;

  /**
   *  \brief  Computes the needed integration order.
   *  \tparam R   RangeFieldType
   *  \tparam r   dimRange of the testBase
   *  \tparam rC  dimRangeRows of the testBase
   */
  template <class R, int r, int rC>
  size_t order(const LocalfunctionTupleType& localFunctions,
               const Stuff::LocalfunctionSetInterface<EntityType, DomainFieldType, dimDomain, R, r, rC>& testBase) const
  {
    CHECK_CRTP(this->as_imp(*this).order(localFunctions, testBase));
    return this->as_imp(*this).order(localFunctions, testBase);
  }

  /**
   *  \brief  Computes a binary codim 1 evaluation.
   *  \tparam IntersectionType    A model of Dune::Intersection< ... >
   *  \tparam R                   RangeFieldType
   *  \tparam r                   dimRange of the testBase
   *  \tparam rC                  dimRangeRows of the testBase
   *  \attention ret is assumed to be zero!
   */
  template <class IntersectionType, class R, int r, int rC>
  void evaluate(const LocalfunctionTupleType& localFunctions,
                const Stuff::LocalfunctionSetInterface<EntityType, DomainFieldType, dimDomain, R, r, rC>& testBase,
                const IntersectionType& intersection,
                const Dune::FieldVector<DomainFieldType, dimDomain - 1>& localPoint, Dune::DynamicVector<R>& ret) const
  {
    CHECK_AND_CALL_CRTP(this->as_imp(*this).evaluate(localFunctions, testBase, intersection, localPoint, ret));
  }
}; // class Codim1Interface< Traits, 1 >

/**
 *  \brief  Interface for binary codim 1 evaluations.
 */
template <class Traits>
class Codim1Interface<Traits, 2> : public Stuff::CRTPInterface<Codim1Interface<Traits, 2>, Traits>
{
public:
  typedef typename Traits::derived_type derived_type;
  typedef typename Traits::EntityType EntityType;
  typedef typename Traits::LocalfunctionTupleType LocalfunctionTupleType;
  typedef typename Traits::DomainFieldType DomainFieldType;
  static const unsigned int dimDomain = Traits::dimDomain;

  /**
   *  \brief  Computes the needed integration order.
   *  \tparam R                   RangeFieldType
   *  \tparam r{T,A}              dimRange of the {testBase,ansatzBase}
   *  \tparam rC{T,A}             dimRangeRows of the {testBase,ansatzBase}
   */
  template <class R, int rT, int rCT, int rA, int rCA>
  size_t
  order(const LocalfunctionTupleType& localFunctions,
        const Stuff::LocalfunctionSetInterface<EntityType, DomainFieldType, dimDomain, R, rT, rCT>& testBase,
        const Stuff::LocalfunctionSetInterface<EntityType, DomainFieldType, dimDomain, R, rA, rCA>& ansatzBase) const
  {
    CHECK_CRTP(this->as_imp(*this).order(localFunctions, testBase, ansatzBase));
    return this->as_imp(*this).order(localFunctions, testBase, ansatzBase);
  }

  /**
   *  \brief  Computes a binary codim 1 evaluation.
   *  \tparam IntersectionType    A model of Dune::Intersection< ... >
   *  \tparam R                   RangeFieldType
   *  \tparam r{T,A}              dimRange of the {testBase*,ansatzBase*}
   *  \tparam rC{T,A}             dimRangeRows of the {testBase*,ansatzBase*}
   *  \attention ret is assumed to be zero!
   */
  template <class IntersectionType, class R, int rT, int rCT, int rA, int rCA>
  void evaluate(const LocalfunctionTupleType& localFunctions,
                const Stuff::LocalfunctionSetInterface<EntityType, DomainFieldType, dimDomain, R, rT, rCT>& testBase,
                const Stuff::LocalfunctionSetInterface<EntityType, DomainFieldType, dimDomain, R, rA, rCA>& ansatzBase,
                const IntersectionType& intersection,
                const Dune::FieldVector<DomainFieldType, dimDomain - 1>& localPoint, Dune::DynamicMatrix<R>& ret) const
  {
    CHECK_AND_CALL_CRTP(
        this->as_imp(*this).evaluate(localFunctions, testBase, ansatzBase, intersection, localPoint, ret));
  }
}; // class Codim1Interface< Traits, 2 >

/**
 *  \brief  Interface for quaternary codim 1 evaluations.
 */
template <class Traits>
class Codim1Interface<Traits, 4> : public Stuff::CRTPInterface<Codim1Interface<Traits, 4>, Traits>
{
public:
  typedef typename Traits::derived_type derived_type;
  typedef typename Traits::EntityType EntityType;
  typedef typename Traits::LocalfunctionTupleType LocalfunctionTupleType;
  typedef typename Traits::DomainFieldType DomainFieldType;
  static const unsigned int dimDomain = Traits::dimDomain;

  /**
   *  \brief  Computes the needed integration order.
   *  \tparam R                     RangeFieldType
   *  \tparam r{T,A}                dimRange of the {testBase*,ansatzBase*}
   *  \tparam rC{T,A}               dimRangeRows of the {testBase*,ansatzBase*}
   */
  template <class R, int rT, int rCT, int rA, int rCA>
  size_t
  order(const LocalfunctionTupleType localFunctionsEntity, const LocalfunctionTupleType localFunctionsNeighbor,
        const Stuff::LocalfunctionSetInterface<EntityType, DomainFieldType, dimDomain, R, rT, rCT>& testBaseEntity,
        const Stuff::LocalfunctionSetInterface<EntityType, DomainFieldType, dimDomain, R, rA, rCA>& ansatzBaseEntity,
        const Stuff::LocalfunctionSetInterface<EntityType, DomainFieldType, dimDomain, R, rT, rCT>& testBaseNeighbor,
        const Stuff::LocalfunctionSetInterface<EntityType, DomainFieldType, dimDomain, R, rA, rCA>& ansatzBaseNeighbor)
      const
  {
    CHECK_CRTP(this->as_imp(*this).order(localFunctionsEntity,
                                         localFunctionsNeighbor,
                                         testBaseEntity,
                                         ansatzBaseEntity,
                                         testBaseNeighbor,
                                         ansatzBaseNeighbor));
    return this->as_imp(*this).order(localFunctionsEntity,
                                     localFunctionsNeighbor,
                                     testBaseEntity,
                                     ansatzBaseEntity,
                                     testBaseNeighbor,
                                     ansatzBaseNeighbor);
  }

  /**
   *  \brief  Computes a quaternary codim 1 evaluation.
   *  \tparam IntersectionType      A model of Dune::Intersection< ... >
   *  \tparam R                     RangeFieldType
   *  \tparam r{T,A}                dimRange of the {testBase*,ansatzBase*}
   *  \tparam rC{T,A}               dimRangeRows of the {testBase*,ansatzBase*}
   *  \attention entityEntityRet, entityEntityRet, entityEntityRet and neighborEntityRet are assumed to be zero!
   */
  template <class IntersectionType, class R, int rT, int rCT, int rA, int rCA>
  void evaluate(
      const LocalfunctionTupleType& localFunctionsEntity, const LocalfunctionTupleType& localFunctionsNeighbor,
      const Stuff::LocalfunctionSetInterface<EntityType, DomainFieldType, dimDomain, R, rT, rCT>& testBaseEntity,
      const Stuff::LocalfunctionSetInterface<EntityType, DomainFieldType, dimDomain, R, rA, rCA>& ansatzBaseEntity,
      const Stuff::LocalfunctionSetInterface<EntityType, DomainFieldType, dimDomain, R, rT, rCT>& testBaseNeighbor,
      const Stuff::LocalfunctionSetInterface<EntityType, DomainFieldType, dimDomain, R, rA, rCA>& ansatzBaseNeighbor,
      const IntersectionType& intersection, const Dune::FieldVector<DomainFieldType, dimDomain - 1>& localPoint,
      Dune::DynamicMatrix<R>& entityEntityRet, Dune::DynamicMatrix<R>& neighborNeighborRet,
      Dune::DynamicMatrix<R>& entityNeighborRet, Dune::DynamicMatrix<R>& neighborEntityRet) const
  {
    CHECK_AND_CALL_CRTP(this->as_imp(*this).evaluate(localFunctionsEntity,
                                                     localFunctionsNeighbor,
                                                     testBaseEntity,
                                                     ansatzBaseEntity,
                                                     testBaseNeighbor,
                                                     ansatzBaseNeighbor,
                                                     intersection,
                                                     localPoint,
                                                     entityEntityRet,
                                                     neighborNeighborRet,
                                                     entityNeighborRet,
                                                     neighborEntityRet));
  }
}; // class Codim1Interface< Traits, 4 >

} // namespace LocalEvaluation
} // namespace GDT
} // namespace Dune

#endif // DUNE_GDT_EVALUATION_INTERFACE_HH
<commit_msg>[localeval] more as_imp(*this) cleanups<commit_after>// This file is part of the dune-gdt project:
//   http://users.dune-project.org/projects/dune-gdt
// Copyright holders: Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_GDT_EVALUATION_INTERFACE_HH
#define DUNE_GDT_EVALUATION_INTERFACE_HH

#include <memory>

#include <dune/stuff/common/disable_warnings.hh>
#include <dune/common/dynmatrix.hh>
#include <dune/common/fvector.hh>
#include <dune/stuff/common/reenable_warnings.hh>

#include <dune/stuff/functions/interfaces.hh>
#include <dune/stuff/common/crtp.hh>

namespace Dune {
namespace GDT {
namespace LocalEvaluation {

/**
 *  \brief  Interface for local evaluations that depend on a codim 0 entity.
 *  \tparam numArguments  The number of local bases.
 *  \note   All evaluations have to be copyable!
 */
template <class Traits, int numArguments>
class Codim0Interface
{
  static_assert(AlwaysFalse<Traits>::value, "There is no interface for this numArguments!");
};

/**
 *  \brief  Interface for unary codim 0 evaluations.
 */
template <class Traits>
class Codim0Interface<Traits, 1> : public Stuff::CRTPInterface<Codim0Interface<Traits, 1>, Traits>
{
public:
  typedef typename Traits::derived_type derived_type;
  typedef typename Traits::EntityType EntityType;
  typedef typename Traits::LocalfunctionTupleType LocalfunctionTupleType;
  typedef typename Traits::DomainFieldType DomainFieldType;
  static const unsigned int dimDomain = Traits::dimDomain;

  LocalfunctionTupleType localFunctions(const EntityType& entity) const
  {
    CHECK_CRTP(this->as_imp().localFunctions(entity));
    return this->as_imp().localFunctions(entity);
  }

  /**
   *  \brief  Computes the needed integration order.
   *  \tparam R   RangeFieldType
   *  \tparam r   dimRange of the testBase
   *  \tparam rC  dimRangeRows of the testBase
   */
  template <class R, int r, int rC>
  size_t order(const LocalfunctionTupleType& localFunctions,
               const Stuff::LocalfunctionSetInterface<EntityType, DomainFieldType, dimDomain, R, r, rC>& testBase) const
  {
    CHECK_CRTP(this->as_imp().order(localFunctions, testBase));
    return this->as_imp().order(localFunctions, testBase);
  }

  /**
   *  \brief  Computes a unary codim 0 evaluation.
   *  \tparam R   RangeFieldType
   *  \tparam r   dimRange of the testBase
   *  \tparam rC  dimRangeRows of the testBase
   *  \attention ret is assumed to be zero!
   */
  template <class R, int r, int rC>
  void evaluate(const LocalfunctionTupleType& localFunctions,
                const Stuff::LocalfunctionSetInterface<EntityType, DomainFieldType, dimDomain, R, r, rC>& testBase,
                const Dune::FieldVector<DomainFieldType, dimDomain>& localPoint, Dune::DynamicVector<R>& ret) const
  {
    CHECK_AND_CALL_CRTP(this->as_imp().evaluate(localFunctions, testBase, localPoint, ret));
  }
}; // class Codim0Interface< Traits, 1 >

/**
 *  \brief  Interface for binary codim 0 evaluations.
 **/
template <class Traits>
class Codim0Interface<Traits, 2> : public Stuff::CRTPInterface<Codim0Interface<Traits, 2>, Traits>
{
public:
  typedef typename Traits::derived_type derived_type;
  typedef typename Traits::EntityType EntityType;
  typedef typename Traits::LocalfunctionTupleType LocalfunctionTupleType;
  typedef typename Traits::DomainFieldType DomainFieldType;
  static const unsigned int dimDomain = Traits::dimDomain;

  /**
   *  \brief  Computes the needed integration order.
   *  \tparam R       RangeFieldType
   *  \tparam r{T,A}  dimRange of the {testBase,ansatzBase}
   *  \tparam rC{T,A} dimRangeRows of the {testBase,ansatzBase}
   */
  template <class R, int rT, int rCT, int rA, int rCA>
  size_t
  order(const LocalfunctionTupleType& localFunctions,
        const Stuff::LocalfunctionSetInterface<EntityType, DomainFieldType, dimDomain, R, rT, rCT>& testBase,
        const Stuff::LocalfunctionSetInterface<EntityType, DomainFieldType, dimDomain, R, rA, rCA>& ansatzBase) const
  {
    CHECK_CRTP(this->as_imp().order(localFunctions, testBase, ansatzBase));
    return this->as_imp().order(localFunctions, testBase, ansatzBase);
  }

  /**
   *  \brief  Computes a binary codim 0 evaluation.
   *  \tparam R         RangeFieldType
   *  \tparam r{L,T,A}  dimRange of the {localFunction,testBase,ansatzBase}
   *  \tparam rC{L,T,A} dimRangeRows of the {localFunction,testBase,ansatzBase}
   *  \attention ret is assumed to be zero!
   */
  template <class R, int rT, int rCT, int rA, int rCA>
  void evaluate(const LocalfunctionTupleType& localFunctions,
                const Stuff::LocalfunctionSetInterface<EntityType, DomainFieldType, dimDomain, R, rT, rCT>& testBase,
                const Stuff::LocalfunctionSetInterface<EntityType, DomainFieldType, dimDomain, R, rA, rCA>& ansatzBase,
                const Dune::FieldVector<DomainFieldType, dimDomain>& localPoint, Dune::DynamicMatrix<R>& ret) const
  {
    CHECK_AND_CALL_CRTP(this->as_imp().evaluate(localFunctions, testBase, ansatzBase, localPoint, ret));
  }
}; // class Codim0Interface< Traits, 2 >

/**
 *  \brief  Interface for local evaluations that depend on an intersection.
 *  \tparam numArguments  The number of local bases.
 *  \note   All evaluations have to be copyable!
 */
template <class Traits, int numArguments>
class Codim1Interface
{
  static_assert(AlwaysFalse<Traits>::value, "There is no interface for this numArguments!");
};

/**
 *  \brief  Interface for unary codim 1 evaluations.
 */
template <class Traits>
class Codim1Interface<Traits, 1> : public Stuff::CRTPInterface<Codim1Interface<Traits, 1>, Traits>
{
public:
  typedef typename Traits::derived_type derived_type;
  typedef typename Traits::EntityType EntityType;
  typedef typename Traits::LocalfunctionTupleType LocalfunctionTupleType;
  typedef typename Traits::DomainFieldType DomainFieldType;
  static const unsigned int dimDomain = Traits::dimDomain;

  /**
   *  \brief  Computes the needed integration order.
   *  \tparam R   RangeFieldType
   *  \tparam r   dimRange of the testBase
   *  \tparam rC  dimRangeRows of the testBase
   */
  template <class R, int r, int rC>
  size_t order(const LocalfunctionTupleType& localFunctions,
               const Stuff::LocalfunctionSetInterface<EntityType, DomainFieldType, dimDomain, R, r, rC>& testBase) const
  {
    CHECK_CRTP(this->as_imp().order(localFunctions, testBase));
    return this->as_imp().order(localFunctions, testBase);
  }

  /**
   *  \brief  Computes a binary codim 1 evaluation.
   *  \tparam IntersectionType    A model of Dune::Intersection< ... >
   *  \tparam R                   RangeFieldType
   *  \tparam r                   dimRange of the testBase
   *  \tparam rC                  dimRangeRows of the testBase
   *  \attention ret is assumed to be zero!
   */
  template <class IntersectionType, class R, int r, int rC>
  void evaluate(const LocalfunctionTupleType& localFunctions,
                const Stuff::LocalfunctionSetInterface<EntityType, DomainFieldType, dimDomain, R, r, rC>& testBase,
                const IntersectionType& intersection,
                const Dune::FieldVector<DomainFieldType, dimDomain - 1>& localPoint, Dune::DynamicVector<R>& ret) const
  {
    CHECK_AND_CALL_CRTP(this->as_imp().evaluate(localFunctions, testBase, intersection, localPoint, ret));
  }
}; // class Codim1Interface< Traits, 1 >

/**
 *  \brief  Interface for binary codim 1 evaluations.
 */
template <class Traits>
class Codim1Interface<Traits, 2> : public Stuff::CRTPInterface<Codim1Interface<Traits, 2>, Traits>
{
public:
  typedef typename Traits::derived_type derived_type;
  typedef typename Traits::EntityType EntityType;
  typedef typename Traits::LocalfunctionTupleType LocalfunctionTupleType;
  typedef typename Traits::DomainFieldType DomainFieldType;
  static const unsigned int dimDomain = Traits::dimDomain;

  /**
   *  \brief  Computes the needed integration order.
   *  \tparam R                   RangeFieldType
   *  \tparam r{T,A}              dimRange of the {testBase,ansatzBase}
   *  \tparam rC{T,A}             dimRangeRows of the {testBase,ansatzBase}
   */
  template <class R, int rT, int rCT, int rA, int rCA>
  size_t
  order(const LocalfunctionTupleType& localFunctions,
        const Stuff::LocalfunctionSetInterface<EntityType, DomainFieldType, dimDomain, R, rT, rCT>& testBase,
        const Stuff::LocalfunctionSetInterface<EntityType, DomainFieldType, dimDomain, R, rA, rCA>& ansatzBase) const
  {
    CHECK_CRTP(this->as_imp().order(localFunctions, testBase, ansatzBase));
    return this->as_imp().order(localFunctions, testBase, ansatzBase);
  }

  /**
   *  \brief  Computes a binary codim 1 evaluation.
   *  \tparam IntersectionType    A model of Dune::Intersection< ... >
   *  \tparam R                   RangeFieldType
   *  \tparam r{T,A}              dimRange of the {testBase*,ansatzBase*}
   *  \tparam rC{T,A}             dimRangeRows of the {testBase*,ansatzBase*}
   *  \attention ret is assumed to be zero!
   */
  template <class IntersectionType, class R, int rT, int rCT, int rA, int rCA>
  void evaluate(const LocalfunctionTupleType& localFunctions,
                const Stuff::LocalfunctionSetInterface<EntityType, DomainFieldType, dimDomain, R, rT, rCT>& testBase,
                const Stuff::LocalfunctionSetInterface<EntityType, DomainFieldType, dimDomain, R, rA, rCA>& ansatzBase,
                const IntersectionType& intersection,
                const Dune::FieldVector<DomainFieldType, dimDomain - 1>& localPoint, Dune::DynamicMatrix<R>& ret) const
  {
    CHECK_AND_CALL_CRTP(this->as_imp().evaluate(localFunctions, testBase, ansatzBase, intersection, localPoint, ret));
  }
}; // class Codim1Interface< Traits, 2 >

/**
 *  \brief  Interface for quaternary codim 1 evaluations.
 */
template <class Traits>
class Codim1Interface<Traits, 4> : public Stuff::CRTPInterface<Codim1Interface<Traits, 4>, Traits>
{
public:
  typedef typename Traits::derived_type derived_type;
  typedef typename Traits::EntityType EntityType;
  typedef typename Traits::LocalfunctionTupleType LocalfunctionTupleType;
  typedef typename Traits::DomainFieldType DomainFieldType;
  static const unsigned int dimDomain = Traits::dimDomain;

  /**
   *  \brief  Computes the needed integration order.
   *  \tparam R                     RangeFieldType
   *  \tparam r{T,A}                dimRange of the {testBase*,ansatzBase*}
   *  \tparam rC{T,A}               dimRangeRows of the {testBase*,ansatzBase*}
   */
  template <class R, int rT, int rCT, int rA, int rCA>
  size_t
  order(const LocalfunctionTupleType localFunctionsEntity, const LocalfunctionTupleType localFunctionsNeighbor,
        const Stuff::LocalfunctionSetInterface<EntityType, DomainFieldType, dimDomain, R, rT, rCT>& testBaseEntity,
        const Stuff::LocalfunctionSetInterface<EntityType, DomainFieldType, dimDomain, R, rA, rCA>& ansatzBaseEntity,
        const Stuff::LocalfunctionSetInterface<EntityType, DomainFieldType, dimDomain, R, rT, rCT>& testBaseNeighbor,
        const Stuff::LocalfunctionSetInterface<EntityType, DomainFieldType, dimDomain, R, rA, rCA>& ansatzBaseNeighbor)
      const
  {
    CHECK_CRTP(this->as_imp().order(localFunctionsEntity,
                                    localFunctionsNeighbor,
                                    testBaseEntity,
                                    ansatzBaseEntity,
                                    testBaseNeighbor,
                                    ansatzBaseNeighbor));
    return this->as_imp().order(localFunctionsEntity,
                                localFunctionsNeighbor,
                                testBaseEntity,
                                ansatzBaseEntity,
                                testBaseNeighbor,
                                ansatzBaseNeighbor);
  }

  /**
   *  \brief  Computes a quaternary codim 1 evaluation.
   *  \tparam IntersectionType      A model of Dune::Intersection< ... >
   *  \tparam R                     RangeFieldType
   *  \tparam r{T,A}                dimRange of the {testBase*,ansatzBase*}
   *  \tparam rC{T,A}               dimRangeRows of the {testBase*,ansatzBase*}
   *  \attention entityEntityRet, entityEntityRet, entityEntityRet and neighborEntityRet are assumed to be zero!
   */
  template <class IntersectionType, class R, int rT, int rCT, int rA, int rCA>
  void evaluate(
      const LocalfunctionTupleType& localFunctionsEntity, const LocalfunctionTupleType& localFunctionsNeighbor,
      const Stuff::LocalfunctionSetInterface<EntityType, DomainFieldType, dimDomain, R, rT, rCT>& testBaseEntity,
      const Stuff::LocalfunctionSetInterface<EntityType, DomainFieldType, dimDomain, R, rA, rCA>& ansatzBaseEntity,
      const Stuff::LocalfunctionSetInterface<EntityType, DomainFieldType, dimDomain, R, rT, rCT>& testBaseNeighbor,
      const Stuff::LocalfunctionSetInterface<EntityType, DomainFieldType, dimDomain, R, rA, rCA>& ansatzBaseNeighbor,
      const IntersectionType& intersection, const Dune::FieldVector<DomainFieldType, dimDomain - 1>& localPoint,
      Dune::DynamicMatrix<R>& entityEntityRet, Dune::DynamicMatrix<R>& neighborNeighborRet,
      Dune::DynamicMatrix<R>& entityNeighborRet, Dune::DynamicMatrix<R>& neighborEntityRet) const
  {
    CHECK_AND_CALL_CRTP(this->as_imp().evaluate(localFunctionsEntity,
                                                localFunctionsNeighbor,
                                                testBaseEntity,
                                                ansatzBaseEntity,
                                                testBaseNeighbor,
                                                ansatzBaseNeighbor,
                                                intersection,
                                                localPoint,
                                                entityEntityRet,
                                                neighborNeighborRet,
                                                entityNeighborRet,
                                                neighborEntityRet));
  }
}; // class Codim1Interface< Traits, 4 >

} // namespace LocalEvaluation
} // namespace GDT
} // namespace Dune

#endif // DUNE_GDT_EVALUATION_INTERFACE_HH
<|endoftext|>


<commit_before>/*
 * This file is part of telepathy-accounts-kcm
 *
 * Copyright (C) 2009 Collabora Ltd. <http://www.collabora.co.uk/>
 *
 * 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; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "edit-account-dialog.h"

#include "KCMTelepathyAccounts/abstract-account-parameters-widget.h"
#include "KCMTelepathyAccounts/abstract-account-ui.h"
#include "KCMTelepathyAccounts/mandatory-parameter-edit-widget.h"
#include "KCMTelepathyAccounts/optional-parameter-edit-widget.h"
#include "KCMTelepathyAccounts/plugin-manager.h"

#include <KDebug>
#include <KLocale>
#include <KTabWidget>

#include <QtCore/QList>

#include <TelepathyQt4/ConnectionManager>
#include <TelepathyQt4/PendingStringList>

class EditAccountDialog::Private
{
public:
    Private()
            : item(0), tabWidget(0), mandatoryParametersWidget(0)
    {
        kDebug();
    }

    AccountItem *item;

    Tp::ProtocolParameterList mandatoryProtocolParameters;
    Tp::ProtocolParameterList optionalProtocolParameters;
    QVariantMap parameterValues;

    KTabWidget *tabWidget;
    AbstractAccountParametersWidget *mandatoryParametersWidget;
    QList<AbstractAccountParametersWidget*> optionalParametersWidgets;
};

EditAccountDialog::EditAccountDialog(AccountItem *item, QWidget *parent)
        : KDialog(parent),
          d(new Private)
{
    kDebug();

    // Set up the tab widget.
    d->tabWidget = new KTabWidget(this);
    setMainWidget(d->tabWidget);
    resize(400, 480);

    d->item = item;

    // Get the protocol's parameters.
    Tp::ProtocolInfo *protocolInfo = d->item->account()->protocolInfo();
    Tp::ProtocolParameterList protocolParameters = protocolInfo->parameters();

    foreach (Tp::ProtocolParameter *parameter, protocolParameters) {
        if (parameter->isRequired()) {
            d->mandatoryProtocolParameters.append(parameter);
        } else {
            d->optionalProtocolParameters.append(parameter);
        }
    }

    // Get the parameter values.
    d->parameterValues = d->item->account()->parameters();

    // The rest of this method is based on code from add-account-assistant.cpp

    // Get the AccountsUi for the plugin, and get the optional parameter widgets for it.
    AbstractAccountUi *ui = PluginManager::instance()->accountUiForProtocol(item->account()->cmName(),
                                                                            item->account()->protocol());

    // Set up the Mandatory Parameters page
    Tp::ProtocolParameterList mandatoryParametersLeft = d->mandatoryProtocolParameters;

    // Create the custom UI or generic UI depending on available parameters.
    if (ui) {
        // UI does exist, set it up.
        AbstractAccountParametersWidget *widget = ui->mandatoryParametersWidget(d->mandatoryProtocolParameters,
                                                                                item->account()->parameters());
        QMap<QString, QVariant::Type> manParams = ui->supportedMandatoryParameters();
        QMap<QString, QVariant::Type>::const_iterator manIter = manParams.constBegin();
        while(manIter != manParams.constEnd()) {
            foreach (Tp::ProtocolParameter *parameter, d->mandatoryProtocolParameters) {
                // If the parameter is not
                if ((parameter->name() == manIter.key()) &&
                    (parameter->type() == manIter.value())) {
                    mandatoryParametersLeft.removeAll(parameter);
                }
            }

            ++manIter;
        }

        if (mandatoryParametersLeft.isEmpty()) {
            d->mandatoryParametersWidget = widget;
        } else {
            // FIXME: At the moment, if the custom widget can't handle all the mandatory
            // parameters we fall back to the generic one for all of them. It might be nicer
            // to have the custom UI for as many as possible, and stick a small generic one
            // underneath for those parameters it doesn't handle.
            widget->deleteLater();
            widget = 0;
        }
    }

    if (!d->mandatoryParametersWidget) {
        d->mandatoryParametersWidget = new MandatoryParameterEditWidget(
                d->mandatoryProtocolParameters,
                item->account()->parameters(),
                d->tabWidget);
    }

    d->tabWidget->addTab(d->mandatoryParametersWidget, i18n("Mandatory Parameters"));

    // Get the list of parameters
    Tp::ProtocolParameterList optionalParametersLeft = d->optionalProtocolParameters;

    // Check if the AbstractAccountUi exists. If not then we use the autogenerated UI for
    // everything.
    if (ui) {
        // UI Does exist, set it up.
        QList<AbstractAccountParametersWidget*> widgets = ui->optionalParametersWidgets(
                d->optionalProtocolParameters,
                item->account()->parameters());

        // Remove all handled parameters from the optionalParameters list.
        QMap<QString, QVariant::Type> opParams = ui->supportedOptionalParameters();
        QMap<QString, QVariant::Type>::const_iterator opIter = opParams.constBegin();
        while(opIter != opParams.constEnd()) {
            foreach (Tp::ProtocolParameter *parameter, d->optionalProtocolParameters) {
                // If the parameter is not
                if ((parameter->name() == opIter.key()) &&
                    (parameter->type() == opIter.value())) {
                    optionalParametersLeft.removeAll(parameter);
                }
            }

            ++opIter;
        }

        foreach (AbstractAccountParametersWidget *widget, widgets) {
            d->optionalParametersWidgets.append(widget);
            d->tabWidget->addTab(widget, i18n("Optional Parameters"));
        }
    }

    // Show the generic UI if optionalParameters is not empty.
    if (optionalParametersLeft.size() > 0) {
        OptionalParameterEditWidget *opew =
                new OptionalParameterEditWidget(optionalParametersLeft,
                                                item->account()->parameters(),
                                                d->tabWidget);
        d->optionalParametersWidgets.append(opew);
        d->tabWidget->addTab(opew, i18n("Optional Parameters"));
    }

}

EditAccountDialog::~EditAccountDialog()
{
    kDebug();
}

void EditAccountDialog::slotButtonClicked(int button)
{
    kDebug() << "Button clicked:" << button;

    if (button == KDialog::Ok) {
        accept();
    } else{
        KDialog::slotButtonClicked(button);
    }
}

void EditAccountDialog::accept()
{
    kDebug();

    // Check all pages of parameters pass validation.
    if (!d->mandatoryParametersWidget->validateParameterValues()) {
        kDebug() << "A widget failed parameter validation. Not accepting wizard.";
        return;
    }

    foreach (AbstractAccountParametersWidget *w, d->optionalParametersWidgets) {
        if (!w->validateParameterValues()) {
            kDebug() << "A widget failed parameter validation. Not accepting wizard.";
            return;
        }
    }

    // Get the mandatory parameters.
    QMap<Tp::ProtocolParameter*, QVariant> mandatoryParameterValues;
    mandatoryParameterValues = d->mandatoryParametersWidget->parameterValues();

    // Get the optional parameters.
    QMap<Tp::ProtocolParameter*, QVariant> optionalParameterValues;

    foreach (AbstractAccountParametersWidget *w, d->optionalParametersWidgets) {
        QMap<Tp::ProtocolParameter*, QVariant> parameters = w->parameterValues();
        QMap<Tp::ProtocolParameter*, QVariant>::const_iterator i = parameters.constBegin();
        while (i != parameters.constEnd()) {
            if (!optionalParameterValues.contains(i.key())) {
                optionalParameterValues.insert(i.key(), i.value());
            } else {
                kWarning() << "Parameter:" << i.key()->name() << "is already in the map.";
            }

            ++i;
        }
        continue;
    }

    // Merge the parameters into a QVariantMap for submitting to the Telepathy AM.
    QVariantMap parameters;
    QStringList unsetParameters;

    foreach (Tp::ProtocolParameter *pp, mandatoryParameterValues.keys()) {
        QVariant value = mandatoryParameterValues.value(pp);

        // Unset empty parameters.
        if (!value.isNull()) {
            parameters.insert(pp->name(), value);
            continue;
        }

        unsetParameters.append(pp->name());
    }

    foreach (Tp::ProtocolParameter *pp, optionalParameterValues.keys()) {
        QVariant value = optionalParameterValues.value(pp);

        // Unset empty parameters.
        if (!value.isNull()) {
            parameters.insert(pp->name(), value);
            continue;
        }

        unsetParameters.append(pp->name());
    }

    Tp::PendingStringList *psl = d->item->account()->updateParameters(parameters, unsetParameters);

    connect(psl,
            SIGNAL(finished(Tp::PendingOperation*)),
            SLOT(onParametersUpdated(Tp::PendingOperation*)));
}

void EditAccountDialog::onParametersUpdated(Tp::PendingOperation *op)
{
    kDebug();

    if (op->isError()) {
        // FIXME: Visual feedback in GUI to user.
        kWarning() << "Could not update parameters:" << op->errorName() << op->errorMessage();
        return;
    }

    emit finished();
}

#include "edit-account-dialog.moc"

<commit_msg>Fix bug where parameters with the default value were not unset when editing the account.<commit_after>/*
 * This file is part of telepathy-accounts-kcm
 *
 * Copyright (C) 2009 Collabora Ltd. <http://www.collabora.co.uk/>
 *
 * 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; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "edit-account-dialog.h"

#include "KCMTelepathyAccounts/abstract-account-parameters-widget.h"
#include "KCMTelepathyAccounts/abstract-account-ui.h"
#include "KCMTelepathyAccounts/mandatory-parameter-edit-widget.h"
#include "KCMTelepathyAccounts/optional-parameter-edit-widget.h"
#include "KCMTelepathyAccounts/plugin-manager.h"

#include <KDebug>
#include <KLocale>
#include <KTabWidget>

#include <QtCore/QList>

#include <TelepathyQt4/ConnectionManager>
#include <TelepathyQt4/PendingStringList>

class EditAccountDialog::Private
{
public:
    Private()
            : item(0), tabWidget(0), mandatoryParametersWidget(0)
    {
        kDebug();
    }

    AccountItem *item;

    Tp::ProtocolParameterList mandatoryProtocolParameters;
    Tp::ProtocolParameterList optionalProtocolParameters;
    QVariantMap parameterValues;

    KTabWidget *tabWidget;
    AbstractAccountParametersWidget *mandatoryParametersWidget;
    QList<AbstractAccountParametersWidget*> optionalParametersWidgets;
};

EditAccountDialog::EditAccountDialog(AccountItem *item, QWidget *parent)
        : KDialog(parent),
          d(new Private)
{
    kDebug();

    // Set up the tab widget.
    d->tabWidget = new KTabWidget(this);
    setMainWidget(d->tabWidget);
    resize(400, 480);

    d->item = item;

    // Get the protocol's parameters.
    Tp::ProtocolInfo *protocolInfo = d->item->account()->protocolInfo();
    Tp::ProtocolParameterList protocolParameters = protocolInfo->parameters();

    foreach (Tp::ProtocolParameter *parameter, protocolParameters) {
        if (parameter->isRequired()) {
            d->mandatoryProtocolParameters.append(parameter);
        } else {
            d->optionalProtocolParameters.append(parameter);
        }
    }

    // Get the parameter values.
    d->parameterValues = d->item->account()->parameters();

    // The rest of this method is based on code from add-account-assistant.cpp

    // Get the AccountsUi for the plugin, and get the optional parameter widgets for it.
    AbstractAccountUi *ui = PluginManager::instance()->accountUiForProtocol(item->account()->cmName(),
                                                                            item->account()->protocol());

    // Set up the Mandatory Parameters page
    Tp::ProtocolParameterList mandatoryParametersLeft = d->mandatoryProtocolParameters;

    // Create the custom UI or generic UI depending on available parameters.
    if (ui) {
        // UI does exist, set it up.
        AbstractAccountParametersWidget *widget = ui->mandatoryParametersWidget(d->mandatoryProtocolParameters,
                                                                                item->account()->parameters());
        QMap<QString, QVariant::Type> manParams = ui->supportedMandatoryParameters();
        QMap<QString, QVariant::Type>::const_iterator manIter = manParams.constBegin();
        while(manIter != manParams.constEnd()) {
            foreach (Tp::ProtocolParameter *parameter, d->mandatoryProtocolParameters) {
                // If the parameter is not
                if ((parameter->name() == manIter.key()) &&
                    (parameter->type() == manIter.value())) {
                    mandatoryParametersLeft.removeAll(parameter);
                }
            }

            ++manIter;
        }

        if (mandatoryParametersLeft.isEmpty()) {
            d->mandatoryParametersWidget = widget;
        } else {
            // FIXME: At the moment, if the custom widget can't handle all the mandatory
            // parameters we fall back to the generic one for all of them. It might be nicer
            // to have the custom UI for as many as possible, and stick a small generic one
            // underneath for those parameters it doesn't handle.
            widget->deleteLater();
            widget = 0;
        }
    }

    if (!d->mandatoryParametersWidget) {
        d->mandatoryParametersWidget = new MandatoryParameterEditWidget(
                d->mandatoryProtocolParameters,
                item->account()->parameters(),
                d->tabWidget);
    }

    d->tabWidget->addTab(d->mandatoryParametersWidget, i18n("Mandatory Parameters"));

    // Get the list of parameters
    Tp::ProtocolParameterList optionalParametersLeft = d->optionalProtocolParameters;

    // Check if the AbstractAccountUi exists. If not then we use the autogenerated UI for
    // everything.
    if (ui) {
        // UI Does exist, set it up.
        QList<AbstractAccountParametersWidget*> widgets = ui->optionalParametersWidgets(
                d->optionalProtocolParameters,
                item->account()->parameters());

        // Remove all handled parameters from the optionalParameters list.
        QMap<QString, QVariant::Type> opParams = ui->supportedOptionalParameters();
        QMap<QString, QVariant::Type>::const_iterator opIter = opParams.constBegin();
        while(opIter != opParams.constEnd()) {
            foreach (Tp::ProtocolParameter *parameter, d->optionalProtocolParameters) {
                // If the parameter is not
                if ((parameter->name() == opIter.key()) &&
                    (parameter->type() == opIter.value())) {
                    optionalParametersLeft.removeAll(parameter);
                }
            }

            ++opIter;
        }

        foreach (AbstractAccountParametersWidget *widget, widgets) {
            d->optionalParametersWidgets.append(widget);
            d->tabWidget->addTab(widget, i18n("Optional Parameters"));
        }
    }

    // Show the generic UI if optionalParameters is not empty.
    if (optionalParametersLeft.size() > 0) {
        OptionalParameterEditWidget *opew =
                new OptionalParameterEditWidget(optionalParametersLeft,
                                                item->account()->parameters(),
                                                d->tabWidget);
        d->optionalParametersWidgets.append(opew);
        d->tabWidget->addTab(opew, i18n("Optional Parameters"));
    }

}

EditAccountDialog::~EditAccountDialog()
{
    kDebug();
}

void EditAccountDialog::slotButtonClicked(int button)
{
    kDebug() << "Button clicked:" << button;

    if (button == KDialog::Ok) {
        accept();
    } else{
        KDialog::slotButtonClicked(button);
    }
}

void EditAccountDialog::accept()
{
    kDebug();

    // Check all pages of parameters pass validation.
    if (!d->mandatoryParametersWidget->validateParameterValues()) {
        kDebug() << "A widget failed parameter validation. Not accepting wizard.";
        return;
    }

    foreach (AbstractAccountParametersWidget *w, d->optionalParametersWidgets) {
        if (!w->validateParameterValues()) {
            kDebug() << "A widget failed parameter validation. Not accepting wizard.";
            return;
        }
    }

    // Get the mandatory parameters.
    QMap<Tp::ProtocolParameter*, QVariant> mandatoryParameterValues;
    mandatoryParameterValues = d->mandatoryParametersWidget->parameterValues();

    // Get the optional parameters.
    QMap<Tp::ProtocolParameter*, QVariant> optionalParameterValues;

    foreach (AbstractAccountParametersWidget *w, d->optionalParametersWidgets) {
        QMap<Tp::ProtocolParameter*, QVariant> parameters = w->parameterValues();
        QMap<Tp::ProtocolParameter*, QVariant>::const_iterator i = parameters.constBegin();
        while (i != parameters.constEnd()) {
            if (!optionalParameterValues.contains(i.key())) {
                optionalParameterValues.insert(i.key(), i.value());
            } else {
                kWarning() << "Parameter:" << i.key()->name() << "is already in the map.";
            }

            ++i;
        }
        continue;
    }

    // Merge the parameters into a QVariantMap for submitting to the Telepathy AM.
    QVariantMap parameters;
    QStringList unsetParameters;

    foreach (Tp::ProtocolParameter *pp, mandatoryParameterValues.keys()) {
        QVariant value = mandatoryParameterValues.value(pp);

        // Unset null parameters.
        if (value.isNull()) {
            unsetParameters.append(pp->name());
            continue;
        }

        // Unset any parameters where the default value is equal to the current value.
        if (pp->defaultValue() == value) {
            unsetParameters.append(pp->name());
            continue;
        }

        // Unset any strings where the default is empty, and the value is an empty string
        if (pp->type() == QVariant::String) {
            if ((pp->defaultValue().isNull()) && value.toString().isEmpty()) {
                unsetParameters.append(pp->name());
                continue;
            }
        }

        // Parameter has a valid value, so set it.
        parameters.insert(pp->name(), value);
    }

    foreach (Tp::ProtocolParameter *pp, optionalParameterValues.keys()) {
        QVariant value = optionalParameterValues.value(pp);

        // Unset null parameters.
        if (value.isNull()) {
            unsetParameters.append(pp->name());
            continue;
        }

        // Unset any parameters where the default value is equal to the current value.
        if (pp->defaultValue() == value) {
            unsetParameters.append(pp->name());
            continue;
        }

        // Unset any strings where the default is empty, and the value is an empty string
        if (pp->type() == QVariant::String) {
            if ((pp->defaultValue().isNull()) && value.toString().isEmpty()) {
                unsetParameters.append(pp->name());
                continue;
            }
        }

        // Parameter has a valid value, so set it.
        parameters.insert(pp->name(), value);
    }

    // kDebug() << "Set parameters:" << parameters;
    // kDebug() << "Unset parameters:" << unsetParameters;

    Tp::PendingStringList *psl = d->item->account()->updateParameters(parameters, unsetParameters);

    connect(psl,
            SIGNAL(finished(Tp::PendingOperation*)),
            SLOT(onParametersUpdated(Tp::PendingOperation*)));
}

void EditAccountDialog::onParametersUpdated(Tp::PendingOperation *op)
{
    kDebug();

    if (op->isError()) {
        // FIXME: Visual feedback in GUI to user.
        kWarning() << "Could not update parameters:" << op->errorName() << op->errorMessage();
        return;
    }

    emit finished();
}

#include "edit-account-dialog.moc"

<|endoftext|>


<commit_before>/*
 * Copyright 2002-2005 The Apache Software Foundation.
 *
 * 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.
 */

/*
 * XSEC
 *
 * XSECCryptoUtils:= Helper crypo utilities that make life easier
 *
 * Author(s): Berin Lautenbach
 *
 * $Id$
 *
 */

#include <xsec/framework/XSECDefs.hpp>
#include <xsec/framework/XSECError.hpp>
#include <xsec/enc/XSECCryptoUtils.hpp>
#include <xsec/enc/XSECCryptoKeyHMAC.hpp>
#include <xsec/utils/XSECPlatformUtils.hpp>

#include <xercesc/util/Janitor.hpp>
#include <xercesc/util/XMLString.hpp>

XERCES_CPP_NAMESPACE_USE

// --------------------------------------------------------------------------------
//           XKMS Limited-Use Shared Secret handling
// --------------------------------------------------------------------------------

int CleanXKMSPassPhrase(unsigned char * input, int inputLen, safeBuffer &output) {

	int j = 0;
	unsigned char c;
	for (int i = 0; i < inputLen; ++i) {

		c = input[i];

		if (c >= 'A' && c <= 'Z') {
			output[j++] = c - 'A' + 'a';
		}
		else if (c != '\n' && c != '\r' && c != '\t' && c != ' ') {
			output[j++] = c;
		}

	}

	return j;

}

int DSIG_EXPORT CalculateXKMSAuthenticationKey(unsigned char * input, int inputLen, unsigned char * output, int maxOutputLen) {

	unsigned char keyVal[] = {XKMSAuthenticationValue};

	XSECCryptoKeyHMAC * k = XSECPlatformUtils::g_cryptoProvider->keyHMAC();
	Janitor<XSECCryptoKeyHMAC> j_k(k);
	k->setKey(keyVal, 1);

	XSECCryptoHash *h = XSECPlatformUtils::g_cryptoProvider->hashHMACSHA1();
	Janitor<XSECCryptoHash> j_h(h);
	h->setKey(k);

	// Clean the input
	safeBuffer sb;
	int l = CleanXKMSPassPhrase(input, inputLen, sb);

	h->hash((unsigned char *) sb.rawBuffer(), l);
	return h->finish(output, maxOutputLen);

}

int DSIG_EXPORT CalculateXKMSRevocationCodeIdentifierEncoding1(unsigned char * input, int inputLen, unsigned char * output, int maxOutputLen) {

	unsigned char keyVal[] = {XKMSRevocationCodeIdenfitierEncoding1};

	XSECCryptoKeyHMAC * k = XSECPlatformUtils::g_cryptoProvider->keyHMAC();
	Janitor<XSECCryptoKeyHMAC> j_k(k);
	k->setKey(keyVal, 1);

	XSECCryptoHash *h = XSECPlatformUtils::g_cryptoProvider->hashHMACSHA1();
	Janitor<XSECCryptoHash> j_h(h);

	h->setKey(k);

	// Clean the input
	safeBuffer sb;
	int l = CleanXKMSPassPhrase(input, inputLen, sb);

	h->hash((unsigned char *) sb.rawBuffer(), l);
	return h->finish(output, maxOutputLen);

}

int DSIG_EXPORT CalculateXKMSRevocationCodeIdentifierEncoding2(unsigned char * input, int inputLen, unsigned char * output, int maxOutputLen) {

	unsigned char tmpBuf[XSEC_MAX_HASH_SIZE];
	int tmpLen = CalculateXKMSRevocationCodeIdentifierEncoding1(input, inputLen, tmpBuf, XSEC_MAX_HASH_SIZE);
	return CalculateXKMSRevocationCodeIdentifierEncoding2From1(tmpBuf, tmpLen, output, maxOutputLen);

}

int DSIG_EXPORT CalculateXKMSRevocationCodeIdentifierEncoding2From1(unsigned char * input, int inputLen, unsigned char * output, int maxOutputLen) {

	unsigned char keyVal[] = {XKMSRevocationCodeIdenfitierEncoding2};

	XSECCryptoKeyHMAC * k = XSECPlatformUtils::g_cryptoProvider->keyHMAC();
	Janitor<XSECCryptoKeyHMAC> j_k(k);
	k->setKey(keyVal, 1);

	XSECCryptoHash *h = XSECPlatformUtils::g_cryptoProvider->hashHMACSHA1();
	Janitor<XSECCryptoHash> j_h(h);

	h->setKey(k);

	h->hash(input, inputLen);
	return h->finish(output, maxOutputLen);

}

int DSIG_EXPORT CalculateXKMSKEK(unsigned char * input, int inputLen, unsigned char * output, int maxOutputLen) {

	unsigned char keyVal[] = {XKMSKeyEncryption};

	XSECCryptoKeyHMAC * k = XSECPlatformUtils::g_cryptoProvider->keyHMAC();
	k->setKey(keyVal, 1);

	XSECCryptoHash *h = XSECPlatformUtils::g_cryptoProvider->hashHMACSHA1();
	Janitor<XSECCryptoHash> j_h(h);

	h->setKey(k);

	// Clean the input
	safeBuffer sb;
	int l = CleanXKMSPassPhrase(input, inputLen, sb);

	h->hash((unsigned char *) sb.rawBuffer(), l);
	return h->finish(output, maxOutputLen);

}

// --------------------------------------------------------------------------------
//           Some Base64 helpers
// --------------------------------------------------------------------------------

XMLCh DSIG_EXPORT * EncodeToBase64XMLCh(unsigned char * input, int inputLen) {

	XSECCryptoBase64 * b64 = XSECPlatformUtils::g_cryptoProvider->base64();
	Janitor<XSECCryptoBase64> j_b64(b64);
	unsigned char * output;
	int outputLen = ((4 * inputLen) / 3) + 5;
	XSECnew(output, unsigned char[outputLen]);
	ArrayJanitor<unsigned char> j_output(output);

	b64->encodeInit();
	int j = b64->encode(input, inputLen, output, outputLen - 1);
	j += b64->encodeFinish(&output[j], outputLen - j - 1);

	// Strip any trailing \n\r
	while (j > 0 && (output[j-1] == '\n' || output[j-1] == '\r'))
		j--;

	// Now transcode and get out of here
	output[j] = '\0';
	return XMLString::transcode((char *) output);

}

unsigned int DSIG_EXPORT DecodeFromBase64XMLCh(const XMLCh * input, unsigned char * output, int maxOutputLen) {

	XSECCryptoBase64 * b64 = XSECPlatformUtils::g_cryptoProvider->base64();
	Janitor<XSECCryptoBase64> j_b64(b64);

	char * tinput = XMLString::transcode(input);
	ArrayJanitor<char> j_tinput(tinput);

	b64->decodeInit();
	unsigned int j = b64->decode((unsigned char *) tinput, strlen(tinput), output, maxOutputLen - 1);
	j += b64->decodeFinish(&output[j], maxOutputLen - j - 1);

	return j;
}

unsigned int DSIG_EXPORT DecodeFromBase64(const char * input, unsigned char * output, int maxOutputLen) {

	XSECCryptoBase64 * b64 = XSECPlatformUtils::g_cryptoProvider->base64();
	Janitor<XSECCryptoBase64> j_b64(b64);

	b64->decodeInit();
	unsigned int j = b64->decode((unsigned char *) input, strlen(input), output, maxOutputLen - 1);
	j += b64->decodeFinish(&output[j], maxOutputLen - j - 1);

	return j;
}

// --------------------------------------------------------------------------------
//           Some stuff to help with wierd signatures
// --------------------------------------------------------------------------------

const unsigned char ASNDSAProlog[] = {0x30, 0x2c, 0x02, 0x14};
const unsigned char ASNDSAMiddle[] = {0x02, 0x14};

bool ASN2DSASig(const unsigned char * input, unsigned char * r, unsigned char * s) {

	if (memcmp(ASNDSAProlog, input, 4) != 0 ||
		memcmp(ASNDSAMiddle, &input[24], 2) != 0)

		return false;

	memcpy(r, &input[4], 20);
	memcpy(s, &input[26], 20);

	return true;

}

<commit_msg>Partially implement SASLstringPrep for pass phrases as required for newer versions of XKMS spec<commit_after>/*
 * Copyright 2002-2005 The Apache Software Foundation.
 *
 * 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.
 */

/*
 * XSEC
 *
 * XSECCryptoUtils:= Helper crypo utilities that make life easier
 *
 * Author(s): Berin Lautenbach
 *
 * $Id$
 *
 */

#include <xsec/framework/XSECDefs.hpp>
#include <xsec/framework/XSECError.hpp>
#include <xsec/enc/XSECCryptoUtils.hpp>
#include <xsec/enc/XSECCryptoKeyHMAC.hpp>
#include <xsec/utils/XSECPlatformUtils.hpp>
#include <xsec/utils/XSECDOMUtils.hpp>

#include <xercesc/util/Janitor.hpp>
#include <xercesc/util/XMLString.hpp>
#include <xercesc/util/XMLUniDefs.hpp>

XERCES_CPP_NAMESPACE_USE

// --------------------------------------------------------------------------------
//           XKMS Limited-Use Shared Secret handling
// --------------------------------------------------------------------------------

int CleanXKMSPassPhrase(unsigned char * input, int inputLen, safeBuffer &output) {

	// Now obsolete - use SASLCleanXKMSPassPhrase instead
	int j = 0;
	unsigned char c;
	for (int i = 0; i < inputLen; ++i) {

		c = input[i];

		if (c >= 'A' && c <= 'Z') {
			output[j++] = c - 'A' + 'a';
		}
		else if (c != '\n' && c != '\r' && c != '\t' && c != ' ') {
			output[j++] = c;
		}

	}

	return j;

}

int SASLCleanXKMSPassPhrase(unsigned char * input, int inputLen, safeBuffer &output) {

	// For now - this does *not* implement the full SASLPrep algorithm.
	// THe NFKC form is not trivial to implement - so this is kept very simple.
	// TODO - Fix this - it can be an interoperability issue as pass phrases from
	// different implementations could be treated differently.
	// Currently we only check for prohibited unput for chars < 0xFFFF and drop any
	// chars over 0xFFFF

	XMLCh * uinput, *uoutput;
	unsigned char * inp = new unsigned char[inputLen + 1];
	ArrayJanitor<unsigned char> j_inp(inp);
	memcpy(inp, input, inputLen);
	inp[inputLen] = '\0';

	uinput = XMLString::transcode((char *) inp);
	unsigned int l = XMLString::stringLen(uinput);
	uoutput = new XMLCh[l + 1];
	ArrayJanitor<XMLCh> j_uinput(uinput);
	ArrayJanitor<XMLCh> j_uoutput(uoutput);

	unsigned int i, j;
	j = 0;

	XMLCh ch1;

	for (i = 0; i < l; ++i) {

		ch1 = uinput[i];
		// Case one - char is < 0x10000
		if (ch1 < 0xD800 || ch1 > 0xDFFF) {

			// OK - ch1 is "real" value - let's see if it is legal
			// The following switch tables are derived from
			// RFC 3454 - see http://www.ietf.org/rfc/rfc3454.txt

			// Non-ASCII Spaces - C.1.2
			switch (ch1) {

			case 0x00A0:		// NO-BREAK SPACE
			case 0x1680:		// OGHAM SPACE MARK
			case 0x2000:		// EN QUAD
			case 0x2001:		// EM QUAD
			case 0x2002:		// EN SPACE
			case 0x2003:		// EM SPACE
			case 0x2004:		// THREE-PER-EM SPACE
			case 0x2005:		// FOUR-PER-EM SPACE
			case 0x2006:		// SIX-PER-EM SPACE
			case 0x2007:		// FIGURE SPACE
			case 0x2008:		// PUNCTUATION SPACE
			case 0x2009:		// THIN SPACE
			case 0x200A:		// HAIR SPACE
			case 0x200B:		// ZERO WIDTH SPACE
			case 0x202F:		// NARROW NO-BREAK SPACE
			case 0x205F:		// MEDIUM MATHEMATICAL SPACE
			case 0x3000:		// IDEOGRAPHIC SPACE

				throw XSECException(XSECException::XKMSError,
					"SASLCleanXKMSPassPhrase - Non ASCII space character in XKMS pass phrase");
			default:

				break;

			}

			// ASCII Control characters
			if ((ch1 >=0 && ch1 <= 0x1F) || ch1 == 0x7F) {
				throw XSECException(XSECException::XKMSError,
					"SASLCleanXKMSPassPhrase - ASCII control character in XKMS pass phrase");
			}

			// Non-ASCII Control Characters
			if ((ch1 >= 0x80 && ch1 <= 0x9F) ||
				(ch1 >= 0x206A && ch1 <= 0x206F) ||
				(ch1 >= 0xFFF9 && ch1 <= 0xFFFC)) {

				throw XSECException(XSECException::XKMSError,
					"SASLCleanXKMSPassPhrase - NON ASCII control character in XKMS pass phrase");
			}

			switch (ch1) {

			case 0x06DD:		// ARABIC END OF AYAH
			case 0x070F:		// SYRIAC ABBREVIATION MARK
			case 0x180E:		// MONGOLIAN VOWEL SEPARATOR
			case 0x200C:		// ZERO WIDTH NON-JOINER
			case 0x200D:		// ZERO WIDTH JOINER
			case 0x2028:		// LINE SEPARATOR
			case 0x2029:		// PARAGRAPH SEPARATOR
			case 0x2060:		// WORD JOINER
			case 0x2061:		// FUNCTION APPLICATION
			case 0x2062:		// INVISIBLE TIMES
			case 0x2063:		// INVISIBLE SEPARATOR
			case 0xFEFF:		// ZERO WIDTH NO-BREAK SPACE
				throw XSECException(XSECException::XKMSError,
					"SASLCleanXKMSPassPhrase - NON ASCII control character in XKMS pass phrase");
			default:
				break;			}
		    // 1D173-1D17A; [MUSICAL CONTROL CHARACTERS] is not relevant as we are looking at
		    // ch1 at the moment

			// Private Use characters
			if ((ch1 >= 0xE000 && ch1 <= 0xF8FF)) {

				throw XSECException(XSECException::XKMSError,
					"SASLCleanXKMSPassPhrase - Private Use character in XKMS pass phrase");
			}

			// Non-character code points
			if ((ch1 >= 0xFDD0 && ch1 <= 0xFDEF) ||
				(ch1 >= 0xFFFE && ch1 <= 0xFFFF)) {

				throw XSECException(XSECException::XKMSError,
					"SASLCleanXKMSPassPhrase - Non-character code points in XKMS pass phrase");
			}

			// Inappropriate for plain text characters

			switch (ch1) {
			case 0xFFF9:		// INTERLINEAR ANNOTATION ANCHOR
			case 0xFFFA:		// INTERLINEAR ANNOTATION SEPARATOR
			case 0xFFFB:		// INTERLINEAR ANNOTATION TERMINATOR
			case 0xFFFC:		// OBJECT REPLACEMENT CHARACTER
			case 0xFFFD:		// REPLACEMENT CHARACTER
				throw XSECException(XSECException::XKMSError,
					"SASLCleanXKMSPassPhrase - Innappropriate for plain text chararcters in XKMS pass phrase");
			default:
				break;
			}

			// Inappripriate for canonical representation characters
			if (ch1 >= 0x2FF0 && ch1 <= 0x2FFB) {
				throw XSECException(XSECException::XKMSError,
					"SASLCleanXKMSPassPhrase - Innappropriate for canonicalisation chararcters in XKMS pass phrase");
			}

			// Change display properties or are deprecated
			switch (ch1) {
			case 0x0340:		// COMBINING GRAVE TONE MARK
			case 0x0341:		// COMBINING ACUTE TONE MARK
			case 0x200E:		// LEFT-TO-RIGHT MARK
			case 0x200F:		// RIGHT-TO-LEFT MARK
			case 0x202A:		// LEFT-TO-RIGHT EMBEDDING
			case 0x202B:		// RIGHT-TO-LEFT EMBEDDING
			case 0x202C:		// POP DIRECTIONAL FORMATTING
			case 0x202D:		// LEFT-TO-RIGHT OVERRIDE
			case 0x202E:		// RIGHT-TO-LEFT OVERRIDE
			case 0x206A:		// INHIBIT SYMMETRIC SWAPPING
			case 0x206B:		// ACTIVATE SYMMETRIC SWAPPING
			case 0x206C:		// INHIBIT ARABIC FORM SHAPING
			case 0x206D:		// ACTIVATE ARABIC FORM SHAPING
			case 0x206E:		// NATIONAL DIGIT SHAPES
			case 0x206F:		// NOMINAL DIGIT SHAPES
				throw XSECException(XSECException::XKMSError,
					"SASLCleanXKMSPassPhrase - change display or deprecated chararcters in XKMS pass phrase");
			default:
				break;
			}

			// We got this far = just run with it for now
			uoutput[j++] = ch1;
		}
		else {
			throw XSECException(XSECException::XKMSError,
				"SASLCleanXKMSPassPhrase - don't support XKMS pass phrase chars > 0xFFFF");
		}
	} /* for */
	uoutput[j++] = chNull;

	// Now transcode
	char * utf8output= transcodeToUTF8(uoutput);
	ArrayJanitor<char> j_utf8output(utf8output);
	output.sbStrcpyIn(utf8output);

	return strlen(utf8output);

}

int DSIG_EXPORT CalculateXKMSAuthenticationKey(unsigned char * input, int inputLen, unsigned char * output, int maxOutputLen) {

	unsigned char keyVal[] = {XKMSAuthenticationValue};

	XSECCryptoKeyHMAC * k = XSECPlatformUtils::g_cryptoProvider->keyHMAC();
	Janitor<XSECCryptoKeyHMAC> j_k(k);
	k->setKey(keyVal, 1);

	XSECCryptoHash *h = XSECPlatformUtils::g_cryptoProvider->hashHMACSHA1();
	Janitor<XSECCryptoHash> j_h(h);
	h->setKey(k);

	// Clean the input
	safeBuffer sb;
	int l = CleanXKMSPassPhrase(input, inputLen, sb);

	h->hash((unsigned char *) sb.rawBuffer(), l);
	return h->finish(output, maxOutputLen);

}

int DSIG_EXPORT CalculateXKMSRevocationCodeIdentifierEncoding1(unsigned char * input, int inputLen, unsigned char * output, int maxOutputLen) {

	unsigned char keyVal[] = {XKMSRevocationCodeIdenfitierEncoding1};

	XSECCryptoKeyHMAC * k = XSECPlatformUtils::g_cryptoProvider->keyHMAC();
	Janitor<XSECCryptoKeyHMAC> j_k(k);
	k->setKey(keyVal, 1);

	XSECCryptoHash *h = XSECPlatformUtils::g_cryptoProvider->hashHMACSHA1();
	Janitor<XSECCryptoHash> j_h(h);

	h->setKey(k);

	// Clean the input
	safeBuffer sb;
	int l = CleanXKMSPassPhrase(input, inputLen, sb);

	h->hash((unsigned char *) sb.rawBuffer(), l);
	return h->finish(output, maxOutputLen);

}

int DSIG_EXPORT CalculateXKMSRevocationCodeIdentifierEncoding2(unsigned char * input, int inputLen, unsigned char * output, int maxOutputLen) {

	unsigned char tmpBuf[XSEC_MAX_HASH_SIZE];
	int tmpLen = CalculateXKMSRevocationCodeIdentifierEncoding1(input, inputLen, tmpBuf, XSEC_MAX_HASH_SIZE);
	return CalculateXKMSRevocationCodeIdentifierEncoding2From1(tmpBuf, tmpLen, output, maxOutputLen);

}

int DSIG_EXPORT CalculateXKMSRevocationCodeIdentifierEncoding2From1(unsigned char * input, int inputLen, unsigned char * output, int maxOutputLen) {

	unsigned char keyVal[] = {XKMSRevocationCodeIdenfitierEncoding2};

	XSECCryptoKeyHMAC * k = XSECPlatformUtils::g_cryptoProvider->keyHMAC();
	Janitor<XSECCryptoKeyHMAC> j_k(k);
	k->setKey(keyVal, 1);

	XSECCryptoHash *h = XSECPlatformUtils::g_cryptoProvider->hashHMACSHA1();
	Janitor<XSECCryptoHash> j_h(h);

	h->setKey(k);

	h->hash(input, inputLen);
	return h->finish(output, maxOutputLen);

}

int DSIG_EXPORT CalculateXKMSKEK(unsigned char * input, int inputLen, unsigned char * output, int maxOutputLen) {

	unsigned char keyVal[] = {XKMSKeyEncryption};
	unsigned char shaOutput[22];	// SHA1 has 20 bytes of output

	// Clean the input
	safeBuffer sb;
	int l = SASLCleanXKMSPassPhrase(input, inputLen, sb);

	// Need to iterate through until we have enough data
	int bytesDone = 0, bytesToDo;;
	shaOutput[0] = keyVal[0];
	int keyLen = 1;
	while (bytesDone < maxOutputLen) {
		XSECCryptoKeyHMAC * k = XSECPlatformUtils::g_cryptoProvider->keyHMAC();
		k->setKey(shaOutput, keyLen);

		XSECCryptoHash *h = XSECPlatformUtils::g_cryptoProvider->hashHMACSHA1();
		Janitor<XSECCryptoHash> j_h(h);

		h->setKey(k);
		delete(k);

		// Now hash next round of data
		h->hash((unsigned char *) sb.rawBuffer(), l);
		keyLen = h->finish(shaOutput, 22);

		// Copy into the output buffer
		bytesToDo = maxOutputLen - bytesDone;
		bytesToDo = bytesToDo > 20 ? 20 : bytesToDo;
		memcpy(&output[bytesDone], shaOutput, bytesToDo);
		bytesDone += bytesToDo;

		// Set up for next key
		shaOutput[0] ^= keyVal[0];
		keyLen = 20;

		j_h.release();
		delete h;
	}

	return bytesDone;

}

// --------------------------------------------------------------------------------
//           Some Base64 helpers
// --------------------------------------------------------------------------------

XMLCh DSIG_EXPORT * EncodeToBase64XMLCh(unsigned char * input, int inputLen) {

	XSECCryptoBase64 * b64 = XSECPlatformUtils::g_cryptoProvider->base64();
	Janitor<XSECCryptoBase64> j_b64(b64);
	unsigned char * output;
	int outputLen = ((4 * inputLen) / 3) + 5;
	XSECnew(output, unsigned char[outputLen]);
	ArrayJanitor<unsigned char> j_output(output);

	b64->encodeInit();
	int j = b64->encode(input, inputLen, output, outputLen - 1);
	j += b64->encodeFinish(&output[j], outputLen - j - 1);

	// Strip any trailing \n\r
	while (j > 0 && (output[j-1] == '\n' || output[j-1] == '\r'))
		j--;

	// Now transcode and get out of here
	output[j] = '\0';
	return XMLString::transcode((char *) output);

}

unsigned int DSIG_EXPORT DecodeFromBase64XMLCh(const XMLCh * input, unsigned char * output, int maxOutputLen) {

	XSECCryptoBase64 * b64 = XSECPlatformUtils::g_cryptoProvider->base64();
	Janitor<XSECCryptoBase64> j_b64(b64);

	char * tinput = XMLString::transcode(input);
	ArrayJanitor<char> j_tinput(tinput);

	b64->decodeInit();
	unsigned int j = b64->decode((unsigned char *) tinput, strlen(tinput), output, maxOutputLen - 1);
	j += b64->decodeFinish(&output[j], maxOutputLen - j - 1);

	return j;
}

unsigned int DSIG_EXPORT DecodeFromBase64(const char * input, unsigned char * output, int maxOutputLen) {

	XSECCryptoBase64 * b64 = XSECPlatformUtils::g_cryptoProvider->base64();
	Janitor<XSECCryptoBase64> j_b64(b64);

	b64->decodeInit();
	unsigned int j = b64->decode((unsigned char *) input, strlen(input), output, maxOutputLen - 1);
	j += b64->decodeFinish(&output[j], maxOutputLen - j - 1);

	return j;
}

// --------------------------------------------------------------------------------
//           Some stuff to help with wierd signatures
// --------------------------------------------------------------------------------

const unsigned char ASNDSAProlog[] = {0x30, 0x2c, 0x02, 0x14};
const unsigned char ASNDSAMiddle[] = {0x02, 0x14};

bool ASN2DSASig(const unsigned char * input, unsigned char * r, unsigned char * s) {

	if (memcmp(ASNDSAProlog, input, 4) != 0 ||
		memcmp(ASNDSAMiddle, &input[24], 2) != 0)

		return false;

	memcpy(r, &input[4], 20);
	memcpy(s, &input[26], 20);

	return true;

}

<|endoftext|>