<commit_before>/*******************************************************************************
* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps  *
* Copyright (C) 2015, IGG Group, ICube, University of Strasbourg, France       *
*                                                                              *
* This library is free software; you can redistribute it and/or modify it      *
* under the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation; either version 2.1 of the License, or (at your     *
* option) any later version.                                                   *
*                                                                              *
* This library is distributed in the hope that it will be useful, but WITHOUT  *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or        *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License  *
* for more details.                                                            *
*                                                                              *
* You should have received a copy of the GNU Lesser General Public License     *
* along with this library; if not, write to the Free Software Foundation,      *
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.           *
*                                                                              *
* Web site: http://cgogn.unistra.fr/                                           *
* Contact information: cgogn@unistra.fr                                        *
*                                                                              *
*******************************************************************************/

#define CGOGN_RENDERING_DLL_EXPORT

#include <iostream>

#include <cgogn/rendering/shaders/shader_scalar_per_vertex.h>

namespace cgogn
{

namespace rendering
{

std::unique_ptr<ShaderScalarPerVertex> ShaderScalarPerVertex::instance_ = nullptr;

const char* ShaderScalarPerVertex::vertex_shader_source_ =
"#version 150\n"
"in vec3 vertex_pos;\n"
"in float vertex_scalar;\n"
"uniform mat4 projection_matrix;\n"
"uniform mat4 model_view_matrix;\n"
"uniform float min_value;\n"
"uniform float max_value;\n"
"uniform int color_map;\n"
"uniform int expansion;\n"
"out vec3 color_v;\n"
"out float scalar_v;\n"
"#define M_PI 3.1415926535897932384626433832795\n"
"float scale_and_clamp_to_0_1(float x, float min, float max)\n"
"{\n"
"	float v = (x - min) / (max - min);\n"
"	return v < 0.0 ? 0.0 : (v > 1.0 ? 1.0 : v);\n"
"}\n"
"float scale_expand_within_0_1(float x, int n)\n"
"{\n"
"	for (int i = 1; i <= n; i++)\n"
"		x = (1.0 - cos(M_PI * x)) / 2.0;\n"
"	for (int i = -1; i >= n; i--)\n"
"		x = acos(1.0 - 2.0 * x) / M_PI;\n"
"	return x;\n"
"}\n"
"float scale_expand_towards_1(float x, int n)\n"
"{\n"
"	for (int i = 1; i <= n; i++)\n"
"		x = sin(x * M_PI / 2.0);\n"
"	for (int i = -1; i >= n; i--)\n"
"		x = asin(x) * 2.0 / M_PI;\n"
"	return x;\n"
"}\n"
"vec3 color_map_blue_white_red(float x)\n"
"{\n"
"	vec3 c = vec3(0);\n"
"	if (x < 0.0)\n"
"		c.b = 1.0;\n"
"	else if (x < 0.5)\n"
"	{\n"
"		c.r = 2.0 * x;\n"
"		c.g = 2.0 * x;\n"
"		c.b = 1.0;\n"
"	}\n"
"	else if (x < 1.0)\n"
"	{\n"
"		c.r = 1.0;\n"
"		c.g = 2.0 - 2.0 * x;\n"
"		c.b = 2.0 - 2.0 * x;\n"
"	}\n"
"	else\n"
"		c.r = 1.0;\n"
"	return c;\n"
"}\n"
"vec3 color_map_cyan_white_red(float x)\n"
"{\n"
"	if (x < 0.0)\n"
"		return vec3(0.0, 0.0, 1.0) ;\n"
"	if (x < 0.5)\n"
"		return vec3(2.0 * x, 1.0 , 1.0);\n"
"	if (x < 1.0)\n"
"		return vec3(1.0, 2.0 - 2.0 * x, 2.0 - 2.0 * x);\n"
"	return vec3(1.0, 0.0, 0.0) ;\n"
"}\n"
"vec3 color_map_BCGYR(float x)\n"
"{\n"
"	if (x < 0.0)\n"
"		return vec3(0.0, 0.0, 1.0) ;\n"
"	if (x < 0.25)\n"
"		return vec3(0.0, 4.0 * x, 1.0);\n"
"	if (x < 0.5)\n"
"		return vec3(0.0, 1.0 , 2.0 - 4.0 * x);\n"
"	if (x < 0.75)\n"
"		return vec3(4.0 * x - 2.0, 1.0, 0.0);\n"
"	if (x < 1.0)\n"
"		return vec3(1.0, 4.0 - 4.0 * x, 0.0);\n"
"	return vec3(1.0, 0.0, 0.0) ;\n"
"}\n"
"vec3 color_map_blue_green_red(float x)\n"
"{\n"
"	if (x < 0.0)\n"
"		return vec3(0.0, 0.0, 1.0) ;\n"
"	if (x < 0.5)\n"
"		return vec3(0.0, 2.0 * x, 1.0 - 2.0 * x);\n"
"	if (x < 1.0)\n"
"		return vec3(2.0 * x - 1.0, 2.0 - 2.0 * x, 0.0);\n"
"	return vec3(1.0, 0.0, 0.0) ;\n"
"}\n"
"void main()\n"
"{\n"
"	float value =\n"
"		scale_expand_within_0_1(\n"
"			scale_and_clamp_to_0_1(\n"
"				vertex_scalar,\n"
"				min_value,\n"
"				max_value\n"
"			),\n"
"			expansion\n"
"		);\n"
"	switch(color_map)\n"
"	{\n"
"		case 0 : color_v = color_map_blue_white_red(value); break;\n"
"		case 1 : color_v = color_map_cyan_white_red(value); break;\n"
"		case 2 : color_v = color_map_BCGYR(value); break;\n"
"		case 3 : color_v = color_map_blue_green_red(value); break;\n"
"	}\n"
"	scalar_v = value;\n"
"   gl_Position = projection_matrix * model_view_matrix * vec4(vertex_pos, 1.0);\n"
"}\n";

const char* ShaderScalarPerVertex::fragment_shader_source_ =
"#version 150\n"
"in vec3 color_v;\n"
"in float scalar_v;\n"
"uniform bool show_iso_lines;\n"
"out vec3 fragColor;\n"
"void main() {\n"
"	if (show_iso_lines)\n"
"	{\n"
"		float s = scalar_v * 20.0;\n"
"		if (s - floor(s) < 0.05)\n"
"			fragColor = vec3(0.0);\n"
"		else\n"
"			fragColor = color_v;\n"
"	}\n"
"	else\n"
"		fragColor = color_v;\n"
"}\n";

ShaderScalarPerVertex::ShaderScalarPerVertex()
{
	prg_.addShaderFromSourceCode(QOpenGLShader::Vertex, vertex_shader_source_);
	prg_.addShaderFromSourceCode(QOpenGLShader::Fragment, fragment_shader_source_);
	prg_.bindAttributeLocation("vertex_pos", ATTRIB_POS);
	prg_.bindAttributeLocation("vertex_scalar", ATTRIB_SCALAR);
	prg_.link();
	get_matrices_uniforms();
	unif_color_map_ = prg_.uniformLocation("color_map");
	unif_expansion_ = prg_.uniformLocation("expansion");
	unif_min_value_ = prg_.uniformLocation("min_value");
	unif_max_value_ = prg_.uniformLocation("max_value");
}

void ShaderScalarPerVertex::set_color_map(ColorMap cm)
{
	if (unif_color_map_ >= 0)
		prg_.setUniformValue(unif_color_map_, cm);
}

void ShaderScalarPerVertex::set_expansion(int32 expansion)
{
	if (unif_expansion_ >= 0)
		prg_.setUniformValue(unif_expansion_, expansion);
}

void ShaderScalarPerVertex::set_min_value(float32 value)
{
	if (unif_min_value_ >= 0)
		prg_.setUniformValue(unif_min_value_, value);
}

void ShaderScalarPerVertex::set_max_value(float32 value)
{
	if (unif_max_value_ >= 0)
		prg_.setUniformValue(unif_max_value_, value);
}

void ShaderScalarPerVertex::set_show_iso_lines(bool b)
{
	if (unif_show_iso_lines_ >= 0)
		prg_.setUniformValue(unif_show_iso_lines_, b);
}

std::unique_ptr<ShaderScalarPerVertex::Param> ShaderScalarPerVertex::generate_param()
{
	if (!instance_)
		instance_ = std::unique_ptr<ShaderScalarPerVertex>(new ShaderScalarPerVertex);
	return cgogn::make_unique<Param>(instance_.get());
}

} // namespace rendering

} // namespace cgogn
<commit_msg>bug fix in scalar per vertex shader<commit_after>/*******************************************************************************
* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps  *
* Copyright (C) 2015, IGG Group, ICube, University of Strasbourg, France       *
*                                                                              *
* This library is free software; you can redistribute it and/or modify it      *
* under the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation; either version 2.1 of the License, or (at your     *
* option) any later version.                                                   *
*                                                                              *
* This library is distributed in the hope that it will be useful, but WITHOUT  *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or        *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License  *
* for more details.                                                            *
*                                                                              *
* You should have received a copy of the GNU Lesser General Public License     *
* along with this library; if not, write to the Free Software Foundation,      *
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.           *
*                                                                              *
* Web site: http://cgogn.unistra.fr/                                           *
* Contact information: cgogn@unistra.fr                                        *
*                                                                              *
*******************************************************************************/

#define CGOGN_RENDERING_DLL_EXPORT

#include <iostream>

#include <cgogn/rendering/shaders/shader_scalar_per_vertex.h>

namespace cgogn
{

namespace rendering
{

std::unique_ptr<ShaderScalarPerVertex> ShaderScalarPerVertex::instance_ = nullptr;

const char* ShaderScalarPerVertex::vertex_shader_source_ =
"#version 150\n"
"in vec3 vertex_pos;\n"
"in float vertex_scalar;\n"
"uniform mat4 projection_matrix;\n"
"uniform mat4 model_view_matrix;\n"
"uniform float min_value;\n"
"uniform float max_value;\n"
"uniform int color_map;\n"
"uniform int expansion;\n"
"out vec3 color_v;\n"
"out float scalar_v;\n"
"#define M_PI 3.1415926535897932384626433832795\n"
"float scale_and_clamp_to_0_1(float x, float min, float max)\n"
"{\n"
"	float v = (x - min) / (max - min);\n"
"	return v < 0.0 ? 0.0 : (v > 1.0 ? 1.0 : v);\n"
"}\n"
"float scale_expand_within_0_1(float x, int n)\n"
"{\n"
"	for (int i = 1; i <= n; i++)\n"
"		x = (1.0 - cos(M_PI * x)) / 2.0;\n"
"	for (int i = -1; i >= n; i--)\n"
"		x = acos(1.0 - 2.0 * x) / M_PI;\n"
"	return x;\n"
"}\n"
"float scale_expand_towards_1(float x, int n)\n"
"{\n"
"	for (int i = 1; i <= n; i++)\n"
"		x = sin(x * M_PI / 2.0);\n"
"	for (int i = -1; i >= n; i--)\n"
"		x = asin(x) * 2.0 / M_PI;\n"
"	return x;\n"
"}\n"
"vec3 color_map_blue_white_red(float x)\n"
"{\n"
"	vec3 c = vec3(0);\n"
"	if (x < 0.0)\n"
"		c.b = 1.0;\n"
"	else if (x < 0.5)\n"
"	{\n"
"		c.r = 2.0 * x;\n"
"		c.g = 2.0 * x;\n"
"		c.b = 1.0;\n"
"	}\n"
"	else if (x < 1.0)\n"
"	{\n"
"		c.r = 1.0;\n"
"		c.g = 2.0 - 2.0 * x;\n"
"		c.b = 2.0 - 2.0 * x;\n"
"	}\n"
"	else\n"
"		c.r = 1.0;\n"
"	return c;\n"
"}\n"
"vec3 color_map_cyan_white_red(float x)\n"
"{\n"
"	if (x < 0.0)\n"
"		return vec3(0.0, 0.0, 1.0) ;\n"
"	if (x < 0.5)\n"
"		return vec3(2.0 * x, 1.0 , 1.0);\n"
"	if (x < 1.0)\n"
"		return vec3(1.0, 2.0 - 2.0 * x, 2.0 - 2.0 * x);\n"
"	return vec3(1.0, 0.0, 0.0) ;\n"
"}\n"
"vec3 color_map_BCGYR(float x)\n"
"{\n"
"	if (x < 0.0)\n"
"		return vec3(0.0, 0.0, 1.0) ;\n"
"	if (x < 0.25)\n"
"		return vec3(0.0, 4.0 * x, 1.0);\n"
"	if (x < 0.5)\n"
"		return vec3(0.0, 1.0 , 2.0 - 4.0 * x);\n"
"	if (x < 0.75)\n"
"		return vec3(4.0 * x - 2.0, 1.0, 0.0);\n"
"	if (x < 1.0)\n"
"		return vec3(1.0, 4.0 - 4.0 * x, 0.0);\n"
"	return vec3(1.0, 0.0, 0.0) ;\n"
"}\n"
"vec3 color_map_blue_green_red(float x)\n"
"{\n"
"	if (x < 0.0)\n"
"		return vec3(0.0, 0.0, 1.0) ;\n"
"	if (x < 0.5)\n"
"		return vec3(0.0, 2.0 * x, 1.0 - 2.0 * x);\n"
"	if (x < 1.0)\n"
"		return vec3(2.0 * x - 1.0, 2.0 - 2.0 * x, 0.0);\n"
"	return vec3(1.0, 0.0, 0.0) ;\n"
"}\n"
"void main()\n"
"{\n"
"	float value =\n"
"		scale_expand_within_0_1(\n"
"			scale_and_clamp_to_0_1(\n"
"				vertex_scalar,\n"
"				min_value,\n"
"				max_value\n"
"			),\n"
"			expansion\n"
"		);\n"
"	switch(color_map)\n"
"	{\n"
"		case 0 : color_v = color_map_blue_white_red(value); break;\n"
"		case 1 : color_v = color_map_cyan_white_red(value); break;\n"
"		case 2 : color_v = color_map_BCGYR(value); break;\n"
"		case 3 : color_v = color_map_blue_green_red(value); break;\n"
"	}\n"
"	scalar_v = value;\n"
"   gl_Position = projection_matrix * model_view_matrix * vec4(vertex_pos, 1.0);\n"
"}\n";

const char* ShaderScalarPerVertex::fragment_shader_source_ =
"#version 150\n"
"in vec3 color_v;\n"
"in float scalar_v;\n"
"uniform bool show_iso_lines;\n"
"out vec3 fragColor;\n"
"void main() {\n"
"	if (show_iso_lines)\n"
"	{\n"
"		float s = scalar_v * 20.0;\n"
"		if (s - floor(s) < 0.05)\n"
"			fragColor = vec3(0.0);\n"
"		else\n"
"			fragColor = color_v;\n"
"	}\n"
"	else\n"
"		fragColor = color_v;\n"
"}\n";

ShaderScalarPerVertex::ShaderScalarPerVertex()
{
	prg_.addShaderFromSourceCode(QOpenGLShader::Vertex, vertex_shader_source_);
	prg_.addShaderFromSourceCode(QOpenGLShader::Fragment, fragment_shader_source_);
	prg_.bindAttributeLocation("vertex_pos", ATTRIB_POS);
	prg_.bindAttributeLocation("vertex_scalar", ATTRIB_SCALAR);
	prg_.link();
	get_matrices_uniforms();
	unif_color_map_ = prg_.uniformLocation("color_map");
	unif_expansion_ = prg_.uniformLocation("expansion");
	unif_min_value_ = prg_.uniformLocation("min_value");
	unif_max_value_ = prg_.uniformLocation("max_value");
	unif_show_iso_lines_ = prg_.uniformLocation("show_iso_lines");
}

void ShaderScalarPerVertex::set_color_map(ColorMap cm)
{
	if (unif_color_map_ >= 0)
		prg_.setUniformValue(unif_color_map_, cm);
}

void ShaderScalarPerVertex::set_expansion(int32 expansion)
{
	if (unif_expansion_ >= 0)
		prg_.setUniformValue(unif_expansion_, expansion);
}

void ShaderScalarPerVertex::set_min_value(float32 value)
{
	if (unif_min_value_ >= 0)
		prg_.setUniformValue(unif_min_value_, value);
}

void ShaderScalarPerVertex::set_max_value(float32 value)
{
	if (unif_max_value_ >= 0)
		prg_.setUniformValue(unif_max_value_, value);
}

void ShaderScalarPerVertex::set_show_iso_lines(bool b)
{
	if (unif_show_iso_lines_ >= 0)
		prg_.setUniformValue(unif_show_iso_lines_, b);
}

std::unique_ptr<ShaderScalarPerVertex::Param> ShaderScalarPerVertex::generate_param()
{
	if (!instance_)
		instance_ = std::unique_ptr<ShaderScalarPerVertex>(new ShaderScalarPerVertex);
	return cgogn::make_unique<Param>(instance_.get());
}

} // namespace rendering

} // namespace cgogn
<|endoftext|>


