<commit_before>/******************************************************************************
*       SOFA, Simulation Open-Framework Architecture, version 1.0 RC 1        *
*                (c) 2006-2011 MGH, INRIA, USTL, UJF, CNRS                    *
*                                                                             *
* 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.          *
*******************************************************************************
*                               SOFA :: Modules                               *
*                                                                             *
* Authors: The SOFA Team and external contributors (see Authors.txt)          *
*                                                                             *
* Contact information: contact@sofa-framework.org                             *
******************************************************************************/
/*
 * OglShaderVisualModel.cpp
 *
 *  Created on: 9 févr. 2009
 *      Author: froy
 */

#include <sofa/component/visualmodel/OglShaderVisualModel.h>
#include <sofa/core/visual/VisualParams.h>
#include <sofa/core/ObjectFactory.h>

#include <sofa/core/topology/TopologyChange.h>
#include <sofa/component/topology/PointSetGeometryAlgorithms.h>
#include <sofa/simulation/common/Node.h>
#include <sofa/defaulttype/VecTypes.h>
#include <sofa/component/visualmodel/OglAttribute.inl>

namespace sofa
{

namespace component
{

namespace visualmodel
{

using namespace sofa::core::topology;
using namespace sofa::core::behavior;

SOFA_DECL_CLASS(OglShaderVisualModel)

int OglShaderVisualModelClass = core::RegisterObject("Visual model for OpenGL display using Glew extensions")
        .add< OglShaderVisualModel >()
        ;

OglShaderVisualModel::OglShaderVisualModel()
    : shader(NULL)
    , restPosition_lastUpdate(-1)
    , vrestpositions(NULL)
    , vrestnormals(NULL)
    , modelMatrixUniform(NULL)
{
}

OglShaderVisualModel::~OglShaderVisualModel()
{
}

void OglShaderVisualModel::pushTransformMatrix(float* matrix)
{
    OglModel::pushTransformMatrix(matrix);

    helper::vector<float> tempModelMatrixValue;

    for ( unsigned int i = 0; i < 16; i++ )
        tempModelMatrixValue.push_back(matrix[i]);
    if (modelMatrixUniform)
        modelMatrixUniform->setValue(tempModelMatrixValue);

    if (shader)
    {
        shader->stop();
        if (modelMatrixUniform)
            modelMatrixUniform->pushValue();
        shader->start();
    }
}

void OglShaderVisualModel::popTransformMatrix()
{
    OglModel::popTransformMatrix();
    /*
    	if (shader)
    		shader->stop();
    */
}

void OglShaderVisualModel::init()
{
    if (!shader)
        OglModel::init();

    sofa::core::objectmodel::BaseContext* context = this->getContext();
    shader = context->core::objectmodel::BaseContext::get<OglShader>();

    if( shader)
    {
        if (!vrestpositions)
            context->get(vrestpositions, "restPosition");
        if (!vrestnormals)
            context->get(vrestnormals, "restNormal");
        if (!modelMatrixUniform)
            context->get(modelMatrixUniform, "modelMatrix");
        //add restPosition as Attribute
        if (!vrestpositions)
        {
            vrestpositions = new OglFloat3Attribute;
            vrestpositions->setName("restPosition");
            this->getContext()->addObject(vrestpositions);
            vrestpositions->setID( std::string("restPosition"));
            vrestpositions->setIndexShader(0);
            vrestpositions->init();
        }

        if (!vrestnormals)
        {
            vrestnormals = new OglFloat3Attribute;
            vrestnormals->setName("restNormal");
            this->getContext()->addObject(vrestnormals);
            vrestnormals->setID( std::string("restNormal"));
            vrestnormals->setIndexShader(0);
            vrestnormals->init();
        }
        /*
            ResizableExtVector<Coord>& vrestpos = * ( vrestpositions.beginEdit() );
            const ResizableExtVector<Coord>& vertices = m_vertices.getValue();
            vrestpos.resize (vertices.size() );
            for ( unsigned int i = 0; i < vertices.size(); i++ )
            {
              vrestpos[i] = vertices[i];
            }
            vrestpositions.endEdit();

            //add restNormal as Attribute
            vrestnormals.setContext( this->getContext());
        	vrestnormals.setID( std::string("restNormal") );
        	vrestnormals.setIndexShader( 0);
            vrestnormals.init();

            computeRestNormals();
        */
        computeRestPositions();
//
//    //add Model Matrix as Uniform
        if (!modelMatrixUniform)
        {
            modelMatrixUniform = new OglMatrix4Variable;
            modelMatrixUniform->setName("modelMatrix");
            this->getContext()->addObject(modelMatrixUniform);
            modelMatrixUniform->setID( std::string("modelMatrix") );
            modelMatrixUniform->setIndexShader( 0);
            modelMatrixUniform->init();
        }
    }
}

void OglShaderVisualModel::initVisual()
{
    OglModel::initVisual();
}

void OglShaderVisualModel::updateVisual()
{
    OglModel::updateVisual();
    computeRestPositions();
}

void OglShaderVisualModel::computeRestPositions()
{
    if (!vrestpositions) return;
    int counter = m_restPositions.getCounter();
    if (counter == restPosition_lastUpdate)
        return;
    restPosition_lastUpdate = counter;

    helper::ReadAccessor< Data<ResizableExtVector<Coord> > > positions = (m_positions.getValue().size() != m_restPositions.getValue().size()) ? m_positions : m_restPositions;
    ResizableExtVector<Coord>& vrestpos = * ( vrestpositions->beginEdit() );
    vrestpos.resize ( positions.size() );

    for ( unsigned int i = 0; i < positions.size(); i++ )
    {
        vrestpos[i] = positions[i];
    }

    vrestpositions->endEdit();
    computeRestNormals();
}

void OglShaderVisualModel::handleTopologyChange()
{
    //init();
    OglModel::handleTopologyChange();

    if (m_topology && shader)
    {
        bool update=false;
        std::list<const TopologyChange *>::const_iterator itBegin=m_topology->beginChange();
        std::list<const TopologyChange *>::const_iterator itEnd=m_topology->endChange();

        while( itBegin != itEnd )
        {
            core::topology::TopologyChangeType changeType = (*itBegin)->getChangeType();
            if ((changeType==core::topology::TRIANGLESREMOVED) ||
                (changeType==core::topology::TRIANGLESADDED) ||
                (changeType==core::topology::QUADSADDED) ||
                (changeType==core::topology::QUADSREMOVED))
                update=true;
            itBegin++;
        }
        if (update)
        {
            computeRestPositions();
            computeRestNormals();
//            std::cerr<< "OglShaderVisualModel - Updating Rest Normals"<<std::endl;
        }
    }

    //TODO// update the rest position when inserting a point. Then, call computeNormals() to update the attributes.
    // Not done here because we don't have the rest position of the model.
    // For the moment, the only class using dynamic topology is HexaToTriangleTopologicalMapping which update itself the attributes...
}

void OglShaderVisualModel::bwdDraw(core::visual::VisualParams* /*vp*/)
{
}

void OglShaderVisualModel::fwdDraw(core::visual::VisualParams* /*vp*/)
{
}

void OglShaderVisualModel::computeRestNormals()
{
    if (!vrestpositions || !vrestnormals) return;
    const ResizableExtVector<Coord>& vrestpos = vrestpositions->getValue();
    const ResizableExtVector<Triangle>& triangles = m_triangles.getValue();
    const ResizableExtVector<Quad>& quads = m_quads.getValue();
    ResizableExtVector<Coord>& restNormals = * ( vrestnormals->beginEdit() );
    restNormals.resize(vrestpos.size());
    for (unsigned int i = 0; i < restNormals.size(); i++)
    {
        restNormals[i].clear();
    }
    for (unsigned int i = 0; i < triangles.size() ; i++)
    {
        if (triangles[i][0] >= vrestpos.size() || triangles[i][1] >= vrestpos.size() || triangles[i][2] >= vrestpos.size())
            continue;
        const Coord  v1 = vrestpos[triangles[i][0]];
        const Coord  v2 = vrestpos[triangles[i][1]];
        const Coord  v3 = vrestpos[triangles[i][2]];
        Coord n = cross(v2-v1, v3-v1);

        n.normalize();
        restNormals[triangles[i][0]] += n;
        restNormals[triangles[i][1]] += n;
        restNormals[triangles[i][2]] += n;
    }
    for (unsigned int i = 0; i < quads.size() ; i++)
    {
        if (quads[i][0] >= vrestpos.size() || quads[i][1] >= vrestpos.size() || quads[i][2] >= vrestpos.size() || quads[i][3] >= vrestpos.size())
            continue;
        const Coord & v1 = vrestpos[quads[i][0]];
        const Coord & v2 = vrestpos[quads[i][1]];
        const Coord & v3 = vrestpos[quads[i][2]];
        const Coord & v4 = vrestpos[quads[i][3]];
        Coord n1 = cross(v2-v1, v4-v1);
        Coord n2 = cross(v3-v2, v1-v2);
        Coord n3 = cross(v4-v3, v2-v3);
        Coord n4 = cross(v1-v4, v3-v4);
        n1.normalize(); n2.normalize(); n3.normalize(); n4.normalize();
        restNormals[quads[i][0]] += n1;
        restNormals[quads[i][1]] += n2;
        restNormals[quads[i][2]] += n3;
        restNormals[quads[i][3]] += n4;
    }
    for (unsigned int i = 0; i < restNormals.size(); i++)
    {
        restNormals[i].normalize();
    }
    vrestnormals->endEdit();
}

} //namespace visualmodel

} //namespace component

} //namespace sofa
<commit_msg>r9072/sofa : improve texture display with topological modification, however, the bug is not fiw since i don't know how to access restPosition from visualComponent<commit_after>/******************************************************************************
*       SOFA, Simulation Open-Framework Architecture, version 1.0 RC 1        *
*                (c) 2006-2011 MGH, INRIA, USTL, UJF, CNRS                    *
*                                                                             *
* 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.          *
*******************************************************************************
*                               SOFA :: Modules                               *
*                                                                             *
* Authors: The SOFA Team and external contributors (see Authors.txt)          *
*                                                                             *
* Contact information: contact@sofa-framework.org                             *
******************************************************************************/
/*
 * OglShaderVisualModel.cpp
 *
 *  Created on: 9 févr. 2009
 *      Author: froy
 */

