<commit_before>#define _USE_MATH_DEFINES
#include <iostream>
#include <cmath>
#include <cstdlib>
#include <cassert>
#include <vector>
#include <numeric>
#include <limits>

using namespace std;

struct point{
	double _x, _y;
	point(double x=0.0, double y=0.0) :_x(x), _y(y){};
	bool in(double x1,double x2, double y1,double y2) const{
		return _x >= x1&&_x <= x2&&_y >= y1&&_y <= y2;
	}
	point operator*(const point& p) const{
		return point(_x*p._x, _y*p._y);
	}
	point operator*(double d) const{
		return point(_x*d, _y*d);
	}
	point operator+(const point& p) const{
		return point(_x+p._x, _y+p._y);
	}
};

point operator*(double d, const point& p) {
	return p*d;
}

template <typename T>
class RV{
public:
	virtual T generate() = 0;
	virtual double pdf(const T &) = 0;
	virtual double cdf(const T &) = 0;
};

class uniform2d :public RV<point>{
	double _a1, _b1,_a2, _b2;
public:
	uniform2d(double a1 = 0.0, double b1 = 1.0, double a2 = 0.0, double b2 = 1.0) :
		_a1(a1), _b1(b1), _a2(a2), _b2(b2){
		assert(a1 < b1 && "a<b!"); assert(a2 < b2 && "a<b!");
	};
	point generate(){
		double x = static_cast<double>(rand()) / RAND_MAX*(_b1 - _a1) + _a1;
		double y = static_cast<double>(rand()) / RAND_MAX*(_b2 - _a2) + _a2;
		return point(x,y);
	};
	double pdf(const point& p){
		return (p._x >= _a1 && p._x <= _b1 && p._y >= _a2 && p._y <= _b2) ? 1.0 / (_b1 - _a1) / (_b2 - _a2) : 0.0;
	};
	double cdf(const point& p) {
		assert(false && "looooool it's a joke. i don't know how to do that");
		return 0;
	};
};

class normal2d : public RV<point>{
	uniform2d _gen;
	point _u, _s;
public:
	normal2d(const point& u = point(), const point& s = point(1,1)) :_u(u), _s(s){};
	point generate(){
		const double epsilon = numeric_limits<double>::min();
		point u1, u2;
		do
		{
			u1 = _gen.generate();
			u2 = _gen.generate();
		} while (u2._x <= epsilon || u2._y <= epsilon);
		point r = -2.0*point(log(u2._x), log(u2._y));
		return point(sqrt(r._x),sqrt(r._y))*point(cos(2 * M_PI*u1._x), cos(2 * M_PI*u1._y))*_s + _u;
	};
	double pdf(const point & p){
		return 1.0 / 2.0 / _s._x / _s._y*exp(-0.5*((p._x - _u._x)*(p._x - _u._x) / _s._x / _s._x + (p._y - _u._y)*(p._y - _u._y) / _s._y / _s._y));
	};
	double cdf(const point & x) {
		assert(false && "that's impossible!");
		return 0;
	};
};

double indicator(const point& p, double x1, double x2, double y1, double y2){
	return p.in(x1, x2, y1, y2);
}

template <typename T>
double mc(double(*f)(const T&), RV<T>& dist,
	double x1 = 0.0, double x2 = 1.0, double y1 = 0.0, double y2 = 1.0, unsigned int n = 1000){
	double s = 0.0;
	for (size_t i = 0; i < n; i++)
	{
		T x = dist.generate();
		s += f(x) / dist.pdf(x)*indicator(x, x1, x2, y1, y2);
	}
	return s / n;
}

double c(const point& x){
	return 1.0;
}

double nexp(const point& p){ // change variable
	return (exp(-p._x) + exp(-1.0 / p._x) / p._x / p._x)*p._y;
}

double mean(const vector<double>& v){
	double sum = accumulate(v.begin(), v.end(), 0.0);
	return sum / v.size();
}

double var(const vector<double>& v){
	double m = mean(v);
	double var = 0.0;
	for (size_t i = 0; i < v.size(); i++)
	{
		var += (v[i] - m)*(v[i] - m);
	}
	return var / v.size();
}

double h(const point& p){
	double x = p._x;
	double y = p._y;
	return exp(-x*x+x*y)*cos(x*M_PI)*sin(y*M_PI);
}

void monte_carlo(vector<double>& v, RV<point>& dist, double x1 = 0.0, double x2 = 1.0, double y1 = 0.0, double y2 = 1.0, unsigned int n=1000){
	v.clear();
	for (size_t i = 0; i < 100; i++)
	{
		v.push_back(mc<point>(h, dist, x1, x2, y1, y2, n));
	}
	cout << mean(v) << endl;
	cout << var(v) << endl;
}

int main(){
	uniform2d u_c(-4.0, 4.0, 0.25, 1.0);
	cout << mc<point>(c, u_c,-4.0,4.0,0.25,1.0) << endl;

	uniform2d u_nexp;
	cout << mc<point>(nexp, u_nexp, 0,1,0,1,10000) << endl;

	uniform2d u_f(-3.0, 3.0,-1.0,1.0);
	vector<double> w;
	monte_carlo(w, u_f, -3.0, 3.0, -1.0, 1.0, 100);
	monte_carlo(w, u_f, -3.0, 3.0, -1.0, 1.0, 1000);
	monte_carlo(w, u_f, -3.0, 3.0, -1.0, 1.0, 10000);

	normal2d n_std;
	monte_carlo(w, n_std, -3.0, 3.0, -1.0, 1.0, 100);
	monte_carlo(w, n_std, -3.0, 3.0, -1.0, 1.0, 1000);
	monte_carlo(w, n_std, -3.0, 3.0, -1.0, 1.0, 10000);

	normal2d n_pi(point(M_PI / 2.0, M_PI / 2.0), point(1, 1));
	monte_carlo(w, n_pi, -3.0, 3.0, -1.0, 1.0, 100);
	monte_carlo(w, n_pi, -3.0, 3.0, -1.0, 1.0, 1000);
	monte_carlo(w, n_pi, -3.0, 3.0, -1.0, 1.0, 10000);

	return 0;
}<commit_msg>pi was missing in pdf<commit_after>#define _USE_MATH_DEFINES
#include <iostream>
#include <cmath>
#include <cstdlib>
#include <cassert>
#include <vector>
#include <numeric>
#include <limits>

using namespace std;

struct point{
	double _x, _y;
	point(double x=0.0, double y=0.0) :_x(x), _y(y){};
	bool in(double x1,double x2, double y1,double y2) const{
		return _x >= x1&&_x <= x2&&_y >= y1&&_y <= y2;
	}
	point operator*(const point& p) const{
		return point(_x*p._x, _y*p._y);
	}
	point operator*(double d) const{
		return point(_x*d, _y*d);
	}
	point operator+(const point& p) const{
		return point(_x+p._x, _y+p._y);
	}
};

point operator*(double d, const point& p) {
	return p*d;
}

template <typename T>
class RV{
public:
	virtual T generate() = 0;
	virtual double pdf(const T &) = 0;
	virtual double cdf(const T &) = 0;
};

class uniform2d :public RV<point>{
	double _a1, _b1,_a2, _b2;
public:
	uniform2d(double a1 = 0.0, double b1 = 1.0, double a2 = 0.0, double b2 = 1.0) :
		_a1(a1), _b1(b1), _a2(a2), _b2(b2){
		assert(a1 < b1 && "a<b!"); assert(a2 < b2 && "a<b!");
	};
	point generate(){
		double x = static_cast<double>(rand()) / RAND_MAX*(_b1 - _a1) + _a1;
		double y = static_cast<double>(rand()) / RAND_MAX*(_b2 - _a2) + _a2;
		return point(x,y);
	};
	double pdf(const point& p){
		return (p._x >= _a1 && p._x <= _b1 && p._y >= _a2 && p._y <= _b2) ? 1.0 / (_b1 - _a1) / (_b2 - _a2) : 0.0;
	};
	double cdf(const point& p) {
		assert(false && "looooool it's a joke. i don't know how to do that");
		return 0;
	};
};

class normal2d : public RV<point>{
	uniform2d _gen;
	point _u, _s;
public:
	normal2d(const point& u = point(), const point& s = point(1,1)) :_u(u), _s(s){};
	point generate(){
		const double epsilon = numeric_limits<double>::min();
		point u1, u2;
		do
		{
			u1 = _gen.generate();
			u2 = _gen.generate();
		} while (u2._x <= epsilon || u2._y <= epsilon);
		point r = -2.0*point(log(u2._x), log(u2._y));
		return point(sqrt(r._x),sqrt(r._y))*point(cos(2 * M_PI*u1._x), cos(2 * M_PI*u1._y))*_s + _u;
	};
	double pdf(const point & p){
		return 1.0 / 2.0 / M_PI/ _s._x / _s._y*exp(-0.5*((p._x - _u._x)*(p._x - _u._x) / _s._x / _s._x + (p._y - _u._y)*(p._y - _u._y) / _s._y / _s._y));
	};
	double cdf(const point & x) {
		assert(false && "that's impossible!");
		return 0;
	};
};

double indicator(const point& p, double x1, double x2, double y1, double y2){
	return p.in(x1, x2, y1, y2);
}

template <typename T>
double mc(double(*f)(const T&), RV<T>& dist,
	double x1 = 0.0, double x2 = 1.0, double y1 = 0.0, double y2 = 1.0, unsigned int n = 1000){
	double s = 0.0;
	for (size_t i = 0; i < n; i++)
	{
		T x = dist.generate();
		s += f(x) / dist.pdf(x)*indicator(x, x1, x2, y1, y2);
	}
	return s / n;
}

double c(const point& x){
	return 1.0;
}

double nexp(const point& p){ // change variable
	return (exp(-p._x) + exp(-1.0 / p._x) / p._x / p._x)*p._y;
}

double mean(const vector<double>& v){
	double sum = accumulate(v.begin(), v.end(), 0.0);
	return sum / v.size();
}

double var(const vector<double>& v){
	double m = mean(v);
	double var = 0.0;
	for (size_t i = 0; i < v.size(); i++)
	{
		var += (v[i] - m)*(v[i] - m);
	}
	return var / v.size();
}

double h(const point& p){
	double x = p._x;
	double y = p._y;
	return exp(-x*x+x*y)*cos(x*M_PI)*sin(y*M_PI);
}

void monte_carlo(vector<double>& v, RV<point>& dist, double x1 = 0.0, double x2 = 1.0, double y1 = 0.0, double y2 = 1.0, unsigned int n=1000){
	v.clear();
	for (size_t i = 0; i < 100; i++)
	{
		v.push_back(mc<point>(h, dist, x1, x2, y1, y2, n));
	}
	cout << mean(v) << endl;
	cout << var(v) << endl;
}

int main(){
	uniform2d u_c(-4.0, 4.0, 0.25, 1.0);
	cout << mc<point>(c, u_c,-4.0,4.0,0.25,1.0) << endl;

	uniform2d u_nexp;
	cout << mc<point>(nexp, u_nexp, 0,1,0,1,10000) << endl;

	uniform2d u_f(-3.0, 3.0,-1.0,1.0);
	vector<double> w;
	monte_carlo(w, u_f, -3.0, 3.0, -1.0, 1.0, 100);
	monte_carlo(w, u_f, -3.0, 3.0, -1.0, 1.0, 1000);
	monte_carlo(w, u_f, -3.0, 3.0, -1.0, 1.0, 10000);

	normal2d n_std;
	monte_carlo(w, n_std, -3.0, 3.0, -1.0, 1.0, 100);
	monte_carlo(w, n_std, -3.0, 3.0, -1.0, 1.0, 1000);
	monte_carlo(w, n_std, -3.0, 3.0, -1.0, 1.0, 10000);

	normal2d n_pi(point(M_PI / 2.0, M_PI / 2.0), point(1, 1));
	monte_carlo(w, n_pi, -3.0, 3.0, -1.0, 1.0, 100);
	monte_carlo(w, n_pi, -3.0, 3.0, -1.0, 1.0, 1000);
	monte_carlo(w, n_pi, -3.0, 3.0, -1.0, 1.0, 10000);

	return 0;
}<|endoftext|>


<commit_before>#include "HTTPSession.h"
#include "Application/HTTP/UrlParam.h"
#include "Application/HTTP/HTTPRequest.h"
#include "Application/HTTP/HTTPConnection.h"
#include "Application/HTTP/HTTPConsts.h"

#define MSG_FAIL     "Unable to process your request at this time"

HTTPSession::HTTPSession()
{
    headerSent = false;
    conn = NULL;
    type = PLAIN;
}

void HTTPSession::SetConnection(HTTPConnection* conn_)
{
    conn = conn_;
    if (conn != NULL)
        json.Init(conn);
}

