<commit_before>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: canvastools.cxx,v $
 * $Revision: 1.12 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_basegfx.hxx"

#include <basegfx/tools/gradienttools.hxx>
#include <basegfx/point/b2dpoint.hxx>
#include <basegfx/range/b2drange.hxx>
#include <basegfx/matrix/b2dhommatrixtools.hxx>

namespace basegfx
{
    /** Most of the setup for linear & axial gradient is the same, except
        for the border treatment. Factored out here.
    */
    static void init1DGradientInfo(ODFGradientInfo& o_rGradientInfo,
                                   const B2DRange&  rTargetRange,
                                   sal_uInt32       nSteps,
                                   double           fBorder,
                                   double           fAngle,
                                   bool             bAxial)
    {
        o_rGradientInfo.maTextureTransform.identity();
        o_rGradientInfo.maBackTextureTransform.identity();
        o_rGradientInfo.mnSteps = nSteps;

        fAngle = -fAngle;

        double fTargetSizeX(rTargetRange.getWidth());
        double fTargetSizeY(rTargetRange.getHeight());
        double fTargetOffsetX(rTargetRange.getMinX());
        double fTargetOffsetY(rTargetRange.getMinY());

        // add object expansion
        if(0.0 != fAngle)
        {
            const double fAbsCos(fabs(cos(fAngle)));
            const double fAbsSin(fabs(sin(fAngle)));
            const double fNewX(fTargetSizeX * fAbsCos + fTargetSizeY * fAbsSin);
            const double fNewY(fTargetSizeY * fAbsCos + fTargetSizeX * fAbsSin);
            fTargetOffsetX -= (fNewX - fTargetSizeX) / 2.0;
            fTargetOffsetY -= (fNewY - fTargetSizeY) / 2.0;
            fTargetSizeX = fNewX;
            fTargetSizeY = fNewY;
        }

        const double fSizeWithoutBorder=1.0 - fBorder;
        if( bAxial )
        {
            o_rGradientInfo.maTextureTransform.scale(1.0, fSizeWithoutBorder * .5);
            o_rGradientInfo.maTextureTransform.translate(0.0, 0.5);
        }
        else
        {
            if(!fTools::equal(fSizeWithoutBorder, 1.0))
            {
                o_rGradientInfo.maTextureTransform.scale(1.0, fSizeWithoutBorder);
                o_rGradientInfo.maTextureTransform.translate(0.0, fBorder);
            }
        }

        o_rGradientInfo.maTextureTransform.scale(fTargetSizeX, fTargetSizeY);

        // add texture rotate after scale to keep perpendicular angles
        if(0.0 != fAngle)
        {
            const B2DPoint aCenter(0.5*fTargetSizeX,
                                   0.5*fTargetSizeY);
            o_rGradientInfo.maTextureTransform =
                o_rGradientInfo.maTextureTransform
                * basegfx::tools::createRotateAroundPoint(aCenter, fAngle);
        }

        // add object translate
        o_rGradientInfo.maTextureTransform.translate(fTargetOffsetX, fTargetOffsetY);

        // prepare aspect for texture
        o_rGradientInfo.mfAspectRatio = (0.0 != fTargetSizeY) ?  fTargetSizeX / fTargetSizeY : 1.0;

        // build transform from u,v to [0.0 .. 1.0].
        o_rGradientInfo.maBackTextureTransform = o_rGradientInfo.maTextureTransform;
        o_rGradientInfo.maBackTextureTransform.invert();
    }

    /** Most of the setup for radial & ellipsoidal gradient is the same,
        except for the border treatment. Factored out here.
    */
    static void initEllipticalGradientInfo(ODFGradientInfo& o_rGradientInfo,
                                           const B2DRange&  rTargetRange,
                                           const B2DVector& rOffset,
                                           sal_uInt32       nSteps,
                                           double           fBorder,
                                           double           fAngle,
                                           bool             bCircular)
    {
        o_rGradientInfo.maTextureTransform.identity();
        o_rGradientInfo.maBackTextureTransform.identity();
        o_rGradientInfo.mnSteps = nSteps;

        fAngle = -fAngle;

        double fTargetSizeX(rTargetRange.getWidth());
        double fTargetSizeY(rTargetRange.getHeight());
        double fTargetOffsetX(rTargetRange.getMinX());
        double fTargetOffsetY(rTargetRange.getMinY());

        // add object expansion
        if( bCircular )
        {
            const double fOriginalDiag(sqrt((fTargetSizeX * fTargetSizeX) + (fTargetSizeY * fTargetSizeY)));
            fTargetOffsetX -= (fOriginalDiag - fTargetSizeX) / 2.0;
            fTargetOffsetY -= (fOriginalDiag - fTargetSizeY) / 2.0;
            fTargetSizeX = fOriginalDiag;
            fTargetSizeY = fOriginalDiag;
        }
        else
        {
            fTargetOffsetX -= (0.4142 / 2.0 ) * fTargetSizeX;
            fTargetOffsetY -= (0.4142 / 2.0 ) * fTargetSizeY;
            fTargetSizeX = 1.4142 * fTargetSizeX;
            fTargetSizeY = 1.4142 * fTargetSizeY;
        }

        const double fHalfBorder((1.0 - fBorder) * 0.5);
        o_rGradientInfo.maTextureTransform.scale(fHalfBorder, fHalfBorder);

        o_rGradientInfo.maTextureTransform.translate(0.5, 0.5);
        o_rGradientInfo.maTextureTransform.scale(fTargetSizeX, fTargetSizeY);

        if( !bCircular )
        {
            // add texture rotate after scale to keep perpendicular angles
            if(0.0 != fAngle)
            {
                const B2DPoint aCenter(0.5*fTargetSizeX,
                                       0.5*fTargetSizeY);
                o_rGradientInfo.maTextureTransform =
                    o_rGradientInfo.maTextureTransform
                    * basegfx::tools::createRotateAroundPoint(aCenter, fAngle);
            }
        }

        // add defined offsets after rotation
        if(0.5 != rOffset.getX() || 0.5 != rOffset.getY())
        {
            // use original target size
            fTargetOffsetX += (rOffset.getX() - 0.5) * rTargetRange.getWidth();
            fTargetOffsetY += (rOffset.getY() - 0.5) * rTargetRange.getHeight();
        }

        // add object translate
        o_rGradientInfo.maTextureTransform.translate(fTargetOffsetX, fTargetOffsetY);

        // prepare aspect for texture
        o_rGradientInfo.mfAspectRatio = (0.0 != fTargetSizeY) ?  fTargetSizeX / fTargetSizeY : 1.0;

        // build transform from u,v to [0.0 .. 1.0].
        o_rGradientInfo.maBackTextureTransform = o_rGradientInfo.maTextureTransform;
        o_rGradientInfo.maBackTextureTransform.invert();
    }

    /** Setup for rect & square gradient is exactly the same. Factored out
        here.
    */
    static void initRectGradientInfo(ODFGradientInfo& o_rGradientInfo,
                                     const B2DRange&  rTargetRange,
                                     const B2DVector& rOffset,
                                     sal_uInt32       nSteps,
                                     double           fBorder,
                                     double           fAngle)
    {
        o_rGradientInfo.maTextureTransform.identity();
        o_rGradientInfo.maBackTextureTransform.identity();
        o_rGradientInfo.mnSteps = nSteps;

        fAngle = -fAngle;

        double fTargetSizeX(rTargetRange.getWidth());
        double fTargetSizeY(rTargetRange.getHeight());
        double fTargetOffsetX(rTargetRange.getMinX());
        double fTargetOffsetY(rTargetRange.getMinY());

        // add object expansion
        if(0.0 != fAngle)
        {
            const double fAbsCos(fabs(cos(fAngle)));
            const double fAbsSin(fabs(sin(fAngle)));
            const double fNewX(fTargetSizeX * fAbsCos + fTargetSizeY * fAbsSin);
            const double fNewY(fTargetSizeY * fAbsCos + fTargetSizeX * fAbsSin);
            fTargetOffsetX -= (fNewX - fTargetSizeX) / 2.0;
            fTargetOffsetY -= (fNewY - fTargetSizeY) / 2.0;
            fTargetSizeX = fNewX;
            fTargetSizeY = fNewY;
        }

        const double fHalfBorder((1.0 - fBorder) * 0.5);
        o_rGradientInfo.maTextureTransform.scale(fHalfBorder, fHalfBorder);

        o_rGradientInfo.maTextureTransform.translate(0.5, 0.5);
        o_rGradientInfo.maTextureTransform.scale(fTargetSizeX, fTargetSizeY);

        // add texture rotate after scale to keep perpendicular angles
        if(0.0 != fAngle)
        {
            const B2DPoint aCenter(0.5*fTargetSizeX,
                                   0.5*fTargetSizeY);
            o_rGradientInfo.maTextureTransform =
                o_rGradientInfo.maTextureTransform
                * basegfx::tools::createRotateAroundPoint(aCenter, fAngle);
        }

        // add defined offsets after rotation
        if(0.5 != rOffset.getX() || 0.5 != rOffset.getY())
        {
            // use scaled target size
            fTargetOffsetX += (rOffset.getX() - 0.5) * fTargetSizeX;
            fTargetOffsetY += (rOffset.getY() - 0.5) * fTargetSizeY;
        }

        // add object translate
        o_rGradientInfo.maTextureTransform.translate(fTargetOffsetX, fTargetOffsetY);

        // prepare aspect for texture
        o_rGradientInfo.mfAspectRatio = (0.0 != fTargetSizeY) ?  fTargetSizeX / fTargetSizeY : 1.0;

        // build transform from u,v to [0.0 .. 1.0]. As base, use inverse texture transform
        o_rGradientInfo.maBackTextureTransform = o_rGradientInfo.maTextureTransform;
        o_rGradientInfo.maBackTextureTransform.invert();
    }

    namespace tools
    {
        ODFGradientInfo& createLinearODFGradientInfo(ODFGradientInfo& o_rGradientInfo,
                                                     const B2DRange&  rTargetArea,
                                                     sal_uInt32       nSteps,
                                                     double           fBorder,
                                                     double           fAngle)
        {
            init1DGradientInfo(o_rGradientInfo,
                               rTargetArea,
                               nSteps,
                               fBorder,
                               fAngle,
                               false);
            return o_rGradientInfo;
        }

        ODFGradientInfo& createAxialODFGradientInfo(ODFGradientInfo& o_rGradientInfo,
                                                    const B2DRange&  rTargetArea,
                                                    sal_uInt32       nSteps,
                                                    double           fBorder,
                                                    double           fAngle)
        {
            init1DGradientInfo(o_rGradientInfo,
                               rTargetArea,
                               nSteps,
                               fBorder,
                               fAngle,
                               true);
            return o_rGradientInfo;
        }

        ODFGradientInfo& createRadialODFGradientInfo(ODFGradientInfo& o_rGradientInfo,
                                                     const B2DRange&  rTargetArea,
                                                     const B2DVector& rOffset,
                                                     sal_uInt32       nSteps,
                                                     double           fBorder)
        {
            initEllipticalGradientInfo(o_rGradientInfo,
                                       rTargetArea,
                                       rOffset,
                                       nSteps,
                                       fBorder,
                                       0.0,
                                       true);
            return o_rGradientInfo;
        }

        ODFGradientInfo& createEllipticalODFGradientInfo(ODFGradientInfo& o_rGradientInfo,
                                                         const B2DRange&  rTargetArea,
                                                         const B2DVector& rOffset,
                                                         sal_uInt32       nSteps,
                                                         double           fBorder,
                                                         double           fAngle)
        {
            initEllipticalGradientInfo(o_rGradientInfo,
                                       rTargetArea,
                                       rOffset,
                                       nSteps,
                                       fBorder,
                                       fAngle,
                                       false);
            return o_rGradientInfo;
        }

        ODFGradientInfo& createSquareODFGradientInfo(ODFGradientInfo& o_rGradientInfo,
                                                     const B2DRange&  rTargetArea,
                                                     const B2DVector& rOffset,
                                                     sal_uInt32       nSteps,
                                                     double           fBorder,
                                                     double           fAngle)
        {
            initRectGradientInfo(o_rGradientInfo,
                                 rTargetArea,
                                 rOffset,
                                 nSteps,
                                 fBorder,
                                 fAngle);
            return o_rGradientInfo;
        }