<commit_before>#include "buildClassConstructorsEtc.h"
#include "symtab.h"
#include "symscope.h"
#include "symbol.h"
#include "type.h"
#include "expr.h"
#include "stmt.h"
#include "stringutil.h"
#include "../traversals/fixup.h"

static void build_constructor(StructuralType* structType) {
  char* name = glomstrings(2, "_construct_", structType->symbol->name);
  FnSymbol* fn = Symboltable::startFnDef(new FnSymbol(name));
  structType->defaultConstructor = fn;
  fn->isConstructor = true;
  fn->cname = glomstrings(2, "_construct_", structType->symbol->cname);

  ParamSymbol* args = NULL;

  if (!useOldConstructor) {
    if (analyzeAST) {
      forv_Vec(TypeSymbol, tmp, structType->types) {
        if (dynamic_cast<VariableType*>(tmp->type)) {
          ParamSymbol* arg = new ParamSymbol(PARAM_BLANK, tmp->name, tmp->type);
          args = appendLink(args, arg);
        }
      }

      forv_Vec(VarSymbol, tmp, structType->fields) {
        char* name = tmp->name;
        Type* type = tmp->type;
        Expr* init = (tmp->defPoint->init) ? tmp->defPoint->init->copy() : new VarInitExpr(tmp);
        if (tmp->defPoint->init) {
          tmp->defPoint->init->extract();
        }
        ParamSymbol* arg = new ParamSymbol(PARAM_BLANK, name, type, init);
        args = appendLink(args, arg);
      }
    }
  }

  Symboltable::continueFnDef(fn, args, structType);

  BlockStmt* body = Symboltable::startCompoundStmt();
  Stmt* stmts = NULL;
  fn->_this = new VarSymbol("this", structType);
  dynamic_cast<VarSymbol*>(fn->_this)->noDefaultInit = true;
  DefExpr* def_expr = new DefExpr(fn->_this);
  stmts = new DefStmt(def_expr);
  if (dynamic_cast<ClassType*>(structType)) {
    char* description = glomstrings(2, "instance of class ", structType->symbol->name);
    Expr* alloc_args = new IntLiteral("1", 1);
    alloc_args = appendLink(alloc_args, new SizeofExpr(structType));
    alloc_args = appendLink(alloc_args, new StringLiteral(description));
    Symbol* alloc_sym = Symboltable::lookupInternal("_chpl_malloc");
    Expr* alloc_call = new FnCall(new Variable(alloc_sym), alloc_args);
    Expr* alloc_lhs = new Variable(fn->_this);
    Expr* alloc_rhs = new CastExpr(structType, alloc_call);
    Expr* alloc_expr = new AssignOp(GETS_NORM, alloc_lhs, alloc_rhs);
    Stmt* alloc_stmt = new ExprStmt(alloc_expr);
    stmts = appendLink(stmts, alloc_stmt);
  }
  structType->buildConstructorBody(stmts, fn->_this, args);

  stmts = appendLink(stmts, new ReturnStmt(new Variable(fn->_this)));
  body = Symboltable::finishCompoundStmt(body, stmts);
  DefExpr* fn_def =
    new DefExpr(Symboltable::finishFnDef(fn, body));
  structType->symbol->defPoint->parentStmt->insertBefore(new DefStmt(fn_def));
}

static void build_union_id_enum(StructuralType* structType) {
  UnionType* unionType = dynamic_cast<UnionType*>(structType);
  if (unionType) {
    unionType->buildFieldSelector();
  }
}

static void build_setters_and_getters(StructuralType* structType) {
  forv_Vec(VarSymbol, tmp, structType->fields) {
    char* setter_name = glomstrings(2, "set_", tmp->name);
    FnSymbol* setter_fn = Symboltable::startFnDef(new FnSymbol(setter_name));
    setter_fn->cname = glomstrings(4, "_", structType->symbol->name, "_", setter_name);
    setter_fn->_setter = tmp;
    ParamSymbol* setter_this = new ParamSymbol(PARAM_REF, "this", structType);
    ParamSymbol* setter_arg = new ParamSymbol(PARAM_BLANK, "_arg", tmp->type);
    setter_this->append(setter_arg);
    Symboltable::continueFnDef(setter_fn, setter_this, dtVoid);
    Expr* setter_lhs = new MemberAccess(new Variable(setter_this), tmp);
    Expr* setter_rhs = new Variable(setter_arg);
    Expr* setter_assignment = new AssignOp(GETS_NORM, setter_lhs, setter_rhs);
    Stmt* setter_stmt = new ExprStmt(setter_assignment);
    DefExpr* setter_def_expr = new DefExpr(
      Symboltable::finishFnDef(setter_fn, setter_stmt));
    DefStmt* setter_def_stmt = new DefStmt(setter_def_expr);
    structType->addDeclarations(setter_def_stmt);
    setter_fn->classBinding = structType->symbol;
    setter_fn->_this = setter_this;

    char* getter_name = glomstrings(2, "_chplget_", tmp->name);
    FnSymbol* getter_fn = Symboltable::startFnDef(new FnSymbol(getter_name));
    getter_fn->cname = glomstrings(4, "_", structType->symbol->name, "_", getter_name);
    getter_fn->_getter = tmp;
    ParamSymbol* getter_this = new ParamSymbol(PARAM_REF, "this", structType);
    Symboltable::continueFnDef(getter_fn, getter_this, tmp->type);
    Expr* getter_expr = new MemberAccess(new Variable(getter_this), tmp);
    Stmt* getter_return = new ReturnStmt(getter_expr);
    DefExpr* getter_def_expr = new DefExpr(
      Symboltable::finishFnDef(getter_fn, getter_return));
    DefStmt* getter_def_stmt = new DefStmt(getter_def_expr);
    structType->addDeclarations(getter_def_stmt);
    getter_fn->classBinding = structType->symbol;
    getter_fn->_this = getter_this;
    /**
     **  Hack getter to have name of field (Can no longer lookup!)
     **/
    getter_fn->name = copystring(tmp->name);
  }
}

static void build_record_equality_function(StructuralType* structType) {
  if (dynamic_cast<ClassType*>(structType)) {
    return;
  }

  FnSymbol* fn = Symboltable::startFnDef(new FnSymbol("=="));
  ParamSymbol* arg1 = new ParamSymbol(PARAM_BLANK, "_arg1", structType);
  ParamSymbol* arg2 = new ParamSymbol(PARAM_BLANK, "_arg2", structType);
  arg1->append(arg2);
  Symboltable::continueFnDef(fn, arg1, dtBoolean);
  Expr* cond = NULL;
  forv_Vec(VarSymbol, tmp, structType->fields) {
    Expr* left = new MemberAccess(new Variable(arg1), tmp);
    Expr* right = new MemberAccess(new Variable(arg2), tmp);
    cond = (cond)
      ? new BinOp(BINOP_LOGAND, cond, new BinOp(BINOP_EQUAL, left, right))
      : new BinOp(BINOP_EQUAL, left, right);
  }
  Stmt* retStmt = new ReturnStmt(cond);
  DefStmt* def_stmt = new DefStmt(new DefExpr(Symboltable::finishFnDef(fn,
                                                                       retStmt))
                                  );
  structType->symbol->defPoint->parentStmt->insertBefore(def_stmt);
}

static void build_record_inequality_function(StructuralType* structType) {
  if (dynamic_cast<ClassType*>(structType)) {
    return;
  }

  FnSymbol* fn = Symboltable::startFnDef(new FnSymbol("!="));

  ParamSymbol* arg1 = new ParamSymbol(PARAM_BLANK, "_arg1", structType);
  ParamSymbol* arg2 = new ParamSymbol(PARAM_BLANK, "_arg2", structType);
  arg1->append(arg2);
  Symboltable::continueFnDef(fn, arg1, dtBoolean);
  Expr* cond = NULL;
  forv_Vec(VarSymbol, tmp, structType->fields) {
    Expr* left = new MemberAccess(new Variable(arg1), tmp);
    Expr* right = new MemberAccess(new Variable(arg2), tmp);
    cond = (cond)
      ? new BinOp(BINOP_LOGOR, cond, new BinOp(BINOP_NEQUAL, left, right))
      : new BinOp(BINOP_NEQUAL, left, right);
  }
  Stmt* retStmt = new ReturnStmt(cond);
  DefStmt* def_stmt = new DefStmt(new DefExpr(Symboltable::finishFnDef(fn,
                                                                       retStmt))
                                  );
  structType->symbol->defPoint->parentStmt->insertBefore(def_stmt);
}

static void build_record_assignment_function(StructuralType* structType) {
  if (dynamic_cast<ClassType*>(structType)) {
    return;
  }

  FnSymbol* fn = Symboltable::startFnDef(new FnSymbol("="));
  ParamSymbol* arg1 = new ParamSymbol(PARAM_BLANK, "_arg1", structType);
  ParamSymbol* arg2 = new ParamSymbol(PARAM_BLANK, "_arg2",
    (analyzeAST) ? dtUnknown : structType);
  arg1->append(arg2);
  Type *ret_type = analyzeAST ? dtUnknown : dtVoid;
  Symboltable::continueFnDef(fn, arg1, ret_type);
  Stmt* body = NULL;
  Symboltable::pushScope(SCOPE_LOCAL);
  forv_Vec(VarSymbol, tmp, structType->fields) {
    Expr* left = new MemberAccess(new Variable(arg1), tmp);
    Expr* right = new MemberAccess(new Variable(arg2), tmp);
    Expr* assign_expr = new AssignOp(GETS_NORM, left, right);
    body = appendLink(body, new ExprStmt(assign_expr));
  }

  if (analyzeAST)
    body = appendLink(body, new ReturnStmt(new Variable(arg2)));
  BlockStmt* block_stmt = new BlockStmt(body, Symboltable::popScope());
  DefStmt* defStmt = new DefStmt(new DefExpr(Symboltable::finishFnDef(fn,
                                                                      block_stmt
                                                                      )));
  structType->symbol->defPoint->parentStmt->insertBefore(defStmt);
}

// static void build_tuple_assignment_function(TupleType* tuple_type) {
//   FnSymbol* fn = Symboltable::startFnDef(new FnSymbol("="));

