<commit_before>/*-----------------------------------------------------------------------------
 This source file is part of Hopsan NG

 Copyright (c) 2011
    Mikael Axin, Robert Braun, Alessandro Dell'Amico, Björn Eriksson,
    Peter Nordin, Karl Pettersson, Petter Krus, Ingo Staack

 This file is provided "as is", with no guarantee or warranty for the
 functionality or reliability of the contents. All contents in this file is
 the original work of the copyright holders at the Division of Fluid and
 Mechatronic Systems (Flumes) at Linköping University. Modifying, using or
 redistributing any part of this file is prohibited without explicit
 permission from the copyright holders.
-----------------------------------------------------------------------------*/

//$Id$

#ifndef MECHANICMULTIPORTTRANSLATIONALMASS_HPP_INCLUDED
#define MECHANICMULTIPORTTRANSLATIONALMASS_HPP_INCLUDED

#include <sstream>
#include <math.h>

#include "ComponentEssentials.h"
#include "ComponentUtilities.h"

namespace hopsan {

    //!
    //! @brief
    //! @ingroup MechanicalComponents
    //!
    class MechanicMultiPortTranslationalMass : public ComponentQ
    {

    private:
        double *mpM, *B, *k, *xMin, *xMax;
        double f1, v1, c1, Zx1, f2, v2, c2, Zx2;                                                    //Node data variables
        double mNum[3];
        double mDen[3];
        DoubleIntegratorWithDamping mIntegrator;
        std::vector<double*> mvpN_f1, mvpN_x1, mvpN_v1, mvpN_me1, mvpN_c1, mvpN_Zx1, mvpN_f2, mvpN_x2, mvpN_v2, mvpN_me2, mvpN_c2, mvpN_Zx2;
        std::vector<double> x1, x2, mvpStartX1, mvpStartX2;
        size_t mNumPorts1, mNumPorts2;
        Port *mpP1, *mpP2;

    public:
        static Component *Creator()
        {
            return new MechanicMultiPortTranslationalMass();
        }

        void configure()
        {
            //Add ports to the component
            mpP1 = addPowerMultiPort("P1", "NodeMechanic");
            mpP2 = addPowerMultiPort("P2", "NodeMechanic");

            //Register changable parameters to the HOPSAN++ core
            addInputVariable("m", "Mass", "kg",                100.0, &mpM);
            addInputVariable("B", "Viscous Friction", "Ns/m",  10.0,  &B);
            //addInputVariable("k", "Spring Coefficient", "N/m", 0.0,   &k);
            //! @todo what about k
            addInputVariable("x_min", "Minimum Position", "m", 0.0,   &xMin);
            addInputVariable("x_max", "Maximum Position", "m", 1.0,   &xMax);
        }

        void initialize()
        {
            mNumPorts1 = mpP1->getNumPorts();
            mNumPorts2 = mpP2->getNumPorts();

            mvpN_f1.resize(mNumPorts1);
            mvpN_x1.resize(mNumPorts1);
            mvpN_v1.resize(mNumPorts1);
            mvpN_me1.resize(mNumPorts1);
            mvpN_c1.resize(mNumPorts1);
            mvpN_Zx1.resize(mNumPorts1);

            mvpN_f2.resize(mNumPorts2);
            mvpN_x2.resize(mNumPorts2);
            mvpN_v2.resize(mNumPorts2);
            mvpN_me2.resize(mNumPorts2);
            mvpN_c2.resize(mNumPorts2);
            mvpN_Zx2.resize(mNumPorts2);

            x1.resize(mNumPorts1);
            x2.resize(mNumPorts2);
            mvpStartX1.resize(mNumPorts1);
            mvpStartX2.resize(mNumPorts2);

            for (size_t i=0; i<mNumPorts1; ++i)
            {
                mvpN_f1[i]  = getSafeMultiPortNodeDataPtr(mpP1, i, NodeMechanic::FORCE);
                mvpN_x1[i]  = getSafeMultiPortNodeDataPtr(mpP1, i, NodeMechanic::Position);
                mvpN_v1[i]  = getSafeMultiPortNodeDataPtr(mpP1, i, NodeMechanic::Velocity);
                mvpN_me1[i]  = getSafeMultiPortNodeDataPtr(mpP1, i, NodeMechanic::EquivalentMass);
                mvpN_c1[i]  = getSafeMultiPortNodeDataPtr(mpP1, i, NodeMechanic::WaveVariable);
                mvpN_Zx1[i] = getSafeMultiPortNodeDataPtr(mpP1, i, NodeMechanic::CharImpedance);
            }

            for (size_t i=0; i<mNumPorts2; ++i)
            {
                mvpN_f2[i]  = getSafeMultiPortNodeDataPtr(mpP2, i, NodeMechanic::Force);
                mvpN_x2[i]  = getSafeMultiPortNodeDataPtr(mpP2, i, NodeMechanic::Position);
                mvpN_v2[i]  = getSafeMultiPortNodeDataPtr(mpP2, i, NodeMechanic::Velocity);
                mvpN_me2[i]  = getSafeMultiPortNodeDataPtr(mpP2, i, NodeMechanic::EquivalentMass);
                mvpN_c2[i]  = getSafeMultiPortNodeDataPtr(mpP2, i, NodeMechanic::WaveVariable);
                mvpN_Zx2[i] = getSafeMultiPortNodeDataPtr(mpP2, i, NodeMechanic::CharImpedance);
            }

            //Initialization
            f1 = 0;
            for (size_t i=0; i<mNumPorts1; ++i)
            {
                f1 += (*mvpN_f1[i]);
            }

            f2 = 0;
            for (size_t i=0; i<mNumPorts2; ++i)
            {
                f2 += (*mvpN_f2[i]);
            }

            for (size_t i=0; i<mNumPorts1; ++i)
            {
                x1[i] = (*mvpN_x1[i]);
                mvpStartX1[i]= (*mvpN_x1[i]);
            }

            for (size_t i=0; i<mNumPorts2; ++i)
            {
                x2[i] = (*mvpN_x2[i]);
                mvpStartX2[i] = (*mvpN_x2[i]);
            }

            v1 = (*mvpN_v1[0]);
            for(size_t i=0; i<mNumPorts1; ++i)
            {
                if(v1 != (*mvpN_v1[i]))
                {
                    addErrorMessage("Velocities in multiport does not match, {"+getName()+"::"+mpP1->getName());
                    stopSimulation();
                }
            }

            v2 = (*mvpN_v2[0]);
            for(size_t i=0; i<mNumPorts2; ++i)
            {
                if(v2 != (*mvpN_v2[i]))
                {
                    addWarningMessage("Velocities in multiport does not match, {"+getName()+"::"+mpP2->getName());
                    stopSimulation();
                }
            }

            mIntegrator.initialize(mTimestep, 0, 0, 0, 0);

            //Print debug message if velocities do not match
            if(v1 != -v2)
            {
                addWarningMessage("Start velocities does not match, {"+getName()+"::"+mpP1->getName()+
                                  "} and {"+getName()+"::"+mpP2->getName()+"}.");
                stopSimulation();
            }

            for (size_t i=0; i<mNumPorts1; ++i)
            {
                (*mvpN_me1[i]) = (*mpM);
            }
            for (size_t i=0; i<mNumPorts2; ++i)
            {
                (*mvpN_me2[i]) = (*mpM);
            }
        }

        void simulateOneTimestep()
        {
            //Get variable values from nodes
            c1 = 0;
            for (size_t i=0; i<mNumPorts1; ++i)
            {
                c1 += (*mvpN_c1[i]);
            }
            Zx1 = 0;
            for (size_t i=0; i<mNumPorts1; ++i)
            {
                Zx1 += (*mvpN_Zx1[i]);
            }
            c2 = 0;
            for (size_t i=0; i<mNumPorts2; ++i)
            {
                c2 += (*mvpN_c2[i]);
            }
            Zx2 = 0;
            for (size_t i=0; i<mNumPorts2; ++i)
            {
                Zx2 += (*mvpN_Zx2[i]);
            }

            const double m = (*mpM);

            mIntegrator.setDamping(((*B)+Zx1+Zx2) / m * mTimestep);
            mIntegrator.integrateWithUndo((c1-c2)/m);
            v2 = mIntegrator.valueFirst();
            double x_nom = mIntegrator.valueSecond();

            if(x_nom<(*xMin))
            {
                x_nom=(*xMin);
                v2=std::max(0.0, v2);
                mIntegrator.initializeValues(0.0, x_nom, v2);
            }
            if(x_nom>(*xMax))
            {
                x_nom=(*xMax);
                v2=std::min(0.0, v2);
                mIntegrator.initializeValues(0.0, x_nom, v2);
            }

            v1 = -v2;

            //Write new values to nodes

            for (size_t i=0; i<mNumPorts1; ++i)
            {
                (*mvpN_f1[i]) = (*mvpN_c1[i]) + (*mvpN_Zx1[i])*v1;
            }
            for (size_t i=0; i<mNumPorts2; ++i)
            {
                (*mvpN_f2[i]) = (*mvpN_c2[i]) + (*mvpN_Zx2[i])*v2;
            }

            for (size_t i=0; i<mNumPorts1; ++i)
            {
                (*mvpN_x1[i]) = mvpStartX1[i]+mvpStartX2[0]-x_nom;
            }
            for (size_t i=0; i<mNumPorts2; ++i)
            {
                (*mvpN_x2[i]) = mvpStartX2[i]-mvpStartX2[0]+x_nom;
            }

            for (size_t i=0; i<mNumPorts1; ++i)
            {
                (*mvpN_v1[i]) = v1;
            }
            for (size_t i=0; i<mNumPorts2; ++i)
            {
                (*mvpN_v2[i]) = v2;
            }
            for (size_t i=0; i<mNumPorts1; ++i)
            {
                (*mvpN_me1[i]) = m;
            }
            for (size_t i=0; i<mNumPorts2; ++i)
            {
                (*mvpN_me2[i]) = m;
            }
        }
    };
}

#endif // MECHANICMULTIPORTTRANSLATIONALMASS_HPP_INCLUDED

<commit_msg>Made sure translational multi-port mass does not override start values. Resolvse #1012.<commit_after>/*-----------------------------------------------------------------------------
 This source file is part of Hopsan NG

 Copyright (c) 2011
    Mikael Axin, Robert Braun, Alessandro Dell'Amico, Björn Eriksson,
    Peter Nordin, Karl Pettersson, Petter Krus, Ingo Staack

 This file is provided "as is", with no guarantee or warranty for the
 functionality or reliability of the contents. All contents in this file is
 the original work of the copyright holders at the Division of Fluid and
 Mechatronic Systems (Flumes) at Linköping University. Modifying, using or
 redistributing any part of this file is prohibited without explicit
 permission from the copyright holders.
-----------------------------------------------------------------------------*/

//$Id$

#ifndef MECHANICMULTIPORTTRANSLATIONALMASS_HPP_INCLUDED
#define MECHANICMULTIPORTTRANSLATIONALMASS_HPP_INCLUDED

#include <sstream>
#include <math.h>

#include "ComponentEssentials.h"
#include "ComponentUtilities.h"

namespace hopsan {

    //!
    //! @brief
    //! @ingroup MechanicalComponents
    //!
    class MechanicMultiPortTranslationalMass : public ComponentQ
    {

    private:
        double *mpM, *B, *k, *xMin, *xMax;
        double f1, v1, c1, Zx1, f2, v2, c2, Zx2;                                                    //Node data variables
        double mNum[3];
        double mDen[3];
        DoubleIntegratorWithDamping mIntegrator;
        std::vector<double*> mvpN_f1, mvpN_x1, mvpN_v1, mvpN_me1, mvpN_c1, mvpN_Zx1, mvpN_f2, mvpN_x2, mvpN_v2, mvpN_me2, mvpN_c2, mvpN_Zx2;
        std::vector<double> x1, x2, mvpStartX1, mvpStartX2;
        size_t mNumPorts1, mNumPorts2;
        Port *mpP1, *mpP2;

    public:
        static Component *Creator()
        {
            return new MechanicMultiPortTranslationalMass();
        }