#include <sofa/component/visualmodel/OglShaderVisualModel.h>
#include <sofa/core/visual/VisualParams.h>
#include <sofa/core/ObjectFactory.h>

#include <sofa/core/topology/TopologyChange.h>
#include <sofa/component/topology/PointSetGeometryAlgorithms.h>
#include <sofa/simulation/common/Node.h>
#include <sofa/defaulttype/VecTypes.h>
#include <sofa/component/visualmodel/OglAttribute.inl>

namespace sofa
{

namespace component
{

namespace visualmodel
{

using namespace sofa::core::topology;
using namespace sofa::core::behavior;

SOFA_DECL_CLASS(OglShaderVisualModel)

int OglShaderVisualModelClass = core::RegisterObject("Visual model for OpenGL display using Glew extensions")
        .add< OglShaderVisualModel >()
        ;

OglShaderVisualModel::OglShaderVisualModel()
    : shader(NULL)
    , restPosition_lastUpdate(-1)
    , vrestpositions(NULL)
    , vrestnormals(NULL)
    , modelMatrixUniform(NULL)
{
}

OglShaderVisualModel::~OglShaderVisualModel()
{
}

void OglShaderVisualModel::pushTransformMatrix(float* matrix)
{
    OglModel::pushTransformMatrix(matrix);

    helper::vector<float> tempModelMatrixValue;

    for ( unsigned int i = 0; i < 16; i++ )
        tempModelMatrixValue.push_back(matrix[i]);
    if (modelMatrixUniform)
        modelMatrixUniform->setValue(tempModelMatrixValue);

    if (shader)
    {
        shader->stop();
        if (modelMatrixUniform)
            modelMatrixUniform->pushValue();
        shader->start();
    }
}

void OglShaderVisualModel::popTransformMatrix()
{
    OglModel::popTransformMatrix();
    /*
    	if (shader)
    		shader->stop();
    */
}

void OglShaderVisualModel::init()
{
    if (!shader)
        OglModel::init();

    sofa::core::objectmodel::BaseContext* context = this->getContext();
    shader = context->core::objectmodel::BaseContext::get<OglShader>();

    if( shader)
    {
        if (!vrestpositions)
            context->get(vrestpositions, "restPosition");
        if (!vrestnormals)
            context->get(vrestnormals, "restNormal");
        if (!modelMatrixUniform)
            context->get(modelMatrixUniform, "modelMatrix");
        //add restPosition as Attribute
        if (!vrestpositions)
        {
            vrestpositions = new OglFloat3Attribute;
            vrestpositions->setName("restPosition");
            this->getContext()->addObject(vrestpositions);
            vrestpositions->setID( std::string("restPosition"));
            vrestpositions->setIndexShader(0);
            vrestpositions->init();
        }

        if (!vrestnormals)
        {
            vrestnormals = new OglFloat3Attribute;
            vrestnormals->setName("restNormal");
            this->getContext()->addObject(vrestnormals);
            vrestnormals->setID( std::string("restNormal"));
            vrestnormals->setIndexShader(0);
            vrestnormals->init();
        }
        /*
            ResizableExtVector<Coord>& vrestpos = * ( vrestpositions.beginEdit() );
            const ResizableExtVector<Coord>& vertices = m_vertices.getValue();
            vrestpos.resize (vertices.size() );
            for ( unsigned int i = 0; i < vertices.size(); i++ )
            {
              vrestpos[i] = vertices[i];
            }
            vrestpositions.endEdit();

            //add restNormal as Attribute
            vrestnormals.setContext( this->getContext());
        	vrestnormals.setID( std::string("restNormal") );
        	vrestnormals.setIndexShader( 0);
            vrestnormals.init();

            computeRestNormals();
        */
        computeRestPositions();
//
//    //add Model Matrix as Uniform
        if (!modelMatrixUniform)
        {
            modelMatrixUniform = new OglMatrix4Variable;
            modelMatrixUniform->setName("modelMatrix");
            this->getContext()->addObject(modelMatrixUniform);
            modelMatrixUniform->setID( std::string("modelMatrix") );
            modelMatrixUniform->setIndexShader( 0);
            modelMatrixUniform->init();
        }
    }
}

void OglShaderVisualModel::initVisual()
{
    OglModel::initVisual();
}

void OglShaderVisualModel::updateVisual()
{
    OglModel::updateVisual();
    computeRestPositions();
}

void OglShaderVisualModel::computeRestPositions()
{
    if (!vrestpositions) return;
//    int counter = m_restPositions.getCounter();
//    if (counter == restPosition_lastUpdate) return;
//    restPosition_lastUpdate = counter;

    helper::ReadAccessor< Data<ResizableExtVector<Coord> > > positions = m_positions;
    helper::ReadAccessor< Data<ResizableExtVector<Coord> > > restpositions = m_restPositions;

    //Get the position of the new point (should be the rest position to avoid artefact !
    if (restpositions.size()!=positions.size()) {
        VecCoord& restVertices = *(m_restPositions.beginEdit());
        for (unsigned int i=restVertices.size(); i<positions.size(); i++) {
            restVertices.push_back(positions[i]);
        }
        m_restPositions.endEdit();
    }

    ResizableExtVector<Coord>& vrestpos = * ( vrestpositions->beginEdit() );
    vrestpos.resize ( restpositions.size() );

    for ( unsigned int i = 0; i < restpositions.size(); i++ )
    {
        vrestpos[i] = restpositions[i];
    }

    vrestpositions->endEdit();
    computeRestNormals();
}

void OglShaderVisualModel::handleTopologyChange()
{
    //init();
    OglModel::handleTopologyChange();

    if (m_topology && shader)
    {
//        bool update=false;
        std::list<const TopologyChange *>::const_iterator itBegin=m_topology->beginChange();
        std::list<const TopologyChange *>::const_iterator itEnd=m_topology->endChange();

//        while( itBegin != itEnd )
//        {
//            core::topology::TopologyChangeType changeType = (*itBegin)->getChangeType();
//            if ((changeType==core::topology::TRIANGLESREMOVED) ||
//                (changeType==core::topology::TRIANGLESADDED) ||
//                (changeType==core::topology::QUADSADDED) ||
//                (changeType==core::topology::QUADSREMOVED))
//            update=true;
//            itBegin++;
//        }
        if (itBegin != itEnd)
        {
            computeRestPositions();
            computeRestNormals();
//            std::cerr<< "OglShaderVisualModel - Updating Rest Normals"<<std::endl;
        }
    }

    //TODO// update the rest position when inserting a point. Then, call computeNormals() to update the attributes.
    // Not done here because we don't have the rest position of the model.
    // For the moment, the only class using dynamic topology is HexaToTriangleTopologicalMapping which update itself the attributes...
}

void OglShaderVisualModel::bwdDraw(core::visual::VisualParams* /*vp*/)
{
}

void OglShaderVisualModel::fwdDraw(core::visual::VisualParams* /*vp*/)
{
}

void OglShaderVisualModel::computeRestNormals()
{
    if (!vrestpositions || !vrestnormals) return;
    const ResizableExtVector<Coord>& vrestpos = vrestpositions->getValue();
    const ResizableExtVector<Triangle>& triangles = m_triangles.getValue();
    const ResizableExtVector<Quad>& quads = m_quads.getValue();
    ResizableExtVector<Coord>& restNormals = * ( vrestnormals->beginEdit() );
    restNormals.resize(vrestpos.size());
    for (unsigned int i = 0; i < restNormals.size(); i++)
    {
        restNormals[i].clear();
    }
    for (unsigned int i = 0; i < triangles.size() ; i++)
    {
        if (triangles[i][0] >= vrestpos.size() || triangles[i][1] >= vrestpos.size() || triangles[i][2] >= vrestpos.size())
            continue;
        const Coord  v1 = vrestpos[triangles[i][0]];
        const Coord  v2 = vrestpos[triangles[i][1]];
        const Coord  v3 = vrestpos[triangles[i][2]];
        Coord n = cross(v2-v1, v3-v1);

        n.normalize();
        restNormals[triangles[i][0]] += n;
        restNormals[triangles[i][1]] += n;
        restNormals[triangles[i][2]] += n;
    }
    for (unsigned int i = 0; i < quads.size() ; i++)
    {
        if (quads[i][0] >= vrestpos.size() || quads[i][1] >= vrestpos.size() || quads[i][2] >= vrestpos.size() || quads[i][3] >= vrestpos.size())
            continue;
        const Coord & v1 = vrestpos[quads[i][0]];
        const Coord & v2 = vrestpos[quads[i][1]];
        const Coord & v3 = vrestpos[quads[i][2]];
        const Coord & v4 = vrestpos[quads[i][3]];
        Coord n1 = cross(v2-v1, v4-v1);
        Coord n2 = cross(v3-v2, v1-v2);
        Coord n3 = cross(v4-v3, v2-v3);
        Coord n4 = cross(v1-v4, v3-v4);
        n1.normalize(); n2.normalize(); n3.normalize(); n4.normalize();
        restNormals[quads[i][0]] += n1;
        restNormals[quads[i][1]] += n2;
        restNormals[quads[i][2]] += n3;
        restNormals[quads[i][3]] += n4;
    }
    for (unsigned int i = 0; i < restNormals.size(); i++)
    {
        restNormals[i].normalize();
    }
    vrestnormals->endEdit();
}

} //namespace visualmodel

} //namespace component

} //namespace sofa
<|endoftext|>