//   ParamSymbol* arg1 = new ParamSymbol(PARAM_BLANK, "_arg1", tuple_type);
//   ParamSymbol* arg2 = new ParamSymbol(PARAM_BLANK, "_arg2",
//     (analyzeAST) ? dtUnknown : tuple_type);
//   arg1->append(arg2);
//   Stmt* body = NULL;
//   for (int i = 1; i <= tuple_type->components.n; i++) {
//     Expr* left =
//       new TupleSelect(new Variable(arg1), new IntLiteral(intstring(i), i));
//     Expr* right =
//       new TupleSelect(new Variable(arg2), new IntLiteral(intstring(i), i));
//     Expr* assign_expr = new AssignOp(GETS_NORM, left, right);
//     body = appendLink(body, new ExprStmt(assign_expr));
//   }
//   BlockStmt* block_stmt = new BlockStmt(body);
//   DefStmt* def_stmt = new DefStmt(new DefExpr(Symboltable::finishFnDef(fn, arg1, dtVoid, block_stmt)));
//   tuple_type->symbol->defPoint->parentStmt->insertBefore(def_stmt);
// }

void buildDefaultStructuralTypeMethods(StructuralType* structuralType) {
  SymScope* newScope =
    structuralType->structScope->findEnclosingScopeLessType(SCOPE_MODULE);
  SymScope* saveScope =
    Symboltable::setCurrentScope(newScope);
  build_setters_and_getters(structuralType);
  build_union_id_enum(structuralType);
  build_constructor(structuralType);
  build_record_equality_function(structuralType);
  build_record_inequality_function(structuralType);
  build_record_assignment_function(structuralType);
  Symboltable::setCurrentScope(saveScope);
}

void BuildClassConstructorsEtc::postProcessExpr(Expr* expr) {
  if (DefExpr* defExpr = dynamic_cast<DefExpr*>(expr)) {
    if (TypeSymbol* sym = dynamic_cast<TypeSymbol*>(defExpr->sym)) {
      if (StructuralType* type = dynamic_cast<StructuralType*>(sym->type)) {
        if (type->defaultConstructor) { /*** already done ***/
          return;
        }
        buildDefaultStructuralTypeMethods(type);
      }
    }
  }
}
<commit_msg>Added constructor of a class to the class's list of methods.<commit_after>#include "buildClassConstructorsEtc.h"
#include "symtab.h"
#include "symscope.h"
#include "symbol.h"
#include "type.h"
#include "expr.h"
#include "stmt.h"
#include "stringutil.h"
#include "../traversals/fixup.h"

static void build_constructor(StructuralType* structType) {
  char* name = glomstrings(2, "_construct_", structType->symbol->name);
  FnSymbol* fn = Symboltable::startFnDef(new FnSymbol(name));
  structType->defaultConstructor = fn;
  fn->isConstructor = true;
  fn->cname = glomstrings(2, "_construct_", structType->symbol->cname);

  ParamSymbol* args = NULL;

  if (!useOldConstructor) {
    if (analyzeAST) {
      forv_Vec(TypeSymbol, tmp, structType->types) {
        if (dynamic_cast<VariableType*>(tmp->type)) {
          ParamSymbol* arg = new ParamSymbol(PARAM_BLANK, tmp->name, tmp->type);
          args = appendLink(args, arg);
        }
      }

      forv_Vec(VarSymbol, tmp, structType->fields) {
        char* name = tmp->name;
        Type* type = tmp->type;
        Expr* init = (tmp->defPoint->init) ? tmp->defPoint->init->copy() : new VarInitExpr(tmp);
        if (tmp->defPoint->init) {
          tmp->defPoint->init->extract();
        }
        ParamSymbol* arg = new ParamSymbol(PARAM_BLANK, name, type, init);
        args = appendLink(args, arg);
      }
    }
  }

  Symboltable::continueFnDef(fn, args, structType);

  BlockStmt* body = Symboltable::startCompoundStmt();
  Stmt* stmts = NULL;
  fn->_this = new VarSymbol("this", structType);
  dynamic_cast<VarSymbol*>(fn->_this)->noDefaultInit = true;
  DefExpr* def_expr = new DefExpr(fn->_this);
  stmts = new DefStmt(def_expr);
  if (dynamic_cast<ClassType*>(structType)) {
    char* description = glomstrings(2, "instance of class ", structType->symbol->name);
    Expr* alloc_args = new IntLiteral("1", 1);
    alloc_args = appendLink(alloc_args, new SizeofExpr(structType));
    alloc_args = appendLink(alloc_args, new StringLiteral(description));
    Symbol* alloc_sym = Symboltable::lookupInternal("_chpl_malloc");
    Expr* alloc_call = new FnCall(new Variable(alloc_sym), alloc_args);
    Expr* alloc_lhs = new Variable(fn->_this);
    Expr* alloc_rhs = new CastExpr(structType, alloc_call);
    Expr* alloc_expr = new AssignOp(GETS_NORM, alloc_lhs, alloc_rhs);
    Stmt* alloc_stmt = new ExprStmt(alloc_expr);
    stmts = appendLink(stmts, alloc_stmt);
  }
  structType->buildConstructorBody(stmts, fn->_this, args);

  stmts = appendLink(stmts, new ReturnStmt(new Variable(fn->_this)));
  body = Symboltable::finishCompoundStmt(body, stmts);
  DefExpr* fn_def =
    new DefExpr(Symboltable::finishFnDef(fn, body));
  structType->symbol->defPoint->parentStmt->insertBefore(new DefStmt(fn_def));
  structType->methods.add(fn);
}

static void build_union_id_enum(StructuralType* structType) {
  UnionType* unionType = dynamic_cast<UnionType*>(structType);
  if (unionType) {
    unionType->buildFieldSelector();
  }
}

static void build_setters_and_getters(StructuralType* structType) {
  forv_Vec(VarSymbol, tmp, structType->fields) {
    char* setter_name = glomstrings(2, "set_", tmp->name);
    FnSymbol* setter_fn = Symboltable::startFnDef(new FnSymbol(setter_name));
    setter_fn->cname = glomstrings(4, "_", structType->symbol->name, "_", setter_name);
    setter_fn->_setter = tmp;
    ParamSymbol* setter_this = new ParamSymbol(PARAM_REF, "this", structType);
    ParamSymbol* setter_arg = new ParamSymbol(PARAM_BLANK, "_arg", tmp->type);
    setter_this->append(setter_arg);
    Symboltable::continueFnDef(setter_fn, setter_this, dtVoid);
    Expr* setter_lhs = new MemberAccess(new Variable(setter_this), tmp);
    Expr* setter_rhs = new Variable(setter_arg);
    Expr* setter_assignment = new AssignOp(GETS_NORM, setter_lhs, setter_rhs);
    Stmt* setter_stmt = new ExprStmt(setter_assignment);
    DefExpr* setter_def_expr = new DefExpr(
      Symboltable::finishFnDef(setter_fn, setter_stmt));
    DefStmt* setter_def_stmt = new DefStmt(setter_def_expr);
    structType->symbol->defPoint->parentStmt->insertBefore(setter_def_stmt);
    structType->methods.add(setter_fn);
    setter_fn->method_type = PRIMARY_METHOD;
    setter_fn->classBinding = structType->symbol;
    setter_fn->_this = setter_this;

    char* getter_name = glomstrings(2, "_chplget_", tmp->name);
    FnSymbol* getter_fn = Symboltable::startFnDef(new FnSymbol(getter_name));
    getter_fn->cname = glomstrings(4, "_", structType->symbol->name, "_", getter_name);
    getter_fn->_getter = tmp;
    ParamSymbol* getter_this = new ParamSymbol(PARAM_REF, "this", structType);
    Symboltable::continueFnDef(getter_fn, getter_this, tmp->type);
    Expr* getter_expr = new MemberAccess(new Variable(getter_this), tmp);
    Stmt* getter_return = new ReturnStmt(getter_expr);
    DefExpr* getter_def_expr = new DefExpr(
      Symboltable::finishFnDef(getter_fn, getter_return));
    DefStmt* getter_def_stmt = new DefStmt(getter_def_expr);
    structType->symbol->defPoint->parentStmt->insertBefore(getter_def_stmt);
    structType->methods.add(getter_fn);
    getter_fn->method_type = PRIMARY_METHOD;
    getter_fn->classBinding = structType->symbol;
    getter_fn->_this = getter_this;
    /**
     **  Hack getter to have name of field (Can no longer lookup!)
     **/
    getter_fn->name = copystring(tmp->name);
  }
}

static void build_record_equality_function(StructuralType* structType) {
  if (dynamic_cast<ClassType*>(structType)) {
    return;
  }

  FnSymbol* fn = Symboltable::startFnDef(new FnSymbol("=="));
  ParamSymbol* arg1 = new ParamSymbol(PARAM_BLANK, "_arg1", structType);
  ParamSymbol* arg2 = new ParamSymbol(PARAM_BLANK, "_arg2", structType);
  arg1->append(arg2);
  Symboltable::continueFnDef(fn, arg1, dtBoolean);
  Expr* cond = NULL;
  forv_Vec(VarSymbol, tmp, structType->fields) {
    Expr* left = new MemberAccess(new Variable(arg1), tmp);
    Expr* right = new MemberAccess(new Variable(arg2), tmp);
    cond = (cond)
      ? new BinOp(BINOP_LOGAND, cond, new BinOp(BINOP_EQUAL, left, right))
      : new BinOp(BINOP_EQUAL, left, right);
  }
  Stmt* retStmt = new ReturnStmt(cond);
  DefStmt* def_stmt = new DefStmt(new DefExpr(Symboltable::finishFnDef(fn,
                                                                       retStmt))
                                  );
  structType->symbol->defPoint->parentStmt->insertBefore(def_stmt);
}

static void build_record_inequality_function(StructuralType* structType) {
  if (dynamic_cast<ClassType*>(structType)) {
    return;
  }

  FnSymbol* fn = Symboltable::startFnDef(new FnSymbol("!="));

  ParamSymbol* arg1 = new ParamSymbol(PARAM_BLANK, "_arg1", structType);
  ParamSymbol* arg2 = new ParamSymbol(PARAM_BLANK, "_arg2", structType);
  arg1->append(arg2);
  Symboltable::continueFnDef(fn, arg1, dtBoolean);
  Expr* cond = NULL;
  forv_Vec(VarSymbol, tmp, structType->fields) {
    Expr* left = new MemberAccess(new Variable(arg1), tmp);
    Expr* right = new MemberAccess(new Variable(arg2), tmp);
    cond = (cond)
      ? new BinOp(BINOP_LOGOR, cond, new BinOp(BINOP_NEQUAL, left, right))
      : new BinOp(BINOP_NEQUAL, left, right);
  }
  Stmt* retStmt = new ReturnStmt(cond);
  DefStmt* def_stmt = new DefStmt(new DefExpr(Symboltable::finishFnDef(fn,
                                                                       retStmt))
                                  );
  structType->symbol->defPoint->parentStmt->insertBefore(def_stmt);
}

static void build_record_assignment_function(StructuralType* structType) {
  if (dynamic_cast<ClassType*>(structType)) {
    return;
  }

  FnSymbol* fn = Symboltable::startFnDef(new FnSymbol("="));
  ParamSymbol* arg1 = new ParamSymbol(PARAM_BLANK, "_arg1", structType);
  ParamSymbol* arg2 = new ParamSymbol(PARAM_BLANK, "_arg2",
    (analyzeAST) ? dtUnknown : structType);
  arg1->append(arg2);
  Type *ret_type = analyzeAST ? dtUnknown : dtVoid;
  Symboltable::continueFnDef(fn, arg1, ret_type);
  Stmt* body = NULL;
  Symboltable::pushScope(SCOPE_LOCAL);
  forv_Vec(VarSymbol, tmp, structType->fields) {
    Expr* left = new MemberAccess(new Variable(arg1), tmp);
    Expr* right = new MemberAccess(new Variable(arg2), tmp);
    Expr* assign_expr = new AssignOp(GETS_NORM, left, right);
    body = appendLink(body, new ExprStmt(assign_expr));
  }

  if (analyzeAST)
    body = appendLink(body, new ReturnStmt(new Variable(arg2)));
  BlockStmt* block_stmt = new BlockStmt(body, Symboltable::popScope());
  DefStmt* defStmt = new DefStmt(new DefExpr(Symboltable::finishFnDef(fn,
                                                                      block_stmt
                                                                      )));
  structType->symbol->defPoint->parentStmt->insertBefore(defStmt);
}

void buildDefaultStructuralTypeMethods(StructuralType* structuralType) {
  SymScope* newScope =
    structuralType->structScope->findEnclosingScopeLessType(SCOPE_MODULE);
  SymScope* saveScope =
    Symboltable::setCurrentScope(newScope);
  build_setters_and_getters(structuralType);
  build_union_id_enum(structuralType);
  build_constructor(structuralType);
  build_record_equality_function(structuralType);
  build_record_inequality_function(structuralType);
  build_record_assignment_function(structuralType);
  Symboltable::setCurrentScope(saveScope);
}

void BuildClassConstructorsEtc::postProcessExpr(Expr* expr) {
  if (DefExpr* defExpr = dynamic_cast<DefExpr*>(expr)) {
    if (TypeSymbol* sym = dynamic_cast<TypeSymbol*>(defExpr->sym)) {
      if (StructuralType* type = dynamic_cast<StructuralType*>(sym->type)) {
        if (type->defaultConstructor) { /*** already done ***/
          return;
        }
        buildDefaultStructuralTypeMethods(type);
      }
    }
  }
}
<|endoftext|>