        void configure()
        {
            //Add ports to the component
            mpP1 = addPowerMultiPort("P1", "NodeMechanic");
            mpP2 = addPowerMultiPort("P2", "NodeMechanic");

            //Register changable parameters to the HOPSAN++ core
            addInputVariable("m", "Mass", "kg",                100.0, &mpM);
            addInputVariable("B", "Viscous Friction", "Ns/m",  10.0,  &B);
            //addInputVariable("k", "Spring Coefficient", "N/m", 0.0,   &k);
            //! @todo what about k
            addInputVariable("x_min", "Minimum Position", "m", 0.0,   &xMin);
            addInputVariable("x_max", "Maximum Position", "m", 1.0,   &xMax);
        }

        void initialize()
        {
            mNumPorts1 = mpP1->getNumPorts();
            mNumPorts2 = mpP2->getNumPorts();

            mvpN_f1.resize(mNumPorts1);
            mvpN_x1.resize(mNumPorts1);
            mvpN_v1.resize(mNumPorts1);
            mvpN_me1.resize(mNumPorts1);
            mvpN_c1.resize(mNumPorts1);
            mvpN_Zx1.resize(mNumPorts1);

            mvpN_f2.resize(mNumPorts2);
            mvpN_x2.resize(mNumPorts2);
            mvpN_v2.resize(mNumPorts2);
            mvpN_me2.resize(mNumPorts2);
            mvpN_c2.resize(mNumPorts2);
            mvpN_Zx2.resize(mNumPorts2);

            x1.resize(mNumPorts1);
            x2.resize(mNumPorts2);
            mvpStartX1.resize(mNumPorts1);
            mvpStartX2.resize(mNumPorts2);

            for (size_t i=0; i<mNumPorts1; ++i)
            {
                mvpN_f1[i]  = getSafeMultiPortNodeDataPtr(mpP1, i, NodeMechanic::FORCE);
                mvpN_x1[i]  = getSafeMultiPortNodeDataPtr(mpP1, i, NodeMechanic::Position);
                mvpN_v1[i]  = getSafeMultiPortNodeDataPtr(mpP1, i, NodeMechanic::Velocity);
                mvpN_me1[i]  = getSafeMultiPortNodeDataPtr(mpP1, i, NodeMechanic::EquivalentMass);
                mvpN_c1[i]  = getSafeMultiPortNodeDataPtr(mpP1, i, NodeMechanic::WaveVariable);
                mvpN_Zx1[i] = getSafeMultiPortNodeDataPtr(mpP1, i, NodeMechanic::CharImpedance);
            }

            for (size_t i=0; i<mNumPorts2; ++i)
            {
                mvpN_f2[i]  = getSafeMultiPortNodeDataPtr(mpP2, i, NodeMechanic::Force);
                mvpN_x2[i]  = getSafeMultiPortNodeDataPtr(mpP2, i, NodeMechanic::Position);
                mvpN_v2[i]  = getSafeMultiPortNodeDataPtr(mpP2, i, NodeMechanic::Velocity);
                mvpN_me2[i]  = getSafeMultiPortNodeDataPtr(mpP2, i, NodeMechanic::EquivalentMass);
                mvpN_c2[i]  = getSafeMultiPortNodeDataPtr(mpP2, i, NodeMechanic::WaveVariable);
                mvpN_Zx2[i] = getSafeMultiPortNodeDataPtr(mpP2, i, NodeMechanic::CharImpedance);
            }

            //Initialization
            f1 = 0;
            for (size_t i=0; i<mNumPorts1; ++i)
            {
                f1 += (*mvpN_f1[i]);
            }

            f2 = 0;
            for (size_t i=0; i<mNumPorts2; ++i)
            {
                f2 += (*mvpN_f2[i]);
            }

            for (size_t i=0; i<mNumPorts1; ++i)
            {
                x1[i] = (*mvpN_x1[i]);
                mvpStartX1[i]= (*mvpN_x1[i]);
            }

            for (size_t i=0; i<mNumPorts2; ++i)
            {
                x2[i] = (*mvpN_x2[i]);
                mvpStartX2[i] = (*mvpN_x2[i]);
            }

            v1 = (*mvpN_v1[0]);
            for(size_t i=0; i<mNumPorts1; ++i)
            {
                if(v1 != (*mvpN_v1[i]))
                {
                    addErrorMessage("Velocities in multiport does not match, {"+getName()+"::"+mpP1->getName());
                    stopSimulation();
                }
            }

            v2 = (*mvpN_v2[0]);
            for(size_t i=0; i<mNumPorts2; ++i)
            {
                if(v2 != (*mvpN_v2[i]))
                {
                    addWarningMessage("Velocities in multiport does not match, {"+getName()+"::"+mpP2->getName());
                    stopSimulation();
                }
            }

            mIntegrator.initialize(mTimestep, 0, 0, x2[0], v2);

            //Print debug message if velocities do not match
            if(v1 != -v2)
            {
                addWarningMessage("Start velocities does not match, {"+getName()+"::"+mpP1->getName()+
                                  "} and {"+getName()+"::"+mpP2->getName()+"}.");
                stopSimulation();
            }

            for (size_t i=0; i<mNumPorts1; ++i)
            {
                (*mvpN_me1[i]) = (*mpM);
            }
            for (size_t i=0; i<mNumPorts2; ++i)
            {
                (*mvpN_me2[i]) = (*mpM);
            }
        }

        void simulateOneTimestep()
        {
            //Get variable values from nodes
            c1 = 0;
            for (size_t i=0; i<mNumPorts1; ++i)
            {
                c1 += (*mvpN_c1[i]);
            }
            Zx1 = 0;
            for (size_t i=0; i<mNumPorts1; ++i)
            {
                Zx1 += (*mvpN_Zx1[i]);
            }
            c2 = 0;
            for (size_t i=0; i<mNumPorts2; ++i)
            {
                c2 += (*mvpN_c2[i]);
            }
            Zx2 = 0;
            for (size_t i=0; i<mNumPorts2; ++i)
            {
                Zx2 += (*mvpN_Zx2[i]);
            }

            const double m = (*mpM);

            mIntegrator.setDamping(((*B)+Zx1+Zx2) / m * mTimestep);
            mIntegrator.integrateWithUndo((c1-c2)/m);
            v2 = mIntegrator.valueFirst();
            double x_nom = mIntegrator.valueSecond();

            if(x_nom<(*xMin))
            {
                x_nom=(*xMin);
                v2=std::max(0.0, v2);
                mIntegrator.initializeValues(0.0, x_nom, v2);
            }
            if(x_nom>(*xMax))
            {
                x_nom=(*xMax);
                v2=std::min(0.0, v2);
                mIntegrator.initializeValues(0.0, x_nom, v2);
            }

            v1 = -v2;

            //Write new values to nodes

            for (size_t i=0; i<mNumPorts1; ++i)
            {
                (*mvpN_f1[i]) = (*mvpN_c1[i]) + (*mvpN_Zx1[i])*v1;
            }
            for (size_t i=0; i<mNumPorts2; ++i)
            {
                (*mvpN_f2[i]) = (*mvpN_c2[i]) + (*mvpN_Zx2[i])*v2;
            }

            for (size_t i=0; i<mNumPorts1; ++i)
            {
                (*mvpN_x1[i]) = mvpStartX1[i]+mvpStartX2[0]-x_nom;
            }
            for (size_t i=0; i<mNumPorts2; ++i)
            {
                (*mvpN_x2[i]) = mvpStartX2[i]-mvpStartX2[0]+x_nom;
            }

            for (size_t i=0; i<mNumPorts1; ++i)
            {
                (*mvpN_v1[i]) = v1;
            }
            for (size_t i=0; i<mNumPorts2; ++i)
            {
                (*mvpN_v2[i]) = v2;
            }
            for (size_t i=0; i<mNumPorts1; ++i)
            {
                (*mvpN_me1[i]) = m;
            }
            for (size_t i=0; i<mNumPorts2; ++i)
            {
                (*mvpN_me2[i]) = m;
            }
        }
    };
}

#endif // MECHANICMULTIPORTTRANSLATIONALMASS_HPP_INCLUDED

<|endoftext|>


<commit_before>/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 1999-2001 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xalan" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */
// Class header file.
#include "XalanSourceTreeParserLiaison.hpp"

#include <algorithm>

#include <sax2/XMLReaderFactory.hpp>

#include <Include/XalanAutoPtr.hpp>
#include <Include/STLHelper.hpp>

#include <PlatformSupport/XalanUnicode.hpp>

#include "XalanSourceTreeContentHandler.hpp"
#include "XalanSourceTreeDOMSupport.hpp"
#include "XalanSourceTreeDocument.hpp"

// http://xml.org/sax/features/validation
const XalanDOMChar	XalanSourceTreeParserLiaison::validationString[] = {
	XalanUnicode::charLetter_h,
	XalanUnicode::charLetter_t,
	XalanUnicode::charLetter_t,
	XalanUnicode::charLetter_p,
	XalanUnicode::charColon,
	XalanUnicode::charSolidus,
	XalanUnicode::charSolidus,
	XalanUnicode::charLetter_x,
	XalanUnicode::charLetter_m,
	XalanUnicode::charLetter_l,
	XalanUnicode::charFullStop,
	XalanUnicode::charLetter_o,
	XalanUnicode::charLetter_r,
	XalanUnicode::charLetter_g,
	XalanUnicode::charSolidus,
	XalanUnicode::charLetter_s,
	XalanUnicode::charLetter_a,
	XalanUnicode::charLetter_x,
	XalanUnicode::charSolidus,
	XalanUnicode::charLetter_f,
	XalanUnicode::charLetter_e,
	XalanUnicode::charLetter_a,
	XalanUnicode::charLetter_t,
	XalanUnicode::charLetter_u,
	XalanUnicode::charLetter_r,
	XalanUnicode::charLetter_e,
	XalanUnicode::charLetter_s,
	XalanUnicode::charSolidus,
	XalanUnicode::charLetter_v,
	XalanUnicode::charLetter_a,
	XalanUnicode::charLetter_l,
	XalanUnicode::charLetter_i,
	XalanUnicode::charLetter_d,
	XalanUnicode::charLetter_a,
	XalanUnicode::charLetter_t,
	XalanUnicode::charLetter_i,
	XalanUnicode::charLetter_o,
	XalanUnicode::charLetter_n,
	0
};

XalanSourceTreeParserLiaison::XalanSourceTreeParserLiaison(
			XalanSourceTreeDOMSupport&	/* theSupport */,
			DocumentNumberType			theStartingNumber) :
	m_documentNumber(theStartingNumber),
	m_xercesParserLiaison(),
	m_documentMap(),
	m_persistentDocumentMap(),
	m_poolAllText(true)
{
}

XalanSourceTreeParserLiaison::XalanSourceTreeParserLiaison(DocumentNumberType	theStartingNumber) :
	m_documentNumber(theStartingNumber),
	m_xercesParserLiaison(),
	m_documentMap(),
	m_persistentDocumentMap(),
	m_poolAllText(true)
{
}

XalanSourceTreeParserLiaison::~XalanSourceTreeParserLiaison()
{
	reset();

#if !defined(XALAN_NO_NAMESPACES)
	using std::for_each;
#endif

	// Delete any persistent documents.
	for_each(m_persistentDocumentMap.begin(),
			 m_persistentDocumentMap.end(),
			 makeMapValueDeleteFunctor(m_persistentDocumentMap));

	m_persistentDocumentMap.clear();
}

void
XalanSourceTreeParserLiaison::reset()
{
#if !defined(XALAN_NO_NAMESPACES)
	using std::for_each;
#endif

	// Delete any documents.
	for_each(m_documentMap.begin(),
			 m_documentMap.end(),
			 makeMapValueDeleteFunctor(m_documentMap));

	m_documentMap.clear();

	m_xercesParserLiaison.reset();
}

ExecutionContext*
XalanSourceTreeParserLiaison::getExecutionContext() const
{
	return m_xercesParserLiaison.getExecutionContext();
}

void
XalanSourceTreeParserLiaison::setExecutionContext(ExecutionContext&		theContext)
{
	m_xercesParserLiaison.setExecutionContext(theContext);
}

void
XalanSourceTreeParserLiaison::parseXMLStream(
			const InputSource&		inputSource,
			DocumentHandler&		handler,
			const XalanDOMString&	identifier)
{
	m_xercesParserLiaison.parseXMLStream(inputSource, handler, identifier);
}