<commit_before>/** DecontextualizerRule.cc ---
 *
 * Copyright (C) 2010 OpenCog Foundation
 *
 * Author: Nil Geisweiller <nilg@laptop>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License v3 as
 * published by the Free Software Foundation and including the exceptions
 * at http://opencog.org/wiki/Licenses
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program; if not, write to:
 * Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include "DecontextualizerRule.h"
#include <opencog/util/algorithm.h>
#include "../RuleFunctions.h"

namespace opencog { namespace pln {

meta DecontextualizerRule::i2oType(const VertexSeq& h) const {
    OC_ASSERT(h.size() == 1);
    pHandle ph = _v2h(h[0]);
    OC_ASSERT(asw->isSubType(ph, CONTEXT_LINK));
    OC_ASSERT(asw->getArity(ph) == 2);
    pHandle CX = asw->getOutgoing(ph,0);
    pHandle A = asw->getOutgoing(ph,1); // contextualized atom

    // this is for case b)
    if(asw->isSubType(A, PREDICATE_NODE) ||
       asw->isSubType(A, EVALUATION_LINK)) {
        /// @todo this might be decomposed into subrule
        A = asw->addLink(SATISFYING_SET_LINK, pHandleSeq(1, A),
                         *asw->getTV(A), false);
    }
    // case a)
    // @note it is missing the cases where concepts are AND_LINK and such
    // for that we need some sort of type checker
    if(asw->isSubType(A, CONCEPT_NODE) ||
       asw->isSubType(A, SATISFYING_SET_LINK)) {
        return meta(new vtree(mva((pHandle)SUBSET_LINK, mva(CX), mva(A))));
    } else { // case c) Relation
        OC_ASSERT(asw->getArity(A)==2); /// @todo generilize for n-ary
        pHandle AC1 = asw->getOutgoing(A,0);
        pHandle AC2 = asw->getOutgoing(A,1);
        return meta(new vtree(mva((pHandle)asw->getType(A),
                                  mva((pHandle)AND_LINK, mva(CX), mva(AC1)),
                                  mva((pHandle)AND_LINK, mva(CX), mva(AC2)))));
    }

}

TVSeq DecontextualizerRule::formatTVarray(const VertexSeq& premiseArray) const {
    OC_ASSERT(premiseArray.size()==1);
    return TVSeq(1, asw->getTV(_v2h(premiseArray[0])));
}

DecontextualizerRule::DecontextualizerRule(AtomSpaceWrapper* _asw)
    : GenericRule<IdentityFormula>(_asw, false, "DecontextualizerRule") {
    inputFilter.push_back(meta(new vtree(mva((pHandle)CONTEXT_LINK,
                                             mva((pHandle)ATOM),
                                             mva((pHandle)ATOM)))));
}

Rule::setOfMPs DecontextualizerRule::o2iMetaExtra(meta outh,
                                                  bool& overrideInputFilter) const {
    vtree::iterator root = outh->begin();
    pHandle ph = _v2h(*root);

    if(asw->isSubType(ph, NODE) ||
       root.number_of_children() != 2) // maybe this should be relaxed
        return Rule::setOfMPs();

    BoundVTree* res;

    vtree::iterator A1_it = root.begin();
    pHandle A1 = _v2h(*A1_it);
    vtree::iterator A2_it = root.last_child();
    pHandle A2 = _v2h(*A2_it);

    // case c)
    if(asw->getType(A1) == AND_LINK && asw->getType(A2) == AND_LINK) {
        // @todo generilize for n-ary
        OC_ASSERT(A1_it.number_of_children() == 2);
        OC_ASSERT(A2_it.number_of_children() == 2);
        pHandleSeq out1, out2; // set of potential contexts
        for(vtree::sibling_iterator sib = A1_it.begin();
            sib != A1_it.end(); sib++) {
            out1.push_back(_v2h(*sib));
        }
        for(vtree::sibling_iterator sib = A2_it.begin();
            sib != A2_it.end(); sib++) {
            out2.push_back(_v2h(*sib));
        }
        // the intersection btw out1 and out2 will be the new context
        pHandleSeq inter = set_intersection(out1, out2);

        if(inter.size() > 0) {
            if(inter.size() != 1) /// @todo generalize for n-ary
                return Rule::setOfMPs();
            pHandle CX = *inter.begin();
            // can be optimized
            pHandleSeq new_out1 = set_difference(out1, inter);
            pHandleSeq new_out2 = set_difference(out2, inter);
            /// @todo generalize for n-ary
            if(new_out1.size() != 1 || new_out2.size())
                return Rule::setOfMPs();
            pHandle A = new_out1[0];
            pHandle B = new_out2[0];
            res = new BoundVTree(mva((pHandle)CONTEXT_LINK, mva(CX),
                                     mva((pHandle)asw->getType(ph),
                                         mva(A), mva(B))));
            makeSingletonSet(Rule::MPs(1, BBvtree(res)));
        }
    }

    // otherwise case a) and b)
    if(asw->isSubType(ph, SUBSET_LINK)) {
        if(asw->isSubType(A2, SATISFYING_SET_LINK)) // case b)
            A2 = _v2h(*A2_it.begin());
        res = new BoundVTree(mva((pHandle)CONTEXT_LINK, mva(A1), mva(A2)));
        return makeSingletonSet(Rule::MPs(1, BBvtree(res)));
    } else // no case applies
        return Rule::setOfMPs();
}

meta DecontextualizerRule::targetTemplate() const {
    return(meta(new vtree(mva((pHandle)LINK,
                              vtree(CreateVar(asw)),
                              vtree(CreateVar(asw))))));
}

}} // namespace opencog { namespace pln {
<commit_msg>Replace OC_ASSERT with simply refusing to produce such Atoms (otherwise the BC will trigger the assert 'by mistake'<commit_after>/** DecontextualizerRule.cc ---
 *
 * Copyright (C) 2010 OpenCog Foundation
 *
 * Author: Nil Geisweiller <nilg@laptop>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License v3 as
 * published by the Free Software Foundation and including the exceptions
 * at http://opencog.org/wiki/Licenses
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program; if not, write to:
 * Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include "DecontextualizerRule.h"
#include <opencog/util/algorithm.h>
#include "../RuleFunctions.h"

namespace opencog { namespace pln {

meta DecontextualizerRule::i2oType(const VertexSeq& h) const {
    OC_ASSERT(h.size() == 1);
    pHandle ph = _v2h(h[0]);
    OC_ASSERT(asw->isSubType(ph, CONTEXT_LINK));
    OC_ASSERT(asw->getArity(ph) == 2);
    pHandle CX = asw->getOutgoing(ph,0);
    pHandle A = asw->getOutgoing(ph,1); // contextualized atom

    // this is for case b)
    if(asw->isSubType(A, PREDICATE_NODE) ||
       asw->isSubType(A, EVALUATION_LINK)) {
        /// @todo this might be decomposed into subrule
        A = asw->addLink(SATISFYING_SET_LINK, pHandleSeq(1, A),
                         *asw->getTV(A), false);
    }
    // case a)
    // @note it is missing the cases where concepts are AND_LINK and such
    // for that we need some sort of type checker
    if(asw->isSubType(A, CONCEPT_NODE) ||
       asw->isSubType(A, SATISFYING_SET_LINK)) {
        return meta(new vtree(mva((pHandle)SUBSET_LINK, mva(CX), mva(A))));
    } else { // case c) Relation
        OC_ASSERT(asw->getArity(A)==2); /// @todo generilize for n-ary
        pHandle AC1 = asw->getOutgoing(A,0);
        pHandle AC2 = asw->getOutgoing(A,1);
        return meta(new vtree(mva((pHandle)asw->getType(A),
                                  mva((pHandle)AND_LINK, mva(CX), mva(AC1)),
                                  mva((pHandle)AND_LINK, mva(CX), mva(AC2)))));
    }

}

TVSeq DecontextualizerRule::formatTVarray(const VertexSeq& premiseArray) const {
    OC_ASSERT(premiseArray.size()==1);
    return TVSeq(1, asw->getTV(_v2h(premiseArray[0])));
}

DecontextualizerRule::DecontextualizerRule(AtomSpaceWrapper* _asw)
    : GenericRule<IdentityFormula>(_asw, false, "DecontextualizerRule") {
    inputFilter.push_back(meta(new vtree(mva((pHandle)CONTEXT_LINK,
                                             mva((pHandle)ATOM),
                                             mva((pHandle)ATOM)))));
}

Rule::setOfMPs DecontextualizerRule::o2iMetaExtra(meta outh,
                                                  bool& overrideInputFilter) const {
    vtree::iterator root = outh->begin();
    pHandle ph = _v2h(*root);

    if(asw->isSubType(ph, NODE) ||
       root.number_of_children() != 2) // maybe this should be relaxed
        return Rule::setOfMPs();

    BoundVTree* res;

    vtree::iterator A1_it = root.begin();
    pHandle A1 = _v2h(*A1_it);
    vtree::iterator A2_it = root.last_child();
    pHandle A2 = _v2h(*A2_it);

    // case c)
    if(asw->getType(A1) == AND_LINK && asw->getType(A2) == AND_LINK) {
        // @todo generilize for n-ary
        if (A1_it.number_of_children() != 2 ||
                A2_it.number_of_children() != 2)
            return Rule::setOfMPs();

        pHandleSeq out1, out2; // set of potential contexts
        for(vtree::sibling_iterator sib = A1_it.begin();
            sib != A1_it.end(); sib++) {
            out1.push_back(_v2h(*sib));
        }
        for(vtree::sibling_iterator sib = A2_it.begin();
            sib != A2_it.end(); sib++) {
            out2.push_back(_v2h(*sib));
        }
        // the intersection btw out1 and out2 will be the new context
        pHandleSeq inter = set_intersection(out1, out2);

        if(inter.size() > 0) {
            if(inter.size() != 1) /// @todo generalize for n-ary
                return Rule::setOfMPs();
            pHandle CX = *inter.begin();
            // can be optimized
            pHandleSeq new_out1 = set_difference(out1, inter);
            pHandleSeq new_out2 = set_difference(out2, inter);
            /// @todo generalize for n-ary
            if(new_out1.size() != 1 || new_out2.size())
                return Rule::setOfMPs();
            pHandle A = new_out1[0];
            pHandle B = new_out2[0];
            res = new BoundVTree(mva((pHandle)CONTEXT_LINK, mva(CX),
                                     mva((pHandle)asw->getType(ph),
                                         mva(A), mva(B))));
            makeSingletonSet(Rule::MPs(1, BBvtree(res)));
        }
    }

    // otherwise case a) and b)
    if(asw->isSubType(ph, SUBSET_LINK)) {
        if(asw->isSubType(A2, SATISFYING_SET_LINK)) // case b)
            A2 = _v2h(*A2_it.begin());
        res = new BoundVTree(mva((pHandle)CONTEXT_LINK, mva(A1), mva(A2)));
        return makeSingletonSet(Rule::MPs(1, BBvtree(res)));
    } else // no case applies
        return Rule::setOfMPs();
}

meta DecontextualizerRule::targetTemplate() const {
    return(meta(new vtree(mva((pHandle)LINK,
                              vtree(CreateVar(asw)),
                              vtree(CreateVar(asw))))));
}

}} // namespace opencog { namespace pln {
<|endoftext|>


<commit_before>/*
   This file is part of the clazy static checker.

  Copyright (C) 2015 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com
  Author: Sérgio Martins <sergio.martins@kdab.com>

  Copyright (C) 2015 Sergio Martins <smartins@kde.org>

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

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Library General Public License for more details.

  You should have received a copy of the GNU Library General Public License
  along with this library; see the file COPYING.LIB.  If not, write to
  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  Boston, MA 02110-1301, USA.
*/