<commit_before> /*
  *   jabberprotocol.cpp  -  Base class for the Kopete Jabber protocol
  *
  * Copyright (c) 2002-2003 by Till Gerken <till@tantalo.net>
  * Copyright (c) 2002 by Daniel Stone <dstone@kde.org>
  *
  *  Kopete   (c) by the Kopete developers  <kopete-devel@kde.org>
  *
  * *************************************************************************
  * *                                                                       *
  * * This program is free software; you can redistribute it and/or modify  *
  * * it under the terms of the GNU General Public License as published by  *
  * * the Free Software Foundation; either version 2 of the License, or     *
  * * (at your option) any later version.                                   *
  * *                                                                       *
  * *************************************************************************
  */

#include <kdebug.h>
#include <kgenericfactory.h>
#include <kconfig.h>
#include <kmessagebox.h>
#include <kiconloader.h>
#include <kpopupmenu.h>
#include <kstandarddirs.h>
#include <klineeditdlg.h>

#include <qapplication.h>
#include <qcursor.h>
#include <qmap.h>
#include <qtimer.h>
#include <qpixmap.h>
#include <qstringlist.h>

#include "im.h"
#include "xmpp.h"

#include <sys/utsname.h>

#include "kopetecontact.h"
#include "kopetecontactlist.h"
#include "kopetemetacontact.h"
#include "kopetemessagemanager.h"
#include "kopeteaway.h"
#include "kopeteglobal.h"
#include "kopeteprotocol.h"
#include "kopeteplugin.h"
#include "addcontactpage.h"
#include "jabbercontact.h"
#include "dlgjabbersendraw.h"
#include "dlgjabberservices.h"
#include "dlgjabberchatjoin.h"
#include "jabberaddcontactpage.h"
#include "jabberprotocol.h"
#include "jabberaccount.h"
#include "kopeteaccountmanager.h"
#include "jabbereditaccountwidget.h"
#include "kopetecommandhandler.h"

JabberProtocol *JabberProtocol::protocolInstance = 0;

typedef KGenericFactory<JabberProtocol> JabberProtocolFactory;

K_EXPORT_COMPONENT_FACTORY( kopete_jabber, JabberProtocolFactory( "kopete_jabber" )  )

JabberProtocol::JabberProtocol (QObject * parent, const char *name, const QStringList &)
: KopeteProtocol( JabberProtocolFactory::instance(), parent, name ),
	JabberKOSChatty(KopeteOnlineStatus::Online,        100, this, 1, "jabber_chatty",     i18n ("Set F&ree to Chat"), i18n ("Free to Chat")),
	JabberKOSOnline(KopeteOnlineStatus::Online,         90, this, 0, QString::null,       i18n ("Go O&nline"), i18n ("Online")),
	JabberKOSAway(KopeteOnlineStatus::Away,             80, this, 2, "jabber_away",       i18n ("Set A&way"), i18n ("Away")),
	JabberKOSXA(KopeteOnlineStatus::Away,               70, this, 3, "jabber_away",       i18n ("Set E&xtended Away"), i18n ("Extended Away")),
	JabberKOSDND(KopeteOnlineStatus::Away,              60, this, 4, "jabber_na",         i18n ("Set &Do not Disturb"), i18n ("Do not Disturb")),
	JabberKOSOffline(KopeteOnlineStatus::Offline,       50, this, 5, QString::null,       i18n ("Go O&ffline"), i18n ("Offline")),
	JabberKOSInvisible(KopeteOnlineStatus::Invisible,   40, this, 6, "jabber_invisible",  i18n ("Set I&nvisible"), i18n ("Invisible")),
	JabberKOSConnecting(KopeteOnlineStatus::Connecting, 30, this, 7, "jabber_connecting", i18n ("FIXME: You should not see this"), i18n("Connecting")),
	propAwayMessage(Kopete::Global::Properties::self()->awayMessage()),
	propFirstName(Kopete::Global::Properties::self()->firstName()),
	propLastName(Kopete::Global::Properties::self()->lastName()),
	propFullName(Kopete::Global::Properties::self()->fullName()),
	propEmailAddress(Kopete::Global::Properties::self()->emailAddress()),
	propPrivatePhone(Kopete::Global::Properties::self()->privatePhone()),
	propPrivateMobilePhone(Kopete::Global::Properties::self()->privateMobilePhone()),
	propWorkPhone(Kopete::Global::Properties::self()->workPhone()),
	propWorkMobilePhone(Kopete::Global::Properties::self()->workMobilePhone()),
	propNickName(Kopete::Global::Properties::self()->nickName()),
	propSubscriptionStatus("jabberSubscriptionStatus", i18n ("Subscription"), QString::null, true, false),
	propAuthorizationStatus("jabberAuthorizationStatus", i18n ("Authorization Status"), QString::null, true, false),
	propAvailableResources("jabberAvailableResources", i18n ("Available Resources"), "jabber_chatty", false, true),
	propVCardCacheTimeStamp("jabberVCardCacheTimeStamp", i18n ("vCard Cache Timestamp"), QString::null, true, false, true)

{

	kdDebug (JABBER_DEBUG_GLOBAL) << "[JabberProtocol] Loading ..." << endl;

	/* This is meant to be a singleton, so we will check if we have
	 * been loaded before. */
	if (protocolInstance)
	{
		kdDebug (JABBER_DEBUG_GLOBAL) << "[JabberProtocol] Warning: Protocol already " << "loaded, not initializing again." << endl;
		return;
	}

	protocolInstance = this;

	addAddressBookField ("messaging/xmpp", KopetePlugin::MakeIndexField);
}

JabberProtocol::~JabberProtocol ()
{
	//disconnectAll();

	/* make sure that the next attempt to load Jabber
	 * re-initializes the protocol class. */
	protocolInstance = 0L;
}

AddContactPage *JabberProtocol::createAddContactWidget (QWidget * parent, KopeteAccount * i)
{
	kdDebug (JABBER_DEBUG_GLOBAL) << "[Jabber Protocol] Create Add Contact  Widget\n" << endl;
	return new JabberAddContactPage (i, parent);
}

KopeteEditAccountWidget *JabberProtocol::createEditAccountWidget (KopeteAccount * account, QWidget * parent)
{
	kdDebug (JABBER_DEBUG_GLOBAL) << "[Jabber Protocol] Edit Account Widget\n" << endl;
	return new JabberEditAccountWidget (this, static_cast < JabberAccount * >(account), parent);
}

KopeteAccount *JabberProtocol::createNewAccount (const QString & accountId)
{
	kdDebug (JABBER_DEBUG_GLOBAL) << "[Jabber Protocol] Create New Account. ID: " << accountId << "\n" << endl;
	return new JabberAccount (this, accountId);
}

KopeteOnlineStatus JabberProtocol::resourceToKOS ( const XMPP::Resource &resource )
{

	// update to offline by default
	KopeteOnlineStatus status = JabberKOSOffline;

	if ( !resource.status().isAvailable () )
	{
		// resource is offline
		status = JabberKOSOffline;
	}
	else
	{
		if (resource.status ().show () == "")
		{
			if (resource.status ().isInvisible ())
			{
				status = JabberKOSInvisible;
			}
			else
			{
				status = JabberKOSOnline;
			}
		}
		else
		if (resource.status ().show () == "chat")
		{
			status = JabberKOSChatty;
		}
		else if (resource.status ().show () == "away")
		{
			status = JabberKOSAway;
		}
		else if (resource.status ().show () == "xa")
		{
			status = JabberKOSXA;
		}
		else if (resource.status ().show () == "dnd")
		{
			status = JabberKOSDND;
		}
		else if (resource.status ().show () == "connecting")
		{
			status = JabberKOSConnecting;
		}
	}

	return status;

}

JabberProtocol *JabberProtocol::protocol ()
{
	// return current instance
	return protocolInstance;
}

KopeteContact *JabberProtocol::deserializeContact (KopeteMetaContact * metaContact,
										 const QMap < QString, QString > &serializedData, const QMap < QString, QString > & /* addressBookData */ )
{
//  kdDebug (JABBER_DEBUG_GLOBAL) << k_funcinfo << "Deserializing data for metacontact " << metaContact->displayName () << "\n" << endl;

	QString contactId = serializedData["contactId"];
	QString displayName = serializedData["displayName"];
	QString accountId = serializedData["accountId"];

	QDict < KopeteAccount > accounts = KopeteAccountManager::manager ()->accounts (this);
	KopeteAccount *account = accounts[accountId];

	if (!account)
	{
		kdDebug(JABBER_DEBUG_GLOBAL) << k_funcinfo << "WARNING: Account for contact does not exist, skipping." << endl;
		return 0;
	}

	if (account)
		account->addContact (contactId, displayName, metaContact);
	return account->contacts()[contactId];
}

#include "jabberprotocol.moc"
<commit_msg>Show XA as XA, not away<commit_after> /*
  *   jabberprotocol.cpp  -  Base class for the Kopete Jabber protocol
  *
  * Copyright (c) 2002-2003 by Till Gerken <till@tantalo.net>
  * Copyright (c) 2002 by Daniel Stone <dstone@kde.org>
  *
  *  Kopete   (c) by the Kopete developers  <kopete-devel@kde.org>
  *
  * *************************************************************************
  * *                                                                       *
  * * This program is free software; you can redistribute it and/or modify  *
  * * it under the terms of the GNU General Public License as published by  *
  * * the Free Software Foundation; either version 2 of the License, or     *
  * * (at your option) any later version.                                   *
  * *                                                                       *
  * *************************************************************************
  */

#include <kdebug.h>
#include <kgenericfactory.h>
#include <kconfig.h>
#include <kmessagebox.h>
#include <kiconloader.h>
#include <kpopupmenu.h>
#include <kstandarddirs.h>
#include <klineeditdlg.h>

#include <qapplication.h>
#include <qcursor.h>
#include <qmap.h>
#include <qtimer.h>
#include <qpixmap.h>
#include <qstringlist.h>

#include "im.h"
#include "xmpp.h"

#include <sys/utsname.h>

#include "kopetecontact.h"
#include "kopetecontactlist.h"
#include "kopetemetacontact.h"
#include "kopetemessagemanager.h"
#include "kopeteaway.h"
#include "kopeteglobal.h"
#include "kopeteprotocol.h"
#include "kopeteplugin.h"
#include "addcontactpage.h"
#include "jabbercontact.h"
#include "dlgjabbersendraw.h"
#include "dlgjabberservices.h"
#include "dlgjabberchatjoin.h"
#include "jabberaddcontactpage.h"
#include "jabberprotocol.h"
#include "jabberaccount.h"
#include "kopeteaccountmanager.h"
#include "jabbereditaccountwidget.h"
#include "kopetecommandhandler.h"

JabberProtocol *JabberProtocol::protocolInstance = 0;

typedef KGenericFactory<JabberProtocol> JabberProtocolFactory;

K_EXPORT_COMPONENT_FACTORY( kopete_jabber, JabberProtocolFactory( "kopete_jabber" )  )

JabberProtocol::JabberProtocol (QObject * parent, const char *name, const QStringList &)
: KopeteProtocol( JabberProtocolFactory::instance(), parent, name ),
	JabberKOSChatty(KopeteOnlineStatus::Online,        100, this, 1, "jabber_chatty",     i18n ("Set F&ree to Chat"), i18n ("Free to Chat")),
	JabberKOSOnline(KopeteOnlineStatus::Online,         90, this, 0, QString::null,       i18n ("Go O&nline"), i18n ("Online")),
	JabberKOSAway(KopeteOnlineStatus::Away,             80, this, 2, "jabber_away",       i18n ("Set A&way"), i18n ("Away")),
	JabberKOSXA(KopeteOnlineStatus::Away,               70, this, 3, "jabber_xa",       i18n ("Set E&xtended Away"), i18n ("Extended Away")),
	JabberKOSDND(KopeteOnlineStatus::Away,              60, this, 4, "jabber_na",         i18n ("Set &Do not Disturb"), i18n ("Do not Disturb")),
	JabberKOSOffline(KopeteOnlineStatus::Offline,       50, this, 5, QString::null,       i18n ("Go O&ffline"), i18n ("Offline")),
	JabberKOSInvisible(KopeteOnlineStatus::Invisible,   40, this, 6, "jabber_invisible",  i18n ("Set I&nvisible"), i18n ("Invisible")),
	JabberKOSConnecting(KopeteOnlineStatus::Connecting, 30, this, 7, "jabber_connecting", i18n ("FIXME: You should not see this"), i18n("Connecting")),
	propAwayMessage(Kopete::Global::Properties::self()->awayMessage()),
	propFirstName(Kopete::Global::Properties::self()->firstName()),
	propLastName(Kopete::Global::Properties::self()->lastName()),
	propFullName(Kopete::Global::Properties::self()->fullName()),
	propEmailAddress(Kopete::Global::Properties::self()->emailAddress()),
	propPrivatePhone(Kopete::Global::Properties::self()->privatePhone()),
	propPrivateMobilePhone(Kopete::Global::Properties::self()->privateMobilePhone()),
	propWorkPhone(Kopete::Global::Properties::self()->workPhone()),
	propWorkMobilePhone(Kopete::Global::Properties::self()->workMobilePhone()),
	propNickName(Kopete::Global::Properties::self()->nickName()),
	propSubscriptionStatus("jabberSubscriptionStatus", i18n ("Subscription"), QString::null, true, false),
	propAuthorizationStatus("jabberAuthorizationStatus", i18n ("Authorization Status"), QString::null, true, false),
	propAvailableResources("jabberAvailableResources", i18n ("Available Resources"), "jabber_chatty", false, true),
	propVCardCacheTimeStamp("jabberVCardCacheTimeStamp", i18n ("vCard Cache Timestamp"), QString::null, true, false, true)