        ODFGradientInfo& createRectangularODFGradientInfo(ODFGradientInfo& o_rGradientInfo,
                                                          const B2DRange&  rTargetArea,
                                                          const B2DVector& rOffset,
                                                          sal_uInt32       nSteps,
                                                          double           fBorder,
                                                          double           fAngle)
        {
            initRectGradientInfo(o_rGradientInfo,
                                 rTargetArea,
                                 rOffset,
                                 nSteps,
                                 fBorder,
                                 fAngle);
            return o_rGradientInfo;
        }

    } // namespace tools

} // namespace basegfx
<commit_msg>#i105937# Post-merge fixes<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: canvastools.cxx,v $
 * $Revision: 1.12 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_basegfx.hxx"

#include <basegfx/tools/gradienttools.hxx>
#include <basegfx/point/b2dpoint.hxx>
#include <basegfx/range/b2drange.hxx>
#include <basegfx/matrix/b2dhommatrixtools.hxx>

namespace basegfx
{
    /** Most of the setup for linear & axial gradient is the same, except
        for the border treatment. Factored out here.
    */
    static void init1DGradientInfo(ODFGradientInfo& o_rGradientInfo,
                                   const B2DRange&  rTargetRange,
                                   sal_uInt32       nSteps,
                                   double           fBorder,
                                   double           fAngle,
                                   bool             bAxial)
    {
        o_rGradientInfo.maTextureTransform.identity();
        o_rGradientInfo.maBackTextureTransform.identity();
        o_rGradientInfo.mnSteps = nSteps;

        fAngle = -fAngle;

        double fTargetSizeX(rTargetRange.getWidth());
        double fTargetSizeY(rTargetRange.getHeight());
        double fTargetOffsetX(rTargetRange.getMinX());
        double fTargetOffsetY(rTargetRange.getMinY());

        // add object expansion
        if(0.0 != fAngle)
        {
            const double fAbsCos(fabs(cos(fAngle)));
            const double fAbsSin(fabs(sin(fAngle)));
            const double fNewX(fTargetSizeX * fAbsCos + fTargetSizeY * fAbsSin);
            const double fNewY(fTargetSizeY * fAbsCos + fTargetSizeX * fAbsSin);
            fTargetOffsetX -= (fNewX - fTargetSizeX) / 2.0;
            fTargetOffsetY -= (fNewY - fTargetSizeY) / 2.0;
            fTargetSizeX = fNewX;
            fTargetSizeY = fNewY;
        }

        const double fSizeWithoutBorder=1.0 - fBorder;
        if( bAxial )
        {
            o_rGradientInfo.maTextureTransform.scale(1.0, fSizeWithoutBorder * .5);
            o_rGradientInfo.maTextureTransform.translate(0.0, 0.5);
        }
        else
        {
            if(!fTools::equal(fSizeWithoutBorder, 1.0))
            {
                o_rGradientInfo.maTextureTransform.scale(1.0, fSizeWithoutBorder);
                o_rGradientInfo.maTextureTransform.translate(0.0, fBorder);
            }
        }

        o_rGradientInfo.maTextureTransform.scale(fTargetSizeX, fTargetSizeY);

        // add texture rotate after scale to keep perpendicular angles
        if(0.0 != fAngle)
        {
            const B2DPoint aCenter(0.5*fTargetSizeX,
                                   0.5*fTargetSizeY);
            o_rGradientInfo.maTextureTransform *=
                basegfx::tools::createRotateAroundPoint(aCenter, fAngle);
        }

        // add object translate
        o_rGradientInfo.maTextureTransform.translate(fTargetOffsetX, fTargetOffsetY);

        // prepare aspect for texture
        o_rGradientInfo.mfAspectRatio = (0.0 != fTargetSizeY) ?  fTargetSizeX / fTargetSizeY : 1.0;

        // build transform from u,v to [0.0 .. 1.0].
        o_rGradientInfo.maBackTextureTransform = o_rGradientInfo.maTextureTransform;
        o_rGradientInfo.maBackTextureTransform.invert();
    }

    /** Most of the setup for radial & ellipsoidal gradient is the same,
        except for the border treatment. Factored out here.
    */
    static void initEllipticalGradientInfo(ODFGradientInfo& o_rGradientInfo,
                                           const B2DRange&  rTargetRange,
                                           const B2DVector& rOffset,
                                           sal_uInt32       nSteps,
                                           double           fBorder,
                                           double           fAngle,
                                           bool             bCircular)
    {
        o_rGradientInfo.maTextureTransform.identity();
        o_rGradientInfo.maBackTextureTransform.identity();
        o_rGradientInfo.mnSteps = nSteps;

        fAngle = -fAngle;

        double fTargetSizeX(rTargetRange.getWidth());
        double fTargetSizeY(rTargetRange.getHeight());
        double fTargetOffsetX(rTargetRange.getMinX());
        double fTargetOffsetY(rTargetRange.getMinY());

        // add object expansion
        if( bCircular )
        {
            const double fOriginalDiag(sqrt((fTargetSizeX * fTargetSizeX) + (fTargetSizeY * fTargetSizeY)));
            fTargetOffsetX -= (fOriginalDiag - fTargetSizeX) / 2.0;
            fTargetOffsetY -= (fOriginalDiag - fTargetSizeY) / 2.0;
            fTargetSizeX = fOriginalDiag;
            fTargetSizeY = fOriginalDiag;
        }
        else
        {
            fTargetOffsetX -= (0.4142 / 2.0 ) * fTargetSizeX;
            fTargetOffsetY -= (0.4142 / 2.0 ) * fTargetSizeY;
            fTargetSizeX = 1.4142 * fTargetSizeX;
            fTargetSizeY = 1.4142 * fTargetSizeY;
        }

        const double fHalfBorder((1.0 - fBorder) * 0.5);
        o_rGradientInfo.maTextureTransform.scale(fHalfBorder, fHalfBorder);

        o_rGradientInfo.maTextureTransform.translate(0.5, 0.5);
        o_rGradientInfo.maTextureTransform.scale(fTargetSizeX, fTargetSizeY);

        // add texture rotate after scale to keep perpendicular angles
        if( !bCircular && 0.0 != fAngle)
        {
            const B2DPoint aCenter(0.5*fTargetSizeX,
                                   0.5*fTargetSizeY);
            o_rGradientInfo.maTextureTransform *=
                basegfx::tools::createRotateAroundPoint(aCenter, fAngle);
        }

        // add defined offsets after rotation
        if(0.5 != rOffset.getX() || 0.5 != rOffset.getY())
        {
            // use original target size
            fTargetOffsetX += (rOffset.getX() - 0.5) * rTargetRange.getWidth();
            fTargetOffsetY += (rOffset.getY() - 0.5) * rTargetRange.getHeight();
        }

        // add object translate
        o_rGradientInfo.maTextureTransform.translate(fTargetOffsetX, fTargetOffsetY);

        // prepare aspect for texture
        o_rGradientInfo.mfAspectRatio = (0.0 != fTargetSizeY) ?  fTargetSizeX / fTargetSizeY : 1.0;

        // build transform from u,v to [0.0 .. 1.0].
        o_rGradientInfo.maBackTextureTransform = o_rGradientInfo.maTextureTransform;
        o_rGradientInfo.maBackTextureTransform.invert();
    }

    /** Setup for rect & square gradient is exactly the same. Factored out
        here.
    */
    static void initRectGradientInfo(ODFGradientInfo& o_rGradientInfo,
                                     const B2DRange&  rTargetRange,
                                     const B2DVector& rOffset,
                                     sal_uInt32       nSteps,
                                     double           fBorder,
                                     double           fAngle)
    {
        o_rGradientInfo.maTextureTransform.identity();
        o_rGradientInfo.maBackTextureTransform.identity();
        o_rGradientInfo.mnSteps = nSteps;

        fAngle = -fAngle;

        double fTargetSizeX(rTargetRange.getWidth());
        double fTargetSizeY(rTargetRange.getHeight());
        double fTargetOffsetX(rTargetRange.getMinX());
        double fTargetOffsetY(rTargetRange.getMinY());

        // add object expansion
        if(0.0 != fAngle)
        {
            const double fAbsCos(fabs(cos(fAngle)));
            const double fAbsSin(fabs(sin(fAngle)));
            const double fNewX(fTargetSizeX * fAbsCos + fTargetSizeY * fAbsSin);
            const double fNewY(fTargetSizeY * fAbsCos + fTargetSizeX * fAbsSin);
            fTargetOffsetX -= (fNewX - fTargetSizeX) / 2.0;
            fTargetOffsetY -= (fNewY - fTargetSizeY) / 2.0;
            fTargetSizeX = fNewX;
            fTargetSizeY = fNewY;
        }

        const double fHalfBorder((1.0 - fBorder) * 0.5);
        o_rGradientInfo.maTextureTransform.scale(fHalfBorder, fHalfBorder);

        o_rGradientInfo.maTextureTransform.translate(0.5, 0.5);
        o_rGradientInfo.maTextureTransform.scale(fTargetSizeX, fTargetSizeY);

        // add texture rotate after scale to keep perpendicular angles
        if(0.0 != fAngle)
        {
            const B2DPoint aCenter(0.5*fTargetSizeX,
                                   0.5*fTargetSizeY);
            o_rGradientInfo.maTextureTransform *=
                basegfx::tools::createRotateAroundPoint(aCenter, fAngle);
        }

        // add defined offsets after rotation
        if(0.5 != rOffset.getX() || 0.5 != rOffset.getY())
        {
            // use scaled target size
            fTargetOffsetX += (rOffset.getX() - 0.5) * fTargetSizeX;
            fTargetOffsetY += (rOffset.getY() - 0.5) * fTargetSizeY;
        }

        // add object translate
        o_rGradientInfo.maTextureTransform.translate(fTargetOffsetX, fTargetOffsetY);

        // prepare aspect for texture
        o_rGradientInfo.mfAspectRatio = (0.0 != fTargetSizeY) ?  fTargetSizeX / fTargetSizeY : 1.0;

        // build transform from u,v to [0.0 .. 1.0]. As base, use inverse texture transform
        o_rGradientInfo.maBackTextureTransform = o_rGradientInfo.maTextureTransform;
        o_rGradientInfo.maBackTextureTransform.invert();
    }

    namespace tools
    {
        ODFGradientInfo& createLinearODFGradientInfo(ODFGradientInfo& o_rGradientInfo,
                                                     const B2DRange&  rTargetArea,
                                                     sal_uInt32       nSteps,
                                                     double           fBorder,
                                                     double           fAngle)
        {
            init1DGradientInfo(o_rGradientInfo,
                               rTargetArea,
                               nSteps,
                               fBorder,
                               fAngle,
                               false);
            return o_rGradientInfo;
        }

        ODFGradientInfo& createAxialODFGradientInfo(ODFGradientInfo& o_rGradientInfo,
                                                    const B2DRange&  rTargetArea,
                                                    sal_uInt32       nSteps,
                                                    double           fBorder,
                                                    double           fAngle)
        {
            init1DGradientInfo(o_rGradientInfo,
                               rTargetArea,
                               nSteps,
                               fBorder,
                               fAngle,
                               true);
            return o_rGradientInfo;
        }

        ODFGradientInfo& createRadialODFGradientInfo(ODFGradientInfo& o_rGradientInfo,
                                                     const B2DRange&  rTargetArea,
                                                     const B2DVector& rOffset,
                                                     sal_uInt32       nSteps,
                                                     double           fBorder)
        {
            initEllipticalGradientInfo(o_rGradientInfo,
                                       rTargetArea,
                                       rOffset,
                                       nSteps,
                                       fBorder,
                                       0.0,
                                       true);
            return o_rGradientInfo;
        }

        ODFGradientInfo& createEllipticalODFGradientInfo(ODFGradientInfo& o_rGradientInfo,
                                                         const B2DRange&  rTargetArea,
                                                         const B2DVector& rOffset,
                                                         sal_uInt32       nSteps,
                                                         double           fBorder,
                                                         double           fAngle)
        {
            initEllipticalGradientInfo(o_rGradientInfo,
                                       rTargetArea,
                                       rOffset,
                                       nSteps,
                                       fBorder,
                                       fAngle,
                                       false);
            return o_rGradientInfo;
        }

        ODFGradientInfo& createSquareODFGradientInfo(ODFGradientInfo& o_rGradientInfo,
                                                     const B2DRange&  rTargetArea,
                                                     const B2DVector& rOffset,
                                                     sal_uInt32       nSteps,
                                                     double           fBorder,
                                                     double           fAngle)
        {
            initRectGradientInfo(o_rGradientInfo,
                                 rTargetArea,
                                 rOffset,
                                 nSteps,
                                 fBorder,
                                 fAngle);
            return o_rGradientInfo;
        }