#include "missingtypeinfo.h"
#include "Utils.h"
#include "TemplateUtils.h"
#include "TypeUtils.h"
#include "QtUtils.h"
#include "checkmanager.h"
#include "StringUtils.h"

#include <clang/AST/AST.h>
#include <clang/AST/DeclTemplate.h>

#include <sstream>

using namespace std;
using namespace clang;

MissingTypeinfo::MissingTypeinfo(const std::string &name, const clang::CompilerInstance &ci)
    : CheckBase(name, ci)
{
}

void MissingTypeinfo::VisitDecl(clang::Decl *decl)
{
    ClassTemplateSpecializationDecl *tstdecl = TemplateUtils::templateDecl(decl);
    if (!tstdecl)
        return;

    const bool isQList = tstdecl->getName() == "QList";
    const bool isQVector = tstdecl->getName() == "QVector";

    if (!isQList && !isQVector) {
        registerQTypeInfo(tstdecl);
        return;
    }

    QualType qt2 = TemplateUtils::getTemplateArgumentType(tstdecl, 0);
    const Type *t = qt2.getTypePtrOrNull();
    CXXRecordDecl *record = t ? t->getAsCXXRecordDecl() : nullptr;
    if (!record || !record->getDefinition() || typeHasClassification(qt2))
        return; // Don't crash if we only have a fwd decl

    const bool isCopyable = qt2.isTriviallyCopyableType(m_ci.getASTContext());
    const bool isTooBigForQList = QtUtils::isTooBigForQList(qt2, m_ci);

    if (isCopyable && (isQVector || (isQList && isTooBigForQList))) {
        std::string typeName = record->getName();
        if (typeName == "QPair") // QPair doesn't use Q_DECLARE_TYPEINFO, but rather a explicit QTypeInfo.
            return;

        std::string s;
        std::stringstream out;
        out << m_ci.getASTContext().getTypeSize(qt2)/8;
        s = "Missing Q_DECLARE_TYPEINFO: " + typeName;
        emitWarning(decl, s.c_str());
        emitWarning(record, "Type declared here:", false);
    }
}