{

	kdDebug (JABBER_DEBUG_GLOBAL) << "[JabberProtocol] Loading ..." << endl;

	/* This is meant to be a singleton, so we will check if we have
	 * been loaded before. */
	if (protocolInstance)
	{
		kdDebug (JABBER_DEBUG_GLOBAL) << "[JabberProtocol] Warning: Protocol already " << "loaded, not initializing again." << endl;
		return;
	}

	protocolInstance = this;

	addAddressBookField ("messaging/xmpp", KopetePlugin::MakeIndexField);
}

JabberProtocol::~JabberProtocol ()
{
	//disconnectAll();

	/* make sure that the next attempt to load Jabber
	 * re-initializes the protocol class. */
	protocolInstance = 0L;
}

AddContactPage *JabberProtocol::createAddContactWidget (QWidget * parent, KopeteAccount * i)
{
	kdDebug (JABBER_DEBUG_GLOBAL) << "[Jabber Protocol] Create Add Contact  Widget\n" << endl;
	return new JabberAddContactPage (i, parent);
}

KopeteEditAccountWidget *JabberProtocol::createEditAccountWidget (KopeteAccount * account, QWidget * parent)
{
	kdDebug (JABBER_DEBUG_GLOBAL) << "[Jabber Protocol] Edit Account Widget\n" << endl;
	return new JabberEditAccountWidget (this, static_cast < JabberAccount * >(account), parent);
}

KopeteAccount *JabberProtocol::createNewAccount (const QString & accountId)
{
	kdDebug (JABBER_DEBUG_GLOBAL) << "[Jabber Protocol] Create New Account. ID: " << accountId << "\n" << endl;
	return new JabberAccount (this, accountId);
}

KopeteOnlineStatus JabberProtocol::resourceToKOS ( const XMPP::Resource &resource )
{

	// update to offline by default
	KopeteOnlineStatus status = JabberKOSOffline;

	if ( !resource.status().isAvailable () )
	{
		// resource is offline
		status = JabberKOSOffline;
	}
	else
	{
		if (resource.status ().show () == "")
		{
			if (resource.status ().isInvisible ())
			{
				status = JabberKOSInvisible;
			}
			else
			{
				status = JabberKOSOnline;
			}
		}
		else
		if (resource.status ().show () == "chat")
		{
			status = JabberKOSChatty;
		}
		else if (resource.status ().show () == "away")
		{
			status = JabberKOSAway;
		}
		else if (resource.status ().show () == "xa")
		{
			status = JabberKOSXA;
		}
		else if (resource.status ().show () == "dnd")
		{
			status = JabberKOSDND;
		}
		else if (resource.status ().show () == "connecting")
		{
			status = JabberKOSConnecting;
		}
	}

	return status;

}

JabberProtocol *JabberProtocol::protocol ()
{
	// return current instance
	return protocolInstance;
}

KopeteContact *JabberProtocol::deserializeContact (KopeteMetaContact * metaContact,
										 const QMap < QString, QString > &serializedData, const QMap < QString, QString > & /* addressBookData */ )
{
//  kdDebug (JABBER_DEBUG_GLOBAL) << k_funcinfo << "Deserializing data for metacontact " << metaContact->displayName () << "\n" << endl;

	QString contactId = serializedData["contactId"];
	QString displayName = serializedData["displayName"];
	QString accountId = serializedData["accountId"];

	QDict < KopeteAccount > accounts = KopeteAccountManager::manager ()->accounts (this);
	KopeteAccount *account = accounts[accountId];

	if (!account)
	{
		kdDebug(JABBER_DEBUG_GLOBAL) << k_funcinfo << "WARNING: Account for contact does not exist, skipping." << endl;
		return 0;
	}

	if (account)
		account->addContact (contactId, displayName, metaContact);
	return account->contacts()[contactId];
}

#include "jabberprotocol.moc"
<|endoftext|>


<commit_before>#include "traditional_algorithm.h"
using namespace std;
Circuit TraditionalAlgorithm::search() {
  queue<Circuit> Q;
  // remove "first" element
  Q.push(root);
  while (Q.empty() == false) {
    Circuit current = Q.front();
    Q.pop();
    // checks single correct output
    if (isCorrectCircuit(current)) {
      return current;
    }
    for (Circuit circuit_to_check : allPossibleCircuits(current)) {
      Q.push(circuit_to_check);
    }
  }
}
}

vector<Circuit> TraditionalAlgorithm::allPossibleCircuits(Circuit c) {
  vector<Circuit> all_possibilities;
  int output_gate_offset = getGateCount() - getOutputCount();
  for (int i = 0; i < c.getOutputCount(); ++i) {
    // try a NOT
    Circuit added_not = c;
    added_not.addGate(NOT,
                      output_gate_offset + i);  // needs to add to the end...
    all_possibilities.push_back(added_not);
    // on odd nums, use binary gates, always can try a unary
    if (i % 2 == 1) {
      // try AND
      Circuit added_and = c;
      added_and.addGate(AND, output_gate_offset + i - 1,
                        output_gate_offset + i);  // needs to add to the end...
      all_possibilities.push_back(added_and);
      // try OR
      Circuit added_or = c;
      added_or.addGate(OR, output_gate_offset + i - 1,
                       output_gate_offset + i);  // needs to add to the end...
      all_possibilities.push_back(added_or);
    }
  }
  return all_possibilities;
}

bool TraditionalAlgorithm::isCorrectCircuit(Circuit c) {
  if (c.evaluateAllInputs() == expected_output)
    return true;
  else
    return false;
}

/* bool checkPermutation(){ //check if one of the outputs matches one of the
 * expected... */
/*   return true; */
/* } */
/* bool keepPermutation(){ */

/*   return true; */
/* } */
<commit_msg>fix hanging bracket<commit_after>#include "traditional_algorithm.h"
using namespace std;
Circuit TraditionalAlgorithm::search() {
  queue<Circuit> Q;
  // remove "first" element
  Q.push(root);
  while (Q.empty() == false) {
    Circuit current = Q.front();
    Q.pop();
    // checks single correct output
    if (isCorrectCircuit(current)) {
      return current;
    }
    for (Circuit circuit_to_check : allPossibleCircuits(current)) {
      Q.push(circuit_to_check);
    }
  }
}

vector<Circuit> TraditionalAlgorithm::allPossibleCircuits(Circuit c) {
  vector<Circuit> all_possibilities;
  int output_gate_offset = getGateCount() - getOutputCount();
  for (int i = 0; i < c.getOutputCount(); ++i) {
    // try a NOT
    Circuit added_not = c;
    added_not.addGate(NOT,
                      output_gate_offset + i);  // needs to add to the end...
    all_possibilities.push_back(added_not);
    // on odd nums, use binary gates, always can try a unary
    if (i % 2 == 1) {
      // try AND
      Circuit added_and = c;
      added_and.addGate(AND, output_gate_offset + i - 1,
                        output_gate_offset + i);  // needs to add to the end...
      all_possibilities.push_back(added_and);
      // try OR
      Circuit added_or = c;
      added_or.addGate(OR, output_gate_offset + i - 1,
                       output_gate_offset + i);  // needs to add to the end...
      all_possibilities.push_back(added_or);
    }
  }
  return all_possibilities;
}

bool TraditionalAlgorithm::isCorrectCircuit(Circuit c) {
  if (c.evaluateAllInputs() == expected_output)
    return true;
  else
    return false;
}

/* bool checkPermutation(){ //check if one of the outputs matches one of the
 * expected... */
/*   return true; */
/* } */
/* bool keepPermutation(){ */

/*   return true; */
/* } */
<|endoftext|>


<commit_before>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "media/filters/ffmpeg_audio_decoder.h"

#include "media/base/callback.h"
#include "media/base/data_buffer.h"
#include "media/base/limits.h"
#include "media/ffmpeg/ffmpeg_common.h"
#include "media/filters/ffmpeg_demuxer.h"

namespace media {

// Size of the decoded audio buffer.
const size_t FFmpegAudioDecoder::kOutputBufferSize =
    AVCODEC_MAX_AUDIO_FRAME_SIZE;

FFmpegAudioDecoder::FFmpegAudioDecoder()
    : codec_context_(NULL) {
}

FFmpegAudioDecoder::~FFmpegAudioDecoder() {
}

// static
bool FFmpegAudioDecoder::IsMediaFormatSupported(const MediaFormat& format) {
  std::string mime_type;
  return format.GetAsString(MediaFormat::kMimeType, &mime_type) &&
      mime_type::kFFmpegAudio == mime_type;
}

void FFmpegAudioDecoder::DoInitialize(DemuxerStream* demuxer_stream,
                                      bool* success,
                                      Task* done_cb) {
  AutoTaskRunner done_runner(done_cb);
  *success = false;

  // Get the AVStream by querying for the provider interface.
  AVStreamProvider* av_stream_provider;
  if (!demuxer_stream->QueryInterface(&av_stream_provider)) {
    return;
  }
  AVStream* av_stream = av_stream_provider->GetAVStream();

  // Grab the AVStream's codec context and make sure we have sensible values.
  codec_context_ = av_stream->codec;
  int bps = av_get_bits_per_sample_format(codec_context_->sample_fmt);
  DCHECK_GT(codec_context_->channels, 0);
  DCHECK_GT(bps, 0);
  DCHECK_GT(codec_context_->sample_rate, 0);
  if (codec_context_->channels == 0 ||
      static_cast<size_t>(codec_context_->channels) > Limits::kMaxChannels ||
      bps == 0 ||
      static_cast<size_t>(bps) > Limits::kMaxBPS ||
      codec_context_->sample_rate == 0 ||
      (static_cast<size_t>(codec_context_->sample_rate) >
       Limits::kMaxSampleRate)) {
    return;
  }

  // Serialize calls to avcodec_open().
  AVCodec* codec = avcodec_find_decoder(codec_context_->codec_id);
  if (!codec || avcodec_open(codec_context_, codec) < 0) {
    return;
  }

  // When calling avcodec_find_decoder(), |codec_context_| might be altered by
  // the decoder to give more accurate values of the output format of the
  // decoder. So set the media format after a decoder is allocated.
  // TODO(hclam): Reuse the information provided by the demuxer for now, we may
  // need to wait until the first buffer is decoded to know the correct
  // information.
  media_format_.SetAsInteger(MediaFormat::kChannels, codec_context_->channels);
  media_format_.SetAsInteger(MediaFormat::kSampleBits,
      av_get_bits_per_sample_format(codec_context_->sample_fmt));
  media_format_.SetAsInteger(MediaFormat::kSampleRate,
      codec_context_->sample_rate);
  media_format_.SetAsString(MediaFormat::kMimeType,
      mime_type::kUncompressedAudio);

  // Prepare the output buffer.
  output_buffer_.reset(static_cast<uint8*>(av_malloc(kOutputBufferSize)));
  if (!output_buffer_.get()) {
    host()->SetError(PIPELINE_ERROR_OUT_OF_MEMORY);
    return;
  }
  *success = true;
}

void FFmpegAudioDecoder::DoSeek(base::TimeDelta time, Task* done_cb) {
  avcodec_flush_buffers(codec_context_);
  estimated_next_timestamp_ = StreamSample::kInvalidTimestamp;
  done_cb->Run();
  delete done_cb;
}

void FFmpegAudioDecoder::DoDecode(Buffer* input, Task* done_cb) {
  AutoTaskRunner done_runner(done_cb);

  // Due to FFmpeg API changes we no longer have const read-only pointers.
  AVPacket packet;
  av_init_packet(&packet);
  packet.data = const_cast<uint8*>(input->GetData());
  packet.size = input->GetDataSize();

  int16_t* output_buffer = reinterpret_cast<int16_t*>(output_buffer_.get());
  int output_buffer_size = kOutputBufferSize;
  int result = avcodec_decode_audio3(codec_context_,
                                     output_buffer,
                                     &output_buffer_size,
                                     &packet);

  // TODO(ajwong): Consider if kOutputBufferSize should just be an int instead
  // of a size_t.
  if (result < 0 ||
      output_buffer_size < 0 ||
      static_cast<size_t>(output_buffer_size) > kOutputBufferSize) {
    LOG(INFO) << "Error decoding an audio frame with timestamp: "
              << input->GetTimestamp().InMicroseconds() << " us"
              << " , duration: "
              << input->GetDuration().InMicroseconds() << " us"
              << " , packet size: "
              << input->GetDataSize() << " bytes";
    return;
  }

  // If we have decoded something, enqueue the result.
  if (output_buffer_size) {
    DataBuffer* result_buffer = new DataBuffer(output_buffer_size);
    result_buffer->SetDataSize(output_buffer_size);
    uint8* data = result_buffer->GetWritableData();
    memcpy(data, output_buffer, output_buffer_size);

    // Determine the duration if the demuxer couldn't figure it out, otherwise
    // copy it over.
    if (input->GetDuration().ToInternalValue() == 0) {
      result_buffer->SetDuration(CalculateDuration(output_buffer_size));
    } else {
      DCHECK(input->GetDuration() != StreamSample::kInvalidTimestamp);
      result_buffer->SetDuration(input->GetDuration());
    }

    // Use our estimate for the timestamp if |input| does not have one.
    // Otherwise, copy over the timestamp.
    if (input->GetTimestamp() == StreamSample::kInvalidTimestamp) {
      result_buffer->SetTimestamp(estimated_next_timestamp_);
    } else {
      result_buffer->SetTimestamp(input->GetTimestamp());
    }

    // Only use the timestamp of |result_buffer| to estimate the next timestamp
    // if it is valid (i.e. != StreamSample::kInvalidTimestamp).  Otherwise the
    // error will stack together and we will get a series of incorrect
    // timestamps.  In this case, this will maintain a series of zero
    // timestamps.
    if (result_buffer->GetTimestamp() != StreamSample::kInvalidTimestamp) {
      // Update our estimated timestamp for the next packet.
      estimated_next_timestamp_ = result_buffer->GetTimestamp() +
          result_buffer->GetDuration();
    }

    EnqueueResult(result_buffer);
    return;
  }

  // We can get a positive result but no decoded data.  This is ok because this
  // this can be a marker packet that only contains timestamp.  In this case we
  // save the timestamp for later use.
  if (result && !input->IsEndOfStream() &&
      input->GetTimestamp() != StreamSample::kInvalidTimestamp &&
      input->GetDuration() != StreamSample::kInvalidTimestamp) {
    estimated_next_timestamp_ = input->GetTimestamp() + input->GetDuration();
    return;
  }

  // Three conditions to meet to declare end of stream for this decoder:
  // 1. FFmpeg didn't read anything.
  // 2. FFmpeg didn't output anything.
  // 3. An end of stream buffer is received.
  if (result == 0 && output_buffer_size == 0 && input->IsEndOfStream()) {
    DataBuffer* result_buffer = new DataBuffer(0);
    result_buffer->SetTimestamp(input->GetTimestamp());
    result_buffer->SetDuration(input->GetDuration());
    EnqueueResult(result_buffer);
  }
}

base::TimeDelta FFmpegAudioDecoder::CalculateDuration(size_t size) {
  int64 denominator = codec_context_->channels *
      av_get_bits_per_sample_format(codec_context_->sample_fmt) / 8 *
      codec_context_->sample_rate;
  double microseconds = size /
      (denominator / static_cast<double>(base::Time::kMicrosecondsPerSecond));
  return base::TimeDelta::FromMicroseconds(static_cast<int64>(microseconds));
}

}  // namespace
<commit_msg>Clean up the audio timestamp and duration code.<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "media/filters/ffmpeg_audio_decoder.h"