        ODFGradientInfo& createRectangularODFGradientInfo(ODFGradientInfo& o_rGradientInfo,
                                                          const B2DRange&  rTargetArea,
                                                          const B2DVector& rOffset,
                                                          sal_uInt32       nSteps,
                                                          double           fBorder,
                                                          double           fAngle)
        {
            initRectGradientInfo(o_rGradientInfo,
                                 rTargetArea,
                                 rOffset,
                                 nSteps,
                                 fBorder,
                                 fAngle);
            return o_rGradientInfo;
        }

    } // namespace tools

} // namespace basegfx
<|endoftext|>


<commit_before>#include <iostream>
#include <regex>
#include <string>
#include <vector>

using namespace std;

class Layer {
 public:
  vector<vector<vector<double>>> h(vector<vector<vector<double>>> x);

  // Helper function
  static void rand_init(vector<vector<double>> matrix, int height, int width) {
    for (int i = 0; i < height; i++) {
      for (int j = 0; j < width; j++) {
        // use numbers between -100 and 100
        double n = (double)rand() / RAND_MAX;  // scales rand() to [0, 1].
        n = n * 200 - 100;
        matrix[i][j] = n;  // (possibly) change to use float to save memory
      }
    }
  }
};

class Conv : public Layer {
 public:
  int num_input_channels;
  int num_filters;
  vector<int> size_per_filter;
  vector<int> stride_per_filter;

  vector<vector<vector<double>>> filters;
  Conv(int num_input_channels, int num_filters, vector<int> size_per_filter, vector<int> stride_per_filter) {
    num_input_channels = num_input_channels;
    num_filters = num_filters;
    size_per_filter = size_per_filter;
    stride_per_filter = stride_per_filter;

    for (int filter_num; filter_num < num_filters; filter_num++) {
      // Filters are square
      int height = size_per_filter[filter_num];
      int width = size_per_filter[filter_num];

      vector<vector<double>> filter;
      Layer().rand_init(filter, height, width);
      filters[filter_num] = filter;
    }
  }

  vector<vector<vector<double>>> h(vector<vector<vector<double>>> a) {
    // Input and output is height x width x num_channels
    // First filter adds to the output of the first channel only, etc.

    // feature map (or activation map) is the output of one filter (or kernel or detector)
    vector<vector<vector<double>>> output_block;
    for (vector<vector<double>> filter : filters) {  // Should be embarrassingly parallel
      vector<vector<double>> feature_map = convolve(a, filter, stride_per_filter);
    }
  }

  // static because this is a self-contained method
  vector<vector<double>> static convolve(vector<vector<vector<double>>> a, vector<vector<double>> filter,
                                         vector<int> stride_per_filter) {
    // a is height x width x num_channels
    // Let's say a is 10x10x3 and filter is 3x3
    // The first convolutional step will use a's top left corner block of size 3x3x3
    // For each (i, j, [1, 2, 3]) section of a, we use the same (i, j)th weight of filter to flatten it
    // In other words, we do a[i][j][1]*w + a[i][j][2]*w + a[i][j][3]*w.
    // This produces a 3x3x1 which we then element-wise multiply with filter which is also 3x3x1 to
    // produce 3x3x1 multiplications. These are then all added together to produce one output per
    // convolutional step.
    // Reference:
    // https://stats.stackexchange.com/questions/335321/in-a-convolutional-neural-network-cnn-when-convolving-the-image-is-the-opera

    int height = a.size();
    int width = a[0].size();
    int depth = a[0][0].size();

    //TODO
};

class Pool : public Layer {};

class Act : public Layer {};

class Dense : public Layer {};

class ConvNet {
 public:
  vector<Layer> layers;
  ConvNet(vector<Layer> layers) { layers = layers; }

  int h(vector<vector<vector<double>>> x) {  // Returns an int, a classification
    for (Layer layer : layers) {
      vector<vector<vector<double>>> a = layer.h(x);
    }
  }
};

int main() {
  // TEST
  cout << "Starting test...\n";

  int num_images = 100;
  vector<vector<vector<vector<double>>>> X;  // num_images x height x width x num_channels
  int Y[num_images];                         // labels for each example

  // Randomly initialize X and Y
  for (int i = 0; i < num_images; i++) {
    for (int j = 0; j < 28; j++) {
      for (int k = 0; k < 28; k++) {
        // use numbers from 0 to 255
        X[i][j][k][1] = rand() % 255;
      }
    }
    Y[i] = rand() % 10;  // TODO: Maybe decrease number of classes for the test?
  }

  // Look at first 2 "images"
  for (int i = 0; i < 2; i++) {
    for (int j = 0; j < 28; j++) {
      for (int k = 0; k < 28; k++) {
        cout << X[j][k][i][1] << ",";
      }
      cout << endl;
    }
    cout << endl;
  }

  // Intialize model
  // Compound literal, (vector[]), helps initialize an array in function call
  ConvNet model = ConvNet(vector<Layer>{Conv(1, 4, (vector<int>){3, 5}, (vector<int>){1, 2})});

  // Do a forward pass with the first "image"
  model.h(X[1]);

  cout << "Test finished!\n";

  // Main

  return 0;
}
<commit_msg>Implementing by layer convolution<commit_after>#include <iostream>
#include <regex>
#include <string>
#include <vector>

using namespace std;

// Good diagram: https://engmrk.com/wp-content/uploads/2018/09/Image-Architecture-of-Convolutional-Neural-Network.png

class Layer {
 public:
  vector<vector<vector<double>>> h(vector<vector<vector<double>>> x);

  // Helper function
  static void rand_init(vector<vector<double>> matrix, int height, int width) {
    for (int i = 0; i < height; i++) {
      for (int j = 0; j < width; j++) {
        // use numbers between -100 and 100
        double n = (double)rand() / RAND_MAX;  // scales rand() to [0, 1].
        n = n * 200 - 100;
        matrix[i][j] = n;  // (possibly) change to use float to save memory
      }
    }
  }
};

class Conv : public Layer {
 public:
  int num_input_channels;
  int num_filters;
  vector<int> size_per_filter;
  vector<int> stride_per_filter;

  vector<vector<vector<double>>> filters;
  Conv(int num_input_channels, int num_filters, vector<int> size_per_filter, vector<int> stride_per_filter) {
    // TODO: Check if there is a better way to save these.
    num_input_channels = num_input_channels;
    num_filters = num_filters;
    size_per_filter = size_per_filter;
    stride_per_filter = stride_per_filter;

    for (int filter_num; filter_num < num_filters; filter_num++) {
      // Filters are square
      int height = size_per_filter[filter_num];
      int width = size_per_filter[filter_num];

      vector<vector<double>> filter;
      Layer().rand_init(filter, height, width);
      filters[filter_num] = filter;
    }
  }

  vector<vector<vector<double>>> h(vector<vector<vector<double>>> a) {
    // Input and output is height x width x num_channels
    // First filter adds to the output of the first channel only, etc.

    // feature map (or activation map) is the output of one filter (or kernel or detector)
    vector<vector<vector<double>>> output_block;
    int num_filters = filters.size();
    for (int i = 0; i < num_filters; i++) {  // Should be embarrassingly parallel
      vector<vector<double>> feature_map = convolve(a, filters[i], stride_per_filter[i]);
    }
  }

  // static because this is a self-contained method
  vector<vector<double>> static convolve(vector<vector<vector<double>>> a, vector<vector<double>> filter, int stride) {
    // a is height x width x num_channels
    // Let's say a is 10x10x3 and filter is 3x3
    // The first convolutional step will use a's top left corner block of size 3x3x3
    // For each (i, j, [1, 2, 3]) section of a, we use the same (i, j)th weight of filter to flatten it
    // In other words, we do a[i][j][1]*w + a[i][j][2]*w + a[i][j][3]*w.
    // This produces a 3x3x1 which we then element-wise multiply with filter which is also 3x3x1 to
    // produce 3x3x1 multiplications. These are then all added together to produce one output per
    // convolutional step.
    // Reference:
    // https://stats.stackexchange.com/questions/335321/in-a-convolutional-neural-network-cnn-when-convolving-the-image-is-the-opera

    int height = a.size();
    int width = a[0].size();
    int depth = a[0][0].size();

    vector<vector<double>> feature_map;
    int depth_of_a = a.size();
    for (int depth = 0; depth < depth_of_a; depth++) {
      vector<vector<double>> feature_map_per_depth = _convole(a[depth], filter, stride);
    }

    //TODO
  }

  vector<vector<double>> static _convole(vector<vector<double>> a, vector<vector<double>> filter, int stride) {
    //TODO
  }
};

class Pool : public Layer {};

class Act : public Layer {};

class Dense : public Layer {};

class ConvNet {
 public:
  vector<Layer> layers;
  ConvNet(vector<Layer> layers) { layers = layers; }