void MissingTypeinfo::registerQTypeInfo(ClassTemplateSpecializationDecl *decl)
{
    if (decl->getName() == "QTypeInfo") {
        const string typeName = TemplateUtils::getTemplateArgumentTypeStr(decl, 0, lo(), /**recordOnly=*/true);
        if (!typeName.empty())
            m_typeInfos.insert(typeName);
    }
}

bool MissingTypeinfo::typeHasClassification(QualType qt) const
{
    return m_typeInfos.find(StringUtils::simpleTypeName(qt, lo())) != m_typeInfos.end();
}

REGISTER_CHECK_WITH_FLAGS("missing-typeinfo", MissingTypeinfo, CheckLevel3)
<commit_msg>missing-type-info: Remove cruft and simplify<commit_after>/*
   This file is part of the clazy static checker.

  Copyright (C) 2015 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com
  Author: Sérgio Martins <sergio.martins@kdab.com>

  Copyright (C) 2015 Sergio Martins <smartins@kde.org>

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

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Library General Public License for more details.

  You should have received a copy of the GNU Library General Public License
  along with this library; see the file COPYING.LIB.  If not, write to
  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  Boston, MA 02110-1301, USA.
*/

#include "missingtypeinfo.h"
#include "Utils.h"
#include "TemplateUtils.h"
#include "TypeUtils.h"
#include "QtUtils.h"
#include "checkmanager.h"
#include "StringUtils.h"

#include <clang/AST/AST.h>
#include <clang/AST/DeclTemplate.h>

using namespace std;
using namespace clang;

MissingTypeinfo::MissingTypeinfo(const std::string &name, const clang::CompilerInstance &ci)
    : CheckBase(name, ci)
{
}

void MissingTypeinfo::VisitDecl(clang::Decl *decl)
{
    ClassTemplateSpecializationDecl *tstdecl = TemplateUtils::templateDecl(decl);
    if (!tstdecl)
        return;

    const bool isQList = tstdecl->getName() == "QList";
    const bool isQVector = tstdecl->getName() == "QVector";

    if (!isQList && !isQVector) {
        registerQTypeInfo(tstdecl);
        return;
    }

    QualType qt2 = TemplateUtils::getTemplateArgumentType(tstdecl, 0);
    const Type *t = qt2.getTypePtrOrNull();
    CXXRecordDecl *record = t ? t->getAsCXXRecordDecl() : nullptr;
    if (!record || !record->getDefinition() || typeHasClassification(qt2))
        return; // Don't crash if we only have a fwd decl

    const bool isCopyable = qt2.isTriviallyCopyableType(m_ci.getASTContext());
    const bool isTooBigForQList = QtUtils::isTooBigForQList(qt2, m_ci);

    if (isCopyable && (isQVector || (isQList && isTooBigForQList))) {
        std::string typeName = record->getName();
        if (typeName == "QPair") // QPair doesn't use Q_DECLARE_TYPEINFO, but rather a explicit QTypeInfo.
            return;

        emitWarning(decl, "Missing Q_DECLARE_TYPEINFO: " + typeName);
        emitWarning(record, "Type declared here:", false);
    }
}

void MissingTypeinfo::registerQTypeInfo(ClassTemplateSpecializationDecl *decl)
{
    if (decl->getName() == "QTypeInfo") {
        const string typeName = TemplateUtils::getTemplateArgumentTypeStr(decl, 0, lo(), /**recordOnly=*/true);
        if (!typeName.empty())
            m_typeInfos.insert(typeName);
    }
}

bool MissingTypeinfo::typeHasClassification(QualType qt) const
{
    return m_typeInfos.find(StringUtils::simpleTypeName(qt, lo())) != m_typeInfos.end();
}

REGISTER_CHECK_WITH_FLAGS("missing-typeinfo", MissingTypeinfo, CheckLevel3)
<|endoftext|>


<commit_before>#include "runner.hh"
#include "task.hh"
#include "buffer.hh"
#include "http/http_message.hh"
#include "uri/uri.hh"
#include <boost/bind.hpp>
#include <boost/lexical_cast.hpp>

#include <iostream>

using namespace fw;

#define SEC2MS(s) (s*1000)

void sock_copy(task::socket &a, task::socket &b, buffer::slice rb) {
    for (;;) {
        pollfd fds[2];
        fds[0].events = EPOLLIN;
        fds[0].fd = a.s.fd;
        fds[1].events = EPOLLIN;
        fds[1].fd = b.s.fd;
        if (!task::poll(fds, 2, 0)) break;
        if (fds[0].revents) {
            ssize_t nr = a.recv(rb.data(), rb.size());
            if (nr <= 0) break;
            ssize_t nw = b.send(rb.data(), nr);
            if (nw != nr) break;
        }
        if (fds[1].revents) {
            ssize_t nr = b.recv(rb.data(), rb.size());
            if (nr <= 0) break;
            ssize_t nw = a.send(rb.data(), nr);
            if (nw != nr) break;

        }
    }
}

void send_503_reply(task::socket &s) {
    http_response resp(503, "Gateway Timeout");
    std::string data = resp.data();
    ssize_t nw = s.send(data.data(), data.size());
    (void)nw; // ignore
}

void proxy_task(int sock) {
    task::socket s(sock);
    buffer buf(4*1024);
    http_parser parser;
    http_request req;
    req.parser_init(&parser);

    buffer::slice rb = buf(0);
    for (;;) {
        ssize_t nr = s.recv(rb.data(), rb.size(), SEC2MS(5));
        if (nr < 0) { goto request_read_error; }
        if (req.parse(&parser, rb.data(), nr)) break;
        if (nr == 0) return;
    }

    try {
        uri u(req.uri);
        u.normalize();
        std::cout << req.method << " " << u.compose() << "\n";

        task::socket cs(AF_INET, SOCK_STREAM);

        if (req.method == "CONNECT") {
            ssize_t pos = u.path.find(':');
            u.host = u.path.substr(1, pos-1);
            u.port = boost::lexical_cast<uint16_t>(u.path.substr(pos+1));
            if (cs.dial(u.host.c_str(), u.port, SEC2MS(10))) {
                goto request_connect_error;
            }

            http_response resp(200, "Connected ok");
            std::string data = resp.data();
            ssize_t nw = s.send(data.data(), data.size(), SEC2MS(5));

            sock_copy(s, cs, rb);
            return;
        } else {
            if (u.port == 0) u.port = 80;
            if (cs.dial(u.host.c_str(), u.port, SEC2MS(10))) {
                goto request_connect_error;
            }

            http_request r(req.method, u.compose(true));
            // HTTP/1.1 requires host header
            r.append_header("Host", u.host);
            r.headers = req.headers;
            std::string data = r.data();
            ssize_t nw = cs.send(data.data(), data.size(), SEC2MS(5));
            if (nw <= 0) { goto request_send_error; }
            if (!req.body.empty()) {
                nw = cs.send(req.body.data(), req.body.size(), SEC2MS(5));
                if (nw <= 0) { goto request_send_error; }
            }

            http_response resp(&r);
            resp.parser_init(&parser);
            bool headers_sent = false;
            for (;;) {
                ssize_t nr = cs.recv(rb.data(), rb.size(), SEC2MS(5));
                if (nr < 0) { goto response_read_error; }
                bool complete = resp.parse(&parser, rb.data(), nr);
                if (headers_sent == false && resp.status_code) {
                    headers_sent = true;
                    data = resp.data();
                    nw = s.send(data.data(), data.size());
                    if (nw <= 0) { goto response_send_error; }
                }

                if (resp.body.size()) {
                    if (resp.header_string("Transfer-Encoding") == "chunked") {
                        char lenbuf[64];
                        int len = snprintf(lenbuf, sizeof(lenbuf)-1, "%zx\r\n", resp.body.size());
                        resp.body.insert(0, lenbuf, len);
                        resp.body.append("\r\n");
                    }
                    nw = s.send(resp.body.data(), resp.body.size());
                    if (nw <= 0) { goto response_send_error; }
                    resp.body.clear();
                }
                if (complete) {
                    // send end chunk
                    if (resp.header_string("Transfer-Encoding") == "chunked") {
                        nw = s.send("0\r\n\r\n", 5);
                    }
                    break;
                }
                if (nr == 0) { goto response_read_error; }
            }
            return;
        }
    } catch (std::exception &e) {
        std::cerr << "exception error: " << req.uri << " : " << e.what() << "\n";
        return;
    }
request_read_error:
    std::cerr << "request read error: " << errno << ": " << strerror(errno) << "\n";
    return;
request_connect_error:
    std::cerr << "request connect error: " << errno << ": " << strerror(errno) << "\n";
    send_503_reply(s);
    return;
request_send_error:
    std::cerr << "request send error: " << errno << ": " << strerror(errno) << "\n";
    send_503_reply(s);
    return;
response_read_error:
    std::cerr << "response read error: " << errno << ": " << strerror(errno) << "\n";
    send_503_reply(s);
    return;
response_send_error:
    std::cerr << "response send error: " << errno << ": " << strerror(errno) << "\n";
    return;
}