#include "media/base/callback.h"
#include "media/base/data_buffer.h"
#include "media/base/limits.h"
#include "media/ffmpeg/ffmpeg_common.h"
#include "media/filters/ffmpeg_demuxer.h"

namespace media {

// Size of the decoded audio buffer.
const size_t FFmpegAudioDecoder::kOutputBufferSize =
    AVCODEC_MAX_AUDIO_FRAME_SIZE;

FFmpegAudioDecoder::FFmpegAudioDecoder()
    : codec_context_(NULL),
      estimated_next_timestamp_(StreamSample::kInvalidTimestamp) {
}

FFmpegAudioDecoder::~FFmpegAudioDecoder() {
}

// static
bool FFmpegAudioDecoder::IsMediaFormatSupported(const MediaFormat& format) {
  std::string mime_type;
  return format.GetAsString(MediaFormat::kMimeType, &mime_type) &&
      mime_type::kFFmpegAudio == mime_type;
}

void FFmpegAudioDecoder::DoInitialize(DemuxerStream* demuxer_stream,
                                      bool* success,
                                      Task* done_cb) {
  AutoTaskRunner done_runner(done_cb);
  *success = false;

  // Get the AVStream by querying for the provider interface.
  AVStreamProvider* av_stream_provider;
  if (!demuxer_stream->QueryInterface(&av_stream_provider)) {
    return;
  }
  AVStream* av_stream = av_stream_provider->GetAVStream();

  // Grab the AVStream's codec context and make sure we have sensible values.
  codec_context_ = av_stream->codec;
  int bps = av_get_bits_per_sample_format(codec_context_->sample_fmt);
  DCHECK_GT(codec_context_->channels, 0);
  DCHECK_GT(bps, 0);
  DCHECK_GT(codec_context_->sample_rate, 0);
  if (codec_context_->channels == 0 ||
      static_cast<size_t>(codec_context_->channels) > Limits::kMaxChannels ||
      bps == 0 ||
      static_cast<size_t>(bps) > Limits::kMaxBPS ||
      codec_context_->sample_rate == 0 ||
      (static_cast<size_t>(codec_context_->sample_rate) >
       Limits::kMaxSampleRate)) {
    return;
  }

  // Serialize calls to avcodec_open().
  AVCodec* codec = avcodec_find_decoder(codec_context_->codec_id);
  if (!codec || avcodec_open(codec_context_, codec) < 0) {
    return;
  }

  // When calling avcodec_find_decoder(), |codec_context_| might be altered by
  // the decoder to give more accurate values of the output format of the
  // decoder. So set the media format after a decoder is allocated.
  // TODO(hclam): Reuse the information provided by the demuxer for now, we may
  // need to wait until the first buffer is decoded to know the correct
  // information.
  media_format_.SetAsInteger(MediaFormat::kChannels, codec_context_->channels);
  media_format_.SetAsInteger(MediaFormat::kSampleBits,
      av_get_bits_per_sample_format(codec_context_->sample_fmt));
  media_format_.SetAsInteger(MediaFormat::kSampleRate,
      codec_context_->sample_rate);
  media_format_.SetAsString(MediaFormat::kMimeType,
      mime_type::kUncompressedAudio);

  // Prepare the output buffer.
  output_buffer_.reset(static_cast<uint8*>(av_malloc(kOutputBufferSize)));
  if (!output_buffer_.get()) {
    host()->SetError(PIPELINE_ERROR_OUT_OF_MEMORY);
    return;
  }
  *success = true;
}

void FFmpegAudioDecoder::DoSeek(base::TimeDelta time, Task* done_cb) {
  avcodec_flush_buffers(codec_context_);
  estimated_next_timestamp_ = StreamSample::kInvalidTimestamp;
  done_cb->Run();
  delete done_cb;
}

void FFmpegAudioDecoder::DoDecode(Buffer* input, Task* done_cb) {
  AutoTaskRunner done_runner(done_cb);

  // Due to FFmpeg API changes we no longer have const read-only pointers.
  AVPacket packet;
  av_init_packet(&packet);
  packet.data = const_cast<uint8*>(input->GetData());
  packet.size = input->GetDataSize();

  int16_t* output_buffer = reinterpret_cast<int16_t*>(output_buffer_.get());
  int output_buffer_size = kOutputBufferSize;
  int result = avcodec_decode_audio3(codec_context_,
                                     output_buffer,
                                     &output_buffer_size,
                                     &packet);

  // TODO(ajwong): Consider if kOutputBufferSize should just be an int instead
  // of a size_t.
  if (result < 0 ||
      output_buffer_size < 0 ||
      static_cast<size_t>(output_buffer_size) > kOutputBufferSize) {
    LOG(INFO) << "Error decoding an audio frame with timestamp: "
              << input->GetTimestamp().InMicroseconds() << " us"
              << " , duration: "
              << input->GetDuration().InMicroseconds() << " us"
              << " , packet size: "
              << input->GetDataSize() << " bytes";
    return;
  }

  // If we have decoded something, enqueue the result.
  if (output_buffer_size) {
    DataBuffer* result_buffer = new DataBuffer(output_buffer_size);
    result_buffer->SetDataSize(output_buffer_size);
    uint8* data = result_buffer->GetWritableData();
    memcpy(data, output_buffer, output_buffer_size);

    // We don't trust the demuxer, so always calculate the duration based on
    // the actual number of samples decoded.
    base::TimeDelta duration = CalculateDuration(output_buffer_size);
    result_buffer->SetDuration(duration);

    // Use an estimated timestamp unless the incoming buffer has a valid one.
    if (input->GetTimestamp() == StreamSample::kInvalidTimestamp) {
      result_buffer->SetTimestamp(estimated_next_timestamp_);

      // Keep the estimated timestamp invalid until we get an incoming buffer
      // with a valid timestamp.  This can happen during seeks, etc...
      if (estimated_next_timestamp_ != StreamSample::kInvalidTimestamp) {
        estimated_next_timestamp_ += duration;
      }
    } else {
      result_buffer->SetTimestamp(input->GetTimestamp());
      estimated_next_timestamp_ = input->GetTimestamp() + duration;
    }

    EnqueueResult(result_buffer);
    return;
  }

  // We can get a positive result but no decoded data.  This is ok because this
  // this can be a marker packet that only contains timestamp.  In this case we
  // save the timestamp for later use.
  if (result && !input->IsEndOfStream() &&
      input->GetTimestamp() != StreamSample::kInvalidTimestamp &&
      input->GetDuration() != StreamSample::kInvalidTimestamp) {
    estimated_next_timestamp_ = input->GetTimestamp() + input->GetDuration();
    return;
  }

  // Three conditions to meet to declare end of stream for this decoder:
  // 1. FFmpeg didn't read anything.
  // 2. FFmpeg didn't output anything.
  // 3. An end of stream buffer is received.
  if (result == 0 && output_buffer_size == 0 && input->IsEndOfStream()) {
    DataBuffer* result_buffer = new DataBuffer(0);
    result_buffer->SetTimestamp(input->GetTimestamp());
    result_buffer->SetDuration(input->GetDuration());
    EnqueueResult(result_buffer);
  }
}

base::TimeDelta FFmpegAudioDecoder::CalculateDuration(size_t size) {
  int64 denominator = codec_context_->channels *
      av_get_bits_per_sample_format(codec_context_->sample_fmt) / 8 *
      codec_context_->sample_rate;
  double microseconds = size /
      (denominator / static_cast<double>(base::Time::kMicrosecondsPerSecond));
  return base::TimeDelta::FromMicroseconds(static_cast<int64>(microseconds));
}

}  // namespace
<|endoftext|>


<commit_before>// Copyright (c) 2009 The Chromium Authors. All rights reserved.  Use of this
// source code is governed by a BSD-style license that can be found in the
// LICENSE file.

#include "media/base/data_buffer.h"
#include "media/filters/ffmpeg_audio_decoder.h"
#include "media/filters/ffmpeg_common.h"
#include "media/filters/ffmpeg_demuxer.h"

namespace media {

// Size of the decoded audio buffer.
const size_t FFmpegAudioDecoder::kOutputBufferSize =
    AVCODEC_MAX_AUDIO_FRAME_SIZE;

FFmpegAudioDecoder::FFmpegAudioDecoder()
    : codec_context_(NULL) {
}

FFmpegAudioDecoder::~FFmpegAudioDecoder() {
}

// static
bool FFmpegAudioDecoder::IsMediaFormatSupported(const MediaFormat& format) {
  std::string mime_type;
  return format.GetAsString(MediaFormat::kMimeType, &mime_type) &&
      mime_type::kFFmpegAudio == mime_type;
}

bool FFmpegAudioDecoder::OnInitialize(DemuxerStream* demuxer_stream) {
  // Get the AVStream by querying for the provider interface.
  AVStreamProvider* av_stream_provider;
  if (!demuxer_stream->QueryInterface(&av_stream_provider)) {
    return false;
  }
  AVStream* av_stream = av_stream_provider->GetAVStream();

  // Grab the AVStream's codec context and make sure we have sensible values.
  codec_context_ = av_stream->codec;
  DCHECK_GT(codec_context_->channels, 0);
  DCHECK_GT(av_get_bits_per_sample_format(codec_context_->sample_fmt), 0);
  DCHECK_GT(codec_context_->sample_rate, 0);

  // Serialize calls to avcodec_open().
  AVCodec* codec = avcodec_find_decoder(codec_context_->codec_id);
  {
    AutoLock auto_lock(FFmpegLock::get()->lock());
    if (!codec || avcodec_open(codec_context_, codec) < 0) {
      return false;
    }
  }

  // When calling avcodec_find_decoder(), |codec_context_| might be altered by
  // the decoder to give more accurate values of the output format of the
  // decoder. So set the media format after a decoder is allocated.
  // TODO(hclam): Reuse the information provided by the demuxer for now, we may
  // need to wait until the first buffer is decoded to know the correct
  // information.
  media_format_.SetAsInteger(MediaFormat::kChannels, codec_context_->channels);
  media_format_.SetAsInteger(MediaFormat::kSampleBits,
      av_get_bits_per_sample_format(codec_context_->sample_fmt));
  media_format_.SetAsInteger(MediaFormat::kSampleRate,
      codec_context_->sample_rate);
  media_format_.SetAsString(MediaFormat::kMimeType,
      mime_type::kUncompressedAudio);

  // Prepare the output buffer.
  output_buffer_.reset(static_cast<uint8*>(av_malloc(kOutputBufferSize)));
  if (!output_buffer_.get()) {
    host()->Error(PIPELINE_ERROR_OUT_OF_MEMORY);
    return false;
  }
  return true;
}

void FFmpegAudioDecoder::OnStop() {
}

void FFmpegAudioDecoder::OnDecode(Buffer* input) {
  // Check for discontinuous buffer. If we receive a discontinuous buffer here,
  // flush the internal buffer of FFmpeg.
  if (input->IsDiscontinuous()) {
    avcodec_flush_buffers(codec_context_);
  }

  // Due to FFmpeg API changes we no longer have const read-only pointers.
  AVPacket packet;
  av_init_packet(&packet);
  packet.data = const_cast<uint8*>(input->GetData());
  packet.size = input->GetDataSize();

  int16_t* output_buffer = reinterpret_cast<int16_t*>(output_buffer_.get());
  int output_buffer_size = kOutputBufferSize;
  int result = avcodec_decode_audio3(codec_context_,
                                     output_buffer,
                                     &output_buffer_size,
                                     &packet);

  // TODO(ajwong): Consider if kOutputBufferSize should just be an int instead
  // of a size_t.
  if (result < 0 ||
      output_buffer_size < 0 ||
      static_cast<size_t>(output_buffer_size) > kOutputBufferSize) {
    host()->Error(PIPELINE_ERROR_DECODE);
    return;
  }

  // If we have decoded something, enqueue the result.
  if (output_buffer_size) {
    DataBuffer* result_buffer = new DataBuffer(output_buffer_size);
    uint8* data = result_buffer->GetWritableData();
    memcpy(data, output_buffer, output_buffer_size);

    // Determine the duration if the demuxer couldn't figure it out, otherwise
    // copy it over.
    if (input->GetDuration().InMicroseconds() == 0) {
      result_buffer->SetDuration(CalculateDuration(output_buffer_size));
    } else {
      result_buffer->SetDuration(input->GetDuration());
    }

    // Copy over the timestamp.
    result_buffer->SetTimestamp(input->GetTimestamp());

    EnqueueResult(result_buffer);
    return;
  }

  // Three conditions to meet to declare end of stream for this decoder:
  // 1. FFmpeg didn't read anything.
  // 2. FFmpeg didn't output anything.
  // 3. An end of stream buffer is received.
  if (result == 0 && output_buffer_size == 0 && input->IsEndOfStream()) {
    DataBuffer* result_buffer = new DataBuffer(0);
    result_buffer->SetTimestamp(input->GetTimestamp());
    result_buffer->SetDuration(input->GetDuration());
    EnqueueResult(result_buffer);
  }
}

base::TimeDelta FFmpegAudioDecoder::CalculateDuration(size_t size) {
  int64 denominator = codec_context_->channels *
      av_get_bits_per_sample_format(codec_context_->sample_fmt) / 8 *
      codec_context_->sample_rate;
  double microseconds = size /
      (denominator / static_cast<double>(base::Time::kMicrosecondsPerSecond));
  return base::TimeDelta::FromMicroseconds(static_cast<int64>(microseconds));
}

}  // namespace
<commit_msg>Fixes bug in FFmpegAudioDecoder where we weren't setting the usable data size.<commit_after>// Copyright (c) 2009 The Chromium Authors. All rights reserved.  Use of this
// source code is governed by a BSD-style license that can be found in the
// LICENSE file.