bool HTTPSession::ParseRequest(HTTPRequest& request, ReadBuffer& cmd, UrlParam& params)
{
    char*       qmark;
    ReadBuffer  rb;
    ReadBuffer  jsonCallback;

    rb = request.line.uri;
    if (rb.GetCharAt(0) == '/')
        rb.Advance(1);

    ParseType(rb);
    cmd = rb;

    qmark = NULL;
    if (rb.GetLength() > 0)
        qmark = FindInBuffer(rb.GetBuffer(), rb.GetLength() - 1, '?');

    if (qmark)
    {
        rb.Advance(qmark - rb.GetBuffer() + 1);
        params.Init(rb.GetBuffer(), rb.GetLength(), '&');
        cmd.SetLength(qmark - cmd.GetBuffer());

        if (type == JSON)
        {
            HTTP_GET_OPT_PARAM(params, "callback", jsonCallback);
            json.SetCallbackPrefix(jsonCallback);
        }
    }

    return true;
}

void HTTPSession::ParseType(ReadBuffer& rb)
{
    const char  JSON_PREFIX[] = "json/";
    const char  HTML_PREFIX[] = "html/";

    type = PLAIN;

    if (HTTP_MATCH_COMMAND(rb, JSON_PREFIX))
    {
        type = JSON;
        rb.Advance(sizeof(JSON_PREFIX) - 1);
    }
    else if (HTTP_MATCH_COMMAND(rb, HTML_PREFIX))
    {
        type = HTML;
        rb.Advance(sizeof(HTML_PREFIX) - 1);
    }
}

void HTTPSession::ResponseFail()
{
    assert(headerSent == false);
    if (!conn)
        return;

    if (type == JSON)
        json.PrintStatus("error", MSG_FAIL);
    else
        conn->Response(HTTP_STATUS_CODE_OK, MSG_FAIL, sizeof(MSG_FAIL) - 1);
}

void HTTPSession::PrintLine(const ReadBuffer& line)
{
    if (!conn)
        return;

    if (!headerSent)
    {
        if (type == JSON)
            json.Start();
        else
            conn->ResponseHeader(HTTP_STATUS_CODE_OK, false);

        headerSent = true;
    }

    if (type == JSON)
        json.PrintString(line.GetBuffer(), line.GetLength());
    else
        conn->Write(line.GetBuffer(), line.GetLength());
}

void HTTPSession::PrintPair(const ReadBuffer& key, const ReadBuffer& value)
{
    if (!conn)
        return;

    if (!headerSent)
    {
        if (type == JSON)
            json.Start();
        else
            conn->ResponseHeader(HTTP_STATUS_CODE_OK, false);

        headerSent = true;
    }

    if (type == JSON)
        json.PrintPair(key.GetBuffer(), key.GetLength(), value.GetBuffer(), value.GetLength());
    else
    {
        conn->Write(key.GetBuffer(), key.GetLength());
        conn->Print(": ");
        conn->Write(value.GetBuffer(), value.GetLength());
        conn->Print("\n");
    }
}

void HTTPSession::PrintPair(const char* key, const char* value)
{
    PrintPair(ReadBuffer(key), ReadBuffer(value));
}

void HTTPSession::Flush()
{
    if (!conn)
        return;

    if (type == JSON)
        json.End();

    conn->Flush(true);
}

<commit_msg>Fixed HTTP content type in HTTPSession.<commit_after>#include "HTTPSession.h"
#include "Application/HTTP/UrlParam.h"
#include "Application/HTTP/HTTPRequest.h"
#include "Application/HTTP/HTTPConnection.h"
#include "Application/HTTP/HTTPConsts.h"
#include "Application/HTTP/Mime.h"

#define MSG_FAIL            "Unable to process your request at this time"
#define CONTENT_TYPE_PLAIN  HTTP_HEADER_CONTENT_TYPE ": " MIME_TYPE_TEXT_PLAIN HTTP_CS_CRLF
#define CONTENT_TYPE_HTML   HTTP_HEADER_CONTENT_TYPE ": " MIME_TYPE_TEXT_HTML HTTP_CS_CRLF

HTTPSession::HTTPSession()
{
    headerSent = false;
    conn = NULL;
    type = PLAIN;
}

void HTTPSession::SetConnection(HTTPConnection* conn_)
{
    conn = conn_;
    if (conn != NULL)
        json.Init(conn);
}

bool HTTPSession::ParseRequest(HTTPRequest& request, ReadBuffer& cmd, UrlParam& params)
{
    char*       qmark;
    ReadBuffer  rb;
    ReadBuffer  jsonCallback;

    rb = request.line.uri;
    if (rb.GetCharAt(0) == '/')
        rb.Advance(1);

    ParseType(rb);
    cmd = rb;

    qmark = NULL;
    if (rb.GetLength() > 0)
        qmark = FindInBuffer(rb.GetBuffer(), rb.GetLength() - 1, '?');

    if (qmark)
    {
        rb.Advance(qmark - rb.GetBuffer() + 1);
        params.Init(rb.GetBuffer(), rb.GetLength(), '&');
        cmd.SetLength(qmark - cmd.GetBuffer());

        if (type == JSON)
        {
            HTTP_GET_OPT_PARAM(params, "callback", jsonCallback);
            json.SetCallbackPrefix(jsonCallback);
        }
    }

    return true;
}

void HTTPSession::ParseType(ReadBuffer& rb)
{
    const char  JSON_PREFIX[] = "json/";
    const char  HTML_PREFIX[] = "html/";

    type = PLAIN;

    if (HTTP_MATCH_COMMAND(rb, JSON_PREFIX))
    {
        type = JSON;
        rb.Advance(sizeof(JSON_PREFIX) - 1);
    }
    else if (HTTP_MATCH_COMMAND(rb, HTML_PREFIX))
    {
        type = HTML;
        rb.Advance(sizeof(HTML_PREFIX) - 1);
    }
}

void HTTPSession::ResponseFail()
{
    assert(headerSent == false);
    if (!conn)
        return;

    if (type == JSON)
        json.PrintStatus("error", MSG_FAIL);
    else
        conn->Response(HTTP_STATUS_CODE_OK, MSG_FAIL, sizeof(MSG_FAIL) - 1);
}

void HTTPSession::PrintLine(const ReadBuffer& line)
{
    Buffer  header;

    if (!conn)
        return;

    if (!headerSent)
    {
        if (type == JSON)
            json.Start();
        else
            conn->ResponseHeader(HTTP_STATUS_CODE_OK, false,
             type == PLAIN ? CONTENT_TYPE_PLAIN : CONTENT_TYPE_HTML);

        headerSent = true;
    }

    if (type == JSON)
        json.PrintString(line.GetBuffer(), line.GetLength());
    else
        conn->Write(line.GetBuffer(), line.GetLength());
}

void HTTPSession::PrintPair(const ReadBuffer& key, const ReadBuffer& value)
{
    if (!conn)
        return;

    if (!headerSent)
    {
        if (type == JSON)
            json.Start();
        else
            conn->ResponseHeader(HTTP_STATUS_CODE_OK, false,
             type == PLAIN ? CONTENT_TYPE_PLAIN : CONTENT_TYPE_HTML);

        headerSent = true;
    }

    if (type == JSON)
        json.PrintPair(key.GetBuffer(), key.GetLength(), value.GetBuffer(), value.GetLength());
    else
    {
        conn->Write(key.GetBuffer(), key.GetLength());
        conn->Print(": ");
        conn->Write(value.GetBuffer(), value.GetLength());
        conn->Print("\n");
    }
}

void HTTPSession::PrintPair(const char* key, const char* value)
{
    PrintPair(ReadBuffer(key), ReadBuffer(value));
}

void HTTPSession::Flush()
{
    if (!conn)
        return;

    if (type == JSON)
        json.End();

    conn->Flush(true);
}

<|endoftext|>


<commit_before>#include "elsa_parser.h"

namespace elsa {
	namespace compiler {

		ElsaParser::ElsaParser(Lexer* lexer)
			:
			lexer_(std::unique_ptr<Lexer>(lexer)),
			current_scope_(nullptr),
			type_checker_(this),
			program_(std::make_unique<Program>()),
			struct_table_ext_(nullptr),
			function_table_ext_(nullptr),
			current_type_(nullptr)
		{
			initialize_grammar();
			next_token();
			Builtin::init(&struct_table_);
		}

		std::unique_ptr<Program> ElsaParser::parse()
		{
			while (current_token_->get_type() != TokenType::END)
			{
				program_->add_statement(parse_statement());
			}

			return std::move(program_);
		}

		std::unique_ptr<Expression> ElsaParser::parse_statement()
		{
			if (current_token_->get_type() == TokenType::Import)
				parse_import_statement();

			auto parser = get_statement_parser(current_token_->get_type());

			if (parser == nullptr)
				throw ParsingException(L"Invalid token", current_token_.get());

			return parser->parse(this);
		}

		std::unique_ptr<Expression> ElsaParser::parse_expression()
		{
			return parse_expression(0);
		}

		std::unique_ptr<Expression> ElsaParser::parse_expression(int precedence)
		{
			Parser* parser = nullptr;

			parser = get_ll2_expression_parser(current_token_->get_type(), peek_token()->get_type());
			if (parser == nullptr)
				parser = get_expression_parser(current_token_->get_type());

			if (parser == nullptr)
				throw ParsingException(L"Invalid token", current_token_.get());

			auto left = std::unique_ptr<Expression>(parser->parse(this));

			while (precedence < get_precedence())
			{
				auto infix_parser = get_infix_parser(current_token()->get_type());
				left = std::unique_ptr<Expression>(infix_parser->parse(this, std::move(left)));
			}

			return left;
		}

		ScopedExpression* ElsaParser::current_scope()
		{
			if (current_scope_ == nullptr)
				throw ParsingException(L"No scope defined", current_token_.get());

			return current_scope_;
		}

		void ElsaParser::set_current_scope(ScopedExpression* scope)
		{
			current_scope_ = scope;
		}

		void ElsaParser::reset_current_scope()
		{
			current_scope_ = nullptr;
		}

		StructTable& ElsaParser::struct_table()
		{
			if (struct_table_ext_ != nullptr)
				return *struct_table_ext_;

			return struct_table_;
		}

		FunctionTable& ElsaParser::function_table()
		{
			if (function_table_ext_ != nullptr)
				return *function_table_ext_;

			return function_table_;
		}

		TypeChecker & ElsaParser::type_checker()
		{
			return type_checker_;
		}

		void ElsaParser::consume(TokenType type)
		{
			if(current_token()->get_type() != type)
				throw ParsingException(L"Unexpected token", current_token_.get());

			next_token();
		}

		void ElsaParser::consume()
		{
			next_token();
		}

		Token* ElsaParser::current_token()
		{
			return current_token_.get();
		}

		Token* ElsaParser::peek_token()
		{
			return lexer_->peek_token();
		}

		void ElsaParser::set_current_type(const ElsaType* type)
		{
			current_type_ = type;
		}

		const ElsaType* ElsaParser::current_type() const
		{
			return current_type_;
		}

		ElsaParser::ElsaParser(Lexer* lexer, StructTable* struct_table, FunctionTable* function_table)
			:
			lexer_(std::unique_ptr<Lexer>(lexer)),
			current_scope_(nullptr),
			type_checker_(this),
			program_(std::make_unique<Program>()),
			struct_table_ext_(struct_table),
			function_table_ext_(function_table),
			current_type_(nullptr)
		{
			initialize_grammar();
			next_token();
		}

		void ElsaParser::next_token()
		{
			current_token_ = lexer_->next_token();
		}

		Parser* ElsaParser::get_expression_parser(TokenType type)
		{
			auto it = expression_parsers_.find(type);
			if (it != expression_parsers_.end())
			{
				return it->second.get();
			}

			return nullptr;
		}

		Parser* ElsaParser::get_ll2_expression_parser(TokenType first, TokenType second)
		{
			for (auto& entry : ll2_expression_parsers_)
			{
				if (entry->first == first && entry->second == second)
					return entry->parser.get();
			}

			return nullptr;
		}

		Parser* ElsaParser::get_statement_parser(TokenType type)
		{
			auto it = statement_parsers_.find(type);
			if (it != statement_parsers_.end())
			{
				return it->second.get();
			}

			return nullptr;
		}

		InfixParser* ElsaParser::get_infix_parser(TokenType type)
		{
			auto it = infix_parsers_.find(type);
			if (it != infix_parsers_.end())
			{
				return it->second.get();
			}

			return nullptr;
		}

		int ElsaParser::get_precedence()
		{
			auto infix_parser = get_infix_parser(current_token()->get_type());
			if (infix_parser != nullptr)
				return infix_parser->precedence();

			return 0;
		}

		void ElsaParser::register_expression_parser(TokenType type, Parser* parser)
		{
			expression_parsers_.insert(std::pair<TokenType, std::unique_ptr<Parser>>(type, std::unique_ptr<Parser>(parser)));
		}

		void ElsaParser::register_ll2_expression_parser(TokenType first, TokenType second, Parser* parser)
		{
			ll2_expression_parsers_.push_back(std::make_unique<LL2Entry>(first, second, parser));
		}

		void ElsaParser::register_statement_parser(TokenType type, Parser* parser)
		{
			statement_parsers_.insert(std::pair<TokenType, std::unique_ptr<Parser>>(type, std::unique_ptr<Parser>(parser)));
		}

		void ElsaParser::register_infix_parser(TokenType type, InfixParser* parser)
		{
			infix_parsers_.insert(std::pair<TokenType, std::unique_ptr<InfixParser>>(type, std::unique_ptr<InfixParser>(parser)));
		}