XalanDocument*
XalanSourceTreeParserLiaison::parseXMLStream(
			const InputSource&		inputSource,
			const XalanDOMString&	/* identifier */)
{
	XalanSourceTreeContentHandler	theContentHandler(createXalanSourceTreeDocument());

	XalanAutoPtr<SAX2XMLReader>		theReader(XMLReaderFactory::createXMLReader());

	theReader->setFeature(
		validationString,
		m_xercesParserLiaison.getUseValidation());

	theReader->setContentHandler(&theContentHandler);

	theReader->setDTDHandler(&theContentHandler);

	ErrorHandler* const		theHandler = getErrorHandler();

	if (theHandler == 0)
	{
		theReader->setErrorHandler(&m_xercesParserLiaison);
	}
	else
	{
		theReader->setErrorHandler(theHandler);
	}

	theReader->setLexicalHandler(&theContentHandler);

	theReader->setEntityResolver(getEntityResolver());

	theReader->parse(inputSource);

	return theContentHandler.getDocument();
}

XalanDocument*
XalanSourceTreeParserLiaison::createDocument()
{
	return createXalanSourceTreeDocument();
}

XalanDocument*
XalanSourceTreeParserLiaison::createDOMFactory()
{
	return m_xercesParserLiaison.createDocument();
}

void
XalanSourceTreeParserLiaison::destroyDocument(XalanDocument*		theDocument)
{
	if (mapDocument(theDocument) != 0)
	{
		m_documentMap.erase(theDocument);

		delete theDocument;
	}
}

XalanSourceTreeParserLiaison::DocumentNumberType
XalanSourceTreeParserLiaison::getNextDocumentNumber()
{
	return m_documentNumber++;
}

int
XalanSourceTreeParserLiaison::getIndent() const
{
	return m_xercesParserLiaison.getIndent();
}

void
XalanSourceTreeParserLiaison::setIndent(int		i)
{
	m_xercesParserLiaison.setIndent(i);
}

bool
XalanSourceTreeParserLiaison::getUseValidation() const
{
	return m_xercesParserLiaison.getUseValidation();
}

void
XalanSourceTreeParserLiaison::setUseValidation(bool		b)
{
	m_xercesParserLiaison.setUseValidation(b);
}

const XalanDOMString
XalanSourceTreeParserLiaison::getParserDescription() const
{
	return StaticStringToDOMString(XALAN_STATIC_UCODE_STRING("XalanSourceTree"));
}

void
XalanSourceTreeParserLiaison::parseXMLStream(
			const InputSource&		theInputSource,
			ContentHandler&			theContentHandler,
			DTDHandler*				theDTDHandler,
			LexicalHandler*			theLexicalHandler,
			const XalanDOMString&	/* theIdentifier */)
{
	XalanAutoPtr<SAX2XMLReader>		theReader(XMLReaderFactory::createXMLReader());

	theReader->setFeature(
		validationString,
		m_xercesParserLiaison.getUseValidation());

	theReader->setContentHandler(&theContentHandler);

	theReader->setDTDHandler(theDTDHandler);

	ErrorHandler* const		theHandler = getErrorHandler();

	if (theHandler == 0)
	{
		theReader->setErrorHandler(&m_xercesParserLiaison);
	}
	else
	{
		theReader->setErrorHandler(theHandler);
	}

	theReader->setLexicalHandler(theLexicalHandler);

	EntityResolver* const	theResolver = getEntityResolver();

	if (theResolver != 0)
	{
		theReader->setEntityResolver(theResolver);
	}

	theReader->parse(theInputSource);
}

bool
XalanSourceTreeParserLiaison::getIncludeIgnorableWhitespace() const
{
	return m_xercesParserLiaison.getIncludeIgnorableWhitespace();
}

void
XalanSourceTreeParserLiaison::setIncludeIgnorableWhitespace(bool	include)
{
	m_xercesParserLiaison.setIncludeIgnorableWhitespace(include);
}

ErrorHandler*
XalanSourceTreeParserLiaison::getErrorHandler() const
{
	return m_xercesParserLiaison.getErrorHandler();
}

void
XalanSourceTreeParserLiaison::setErrorHandler(ErrorHandler*	handler)
{
	m_xercesParserLiaison.setErrorHandler(handler);
}

bool
XalanSourceTreeParserLiaison::getDoNamespaces() const
{
	return m_xercesParserLiaison.getDoNamespaces();
}

void
XalanSourceTreeParserLiaison::setDoNamespaces(bool	newState)
{
	m_xercesParserLiaison.setDoNamespaces(newState);
}

bool
XalanSourceTreeParserLiaison::getExitOnFirstFatalError() const
{
	return m_xercesParserLiaison.getExitOnFirstFatalError();
}

void
XalanSourceTreeParserLiaison::setExitOnFirstFatalError(bool		newState)
{
	m_xercesParserLiaison.setExitOnFirstFatalError(newState);
}

EntityResolver*
XalanSourceTreeParserLiaison::getEntityResolver() const
{
	return m_xercesParserLiaison.getEntityResolver();
}

void
XalanSourceTreeParserLiaison::setEntityResolver(EntityResolver*	resolver)
{
	m_xercesParserLiaison.setEntityResolver(resolver);
}

XalanSourceTreeDocument*
XalanSourceTreeParserLiaison::mapDocument(const XalanDocument*	theDocument) const
{
	DocumentMapType::const_iterator		i =
		m_documentMap.find(theDocument);

	if (i != m_documentMap.end())
	{
		return (*i).second;
	}
	else
	{
		i =	m_persistentDocumentMap.find(theDocument);

		if (i != m_persistentDocumentMap.end())
		{
			return (*i).second;
		}
		else
		{
			return 0;
		}
	}
}

XalanSourceTreeDocument*
XalanSourceTreeParserLiaison::createXalanSourceTreeDocument()
{
	XalanSourceTreeDocument* const	theNewDocument =
		new XalanSourceTreeDocument(getNextDocumentNumber(), m_poolAllText);

	m_documentMap[theNewDocument] = theNewDocument;

	return theNewDocument;
}

bool
XalanSourceTreeParserLiaison::setPersistent(XalanSourceTreeDocument*	theDocument)
{
	const DocumentMapType::iterator		i =
		m_documentMap.find(theDocument);

	if (i != m_documentMap.end())
	{
		return false;
	}
	else
	{
		m_persistentDocumentMap[(*i).first] = (*i).second;

		m_documentMap.erase(i);

		return true;
	}
}

bool
XalanSourceTreeParserLiaison::unsetPersistent(XalanSourceTreeDocument*	theDocument)
{
	const DocumentMapType::iterator		i =
		m_persistentDocumentMap.find(theDocument);

	if (i != m_persistentDocumentMap.end())
	{
		return false;
	}
	else
	{
		m_documentMap[(*i).first] = (*i).second;

		m_persistentDocumentMap.erase(i);

		return true;
	}
}
<commit_msg>Chain up to XercesParserLiaison member.<commit_after>/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 1999-2001 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xalan" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */
// Class header file.
#include "XalanSourceTreeParserLiaison.hpp"

#include <algorithm>

#include <sax2/XMLReaderFactory.hpp>

#include <Include/XalanAutoPtr.hpp>
#include <Include/STLHelper.hpp>

#include <PlatformSupport/XalanUnicode.hpp>

#include "XalanSourceTreeContentHandler.hpp"
#include "XalanSourceTreeDOMSupport.hpp"
#include "XalanSourceTreeDocument.hpp"

// http://xml.org/sax/features/validation
const XalanDOMChar	XalanSourceTreeParserLiaison::validationString[] = {
	XalanUnicode::charLetter_h,
	XalanUnicode::charLetter_t,
	XalanUnicode::charLetter_t,
	XalanUnicode::charLetter_p,
	XalanUnicode::charColon,
	XalanUnicode::charSolidus,
	XalanUnicode::charSolidus,
	XalanUnicode::charLetter_x,
	XalanUnicode::charLetter_m,
	XalanUnicode::charLetter_l,
	XalanUnicode::charFullStop,
	XalanUnicode::charLetter_o,
	XalanUnicode::charLetter_r,
	XalanUnicode::charLetter_g,
	XalanUnicode::charSolidus,
	XalanUnicode::charLetter_s,
	XalanUnicode::charLetter_a,
	XalanUnicode::charLetter_x,
	XalanUnicode::charSolidus,
	XalanUnicode::charLetter_f,
	XalanUnicode::charLetter_e,
	XalanUnicode::charLetter_a,
	XalanUnicode::charLetter_t,
	XalanUnicode::charLetter_u,
	XalanUnicode::charLetter_r,
	XalanUnicode::charLetter_e,
	XalanUnicode::charLetter_s,
	XalanUnicode::charSolidus,
	XalanUnicode::charLetter_v,
	XalanUnicode::charLetter_a,
	XalanUnicode::charLetter_l,
	XalanUnicode::charLetter_i,
	XalanUnicode::charLetter_d,
	XalanUnicode::charLetter_a,
	XalanUnicode::charLetter_t,
	XalanUnicode::charLetter_i,
	XalanUnicode::charLetter_o,
	XalanUnicode::charLetter_n,
	0
};

XalanSourceTreeParserLiaison::XalanSourceTreeParserLiaison(
			XalanSourceTreeDOMSupport&	/* theSupport */,
			DocumentNumberType			theStartingNumber) :
	m_documentNumber(theStartingNumber),
	m_xercesParserLiaison(),
	m_documentMap(),
	m_persistentDocumentMap(),
	m_poolAllText(true)
{
}

XalanSourceTreeParserLiaison::XalanSourceTreeParserLiaison(DocumentNumberType	theStartingNumber) :
	m_documentNumber(theStartingNumber),
	m_xercesParserLiaison(),
	m_documentMap(),
	m_persistentDocumentMap(),
	m_poolAllText(true)
{
}

XalanSourceTreeParserLiaison::~XalanSourceTreeParserLiaison()
{
	reset();

#if !defined(XALAN_NO_NAMESPACES)
	using std::for_each;
#endif

	// Delete any persistent documents.
	for_each(m_persistentDocumentMap.begin(),
			 m_persistentDocumentMap.end(),
			 makeMapValueDeleteFunctor(m_persistentDocumentMap));

	m_persistentDocumentMap.clear();
}

void
XalanSourceTreeParserLiaison::reset()
{
#if !defined(XALAN_NO_NAMESPACES)
	using std::for_each;
#endif

	// Delete any documents.
	for_each(m_documentMap.begin(),
			 m_documentMap.end(),
			 makeMapValueDeleteFunctor(m_documentMap));

	m_documentMap.clear();

	m_xercesParserLiaison.reset();
}

ExecutionContext*
XalanSourceTreeParserLiaison::getExecutionContext() const
{
	return m_xercesParserLiaison.getExecutionContext();
}

void
XalanSourceTreeParserLiaison::setExecutionContext(ExecutionContext&		theContext)
{
	m_xercesParserLiaison.setExecutionContext(theContext);
}

void
XalanSourceTreeParserLiaison::parseXMLStream(
			const InputSource&		inputSource,
			DocumentHandler&		handler,
			const XalanDOMString&	identifier)
{
	m_xercesParserLiaison.parseXMLStream(inputSource, handler, identifier);
}

XalanDocument*
XalanSourceTreeParserLiaison::parseXMLStream(
			const InputSource&		inputSource,
			const XalanDOMString&	/* identifier */)
{
	XalanSourceTreeContentHandler	theContentHandler(createXalanSourceTreeDocument());

	XalanAutoPtr<SAX2XMLReader>		theReader(XMLReaderFactory::createXMLReader());

	theReader->setFeature(
		validationString,
		m_xercesParserLiaison.getUseValidation());

	theReader->setContentHandler(&theContentHandler);

	theReader->setDTDHandler(&theContentHandler);

	ErrorHandler* const		theHandler = getErrorHandler();

	if (theHandler == 0)
	{
		theReader->setErrorHandler(&m_xercesParserLiaison);
	}
	else
	{
		theReader->setErrorHandler(theHandler);
	}

	theReader->setLexicalHandler(&theContentHandler);

	theReader->setEntityResolver(getEntityResolver());

	theReader->parse(inputSource);

	return theContentHandler.getDocument();
}

XalanDocument*
XalanSourceTreeParserLiaison::createDocument()
{
	return createXalanSourceTreeDocument();
}