  int h(vector<vector<vector<double>>> x) {  // Returns an int, a classification
    vector<vector<vector<double>>> a = x;
    for (Layer layer : layers) {
      vector<vector<vector<double>>> a = layer.h(a);
    }
    // Convert the final output into a classification
  }
};

int main() {
  // TEST
  cout << "Starting test...\n";

  int num_images = 100;
  vector<vector<vector<vector<double>>>> X;  // num_images x height x width x num_channels
  int Y[num_images];                         // labels for each example

  // Randomly initialize X and Y
  for (int i = 0; i < num_images; i++) {
    for (int j = 0; j < 28; j++) {
      for (int k = 0; k < 28; k++) {
        // use numbers from 0 to 255
        X[i][j][k][1] = rand() % 255;
      }
    }
    Y[i] = rand() % 10;  // TODO: Maybe decrease number of classes for the test?
  }

  // Look at first 2 "images"
  for (int i = 0; i < 2; i++) {
    for (int j = 0; j < 28; j++) {
      for (int k = 0; k < 28; k++) {
        cout << X[j][k][i][1] << ",";
      }
      cout << endl;
    }
    cout << endl;
  }

  // Intialize model
  // Compound literal, (vector[]), helps initialize an array in function call
  ConvNet model = ConvNet(vector<Layer>{Conv(1, 4, (vector<int>){3, 3, 5, 5}, (vector<int>){1, 1, 2, 2})});

  // Do a forward pass with the first "image"
  model.h(X[1]);

  cout << "Test finished!\n";

  // Main

  return 0;
}
<|endoftext|>


<commit_before>// Begin CVS Header
//   $Source: /Volumes/Home/Users/shoops/cvs/copasi_dev/copasi/UI/CQSensResultWidget.cpp,v $
//   $Revision: 1.13 $
//   $Name:  $
//   $Author: shoops $
//   $Date: 2009/07/16 15:47:26 $
// End CVS Header

// Copyright (C) 2008 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc., EML Research, gGmbH, University of Heidelberg,
// and The University of Manchester.
// All rights reserved.

// Copyright (C) 2001 - 2007 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc. and EML Research, gGmbH.
// All rights reserved.

//#include <qpushbutton.h>
#include <qlayout.h>
#include <qlineedit.h>
#include <qlabel.h>
#include <q3table.h>
//Added by qt3to4:
#include <Q3GridLayout>

#include "copasi.h"

#include "CQSensResultWidget.h"
//#include "StateSubwidget.h"
//#include "CTimeSeriesTable.h"
#include "qtUtilities.h"
#include "sensitivities/CSensTask.h"
#include "sensitivities/CSensProblem.h"

#include "CopasiDataModel/CCopasiDataModel.h"
#include "report/CCopasiRootContainer.h"
#include "utilities/CCopasiVector.h"

#include <qtabwidget.h>

/*
 *  Constructs a CQSensResultWidget which is a child of 'parent', with the
 *  name 'name' and widget flags set to 'f'.
 */
CQSensResultWidget::CQSensResultWidget(QWidget* parent, const char* name, Qt::WFlags fl)
    : CopasiWidget(parent, name, fl),
    mpResult(NULL)
{
  if (!name)
    setName("CQSensResultWidget");

  setCaption("CQSensResultWidget");

  mWidgetLayout = new Q3GridLayout(this, 1, 1, 11, 6, "CQSensResultWidgetLayout");

  // **********  Label **************
  mLabelTitle = new QLabel(this, "SensLabel");
  mLabelTitle->setText("Sensitivities");
  mLabelTitle->setAlignment(int(Qt::AlignVCenter
                                | Qt::AlignLeft));
  mLabelTitle->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
  mWidgetLayout->addWidget(mLabelTitle, 0, 0);

  // tab widget
  mpTab = new QTabWidget(this, "TabWidget");
  mWidgetLayout->addMultiCellWidget(mpTab, 1, 2, 0, 2);

  // unscaled array
  mArrayWidget = new CQArrayAnnotationsWidget(mpTab, "ArrayWidget");
  //mArrayWidget->setColorCoding(new CColorScale1());
  //CColorScaleAverage * tcs = new CColorScaleAverage();
  CColorScaleBiLog * tcs = new CColorScaleBiLog();
  mArrayWidget->setColorCoding(tcs);
  //tcs->setMinMax(-1,1);
  //tcs->setSymmetric(true);
  //tcs->setFactor(3.0);
  mArrayWidget->setColorScalingAutomatic(true);
  mpTab->addTab(mArrayWidget, "unscaled");

  //scaled array
  mArrayWidgetScaled = new CQArrayAnnotationsWidget(mpTab, "ArrayWidget2");
  //mArrayWidgetScaled->setColorCoding(new CColorScale1());
  CColorScaleAverage* tcs2 = new CColorScaleAverage();
  mArrayWidgetScaled->setColorCoding(tcs2);
  //tcs2->setMinMax(-1,1);
  //tcs2->setSymmetric(true);
  tcs2->setFactor(3.0);
  mArrayWidgetScaled->setColorScalingAutomatic(true);
  mpTab->addTab(mArrayWidgetScaled, "scaled");

  //scaled array
  mArrayWidgetCollapsed = new CQArrayAnnotationsWidget(mpTab, "ArrayWidget3");
  //mArrayWidgetScaled->setColorCoding(new CColorScale1());
  CColorScaleAverage* tcs3 = new CColorScaleAverage();
  mArrayWidgetCollapsed->setColorCoding(tcs3);
  //tcs3->setMinMax(-1,1);
  //tcs3->setSymmetric(true);
  tcs3->setFactor(3.0);
  mArrayWidgetCollapsed->setColorScalingAutomatic(true);
  mpTab->addTab(mArrayWidgetCollapsed, "summarized");
}

/*
 *  Destroys the object and frees any allocated resources
 */
CQSensResultWidget::~CQSensResultWidget()
{}

void CQSensResultWidget::newResult()
{
  assert(CCopasiRootContainer::getDatamodelList()->size() > 0);
  CSensTask * pTask =
    dynamic_cast<CSensTask*>((*(*CCopasiRootContainer::getDatamodelList())[0]->getTaskList())["Sensitivities"]);

  if (!pTask)
    {
      clearArrays();
      return;
    }

  CSensProblem * pProblem = dynamic_cast< CSensProblem * >(pTask->getProblem());

  if (!pProblem)
    {
      clearArrays();
      return;
    }

  mpResult = pProblem->getResultAnnotated();
  mpScaledResult = pProblem->getScaledResultAnnotated();

  mArrayWidget->setArrayAnnotation(mpResult);
  mArrayWidgetScaled->setArrayAnnotation(mpScaledResult);

  //tab for collapsed result
  if (pProblem->collapsRequested())
    {
      mpCollapsedResult = pProblem->getCollapsedResultAnnotated();
      mpTab->setTabEnabled(mArrayWidgetCollapsed, true);
    }
  else
    {
      mpCollapsedResult = NULL;
      mpTab->setTabEnabled(mArrayWidgetCollapsed, false);
    }

  mArrayWidgetCollapsed->setArrayAnnotation(mpCollapsedResult);
}

void CQSensResultWidget::clearArrays()
{
  mArrayWidget->setArrayAnnotation(NULL);
  mArrayWidgetScaled->setArrayAnnotation(NULL);
  mArrayWidgetCollapsed->setArrayAnnotation(NULL);
}

//*************************************

bool CQSensResultWidget::update(ListViews::ObjectType C_UNUSED(objectType), ListViews::Action
                                C_UNUSED(action), const std::string & C_UNUSED(key))
{
  /*  if (this->isShown())
      return loadFromBackend();
    else
      return true;*/
  return true;
}

bool CQSensResultWidget::leave()
{
  return true;
}

bool CQSensResultWidget::enterProtected()
{
  //clear the widget if the pointer to the result has changed
  assert(CCopasiRootContainer::getDatamodelList()->size() > 0);
  CSensTask * pTask =
    dynamic_cast<CSensTask*>((*(*CCopasiRootContainer::getDatamodelList())[0]->getTaskList())["Sensitivities"]);

  if (!pTask)
    {
      clearArrays();
      return false;
    }

  CSensProblem * pProblem = dynamic_cast< CSensProblem * >(pTask->getProblem());

  if (!pProblem)
    {
      clearArrays();
      return false;
    }

  if (mpResult != pProblem->getResultAnnotated())
    {
      clearArrays();
      return false;
    }

  return true;
}
<commit_msg>Fix a bug: the old one should be deleted before filling it with new result.<commit_after>// Begin CVS Header
//   $Source: /Volumes/Home/Users/shoops/cvs/copasi_dev/copasi/UI/CQSensResultWidget.cpp,v $
//   $Revision: 1.14 $
//   $Name:  $
//   $Author: pwilly $
//   $Date: 2010/01/21 10:49:19 $
// End CVS Header

// Copyright (C) 2008 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc., EML Research, gGmbH, University of Heidelberg,
// and The University of Manchester.
// All rights reserved.

// Copyright (C) 2001 - 2007 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc. and EML Research, gGmbH.
// All rights reserved.

//#include <qpushbutton.h>
#include <qlayout.h>
#include <qlineedit.h>
#include <qlabel.h>
#include <q3table.h>
//Added by qt3to4:
#include <Q3GridLayout>

#include "copasi.h"

#include "CQSensResultWidget.h"
//#include "StateSubwidget.h"
//#include "CTimeSeriesTable.h"
#include "qtUtilities.h"
#include "sensitivities/CSensTask.h"
#include "sensitivities/CSensProblem.h"

#include "CopasiDataModel/CCopasiDataModel.h"
#include "report/CCopasiRootContainer.h"
#include "utilities/CCopasiVector.h"

#include <qtabwidget.h>

/*
 *  Constructs a CQSensResultWidget which is a child of 'parent', with the
 *  name 'name' and widget flags set to 'f'.
 */
CQSensResultWidget::CQSensResultWidget(QWidget* parent, const char* name, Qt::WFlags fl)
    : CopasiWidget(parent, name, fl),
    mpResult(NULL)
{
  if (!name)
    setName("CQSensResultWidget");

  setCaption("CQSensResultWidget");

  mWidgetLayout = new Q3GridLayout(this, 1, 1, 11, 6, "CQSensResultWidgetLayout");

  // **********  Label **************
  mLabelTitle = new QLabel(this, "SensLabel");
  mLabelTitle->setText("Sensitivities");
  mLabelTitle->setAlignment(int(Qt::AlignVCenter
                                | Qt::AlignLeft));
  mLabelTitle->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
  mWidgetLayout->addWidget(mLabelTitle, 0, 0);

  // tab widget
  mpTab = new QTabWidget(this, "TabWidget");
  mWidgetLayout->addMultiCellWidget(mpTab, 1, 2, 0, 2);

  // unscaled array
  mArrayWidget = new CQArrayAnnotationsWidget(mpTab, "ArrayWidget");
  //mArrayWidget->setColorCoding(new CColorScale1());
  //CColorScaleAverage * tcs = new CColorScaleAverage();
  CColorScaleBiLog * tcs = new CColorScaleBiLog();
  mArrayWidget->setColorCoding(tcs);
  //tcs->setMinMax(-1,1);
  //tcs->setSymmetric(true);
  //tcs->setFactor(3.0);
  mArrayWidget->setColorScalingAutomatic(true);
  mpTab->addTab(mArrayWidget, "unscaled");

  //scaled array
  mArrayWidgetScaled = new CQArrayAnnotationsWidget(mpTab, "ArrayWidget2");
  //mArrayWidgetScaled->setColorCoding(new CColorScale1());
  CColorScaleAverage* tcs2 = new CColorScaleAverage();
  mArrayWidgetScaled->setColorCoding(tcs2);
  //tcs2->setMinMax(-1,1);
  //tcs2->setSymmetric(true);
  tcs2->setFactor(3.0);
  mArrayWidgetScaled->setColorScalingAutomatic(true);
  mpTab->addTab(mArrayWidgetScaled, "scaled");

  //scaled array
  mArrayWidgetCollapsed = new CQArrayAnnotationsWidget(mpTab, "ArrayWidget3");
  //mArrayWidgetScaled->setColorCoding(new CColorScale1());
  CColorScaleAverage* tcs3 = new CColorScaleAverage();
  mArrayWidgetCollapsed->setColorCoding(tcs3);
  //tcs3->setMinMax(-1,1);
  //tcs3->setSymmetric(true);
  tcs3->setFactor(3.0);
  mArrayWidgetCollapsed->setColorScalingAutomatic(true);
  mpTab->addTab(mArrayWidgetCollapsed, "summarized");
}

/*
 *  Destroys the object and frees any allocated resources
 */
CQSensResultWidget::~CQSensResultWidget()
{}

void CQSensResultWidget::newResult()
{
  assert(CCopasiRootContainer::getDatamodelList()->size() > 0);

  // clear the old one
  clearArrays();

  CSensTask * pTask =
    dynamic_cast<CSensTask*>((*(*CCopasiRootContainer::getDatamodelList())[0]->getTaskList())["Sensitivities"]);

  if (!pTask)
    return;

  CSensProblem * pProblem = dynamic_cast< CSensProblem * >(pTask->getProblem());

  if (!pProblem)
    return;

  mpResult = pProblem->getResultAnnotated();
  mpScaledResult = pProblem->getScaledResultAnnotated();

  mArrayWidget->setArrayAnnotation(mpResult);
  mArrayWidgetScaled->setArrayAnnotation(mpScaledResult);

  //tab for collapsed result
  if (pProblem->collapsRequested())
    {
      mpCollapsedResult = pProblem->getCollapsedResultAnnotated();
      mpTab->setTabEnabled(mArrayWidgetCollapsed, true);
    }
  else
    {
      mpCollapsedResult = NULL;
      mpTab->setTabEnabled(mArrayWidgetCollapsed, false);
    }

  mArrayWidgetCollapsed->setArrayAnnotation(mpCollapsedResult);
}

void CQSensResultWidget::clearArrays()
{
  mArrayWidget->setArrayAnnotation(NULL);
  mArrayWidgetScaled->setArrayAnnotation(NULL);
  mArrayWidgetCollapsed->setArrayAnnotation(NULL);
}

//*************************************

bool CQSensResultWidget::update(ListViews::ObjectType C_UNUSED(objectType), ListViews::Action
                                C_UNUSED(action), const std::string & C_UNUSED(key))
{
  /*  if (this->isShown())
      return loadFromBackend();
    else
      return true;*/
  return true;
}

bool CQSensResultWidget::leave()
{
  return true;
}

bool CQSensResultWidget::enterProtected()
{
  //clear the widget if the pointer to the result has changed
  assert(CCopasiRootContainer::getDatamodelList()->size() > 0);
  CSensTask * pTask =
    dynamic_cast<CSensTask*>((*(*CCopasiRootContainer::getDatamodelList())[0]->getTaskList())["Sensitivities"]);

  if (!pTask)
    {
      clearArrays();
      return false;
    }

  CSensProblem * pProblem = dynamic_cast< CSensProblem * >(pTask->getProblem());

  if (!pProblem)
    {
      clearArrays();
      return false;
    }

  if (mpResult != pProblem->getResultAnnotated())
    {
      clearArrays();
      return false;
    }

  return true;
}
<|endoftext|>


<commit_before>/* Begin CVS Header
   $Source: /Volumes/Home/Users/shoops/cvs/copasi_dev/copasi/utilities/CCopasiTask.cpp,v $
   $Revision: 1.43 $
   $Name:  $
   $Author: shoops $
   $Date: 2006/04/19 18:37:00 $
   End CVS Header */

/**
 *  CCopasiTask class.
 *  This class is used to describe a task in COPASI. This class is
 *  intended to be used as the parent class for all tasks whithin COPASI.
 *
 *  Created for Copasi by Stefan Hoops 2003
 */

#include "copasi.h"

#include "CCopasiTask.h"
#include "CCopasiProblem.h"
#include "CCopasiMethod.h"
#include "report/CReport.h"
#include "report/CKeyFactory.h"
#include "utilities/COutputHandler.h"
#include "model/CModel.h"
#include "model/CState.h"
#include "report/CCopasiObjectReference.h"
#include "CopasiDataModel/CCopasiDataModel.h"

const std::string CCopasiTask::TypeName[] =
  {
    "Steady-State",
    "Time-Course",
    "Scan",
    "Elementary Flux Modes",
    "Optimization",
    "Parameter Estimation",
    "Metabolic Control Analysis",
    "Time scale separation",
    "Sensitivities",
    ""
  };

const char* CCopasiTask::XMLType[] =
  {
    "steadyState",
    "timeCourse",
    "scan",
    "fluxMode",
    "optimization",
    "parameterFitting",
    "metabolicControlAnalysis",
    "timeScaleSeparation",
    "sensitivities",
    NULL
  };

const unsigned C_INT32 CCopasiTask::ValidMethods[] =
  {
    CCopasiMethod::unset
  };

//static
CCopasiTask::Type CCopasiTask::XMLNameToEnum(const char * xmlTypeName)
{
  unsigned C_INT32 i = 0;
  while (XMLType[i] && strcmp(xmlTypeName, XMLType[i])) i++;

  if (XMLType[i]) return (CCopasiTask::Type) i;
  else return CCopasiTask::unset;
}

CCopasiTask::CCopasiTask(const std::string & name,
                         const CCopasiContainer * pParent,
                         const std::string & type):
    CCopasiContainer(name, pParent, type),
    mType(CCopasiTask::unset),
    mKey(GlobalKeys.add("Task", this)),
    mDescription(this),
    mResult(this),
    mScheduled(false),
    mUpdateModel(false),
    mpInitialState(NULL),
    mpProblem(NULL),
    mpMethod(NULL),
    mReport(),
    mpCallBack(NULL),
    mpSliders(NULL),
    mDoOutput(OUTPUT_COMPLETE),
    mOutputCounter(0)
{initObjects();}

CCopasiTask::CCopasiTask(const CCopasiTask::Type & taskType,
                         const CCopasiContainer * pParent,
                         const std::string & type):
    CCopasiContainer(CCopasiTask::TypeName[taskType], pParent, type),
    mType(taskType),
    mKey(GlobalKeys.add("Task", this)),
    mDescription(this),
    mResult(this),
    mScheduled(false),
    mUpdateModel(false),
    mpInitialState(NULL),
    mpProblem(NULL),
    mpMethod(NULL),
    mReport(),
    mpCallBack(NULL),
    mpSliders(NULL),
    mDoOutput(OUTPUT_COMPLETE),
    mOutputCounter(0)
{initObjects();}

CCopasiTask::CCopasiTask(const CCopasiTask & src,
                         const CCopasiContainer * pParent):
    CCopasiContainer(src, pParent),
    mType(src.mType),
    mKey(GlobalKeys.add("Task", this)),
    mDescription(src.mDescription, this),
    mResult(src.mResult, this),
    mScheduled(src.mScheduled),
    mUpdateModel(src.mUpdateModel),
    mpInitialState(src.mpInitialState ? new CState(*src.mpInitialState) : NULL),
    mpProblem(NULL),
    mpMethod(NULL),
    mReport(src.mReport),
    mpCallBack(NULL),
    mpSliders(NULL),
    mDoOutput(OUTPUT_COMPLETE),
    mOutputCounter(0)
{initObjects();}

CCopasiTask::~CCopasiTask()
{
  GlobalKeys.remove(mKey);

  pdelete(mpInitialState);
  pdelete(mpProblem);
  pdelete(mpMethod);
  pdelete(mpSliders);
}

//const std::string & CCopasiTask::getName() const {return getObjectName();}

bool CCopasiTask::setName(const std::string & name)
{return setObjectName(name);}

CCopasiTask::Type CCopasiTask::getType() const {return mType;}

void CCopasiTask::setType(const CCopasiTask::Type & type) {mType = type;}

const std::string & CCopasiTask::getKey() const {return mKey;}

void CCopasiTask::setScheduled(const bool & scheduled) {mScheduled = scheduled;}

const bool & CCopasiTask::isScheduled() const {return mScheduled;}

void CCopasiTask::setUpdateModel(const bool & updateModel) {mUpdateModel = updateModel;}

const bool & CCopasiTask::isUpdateModel() const {return mUpdateModel;}

bool CCopasiTask::setCallBack(CProcessReport * pCallBack)
{
  mpCallBack = pCallBack;
  return true;
}

CProcessReport * CCopasiTask::getCallBack() const
  {
    return mpCallBack;
  }

bool CCopasiTask::initialize(const OutputFlag & of,
                             std::ostream * pOstream)
{
  bool success = true;

  if (!mpProblem)
    {
      CCopasiMessage(CCopasiMessage::ERROR, MCCopasiTask + 1, getObjectName().c_str());
      return false;
    }
  if (!mpProblem->getModel())
    {
      CCopasiMessage(CCopasiMessage::ERROR, MCCopasiTask + 2, getObjectName().c_str());
      return false;
    }
  if (!mpMethod)
    {
      CCopasiMessage(CCopasiMessage::ERROR, MCCopasiTask + 3, getObjectName().c_str());
      return false;
    }

  if (!mpProblem->getModel()->compileIfNecessary())
    {
      CCopasiMessage(CCopasiMessage::ERROR, MCCopasiTask + 4, mpProblem->getModel()->getObjectName().c_str());
      return false;
    }

  if (!mUpdateModel)
    {
      pdelete(mpInitialState);
      mpInitialState = new CState(mpProblem->getModel()->getInitialState());
    }

  mDoOutput = of;
  if (mDoOutput == NO_OUTPUT) return true;

  mOutputCounter = 0;

  if (!mReport.open(pOstream))
    {
      // Warning
      CCopasiMessage(CCopasiMessage::WARNING, MCCopasiTask + 5, mReport.getObjectName().c_str());
      success = false;
    }

  if (success) CCopasiDataModel::Global->addInterface(&mReport);

  std::vector< CCopasiContainer * > ListOfContainer;
  ListOfContainer.push_back(this);

  if (!CCopasiDataModel::Global->compile(ListOfContainer))
    {
      // Warning
      CCopasiMessage(CCopasiMessage::WARNING, MCCopasiTask + 7);
      success = false;
    }

  return success;
}

bool CCopasiTask::process(const bool &)
{return false;}

bool CCopasiTask::restore()
{
  //mReport.close();
  setCallBack(NULL);

  if (!mUpdateModel)
    {
      if (mpInitialState)
        mpProblem->getModel()->setInitialState(*mpInitialState);
    }

  mpProblem->restore(mUpdateModel);

  mReport.finish();
  CCopasiDataModel::Global->finish();
  CCopasiDataModel::Global->removeInterface(&mReport);
  return true;
}

CCopasiProblem * CCopasiTask::getProblem() {return mpProblem;}

const CCopasiProblem * CCopasiTask::getProblem() const {return mpProblem;}

bool CCopasiTask::setMethodType(const int & C_UNUSED(type))
{return false;}

CCopasiMethod * CCopasiTask::getMethod() {return mpMethod;}

const CCopasiMethod * CCopasiTask::getMethod() const {return mpMethod;}

CReport & CCopasiTask::getReport() {return mReport;}

const CCopasiTask::CDescription & CCopasiTask::getDescription() const
  {return mDescription;}

const CCopasiTask::CResult & CCopasiTask::getResult() const
  {return mResult;}

void CCopasiTask::cleanup() {}

CCopasiParameterGroup * CCopasiTask::getSliders()
{return mpSliders;}

// output stuff

void CCopasiTask::output(const COutputInterface::Activity & activity)
{
  switch (activity)
    {
    case COutputInterface::DURING:
        if (mDoOutput)
          CCopasiDataModel::Global->output(activity);
      break;

    case COutputInterface::BEFORE:
    case COutputInterface::AFTER:
      if (mDoOutput == OUTPUT_COMPLETE)
        CCopasiDataModel::Global->output(activity);
      break;
    }
}

void CCopasiTask::separate(const COutputInterface::Activity & activity)
{
  switch (activity)
    {
    case COutputInterface::DURING:
      if (mDoOutput)
        CCopasiDataModel::Global->separate(activity);
      break;

    case COutputInterface::BEFORE:
    case COutputInterface::AFTER:
      if (mDoOutput == OUTPUT_COMPLETE)
        CCopasiDataModel::Global->separate(activity);
      break;
    }
}

void CCopasiTask::initObjects()
{
  addObjectReference("Output counter", mOutputCounter, CCopasiObject::ValueInt);
}

CCopasiTask::CDescription::CDescription(const CCopasiContainer * pParent):
    CCopasiObject("Description", pParent, "Object")
{}

CCopasiTask::CDescription::CDescription(const CCopasiTask::CDescription & src,
                                        const CCopasiContainer * pParent):
    CCopasiObject(src, pParent)
{}

CCopasiTask::CDescription::~CDescription() {}

void CCopasiTask::CDescription::print(std::ostream * ostream) const
  {*ostream << *this;}

std::ostream &operator<<(std::ostream &os,
                         const CCopasiTask::CDescription & o)
{
  const CCopasiTask & Task = *static_cast<const CCopasiTask *>(o.getObjectParent());

  os << Task.getObjectName() << " Task" << std::endl << std::endl;

  if (Task.getProblem())
    {
      Task.getProblem()->print(&os);
      os << std::endl;
    }
  else
    os << "No Problem Specified!" << std::endl;

  if (Task.getMethod())
    {
      Task.getMethod()->print(&os);
      os << std::endl;
    }
  else
    os << "No Method Specified!" << std::endl;

  return os;
}

CCopasiTask::CResult::CResult(const CCopasiContainer * pParent):
    CCopasiObject("Result", pParent, "Object")
{}

CCopasiTask::CResult::CResult(const CCopasiTask::CResult & src,
                              const CCopasiContainer * pParent):
    CCopasiObject(src, pParent)
{}

CCopasiTask::CResult::~CResult() {}

void CCopasiTask::CResult::print(std::ostream * ostream) const
  {*ostream << *this;}

std::ostream &operator<<(std::ostream &os,
                         const CCopasiTask::CResult & o)
{
  const CCopasiTask & Task = *static_cast<const CCopasiTask *>(o.getObjectParent());

  os << Task.getObjectName() << " Result:" << std::endl << std::endl;

  if (Task.getProblem())
    {
      Task.getProblem()->printResult(&os);
      os << std::endl;
    }
  else
    os << "No Problem Specified!" << std::endl;

  return os;
}
<commit_msg>Restore now longer calls CCopasiDataModel::Global->finish() since only outer most task may do so.<commit_after>/* Begin CVS Header
   $Source: /Volumes/Home/Users/shoops/cvs/copasi_dev/copasi/utilities/CCopasiTask.cpp,v $
   $Revision: 1.44 $
   $Name:  $
   $Author: shoops $
   $Date: 2006/04/20 15:26:27 $
   End CVS Header */

/**
 *  CCopasiTask class.
 *  This class is used to describe a task in COPASI. This class is
 *  intended to be used as the parent class for all tasks whithin COPASI.
 *
 *  Created for Copasi by Stefan Hoops 2003
 */

#include "copasi.h"

#include "CCopasiTask.h"
#include "CCopasiProblem.h"
#include "CCopasiMethod.h"
#include "report/CReport.h"
#include "report/CKeyFactory.h"
#include "utilities/COutputHandler.h"
#include "model/CModel.h"
#include "model/CState.h"
#include "report/CCopasiObjectReference.h"
#include "CopasiDataModel/CCopasiDataModel.h"

const std::string CCopasiTask::TypeName[] =
  {
    "Steady-State",
    "Time-Course",
    "Scan",
    "Elementary Flux Modes",
    "Optimization",
    "Parameter Estimation",
    "Metabolic Control Analysis",
    "Time scale separation",
    "Sensitivities",
    ""
  };

const char* CCopasiTask::XMLType[] =
  {
    "steadyState",
    "timeCourse",
    "scan",
    "fluxMode",
    "optimization",
    "parameterFitting",
    "metabolicControlAnalysis",
    "timeScaleSeparation",
    "sensitivities",
    NULL
  };

const unsigned C_INT32 CCopasiTask::ValidMethods[] =
  {
    CCopasiMethod::unset
  };

//static
CCopasiTask::Type CCopasiTask::XMLNameToEnum(const char * xmlTypeName)
{
  unsigned C_INT32 i = 0;
  while (XMLType[i] && strcmp(xmlTypeName, XMLType[i])) i++;

  if (XMLType[i]) return (CCopasiTask::Type) i;
  else return CCopasiTask::unset;
}

CCopasiTask::CCopasiTask(const std::string & name,
                         const CCopasiContainer * pParent,
                         const std::string & type):
    CCopasiContainer(name, pParent, type),
    mType(CCopasiTask::unset),
    mKey(GlobalKeys.add("Task", this)),
    mDescription(this),
    mResult(this),
    mScheduled(false),
    mUpdateModel(false),
    mpInitialState(NULL),
    mpProblem(NULL),
    mpMethod(NULL),
    mReport(),
    mpCallBack(NULL),
    mpSliders(NULL),
    mDoOutput(OUTPUT_COMPLETE),
    mOutputCounter(0)
{initObjects();}

CCopasiTask::CCopasiTask(const CCopasiTask::Type & taskType,
                         const CCopasiContainer * pParent,
                         const std::string & type):
    CCopasiContainer(CCopasiTask::TypeName[taskType], pParent, type),
    mType(taskType),
    mKey(GlobalKeys.add("Task", this)),
    mDescription(this),
    mResult(this),
    mScheduled(false),
    mUpdateModel(false),
    mpInitialState(NULL),
    mpProblem(NULL),
    mpMethod(NULL),
    mReport(),
    mpCallBack(NULL),
    mpSliders(NULL),
    mDoOutput(OUTPUT_COMPLETE),
    mOutputCounter(0)
{initObjects();}

CCopasiTask::CCopasiTask(const CCopasiTask & src,
                         const CCopasiContainer * pParent):
    CCopasiContainer(src, pParent),
    mType(src.mType),
    mKey(GlobalKeys.add("Task", this)),
    mDescription(src.mDescription, this),
    mResult(src.mResult, this),
    mScheduled(src.mScheduled),
    mUpdateModel(src.mUpdateModel),
    mpInitialState(src.mpInitialState ? new CState(*src.mpInitialState) : NULL),
    mpProblem(NULL),
    mpMethod(NULL),
    mReport(src.mReport),
    mpCallBack(NULL),
    mpSliders(NULL),
    mDoOutput(OUTPUT_COMPLETE),
    mOutputCounter(0)
{initObjects();}

CCopasiTask::~CCopasiTask()
{
  GlobalKeys.remove(mKey);

  pdelete(mpInitialState);
  pdelete(mpProblem);
  pdelete(mpMethod);
  pdelete(mpSliders);
}

//const std::string & CCopasiTask::getName() const {return getObjectName();}

bool CCopasiTask::setName(const std::string & name)
{return setObjectName(name);}

CCopasiTask::Type CCopasiTask::getType() const {return mType;}

void CCopasiTask::setType(const CCopasiTask::Type & type) {mType = type;}

const std::string & CCopasiTask::getKey() const {return mKey;}

void CCopasiTask::setScheduled(const bool & scheduled) {mScheduled = scheduled;}

const bool & CCopasiTask::isScheduled() const {return mScheduled;}

void CCopasiTask::setUpdateModel(const bool & updateModel) {mUpdateModel = updateModel;}

const bool & CCopasiTask::isUpdateModel() const {return mUpdateModel;}

bool CCopasiTask::setCallBack(CProcessReport * pCallBack)
{
  mpCallBack = pCallBack;
  return true;
}

CProcessReport * CCopasiTask::getCallBack() const
  {
    return mpCallBack;
  }

bool CCopasiTask::initialize(const OutputFlag & of,
                             std::ostream * pOstream)
{
  bool success = true;

  if (!mpProblem)
    {
      CCopasiMessage(CCopasiMessage::ERROR, MCCopasiTask + 1, getObjectName().c_str());
      return false;
    }
  if (!mpProblem->getModel())
    {
      CCopasiMessage(CCopasiMessage::ERROR, MCCopasiTask + 2, getObjectName().c_str());
      return false;
    }
  if (!mpMethod)
    {
      CCopasiMessage(CCopasiMessage::ERROR, MCCopasiTask + 3, getObjectName().c_str());
      return false;
    }

  if (!mpProblem->getModel()->compileIfNecessary())
    {
      CCopasiMessage(CCopasiMessage::ERROR, MCCopasiTask + 4, mpProblem->getModel()->getObjectName().c_str());
      return false;
    }

  if (!mUpdateModel)
    {
      pdelete(mpInitialState);
      mpInitialState = new CState(mpProblem->getModel()->getInitialState());
    }

  mDoOutput = of;
  if (mDoOutput == NO_OUTPUT) return true;

  mOutputCounter = 0;

  if (!mReport.open(pOstream))
    {
      // Warning
      CCopasiMessage(CCopasiMessage::WARNING, MCCopasiTask + 5, mReport.getObjectName().c_str());
      success = false;
    }

  if (success) CCopasiDataModel::Global->addInterface(&mReport);

  std::vector< CCopasiContainer * > ListOfContainer;
  ListOfContainer.push_back(this);

  if (!CCopasiDataModel::Global->compile(ListOfContainer))
    {
      // Warning
      CCopasiMessage(CCopasiMessage::WARNING, MCCopasiTask + 7);
      success = false;
    }

  return success;
}

bool CCopasiTask::process(const bool &)
{return false;}

bool CCopasiTask::restore()
{
  //mReport.close();
  setCallBack(NULL);

  if (!mUpdateModel)
    {
      if (mpInitialState)
        mpProblem->getModel()->setInitialState(*mpInitialState);
    }

  mpProblem->restore(mUpdateModel);

  return true;
}

CCopasiProblem * CCopasiTask::getProblem() {return mpProblem;}

const CCopasiProblem * CCopasiTask::getProblem() const {return mpProblem;}

bool CCopasiTask::setMethodType(const int & C_UNUSED(type))
{return false;}

CCopasiMethod * CCopasiTask::getMethod() {return mpMethod;}

const CCopasiMethod * CCopasiTask::getMethod() const {return mpMethod;}

CReport & CCopasiTask::getReport() {return mReport;}

const CCopasiTask::CDescription & CCopasiTask::getDescription() const
  {return mDescription;}

const CCopasiTask::CResult & CCopasiTask::getResult() const
  {return mResult;}

void CCopasiTask::cleanup() {}

CCopasiParameterGroup * CCopasiTask::getSliders()
{return mpSliders;}

// output stuff

void CCopasiTask::output(const COutputInterface::Activity & activity)
{
  switch (activity)
    {
    case COutputInterface::DURING:
        if (mDoOutput)
          CCopasiDataModel::Global->output(activity);
      break;

    case COutputInterface::BEFORE:
    case COutputInterface::AFTER:
      if (mDoOutput == OUTPUT_COMPLETE)
        CCopasiDataModel::Global->output(activity);
      break;
    }
}

void CCopasiTask::separate(const COutputInterface::Activity & activity)
{
  switch (activity)
    {
    case COutputInterface::DURING:
      if (mDoOutput)
        CCopasiDataModel::Global->separate(activity);
      break;

    case COutputInterface::BEFORE:
    case COutputInterface::AFTER:
      if (mDoOutput == OUTPUT_COMPLETE)
        CCopasiDataModel::Global->separate(activity);
      break;
    }
}

void CCopasiTask::initObjects()
{
  addObjectReference("Output counter", mOutputCounter, CCopasiObject::ValueInt);
}

CCopasiTask::CDescription::CDescription(const CCopasiContainer * pParent):
    CCopasiObject("Description", pParent, "Object")
{}

CCopasiTask::CDescription::CDescription(const CCopasiTask::CDescription & src,
                                        const CCopasiContainer * pParent):
    CCopasiObject(src, pParent)
{}

CCopasiTask::CDescription::~CDescription() {}

void CCopasiTask::CDescription::print(std::ostream * ostream) const
  {*ostream << *this;}

std::ostream &operator<<(std::ostream &os,
                         const CCopasiTask::CDescription & o)
{
  const CCopasiTask & Task = *static_cast<const CCopasiTask *>(o.getObjectParent());

  os << Task.getObjectName() << " Task" << std::endl << std::endl;

  if (Task.getProblem())
    {
      Task.getProblem()->print(&os);
      os << std::endl;
    }
  else
    os << "No Problem Specified!" << std::endl;

  if (Task.getMethod())
    {
      Task.getMethod()->print(&os);
      os << std::endl;
    }
  else
    os << "No Method Specified!" << std::endl;

  return os;
}

CCopasiTask::CResult::CResult(const CCopasiContainer * pParent):
    CCopasiObject("Result", pParent, "Object")
{}

CCopasiTask::CResult::CResult(const CCopasiTask::CResult & src,
                              const CCopasiContainer * pParent):
    CCopasiObject(src, pParent)
{}

CCopasiTask::CResult::~CResult() {}

void CCopasiTask::CResult::print(std::ostream * ostream) const
  {*ostream << *this;}

std::ostream &operator<<(std::ostream &os,
                         const CCopasiTask::CResult & o)
{
  const CCopasiTask & Task = *static_cast<const CCopasiTask *>(o.getObjectParent());

  os << Task.getObjectName() << " Result:" << std::endl << std::endl;

  if (Task.getProblem())
    {
      Task.getProblem()->printResult(&os);
      os << std::endl;
    }
  else
    os << "No Problem Specified!" << std::endl;

  return os;
}
<|endoftext|>


<commit_before>#include <cstdio>
#include <cstring>
#include <iostream>
#include <bitset>
#include <sstream>

#include <netinet/in.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <vector>
#include <algorithm>
#include <list>
#include <map>

#include <netdb.h>
#include <cstdlib>

#include "segment.h"
#include "message.h"
#include "loc_success_message.h"
#include "loc_failure_message.h"
#include "loc_request_message.h"
#include "execute_success_message.h"
#include "execute_failure_message.h"
#include "execute_request_message.h"
#include "register_success_message.h"
#include "register_failure_message.h"
#include "register_request_message.h"
#include "terminate_message.h"

#include "rpc.h"
#include "constants.h"
#include "network.h"
#include "helper_functions.h"

using namespace std;

// Global variables for client
bool connectedToBinder = false;
int binderSocket = 0;

// Global variables for server
static map<procedure_signature, skeleton, ps_compare> procSkeleDict;
string serverIdentifier;
unsigned int port = 0;
int welcomeSocket = 0;
bool onSwitch = true;

void mapPrint(){
  cout << "procSkeleDict size: "<<procSkeleDict.size() << endl;

  cout << "Map Print: ";

  for(map<procedure_signature, skeleton>::iterator it = procSkeleDict.begin();
   it != procSkeleDict.end(); ++it){

    cout << it->first.name << ", ";
  }

  cout << endl;
}

void printArgTypes(int * argTypes){
  cout << " Printing argTypes: " ;

  unsigned num = countNumOfArgTypes(argTypes);

  for(int i = 0; i < num; i++){
    cout << argTypes[i] << ", ";
  }
  cout << endl;
}

void printArgs(int * argTypes, void  ** args){
  cout << "Printing args: " ;

  // Parses the argument from the buffer
  unsigned numOfArgs = countNumOfArgTypes(argTypes) - 1;

  cout<<"Number of args: " << numOfArgs << endl;

  for (unsigned int i = 0; i < numOfArgs; i++) {
    int argType = argTypes[i];
    int argTypeInformation =
      (argType & ARG_TYPE_INFORMATION_MASK) >> ARG_TYPE_INFORMATION_SHIFT_AMOUNT;
    int argTypeArrayLength = argType & ARG_TYPE_ARRAY_LENGTH_MASK;
    argTypeArrayLength = (argTypeArrayLength == 0) ? 1: argTypeArrayLength;
    void *arg = args[i];

    switch (argTypeInformation) {
      case ARG_CHAR: {
        cout << "Printing ARG_CHAR: " << endl;
        char *argCharArray = (char *) arg;
        cout << argCharArray << endl;
        break;
      }

      case ARG_SHORT: {
        cout << "Printing ARG_SHORT: " << endl;
        short *argShortArray = (short *) arg;
        for (int j = 0; j < argTypeArrayLength; j++) {
          cout << argShortArray[i] << ", ";
        }
        cout << endl;
        break;
      }

      case ARG_INT: {
        cout << "Printing ARG_INT: " << endl;
        int *argIntArray = (int *) arg;
        for (int j = 0; j < argTypeArrayLength; j++) {
          cout << argIntArray[j] << ", ";
        }
        cout << endl;
        break;
      }

      case ARG_LONG: {
        cout << "Printing ARG_LONG: " << endl;
        long *argLongArray = (long *) arg;
        for (int j = 0; j < argTypeArrayLength; j++) {
          cout << argLongArray[j] << ",";
        }
        cout << endl;
        break;
      }

      case ARG_DOUBLE: {
        cout << "Printing ARG_DOUBLE: " << endl;
        double *argDoubleArray = (double *) arg;
        for (int j = 0; j < argTypeArrayLength; j++) {
          cout << argDoubleArray[j] << ", ";
        }
        cout << endl;
        break;
      }

      case ARG_FLOAT: {
        cout << "Printing ARG_FLOAT: " << endl;
        float *argFloatArray = (float *) arg;
        for (int j = 0; j < argTypeArrayLength; j++) {
          cout << argFloatArray[j] << ", ";
        }
        cout << endl;
        break;
      }
    }
  }
  cout << endl;
}

// See interface (header file).
int rpcInit(){
	cout << "Running rpcInit..." << endl;

	// Creates a connection socket to be used for accepting connections
	// from clients
	welcomeSocket = createSocket();
	setUpToListen(welcomeSocket);
	serverIdentifier = getHostAddress();
	port = getSocketPort(welcomeSocket);

	// Opens a connection to the binder
	binderSocket = createSocket();
	string binderAddress = getBinderAddress();
	unsigned int binderPort = getBinderPort();
	setUpToConnect(binderSocket, binderAddress, binderPort);
  connectedToBinder = true;

  return 0;
}

// See interface (header file).
int rpcCall(char *name, int *argTypes, void **args) {
  cout << "Running rpcCall..." << endl;

	string serverAddress;
	unsigned int serverPort = 0;
	int status;

	if(!connectedToBinder){
    cout << "Connecting to binder..." << endl;
		binderSocket = createSocket();
		string binderAddress = getBinderAddress();
		unsigned int binderPort = getBinderPort();
		status = setUpToConnect(binderSocket, binderAddress, binderPort);
	  connectedToBinder = true;
    cout << "Connected to binder..." << endl;
	}
	//do something with returnVal

  LocRequestMessage messageToBinder = LocRequestMessage(string(name), argTypes);
  Segment segmentToBinder =
	  Segment(messageToBinder.getLength(), MSG_TYPE_LOC_REQUEST, &messageToBinder);
  int binder_status = segmentToBinder.send(binderSocket);
  cout << "LOC REQUEST message sent..." << endl;

	//maybe error check with binder_status
  //TODO: SEGMENT FAULT IF NOT IN THIS FOR LOOP
	/**Server stuff **/
	if(binder_status >= 0){

    Segment *parsedSegment = 0;
    int tempStatus = 0;
    tempStatus = Segment::receive(binderSocket, parsedSegment);

    Message *messageFromBinder = parsedSegment->getMessage();
		switch (parsedSegment->getType()) {
			case MSG_TYPE_LOC_SUCCESS: {
				cout << "LOC SUCCESS message received..." << endl;
        LocSuccessMessage *lsm =
				  dynamic_cast<LocSuccessMessage *>(messageFromBinder);
				serverAddress = lsm->getServerIdentifier();
				serverPort = lsm->getPort();
				cout << "serverAddress: " << serverAddress << endl;
        cout << "serverPort: " << serverPort << endl;
        break;
			}

			case MSG_TYPE_LOC_FAILURE: {
        cout << "LOC FAILURE message received..." << endl;
				return -1;
				break;
			}
		}
	}

  cout << "Connecting to server..." << endl;
  int serverSocket = createSocket();
	int status1 = setUpToConnect(serverSocket, serverAddress, serverPort);

  cout << "status1: " << status1 << endl;
  cout << "Server Socket: " << serverSocket << endl;
  cout << "Server Address: " << serverAddress << endl;
  cout << "Server Port: " << serverPort << endl;
  cout << "Connected to server..." << endl;

  ExecuteRequestMessage exeReqMsg = ExecuteRequestMessage(name, argTypes, args);
  Segment exeReqSeg = Segment(exeReqMsg.getLength(), MSG_TYPE_EXECUTE_REQUEST, &exeReqMsg);
  int status2 =  exeReqSeg.send(serverSocket);

  cout << "Status of exeRegMsg send: " << status2 << endl;

  int returnVal = 0;

  Segment * parsedSegmentEsm = 0;
  int status3 = 0;
  status3 = Segment::receive(serverSocket, parsedSegmentEsm);
  cout << "Flag 1" << endl;

  //instead we have

  cout << "Flag 2" << endl;

  switch (parsedSegmentEsm->getType()) {
    case MSG_TYPE_EXECUTE_SUCCESS: {
      cout << "EXECUTE SUCCESS message received..." << endl;

      Message * msg = parsedSegmentEsm->getMessage();
      ExecuteSuccessMessage * esm = dynamic_cast<ExecuteSuccessMessage*>(msg);

      // TODO FIX: name = esm->getName();
      //argTypes = esm->getArgTypes();
      void** newArgs = esm->getArgs();
      unsigned numOfArgs = countNumOfArgTypes(esm->getArgTypes()) - 1;

      for (unsigned int i = 0; i < numOfArgs; i++) {
        args[i] = newArgs[i];
      }

      break;
    }

    case MSG_TYPE_EXECUTE_FAILURE: {
      cout << "EXECUTE FAILURE message received..." << endl;

      Message * cast = parsedSegmentEsm->getMessage();
      ExecuteFailureMessage * efm = dynamic_cast<ExecuteFailureMessage*>(cast);
      returnVal = efm->getReasonCode();
      break;
    }
  }

  return returnVal;
}