		void ElsaParser::register_prefix_parser(TokenType type)
		{
			register_expression_parser(type, new PrefixOperatorParser());
		}

		void ElsaParser::register_postfix_parser(TokenType type, InfixParser* parser)
		{
			register_infix_parser(type, parser);
		}

		void ElsaParser::initialize_grammar()
		{
			// Statements
			register_statement_parser(TokenType::Func, new FuncDeclarationParser());
			register_statement_parser(TokenType::Struct, new StructDeclarationParser());

			// LL2 Expressions
			register_ll2_expression_parser(TokenType::Identifier, TokenType::Dot, new StructAccessParser());
			register_ll2_expression_parser(TokenType::Identifier, TokenType::LParen, new FuncCallParser());
			register_ll2_expression_parser(TokenType::Identifier, TokenType::LSBracket, new ArrayAccessParser());
			register_ll2_expression_parser(TokenType::Identifier, TokenType::Identifier, new VariableDeclarationParser());

			// Expressions
			register_expression_parser(TokenType::Var, new VariableDeclarationParser());
			register_expression_parser(TokenType::Int, new VariableDeclarationParser());
			register_expression_parser(TokenType::Float, new VariableDeclarationParser());
			register_expression_parser(TokenType::Char, new VariableDeclarationParser());
			register_expression_parser(TokenType::Bool, new VariableDeclarationParser());
			register_expression_parser(TokenType::Identifier, new IdentifierParser());
			register_expression_parser(TokenType::IntegerLiteral, new LiteralParser());
			register_expression_parser(TokenType::FloatLiteral, new LiteralParser());
			register_expression_parser(TokenType::CharLiteral, new LiteralParser());
			register_expression_parser(TokenType::BoolLiteral, new LiteralParser());
			register_expression_parser(TokenType::StringLiteral, new LiteralParser());
			register_expression_parser(TokenType::Elsa, new ElsaInvokeParser());
			register_expression_parser(TokenType::New, new CreateStructParser());
			register_expression_parser(TokenType::If, new ConditionalParser());
			register_expression_parser(TokenType::Loop, new LoopParser());
			register_expression_parser(TokenType::Return, new ReturnParser());

			// Prefix
			register_prefix_parser(TokenType::Exclamation);

			// Infix
			register_infix_parser(TokenType::Plus, new BinaryOperatorParser(Precedence::Sum));
			register_infix_parser(TokenType::Minus, new BinaryOperatorParser(Precedence::Sum));
			register_infix_parser(TokenType::Slash, new BinaryOperatorParser(Precedence::Product));
			register_infix_parser(TokenType::Asterix, new BinaryOperatorParser(Precedence::Product));
			register_infix_parser(TokenType::DoubleAmpersand, new BinaryOperatorParser(Precedence::ConditionalAnd));
			register_infix_parser(TokenType::DoubleVerticalBar, new BinaryOperatorParser(Precedence::ConditionalOr));

			register_infix_parser(TokenType::DoubleEquals, new BinaryOperatorParser(Precedence::Equality));
			register_infix_parser(TokenType::NotEquals, new BinaryOperatorParser(Precedence::Equality));

			register_infix_parser(TokenType::LessThan, new BinaryOperatorParser(Precedence::Relational));
			register_infix_parser(TokenType::GreaterThan, new BinaryOperatorParser(Precedence::Relational));
			register_infix_parser(TokenType::LessThanEquals, new BinaryOperatorParser(Precedence::Relational));
			register_infix_parser(TokenType::GreaterThanEquals, new BinaryOperatorParser(Precedence::Relational));

			register_infix_parser(TokenType::Equals, new AssignmentParser());

			// Postfix
			register_postfix_parser(TokenType::PlusPlus, new PostfixOperatorParser(Precedence::Unary));
			register_postfix_parser(TokenType::MinusMinus, new PostfixOperatorParser(Precedence::Unary));
		}

		void ElsaParser::parse_import_statement()
		{
			consume(TokenType::Import);
			auto filename = current_token_->get_value();
			consume(TokenType::StringLiteral);
			consume(TokenType::Semicolon);
			import_source_file(filename);
		}

		void ElsaParser::import_source_file(const std::wstring& filename)
		{
			auto filename_with_extension = filename + L".elsa";
			auto parser = ElsaParser(new Lexer(new SourceFile(filename_with_extension.c_str())), &struct_table_, &function_table_);
			parser.parse(program_.get());
		}

		void ElsaParser::parse(Program* program)
		{
			while (current_token_->get_type() != TokenType::END)
			{
				program->add_statement(parse_statement());
			}
		}
	}
}
<commit_msg>added support for multiple import statements<commit_after>#include "elsa_parser.h"

namespace elsa {
	namespace compiler {

		ElsaParser::ElsaParser(Lexer* lexer)
			:
			lexer_(std::unique_ptr<Lexer>(lexer)),
			current_scope_(nullptr),
			type_checker_(this),
			program_(std::make_unique<Program>()),
			struct_table_ext_(nullptr),
			function_table_ext_(nullptr),
			current_type_(nullptr)
		{
			initialize_grammar();
			next_token();
			Builtin::init(&struct_table_);
		}

		std::unique_ptr<Program> ElsaParser::parse()
		{
			while (current_token_->get_type() != TokenType::END)
			{
				program_->add_statement(parse_statement());
			}

			return std::move(program_);
		}

		std::unique_ptr<Expression> ElsaParser::parse_statement()
		{
			while(current_token_->get_type() == TokenType::Import)
				parse_import_statement();

			auto parser = get_statement_parser(current_token_->get_type());

			if (parser == nullptr)
				throw ParsingException(L"Invalid token", current_token_.get());

			return parser->parse(this);
		}

		std::unique_ptr<Expression> ElsaParser::parse_expression()
		{
			return parse_expression(0);
		}

		std::unique_ptr<Expression> ElsaParser::parse_expression(int precedence)
		{
			Parser* parser = nullptr;

			parser = get_ll2_expression_parser(current_token_->get_type(), peek_token()->get_type());
			if (parser == nullptr)
				parser = get_expression_parser(current_token_->get_type());

			if (parser == nullptr)
				throw ParsingException(L"Invalid token", current_token_.get());

			auto left = std::unique_ptr<Expression>(parser->parse(this));

			while (precedence < get_precedence())
			{
				auto infix_parser = get_infix_parser(current_token()->get_type());
				left = std::unique_ptr<Expression>(infix_parser->parse(this, std::move(left)));
			}

			return left;
		}

		ScopedExpression* ElsaParser::current_scope()
		{
			if (current_scope_ == nullptr)
				throw ParsingException(L"No scope defined", current_token_.get());

			return current_scope_;
		}

		void ElsaParser::set_current_scope(ScopedExpression* scope)
		{
			current_scope_ = scope;
		}

		void ElsaParser::reset_current_scope()
		{
			current_scope_ = nullptr;
		}

		StructTable& ElsaParser::struct_table()
		{
			if (struct_table_ext_ != nullptr)
				return *struct_table_ext_;

			return struct_table_;
		}

		FunctionTable& ElsaParser::function_table()
		{
			if (function_table_ext_ != nullptr)
				return *function_table_ext_;

			return function_table_;
		}

		TypeChecker & ElsaParser::type_checker()
		{
			return type_checker_;
		}

		void ElsaParser::consume(TokenType type)
		{
			if(current_token()->get_type() != type)
				throw ParsingException(L"Unexpected token", current_token_.get());

			next_token();
		}

		void ElsaParser::consume()
		{
			next_token();
		}

		Token* ElsaParser::current_token()
		{
			return current_token_.get();
		}

		Token* ElsaParser::peek_token()
		{
			return lexer_->peek_token();
		}

		void ElsaParser::set_current_type(const ElsaType* type)
		{
			current_type_ = type;
		}

		const ElsaType* ElsaParser::current_type() const
		{
			return current_type_;
		}

		ElsaParser::ElsaParser(Lexer* lexer, StructTable* struct_table, FunctionTable* function_table)
			:
			lexer_(std::unique_ptr<Lexer>(lexer)),
			current_scope_(nullptr),
			type_checker_(this),
			program_(std::make_unique<Program>()),
			struct_table_ext_(struct_table),
			function_table_ext_(function_table),
			current_type_(nullptr)
		{
			initialize_grammar();
			next_token();
		}

		void ElsaParser::next_token()
		{
			current_token_ = lexer_->next_token();
		}

		Parser* ElsaParser::get_expression_parser(TokenType type)
		{
			auto it = expression_parsers_.find(type);
			if (it != expression_parsers_.end())
			{
				return it->second.get();
			}

			return nullptr;
		}

		Parser* ElsaParser::get_ll2_expression_parser(TokenType first, TokenType second)
		{
			for (auto& entry : ll2_expression_parsers_)
			{
				if (entry->first == first && entry->second == second)
					return entry->parser.get();
			}

			return nullptr;
		}

		Parser* ElsaParser::get_statement_parser(TokenType type)
		{
			auto it = statement_parsers_.find(type);
			if (it != statement_parsers_.end())
			{
				return it->second.get();
			}

			return nullptr;
		}

		InfixParser* ElsaParser::get_infix_parser(TokenType type)
		{
			auto it = infix_parsers_.find(type);
			if (it != infix_parsers_.end())
			{
				return it->second.get();
			}

			return nullptr;
		}

		int ElsaParser::get_precedence()
		{
			auto infix_parser = get_infix_parser(current_token()->get_type());
			if (infix_parser != nullptr)
				return infix_parser->precedence();

			return 0;
		}

		void ElsaParser::register_expression_parser(TokenType type, Parser* parser)
		{
			expression_parsers_.insert(std::pair<TokenType, std::unique_ptr<Parser>>(type, std::unique_ptr<Parser>(parser)));
		}

		void ElsaParser::register_ll2_expression_parser(TokenType first, TokenType second, Parser* parser)
		{
			ll2_expression_parsers_.push_back(std::make_unique<LL2Entry>(first, second, parser));
		}

		void ElsaParser::register_statement_parser(TokenType type, Parser* parser)
		{
			statement_parsers_.insert(std::pair<TokenType, std::unique_ptr<Parser>>(type, std::unique_ptr<Parser>(parser)));
		}

		void ElsaParser::register_infix_parser(TokenType type, InfixParser* parser)
		{
			infix_parsers_.insert(std::pair<TokenType, std::unique_ptr<InfixParser>>(type, std::unique_ptr<InfixParser>(parser)));
		}

		void ElsaParser::register_prefix_parser(TokenType type)
		{
			register_expression_parser(type, new PrefixOperatorParser());
		}

		void ElsaParser::register_postfix_parser(TokenType type, InfixParser* parser)
		{
			register_infix_parser(type, parser);
		}

		void ElsaParser::initialize_grammar()
		{
			// Statements
			register_statement_parser(TokenType::Func, new FuncDeclarationParser());
			register_statement_parser(TokenType::Struct, new StructDeclarationParser());

			// LL2 Expressions
			register_ll2_expression_parser(TokenType::Identifier, TokenType::Dot, new StructAccessParser());
			register_ll2_expression_parser(TokenType::Identifier, TokenType::LParen, new FuncCallParser());
			register_ll2_expression_parser(TokenType::Identifier, TokenType::LSBracket, new ArrayAccessParser());
			register_ll2_expression_parser(TokenType::Identifier, TokenType::Identifier, new VariableDeclarationParser());

			// Expressions
			register_expression_parser(TokenType::Var, new VariableDeclarationParser());
			register_expression_parser(TokenType::Int, new VariableDeclarationParser());
			register_expression_parser(TokenType::Float, new VariableDeclarationParser());
			register_expression_parser(TokenType::Char, new VariableDeclarationParser());
			register_expression_parser(TokenType::Bool, new VariableDeclarationParser());
			register_expression_parser(TokenType::Identifier, new IdentifierParser());
			register_expression_parser(TokenType::IntegerLiteral, new LiteralParser());
			register_expression_parser(TokenType::FloatLiteral, new LiteralParser());
			register_expression_parser(TokenType::CharLiteral, new LiteralParser());
			register_expression_parser(TokenType::BoolLiteral, new LiteralParser());
			register_expression_parser(TokenType::StringLiteral, new LiteralParser());
			register_expression_parser(TokenType::Elsa, new ElsaInvokeParser());
			register_expression_parser(TokenType::New, new CreateStructParser());
			register_expression_parser(TokenType::If, new ConditionalParser());
			register_expression_parser(TokenType::Loop, new LoopParser());
			register_expression_parser(TokenType::Return, new ReturnParser());

			// Prefix
			register_prefix_parser(TokenType::Exclamation);

			// Infix
			register_infix_parser(TokenType::Plus, new BinaryOperatorParser(Precedence::Sum));
			register_infix_parser(TokenType::Minus, new BinaryOperatorParser(Precedence::Sum));
			register_infix_parser(TokenType::Slash, new BinaryOperatorParser(Precedence::Product));
			register_infix_parser(TokenType::Asterix, new BinaryOperatorParser(Precedence::Product));
			register_infix_parser(TokenType::DoubleAmpersand, new BinaryOperatorParser(Precedence::ConditionalAnd));
			register_infix_parser(TokenType::DoubleVerticalBar, new BinaryOperatorParser(Precedence::ConditionalOr));

			register_infix_parser(TokenType::DoubleEquals, new BinaryOperatorParser(Precedence::Equality));
			register_infix_parser(TokenType::NotEquals, new BinaryOperatorParser(Precedence::Equality));

			register_infix_parser(TokenType::LessThan, new BinaryOperatorParser(Precedence::Relational));
			register_infix_parser(TokenType::GreaterThan, new BinaryOperatorParser(Precedence::Relational));
			register_infix_parser(TokenType::LessThanEquals, new BinaryOperatorParser(Precedence::Relational));
			register_infix_parser(TokenType::GreaterThanEquals, new BinaryOperatorParser(Precedence::Relational));

			register_infix_parser(TokenType::Equals, new AssignmentParser());

			// Postfix
			register_postfix_parser(TokenType::PlusPlus, new PostfixOperatorParser(Precedence::Unary));
			register_postfix_parser(TokenType::MinusMinus, new PostfixOperatorParser(Precedence::Unary));
		}