XalanDocument*
XalanSourceTreeParserLiaison::createDOMFactory()
{
	return m_xercesParserLiaison.createDocument();
}

void
XalanSourceTreeParserLiaison::destroyDocument(XalanDocument*	theDocument)
{
	if (mapDocument(theDocument) != 0)
	{
		m_documentMap.erase(theDocument);

		delete theDocument;
	}
	else
	{
		m_xercesParserLiaison.destroyDocument(theDocument);
	}
}

XalanSourceTreeParserLiaison::DocumentNumberType
XalanSourceTreeParserLiaison::getNextDocumentNumber()
{
	return m_documentNumber++;
}

int
XalanSourceTreeParserLiaison::getIndent() const
{
	return m_xercesParserLiaison.getIndent();
}

void
XalanSourceTreeParserLiaison::setIndent(int		i)
{
	m_xercesParserLiaison.setIndent(i);
}

bool
XalanSourceTreeParserLiaison::getUseValidation() const
{
	return m_xercesParserLiaison.getUseValidation();
}

void
XalanSourceTreeParserLiaison::setUseValidation(bool		b)
{
	m_xercesParserLiaison.setUseValidation(b);
}

const XalanDOMString
XalanSourceTreeParserLiaison::getParserDescription() const
{
	return StaticStringToDOMString(XALAN_STATIC_UCODE_STRING("XalanSourceTree"));
}

void
XalanSourceTreeParserLiaison::parseXMLStream(
			const InputSource&		theInputSource,
			ContentHandler&			theContentHandler,
			DTDHandler*				theDTDHandler,
			LexicalHandler*			theLexicalHandler,
			const XalanDOMString&	/* theIdentifier */)
{
	XalanAutoPtr<SAX2XMLReader>		theReader(XMLReaderFactory::createXMLReader());

	theReader->setFeature(
		validationString,
		m_xercesParserLiaison.getUseValidation());

	theReader->setContentHandler(&theContentHandler);

	theReader->setDTDHandler(theDTDHandler);

	ErrorHandler* const		theHandler = getErrorHandler();

	if (theHandler == 0)
	{
		theReader->setErrorHandler(&m_xercesParserLiaison);
	}
	else
	{
		theReader->setErrorHandler(theHandler);
	}

	theReader->setLexicalHandler(theLexicalHandler);

	EntityResolver* const	theResolver = getEntityResolver();

	if (theResolver != 0)
	{
		theReader->setEntityResolver(theResolver);
	}

	theReader->parse(theInputSource);
}

bool
XalanSourceTreeParserLiaison::getIncludeIgnorableWhitespace() const
{
	return m_xercesParserLiaison.getIncludeIgnorableWhitespace();
}

void
XalanSourceTreeParserLiaison::setIncludeIgnorableWhitespace(bool	include)
{
	m_xercesParserLiaison.setIncludeIgnorableWhitespace(include);
}

ErrorHandler*
XalanSourceTreeParserLiaison::getErrorHandler() const
{
	return m_xercesParserLiaison.getErrorHandler();
}

void
XalanSourceTreeParserLiaison::setErrorHandler(ErrorHandler*	handler)
{
	m_xercesParserLiaison.setErrorHandler(handler);
}

bool
XalanSourceTreeParserLiaison::getDoNamespaces() const
{
	return m_xercesParserLiaison.getDoNamespaces();
}

void
XalanSourceTreeParserLiaison::setDoNamespaces(bool	newState)
{
	m_xercesParserLiaison.setDoNamespaces(newState);
}

bool
XalanSourceTreeParserLiaison::getExitOnFirstFatalError() const
{
	return m_xercesParserLiaison.getExitOnFirstFatalError();
}

void
XalanSourceTreeParserLiaison::setExitOnFirstFatalError(bool		newState)
{
	m_xercesParserLiaison.setExitOnFirstFatalError(newState);
}

EntityResolver*
XalanSourceTreeParserLiaison::getEntityResolver() const
{
	return m_xercesParserLiaison.getEntityResolver();
}

void
XalanSourceTreeParserLiaison::setEntityResolver(EntityResolver*	resolver)
{
	m_xercesParserLiaison.setEntityResolver(resolver);
}

XalanSourceTreeDocument*
XalanSourceTreeParserLiaison::mapDocument(const XalanDocument*	theDocument) const
{
	DocumentMapType::const_iterator		i =
		m_documentMap.find(theDocument);

	if (i != m_documentMap.end())
	{
		return (*i).second;
	}
	else
	{
		i =	m_persistentDocumentMap.find(theDocument);

		if (i != m_persistentDocumentMap.end())
		{
			return (*i).second;
		}
		else
		{
			return 0;
		}
	}
}

XalanSourceTreeDocument*
XalanSourceTreeParserLiaison::createXalanSourceTreeDocument()
{
	XalanSourceTreeDocument* const	theNewDocument =
		new XalanSourceTreeDocument(getNextDocumentNumber(), m_poolAllText);

	m_documentMap[theNewDocument] = theNewDocument;

	return theNewDocument;
}

bool
XalanSourceTreeParserLiaison::setPersistent(XalanSourceTreeDocument*	theDocument)
{
	const DocumentMapType::iterator		i =
		m_documentMap.find(theDocument);

	if (i != m_documentMap.end())
	{
		return false;
	}
	else
	{
		m_persistentDocumentMap[(*i).first] = (*i).second;

		m_documentMap.erase(i);

		return true;
	}
}

bool
XalanSourceTreeParserLiaison::unsetPersistent(XalanSourceTreeDocument*	theDocument)
{
	const DocumentMapType::iterator		i =
		m_persistentDocumentMap.find(theDocument);

	if (i != m_persistentDocumentMap.end())
	{
		return false;
	}
	else
	{
		m_documentMap[(*i).first] = (*i).second;

		m_persistentDocumentMap.erase(i);

		return true;
	}
}
<|endoftext|>


<commit_before>#include <iostream>
#include "pcl/simulation/camera.hpp"

using namespace Eigen;

namespace pcl
{

void Camera::move(double vx, double vy, double vz)
{
  Vector3d v;
  v << vx, vy, vz;
  pose_.pretranslate(pose_.rotation()*v);
  x_ = pose_.translation().x();
  y_ = pose_.translation().y();
  z_ = pose_.translation().z();

}

void Camera::update_pose() {
  Matrix3d m;
  m = AngleAxisd(yaw_, Vector3d::UnitZ())
    * AngleAxisd(pitch_, Vector3d::UnitY())
    * AngleAxisd(roll_, Vector3d::UnitX());

  pose_.setIdentity();
  pose_ *= m;

  Vector3d v;
  v << x_, y_, z_;
  pose_.translation() = v;
}

}
<commit_msg><commit_after>#include <iostream>
#include "pcl/simulation/camera.hpp"

using namespace Eigen;
namespace pcl
{

void Camera::move(double vx, double vy, double vz)
{
  Vector3d v;
  v << vx, vy, vz;
  pose_.pretranslate(pose_.rotation()*v);
  x_ = pose_.translation().x();
  y_ = pose_.translation().y();
  z_ = pose_.translation().z();

}

void Camera::update_pose() {
  Matrix3d m;
  m = AngleAxisd(yaw_, Vector3d::UnitZ())
    * AngleAxisd(pitch_, Vector3d::UnitY())
    * AngleAxisd(roll_, Vector3d::UnitX());

  pose_.setIdentity();
  pose_ *= m;

  Vector3d v;
  v << x_, y_, z_;
  pose_.translation() = v;
}

}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: rdbtdp_tdenumeration.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: kso $ $Date: 2002-11-13 16:01:19 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _STOC_RDBTDP_TDENUMERATION_HXX
#define _STOC_RDBTDP_TDENUMERATION_HXX

#include <list>

#ifndef _OSL_MUTEX_HXX_
#include <osl/mutex.hxx>
#endif
#ifndef _RTL_REF_HXX_
#include <rtl/ref.hxx>
#endif
#ifndef _COM_SUN_STAR_CONTAINER_XHIERARCHICALNAMEACCESS_HPP_
#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
#endif
#ifndef _COM_SUN_STAR_REFLECTION_INVALIDTYPENAMEEXCEPTION_HPP_
#include <com/sun/star/reflection/InvalidTypeNameException.hpp>
#endif
#ifndef _COM_SUN_STAR_REFLECTION_NOSUCHTYPENAMEEXCEPTION_HPP_
#include <com/sun/star/reflection/NoSuchTypeNameException.hpp>
#endif
#ifndef _COM_SUN_STAR_REFLECTION_TYPEDESCRIPTIONSEARCHDEPTH_HPP_
#include <com/sun/star/reflection/TypeDescriptionSearchDepth.hpp>
#endif
#ifndef _COM_SUN_STAR_REFLECTION_XTYPEDESCRIPTIONENUMERATION_HPP_
#include <com/sun/star/reflection/XTypeDescriptionEnumeration.hpp>
#endif
#ifndef _COM_SUN_STAR_UNO_SEQUENCE_HXX_
#include <com/sun/star/uno/Sequence.hxx>
#endif
#ifndef _COM_SUN_STAR_UNO_TYPECLASS_HPP_
#include <com/sun/star/uno/TypeClass.hpp>
#endif
#ifndef _CPPUHELPER_IMPLBASE1_HXX_
#include <cppuhelper/implbase1.hxx>
#endif

#ifndef _STOC_RDBTDP_BASE_HXX
#include "base.hxx"
#endif

class RegistryTypeReaderLoader;

namespace stoc_rdbtdp
{

typedef ::std::list< ::com::sun::star::uno::Reference<
    ::com::sun::star::reflection::XTypeDescription > > TypeDescriptionList;

class TypeDescriptionEnumerationImpl
    : public cppu::WeakImplHelper1<
                com::sun::star::reflection::XTypeDescriptionEnumeration >
{
public:
    static rtl::Reference< TypeDescriptionEnumerationImpl > createInstance(
        const ::com::sun::star::uno::Reference<
            ::com::sun::star::uno::XComponentContext > & xContext,
        const rtl::OUString & rModuleName,
        const ::com::sun::star::uno::Sequence<
            ::com::sun::star::uno::TypeClass > & rTypes,
        ::com::sun::star::reflection::TypeDescriptionSearchDepth eDepth,
        const RegistryTypeReaderLoader & rLoader,
        const RegistryKeyList & rBaseKeys )
            throw ( ::com::sun::star::reflection::NoSuchTypeNameException,
                    ::com::sun::star::reflection::InvalidTypeNameException,
                    ::com::sun::star::uno::RuntimeException );

    virtual ~TypeDescriptionEnumerationImpl();

    // XEnumeration (base of XTypeDescriptionEnumeration)
    virtual sal_Bool SAL_CALL hasMoreElements()
        throw ( ::com::sun::star::uno::RuntimeException );
    virtual ::com::sun::star::uno::Any SAL_CALL nextElement()
        throw ( ::com::sun::star::container::NoSuchElementException,
                ::com::sun::star::lang::WrappedTargetException,
                ::com::sun::star::uno::RuntimeException );

    // XTypeDescriptionEnumeration
    virtual ::com::sun::star::uno::Reference<
        ::com::sun::star::reflection::XTypeDescription > SAL_CALL
    nextTypeDescription()
        throw ( ::com::sun::star::container::NoSuchElementException,
                ::com::sun::star::uno::RuntimeException );

private:
    // Note: keys must be open (XRegistryKey->openKey(...)).
    TypeDescriptionEnumerationImpl(
        const ::com::sun::star::uno::Reference<
            ::com::sun::star::uno::XComponentContext > & xContext,
        const RegistryKeyList & rModuleKeys,
        const ::com::sun::star::uno::Sequence<
            ::com::sun::star::uno::TypeClass > & rTypes,
        ::com::sun::star::reflection::TypeDescriptionSearchDepth eDepth,
        const RegistryTypeReaderLoader & rLoader );

    bool queryMore();
    ::com::sun::star::uno::Reference<
        ::com::sun::star::reflection::XTypeDescription > queryNext();
    ::com::sun::star::uno::Reference<
        ::com::sun::star::container::XHierarchicalNameAccess > getTDMgr();

    // members
    osl::Mutex m_aMutex;
    RegistryKeyList     m_aModuleKeys;
    RegistryKeyList     m_aCurrentModuleSubKeys;
    TypeDescriptionList m_aTypeDescs;
    ::com::sun::star::uno::Sequence<
        ::com::sun::star::uno::TypeClass > m_aTypes;
    ::com::sun::star::reflection::TypeDescriptionSearchDepth m_eDepth;
    RegistryTypeReaderLoader m_aLoader;
    ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >
        m_xContext;
    ::com::sun::star::uno::Reference<
        ::com::sun::star::container::XHierarchicalNameAccess > m_xTDMgr;
};

} // namespace stoc_rdbtdp