#include "media/base/data_buffer.h"
#include "media/filters/ffmpeg_audio_decoder.h"
#include "media/filters/ffmpeg_common.h"
#include "media/filters/ffmpeg_demuxer.h"

namespace media {

// Size of the decoded audio buffer.
const size_t FFmpegAudioDecoder::kOutputBufferSize =
    AVCODEC_MAX_AUDIO_FRAME_SIZE;

FFmpegAudioDecoder::FFmpegAudioDecoder()
    : codec_context_(NULL) {
}

FFmpegAudioDecoder::~FFmpegAudioDecoder() {
}

// static
bool FFmpegAudioDecoder::IsMediaFormatSupported(const MediaFormat& format) {
  std::string mime_type;
  return format.GetAsString(MediaFormat::kMimeType, &mime_type) &&
      mime_type::kFFmpegAudio == mime_type;
}

bool FFmpegAudioDecoder::OnInitialize(DemuxerStream* demuxer_stream) {
  // Get the AVStream by querying for the provider interface.
  AVStreamProvider* av_stream_provider;
  if (!demuxer_stream->QueryInterface(&av_stream_provider)) {
    return false;
  }
  AVStream* av_stream = av_stream_provider->GetAVStream();

  // Grab the AVStream's codec context and make sure we have sensible values.
  codec_context_ = av_stream->codec;
  DCHECK_GT(codec_context_->channels, 0);
  DCHECK_GT(av_get_bits_per_sample_format(codec_context_->sample_fmt), 0);
  DCHECK_GT(codec_context_->sample_rate, 0);

  // Serialize calls to avcodec_open().
  AVCodec* codec = avcodec_find_decoder(codec_context_->codec_id);
  {
    AutoLock auto_lock(FFmpegLock::get()->lock());
    if (!codec || avcodec_open(codec_context_, codec) < 0) {
      return false;
    }
  }

  // When calling avcodec_find_decoder(), |codec_context_| might be altered by
  // the decoder to give more accurate values of the output format of the
  // decoder. So set the media format after a decoder is allocated.
  // TODO(hclam): Reuse the information provided by the demuxer for now, we may
  // need to wait until the first buffer is decoded to know the correct
  // information.
  media_format_.SetAsInteger(MediaFormat::kChannels, codec_context_->channels);
  media_format_.SetAsInteger(MediaFormat::kSampleBits,
      av_get_bits_per_sample_format(codec_context_->sample_fmt));
  media_format_.SetAsInteger(MediaFormat::kSampleRate,
      codec_context_->sample_rate);
  media_format_.SetAsString(MediaFormat::kMimeType,
      mime_type::kUncompressedAudio);

  // Prepare the output buffer.
  output_buffer_.reset(static_cast<uint8*>(av_malloc(kOutputBufferSize)));
  if (!output_buffer_.get()) {
    host()->Error(PIPELINE_ERROR_OUT_OF_MEMORY);
    return false;
  }
  return true;
}

void FFmpegAudioDecoder::OnStop() {
}

void FFmpegAudioDecoder::OnDecode(Buffer* input) {
  // Check for discontinuous buffer. If we receive a discontinuous buffer here,
  // flush the internal buffer of FFmpeg.
  if (input->IsDiscontinuous()) {
    avcodec_flush_buffers(codec_context_);
  }

  // Due to FFmpeg API changes we no longer have const read-only pointers.
  AVPacket packet;
  av_init_packet(&packet);
  packet.data = const_cast<uint8*>(input->GetData());
  packet.size = input->GetDataSize();

  int16_t* output_buffer = reinterpret_cast<int16_t*>(output_buffer_.get());
  int output_buffer_size = kOutputBufferSize;
  int result = avcodec_decode_audio3(codec_context_,
                                     output_buffer,
                                     &output_buffer_size,
                                     &packet);

  // TODO(ajwong): Consider if kOutputBufferSize should just be an int instead
  // of a size_t.
  if (result < 0 ||
      output_buffer_size < 0 ||
      static_cast<size_t>(output_buffer_size) > kOutputBufferSize) {
    host()->Error(PIPELINE_ERROR_DECODE);
    return;
  }

  // If we have decoded something, enqueue the result.
  if (output_buffer_size) {
    DataBuffer* result_buffer = new DataBuffer(output_buffer_size);
    result_buffer->SetDataSize(output_buffer_size);
    uint8* data = result_buffer->GetWritableData();
    memcpy(data, output_buffer, output_buffer_size);

    // Determine the duration if the demuxer couldn't figure it out, otherwise
    // copy it over.
    if (input->GetDuration().InMicroseconds() == 0) {
      result_buffer->SetDuration(CalculateDuration(output_buffer_size));
    } else {
      result_buffer->SetDuration(input->GetDuration());
    }

    // Copy over the timestamp.
    result_buffer->SetTimestamp(input->GetTimestamp());

    EnqueueResult(result_buffer);
    return;
  }

  // Three conditions to meet to declare end of stream for this decoder:
  // 1. FFmpeg didn't read anything.
  // 2. FFmpeg didn't output anything.
  // 3. An end of stream buffer is received.
  if (result == 0 && output_buffer_size == 0 && input->IsEndOfStream()) {
    DataBuffer* result_buffer = new DataBuffer(0);
    result_buffer->SetTimestamp(input->GetTimestamp());
    result_buffer->SetDuration(input->GetDuration());
    EnqueueResult(result_buffer);
  }
}

base::TimeDelta FFmpegAudioDecoder::CalculateDuration(size_t size) {
  int64 denominator = codec_context_->channels *
      av_get_bits_per_sample_format(codec_context_->sample_fmt) / 8 *
      codec_context_->sample_rate;
  double microseconds = size /
      (denominator / static_cast<double>(base::Time::kMicrosecondsPerSecond));
  return base::TimeDelta::FromMicroseconds(static_cast<int64>(microseconds));
}

}  // namespace
<|endoftext|>


<commit_before>#include <string>

#include "authoring/constraint_task_space_region.h"
#include "authoring/constraint_sequence.h"

using namespace std;
using namespace boost;
using namespace lcm;
using namespace urdf;
using namespace drc;
using namespace state;
using namespace affordance;
using namespace authoring;

Constraint_Sequence::
Constraint_Sequence( unsigned int numConstraints ) : _constraints( numConstraints ),
                                                      _q0() {

}

Constraint_Sequence::
~Constraint_Sequence() {

}

Constraint_Sequence::
Constraint_Sequence( const Constraint_Sequence& other ) : _constraints( other._constraints ),
                                                          _q0( other._q0 ) {

}

Constraint_Sequence&
Constraint_Sequence::
operator=( const Constraint_Sequence& other ) {
  _constraints = other._constraints;
  _q0 = other._q0;
  return (*this);
}

void
Constraint_Sequence::
from_xml( const string& filename ){
  xmlDoc * doc = NULL;
  doc = xmlReadFile( filename.c_str(), NULL, 0 );
  from_xml( xmlDocGetRootElement( doc ) );
  xmlFreeDoc( doc );
  return;
}

void
Constraint_Sequence::
from_xml( xmlNodePtr root ){
  for( vector< Constraint_Task_Space_Region >::iterator it = _constraints.begin(); it != _constraints.end(); it++ ){
    it->active() = false;
  }

  vector< Constraint_Task_Space_Region >::iterator it = _constraints.begin();
  if( root->type == XML_ELEMENT_NODE ){
    xmlNodePtr l1 = NULL;
    for( l1 = root->children; l1; l1 = l1->next ){
      if( l1->type == XML_ELEMENT_NODE ){
        if( xmlStrcmp( l1->name, ( const xmlChar* )( "constraint_task_space_region" ) ) == 0 ){
          cout << "found constraint task space region" << endl;
          it->from_xml( l1 );
          it++;
          if( it == _constraints.end() ){
            return;
          }
        }
      }
    }
  }
  return;
}

void
Constraint_Sequence::
to_xml( const string& filename )const{
  ofstream out;
  out.open( filename.c_str() );
  to_xml( out );
  out.close();
  return;
}

void
Constraint_Sequence::
to_xml( ofstream& out,
        unsigned int indent )const{
  out << string( indent, ' ' ) << "<constraint_sequence>" << endl;
  for( vector< Constraint_Task_Space_Region >::const_iterator it = _constraints.begin(); it != _constraints.end(); it++ ){
    if( it->active() ){
      it->to_xml( out, indent + 2 );
    }
  }
  out << string( indent, ' ' ) << "</constraint_sequence>" << endl;
  return;
}

void
Constraint_Sequence::
to_msg( action_sequence_t& msg,
        vector< AffordanceState >& affordanceCollection ){
  msg.utime = 0;
  msg.num_contact_goals = 0;
  msg.contact_goals.clear();
  msg.robot_name = "atlas";
  _q0.to_lcm( &msg.q0 );
  for( vector< Constraint_Task_Space_Region >::iterator it = _constraints.begin(); it != _constraints.end(); it++ ){
    cout << it->id() << ": " << it->active() << endl;
    if( it->active() ) {
      it->add_to_drc_action_sequence_t( msg, affordanceCollection );
    }
  }
  return;
}

void
Constraint_Sequence::
from_msg( const action_sequence_t& msg ){
  _q0.from_lcm( &msg.q0 );
  for( vector< Constraint_Task_Space_Region >::iterator it = _constraints.begin(); it != _constraints.end(); it++ ){
    it->active() = false;
    it->parents().clear();
  }
  cout << "found " << msg.num_contact_goals << " contact_goals" << endl;
  vector< Constraint_Task_Space_Region >::iterator it = _constraints.begin();
  for( unsigned int i = 0; i < msg.num_contact_goals/2; i++ ){
    it->active() = true;
    it->metadata() = "NA";
    it->start() = msg.contact_goals[2*i].lower_bound_completion_time;
    it->end() = msg.contact_goals[2*i].upper_bound_completion_time;
    it->relation_type() = CONSTRAINT_TASK_SPACE_REGION_AFFORDANCE_RELATION_TYPE;
    if( msg.contact_goals[2*i].contact_type == contact_goal_t::WITHIN_REGION ){
      it->contact_type() = CONSTRAINT_TASK_SPACE_REGION_WITHIN_REGION_CONTACT_TYPE;
    } else {
      it->contact_type() = CONSTRAINT_TASK_SPACE_REGION_SUPPORTED_WITHIN_REGION_CONTACT_TYPE;
    }
    it->ranges()[ CONSTRAINT_TASK_SPACE_REGION_X_MIN_RANGE ].first = ( msg.contact_goals[2*i].x_offset > -1000.0 );
    it->ranges()[ CONSTRAINT_TASK_SPACE_REGION_X_MAX_RANGE ].first = ( msg.contact_goals[2*i+1].x_offset < 1000.0 );
    it->ranges()[ CONSTRAINT_TASK_SPACE_REGION_Y_MIN_RANGE ].first = ( msg.contact_goals[2*i].y_offset > -1000.0 );
    it->ranges()[ CONSTRAINT_TASK_SPACE_REGION_Y_MAX_RANGE ].first = ( msg.contact_goals[2*i+1].y_offset < 1000.0 );
    it->ranges()[ CONSTRAINT_TASK_SPACE_REGION_Z_MIN_RANGE ].first = ( msg.contact_goals[2*i].z_offset > -1000.0 );
    it->ranges()[ CONSTRAINT_TASK_SPACE_REGION_Z_MAX_RANGE ].first = ( msg.contact_goals[2*i+1].z_offset < 1000.0 );
    it->ranges()[ CONSTRAINT_TASK_SPACE_REGION_X_MIN_RANGE ].second = msg.contact_goals[2*i].x_offset;
    it->ranges()[ CONSTRAINT_TASK_SPACE_REGION_X_MAX_RANGE ].second = msg.contact_goals[2*i+1].x_offset;
    it->ranges()[ CONSTRAINT_TASK_SPACE_REGION_Y_MIN_RANGE ].second = msg.contact_goals[2*i].y_offset;
    it->ranges()[ CONSTRAINT_TASK_SPACE_REGION_Y_MAX_RANGE ].second = msg.contact_goals[2*i+1].y_offset;
    it->ranges()[ CONSTRAINT_TASK_SPACE_REGION_Z_MIN_RANGE ].second = msg.contact_goals[2*i].z_offset;
    it->ranges()[ CONSTRAINT_TASK_SPACE_REGION_Z_MAX_RANGE ].second = msg.contact_goals[2*i+1].z_offset;
    it->parents().push_back( msg.contact_goals[2*i].object_1_name + "-" + msg.contact_goals[2*i].object_1_contact_grp );
    it->child() = ( msg.contact_goals[2*i].object_2_name + "/" + msg.contact_goals[2*i].object_2_contact_grp );
    it++;
  }

  return;
}