void listen_task() {
    task::socket s(AF_INET, SOCK_STREAM);
    s.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1);
    address addr("0.0.0.0", 8080);
    s.bind(addr);
    s.getsockname(addr);
    std::cout << "listening on: " << addr << "\n";
    s.listen();

    for (;;) {
        address client_addr;
        int sock;
        while ((sock = s.accept(client_addr, 0)) > 0) {
            task::spawn(boost::bind(proxy_task, sock), 0, 4*1024*1024);
        }
    }
}

int main(int argc, char *argv[]) {
    runner::init();
    task::spawn(listen_task);
    return runner::main();
}
<commit_msg>use logging<commit_after>#include "runner.hh"
#include "task.hh"
#include "buffer.hh"
#include "http/http_message.hh"
#include "uri/uri.hh"
#include "logging.hh"
#include <boost/bind.hpp>
#include <boost/lexical_cast.hpp>

using namespace fw;

#define SEC2MS(s) (s*1000)

void sock_copy(task::socket &a, task::socket &b, buffer::slice rb) {
    for (;;) {
        pollfd fds[2];
        fds[0].events = EPOLLIN;
        fds[0].fd = a.s.fd;
        fds[1].events = EPOLLIN;
        fds[1].fd = b.s.fd;
        if (!task::poll(fds, 2, 0)) break;
        if (fds[0].revents) {
            ssize_t nr = a.recv(rb.data(), rb.size());
            if (nr <= 0) break;
            ssize_t nw = b.send(rb.data(), nr);
            if (nw != nr) break;
        }
        if (fds[1].revents) {
            ssize_t nr = b.recv(rb.data(), rb.size());
            if (nr <= 0) break;
            ssize_t nw = a.send(rb.data(), nr);
            if (nw != nr) break;

        }
    }
}

void send_503_reply(task::socket &s) {
    http_response resp(503, "Gateway Timeout");
    std::string data = resp.data();
    ssize_t nw = s.send(data.data(), data.size());
    (void)nw; // ignore
}

void proxy_task(int sock) {
    task::socket s(sock);
    buffer buf(4*1024);
    http_parser parser;
    http_request req;
    req.parser_init(&parser);

    buffer::slice rb = buf(0);
    for (;;) {
        ssize_t nr = s.recv(rb.data(), rb.size(), SEC2MS(5));
        if (nr < 0) { goto request_read_error; }
        if (req.parse(&parser, rb.data(), nr)) break;
        if (nr == 0) return;
    }

    try {
        uri u(req.uri);
        u.normalize();
        LOG(INFO) << req.method << " " << u.compose();

        task::socket cs(AF_INET, SOCK_STREAM);

        if (req.method == "CONNECT") {
            ssize_t pos = u.path.find(':');
            u.host = u.path.substr(1, pos-1);
            u.port = boost::lexical_cast<uint16_t>(u.path.substr(pos+1));
            if (cs.dial(u.host.c_str(), u.port, SEC2MS(10))) {
                goto request_connect_error;
            }

            http_response resp(200, "Connected ok");
            std::string data = resp.data();
            ssize_t nw = s.send(data.data(), data.size(), SEC2MS(5));

            sock_copy(s, cs, rb);
            return;
        } else {
            if (u.port == 0) u.port = 80;
            if (cs.dial(u.host.c_str(), u.port, SEC2MS(10))) {
                goto request_connect_error;
            }

            http_request r(req.method, u.compose(true));
            // HTTP/1.1 requires host header
            r.append_header("Host", u.host);
            r.headers = req.headers;
            std::string data = r.data();
            ssize_t nw = cs.send(data.data(), data.size(), SEC2MS(5));
            if (nw <= 0) { goto request_send_error; }
            if (!req.body.empty()) {
                nw = cs.send(req.body.data(), req.body.size(), SEC2MS(5));
                if (nw <= 0) { goto request_send_error; }
            }

            http_response resp(&r);
            resp.parser_init(&parser);
            bool headers_sent = false;
            for (;;) {
                ssize_t nr = cs.recv(rb.data(), rb.size(), SEC2MS(5));
                if (nr < 0) { goto response_read_error; }
                bool complete = resp.parse(&parser, rb.data(), nr);
                if (headers_sent == false && resp.status_code) {
                    headers_sent = true;
                    data = resp.data();
                    nw = s.send(data.data(), data.size());
                    if (nw <= 0) { goto response_send_error; }
                }

                if (resp.body.size()) {
                    if (resp.header_string("Transfer-Encoding") == "chunked") {
                        char lenbuf[64];
                        int len = snprintf(lenbuf, sizeof(lenbuf)-1, "%zx\r\n", resp.body.size());
                        resp.body.insert(0, lenbuf, len);
                        resp.body.append("\r\n");
                    }
                    nw = s.send(resp.body.data(), resp.body.size());
                    if (nw <= 0) { goto response_send_error; }
                    resp.body.clear();
                }
                if (complete) {
                    // send end chunk
                    if (resp.header_string("Transfer-Encoding") == "chunked") {
                        nw = s.send("0\r\n\r\n", 5);
                    }
                    break;
                }
                if (nr == 0) { goto response_read_error; }
            }
            return;
        }
    } catch (std::exception &e) {
        LOG(ERROR) << "exception error: " << req.uri << " : " << e.what();
        return;
    }
request_read_error:
    PLOG(ERROR) << "request read error";
    return;
request_connect_error:
    PLOG(ERROR) << "request connect error " << req.method << " " << req.uri;
    send_503_reply(s);
    return;
request_send_error:
    PLOG(ERROR) << "request send error: " << req.method << " " << req.uri;
    send_503_reply(s);
    return;
response_read_error:
    PLOG(ERROR) << "response read error: " << req.method << " " << req.uri;
    send_503_reply(s);
    return;
response_send_error:
    PLOG(ERROR) << "response send error: " << req.method << " " << req.uri;
    return;
}

void listen_task() {
    task::socket s(AF_INET, SOCK_STREAM);
    s.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1);
    address addr("0.0.0.0", 8080);
    s.bind(addr);
    s.getsockname(addr);
    LOG(INFO) << "listening on: " << addr;
    s.listen();

    for (;;) {
        address client_addr;
        int sock;
        while ((sock = s.accept(client_addr, 0)) > 0) {
            task::spawn(boost::bind(proxy_task, sock), 0, 4*1024*1024);
        }
    }
}

int main(int argc, char *argv[]) {
    runner::init();
    task::spawn(listen_task);
    return runner::main();
}
<|endoftext|>


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

#include <string>
#include <vector>

#include "cartographer/common/configuration_file_resolver.h"
#include "cartographer/common/lua_parameter_dictionary.h"
#include "cartographer_ros/node_options.h"
#include "cartographer_ros/trajectory_options.h"
#include "gtest/gtest.h"
#include "ros/package.h"