#endif /* _STOC_RDBTDP_TDENUMERATION_HXX */

<commit_msg>INTEGRATION: CWS sb8 (1.2.68); FILE MERGED 2003/09/03 10:37:17 sb 1.2.68.1: #112071# Fixed comparison of RTTypeClass with com.sun.star.uno.TypeClass.<commit_after>/*************************************************************************
 *
 *  $RCSfile: rdbtdp_tdenumeration.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: vg $ $Date: 2003-10-09 10:24:08 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _STOC_RDBTDP_TDENUMERATION_HXX
#define _STOC_RDBTDP_TDENUMERATION_HXX

#include <list>

#ifndef _OSL_MUTEX_HXX_
#include <osl/mutex.hxx>
#endif
#ifndef _RTL_REF_HXX_
#include <rtl/ref.hxx>
#endif
#ifndef _REGISTRY_REFLTYPE_HXX_
#include <registry/refltype.hxx>
#endif
#ifndef _COM_SUN_STAR_CONTAINER_XHIERARCHICALNAMEACCESS_HPP_
#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
#endif
#ifndef _COM_SUN_STAR_REFLECTION_INVALIDTYPENAMEEXCEPTION_HPP_
#include <com/sun/star/reflection/InvalidTypeNameException.hpp>
#endif
#ifndef _COM_SUN_STAR_REFLECTION_NOSUCHTYPENAMEEXCEPTION_HPP_
#include <com/sun/star/reflection/NoSuchTypeNameException.hpp>
#endif
#ifndef _COM_SUN_STAR_REFLECTION_TYPEDESCRIPTIONSEARCHDEPTH_HPP_
#include <com/sun/star/reflection/TypeDescriptionSearchDepth.hpp>
#endif
#ifndef _COM_SUN_STAR_REFLECTION_XTYPEDESCRIPTIONENUMERATION_HPP_
#include <com/sun/star/reflection/XTypeDescriptionEnumeration.hpp>
#endif
#ifndef _COM_SUN_STAR_UNO_SEQUENCE_HXX_
#include <com/sun/star/uno/Sequence.hxx>
#endif
#ifndef _COM_SUN_STAR_UNO_TYPECLASS_HPP_
#include <com/sun/star/uno/TypeClass.hpp>
#endif
#ifndef _CPPUHELPER_IMPLBASE1_HXX_
#include <cppuhelper/implbase1.hxx>
#endif

#ifndef _STOC_RDBTDP_BASE_HXX
#include "base.hxx"
#endif

class RegistryTypeReaderLoader;

namespace stoc_rdbtdp
{

typedef ::std::list< ::com::sun::star::uno::Reference<
    ::com::sun::star::reflection::XTypeDescription > > TypeDescriptionList;

class TypeDescriptionEnumerationImpl
    : public cppu::WeakImplHelper1<
                com::sun::star::reflection::XTypeDescriptionEnumeration >
{
public:
    static rtl::Reference< TypeDescriptionEnumerationImpl > createInstance(
        const ::com::sun::star::uno::Reference<
            ::com::sun::star::uno::XComponentContext > & xContext,
        const rtl::OUString & rModuleName,
        const ::com::sun::star::uno::Sequence<
            ::com::sun::star::uno::TypeClass > & rTypes,
        ::com::sun::star::reflection::TypeDescriptionSearchDepth eDepth,
        const RegistryTypeReaderLoader & rLoader,
        const RegistryKeyList & rBaseKeys )
            throw ( ::com::sun::star::reflection::NoSuchTypeNameException,
                    ::com::sun::star::reflection::InvalidTypeNameException,
                    ::com::sun::star::uno::RuntimeException );

    virtual ~TypeDescriptionEnumerationImpl();

    // XEnumeration (base of XTypeDescriptionEnumeration)
    virtual sal_Bool SAL_CALL hasMoreElements()
        throw ( ::com::sun::star::uno::RuntimeException );
    virtual ::com::sun::star::uno::Any SAL_CALL nextElement()
        throw ( ::com::sun::star::container::NoSuchElementException,
                ::com::sun::star::lang::WrappedTargetException,
                ::com::sun::star::uno::RuntimeException );

    // XTypeDescriptionEnumeration
    virtual ::com::sun::star::uno::Reference<
        ::com::sun::star::reflection::XTypeDescription > SAL_CALL
    nextTypeDescription()
        throw ( ::com::sun::star::container::NoSuchElementException,
                ::com::sun::star::uno::RuntimeException );

private:
    // Note: keys must be open (XRegistryKey->openKey(...)).
    TypeDescriptionEnumerationImpl(
        const ::com::sun::star::uno::Reference<
            ::com::sun::star::uno::XComponentContext > & xContext,
        const RegistryKeyList & rModuleKeys,
        const ::com::sun::star::uno::Sequence<
            ::com::sun::star::uno::TypeClass > & rTypes,
        ::com::sun::star::reflection::TypeDescriptionSearchDepth eDepth,
        const RegistryTypeReaderLoader & rLoader );

    static bool match( ::RTTypeClass eType1,
                       ::com::sun::star::uno::TypeClass eType2 );
    bool queryMore();
    ::com::sun::star::uno::Reference<
        ::com::sun::star::reflection::XTypeDescription > queryNext();
    ::com::sun::star::uno::Reference<
        ::com::sun::star::container::XHierarchicalNameAccess > getTDMgr();

    // members
    osl::Mutex m_aMutex;
    RegistryKeyList     m_aModuleKeys;
    RegistryKeyList     m_aCurrentModuleSubKeys;
    TypeDescriptionList m_aTypeDescs;
    ::com::sun::star::uno::Sequence<
        ::com::sun::star::uno::TypeClass > m_aTypes;
    ::com::sun::star::reflection::TypeDescriptionSearchDepth m_eDepth;
    RegistryTypeReaderLoader m_aLoader;
    ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >
        m_xContext;
    ::com::sun::star::uno::Reference<
        ::com::sun::star::container::XHierarchicalNameAccess > m_xTDMgr;
};

} // namespace stoc_rdbtdp

#endif /* _STOC_RDBTDP_TDENUMERATION_HXX */

<|endoftext|>


<commit_before>// GRSimpleVals.cpp - Transfer functions for tracking simple values -*- C++ -*--
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This file defines GRSimpleVals, a sub-class of GRTransferFuncs that
//  provides transfer functions for performing simple value tracking with
//  limited support for symbolics.
//
//===----------------------------------------------------------------------===//

#include "GRSimpleVals.h"
#include "BasicObjCFoundationChecks.h"
#include "clang/Analysis/PathSensitive/ValueState.h"
#include "clang/Analysis/PathDiagnostic.h"
#include <sstream>

using namespace clang;

namespace clang {

template <typename ITERATOR>
static inline ProgramPoint GetLocation(ITERATOR I) {
  return (*I)->getLocation();
}

template <>
inline ProgramPoint GetLocation(GRExprEngine::undef_arg_iterator I) {
  return I->first->getLocation();
}

static inline Stmt* GetStmt(const ProgramPoint& P) {
  if (const PostStmt* PS = dyn_cast<PostStmt>(&P)) {
    return PS->getStmt();
  }
  else if (const BlockEdge* BE = dyn_cast<BlockEdge>(&P)) {
    return BE->getSrc()->getTerminator();
  }

  assert (false && "Unsupported ProgramPoint.");
  return NULL;
}

template <typename ITERATOR>
static void EmitDiag(Diagnostic& Diag, PathDiagnosticClient* PD,
                     SourceManager& SrcMgr,
unsigned ErrorDiag, ITERATOR I) {

  Stmt* S = GetStmt(GetLocation(I));
  Diag.Report(PD, FullSourceLoc(S->getLocStart(), SrcMgr), ErrorDiag);
}

template <>
static void EmitDiag(Diagnostic& Diag, PathDiagnosticClient* PD,
                     SourceManager& SrcMgr, unsigned ErrorDiag,
                     GRExprEngine::undef_arg_iterator I) {

  Stmt* S1 = GetStmt(GetLocation(I));
  Expr* E2 = cast<Expr>(I->second);

  SourceLocation Loc = S1->getLocStart();
  SourceRange R = E2->getSourceRange();
  Diag.Report(PD, FullSourceLoc(Loc, SrcMgr), ErrorDiag, 0, 0, &R, 1);
}

template <typename ITERATOR>
void EmitWarning(Diagnostic& Diag,  PathDiagnosticClient* PD,
                 SourceManager& SrcMgr,
                 ITERATOR I, ITERATOR E, const char* msg) {

  std::ostringstream Out;
  Out << "[CHECKER] " << msg;
  msg = Out.str().c_str();

  bool isFirst = true;
  unsigned ErrorDiag = 0;
  llvm::SmallPtrSet<void*,10> CachedErrors;

  for (; I != E; ++I) {

    if (isFirst) {
      isFirst = false;
      ErrorDiag = Diag.getCustomDiagID(Diagnostic::Warning, msg);
    }
    else {

      // HACK: Cache the location of the error.  Don't emit the same
      // warning for the same error type that occurs at the same program
      // location but along a different path.
      void* p = GetLocation(I).getRawData();

      if (CachedErrors.count(p))
        continue;

      CachedErrors.insert(p);
    }

    EmitDiag(Diag, PD, SrcMgr, ErrorDiag, I);
  }
}

unsigned RunGRSimpleVals(CFG& cfg, Decl& CD, ASTContext& Ctx,
                         Diagnostic& Diag, PathDiagnosticClient* PD,
                         bool Visualize, bool TrimGraph) {

  GRCoreEngine<GRExprEngine> Eng(cfg, CD, Ctx);
  GRExprEngine* CheckerState = &Eng.getCheckerState();

  // Set base transfer functions.
  GRSimpleVals GRSV;
  CheckerState->setTransferFunctions(GRSV);

  // Add extra checkers.
  llvm::OwningPtr<GRSimpleAPICheck> FoundationCheck(
    CreateBasicObjCFoundationChecks(Ctx, &CheckerState->getStateManager()));

  CheckerState->AddObjCMessageExprCheck(FoundationCheck.get());

  // Execute the worklist algorithm.
  Eng.ExecuteWorkList(120000);

  SourceManager& SrcMgr = Ctx.getSourceManager();

  EmitWarning(Diag, PD, SrcMgr,
              CheckerState->null_derefs_begin(),
              CheckerState->null_derefs_end(),
              "Dereference of NULL pointer.");

  EmitWarning(Diag, PD, SrcMgr,
              CheckerState->undef_derefs_begin(),
              CheckerState->undef_derefs_end(),
              "Dereference of undefined value.");

  EmitWarning(Diag, PD, SrcMgr,
              CheckerState->undef_branches_begin(),
              CheckerState->undef_branches_end(),
              "Branch condition evaluates to an uninitialized value.");

  EmitWarning(Diag, PD, SrcMgr,
              CheckerState->explicit_bad_divides_begin(),
              CheckerState->explicit_bad_divides_end(),
              "Division by zero/undefined value.");

  EmitWarning(Diag, PD, SrcMgr,
              CheckerState->undef_results_begin(),
              CheckerState->undef_results_end(),
              "Result of operation is undefined.");

  EmitWarning(Diag, PD, SrcMgr,
              CheckerState->bad_calls_begin(),
              CheckerState->bad_calls_end(),
              "Call using a NULL or undefined function pointer value.");

  EmitWarning(Diag, PD, SrcMgr,
              CheckerState->undef_arg_begin(),
              CheckerState->undef_arg_end(),
              "Pass-by-value argument in function is undefined.");

  EmitWarning(Diag, PD, SrcMgr,
              CheckerState->msg_expr_undef_arg_begin(),
              CheckerState->msg_expr_undef_arg_end(),
              "Pass-by-value argument in message expression is undefined.");

  EmitWarning(Diag, PD, SrcMgr,
              CheckerState->undef_receivers_begin(),
              CheckerState->undef_receivers_end(),
              "Receiver in message expression is an uninitialized value.");

  EmitWarning(Diag, PD, SrcMgr,
              CheckerState->ret_stackaddr_begin(),
              CheckerState->ret_stackaddr_end(),
              "Address of stack-allocated variable returned.");

  FoundationCheck.get()->ReportResults(Diag);
#ifndef NDEBUG
  if (Visualize) CheckerState->ViewGraph(TrimGraph);
#endif

  return Eng.getGraph().size();
}

} // end clang namespace