		void ElsaParser::parse_import_statement()
		{
			consume(TokenType::Import);
			auto filename = current_token_->get_value();
			consume(TokenType::StringLiteral);
			consume(TokenType::Semicolon);
			import_source_file(filename);
		}

		void ElsaParser::import_source_file(const std::wstring& filename)
		{
			auto filename_with_extension = filename + L".elsa";
			auto parser = ElsaParser(new Lexer(new SourceFile(filename_with_extension.c_str())), &struct_table_, &function_table_);
			parser.parse(program_.get());
		}

		void ElsaParser::parse(Program* program)
		{
			while (current_token_->get_type() != TokenType::END)
			{
				program->add_statement(parse_statement());
			}
		}
	}
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2008, 2009 Nokia Corporation.
 *
 * Contact: Marius Vollmer <marius.vollmer@nokia.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License
 * version 2.1 as published by the Free Software Foundation.
 *
 * This library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA
 *
 */

#include <QtTest/QtTest>
#include <QtCore>
#include "fileutils.h"
#include "infocdbbackend.h"
#include "cdbwriter.h"

class InfoCdbBackendUnitTest : public QObject
{
    Q_OBJECT
    InfoCdbBackend *backend;

private:
    void createBaseDatabase(QString path);
    void createAlternateDatabase(QString path);

private slots:
    void initTestCase();
    void name();
    void databaseExists();
    void databaseDirectory();
    void listKeys();
    void typeForKey();
    void docForKey();
    void keyDeclared();
    void providersForKey();
    void dynamics();
    void removed();
    void cleanupTestCase();
};

void InfoCdbBackendUnitTest::createBaseDatabase(QString path)
{
    CDBWriter writer(path);

    if (! writer.isWritable())
        qFatal("Failed to open %s for reading!", path.toLocal8Bit().data());

    writer.add("KEYS", "Battery.Charging");
    writer.add("KEYS", "Internet.BytesOut");
    writer.add("Battery.Charging:KEYTYPE", "TRUTH");
    writer.add("Internet.BytesOut:KEYTYPE", "INTEGER");
    writer.add("Battery.Charging:KEYDOC", "doc1");

    QVariantList providers1;
    QHash <QString, QVariant> provider1;
    provider1.insert("plugin", "contextkit-dbus");
    provider1.insert("constructionString", "system:org.freedesktop.ContextKit.contextd1");
    providers1 << QVariant(provider1);
    writer.add("Battery.Charging:PROVIDERS", QVariant(providers1));

    QVariantList providers2;
    QHash <QString, QVariant> provider2;
    provider2.insert("plugin", "contextkit-dbus");
    provider2.insert("constructionString", "session:org.freedesktop.ContextKit.contextd2");
    providers2 << QVariant(provider2);
    writer.add("Internet.BytesOut:PROVIDERS", QVariant(providers2));

    writer.close();
}

void InfoCdbBackendUnitTest::createAlternateDatabase(QString path)
{
    CDBWriter writer(path);

    if (! writer.isWritable())
        qFatal("Failed to open %s for reading!", path.toLocal8Bit().data());

    writer.add("KEYS", "Battery.Charging");
    writer.add("KEYS", "Battery.Capacity");
    writer.add("Battery.Charging:KEYTYPE", "INTEGER");
    writer.add("Battery.Charging:KEYDOC", "doc1");
    writer.add("Battery.Capacity:KEYTYPE", "INTEGER");
    writer.add("Battery.Capacity:KEYDOC", "doc3");

    QVariantList providers1;
    QHash <QString, QVariant> provider1;
    provider1.insert("plugin", "contextkit-dbus");
    provider1.insert("constructionString", "system:org.freedesktop.ContextKit.contextd1");
    providers1 << QVariant(provider1);
    writer.add("Battery.Charging:PROVIDERS", QVariant(providers1));

    QVariantList providers2;
    QHash <QString, QVariant> provider2;
    QHash <QString, QVariant> provider3;
    provider2.insert("plugin", "contextkit-dbus");
    provider2.insert("constructionString", "system:org.freedesktop.ContextKit.contextd1");
    provider3.insert("plugin", "contextkit-dbus");
    provider3.insert("constructionString", "system:org.freedesktop.ContextKit.contextdX");
    providers2 << QVariant(provider2);
    providers2 << QVariant(provider3);
    writer.add("Battery.Capacity:PROVIDERS", providers2);

    writer.close();
}

void InfoCdbBackendUnitTest::initTestCase()
{
    createBaseDatabase("cache.cdb");

    utilSetEnv("CONTEXT_PROVIDERS", "./");
    utilSetEnv("CONTEXT_CORE_DECLARATIONS", "/dev/null");
    backend = new InfoCdbBackend();
}

void InfoCdbBackendUnitTest::name()
{
    QCOMPARE(backend->name(), QString("cdb"));
}

void InfoCdbBackendUnitTest::databaseDirectory()
{
    QVERIFY(backend->databaseDirectory() == QString("./") ||
            backend->databaseDirectory() == QString("."));
}

void InfoCdbBackendUnitTest::databaseExists()
{
    QCOMPARE(backend->databaseExists(), true);
}

void InfoCdbBackendUnitTest::listKeys()
{
    QStringList keys = backend->listKeys();
    QCOMPARE(keys.count(), 2);
    QVERIFY(keys.contains("Battery.Charging"));
    QVERIFY(keys.contains("Internet.BytesOut"));
}

void InfoCdbBackendUnitTest::typeForKey()
{
    QCOMPARE(backend->typeForKey("Internet.BytesOut"), QString("INTEGER"));
    QCOMPARE(backend->typeForKey("Battery.Charging"), QString("TRUTH"));
    QCOMPARE(backend->typeForKey("Does.Not.Exist"), QString());
}

void InfoCdbBackendUnitTest::docForKey()
{
    QCOMPARE(backend->docForKey("Internet.BytesOut"), QString());
    QCOMPARE(backend->docForKey("Battery.Charging"), QString("doc1"));
    QCOMPARE(backend->docForKey("Does.Not.Exist"), QString());
}

void InfoCdbBackendUnitTest::keyDeclared()
{
    foreach (QString key, backend->listKeys())
        QCOMPARE(backend->keyDeclared(key), true);

    QCOMPARE(backend->keyDeclared("Does.Not.Exist"), false);
    QCOMPARE(backend->keyDeclared("Battery.Charging"), true);
}

void InfoCdbBackendUnitTest::providersForKey()
{
    QList <ContextProviderInfo> list1 = backend->providersForKey("Battery.Charging");
    QCOMPARE(list1.count(), 1);
    QCOMPARE(list1.at(0).plugin, QString("contextkit-dbus"));
    QCOMPARE(list1.at(0).constructionString, QString("system:org.freedesktop.ContextKit.contextd1"));

    QList <ContextProviderInfo> list2 = backend->providersForKey("Does.Not.Exist");
    QCOMPARE(list2.count(), 0);
}

void InfoCdbBackendUnitTest::dynamics()
{
    backend->connectNotify("-"); // Fake it. Spy does something fishy here.

    // Setup the spy observers
    QSignalSpy spy1(backend, SIGNAL(keysRemoved(QStringList)));
    QSignalSpy spy2(backend, SIGNAL(keysChanged(QStringList)));
    QSignalSpy spy3(backend, SIGNAL(keyChanged(QString)));
    QSignalSpy spy4(backend, SIGNAL(keysAdded(QStringList)));

    createAlternateDatabase("cache-next.cdb");
    QFile::remove("cache.cdb");
    QFile::copy("cache-next.cdb", "cache.cdb");
    QTest::qWait(DEFAULT_WAIT_PERIOD);

    // Test the new values
    QCOMPARE(backend->databaseExists(), true);
    QCOMPARE(backend->listKeys().count(), 2);
    QVERIFY(backend->listKeys().contains("Battery.Charging"));
    QVERIFY(backend->listKeys().contains("Battery.Capacity"));
    QCOMPARE(backend->typeForKey("Battery.Charging"), QString("INTEGER"));
    QCOMPARE(backend->docForKey("Battery.Charging"), QString("doc1"));

    // Check providers
    QList <ContextProviderInfo> list1 = backend->providersForKey("Battery.Charging");
    QCOMPARE(list1.count(), 1);
    QCOMPARE(list1.at(0).plugin, QString("contextkit-dbus"));
    QCOMPARE(list1.at(0).constructionString, QString("system:org.freedesktop.ContextKit.contextd1"));
    QList <ContextProviderInfo> list2 = backend->providersForKey("Battery.Capacity");
    QCOMPARE(list2.count(), 2);
    QCOMPARE(list2.at(0).plugin, QString("contextkit-dbus"));
    QCOMPARE(list2.at(0).constructionString, QString("system:org.freedesktop.ContextKit.contextd1"));
    QCOMPARE(list2.at(1).plugin, QString("contextkit-dbus"));
    QCOMPARE(list2.at(1).constructionString, QString("system:org.freedesktop.ContextKit.contextdX"));

    // Test emissions
    QCOMPARE(spy1.count(), 1);
    QList<QVariant> args1 = spy1.takeFirst();
    QCOMPARE(args1.at(0).toList().size(), 1);
    QCOMPARE(args1.at(0).toStringList().at(0), QString("Internet.BytesOut"));

    QCOMPARE(spy2.count(), 1);
    QList<QVariant> args2 = spy2.takeFirst();
    QCOMPARE(args2.at(0).toList().size(), 2);
    QCOMPARE(args2.at(0).toStringList().at(0), QString("Battery.Charging"));
    QCOMPARE(args2.at(0).toStringList().at(1), QString("Battery.Capacity"));

    QCOMPARE(spy3.count(), 3);

    QCOMPARE(spy4.count(), 1);
    QList<QVariant> args4 = spy4.takeFirst();
    QCOMPARE(args4.at(0).toList().size(), 1);
    QCOMPARE(args4.at(0).toStringList().at(0), QString("Battery.Capacity"));

    backend->disconnectNotify("-"); // Fake it. Spy does something fishy here.
}

void InfoCdbBackendUnitTest::removed()
{
    backend->connectNotify("-"); // Fake it. Spy does something fishy here.
    QSignalSpy spy(backend, SIGNAL(keysRemoved(QStringList)));

    QFile::remove("cache.cdb");

    QTest::qWait(DEFAULT_WAIT_PERIOD);

    QCOMPARE(spy.count(), 1);
    QList<QVariant> args = spy.takeFirst();
    QCOMPARE(args.at(0).toList().size(), 2);

    backend->disconnectNotify("-"); // Fake it. Spy does something fishy here.
}

void InfoCdbBackendUnitTest::cleanupTestCase()
{
    QFile::remove("cache.cdb");
    QFile::remove("cache-next.cdb");
}

#include "infocdbbackendunittest.moc"
QTEST_MAIN(InfoCdbBackendUnitTest);
<commit_msg>Version compatibility unit test for cdb backend.<commit_after>/*
 * Copyright (C) 2008, 2009 Nokia Corporation.
 *
 * Contact: Marius Vollmer <marius.vollmer@nokia.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License
 * version 2.1 as published by the Free Software Foundation.
 *
 * This library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA
 *
 */

#include <QtTest/QtTest>
#include <QtCore>
#include "fileutils.h"
#include "infocdbbackend.h"
#include "cdbwriter.h"

class InfoCdbBackendUnitTest : public QObject
{
    Q_OBJECT
    InfoCdbBackend *backend;

private:
    void createBaseDatabase(QString path);
    void createAlternateDatabase(QString path);
    void createIncompatibleDatabase(QString path);

private slots:
    void initTestCase();
    void name();
    void databaseExists();
    void databaseDirectory();
    void listKeys();
    void typeForKey();
    void docForKey();
    void keyDeclared();
    void providersForKey();
    void dynamics();
    void removed();
    void incompatibleDatabase();
    void cleanupTestCase();
};

void InfoCdbBackendUnitTest::createBaseDatabase(QString path)
{
    CDBWriter writer(path);

    if (! writer.isWritable())
        qFatal("Failed to open %s for reading!", path.toLocal8Bit().data());

    writer.add("KEYS", "Battery.Charging");
    writer.add("KEYS", "Internet.BytesOut");
    writer.add("Battery.Charging:KEYTYPE", "TRUTH");
    writer.add("Internet.BytesOut:KEYTYPE", "INTEGER");
    writer.add("Battery.Charging:KEYDOC", "doc1");

    QVariantList providers1;
    QHash <QString, QVariant> provider1;
    provider1.insert("plugin", "contextkit-dbus");
    provider1.insert("constructionString", "system:org.freedesktop.ContextKit.contextd1");
    providers1 << QVariant(provider1);
    writer.add("Battery.Charging:PROVIDERS", QVariant(providers1));

    QVariantList providers2;
    QHash <QString, QVariant> provider2;
    provider2.insert("plugin", "contextkit-dbus");
    provider2.insert("constructionString", "session:org.freedesktop.ContextKit.contextd2");
    providers2 << QVariant(provider2);
    writer.add("Internet.BytesOut:PROVIDERS", QVariant(providers2));

    writer.close();
}

void InfoCdbBackendUnitTest::createAlternateDatabase(QString path)
{
    CDBWriter writer(path);

    if (! writer.isWritable())
        qFatal("Failed to open %s for reading!", path.toLocal8Bit().data());

    writer.add("KEYS", "Battery.Charging");
    writer.add("KEYS", "Battery.Capacity");
    writer.add("Battery.Charging:KEYTYPE", "INTEGER");
    writer.add("Battery.Charging:KEYDOC", "doc1");
    writer.add("Battery.Capacity:KEYTYPE", "INTEGER");
    writer.add("Battery.Capacity:KEYDOC", "doc3");

    QVariantList providers1;
    QHash <QString, QVariant> provider1;
    provider1.insert("plugin", "contextkit-dbus");
    provider1.insert("constructionString", "system:org.freedesktop.ContextKit.contextd1");
    providers1 << QVariant(provider1);
    writer.add("Battery.Charging:PROVIDERS", QVariant(providers1));

    QVariantList providers2;
    QHash <QString, QVariant> provider2;
    QHash <QString, QVariant> provider3;
    provider2.insert("plugin", "contextkit-dbus");
    provider2.insert("constructionString", "system:org.freedesktop.ContextKit.contextd1");
    provider3.insert("plugin", "contextkit-dbus");
    provider3.insert("constructionString", "system:org.freedesktop.ContextKit.contextdX");
    providers2 << QVariant(provider2);
    providers2 << QVariant(provider3);
    writer.add("Battery.Capacity:PROVIDERS", providers2);

    writer.close();
}

void InfoCdbBackendUnitTest::createIncompatibleDatabase(QString path)
{
    CDBWriter writer(path);

    if (! writer.isWritable())
        qFatal("Failed to open %s for reading!", path.toLocal8Bit().data());

    writer.add("KEYS", "Battery.Charging");
    writer.add("Battery.Charging:KEYTYPE", "INTEGER");
    writer.add("Battery.Charging:KEYDOC", "doc1");

    QVariantList providers;
    QHash <QString, QVariant> provider1;
    provider1.insert("plugin", "contextkit-dbus");
    provider1.insert("constructionString", "system:org.freedesktop.ContextKit.contextd1");
    providers << QVariant(provider1);
    writer.add("Battery.Charging:PROVIDERS", QVariant(providers));
    writer.add("VERSION", "bull");

    writer.close();
}

void InfoCdbBackendUnitTest::initTestCase()
{
    createBaseDatabase("cache.cdb");

    utilSetEnv("CONTEXT_PROVIDERS", "./");
    utilSetEnv("CONTEXT_CORE_DECLARATIONS", "/dev/null");
    backend = new InfoCdbBackend();
}

void InfoCdbBackendUnitTest::name()
{
    QCOMPARE(backend->name(), QString("cdb"));
}

void InfoCdbBackendUnitTest::databaseDirectory()
{
    QVERIFY(backend->databaseDirectory() == QString("./") ||
            backend->databaseDirectory() == QString("."));
}

void InfoCdbBackendUnitTest::databaseExists()
{
    QCOMPARE(backend->databaseExists(), true);
}

void InfoCdbBackendUnitTest::listKeys()
{
    QStringList keys = backend->listKeys();
    QCOMPARE(keys.count(), 2);
    QVERIFY(keys.contains("Battery.Charging"));
    QVERIFY(keys.contains("Internet.BytesOut"));
}

void InfoCdbBackendUnitTest::typeForKey()
{
    QCOMPARE(backend->typeForKey("Internet.BytesOut"), QString("INTEGER"));
    QCOMPARE(backend->typeForKey("Battery.Charging"), QString("TRUTH"));
    QCOMPARE(backend->typeForKey("Does.Not.Exist"), QString());
}

void InfoCdbBackendUnitTest::docForKey()
{
    QCOMPARE(backend->docForKey("Internet.BytesOut"), QString());
    QCOMPARE(backend->docForKey("Battery.Charging"), QString("doc1"));
    QCOMPARE(backend->docForKey("Does.Not.Exist"), QString());
}

void InfoCdbBackendUnitTest::keyDeclared()
{
    foreach (QString key, backend->listKeys())
        QCOMPARE(backend->keyDeclared(key), true);

    QCOMPARE(backend->keyDeclared("Does.Not.Exist"), false);
    QCOMPARE(backend->keyDeclared("Battery.Charging"), true);
}

void InfoCdbBackendUnitTest::providersForKey()
{
    QList <ContextProviderInfo> list1 = backend->providersForKey("Battery.Charging");
    QCOMPARE(list1.count(), 1);
    QCOMPARE(list1.at(0).plugin, QString("contextkit-dbus"));
    QCOMPARE(list1.at(0).constructionString, QString("system:org.freedesktop.ContextKit.contextd1"));

    QList <ContextProviderInfo> list2 = backend->providersForKey("Does.Not.Exist");
    QCOMPARE(list2.count(), 0);
}

void InfoCdbBackendUnitTest::dynamics()
{
    backend->connectNotify("-"); // Fake it. Spy does something fishy here.

    // Setup the spy observers
    QSignalSpy spy1(backend, SIGNAL(keysRemoved(QStringList)));
    QSignalSpy spy2(backend, SIGNAL(keysChanged(QStringList)));
    QSignalSpy spy3(backend, SIGNAL(keyChanged(QString)));
    QSignalSpy spy4(backend, SIGNAL(keysAdded(QStringList)));

    createAlternateDatabase("cache-next.cdb");
    QFile::remove("cache.cdb");
    QFile::copy("cache-next.cdb", "cache.cdb");
    QTest::qWait(DEFAULT_WAIT_PERIOD);

    // Test the new values
    QCOMPARE(backend->databaseExists(), true);
    QCOMPARE(backend->listKeys().count(), 2);
    QVERIFY(backend->listKeys().contains("Battery.Charging"));
    QVERIFY(backend->listKeys().contains("Battery.Capacity"));
    QCOMPARE(backend->typeForKey("Battery.Charging"), QString("INTEGER"));
    QCOMPARE(backend->docForKey("Battery.Charging"), QString("doc1"));

    // Check providers
    QList <ContextProviderInfo> list1 = backend->providersForKey("Battery.Charging");
    QCOMPARE(list1.count(), 1);
    QCOMPARE(list1.at(0).plugin, QString("contextkit-dbus"));
    QCOMPARE(list1.at(0).constructionString, QString("system:org.freedesktop.ContextKit.contextd1"));
    QList <ContextProviderInfo> list2 = backend->providersForKey("Battery.Capacity");
    QCOMPARE(list2.count(), 2);
    QCOMPARE(list2.at(0).plugin, QString("contextkit-dbus"));
    QCOMPARE(list2.at(0).constructionString, QString("system:org.freedesktop.ContextKit.contextd1"));
    QCOMPARE(list2.at(1).plugin, QString("contextkit-dbus"));
    QCOMPARE(list2.at(1).constructionString, QString("system:org.freedesktop.ContextKit.contextdX"));

    // Test emissions
    QCOMPARE(spy1.count(), 1);
    QList<QVariant> args1 = spy1.takeFirst();
    QCOMPARE(args1.at(0).toList().size(), 1);
    QCOMPARE(args1.at(0).toStringList().at(0), QString("Internet.BytesOut"));

    QCOMPARE(spy2.count(), 1);
    QList<QVariant> args2 = spy2.takeFirst();
    QCOMPARE(args2.at(0).toList().size(), 2);
    QCOMPARE(args2.at(0).toStringList().at(0), QString("Battery.Charging"));
    QCOMPARE(args2.at(0).toStringList().at(1), QString("Battery.Capacity"));

    QCOMPARE(spy3.count(), 3);

    QCOMPARE(spy4.count(), 1);
    QList<QVariant> args4 = spy4.takeFirst();
    QCOMPARE(args4.at(0).toList().size(), 1);
    QCOMPARE(args4.at(0).toStringList().at(0), QString("Battery.Capacity"));

    backend->disconnectNotify("-"); // Fake it. Spy does something fishy here.
}

void InfoCdbBackendUnitTest::removed()
{
    backend->connectNotify("-"); // Fake it. Spy does something fishy here.
    QSignalSpy spy(backend, SIGNAL(keysRemoved(QStringList)));

    QFile::remove("cache.cdb");

    QTest::qWait(DEFAULT_WAIT_PERIOD);

    QCOMPARE(spy.count(), 1);
    QList<QVariant> args = spy.takeFirst();
    QCOMPARE(args.at(0).toList().size(), 2);

    backend->disconnectNotify("-"); // Fake it. Spy does something fishy here.
}

void InfoCdbBackendUnitTest::incompatibleDatabase()
{
    QFile::remove("cache.cdb");
    QTest::qWait(DEFAULT_WAIT_PERIOD);
    createIncompatibleDatabase("cache.cdb");
    QTest::qWait(DEFAULT_WAIT_PERIOD);

    QCOMPARE(backend->databaseExists(), true);
    QCOMPARE(backend->listKeys().count(), 0);
    QCOMPARE(backend->typeForKey("Battery.Charging"), QString());
    QCOMPARE(backend->docForKey("Battery.Charging"), QString());
    QCOMPARE(backend->providersForKey("Battery.Charging").size(), 0);
}

void InfoCdbBackendUnitTest::cleanupTestCase()
{
    QFile::remove("cache.cdb");
    QFile::remove("cache-next.cdb");
}

#include "infocdbbackendunittest.moc"
QTEST_MAIN(InfoCdbBackendUnitTest);
<|endoftext|>


<commit_before>/***************************************************************************
 *   Copyright (c) 2008 Werner Mayer <wmayer[at]users.sourceforge.net>     *
 *                                                                         *
 *   This file is part of the FreeCAD CAx development system.              *
 *                                                                         *
 *   This library is free software; you can redistribute it and/or         *
 *   modify it under the terms of the GNU Library General Public           *
 *   License as published by the Free Software Foundation; either          *
 *   version 2 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 Library General Public License for more details.                  *
 *                                                                         *
 *   You should have received a copy of the GNU Library General Public     *
 *   License along with this library; see the file COPYING.LIB. If not,    *
 *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
 *   Suite 330, Boston, MA  02111-1307, USA                                *
 *                                                                         *
 ***************************************************************************/

#include "PreCompiled.h"
#ifndef _PreComp_
# include <BRepFilletAPI_MakeFillet.hxx>
# include <TopExp_Explorer.hxx>
# include <TopoDS.hxx>
# include <TopoDS_Edge.hxx>
#endif

#include <Mod/Part/App/TopoShape.h>

#include "FeatureFillet.h"

using namespace PartDesign;

PROPERTY_SOURCE(PartDesign::Fillet, PartDesign::DressUp)

const App::PropertyFloatConstraint::Constraints floatRadius = {0.0f,FLT_MAX,0.1f};

Fillet::Fillet()
{
    ADD_PROPERTY(Radius,(1.0f));
    Radius.setConstraints(&floatRadius);
}

short Fillet::mustExecute() const
{
    if (Base.isTouched() || Radius.isTouched())
        return 1;
    if (Base.getValue() && Base.getValue()->isTouched())
        return 1;
    return 0;
}

App::DocumentObjectExecReturn *Fillet::execute(void)
{
    App::DocumentObject* link = Base.getValue();
    if (!link)
        return new App::DocumentObjectExecReturn("No object linked");
    if (!link->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId()))
        return new App::DocumentObjectExecReturn("Linked object is not a Part object");
    Part::Feature *base = static_cast<Part::Feature*>(Base.getValue());
    const Part::TopoShape& TopShape = base->Shape.getShape();
    if (TopShape._Shape.IsNull())
        return new App::DocumentObjectExecReturn("Cannot fillet invalid shape");