  //TODO:
  // CREATE SERVER
  // CONNECT TO BINDER

int rpcRegister(char * name, int *argTypes, skeleton f){
  cout << "Running rpcRegister..." << endl;
  RegisterRequestMessage regReqMsg = RegisterRequestMessage(serverIdentifier, port, name, argTypes);

  /*
  cout << "rpcRegister name: " << name << endl;
  cout << "rpcRegister serverIdentifier: " << serverIdentifier << endl;
  cout << "rpcRegister port: " << port << endl;
  */

  /*
  We should get seg.send to give us some feed back maybe
  int status = regReqMsg->send(binderSocket);
  */

  Segment regReqSeg = Segment(regReqMsg.getLength(), MSG_TYPE_REGISTER_REQUEST, &regReqMsg);
  int status = regReqSeg.send(binderSocket);

  //cout << "rpcRegister Status: " << status << endl;

  if(status >= 0){
    //Success
    Segment *parsedSegment = 0;
    int result = 0;
    result = Segment::receive(binderSocket, parsedSegment);

    if(parsedSegment->getType() == MSG_TYPE_REGISTER_SUCCESS){

      cout << "MSG_TYPE_REGISTER_SUCCESS" << endl;

      Message * cast = parsedSegment->getMessage();
      //Error Checking maybe
      RegisterSuccessMessage * rsm = dynamic_cast<RegisterSuccessMessage*>(cast);

      //struct procedure_signature k(string(name), argTypes);
      struct procedure_signature k = procedure_signature(string(name), argTypes);

      procSkeleDict[k] = f;

      cout << "k: " << k.name << ", "<< f << endl;

    }else if(parsedSegment->getType() == MSG_TYPE_REGISTER_FAILURE){
      return 0;
    }

  }else if( status < 0){
    //Error
    return -99;
  }

  return 1;
}

int rpcExecute(){
  cout << "Running rpcExecute..." << endl;

  // Code refactoring

  fd_set allSockets;
  fd_set readSockets;

  // Clears all entries from the all sockets set and the read
  // sockets set
  FD_ZERO(&allSockets);
  FD_ZERO(&readSockets);

  // Creates the welcome socket, adds it to the all sockets set and
  // sets it as the maximum socket so far
  FD_SET(welcomeSocket, &allSockets);
  int maxSocket = welcomeSocket;

  while (onSwitch) {
    readSockets = allSockets;

    // Checks if some of the sockets are ready to be read from
    int result = select(maxSocket + 1, &readSockets, 0, 0, 0);
    if (result < 0) {
      continue;
    }

    for (int i = 0; i <= maxSocket; i++) {
      if (!FD_ISSET(i, &readSockets)) {
        continue;
      }

      if (i == welcomeSocket) {

        // Creates the connection socket when a connection is made
        // to the welcome socket
        int connectionSocket = acceptConnection(i);
        if (connectionSocket < 0) {
          continue;
        }

        // Adds the connection socket to the all sockets set
        FD_SET(connectionSocket, &allSockets);

        // Sets the connection socket as the maximum socket so far
        // if necessary
        if (connectionSocket > maxSocket) {
          maxSocket = connectionSocket;
        }

      }

        // Creates a segment to receive data from the client/server and
        // reads into it from the connection socket
        Segment *segment = 0;
        result = 0;
        result = Segment::receive(i, segment);
        if (result <= 0) {
          // Closes the connection socket and removes it from the
          // all sockets set
          destroySocket(i);
          FD_CLR(i, &allSockets);
          continue;
        }

        if(segment->getType() == MSG_TYPE_EXECUTE_REQUEST){
          Message * cast = segment->getMessage();
          ExecuteRequestMessage * erm = dynamic_cast<ExecuteRequestMessage*>(cast);

          procedure_signature * ps = new procedure_signature(erm->getName(), erm->getArgTypes());

          cout << "erm->getName(): " << erm->getName() << endl;
          printArgTypes(erm->getArgTypes());
          printArgs(erm->getArgTypes(), erm->getArgs());

          skeleton skel = procSkeleDict[*ps];

          if(skel == 0){
            cout << "Skel is null" << endl;
          }

          int result = skel(erm->getArgTypes(), erm->getArgs());

          cout << "Result: " << result << endl;
          printArgs(erm->getArgTypes(), erm->getArgs());

          if(result == 0 ){
            ExecuteSuccessMessage exeSuccessMsg = ExecuteSuccessMessage(erm->getName(), erm->getArgTypes(), erm->getArgs());
            Segment exeSuccessSeg = Segment(exeSuccessMsg.getLength(), MSG_TYPE_EXECUTE_SUCCESS, &exeSuccessMsg);
            int tstatus = exeSuccessSeg.send(i);
            cout << "ExecuteSuccessMessage status: " << tstatus << endl;

          }else{
            ExecuteFailureMessage exeFailMsg = ExecuteFailureMessage(result);
            Segment exeFailSeg = Segment(exeFailMsg.getLength(), MSG_TYPE_EXECUTE_FAILURE, &exeFailMsg);
            int tstatus = exeFailSeg.send(i);
          }

        }else if(segment->getType() == MSG_TYPE_TERMINATE){
          cout << "Got to terminate" << endl;
          onSwitch = false;
          //and other clean up
        }
      }
    }

  // Destroys the welcome socket
  destroySocket(welcomeSocket);

  return 0;
}

int rpcCacheCall() {
  cout << "Running rpcCacheCall..." << endl;
	return 0;
}

int rpcTerminate() {
	cout << "Running rpcTerminate..." << endl;

  // Sends a terminate message to the binder
  TerminateMessage messageToBinder = TerminateMessage();
  Segment segmentToBinder =
    Segment(messageToBinder.getLength(), MSG_TYPE_TERMINATE, &messageToBinder);
  int binder_status = segmentToBinder.send(binderSocket);
  cout << segmentToBinder.getType() << endl;

  cout << "binderSocket: " << binderSocket << endl;
  sleep(1);
  // Closes the connection to the binder
  destroySocket(binderSocket);

	return 0;
}
<commit_msg>changes<commit_after>#include <cstdio>
#include <cstring>
#include <iostream>
#include <bitset>
#include <sstream>

#include <netinet/in.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <vector>
#include <algorithm>
#include <list>
#include <map>

#include <netdb.h>
#include <cstdlib>

#include "segment.h"
#include "message.h"
#include "loc_success_message.h"
#include "loc_failure_message.h"
#include "loc_request_message.h"
#include "execute_success_message.h"
#include "execute_failure_message.h"
#include "execute_request_message.h"
#include "register_success_message.h"
#include "register_failure_message.h"
#include "register_request_message.h"
#include "terminate_message.h"

#include "rpc.h"
#include "constants.h"
#include "network.h"
#include "helper_functions.h"

using namespace std;

// Global variables for client
bool connectedToBinder = false;
int binderSocket = 0;

// Global variables for server
static map<procedure_signature, skeleton, ps_compare> procSkeleDict;
string serverIdentifier;
unsigned int port = 0;
int welcomeSocket = 0;
bool onSwitch = true;

void mapPrint(){
  cout << "procSkeleDict size: "<<procSkeleDict.size() << endl;

  cout << "Map Print: ";

  for(map<procedure_signature, skeleton>::iterator it = procSkeleDict.begin();
   it != procSkeleDict.end(); ++it){

    cout << it->first.name << ", ";
  }

  cout << endl;
}

void printArgTypes(int * argTypes){
  cout << " Printing argTypes: " ;

  unsigned num = countNumOfArgTypes(argTypes);

  for(int i = 0; i < num; i++){
    cout << argTypes[i] << ", ";
  }
  cout << endl;
}

void printArgs(int * argTypes, void  ** args){
  cout << "Printing args: " ;

  // Parses the argument from the buffer
  unsigned numOfArgs = countNumOfArgTypes(argTypes) - 1;

  cout<<"Number of args: " << numOfArgs << endl;

  for (unsigned int i = 0; i < numOfArgs; i++) {
    int argType = argTypes[i];
    int argTypeInformation =
      (argType & ARG_TYPE_INFORMATION_MASK) >> ARG_TYPE_INFORMATION_SHIFT_AMOUNT;
    int argTypeArrayLength = argType & ARG_TYPE_ARRAY_LENGTH_MASK;
    argTypeArrayLength = (argTypeArrayLength == 0) ? 1: argTypeArrayLength;
    void *arg = args[i];

    switch (argTypeInformation) {
      case ARG_CHAR: {
        cout << "Printing ARG_CHAR: " << endl;
        char *argCharArray = (char *) arg;
        cout << argCharArray << endl;
        break;
      }

      case ARG_SHORT: {
        cout << "Printing ARG_SHORT: " << endl;
        short *argShortArray = (short *) arg;
        for (int j = 0; j < argTypeArrayLength; j++) {
          cout << argShortArray[i] << ", ";
        }
        cout << endl;
        break;
      }

      case ARG_INT: {
        cout << "Printing ARG_INT: " << endl;
        int *argIntArray = (int *) arg;
        for (int j = 0; j < argTypeArrayLength; j++) {
          cout << argIntArray[j] << ", ";
        }
        cout << endl;
        break;
      }

      case ARG_LONG: {
        cout << "Printing ARG_LONG: " << endl;
        long *argLongArray = (long *) arg;
        for (int j = 0; j < argTypeArrayLength; j++) {
          cout << argLongArray[j] << ",";
        }
        cout << endl;
        break;
      }

      case ARG_DOUBLE: {
        cout << "Printing ARG_DOUBLE: " << endl;
        double *argDoubleArray = (double *) arg;
        for (int j = 0; j < argTypeArrayLength; j++) {
          cout << argDoubleArray[j] << ", ";
        }
        cout << endl;
        break;
      }

      case ARG_FLOAT: {
        cout << "Printing ARG_FLOAT: " << endl;
        float *argFloatArray = (float *) arg;
        for (int j = 0; j < argTypeArrayLength; j++) {
          cout << argFloatArray[j] << ", ";
        }
        cout << endl;
        break;
      }
    }
  }
  cout << endl;
}

// See interface (header file).
int rpcInit(){
	cout << "Running rpcInit..." << endl;

	// Creates a connection socket to be used for accepting connections
	// from clients
	welcomeSocket = createSocket();
	setUpToListen(welcomeSocket);
	serverIdentifier = getHostAddress();
	port = getSocketPort(welcomeSocket);

	// Opens a connection to the binder
	binderSocket = createSocket();
	string binderAddress = getBinderAddress();
	unsigned int binderPort = getBinderPort();
	setUpToConnect(binderSocket, binderAddress, binderPort);
  connectedToBinder = true;

  return 0;
}

// See interface (header file).
int rpcCall(char *name, int *argTypes, void **args) {
  cout << "Running rpcCall..." << endl;

	string serverAddress;
	unsigned int serverPort = 0;
	int status;

	if(!connectedToBinder){
    cout << "Connecting to binder..." << endl;
		binderSocket = createSocket();
		string binderAddress = getBinderAddress();
		unsigned int binderPort = getBinderPort();
		status = setUpToConnect(binderSocket, binderAddress, binderPort);
	  connectedToBinder = true;
    cout << "Connected to binder..." << endl;
	}
	//do something with returnVal

  LocRequestMessage messageToBinder = LocRequestMessage(string(name), argTypes);
  Segment segmentToBinder =
	  Segment(messageToBinder.getLength(), MSG_TYPE_LOC_REQUEST, &messageToBinder);
  int binder_status = segmentToBinder.send(binderSocket);
  cout << "LOC REQUEST message sent..." << endl;

	//maybe error check with binder_status
  //TODO: SEGMENT FAULT IF NOT IN THIS FOR LOOP
	/**Server stuff **/
	if(binder_status >= 0){

    Segment *parsedSegment = 0;
    int tempStatus = 0;
    tempStatus = Segment::receive(binderSocket, parsedSegment);

    Message *messageFromBinder = parsedSegment->getMessage();
		switch (parsedSegment->getType()) {
			case MSG_TYPE_LOC_SUCCESS: {
				cout << "LOC SUCCESS message received..." << endl;
        LocSuccessMessage *lsm =
				  dynamic_cast<LocSuccessMessage *>(messageFromBinder);
				serverAddress = lsm->getServerIdentifier();
				serverPort = lsm->getPort();
				cout << "serverAddress: " << serverAddress << endl;
        cout << "serverPort: " << serverPort << endl;
        break;
			}

			case MSG_TYPE_LOC_FAILURE: {
        cout << "LOC FAILURE message received..." << endl;
				return -1;
				break;
			}
		}
	}

  cout << "Connecting to server..." << endl;
  int serverSocket = createSocket();
	int status1 = setUpToConnect(serverSocket, serverAddress, serverPort);

  cout << "status1: " << status1 << endl;
  cout << "Server Socket: " << serverSocket << endl;
  cout << "Server Address: " << serverAddress << endl;
  cout << "Server Port: " << serverPort << endl;
  cout << "Connected to server..." << endl;

  ExecuteRequestMessage exeReqMsg = ExecuteRequestMessage(name, argTypes, args);
  Segment exeReqSeg = Segment(exeReqMsg.getLength(), MSG_TYPE_EXECUTE_REQUEST, &exeReqMsg);
  int status2 =  exeReqSeg.send(serverSocket);

  cout << "Status of exeRegMsg send: " << status2 << endl;

  int returnVal = 0;

  Segment * parsedSegmentEsm = 0;
  int status3 = 0;
  status3 = Segment::receive(serverSocket, parsedSegmentEsm);
  cout << "Flag 1" << endl;

  //instead we have

  cout << "Flag 2" << endl;

  switch (parsedSegmentEsm->getType()) {
    case MSG_TYPE_EXECUTE_SUCCESS: {
      cout << "EXECUTE SUCCESS message received..." << endl;

      Message * msg = parsedSegmentEsm->getMessage();
      ExecuteSuccessMessage * esm = dynamic_cast<ExecuteSuccessMessage*>(msg);

      // TODO FIX: name = esm->getName();
      //argTypes = esm->getArgTypes();
      void** newArgs = esm->getArgs();
      unsigned numOfArgs = countNumOfArgTypes(esm->getArgTypes()) - 1;

      for (unsigned int i = 0; i < numOfArgs; i++) {
        args[i] = newArgs[i];
      }

      break;
    }

    case MSG_TYPE_EXECUTE_FAILURE: {
      cout << "EXECUTE FAILURE message received..." << endl;

      Message * cast = parsedSegmentEsm->getMessage();
      ExecuteFailureMessage * efm = dynamic_cast<ExecuteFailureMessage*>(cast);
      returnVal = efm->getReasonCode();
      break;
    }
  }

  return returnVal;
}