//===----------------------------------------------------------------------===//
// Transfer function for Casts.
//===----------------------------------------------------------------------===//

RVal GRSimpleVals::EvalCast(GRExprEngine& Eng, NonLVal X, QualType T) {

  if (!isa<nonlval::ConcreteInt>(X))
    return UnknownVal();

  BasicValueFactory& BasicVals = Eng.getBasicVals();

  llvm::APSInt V = cast<nonlval::ConcreteInt>(X).getValue();
  V.setIsUnsigned(T->isUnsignedIntegerType() || T->isPointerType()
                  || T->isObjCQualifiedIdType());
  V.extOrTrunc(Eng.getContext().getTypeSize(T));

  if (T->isPointerType())
    return lval::ConcreteInt(BasicVals.getValue(V));
  else
    return nonlval::ConcreteInt(BasicVals.getValue(V));
}

// Casts.

RVal GRSimpleVals::EvalCast(GRExprEngine& Eng, LVal X, QualType T) {

  if (T->isPointerType() || T->isReferenceType() || T->isObjCQualifiedIdType())
    return X;

  assert (T->isIntegerType());

  if (!isa<lval::ConcreteInt>(X))
    return UnknownVal();

  BasicValueFactory& BasicVals = Eng.getBasicVals();

  llvm::APSInt V = cast<lval::ConcreteInt>(X).getValue();
  V.setIsUnsigned(T->isUnsignedIntegerType() || T->isPointerType());
  V.extOrTrunc(Eng.getContext().getTypeSize(T));

  return nonlval::ConcreteInt(BasicVals.getValue(V));
}

// Unary operators.

RVal GRSimpleVals::EvalMinus(GRExprEngine& Eng, UnaryOperator* U, NonLVal X){

  switch (X.getSubKind()) {

    case nonlval::ConcreteIntKind:
      return cast<nonlval::ConcreteInt>(X).EvalMinus(Eng.getBasicVals(), U);

    default:
      return UnknownVal();
  }
}

RVal GRSimpleVals::EvalComplement(GRExprEngine& Eng, NonLVal X) {

  switch (X.getSubKind()) {

    case nonlval::ConcreteIntKind:
      return cast<nonlval::ConcreteInt>(X).EvalComplement(Eng.getBasicVals());

    default:
      return UnknownVal();
  }
}

// Binary operators.

RVal GRSimpleVals::EvalBinOp(GRExprEngine& Eng, BinaryOperator::Opcode Op,
                             NonLVal L, NonLVal R)  {

  BasicValueFactory& BasicVals = Eng.getBasicVals();

  while (1) {

    switch (L.getSubKind()) {
      default:
        return UnknownVal();

      case nonlval::ConcreteIntKind:

        if (isa<nonlval::ConcreteInt>(R)) {
          const nonlval::ConcreteInt& L_CI = cast<nonlval::ConcreteInt>(L);
          const nonlval::ConcreteInt& R_CI = cast<nonlval::ConcreteInt>(R);
          return L_CI.EvalBinOp(BasicVals, Op, R_CI);
        }
        else {
          NonLVal tmp = R;
          R = L;
          L = tmp;
          continue;
        }

      case nonlval::SymbolValKind: {

        if (isa<nonlval::ConcreteInt>(R)) {
          const SymIntConstraint& C =
            BasicVals.getConstraint(cast<nonlval::SymbolVal>(L).getSymbol(), Op,
                                    cast<nonlval::ConcreteInt>(R).getValue());

          return nonlval::SymIntConstraintVal(C);
        }
        else
          return UnknownVal();
      }
    }
  }
}

// Binary Operators (except assignments and comma).

RVal GRSimpleVals::EvalBinOp(GRExprEngine& Eng, BinaryOperator::Opcode Op,
                             LVal L, LVal R) {

  switch (Op) {

    default:
      return UnknownVal();

    case BinaryOperator::EQ:
      return EvalEQ(Eng, L, R);

    case BinaryOperator::NE:
      return EvalNE(Eng, L, R);
  }
}

// Pointer arithmetic.

RVal GRSimpleVals::EvalBinOp(GRExprEngine& Eng, BinaryOperator::Opcode Op,
                             LVal L, NonLVal R) {
  return UnknownVal();
}

// Equality operators for LVals.

RVal GRSimpleVals::EvalEQ(GRExprEngine& Eng, LVal L, LVal R) {

  BasicValueFactory& BasicVals = Eng.getBasicVals();

  switch (L.getSubKind()) {

    default:
      assert(false && "EQ not implemented for this LVal.");
      return UnknownVal();

    case lval::ConcreteIntKind:

      if (isa<lval::ConcreteInt>(R)) {
        bool b = cast<lval::ConcreteInt>(L).getValue() ==
                 cast<lval::ConcreteInt>(R).getValue();

        return NonLVal::MakeIntTruthVal(BasicVals, b);
      }
      else if (isa<lval::SymbolVal>(R)) {

        const SymIntConstraint& C =
          BasicVals.getConstraint(cast<lval::SymbolVal>(R).getSymbol(),
                               BinaryOperator::EQ,
                               cast<lval::ConcreteInt>(L).getValue());

        return nonlval::SymIntConstraintVal(C);
      }

      break;

    case lval::SymbolValKind: {

      if (isa<lval::ConcreteInt>(R)) {
        const SymIntConstraint& C =
          BasicVals.getConstraint(cast<lval::SymbolVal>(L).getSymbol(),
                               BinaryOperator::EQ,
                               cast<lval::ConcreteInt>(R).getValue());

        return nonlval::SymIntConstraintVal(C);
      }

      // FIXME: Implement == for lval Symbols.  This is mainly useful
      //  in iterator loops when traversing a buffer, e.g. while(z != zTerm).
      //  Since this is not useful for many checkers we'll punt on this for
      //  now.

      return UnknownVal();
    }

    case lval::DeclValKind:
    case lval::FuncValKind:
    case lval::GotoLabelKind:
      return NonLVal::MakeIntTruthVal(BasicVals, L == R);
  }

  return NonLVal::MakeIntTruthVal(BasicVals, false);
}

RVal GRSimpleVals::EvalNE(GRExprEngine& Eng, LVal L, LVal R) {

  BasicValueFactory& BasicVals = Eng.getBasicVals();

  switch (L.getSubKind()) {

    default:
      assert(false && "NE not implemented for this LVal.");
      return UnknownVal();

    case lval::ConcreteIntKind:

      if (isa<lval::ConcreteInt>(R)) {
        bool b = cast<lval::ConcreteInt>(L).getValue() !=
                 cast<lval::ConcreteInt>(R).getValue();

        return NonLVal::MakeIntTruthVal(BasicVals, b);
      }
      else if (isa<lval::SymbolVal>(R)) {
        const SymIntConstraint& C =
          BasicVals.getConstraint(cast<lval::SymbolVal>(R).getSymbol(),
                                  BinaryOperator::NE,
                                  cast<lval::ConcreteInt>(L).getValue());

        return nonlval::SymIntConstraintVal(C);
      }

      break;

    case lval::SymbolValKind: {
      if (isa<lval::ConcreteInt>(R)) {
        const SymIntConstraint& C =
          BasicVals.getConstraint(cast<lval::SymbolVal>(L).getSymbol(),
                                  BinaryOperator::NE,
                                  cast<lval::ConcreteInt>(R).getValue());

        return nonlval::SymIntConstraintVal(C);
      }

      // FIXME: Implement != for lval Symbols.  This is mainly useful
      //  in iterator loops when traversing a buffer, e.g. while(z != zTerm).
      //  Since this is not useful for many checkers we'll punt on this for
      //  now.

      return UnknownVal();

      break;
    }

    case lval::DeclValKind:
    case lval::FuncValKind:
    case lval::GotoLabelKind:
      return NonLVal::MakeIntTruthVal(BasicVals, L != R);
  }

  return NonLVal::MakeIntTruthVal(BasicVals, true);
}

//===----------------------------------------------------------------------===//
// Transfer function for Function Calls.
//===----------------------------------------------------------------------===//

void GRSimpleVals::EvalCall(ExplodedNodeSet<ValueState>& Dst,
                            GRExprEngine& Eng,
                            GRStmtNodeBuilder<ValueState>& Builder,
                            CallExpr* CE, LVal L,
                            ExplodedNode<ValueState>* Pred) {

  ValueStateManager& StateMgr = Eng.getStateManager();
  ValueState* St = Builder.GetState(Pred);

  // Invalidate all arguments passed in by reference (LVals).

  for (CallExpr::arg_iterator I = CE->arg_begin(), E = CE->arg_end();
        I != E; ++I) {

    RVal V = StateMgr.GetRVal(St, *I);

    if (isa<LVal>(V))
      St = StateMgr.SetRVal(St, cast<LVal>(V), UnknownVal());
  }

  // Make up a symbol for the return value of this function.

  if (CE->getType() != Eng.getContext().VoidTy) {
    unsigned Count = Builder.getCurrentBlockCount();
    SymbolID Sym = Eng.getSymbolManager().getConjuredSymbol(CE, Count);

    RVal X = CE->getType()->isPointerType()
             ? cast<RVal>(lval::SymbolVal(Sym))
             : cast<RVal>(nonlval::SymbolVal(Sym));

    St = StateMgr.SetRVal(St, CE, X, Eng.getCFG().isBlkExpr(CE), false);
  }

  Builder.MakeNode(Dst, CE, Pred, St);
}
<commit_msg>Include ranges in GRSimpleVals diagnostics.<commit_after>// GRSimpleVals.cpp - Transfer functions for tracking simple values -*- C++ -*--
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This file defines GRSimpleVals, a sub-class of GRTransferFuncs that
//  provides transfer functions for performing simple value tracking with
//  limited support for symbolics.
//
//===----------------------------------------------------------------------===//

#include "GRSimpleVals.h"
#include "BasicObjCFoundationChecks.h"
#include "clang/Analysis/PathSensitive/ValueState.h"
#include "clang/Analysis/PathDiagnostic.h"
#include <sstream>

using namespace clang;