    const std::vector<std::string>& SubVals = Base.getSubValuesStartsWith("Edge");
    if (SubVals.size() == 0)
        return new App::DocumentObjectExecReturn("No edges specified");

    float radius = Radius.getValue();

    try {
        BRepFilletAPI_MakeFillet mkFillet(base->Shape.getValue());

        for (std::vector<std::string>::const_iterator it= SubVals.begin();it!=SubVals.end();++it) {
            TopoDS_Edge edge = TopoDS::Edge(TopShape.getSubShape(it->c_str()));
            mkFillet.Add(radius, radius, edge);
        }

        if (!mkFillet.IsDone())
            return new App::DocumentObjectExecReturn("Failed to create fillet");

        TopoDS_Shape shape = mkFillet.Shape();
        if (shape.IsNull())
            return new App::DocumentObjectExecReturn("Resulting shape is null");
        this->Shape.setValue(shape);
        return App::DocumentObject::StdReturn;
    }
    catch (Standard_Failure) {
        Handle_Standard_Failure e = Standard_Failure::Caught();
        return new App::DocumentObjectExecReturn(e->GetMessageString());
    }
}
<commit_msg>0000532: fillet command in Part Design shows only partial dialog<commit_after>/***************************************************************************
 *   Copyright (c) 2008 Werner Mayer <wmayer[at]users.sourceforge.net>     *
 *                                                                         *
 *   This file is part of the FreeCAD CAx development system.              *
 *                                                                         *
 *   This library is free software; you can redistribute it and/or         *
 *   modify it under the terms of the GNU Library General Public           *
 *   License as published by the Free Software Foundation; either          *
 *   version 2 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 Library General Public License for more details.                  *
 *                                                                         *
 *   You should have received a copy of the GNU Library General Public     *
 *   License along with this library; see the file COPYING.LIB. If not,    *
 *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
 *   Suite 330, Boston, MA  02111-1307, USA                                *
 *                                                                         *
 ***************************************************************************/