void
Constraint_Sequence::
print_msg( const action_sequence_t& msg ){
  cout << "utime:{" << msg.utime << "} ";
  cout << "robot_name:{" << msg.robot_name << "} ";
  cout << "contact_goals[" << msg.num_contact_goals << "]:{";
  for( vector< contact_goal_t >::const_iterator it = msg.contact_goals.begin(); it != msg.contact_goals.end(); it++ ){
    cout << "{(" << it->lower_bound_completion_time << "," << it->upper_bound_completion_time << "),";
    cout << "(" << it->object_1_name << "," << it->object_1_contact_grp << "),";
    cout << "(" << it->object_2_name << "," << it->object_2_contact_grp << "),";
    if( it->contact_type == contact_goal_t::WITHIN_REGION ){
      cout << "(WITHIN_REGION),";
    } else if ( it->contact_type == contact_goal_t::SUPPORTED_WITHIN_REGION ){
      cout << "(SUPPORTED_WITHIN_REGION),";
    } else {
      cout << "(UNKNOWN),";
    }
    if( it->x_relation == contact_goal_t::REL_EQUAL ){
      cout << "(x=" << it->x_offset << "),";
    } else if( it->x_relation == contact_goal_t::REL_LESS_THAN ){
      cout << "(x<" << it->x_offset << "),";
    } else if ( it->x_relation == contact_goal_t::REL_GREATER_THAN ){
      cout << "(x>" << it->x_offset << "),";
    }
    if( it->y_relation == contact_goal_t::REL_EQUAL ){
      cout << "(y=" << it->y_offset << "),";
    } else if( it->y_relation == contact_goal_t::REL_LESS_THAN ){
      cout << "(y<" << it->y_offset << "),";
    } else if ( it->y_relation == contact_goal_t::REL_GREATER_THAN ){
      cout << "(y>" << it->y_offset << "),";
    }
    if( it->z_relation == contact_goal_t::REL_EQUAL ){
      cout << "(z=" << it->z_offset << ")";
    } else if( it->z_relation == contact_goal_t::REL_LESS_THAN ){
      cout << "(z<" << it->z_offset << ")";
    } else if ( it->z_relation == contact_goal_t::REL_GREATER_THAN ){
      cout << "(z>" << it->z_offset << ")";
    }
    cout << "}";
  }
  cout << "}" << endl;
  return;
}

namespace authoring {
  ostream&
  operator<<( ostream& out,
              const Constraint_Sequence& other ) {
    return out;
  }

}
<commit_msg>Sets msg.q0.robot_name to match msg.robot_name in Constraint_Sequence::to_msg.<commit_after>#include <string>

#include "authoring/constraint_task_space_region.h"
#include "authoring/constraint_sequence.h"

using namespace std;
using namespace boost;
using namespace lcm;
using namespace urdf;
using namespace drc;
using namespace state;
using namespace affordance;
using namespace authoring;

Constraint_Sequence::
Constraint_Sequence( unsigned int numConstraints ) : _constraints( numConstraints ),
                                                      _q0() {

}

Constraint_Sequence::
~Constraint_Sequence() {

}

Constraint_Sequence::
Constraint_Sequence( const Constraint_Sequence& other ) : _constraints( other._constraints ),
                                                          _q0( other._q0 ) {

}

Constraint_Sequence&
Constraint_Sequence::
operator=( const Constraint_Sequence& other ) {
  _constraints = other._constraints;
  _q0 = other._q0;
  return (*this);
}

void
Constraint_Sequence::
from_xml( const string& filename ){
  xmlDoc * doc = NULL;
  doc = xmlReadFile( filename.c_str(), NULL, 0 );
  from_xml( xmlDocGetRootElement( doc ) );
  xmlFreeDoc( doc );
  return;
}

void
Constraint_Sequence::
from_xml( xmlNodePtr root ){
  for( vector< Constraint_Task_Space_Region >::iterator it = _constraints.begin(); it != _constraints.end(); it++ ){
    it->active() = false;
  }

  vector< Constraint_Task_Space_Region >::iterator it = _constraints.begin();
  if( root->type == XML_ELEMENT_NODE ){
    xmlNodePtr l1 = NULL;
    for( l1 = root->children; l1; l1 = l1->next ){
      if( l1->type == XML_ELEMENT_NODE ){
        if( xmlStrcmp( l1->name, ( const xmlChar* )( "constraint_task_space_region" ) ) == 0 ){
          cout << "found constraint task space region" << endl;
          it->from_xml( l1 );
          it++;
          if( it == _constraints.end() ){
            return;
          }
        }
      }
    }
  }
  return;
}

void
Constraint_Sequence::
to_xml( const string& filename )const{
  ofstream out;
  out.open( filename.c_str() );
  to_xml( out );
  out.close();
  return;
}

void
Constraint_Sequence::
to_xml( ofstream& out,
        unsigned int indent )const{
  out << string( indent, ' ' ) << "<constraint_sequence>" << endl;
  for( vector< Constraint_Task_Space_Region >::const_iterator it = _constraints.begin(); it != _constraints.end(); it++ ){
    if( it->active() ){
      it->to_xml( out, indent + 2 );
    }
  }
  out << string( indent, ' ' ) << "</constraint_sequence>" << endl;
  return;
}

void
Constraint_Sequence::
to_msg( action_sequence_t& msg,
        vector< AffordanceState >& affordanceCollection ){
  msg.utime = 0;
  msg.num_contact_goals = 0;
  msg.contact_goals.clear();
  msg.robot_name = "atlas";
  _q0.to_lcm( &msg.q0 );
  msg.q0.robot_name = msg.robot_name;
  for( vector< Constraint_Task_Space_Region >::iterator it = _constraints.begin(); it != _constraints.end(); it++ ){
    cout << it->id() << ": " << it->active() << endl;
    if( it->active() ) {
      it->add_to_drc_action_sequence_t( msg, affordanceCollection );
    }
  }
  return;
}

void
Constraint_Sequence::
from_msg( const action_sequence_t& msg ){
  _q0.from_lcm( &msg.q0 );
  for( vector< Constraint_Task_Space_Region >::iterator it = _constraints.begin(); it != _constraints.end(); it++ ){
    it->active() = false;
    it->parents().clear();
  }
  cout << "found " << msg.num_contact_goals << " contact_goals" << endl;
  vector< Constraint_Task_Space_Region >::iterator it = _constraints.begin();
  for( unsigned int i = 0; i < msg.num_contact_goals/2; i++ ){
    it->active() = true;
    it->metadata() = "NA";
    it->start() = msg.contact_goals[2*i].lower_bound_completion_time;
    it->end() = msg.contact_goals[2*i].upper_bound_completion_time;
    it->relation_type() = CONSTRAINT_TASK_SPACE_REGION_AFFORDANCE_RELATION_TYPE;
    if( msg.contact_goals[2*i].contact_type == contact_goal_t::WITHIN_REGION ){
      it->contact_type() = CONSTRAINT_TASK_SPACE_REGION_WITHIN_REGION_CONTACT_TYPE;
    } else {
      it->contact_type() = CONSTRAINT_TASK_SPACE_REGION_SUPPORTED_WITHIN_REGION_CONTACT_TYPE;
    }
    it->ranges()[ CONSTRAINT_TASK_SPACE_REGION_X_MIN_RANGE ].first = ( msg.contact_goals[2*i].x_offset > -1000.0 );
    it->ranges()[ CONSTRAINT_TASK_SPACE_REGION_X_MAX_RANGE ].first = ( msg.contact_goals[2*i+1].x_offset < 1000.0 );
    it->ranges()[ CONSTRAINT_TASK_SPACE_REGION_Y_MIN_RANGE ].first = ( msg.contact_goals[2*i].y_offset > -1000.0 );
    it->ranges()[ CONSTRAINT_TASK_SPACE_REGION_Y_MAX_RANGE ].first = ( msg.contact_goals[2*i+1].y_offset < 1000.0 );
    it->ranges()[ CONSTRAINT_TASK_SPACE_REGION_Z_MIN_RANGE ].first = ( msg.contact_goals[2*i].z_offset > -1000.0 );
    it->ranges()[ CONSTRAINT_TASK_SPACE_REGION_Z_MAX_RANGE ].first = ( msg.contact_goals[2*i+1].z_offset < 1000.0 );
    it->ranges()[ CONSTRAINT_TASK_SPACE_REGION_X_MIN_RANGE ].second = msg.contact_goals[2*i].x_offset;
    it->ranges()[ CONSTRAINT_TASK_SPACE_REGION_X_MAX_RANGE ].second = msg.contact_goals[2*i+1].x_offset;
    it->ranges()[ CONSTRAINT_TASK_SPACE_REGION_Y_MIN_RANGE ].second = msg.contact_goals[2*i].y_offset;
    it->ranges()[ CONSTRAINT_TASK_SPACE_REGION_Y_MAX_RANGE ].second = msg.contact_goals[2*i+1].y_offset;
    it->ranges()[ CONSTRAINT_TASK_SPACE_REGION_Z_MIN_RANGE ].second = msg.contact_goals[2*i].z_offset;
    it->ranges()[ CONSTRAINT_TASK_SPACE_REGION_Z_MAX_RANGE ].second = msg.contact_goals[2*i+1].z_offset;
    it->parents().push_back( msg.contact_goals[2*i].object_1_name + "-" + msg.contact_goals[2*i].object_1_contact_grp );
    it->child() = ( msg.contact_goals[2*i].object_2_name + "/" + msg.contact_goals[2*i].object_2_contact_grp );
    it++;
  }

  return;
}

void
Constraint_Sequence::
print_msg( const action_sequence_t& msg ){
  cout << "utime:{" << msg.utime << "} ";
  cout << "robot_name:{" << msg.robot_name << "} ";
  cout << "contact_goals[" << msg.num_contact_goals << "]:{";
  for( vector< contact_goal_t >::const_iterator it = msg.contact_goals.begin(); it != msg.contact_goals.end(); it++ ){
    cout << "{(" << it->lower_bound_completion_time << "," << it->upper_bound_completion_time << "),";
    cout << "(" << it->object_1_name << "," << it->object_1_contact_grp << "),";
    cout << "(" << it->object_2_name << "," << it->object_2_contact_grp << "),";
    if( it->contact_type == contact_goal_t::WITHIN_REGION ){
      cout << "(WITHIN_REGION),";
    } else if ( it->contact_type == contact_goal_t::SUPPORTED_WITHIN_REGION ){
      cout << "(SUPPORTED_WITHIN_REGION),";
    } else {
      cout << "(UNKNOWN),";
    }
    if( it->x_relation == contact_goal_t::REL_EQUAL ){
      cout << "(x=" << it->x_offset << "),";
    } else if( it->x_relation == contact_goal_t::REL_LESS_THAN ){
      cout << "(x<" << it->x_offset << "),";
    } else if ( it->x_relation == contact_goal_t::REL_GREATER_THAN ){
      cout << "(x>" << it->x_offset << "),";
    }
    if( it->y_relation == contact_goal_t::REL_EQUAL ){
      cout << "(y=" << it->y_offset << "),";
    } else if( it->y_relation == contact_goal_t::REL_LESS_THAN ){
      cout << "(y<" << it->y_offset << "),";
    } else if ( it->y_relation == contact_goal_t::REL_GREATER_THAN ){
      cout << "(y>" << it->y_offset << "),";
    }
    if( it->z_relation == contact_goal_t::REL_EQUAL ){
      cout << "(z=" << it->z_offset << ")";
    } else if( it->z_relation == contact_goal_t::REL_LESS_THAN ){
      cout << "(z<" << it->z_offset << ")";
    } else if ( it->z_relation == contact_goal_t::REL_GREATER_THAN ){
      cout << "(z>" << it->z_offset << ")";
    }
    cout << "}";
  }
  cout << "}" << endl;
  return;
}

namespace authoring {
  ostream&
  operator<<( ostream& out,
              const Constraint_Sequence& other ) {
    return out;
  }

}
<|endoftext|>