namespace clang {

template <typename ITERATOR>
static inline ProgramPoint GetLocation(ITERATOR I) {
  return (*I)->getLocation();
}

template <>
inline ProgramPoint GetLocation(GRExprEngine::undef_arg_iterator I) {
  return I->first->getLocation();
}

static inline Stmt* GetStmt(const ProgramPoint& P) {
  if (const PostStmt* PS = dyn_cast<PostStmt>(&P)) {
    return PS->getStmt();
  }
  else if (const BlockEdge* BE = dyn_cast<BlockEdge>(&P)) {
    return BE->getSrc()->getTerminator();
  }

  assert (false && "Unsupported ProgramPoint.");
  return NULL;
}

template <typename ITERATOR>
static void EmitDiag(Diagnostic& Diag, PathDiagnosticClient* PD,
                     SourceManager& SrcMgr,
unsigned ErrorDiag, ITERATOR I) {

  Stmt* S = GetStmt(GetLocation(I));
  SourceRange R = S->getSourceRange();
  Diag.Report(PD, FullSourceLoc(S->getLocStart(), SrcMgr), ErrorDiag,
              NULL, 0, &R, 1);
}

template <>
static void EmitDiag(Diagnostic& Diag, PathDiagnosticClient* PD,
                     SourceManager& SrcMgr, unsigned ErrorDiag,
                     GRExprEngine::undef_arg_iterator I) {

  Stmt* S1 = GetStmt(GetLocation(I));
  Expr* E2 = cast<Expr>(I->second);

  SourceLocation Loc = S1->getLocStart();
  SourceRange R = E2->getSourceRange();
  Diag.Report(PD, FullSourceLoc(Loc, SrcMgr), ErrorDiag, 0, 0, &R, 1);
}

template <typename ITERATOR>
void EmitWarning(Diagnostic& Diag,  PathDiagnosticClient* PD,
                 SourceManager& SrcMgr,
                 ITERATOR I, ITERATOR E, const char* msg) {

  std::ostringstream Out;
  Out << "[CHECKER] " << msg;
  msg = Out.str().c_str();

  bool isFirst = true;
  unsigned ErrorDiag = 0;
  llvm::SmallPtrSet<void*,10> CachedErrors;

  for (; I != E; ++I) {

    if (isFirst) {
      isFirst = false;
      ErrorDiag = Diag.getCustomDiagID(Diagnostic::Warning, msg);
    }
    else {

      // HACK: Cache the location of the error.  Don't emit the same
      // warning for the same error type that occurs at the same program
      // location but along a different path.
      void* p = GetLocation(I).getRawData();

      if (CachedErrors.count(p))
        continue;

      CachedErrors.insert(p);
    }

    EmitDiag(Diag, PD, SrcMgr, ErrorDiag, I);
  }
}

unsigned RunGRSimpleVals(CFG& cfg, Decl& CD, ASTContext& Ctx,
                         Diagnostic& Diag, PathDiagnosticClient* PD,
                         bool Visualize, bool TrimGraph) {

  GRCoreEngine<GRExprEngine> Eng(cfg, CD, Ctx);
  GRExprEngine* CheckerState = &Eng.getCheckerState();

  // Set base transfer functions.
  GRSimpleVals GRSV;
  CheckerState->setTransferFunctions(GRSV);

  // Add extra checkers.
  llvm::OwningPtr<GRSimpleAPICheck> FoundationCheck(
    CreateBasicObjCFoundationChecks(Ctx, &CheckerState->getStateManager()));

  CheckerState->AddObjCMessageExprCheck(FoundationCheck.get());

  // Execute the worklist algorithm.
  Eng.ExecuteWorkList(120000);

  SourceManager& SrcMgr = Ctx.getSourceManager();

  EmitWarning(Diag, PD, SrcMgr,
              CheckerState->null_derefs_begin(),
              CheckerState->null_derefs_end(),
              "Dereference of NULL pointer.");

  EmitWarning(Diag, PD, SrcMgr,
              CheckerState->undef_derefs_begin(),
              CheckerState->undef_derefs_end(),
              "Dereference of undefined value.");

  EmitWarning(Diag, PD, SrcMgr,
              CheckerState->undef_branches_begin(),
              CheckerState->undef_branches_end(),
              "Branch condition evaluates to an uninitialized value.");

  EmitWarning(Diag, PD, SrcMgr,
              CheckerState->explicit_bad_divides_begin(),
              CheckerState->explicit_bad_divides_end(),
              "Division by zero/undefined value.");

  EmitWarning(Diag, PD, SrcMgr,
              CheckerState->undef_results_begin(),
              CheckerState->undef_results_end(),
              "Result of operation is undefined.");

  EmitWarning(Diag, PD, SrcMgr,
              CheckerState->bad_calls_begin(),
              CheckerState->bad_calls_end(),
              "Call using a NULL or undefined function pointer value.");

  EmitWarning(Diag, PD, SrcMgr,
              CheckerState->undef_arg_begin(),
              CheckerState->undef_arg_end(),
              "Pass-by-value argument in function is undefined.");

  EmitWarning(Diag, PD, SrcMgr,
              CheckerState->msg_expr_undef_arg_begin(),
              CheckerState->msg_expr_undef_arg_end(),
              "Pass-by-value argument in message expression is undefined.");

  EmitWarning(Diag, PD, SrcMgr,
              CheckerState->undef_receivers_begin(),
              CheckerState->undef_receivers_end(),
              "Receiver in message expression is an uninitialized value.");

  EmitWarning(Diag, PD, SrcMgr,
              CheckerState->ret_stackaddr_begin(),
              CheckerState->ret_stackaddr_end(),
              "Address of stack-allocated variable returned.");

  FoundationCheck.get()->ReportResults(Diag);
#ifndef NDEBUG
  if (Visualize) CheckerState->ViewGraph(TrimGraph);
#endif

  return Eng.getGraph().size();
}

} // end clang namespace

//===----------------------------------------------------------------------===//
// Transfer function for Casts.
//===----------------------------------------------------------------------===//

RVal GRSimpleVals::EvalCast(GRExprEngine& Eng, NonLVal X, QualType T) {

  if (!isa<nonlval::ConcreteInt>(X))
    return UnknownVal();

  BasicValueFactory& BasicVals = Eng.getBasicVals();

  llvm::APSInt V = cast<nonlval::ConcreteInt>(X).getValue();
  V.setIsUnsigned(T->isUnsignedIntegerType() || T->isPointerType()
                  || T->isObjCQualifiedIdType());
  V.extOrTrunc(Eng.getContext().getTypeSize(T));

  if (T->isPointerType())
    return lval::ConcreteInt(BasicVals.getValue(V));
  else
    return nonlval::ConcreteInt(BasicVals.getValue(V));
}

// Casts.

RVal GRSimpleVals::EvalCast(GRExprEngine& Eng, LVal X, QualType T) {

  if (T->isPointerType() || T->isReferenceType() || T->isObjCQualifiedIdType())
    return X;

  assert (T->isIntegerType());

  if (!isa<lval::ConcreteInt>(X))
    return UnknownVal();

  BasicValueFactory& BasicVals = Eng.getBasicVals();

  llvm::APSInt V = cast<lval::ConcreteInt>(X).getValue();
  V.setIsUnsigned(T->isUnsignedIntegerType() || T->isPointerType());
  V.extOrTrunc(Eng.getContext().getTypeSize(T));

  return nonlval::ConcreteInt(BasicVals.getValue(V));
}

// Unary operators.

RVal GRSimpleVals::EvalMinus(GRExprEngine& Eng, UnaryOperator* U, NonLVal X){

  switch (X.getSubKind()) {

    case nonlval::ConcreteIntKind:
      return cast<nonlval::ConcreteInt>(X).EvalMinus(Eng.getBasicVals(), U);

    default:
      return UnknownVal();
  }
}

RVal GRSimpleVals::EvalComplement(GRExprEngine& Eng, NonLVal X) {

  switch (X.getSubKind()) {

    case nonlval::ConcreteIntKind:
      return cast<nonlval::ConcreteInt>(X).EvalComplement(Eng.getBasicVals());

    default:
      return UnknownVal();
  }
}

// Binary operators.

RVal GRSimpleVals::EvalBinOp(GRExprEngine& Eng, BinaryOperator::Opcode Op,
                             NonLVal L, NonLVal R)  {

  BasicValueFactory& BasicVals = Eng.getBasicVals();

  while (1) {

    switch (L.getSubKind()) {
      default:
        return UnknownVal();

      case nonlval::ConcreteIntKind:

        if (isa<nonlval::ConcreteInt>(R)) {
          const nonlval::ConcreteInt& L_CI = cast<nonlval::ConcreteInt>(L);
          const nonlval::ConcreteInt& R_CI = cast<nonlval::ConcreteInt>(R);
          return L_CI.EvalBinOp(BasicVals, Op, R_CI);
        }
        else {
          NonLVal tmp = R;
          R = L;
          L = tmp;
          continue;
        }

      case nonlval::SymbolValKind: {

        if (isa<nonlval::ConcreteInt>(R)) {
          const SymIntConstraint& C =
            BasicVals.getConstraint(cast<nonlval::SymbolVal>(L).getSymbol(), Op,
                                    cast<nonlval::ConcreteInt>(R).getValue());

          return nonlval::SymIntConstraintVal(C);
        }
        else
          return UnknownVal();
      }
    }
  }
}

// Binary Operators (except assignments and comma).

RVal GRSimpleVals::EvalBinOp(GRExprEngine& Eng, BinaryOperator::Opcode Op,
                             LVal L, LVal R) {

  switch (Op) {

    default:
      return UnknownVal();

    case BinaryOperator::EQ:
      return EvalEQ(Eng, L, R);

    case BinaryOperator::NE:
      return EvalNE(Eng, L, R);
  }
}

// Pointer arithmetic.

RVal GRSimpleVals::EvalBinOp(GRExprEngine& Eng, BinaryOperator::Opcode Op,
                             LVal L, NonLVal R) {
  return UnknownVal();
}

// Equality operators for LVals.

RVal GRSimpleVals::EvalEQ(GRExprEngine& Eng, LVal L, LVal R) {

  BasicValueFactory& BasicVals = Eng.getBasicVals();

  switch (L.getSubKind()) {

    default:
      assert(false && "EQ not implemented for this LVal.");
      return UnknownVal();

    case lval::ConcreteIntKind:

      if (isa<lval::ConcreteInt>(R)) {
        bool b = cast<lval::ConcreteInt>(L).getValue() ==
                 cast<lval::ConcreteInt>(R).getValue();

        return NonLVal::MakeIntTruthVal(BasicVals, b);
      }
      else if (isa<lval::SymbolVal>(R)) {

        const SymIntConstraint& C =
          BasicVals.getConstraint(cast<lval::SymbolVal>(R).getSymbol(),
                               BinaryOperator::EQ,
                               cast<lval::ConcreteInt>(L).getValue());

        return nonlval::SymIntConstraintVal(C);
      }

      break;

    case lval::SymbolValKind: {

      if (isa<lval::ConcreteInt>(R)) {
        const SymIntConstraint& C =
          BasicVals.getConstraint(cast<lval::SymbolVal>(L).getSymbol(),
                               BinaryOperator::EQ,
                               cast<lval::ConcreteInt>(R).getValue());

        return nonlval::SymIntConstraintVal(C);
      }

      // FIXME: Implement == for lval Symbols.  This is mainly useful
      //  in iterator loops when traversing a buffer, e.g. while(z != zTerm).
      //  Since this is not useful for many checkers we'll punt on this for
      //  now.

      return UnknownVal();
    }

    case lval::DeclValKind:
    case lval::FuncValKind:
    case lval::GotoLabelKind:
      return NonLVal::MakeIntTruthVal(BasicVals, L == R);
  }

  return NonLVal::MakeIntTruthVal(BasicVals, false);
}

RVal GRSimpleVals::EvalNE(GRExprEngine& Eng, LVal L, LVal R) {

  BasicValueFactory& BasicVals = Eng.getBasicVals();

  switch (L.getSubKind()) {

    default:
      assert(false && "NE not implemented for this LVal.");
      return UnknownVal();

    case lval::ConcreteIntKind:

      if (isa<lval::ConcreteInt>(R)) {
        bool b = cast<lval::ConcreteInt>(L).getValue() !=
                 cast<lval::ConcreteInt>(R).getValue();

        return NonLVal::MakeIntTruthVal(BasicVals, b);
      }
      else if (isa<lval::SymbolVal>(R)) {
        const SymIntConstraint& C =
          BasicVals.getConstraint(cast<lval::SymbolVal>(R).getSymbol(),
                                  BinaryOperator::NE,
                                  cast<lval::ConcreteInt>(L).getValue());

        return nonlval::SymIntConstraintVal(C);
      }

      break;

    case lval::SymbolValKind: {
      if (isa<lval::ConcreteInt>(R)) {
        const SymIntConstraint& C =
          BasicVals.getConstraint(cast<lval::SymbolVal>(L).getSymbol(),
                                  BinaryOperator::NE,
                                  cast<lval::ConcreteInt>(R).getValue());

        return nonlval::SymIntConstraintVal(C);
      }

      // FIXME: Implement != for lval Symbols.  This is mainly useful
      //  in iterator loops when traversing a buffer, e.g. while(z != zTerm).
      //  Since this is not useful for many checkers we'll punt on this for
      //  now.

      return UnknownVal();

      break;
    }

    case lval::DeclValKind:
    case lval::FuncValKind:
    case lval::GotoLabelKind:
      return NonLVal::MakeIntTruthVal(BasicVals, L != R);
  }

  return NonLVal::MakeIntTruthVal(BasicVals, true);
}

//===----------------------------------------------------------------------===//
// Transfer function for Function Calls.
//===----------------------------------------------------------------------===//