#include "PreCompiled.h"
#ifndef _PreComp_
# include <BRepFilletAPI_MakeFillet.hxx>
# include <TopExp_Explorer.hxx>
# include <TopoDS.hxx>
# include <TopoDS_Edge.hxx>
#endif

#include <Mod/Part/App/TopoShape.h>

#include "FeatureFillet.h"

using namespace PartDesign;

PROPERTY_SOURCE(PartDesign::Fillet, PartDesign::DressUp)

const App::PropertyFloatConstraint::Constraints floatRadius = {0.0f,FLT_MAX,0.1f};

Fillet::Fillet()
{
    ADD_PROPERTY(Radius,(1.0f));
    Radius.setConstraints(&floatRadius);
}

short Fillet::mustExecute() const
{
    if (Base.isTouched() || Radius.isTouched())
        return 1;
    if (Base.getValue() && Base.getValue()->isTouched())
        return 1;
    return 0;
}

App::DocumentObjectExecReturn *Fillet::execute(void)
{
    App::DocumentObject* link = Base.getValue();
    if (!link)
        return new App::DocumentObjectExecReturn("No object linked");
    if (!link->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId()))
        return new App::DocumentObjectExecReturn("Linked object is not a Part object");
    Part::Feature *base = static_cast<Part::Feature*>(Base.getValue());
    const Part::TopoShape& TopShape = base->Shape.getShape();
    if (TopShape._Shape.IsNull())
        return new App::DocumentObjectExecReturn("Cannot fillet invalid shape");

    const std::vector<std::string>& SubVals = Base.getSubValuesStartsWith("Edge");
    if (SubVals.size() == 0)
        return new App::DocumentObjectExecReturn("No edges specified");

    float radius = Radius.getValue();

    try {
        BRepFilletAPI_MakeFillet mkFillet(base->Shape.getValue());

        for (std::vector<std::string>::const_iterator it= SubVals.begin();it!=SubVals.end();++it) {
            TopoDS_Edge edge = TopoDS::Edge(TopShape.getSubShape(it->c_str()));
            mkFillet.Add(radius, radius, edge);
        }

        mkFillet.Build();
        if (!mkFillet.IsDone())
            return new App::DocumentObjectExecReturn("Failed to create fillet");

        TopoDS_Shape shape = mkFillet.Shape();
        if (shape.IsNull())
            return new App::DocumentObjectExecReturn("Resulting shape is null");
        this->Shape.setValue(shape);
        return App::DocumentObject::StdReturn;
    }
    catch (Standard_Failure) {
        Handle_Standard_Failure e = Standard_Failure::Caught();
        return new App::DocumentObjectExecReturn(e->GetMessageString());
    }
}
<|endoftext|>


<commit_before>/*
 * Qumulus UML editor
 * Author: Frank Erens
 * Author: Randy Thiemann
 *
 */

#include "PackageShape.h"
#include <QtGui/QBrush>
#include <QtGui/QPainter>

#include <Uml/Kernel/Package.h>

QUML_BEGIN_NAMESPACE_GD

PackageShape::PackageShape(QuUK::Element* e,
        DiagramElement* p) :
        SelectableShape(e, p) {
    constexpr int kPackageZOrdering = -2;
    setZValue(kPackageZOrdering);
    updateSizeConstraints();
    resize(0, 0);
}

PackageShape::PackageShape(const PackageShape& c) :
        SelectableShape(c) {}

void PackageShape::updateSizeConstraints() {
    setMinimumSize({100, 10 + std::max(packageNameWidth(), 50)});
}

void PackageShape::resize(double w, double h) {
    w = minimumSize().width() == -1 ? w : std::max(w, minimumSize().width());
    h = minimumSize().height() == -1 ? h : std::max(h, minimumSize().height());

    setSize({w, h});
}

void PackageShape::paint(QPainter* painter, const QStyleOptionGraphicsItem* option,
        QWidget* widget) {
    painter->setBrush(Qt::white);

    painter->drawRect(0, 0, 30, 10);
    painter->drawRect(0, 10, width(), height() - 10);

    int twidth = packageNameWidth();

    painter->setFont(font);
    painter->drawText((width() / 2) - (twidth / 2), 25, packageName());

    SelectableShape::paint(painter, option, widget);
}

QString PackageShape::packageName() const {
    return *(dynamic_cast<QuUK::Package*>(modelElement())->name());
}

int PackageShape::packageNameWidth() const {
    QFont font = sharedStyle()->font();
    font.setBold(true);

    QFontMetrics m(font);
    return m.width(packageName());
}

QUML_END_NAMESPACE_GD

<commit_msg>Update size constraint in paint.<commit_after>/*
 * Qumulus UML editor
 * Author: Frank Erens
 * Author: Randy Thiemann
 *
 */

#include "PackageShape.h"
#include <QtGui/QBrush>
#include <QtGui/QPainter>

#include <Uml/Kernel/Package.h>

QUML_BEGIN_NAMESPACE_GD

PackageShape::PackageShape(QuUK::Element* e,
        DiagramElement* p) :
        SelectableShape(e, p) {
    constexpr int kPackageZOrdering = -2;
    setZValue(kPackageZOrdering);
    updateSizeConstraints();
    resize(0, 0);
}

PackageShape::PackageShape(const PackageShape& c) :
        SelectableShape(c) {}

void PackageShape::updateSizeConstraints() {
    setMinimumSize({100, 10 + std::max(packageNameWidth(), 50)});
}

void PackageShape::resize(double w, double h) {
    w = minimumSize().width() == -1 ? w : std::max(w, minimumSize().width());
    h = minimumSize().height() == -1 ? h : std::max(h, minimumSize().height());

    setSize({w, h});
}

void PackageShape::paint(QPainter* painter, const QStyleOptionGraphicsItem* option,
        QWidget* widget) {
    updateSizeConstraints();
    resize(size());

    painter->setBrush(Qt::white);

    painter->drawRect(0, 0, 30, 10);
    painter->drawRect(0, 10, width(), height() - 10);

    int twidth = packageNameWidth();

    painter->setFont(font);
    painter->drawText((width() / 2) - (twidth / 2), 25, packageName());

    SelectableShape::paint(painter, option, widget);
}

QString PackageShape::packageName() const {
    return *(dynamic_cast<QuUK::Package*>(modelElement())->name());
}

int PackageShape::packageNameWidth() const {
    QFont font = sharedStyle()->font();
    font.setBold(true);

    QFontMetrics m(font);
    return m.width(packageName());
}

QUML_END_NAMESPACE_GD

<|endoftext|>


<commit_before>/*

openfx-arena - https://github.com/olear/openfx-arena

Copyright (c) 2015, Ole-André Rodlie <olear@fxarena.net>
Copyright (c) 2015, FxArena DA <mail@fxarena.net>
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice, this
  list of conditions and the following disclaimer.

* Neither the name of FxArena DA nor the names of its
  contributors may be used to endorse or promote products derived from
  this software without specific prior written permission.

* Redistributions in binary form must reproduce the above copyright notice,
  this list of conditions and the following disclaimer in the documentation
  and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

*/

#include "ReadPSD.h"
#include <iostream>
#include <string>
#include <Magick++.h>
#include "GenericReader.h"
#include "GenericOCIO.h"
#include "ofxsMacros.h"

#ifdef OFX_IO_USING_OCIO
#include <OpenColorIO/OpenColorIO.h>
#endif

#define kPluginName "ReadPSD"
#define kPluginGrouping "Image/Readers"
#define kPluginIdentifier "net.fxarena.openfx.ReadPSD"
#define kPluginVersionMajor 1
#define kPluginVersionMinor 3

#define kSupportsRGBA true
#define kSupportsRGB false
#define kSupportsAlpha false
#define kSupportsTiles false
#define kIsMultiPlanar true

#define DEBUG_MAGICK false

class ReadPSDPlugin : public GenericReaderPlugin
{
public:
    ReadPSDPlugin(OfxImageEffectHandle handle);
    virtual ~ReadPSDPlugin();
private:
    virtual bool isVideoStream(const std::string& /*filename*/) OVERRIDE FINAL { return false; }
    virtual void decode(const std::string& filename, OfxTime time, const OfxRectI& renderWindow, float *pixelData, const OfxRectI& bounds,
                             OFX::PixelComponentEnum pixelComponents, int pixelComponentCount, int rowBytes) OVERRIDE FINAL
    {
        std::string rawComps;
        switch (pixelComponents) {
            case OFX::ePixelComponentAlpha:
                rawComps = kOfxImageComponentAlpha;
                break;
            case OFX::ePixelComponentRGB:
                rawComps = kOfxImageComponentRGB;
                break;
            case OFX::ePixelComponentRGBA:
                rawComps = kOfxImageComponentRGBA;
                break;
            default:
                OFX::throwSuiteStatusException(kOfxStatFailed);
                return;
        }
        decodePlane(filename, time, renderWindow, pixelData, bounds, pixelComponents, pixelComponentCount, rawComps, rowBytes);
    }
    virtual void getClipComponents(const OFX::ClipComponentsArguments& args, OFX::ClipComponentsSetter& clipComponents) OVERRIDE FINAL;
    virtual void decodePlane(const std::string& filename, OfxTime time, const OfxRectI& renderWindow, float *pixelData, const OfxRectI& bounds, OFX::PixelComponentEnum pixelComponents, int pixelComponentCount, const std::string& rawComponents, int rowBytes) OVERRIDE FINAL;
    virtual bool getFrameBounds(const std::string& filename, OfxTime time, OfxRectI *bounds, double *par, std::string *error) OVERRIDE FINAL;
    virtual void restoreState(const std::string& filename) OVERRIDE FINAL;
    virtual void onInputFileChanged(const std::string& newFile, OFX::PreMultiplicationEnum *premult, OFX::PixelComponentEnum *components, int *componentCount) OVERRIDE FINAL;
    int getImageLayers(const std::string& filename);
    int _imageLayers;
    int _imageWidth;
    int _imageHeight;
};

ReadPSDPlugin::ReadPSDPlugin(OfxImageEffectHandle handle)
: GenericReaderPlugin(handle, kSupportsRGBA, kSupportsRGB, kSupportsAlpha, kSupportsTiles,
#ifdef OFX_EXTENSIONS_NUKE
(OFX::getImageEffectHostDescription() && OFX::getImageEffectHostDescription()->isMultiPlanar) ? kIsMultiPlanar : false
#else
false
#endif
)
,_imageLayers(0)
,_imageWidth(0)
,_imageHeight(0)
{
    Magick::InitializeMagick(NULL);
    assert(_outputComponents);
}

ReadPSDPlugin::~ReadPSDPlugin()
{
}

int ReadPSDPlugin::getImageLayers(const std::string &filename)
{
    #ifdef DEBUG
    std::cout << "getImageLayers ..." << std::endl;
    #endif
    int layers = 0;
    int max = 999;
    Magick::Image image;
    #ifdef DEBUG
    image.debug(DEBUG_MAGICK);
    #endif
    while (layers<max) {
        std::ostringstream layer;
        layer << filename;
        layer << "[" << layers << "]";
        try {
            image.read(layer.str());
        }
        catch(Magick::Exception) {
            break;
        }
        layers++;
    }
    if (layers>0)
        layers--;
    #ifdef DEBUG
    std::cout << "found " << layers << " layers" << std::endl;
    #endif
    return layers;
}