  //TODO:
  // CREATE SERVER
  // CONNECT TO BINDER

int rpcRegister(char * name, int *argTypes, skeleton f){
  cout << "Running rpcRegister..." << endl;
  RegisterRequestMessage regReqMsg = RegisterRequestMessage(serverIdentifier, port, name, argTypes);

  /*
  cout << "rpcRegister name: " << name << endl;
  cout << "rpcRegister serverIdentifier: " << serverIdentifier << endl;
  cout << "rpcRegister port: " << port << endl;
  */

  /*
  We should get seg.send to give us some feed back maybe
  int status = regReqMsg->send(binderSocket);
  */

  Segment regReqSeg = Segment(regReqMsg.getLength(), MSG_TYPE_REGISTER_REQUEST, &regReqMsg);
  int status = regReqSeg.send(binderSocket);

  //cout << "rpcRegister Status: " << status << endl;

  if(status >= 0){
    //Success
    Segment *parsedSegment = 0;
    int result = 0;
    result = Segment::receive(binderSocket, parsedSegment);

    if(parsedSegment->getType() == MSG_TYPE_REGISTER_SUCCESS){

      cout << "MSG_TYPE_REGISTER_SUCCESS" << endl;

      Message * cast = parsedSegment->getMessage();
      //Error Checking maybe
      RegisterSuccessMessage * rsm = dynamic_cast<RegisterSuccessMessage*>(cast);

      //struct procedure_signature k(string(name), argTypes);
      struct procedure_signature k = procedure_signature(string(name), argTypes);

      procSkeleDict[k] = f;

      cout << "k: " << k.name << ", "<< f << endl;

    }else if(parsedSegment->getType() == MSG_TYPE_REGISTER_FAILURE){
      return 0;
    }

  }else if( status < 0){
    //Error
    return -99;
  }

  return 1;
}

int rpcExecute(){
  cout << "Running rpcExecute..." << endl;

  // Code refactoring

  fd_set allSockets;
  fd_set readSockets;

  // Clears all entries from the all sockets set and the read
  // sockets set
  FD_ZERO(&allSockets);
  FD_ZERO(&readSockets);

  // Creates the welcome socket, adds it to the all sockets set and
  // sets it as the maximum socket so far
  FD_SET(welcomeSocket, &allSockets);
  int maxSocket = welcomeSocket;

  while (onSwitch) {
    readSockets = allSockets;

    // Checks if some of the sockets are ready to be read from
    int result = select(maxSocket + 1, &readSockets, 0, 0, 0);
    if (result < 0) {
      continue;
    }

    for (int i = 0; i <= maxSocket; i++) {
      if (!FD_ISSET(i, &readSockets)) {
        continue;
      }

      if (i == welcomeSocket) {

        // Creates the connection socket when a connection is made
        // to the welcome socket
        int connectionSocket = acceptConnection(i);
        if (connectionSocket < 0) {
          continue;
        }

        // Adds the connection socket to the all sockets set
        FD_SET(connectionSocket, &allSockets);

        // Sets the connection socket as the maximum socket so far
        // if necessary
        if (connectionSocket > maxSocket) {
          maxSocket = connectionSocket;
        }

      } else {

        // Creates a segment to receive data from the client/server and
        // reads into it from the connection socket
        Segment *segment = 0;
        result = 0;
        result = Segment::receive(i, segment);
        if (result < 0) {
          // Closes the connection socket and removes it from the
          // all sockets set
          destroySocket(i);
          FD_CLR(i, &allSockets);
          continue;
        }

        if(segment->getType() == MSG_TYPE_EXECUTE_REQUEST){
          Message * cast = segment->getMessage();
          ExecuteRequestMessage * erm = dynamic_cast<ExecuteRequestMessage*>(cast);

          procedure_signature * ps = new procedure_signature(erm->getName(), erm->getArgTypes());

          cout << "erm->getName(): " << erm->getName() << endl;
          printArgTypes(erm->getArgTypes());
          printArgs(erm->getArgTypes(), erm->getArgs());

          skeleton skel = procSkeleDict[*ps];

          if(skel == 0){
            cout << "Skel is null" << endl;
          }

          int result = skel(erm->getArgTypes(), erm->getArgs());

          cout << "Result: " << result << endl;
          printArgs(erm->getArgTypes(), erm->getArgs());

          if(result == 0 ){
            ExecuteSuccessMessage exeSuccessMsg = ExecuteSuccessMessage(erm->getName(), erm->getArgTypes(), erm->getArgs());
            Segment exeSuccessSeg = Segment(exeSuccessMsg.getLength(), MSG_TYPE_EXECUTE_SUCCESS, &exeSuccessMsg);
            int tstatus = exeSuccessSeg.send(i);
            cout << "ExecuteSuccessMessage status: " << tstatus << endl;

          }else{
            ExecuteFailureMessage exeFailMsg = ExecuteFailureMessage(result);
            Segment exeFailSeg = Segment(exeFailMsg.getLength(), MSG_TYPE_EXECUTE_FAILURE, &exeFailMsg);
            int tstatus = exeFailSeg.send(i);
          }

        }else if(segment->getType() == MSG_TYPE_TERMINATE){
          cout << "Got to terminate" << endl;
          onSwitch = false;
          //and other clean up
        }
      }
    }
  }

  // Destroys the welcome socket
  destroySocket(welcomeSocket);

  return 0;
}

int rpcCacheCall() {
  cout << "Running rpcCacheCall..." << endl;
	return 0;
}

int rpcTerminate() {
	cout << "Running rpcTerminate..." << endl;

  // Sends a terminate message to the binder
  TerminateMessage messageToBinder = TerminateMessage();
  Segment segmentToBinder =
    Segment(messageToBinder.getLength(), MSG_TYPE_TERMINATE, &messageToBinder);
  int binder_status = segmentToBinder.send(binderSocket);
  cout << segmentToBinder.getType() << endl;

  cout << "binderSocket: " << binderSocket << endl;
  sleep(1);
  // Closes the connection to the binder
  destroySocket(binderSocket);

	return 0;
}
<|endoftext|>