void GRSimpleVals::EvalCall(ExplodedNodeSet<ValueState>& Dst,
                            GRExprEngine& Eng,
                            GRStmtNodeBuilder<ValueState>& Builder,
                            CallExpr* CE, LVal L,
                            ExplodedNode<ValueState>* Pred) {

  ValueStateManager& StateMgr = Eng.getStateManager();
  ValueState* St = Builder.GetState(Pred);

  // Invalidate all arguments passed in by reference (LVals).

  for (CallExpr::arg_iterator I = CE->arg_begin(), E = CE->arg_end();
        I != E; ++I) {

    RVal V = StateMgr.GetRVal(St, *I);

    if (isa<LVal>(V))
      St = StateMgr.SetRVal(St, cast<LVal>(V), UnknownVal());
  }

  // Make up a symbol for the return value of this function.

  if (CE->getType() != Eng.getContext().VoidTy) {
    unsigned Count = Builder.getCurrentBlockCount();
    SymbolID Sym = Eng.getSymbolManager().getConjuredSymbol(CE, Count);

    RVal X = CE->getType()->isPointerType()
             ? cast<RVal>(lval::SymbolVal(Sym))
             : cast<RVal>(nonlval::SymbolVal(Sym));

    St = StateMgr.SetRVal(St, CE, X, Eng.getCFG().isBlkExpr(CE), false);
  }

  Builder.MakeNode(Dst, CE, Pred, St);
}
<|endoftext|>


<commit_before>#include "fuse++.hpp"

#include <alloca.h>
#include <errno.h>
#include <iostream>

#include <boost/assert.hpp>
#include <boost/bind.hpp>

#include <fuse_lowlevel.h>
#include <fuse_opt.h>

using namespace std;
namespace asio = boost::asio;

extern "C" {
    // D-wrappers to map fuse_userdata to a specific FileSystem. Also ensures fuse gets
    // an error if an Exception aborts control.
    static void _op_lookup(fuse_req_t req, fuse_ino_t parent, const char *name) {
        int res = ((BoostAsioFilesystem*)fuse_req_userdata(req))->fuse_lookup(req, parent, name);
        if (res)
            fuse_reply_err(req, res);
    }
    static void _op_forget(fuse_req_t req, fuse_ino_t ino, u_long nlookup) {
        ((BoostAsioFilesystem*)fuse_req_userdata(req))->fuse_forget(ino, nlookup);
        fuse_reply_none(req);
    }
    static void _op_getattr(fuse_req_t req, fuse_ino_t ino, fuse_file_info *fi) {
        int res = ((BoostAsioFilesystem*)fuse_req_userdata(req))->fuse_getattr(req, ino, fi);
        if (res)
            fuse_reply_err(req, res);
    }
    static void _op_open(fuse_req_t req, fuse_ino_t ino, fuse_file_info *fi) {
        int res = ((BoostAsioFilesystem*)fuse_req_userdata(req))->fuse_open(req, ino, fi);
        if (res)
            fuse_reply_err(req, res);
    }
    static void _op_release(fuse_req_t req, fuse_ino_t ino, fuse_file_info *fi) {
        int res = ((BoostAsioFilesystem*)fuse_req_userdata(req))->fuse_release(req, ino, fi);
        if (res)
            fuse_reply_err(req, res);
    }
    static void _op_read(fuse_req_t req, fuse_ino_t ino, size_t size, off_t off, fuse_file_info *fi) {
        int res = ((BoostAsioFilesystem*)fuse_req_userdata(req))->fuse_read(req, ino, size, off, fi);
        if (res)
            fuse_reply_err(req, res);
    }
}

BoostAsioFilesystem_Options::BoostAsioFilesystem_Options()
	: mountpoint(""), debug(false)
{
	this->insert(value_type("max_read", "65536"));
	this->insert(value_type("async_read", ""));
	this->insert(value_type("allow_other", ""));
}

void BoostAsioFilesystem_Options::format_ll_opts(std::vector<std::string>& target) {
	target.push_back(name);
	target.push_back("-ofsname="+name);

	if (debug) {
		target.push_back("-d");
	}
	BoostAsioFilesystem_Options::iterator iter;
	for (iter = begin(); iter != end(); iter++) {
		ostringstream oss;
		oss << "-o" << iter->first;
		if (iter->second.length())
			oss << '=' << iter->second;
		target.push_back(oss.str());
	}
	target.insert(target.end(), args.begin(), args.end());
}

BoostAsioFilesystem::BoostAsioFilesystem(asio::io_service & ioSvc, BoostAsioFilesystem_Options & options)
	: _channel(ioSvc), _mountpoint(options.mountpoint), _fuse_chan(0), _fuse_session(0)
{
	vector<string> opts;
	options.format_ll_opts(opts);
	debug = options.debug;

	uint16_t argc = opts.size();
	char** argv = (char**)malloc(argc * sizeof(char*));
	for (int i=0; i < argc; i++)
		argv[i] = strdup(opts[i].c_str());

	fuse_args f_args = FUSE_ARGS_INIT(argc, argv);
	_fuse_chan = fuse_mount(_mountpoint.c_str(), &f_args);
	if (!_fuse_chan)
		throw string("Failed to mount");

	_channel.assign(fuse_chan_fd(_fuse_chan));

	/************************************************************************************
	* FUSE_lowlevel_ops struct, pointing to the C++-class-wrappers.
	***********************************************************************************/
	static fuse_lowlevel_ops qfs_ops;
	bzero(&qfs_ops, sizeof(qfs_ops));
	qfs_ops.lookup =  _op_lookup;
	qfs_ops.forget =  _op_forget;
	qfs_ops.getattr = _op_getattr;
	qfs_ops.open =    _op_open;
	qfs_ops.read =    _op_read;
	qfs_ops.release = _op_release;

	_fuse_session = fuse_lowlevel_new(&f_args, &qfs_ops, sizeof(qfs_ops), this);
	// scope(failure)fuse_session_destroy(s);

	fuse_session_add_chan(_fuse_session, _fuse_chan);

	_receive_buf.allocate(fuse_chan_bufsize(_fuse_chan));
	readNext();
}

BoostAsioFilesystem::~BoostAsioFilesystem() {
	if (_fuse_chan)
		fuse_unmount(_mountpoint.c_str(), _fuse_chan);
	if (_fuse_session)
		fuse_session_destroy(_fuse_session);
}

void BoostAsioFilesystem::dispatch_waiting(const boost::system::error_code& error, size_t count) {
	if (error) {
		cerr << "ERROR reading from fuse: " << error.message() << endl;
	} else {
		fuse_session_process(_fuse_session, (const char*)_receive_buf.ptr, count, _fuse_chan);
		readNext();
	}
}

void BoostAsioFilesystem::readNext()
{
	_channel.async_read_some(
		asio::buffer(_receive_buf.ptr, _receive_buf.capacity),
		boost::bind(&BoostAsioFilesystem::dispatch_waiting, this, asio::placeholders::error(), asio::placeholders::bytes_transferred())
	);
}

<commit_msg>[bhfuse]Rename old Qt-name to reflect boost-filesystem.<commit_after>#include "fuse++.hpp"

#include <alloca.h>
#include <errno.h>
#include <iostream>

#include <boost/assert.hpp>
#include <boost/bind.hpp>

#include <fuse_lowlevel.h>
#include <fuse_opt.h>

using namespace std;
namespace asio = boost::asio;

extern "C" {
    // D-wrappers to map fuse_userdata to a specific FileSystem. Also ensures fuse gets
    // an error if an Exception aborts control.
    static void _op_lookup(fuse_req_t req, fuse_ino_t parent, const char *name) {
        int res = ((BoostAsioFilesystem*)fuse_req_userdata(req))->fuse_lookup(req, parent, name);
        if (res)
            fuse_reply_err(req, res);
    }
    static void _op_forget(fuse_req_t req, fuse_ino_t ino, u_long nlookup) {
        ((BoostAsioFilesystem*)fuse_req_userdata(req))->fuse_forget(ino, nlookup);
        fuse_reply_none(req);
    }
    static void _op_getattr(fuse_req_t req, fuse_ino_t ino, fuse_file_info *fi) {
        int res = ((BoostAsioFilesystem*)fuse_req_userdata(req))->fuse_getattr(req, ino, fi);
        if (res)
            fuse_reply_err(req, res);
    }
    static void _op_open(fuse_req_t req, fuse_ino_t ino, fuse_file_info *fi) {
        int res = ((BoostAsioFilesystem*)fuse_req_userdata(req))->fuse_open(req, ino, fi);
        if (res)
            fuse_reply_err(req, res);
    }
    static void _op_release(fuse_req_t req, fuse_ino_t ino, fuse_file_info *fi) {
        int res = ((BoostAsioFilesystem*)fuse_req_userdata(req))->fuse_release(req, ino, fi);
        if (res)
            fuse_reply_err(req, res);
    }
    static void _op_read(fuse_req_t req, fuse_ino_t ino, size_t size, off_t off, fuse_file_info *fi) {
        int res = ((BoostAsioFilesystem*)fuse_req_userdata(req))->fuse_read(req, ino, size, off, fi);
        if (res)
            fuse_reply_err(req, res);
    }
}

BoostAsioFilesystem_Options::BoostAsioFilesystem_Options()
	: mountpoint(""), debug(false)
{
	this->insert(value_type("max_read", "65536"));
	this->insert(value_type("async_read", ""));
	this->insert(value_type("allow_other", ""));
}

void BoostAsioFilesystem_Options::format_ll_opts(std::vector<std::string>& target) {
	target.push_back(name);
	target.push_back("-ofsname="+name);

	if (debug) {
		target.push_back("-d");
	}
	BoostAsioFilesystem_Options::iterator iter;
	for (iter = begin(); iter != end(); iter++) {
		ostringstream oss;
		oss << "-o" << iter->first;
		if (iter->second.length())
			oss << '=' << iter->second;
		target.push_back(oss.str());
	}
	target.insert(target.end(), args.begin(), args.end());
}

BoostAsioFilesystem::BoostAsioFilesystem(asio::io_service & ioSvc, BoostAsioFilesystem_Options & options)
	: _channel(ioSvc), _mountpoint(options.mountpoint), _fuse_chan(0), _fuse_session(0)
{
	vector<string> opts;
	options.format_ll_opts(opts);
	debug = options.debug;

	uint16_t argc = opts.size();
	char** argv = (char**)malloc(argc * sizeof(char*));
	for (int i=0; i < argc; i++)
		argv[i] = strdup(opts[i].c_str());

	fuse_args f_args = FUSE_ARGS_INIT(argc, argv);
	_fuse_chan = fuse_mount(_mountpoint.c_str(), &f_args);
	if (!_fuse_chan)
		throw string("Failed to mount");

	_channel.assign(fuse_chan_fd(_fuse_chan));

	/************************************************************************************
	* FUSE_lowlevel_ops struct, pointing to the C++-class-wrappers.
	***********************************************************************************/
	static fuse_lowlevel_ops bfs_ops;
	bzero(&bfs_ops, sizeof(bfs_ops));
	bfs_ops.init =    _op_init;
	bfs_ops.lookup =  _op_lookup;
	bfs_ops.forget =  _op_forget;
	bfs_ops.getattr = _op_getattr;
	bfs_ops.open =    _op_open;
	bfs_ops.read =    _op_read;
	bfs_ops.release = _op_release;

	_fuse_session = fuse_lowlevel_new(&f_args, &bfs_ops, sizeof(bfs_ops), this);
	// scope(failure)fuse_session_destroy(s);

	fuse_session_add_chan(_fuse_session, _fuse_chan);

	_receive_buf.allocate(fuse_chan_bufsize(_fuse_chan));
	readNext();
}

BoostAsioFilesystem::~BoostAsioFilesystem() {
	if (_fuse_chan)
		fuse_unmount(_mountpoint.c_str(), _fuse_chan);
	if (_fuse_session)
		fuse_session_destroy(_fuse_session);
}

void BoostAsioFilesystem::dispatch_waiting(const boost::system::error_code& error, size_t count) {
	if (error) {
		cerr << "ERROR reading from fuse: " << error.message() << endl;
	} else {
		fuse_session_process(_fuse_session, (const char*)_receive_buf.ptr, count, _fuse_chan);
		readNext();
	}
}

void BoostAsioFilesystem::readNext()
{
	_channel.async_read_some(
		asio::buffer(_receive_buf.ptr, _receive_buf.capacity),
		boost::bind(&BoostAsioFilesystem::dispatch_waiting, this, asio::placeholders::error(), asio::placeholders::bytes_transferred())
	);
}

<|endoftext|>