void ReadPSDPlugin::getClipComponents(const OFX::ClipComponentsArguments& args, OFX::ClipComponentsSetter& clipComponents)
{
    #ifdef DEBUG
    std::cout << "getClipComponents ..." << std::endl;
    #endif
    assert(isMultiPlanar());
    clipComponents.addClipComponents(*_outputClip, getOutputComponents());
    clipComponents.setPassThroughClip(NULL, args.time, args.view);
    if (_imageLayers>0) {
        for(int i = 1; i<_imageLayers+1;i++) {
            std::string component(kNatronOfxImageComponentsPlane);
            std::ostringstream layerName;
            layerName << "Layer#" << i;
            component.append(layerName.str());
            component.append(kNatronOfxImageComponentsPlaneChannel);
            component.append("R");
            component.append(kNatronOfxImageComponentsPlaneChannel);
            component.append("G");
            component.append(kNatronOfxImageComponentsPlaneChannel);
            component.append("B");
            component.append(kNatronOfxImageComponentsPlaneChannel);
            component.append("A");
            clipComponents.addClipComponents(*_outputClip, component);
        }
    }
}

void ReadPSDPlugin::decodePlane(const std::string& filename, OfxTime /*time*/, const OfxRectI& /*renderWindow*/, float *pixelData, const OfxRectI& bounds,
                                 OFX::PixelComponentEnum /*pixelComponents*/, int /*pixelComponentCount*/, const std::string& rawComponents, int /*rowBytes*/)
{
    #ifdef DEBUG
    std::cout << "decodePlane ..." << std::endl;
    #endif
    int layer = 0;
    std::string layerInfo = rawComponents;
    std::replace(layerInfo.begin(), layerInfo.end(), '_', ' ');
    std::stringstream stream(layerInfo);
    std::string streamInfo;
    while (stream>>streamInfo) {
        std::string findLayer = "Layer#";
        if (streamInfo.find(findLayer) != std::string::npos) {
            streamInfo.erase(streamInfo.find(findLayer),findLayer.length());
            layer = std::atoi(streamInfo.c_str());
        }
    }
    Magick::Image image;
    #ifdef DEBUG
    image.debug(DEBUG_MAGICK);
    #endif
    image.backgroundColor("none");
    std::ostringstream file;
    file << filename.c_str() << "[" << layer << "]";
    image.read(file.str());
    if (image.columns()>0 && image.rows()>0) {
        Magick::Image container(Magick::Geometry(bounds.x2,bounds.y2),Magick::Color("rgba(0,0,0,0)"));
        #ifdef DEBUG
        container.debug(DEBUG_MAGICK);
        #endif
        container.composite(image,image.page().xOff(),image.page().yOff(),Magick::OverCompositeOp);
        container.flip();
        container.write(0,0,bounds.x2,bounds.y2,"RGBA",Magick::FloatPixel,pixelData);
    }
    else {
        setPersistentMessage(OFX::Message::eMessageError, "", "Unable to read image");
        OFX::throwSuiteStatusException(kOfxStatErrFormat);
    }
}

bool ReadPSDPlugin::getFrameBounds(const std::string& /*filename*/,
                              OfxTime /*time*/,
                              OfxRectI *bounds,
                              double *par,
                              std::string */*error*/)
{
    #ifdef DEBUG
    std::cout << "getFrameBounds ..." << std::endl;
    #endif
    if (_imageWidth>0 && _imageHeight>0) {
        bounds->x1 = 0;
        bounds->x2 = _imageWidth;
        bounds->y1 = 0;
        bounds->y2 = _imageHeight;
        *par = 1.0;
    }
    return true;
}

void ReadPSDPlugin::restoreState(const std::string& filename)
{
    #ifdef DEBUG
    std::cout << "restoreState ..." << std::endl;
    #endif
    Magick::Image image;
    #ifdef DEBUG
    image.debug(DEBUG_MAGICK);
    #endif
    image.read(filename);
    if (image.columns()>0 && image.rows()>0) {
        _imageWidth = image.columns();
        _imageHeight = image.rows();
        _imageLayers = getImageLayers(filename);
    }
    else {
        setPersistentMessage(OFX::Message::eMessageError, "", "Unable to read image");
        OFX::throwSuiteStatusException(kOfxStatErrFormat);
    }
}

void ReadPSDPlugin::onInputFileChanged(const std::string& newFile,
                                  OFX::PreMultiplicationEnum *premult,
                                  OFX::PixelComponentEnum *components,int */*componentCount*/)
{
    #ifdef DEBUG
    std::cout << "onInputFileChanged ..." << std::endl;
    #endif
    assert(premult && components);
    Magick::Image image;
    #ifdef DEBUG
    image.debug(DEBUG_MAGICK);
    #endif
    image.read(newFile);
    if (image.columns()>0 && image.rows()>0) {
        _imageWidth = image.columns();
        _imageHeight = image.rows();
        _imageLayers = getImageLayers(newFile);
        # ifdef OFX_IO_USING_OCIO
        switch(image.colorSpace()) {
        case Magick::RGBColorspace:
            _ocio->setInputColorspace("sRGB");
            break;
        case Magick::sRGBColorspace:
            _ocio->setInputColorspace("sRGB");
            break;
        case Magick::scRGBColorspace:
            _ocio->setInputColorspace("sRGB");
            break;
        case Magick::Rec709LumaColorspace:
            _ocio->setInputColorspace("Rec709");
            break;
        case Magick::Rec709YCbCrColorspace:
            _ocio->setInputColorspace("Rec709");
            break;
        default:
            _ocio->setInputColorspace("Linear");
            break;
        }
        # endif // OFX_IO_USING_OCIO
    }
    else {
        setPersistentMessage(OFX::Message::eMessageError, "", "Unable to read image");
        OFX::throwSuiteStatusException(kOfxStatErrFormat);
    }
    *components = OFX::ePixelComponentRGBA;
    *premult = OFX::eImageOpaque;
}

using namespace OFX;

mDeclareReaderPluginFactory(ReadPSDPluginFactory, {}, {}, false);

/** @brief The basic describe function, passed a plugin descriptor */
void ReadPSDPluginFactory::describe(OFX::ImageEffectDescriptor &desc)
{
    GenericReaderDescribe(desc, kSupportsTiles, kIsMultiPlanar);
    desc.setLabel(kPluginName);

    #ifdef OFX_EXTENSIONS_TUTTLE
    const char* extensions[] = {"psd", NULL};
    desc.addSupportedExtensions(extensions);
    desc.setPluginEvaluation(92);
    #endif

    std::string magickV = MagickCore::GetMagickVersion(NULL);
    desc.setPluginDescription("Read PSD image format.\n\nWritten by Ole-André Rodlie <olear@fxarena.net>\n\nPowered by "+magickV);
}

/** @brief The describe in context function, passed a plugin descriptor and a context */
void ReadPSDPluginFactory::describeInContext(OFX::ImageEffectDescriptor &desc, ContextEnum context)
{
    PageParamDescriptor *page = GenericReaderDescribeInContextBegin(desc, context, isVideoStreamPlugin(), kSupportsRGBA, kSupportsRGB, kSupportsAlpha, kSupportsTiles);
    GenericReaderDescribeInContextEnd(desc, context, page, "reference", "reference");
}

/** @brief The create instance function, the plugin must return an object derived from the \ref OFX::ImageEffect class */
ImageEffect* ReadPSDPluginFactory::createInstance(OfxImageEffectHandle handle,
                                     ContextEnum /*context*/)
{
    ReadPSDPlugin* ret =  new ReadPSDPlugin(handle);
    ret->restoreStateFromParameters();
    return ret;
}

void getReadPSDPluginID(OFX::PluginFactoryArray &ids)
{
    static ReadPSDPluginFactory p(kPluginIdentifier, kPluginVersionMajor, kPluginVersionMinor);
    ids.push_back(&p);
}
<commit_msg>ReadPSD: faster layer count, issue #120<commit_after>/*

openfx-arena - https://github.com/olear/openfx-arena

Copyright (c) 2015, Ole-André Rodlie <olear@fxarena.net>
Copyright (c) 2015, FxArena DA <mail@fxarena.net>
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice, this
  list of conditions and the following disclaimer.

* Neither the name of FxArena DA nor the names of its
  contributors may be used to endorse or promote products derived from
  this software without specific prior written permission.

* Redistributions in binary form must reproduce the above copyright notice,
  this list of conditions and the following disclaimer in the documentation
  and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

*/

#include "ReadPSD.h"
#include <iostream>
#include <string>
#include <Magick++.h>
#include "GenericReader.h"
#include "GenericOCIO.h"
#include "ofxsMacros.h"

#ifdef OFX_IO_USING_OCIO
#include <OpenColorIO/OpenColorIO.h>
#endif

#define kPluginName "ReadPSD"
#define kPluginGrouping "Image/Readers"
#define kPluginIdentifier "net.fxarena.openfx.ReadPSD"
#define kPluginVersionMajor 1
#define kPluginVersionMinor 3

#define kSupportsRGBA true
#define kSupportsRGB false
#define kSupportsAlpha false
#define kSupportsTiles false
#define kIsMultiPlanar true

#define DEBUG_MAGICK false

class ReadPSDPlugin : public GenericReaderPlugin
{
public:
    ReadPSDPlugin(OfxImageEffectHandle handle);
    virtual ~ReadPSDPlugin();
private:
    virtual bool isVideoStream(const std::string& /*filename*/) OVERRIDE FINAL { return false; }
    virtual void decode(const std::string& filename, OfxTime time, const OfxRectI& renderWindow, float *pixelData, const OfxRectI& bounds,
                             OFX::PixelComponentEnum pixelComponents, int pixelComponentCount, int rowBytes) OVERRIDE FINAL
    {
        std::string rawComps;
        switch (pixelComponents) {
            case OFX::ePixelComponentAlpha:
                rawComps = kOfxImageComponentAlpha;
                break;
            case OFX::ePixelComponentRGB:
                rawComps = kOfxImageComponentRGB;
                break;
            case OFX::ePixelComponentRGBA:
                rawComps = kOfxImageComponentRGBA;
                break;
            default:
                OFX::throwSuiteStatusException(kOfxStatFailed);
                return;
        }
        decodePlane(filename, time, renderWindow, pixelData, bounds, pixelComponents, pixelComponentCount, rawComps, rowBytes);
    }
    virtual void getClipComponents(const OFX::ClipComponentsArguments& args, OFX::ClipComponentsSetter& clipComponents) OVERRIDE FINAL;
    virtual void decodePlane(const std::string& filename, OfxTime time, const OfxRectI& renderWindow, float *pixelData, const OfxRectI& bounds, OFX::PixelComponentEnum pixelComponents, int pixelComponentCount, const std::string& rawComponents, int rowBytes) OVERRIDE FINAL;
    virtual bool getFrameBounds(const std::string& filename, OfxTime time, OfxRectI *bounds, double *par, std::string *error) OVERRIDE FINAL;
    virtual void restoreState(const std::string& filename) OVERRIDE FINAL;
    virtual void onInputFileChanged(const std::string& newFile, OFX::PreMultiplicationEnum *premult, OFX::PixelComponentEnum *components, int *componentCount) OVERRIDE FINAL;
    int getImageLayers(const std::string& filename);
    int _imageLayers;
    int _imageWidth;
    int _imageHeight;
};

ReadPSDPlugin::ReadPSDPlugin(OfxImageEffectHandle handle)
: GenericReaderPlugin(handle, kSupportsRGBA, kSupportsRGB, kSupportsAlpha, kSupportsTiles,
#ifdef OFX_EXTENSIONS_NUKE
(OFX::getImageEffectHostDescription() && OFX::getImageEffectHostDescription()->isMultiPlanar) ? kIsMultiPlanar : false
#else
false
#endif
)
,_imageLayers(0)
,_imageWidth(0)
,_imageHeight(0)
{
    Magick::InitializeMagick(NULL);
    assert(_outputComponents);
}

ReadPSDPlugin::~ReadPSDPlugin()
{
}

int ReadPSDPlugin::getImageLayers(const std::string &filename)
{
    #ifdef DEBUG
    std::cout << "getImageLayers ..." << std::endl;
    #endif
    int layers;
    std::list <Magick::Image> image;
    Magick::readImages(&image, filename);
    layers = image.size();
    if (layers>0)
        layers--;
    #ifdef DEBUG
    std::cout << "found " << layers << " layers" << std::endl;
    #endif
    return layers;
}

void ReadPSDPlugin::getClipComponents(const OFX::ClipComponentsArguments& args, OFX::ClipComponentsSetter& clipComponents)
{
    #ifdef DEBUG
    std::cout << "getClipComponents ..." << std::endl;
    #endif
    assert(isMultiPlanar());
    clipComponents.addClipComponents(*_outputClip, getOutputComponents());
    clipComponents.setPassThroughClip(NULL, args.time, args.view);
    if (_imageLayers>0) {
        for(int i = 1; i<_imageLayers+1;i++) {
            std::string component(kNatronOfxImageComponentsPlane);
            std::ostringstream layerName;
            layerName << "Layer#" << i;
            component.append(layerName.str());
            component.append(kNatronOfxImageComponentsPlaneChannel);
            component.append("R");
            component.append(kNatronOfxImageComponentsPlaneChannel);
            component.append("G");
            component.append(kNatronOfxImageComponentsPlaneChannel);
            component.append("B");
            component.append(kNatronOfxImageComponentsPlaneChannel);
            component.append("A");
            clipComponents.addClipComponents(*_outputClip, component);
        }
    }
}