namespace cartographer_ros {
namespace {

class ConfigurationFilesTest : public ::testing::TestWithParam<const char*> {};

TEST_P(ConfigurationFilesTest, ValidateNodeOptions) {
  EXPECT_NO_FATAL_FAILURE({
    auto file_resolver = ::cartographer::common::make_unique<
        ::cartographer::common::ConfigurationFileResolver>(
        std::vector<string>{::ros::package::getPath("cartographer_turtlebot") +
                            "/configuration_files"});
    const string code = file_resolver->GetFileContentOrDie(GetParam());
    ::cartographer::common::LuaParameterDictionary lua_parameter_dictionary(
        code, std::move(file_resolver));
    ::cartographer_ros::CreateNodeOptions(&lua_parameter_dictionary);
    ::cartographer_ros::CreateTrajectoryOptions(&lua_parameter_dictionary);
  });
}

INSTANTIATE_TEST_CASE_P(ValidateAllNodeOptions, ConfigurationFilesTest,
                        ::testing::Values("turtlebot_depth_camera_2d.lua",
                                          "turtlebot_depth_camera_3d.lua",
                                          "turtlebot_urg_lidar_2d.lua"));

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

#include <string>
#include <vector>

#include "cartographer_ros/node_options.h"
#include "gtest/gtest.h"
#include "ros/package.h"

namespace cartographer_ros {
namespace {

class ConfigurationFilesTest : public ::testing::TestWithParam<const char*> {};

TEST_P(ConfigurationFilesTest, ValidateNodeOptions) {
  EXPECT_NO_FATAL_FAILURE({
    LoadOptions(::ros::package::getPath("cartographer_turtlebot") +
                    "/configuration_files",
                GetParam());
  });
}

INSTANTIATE_TEST_CASE_P(ValidateAllNodeOptions, ConfigurationFilesTest,
                        ::testing::Values("turtlebot_depth_camera_2d.lua",
                                          "turtlebot_depth_camera_3d.lua",
                                          "turtlebot_urg_lidar_2d.lua"));

}  // namespace
}  // namespace cartographer_ros
<|endoftext|>


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

#include "metaMetaModel/metamodel.h"

using namespace qReal;

Metamodel::Metamodel()
{
}

QString Metamodel::id() const
{
	return mId;
}

void Metamodel::setId(const QString &id)
{
	mId = id;
}

QString Metamodel::version() const
{
	return mVersion;
}

void Metamodel::setVersion(const QString &version)
{
	mVersion = version;
}

const QStringList &Metamodel::diagrams() const
{
	return mDiagrams;
}

void Metamodel::setDiagrams(const QStringList &diagrams)
{
	mDiagrams = diagrams;
}

void Metamodel::addDiagram(const QString &diagramName)
{
	if (!mDiagrams.contains(diagramName)) {
		mDiagrams << diagramName;
	}
}

QList<ElementType *> Metamodel::elements(const QString &diagram) const
{
	return mElements[diagram].values();
}

ElementType &Metamodel::elementType(const Id &id) const
{
	return elementType(id.diagram(), id.element());
}

ElementType &Metamodel::elementType(const QString &diagram, const QString &element) const
{
	Q_ASSERT_X(mElements.contains(diagram) && mElements[diagram].contains(element)
			, Q_FUNC_INFO, "No such entity in metamodel!");
	ElementType * const result = mElements[diagram][element];
	Q_ASSERT_X(result, Q_FUNC_INFO, "No such entity in metamodel!");
	return *result;
}

void Metamodel::addElement(ElementType &element)
{
	addNode(element);
}

QStringList Metamodel::enumNames() const
{
	return mEnumValues.keys();
}

QList<QPair<QString, QString>> Metamodel::enumValues(const QString &name) const
{
	return mEnumValues[name];
}

void Metamodel::addEnum(const QString &name, const QList<QPair<QString, QString> > &values)
{
	for (auto &&value : values) {
		if (mEnumValues[name].contains(value)) {
			mEnumValues[name] << value;
		}
	}
}

bool Metamodel::isEnumEditable(const QString &name) const
{
	return mEnumsEditability[name];
}

void Metamodel::setEnumEditable(const QString &name, bool editable)
{
	mEnumsEditability[name] = editable;
}

QString Metamodel::friendlyName() const
{
	return mFriendlyName;
}

void Metamodel::setFriendlyName(const QString &friendlyName)
{
	mFriendlyName = friendlyName;
}

QString Metamodel::diagramFriendlyName(const QString &diagram) const
{
	return mDiagramFriendlyNames[diagram];
}

void Metamodel::setDiagramFriendlyName(const QString &diagram, const QString &friendlyName)
{
	mDiagramFriendlyNames[diagram] = friendlyName;
}

ElementType *Metamodel::diagramNode(const QString &diagram) const
{
	return mDiagramNodes[diagram].isEmpty() ? nullptr : &elementType(diagram, mDiagramNodes[diagram]);
}

void Metamodel::setDiagramNode(const QString &diagram, const QString &elementName)
{
	if (!elementName.isEmpty()) {
		mDiagramNodes[diagram] = elementName;
	}
}

QStringList Metamodel::diagramPaletteGroups(const QString &diagram) const
{
	return mPaletteGroups[diagram];
}

void Metamodel::appendDiagramPaletteGroup(const QString &diagram, const QString &group)
{
	if (!mPaletteGroups[diagram].contains(group)) {
		mPaletteGroups[diagram] << group;
	}
}

QStringList Metamodel::diagramPaletteGroupList(const QString &diagram, const QString &group) const
{
	return mPaletteGroupContents[diagram][group];
}

void Metamodel::addElementToDiagramPaletteGroup(const QString &diagram, const QString &group, const QString &element)
{
	mPaletteGroupContents[diagram][group] << element;
}

QString Metamodel::diagramPaletteGroupDescription(const QString &diagram, const QString &group) const
{
	return mPaletteGroupDescriptions[diagram][group];
}

void Metamodel::setDiagramPaletteGroupDescription(const QString &diagram, const QString &group
		, const QString &description)
{
	mPaletteGroupDescriptions[diagram][group] = description;
}

bool Metamodel::shallPaletteBeSorted(const QString &diagram) const
{
	return mPaletteSorting[diagram];
}

void Metamodel::setPaletteSorted(const QString &diagram, bool sorted)
{
	mPaletteSorting[diagram] = sorted;
}

void Metamodel::addNode(qrgraph::Node &entity)
{
	ElementType * const type = dynamic_cast<ElementType *>(&entity);
	Q_ASSERT_X(type, Q_FUNC_INFO, "Attempt to add non-metamodel enitity!");
	Q_ASSERT_X(&type->metamodel() == this, Q_FUNC_INFO, "Attempt to add entity from other metamodel!");

	const QString diagram = type->diagram();
	const QString element = type->name();
	Q_ASSERT_X(!mElements[diagram][element], Q_FUNC_INFO, "Duplicate enitity in metamodel");

	mElements[diagram][element] = type;
	Multigraph::addNode(entity);
}

void Metamodel::addExplosion(ElementType &source, ElementType &target, bool isReusable, bool requiresImmediateLinkage)
{
	Explosion *explosion = new Explosion(*this, isReusable, requiresImmediateLinkage);
	addEdge(*explosion);
	explosion->connectBegin(source);
	explosion->connectEnd(target);
}
<commit_msg>fixed combo-boxes in property editor PS best fix ever<commit_after>/* Copyright 2016 Dmitry Mordvinov
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License. */

#include "metaMetaModel/metamodel.h"

using namespace qReal;

Metamodel::Metamodel()
{
}

QString Metamodel::id() const
{
	return mId;
}

void Metamodel::setId(const QString &id)
{
	mId = id;
}

QString Metamodel::version() const
{
	return mVersion;
}

void Metamodel::setVersion(const QString &version)
{
	mVersion = version;
}

const QStringList &Metamodel::diagrams() const
{
	return mDiagrams;
}

void Metamodel::setDiagrams(const QStringList &diagrams)
{
	mDiagrams = diagrams;
}

void Metamodel::addDiagram(const QString &diagramName)
{
	if (!mDiagrams.contains(diagramName)) {
		mDiagrams << diagramName;
	}
}

QList<ElementType *> Metamodel::elements(const QString &diagram) const
{
	return mElements[diagram].values();
}

ElementType &Metamodel::elementType(const Id &id) const
{
	return elementType(id.diagram(), id.element());
}

ElementType &Metamodel::elementType(const QString &diagram, const QString &element) const
{
	Q_ASSERT_X(mElements.contains(diagram) && mElements[diagram].contains(element)
			, Q_FUNC_INFO, "No such entity in metamodel!");
	ElementType * const result = mElements[diagram][element];
	Q_ASSERT_X(result, Q_FUNC_INFO, "No such entity in metamodel!");
	return *result;
}

void Metamodel::addElement(ElementType &element)
{
	addNode(element);
}

QStringList Metamodel::enumNames() const
{
	return mEnumValues.keys();
}

QList<QPair<QString, QString>> Metamodel::enumValues(const QString &name) const
{
	return mEnumValues[name];
}

void Metamodel::addEnum(const QString &name, const QList<QPair<QString, QString> > &values)
{
	for (auto &&value : values) {
		if (!mEnumValues[name].contains(value)) {
			mEnumValues[name] << value;
		}
	}
}

bool Metamodel::isEnumEditable(const QString &name) const
{
	return mEnumsEditability[name];
}

void Metamodel::setEnumEditable(const QString &name, bool editable)
{
	mEnumsEditability[name] = editable;
}

QString Metamodel::friendlyName() const
{
	return mFriendlyName;
}

void Metamodel::setFriendlyName(const QString &friendlyName)
{
	mFriendlyName = friendlyName;
}

QString Metamodel::diagramFriendlyName(const QString &diagram) const
{
	return mDiagramFriendlyNames[diagram];
}

void Metamodel::setDiagramFriendlyName(const QString &diagram, const QString &friendlyName)
{
	mDiagramFriendlyNames[diagram] = friendlyName;
}

ElementType *Metamodel::diagramNode(const QString &diagram) const
{
	return mDiagramNodes[diagram].isEmpty() ? nullptr : &elementType(diagram, mDiagramNodes[diagram]);
}

void Metamodel::setDiagramNode(const QString &diagram, const QString &elementName)
{
	if (!elementName.isEmpty()) {
		mDiagramNodes[diagram] = elementName;
	}
}

QStringList Metamodel::diagramPaletteGroups(const QString &diagram) const
{
	return mPaletteGroups[diagram];
}

void Metamodel::appendDiagramPaletteGroup(const QString &diagram, const QString &group)
{
	if (!mPaletteGroups[diagram].contains(group)) {
		mPaletteGroups[diagram] << group;
	}
}

QStringList Metamodel::diagramPaletteGroupList(const QString &diagram, const QString &group) const
{
	return mPaletteGroupContents[diagram][group];
}

void Metamodel::addElementToDiagramPaletteGroup(const QString &diagram, const QString &group, const QString &element)
{
	mPaletteGroupContents[diagram][group] << element;
}

QString Metamodel::diagramPaletteGroupDescription(const QString &diagram, const QString &group) const
{
	return mPaletteGroupDescriptions[diagram][group];
}

void Metamodel::setDiagramPaletteGroupDescription(const QString &diagram, const QString &group
		, const QString &description)
{
	mPaletteGroupDescriptions[diagram][group] = description;
}

bool Metamodel::shallPaletteBeSorted(const QString &diagram) const
{
	return mPaletteSorting[diagram];
}

void Metamodel::setPaletteSorted(const QString &diagram, bool sorted)
{
	mPaletteSorting[diagram] = sorted;
}

void Metamodel::addNode(qrgraph::Node &entity)
{
	ElementType * const type = dynamic_cast<ElementType *>(&entity);
	Q_ASSERT_X(type, Q_FUNC_INFO, "Attempt to add non-metamodel enitity!");
	Q_ASSERT_X(&type->metamodel() == this, Q_FUNC_INFO, "Attempt to add entity from other metamodel!");

	const QString diagram = type->diagram();
	const QString element = type->name();
	Q_ASSERT_X(!mElements[diagram][element], Q_FUNC_INFO, "Duplicate enitity in metamodel");

	mElements[diagram][element] = type;
	Multigraph::addNode(entity);
}

void Metamodel::addExplosion(ElementType &source, ElementType &target, bool isReusable, bool requiresImmediateLinkage)
{
	Explosion *explosion = new Explosion(*this, isReusable, requiresImmediateLinkage);
	addEdge(*explosion);
	explosion->connectBegin(source);
	explosion->connectEnd(target);
}
<|endoftext|>


<commit_before>#ifndef DEEP_PTR_HPP
#define DEEP_PTR_HPP

#include <memory>

#include "namespace_utils.hpp"

BEGIN_NAMESPACE_ETL

BEGIN_NAMESPACE_UTILS

struct deep_ptr_basic_copy
{
	template <class T> static T* clone(const T& t)
	{
		return new T(t);
	}
};

struct deep_ptr_clone_copy
{
	template <class T> static T* clone(const T& t)
	{
		return t.clone();
	}
};

template <class T, class COPY_POLICY = deep_ptr_basic_copy> class deep_ptr
{
public:
	using ptr_t = std::unique_ptr<T>;
	using pointer = typename ptr_t::pointer;
	using element_type = typename ptr_t::element_type;
	using reference = typename std::add_lvalue_reference<element_type>::type;
	using const_reference = typename std::add_const<reference>::type;

	deep_ptr() noexcept = default;

	deep_ptr(pointer t) noexcept : m_ptr(t)
	{
	}

	template <class U>
	deep_ptr(const deep_ptr<U>& p)
		: m_ptr(p.m_ptr ? COPY_POLICY::clone(*p.m_ptr) : nullptr)
	{
	}

	deep_ptr(const deep_ptr& p) : m_ptr(p.m_ptr ? COPY_POLICY::clone(*p.m_ptr) : nullptr)
	{
	}

	deep_ptr(deep_ptr&&) = default;

	deep_ptr& operator=(const deep_ptr& p)
	{
		m_ptr.reset(p.m_ptr ? COPY_POLICY::clone(*p.m_ptr) : nullptr);
	}

	deep_ptr& operator=(deep_ptr&&) = default;

	reference operator*() noexcept
	{
		return *m_ptr;
	}

	const_reference operator*() const noexcept
	{
		return *m_ptr;
	}

	bool operator==(const deep_ptr& p) const noexcept
	{
		return m_ptr == p.m_ptr;
	}

	bool operator!=(const deep_ptr& p) const noexcept
	{
		return !(*this == p);
	}

	operator bool() const noexcept
	{
		return (bool)m_ptr;
	}

	pointer operator->() const noexcept
	{
		return m_ptr.get();
	}

	pointer get() const noexcept
	{
		return m_ptr.get();
	}

private:
	ptr_t m_ptr;
};

END_NAMESPACE_UTILS

END_NAMESPACE_ETL

#endif // DEEP_PTR_HPP
<commit_msg>small correction on deep_ptr<commit_after>#ifndef DEEP_PTR_HPP
#define DEEP_PTR_HPP

#include <memory>

#include "namespace_utils.hpp"

BEGIN_NAMESPACE_ETL

BEGIN_NAMESPACE_UTILS

struct deep_ptr_basic_copy
{
	template <class T> static T* clone(const T& t)
	{
		return new T(t);
	}
};

struct deep_ptr_clone_copy
{
	template <class T> static T* clone(const T& t)
	{
		return t.clone();
	}
};

template <class T, class COPY_POLICY = deep_ptr_basic_copy> class deep_ptr
{
public:
	using ptr_t = std::unique_ptr<T>;
	using pointer = typename ptr_t::pointer;
	using element_type = typename ptr_t::element_type;
	using reference = typename std::add_lvalue_reference<element_type>::type;
	using const_reference = typename std::add_const<reference>::type;

	deep_ptr() noexcept = default;

	deep_ptr(pointer t) noexcept : m_ptr(t)
	{
	}

	template <class U>
	deep_ptr(const deep_ptr<U>& p)
		: m_ptr(p.m_ptr ? COPY_POLICY::clone(*p.m_ptr) : nullptr)
	{
	}

	deep_ptr(const deep_ptr& p) : m_ptr(p.m_ptr ? COPY_POLICY::clone(*p.m_ptr) : nullptr)
	{
	}

	deep_ptr(deep_ptr&&) = default;

	deep_ptr& operator=(const deep_ptr& p)
	{
		m_ptr.reset(p.m_ptr ? COPY_POLICY::clone(*p.m_ptr) : nullptr);
        return *this;
	}

	deep_ptr& operator=(deep_ptr&&) = default;

	reference operator*() noexcept
	{
		return *m_ptr;
	}

	const_reference operator*() const noexcept
	{
		return *m_ptr;
	}

	bool operator==(const deep_ptr& p) const noexcept
	{
		return m_ptr == p.m_ptr;
	}

	bool operator!=(const deep_ptr& p) const noexcept
	{
		return !(*this == p);
	}

	operator bool() const noexcept
	{
		return (bool)m_ptr;
	}

	pointer operator->() const noexcept
	{
		return m_ptr.get();
	}

	pointer get() const noexcept
	{
		return m_ptr.get();
	}

private:
	ptr_t m_ptr;
};

END_NAMESPACE_UTILS

END_NAMESPACE_ETL

#endif // DEEP_PTR_HPP
<|endoftext|>