void ReadPSDPlugin::decodePlane(const std::string& filename, OfxTime /*time*/, const OfxRectI& /*renderWindow*/, float *pixelData, const OfxRectI& bounds,
                                 OFX::PixelComponentEnum /*pixelComponents*/, int /*pixelComponentCount*/, const std::string& rawComponents, int /*rowBytes*/)
{
    #ifdef DEBUG
    std::cout << "decodePlane ..." << std::endl;
    #endif
    int layer = 0;
    std::string layerInfo = rawComponents;
    std::replace(layerInfo.begin(), layerInfo.end(), '_', ' ');
    std::stringstream stream(layerInfo);
    std::string streamInfo;
    while (stream>>streamInfo) {
        std::string findLayer = "Layer#";
        if (streamInfo.find(findLayer) != std::string::npos) {
            streamInfo.erase(streamInfo.find(findLayer),findLayer.length());
            layer = std::atoi(streamInfo.c_str());
        }
    }
    Magick::Image image;
    #ifdef DEBUG
    image.debug(DEBUG_MAGICK);
    #endif
    image.backgroundColor("none");
    std::ostringstream file;
    file << filename.c_str() << "[" << layer << "]";
    image.read(file.str());
    if (image.columns()>0 && image.rows()>0) {
        Magick::Image container(Magick::Geometry(bounds.x2,bounds.y2),Magick::Color("rgba(0,0,0,0)"));
        #ifdef DEBUG
        container.debug(DEBUG_MAGICK);
        #endif
        container.composite(image,image.page().xOff(),image.page().yOff(),Magick::OverCompositeOp);
        container.flip();
        container.write(0,0,bounds.x2,bounds.y2,"RGBA",Magick::FloatPixel,pixelData);
    }
    else {
        setPersistentMessage(OFX::Message::eMessageError, "", "Unable to read image");
        OFX::throwSuiteStatusException(kOfxStatErrFormat);
    }
}

bool ReadPSDPlugin::getFrameBounds(const std::string& /*filename*/,
                              OfxTime /*time*/,
                              OfxRectI *bounds,
                              double *par,
                              std::string */*error*/)
{
    #ifdef DEBUG
    std::cout << "getFrameBounds ..." << std::endl;
    #endif
    if (_imageWidth>0 && _imageHeight>0) {
        bounds->x1 = 0;
        bounds->x2 = _imageWidth;
        bounds->y1 = 0;
        bounds->y2 = _imageHeight;
        *par = 1.0;
    }
    return true;
}

void ReadPSDPlugin::restoreState(const std::string& filename)
{
    #ifdef DEBUG
    std::cout << "restoreState ..." << std::endl;
    #endif
    Magick::Image image;
    #ifdef DEBUG
    image.debug(DEBUG_MAGICK);
    #endif
    image.read(filename);
    if (image.columns()>0 && image.rows()>0) {
        _imageWidth = image.columns();
        _imageHeight = image.rows();
        _imageLayers = getImageLayers(filename);
    }
    else {
        setPersistentMessage(OFX::Message::eMessageError, "", "Unable to read image");
        OFX::throwSuiteStatusException(kOfxStatErrFormat);
    }
}

void ReadPSDPlugin::onInputFileChanged(const std::string& newFile,
                                  OFX::PreMultiplicationEnum *premult,
                                  OFX::PixelComponentEnum *components,int */*componentCount*/)
{
    #ifdef DEBUG
    std::cout << "onInputFileChanged ..." << std::endl;
    #endif
    assert(premult && components);
    Magick::Image image;
    #ifdef DEBUG
    image.debug(DEBUG_MAGICK);
    #endif
    image.read(newFile);
    if (image.columns()>0 && image.rows()>0) {
        _imageWidth = image.columns();
        _imageHeight = image.rows();
        _imageLayers = getImageLayers(newFile);
        # ifdef OFX_IO_USING_OCIO
        switch(image.colorSpace()) {
        case Magick::RGBColorspace:
            _ocio->setInputColorspace("sRGB");
            break;
        case Magick::sRGBColorspace:
            _ocio->setInputColorspace("sRGB");
            break;
        case Magick::scRGBColorspace:
            _ocio->setInputColorspace("sRGB");
            break;
        case Magick::Rec709LumaColorspace:
            _ocio->setInputColorspace("Rec709");
            break;
        case Magick::Rec709YCbCrColorspace:
            _ocio->setInputColorspace("Rec709");
            break;
        default:
            _ocio->setInputColorspace("Linear");
            break;
        }
        # endif // OFX_IO_USING_OCIO
    }
    else {
        setPersistentMessage(OFX::Message::eMessageError, "", "Unable to read image");
        OFX::throwSuiteStatusException(kOfxStatErrFormat);
    }
    *components = OFX::ePixelComponentRGBA;
    *premult = OFX::eImageOpaque;
}

using namespace OFX;

mDeclareReaderPluginFactory(ReadPSDPluginFactory, {}, {}, false);

/** @brief The basic describe function, passed a plugin descriptor */
void ReadPSDPluginFactory::describe(OFX::ImageEffectDescriptor &desc)
{
    GenericReaderDescribe(desc, kSupportsTiles, kIsMultiPlanar);
    desc.setLabel(kPluginName);

    #ifdef OFX_EXTENSIONS_TUTTLE
    const char* extensions[] = {"psd", NULL};
    desc.addSupportedExtensions(extensions);
    desc.setPluginEvaluation(92);
    #endif

    std::string magickV = MagickCore::GetMagickVersion(NULL);
    desc.setPluginDescription("Read PSD image format.\n\nWritten by Ole-André Rodlie <olear@fxarena.net>\n\nPowered by "+magickV);
}

/** @brief The describe in context function, passed a plugin descriptor and a context */
void ReadPSDPluginFactory::describeInContext(OFX::ImageEffectDescriptor &desc, ContextEnum context)
{
    PageParamDescriptor *page = GenericReaderDescribeInContextBegin(desc, context, isVideoStreamPlugin(), kSupportsRGBA, kSupportsRGB, kSupportsAlpha, kSupportsTiles);
    GenericReaderDescribeInContextEnd(desc, context, page, "reference", "reference");
}

/** @brief The create instance function, the plugin must return an object derived from the \ref OFX::ImageEffect class */
ImageEffect* ReadPSDPluginFactory::createInstance(OfxImageEffectHandle handle,
                                     ContextEnum /*context*/)
{
    ReadPSDPlugin* ret =  new ReadPSDPlugin(handle);
    ret->restoreStateFromParameters();
    return ret;
}

void getReadPSDPluginID(OFX::PluginFactoryArray &ids)
{
    static ReadPSDPluginFactory p(kPluginIdentifier, kPluginVersionMajor, kPluginVersionMinor);
    ids.push_back(&p);
}
<|endoftext|>


<commit_before>#pragma once
//=====================================================================//
/*!	@file
	@brief	R8C メイン・ヘッダー
	@author	平松邦仁 (hira@rvf-rc45.net)
*/
//=====================================================================//
#include "M120AN/port.hpp"
#include "common/intr_utils.hpp"
#include "common/uart_io.hpp"
#include "common/trb_io.hpp"
#include "common/trc_io.hpp"
#include "common/adc_io.hpp"
#include "common/flash_io.hpp"
#include "common/ds1371_io.hpp"
#include "common/lcd_io.hpp"
#include "common/monograph.hpp"
#include "port_def.hpp"

typedef device::uart_io<device::UART0, 16, 16> uart0;

typedef device::trb_io<utils::null_task> timer_b;

typedef device::trc_io<utils::null_task> timer_c;

typedef device::adc_io adc;

typedef device::flash_io flash;

typedef graphics::monograph mono_graph;

typedef device::ds1371_io<scl_sda> ds1371;

typedef device::lcd_io<spi_base, spi_ctrl> lcd;
<commit_msg>delete file<commit_after><|endoftext|>


<commit_before><commit_msg>Suppress a GTK warning and file a bug for it.<commit_after><|endoftext|>


<commit_before><commit_msg>Adding commandline option to gm to make it write image results for tests that fails due to pixel mismatches. Review URL: https://codereview.appspot.com/7100043<commit_after><|endoftext|>


<commit_before>/*
 * FogLAMP storage service.
 *
 * Copyright (c) 2017-2018 OSisoft, LLC
 *
 * Released under the Apache 2.0 Licence
 *
 * Author: Mark Riddoch, Massimiliano Pinto
 */
#include <logger.h>
#include <stdio.h>
#include <unistd.h>
#include <syslog.h>
#include <stdarg.h>
#include <memory>
#include <string.h>

using namespace std;

Logger *Logger::instance = 0;

Logger::Logger(const string& application)
{
	m_app_name = new string(application);
	openlog(m_app_name->c_str(), LOG_PID|LOG_CONS, LOG_USER);
	instance = this;
}

Logger::~Logger()
{
	closelog();
	delete m_app_name;
}

Logger *Logger::getLogger()
{
	return instance;
}

void Logger::debug(const string& msg, ...)
{
	va_list args;
	va_start(args, msg);
	string *fmt = format(msg, args);
	syslog(LOG_DEBUG, "DEBUG: %s", fmt->c_str());
	delete fmt;
	va_end(args);
}

void Logger::info(const string& msg, ...)
{
	va_list args;
	va_start(args, msg);
	string *fmt = format(msg, args);
	syslog(LOG_INFO, "INFO: %s", fmt->c_str());
	delete fmt;
	va_end(args);
}

void Logger::warn(const string& msg, ...)
{
	va_list args;
	va_start(args, msg);
	string *fmt = format(msg, args);
	syslog(LOG_WARNING, "WARNING: %s", fmt->c_str());
	delete fmt;
	va_end(args);
}

void Logger::error(const string& msg, ...)
{
	va_list args;
	va_start(args, msg);
	string *fmt = format(msg, args);
	syslog(LOG_ERR, "ERROR: %s", fmt->c_str());
	delete fmt;
	va_end(args);
}

void Logger::fatal(const string& msg, ...)
{
	va_list args;
	va_start(args, msg);
	string *fmt = format(msg, args);
	syslog(LOG_CRIT, "FATAL: %s", fmt->c_str());
	delete fmt;
	va_end(args);
}

string *Logger::format( const std::string& format, va_list args)
{
char	buf[1000];

	  vsnprintf(buf, sizeof(buf), format.c_str(), args);
	  return new string(buf);
}
<commit_msg>Added support for adding usec level timestamps to info logs, if required<commit_after>/*
 * FogLAMP storage service.
 *
 * Copyright (c) 2017-2018 OSisoft, LLC
 *
 * Released under the Apache 2.0 Licence
 *
 * Author: Mark Riddoch, Massimiliano Pinto
 */
#include <logger.h>
#include <stdio.h>
#include <unistd.h>
#include <syslog.h>
#include <stdarg.h>
#include <memory>
#include <string.h>
#include <sys/time.h>

using namespace std;

// uncomment line below to get uSec level timestamps
//#define ADD_USEC_TS

inline long getCurrTimeUsec()
{
	struct timeval m_timestamp;
	gettimeofday(&m_timestamp, NULL);
	return m_timestamp.tv_usec;
}

Logger *Logger::instance = 0;

Logger::Logger(const string& application)
{
	m_app_name = new string(application);
	openlog(m_app_name->c_str(), LOG_PID|LOG_CONS, LOG_USER);
	instance = this;
}

Logger::~Logger()
{
	closelog();
	delete m_app_name;
}

Logger *Logger::getLogger()
{
	return instance;
}

void Logger::debug(const string& msg, ...)
{
	va_list args;
	va_start(args, msg);
	string *fmt = format(msg, args);
	syslog(LOG_DEBUG, "DEBUG: %s", fmt->c_str());
	delete fmt;
	va_end(args);
}

void Logger::info(const string& msg, ...)
{
	va_list args;
	va_start(args, msg);
	string *fmt = format(msg, args);
#ifdef ADD_USEC_TS
	syslog(LOG_INFO, "[.%06ld] INFO: %s", getCurrTimeUsec(), fmt->c_str());
#else
	syslog(LOG_INFO, "INFO: %s", fmt->c_str());
#endif
	delete fmt;
	va_end(args);
}

void Logger::warn(const string& msg, ...)
{
	va_list args;
	va_start(args, msg);
	string *fmt = format(msg, args);
	syslog(LOG_WARNING, "WARNING: %s", fmt->c_str());
	delete fmt;
	va_end(args);
}

void Logger::error(const string& msg, ...)
{
	va_list args;
	va_start(args, msg);
	string *fmt = format(msg, args);
	syslog(LOG_ERR, "ERROR: %s", fmt->c_str());
	delete fmt;
	va_end(args);
}

void Logger::fatal(const string& msg, ...)
{
	va_list args;
	va_start(args, msg);
	string *fmt = format(msg, args);
	syslog(LOG_CRIT, "FATAL: %s", fmt->c_str());
	delete fmt;
	va_end(args);
}

string *Logger::format( const std::string& format, va_list args)
{
char	buf[1000];

	  vsnprintf(buf, sizeof(buf), format.c_str(), args);
	  return new string(buf);
}
<|endoftext|>