<commit_before>// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-

/* This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2
 * as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 *
 * Authors:
 * Caner Candan <caner.candan@univ-angers.fr>
 */

#include <boost/algorithm/string.hpp>
#include <boost/mpi.hpp>
#include <eo>
#include <eoSwapMutation.h>
#include <eoShiftMutation.h>
#include <eoInversionMutation.h>
#include <eoTwoOptMutation.h>
#include <dim/dim>
#include <dim/algo/Easy.h>
#include <dim/evolver/Easy.h>
#include <dim/feedbacker/Easy.h>
#include <dim/migrator/Easy.h>
#include <dim/vectorupdater/Easy.h>
#include <dim/core/State.h>

#if __cplusplus > 199711L
namespace std_or_boost = std;
#include <mutex>
#include <condition_variable>
#else
#include <boost/thread/thread.hpp>
#include <boost/chrono/chrono_io.hpp>
#include <boost/thread/mutex.hpp>
namespace std_or_boost = boost;
#endif

typedef dim::representation::Route<double> EOT;

int main (int argc, char *argv[])
{
    /*************************
     * Initialisation de MPI *
     *************************/

    // boost::mpi::environment env(argc, argv, MPI_THREAD_MULTIPLE, true);
    // boost::mpi::communicator world;

    /****************************
     * Il faut au moins 4 nœuds *
     ****************************/

    // const size_t ALL = world.size();
    // const size_t RANK = world.rank();

    /************************
     * Initialisation de EO *
     ************************/

    eoParser parser(argc, argv);
    eoState state;    // keeps all things allocated
    dim::core::State state_dim;    // keeps all things allocated

    /*****************************
     * Definition des paramètres *
     *****************************/

    // N
    unsigned nislands = parser.createParam(unsigned(4), "nislands", "Number of islands (see --smp)", 'N', "Islands Model").value();
    // a
    double alphaP = parser.createParam(double(0.2), "alpha", "Alpha Probability", 'a', "Islands Model").value();
    // A
    double alphaF = parser.createParam(double(0.01), "alphaF", "Alpha Fitness", 'A', "Islands Model").value();
    // b
    double betaP = parser.createParam(double(0.01), "beta", "Beta Probability", 'b', "Islands Model").value();
    // d
    double probaSame = parser.createParam(double(100./nislands), "probaSame", "Probability for an individual to stay in the same island", 'd', "Islands Model").value();
    // I
    bool initG = parser.createParam(bool(true), "initG", "initG", 'I', "Islands Model").value();
    unsigned nmigrations = parser.createParam(unsigned(1), "nmigrations", "Number of migrations to do at each generation (0=all individuals are migrated)", 0, "Islands Model").value();
    unsigned stepTimer = parser.createParam(unsigned(0), "stepTimer", "stepTimer", 0, "Islands Model").value();
    bool deltaUpdate = parser.createParam(bool(true), "deltaUpdate", "deltaUpdate", 0, "Islands Model").value();
    bool deltaFeedback = parser.createParam(bool(true), "deltaFeedback", "deltaFeedback", 0, "Islands Model").value();
    double sensitivity = 1 / parser.createParam(double(1.), "sensitivity", "sensitivity of delta{t} (1/sensitivity)", 0, "Islands Model").value();
    std::string rewardStrategy = parser.createParam(std::string("best"), "rewardStrategy", "Strategy of rewarding: best or avg", 0, "Islands Model").value();

    /*********************************
     * Déclaration des composants EO *
     *********************************/

    std::string tspInstance =  parser.getORcreateParam(std::string("benchs/ali535.xml"), "tspInstance", "filename of the instance for TSP problem", 0, "Problem").value();

    dim::evaluation::Route<double> mainEval;
    eoEvalFuncCounter<EOT> eval(mainEval);

    unsigned popSize = parser.getORcreateParam(unsigned(100), "popSize", "Population Size", 'P', "Evolution Engine").value();

    double targetFitness = parser.getORcreateParam(double(0), "targetFitness", "Stop when fitness reaches",'T', "Stopping criterion").value();
    unsigned maxGen = parser.getORcreateParam(unsigned(10000), "maxGen", "Maximum number of generations () = none)",'G',"Stopping criterion").value();

    std::string monitorPrefix = parser.getORcreateParam(std::string("result"), "monitorPrefix", "Monitor prefix filenames", '\0', "Output").value();

    std::map< std::string, eoMonOp<EOT>* > mapOperators;
    std::vector< std::string > operatorsOrder;

    mapOperators["swap"] = new eoSwapMutation<EOT>;		operatorsOrder.push_back("swap");
    mapOperators["shift"] = new eoShiftMutation<EOT>;		operatorsOrder.push_back("shift");
    mapOperators["inversion"] = new eoInversionMutation<EOT>;	operatorsOrder.push_back("inversion");

    mapOperators["first_improve_swap"] = new eoFirstImprovementSwapMutation<EOT>(eval);
    operatorsOrder.push_back("first_improve_swap");
    mapOperators["first_improve_shift"] = new eoFirstImprovementShiftMutation<EOT>(eval);
    operatorsOrder.push_back("first_improve_shift");
    mapOperators["first_improve_inversion"] = new eoFirstImprovementInversionMutation<EOT>(eval);
    operatorsOrder.push_back("first_improve_inversion");

    mapOperators["relative_best_improve_swap"] = new eoRelativeBestImprovementSwapMutation<EOT>(eval);
    operatorsOrder.push_back("relative_best_improve_swap");
    mapOperators["relative_best_improve_shift"] = new eoRelativeBestImprovementShiftMutation<EOT>(eval);
    operatorsOrder.push_back("relative_best_improve_shift");
    mapOperators["relative_best_improve_inversion"] = new eoRelativeBestImprovementInversionMutation<EOT>(eval);
    operatorsOrder.push_back("relative_best_improve_inversion");

    mapOperators["best_improve_swap"] = new eoBestImprovementSwapMutation<EOT>(eval);
    operatorsOrder.push_back("best_improve_swap");
    mapOperators["best_improve_shift"] = new eoBestImprovementShiftMutation<EOT>(eval);
    operatorsOrder.push_back("best_improve_shift");
    mapOperators["best_improve_inversion"] = new eoBestImprovementInversionMutation<EOT>(eval);
    operatorsOrder.push_back("best_improve_inversion");

    mapOperators["2swap"] = new eoSwapMutation<EOT>(2);	operatorsOrder.push_back("2swap");
    mapOperators["2opt"] = new eoTwoOptMutation<EOT>;	operatorsOrder.push_back("2opt");

    std::ostringstream ssOrder, ssOrder2;
    ssOrder << "Set an operator between " << operatorsOrder[0];
    ssOrder2 << "List of operators separeted by a comma. Select operators between " << operatorsOrder[0];
    for ( size_t k = 1; k < operatorsOrder.size(); ++k )
	{
	    ssOrder << "," << operatorsOrder[k];
	    ssOrder2 << "," << operatorsOrder[k];
	}

    std::vector<std::string> operatorsVec(nislands, "");

    for (size_t i = 0; i < nislands; ++i)
	{
	    std::ostringstream ss;
	    ss << "operator" << i;
	    operatorsVec[i] = parser.createParam(std::string(operatorsOrder[ i % operatorsOrder.size() ]), ss.str(), ssOrder.str(), 0, "Islands Model").value();
	}

    // O
    std::string operators = parser.createParam(std::string(""), "operators", ssOrder2.str(), 'O', "Islands Model").value();

    if (!operators.empty())
	{
	    boost::split(operatorsVec, operators, boost::is_any_of(","));
	}

    /**************
     * EO routine *
     **************/

    make_parallel(parser);
    make_verbose(parser);
    make_help(parser);

    dim::initialization::TSPLibGraph::load( tspInstance ); // Instance
    dim::initialization::Route<double> init ; // Sol. Random Init.
    dim::core::Pop<EOT>& pop = dim::do_make::detail::pop(parser, state, init);

    // smp

    /**********************************
     * Déclaration des composants DIM *
     **********************************/

    dim::core::ThreadsRunner< EOT > tr;

    std::vector< dim::core::Pop<EOT>* > islandPop(nislands);
    std::vector< dim::core::IslandData<EOT>* > islandData(nislands);

    dim::core::MigrationMatrix probabilities( nislands );
    dim::core::InitMatrix initmatrix( initG, probaSame );

    initmatrix( probabilities );
    std::cout << probabilities;

    std::cout << "size: " << dim::initialization::TSPLibGraph::size() << std::endl;

    for (size_t i = 0; i < nislands; ++i)
	{
	    std::cout << "island " << i << std::endl;

	    islandPop[i] = new dim::core::Pop<EOT>(popSize, init);
	    islandData[i] = new dim::core::IslandData<EOT>(nislands, i);

	    std::cout << islandData[i]->size() << " " << islandData[i]->rank() << " " << operatorsVec[ islandData[i]->rank() ] << std::endl;

	    islandData[i]->proba = probabilities(i);
	    apply<EOT>(eval, *(islandPop[i]));

	    /****************************************
	     * Distribution des opérateurs aux iles *
	     ****************************************/

	    eoMonOp<EOT>* ptMon = mapOperators[ operatorsVec[ islandData[i]->rank() ] ];

	    dim::evolver::Base<EOT>* ptEvolver = new dim::evolver::Easy<EOT>( /*eval*/mainEval, *ptMon );
	    state_dim.storeFunctor(ptEvolver);

	    dim::feedbacker::Base<EOT>* ptFeedbacker = new dim::feedbacker::smp::Easy<EOT>(islandPop, islandData, alphaF);
	    state_dim.storeFunctor(ptFeedbacker);

	    dim::vectorupdater::Reward<EOT>* ptReward = NULL;
	    if (rewardStrategy == "best")
		{
		    ptReward = new dim::vectorupdater::Best<EOT>(alphaP, betaP);
		}
	    else
		{
		    ptReward = new dim::vectorupdater::Average<EOT>(alphaP, betaP);
		}
	    state_dim.storeFunctor(ptReward);

	    dim::vectorupdater::Base<EOT>* ptUpdater = new dim::vectorupdater::Easy<EOT>(*ptReward);
	    state_dim.storeFunctor(ptUpdater);

	    dim::memorizer::Base<EOT>* ptMemorizer = new dim::memorizer::Easy<EOT>();
	    state_dim.storeFunctor(ptMemorizer);

	    dim::migrator::Base<EOT>* ptMigrator = new dim::migrator::smp::Easy<EOT>(islandPop, islandData, monitorPrefix);
	    state_dim.storeFunctor(ptMigrator);

	    dim::continuator::Base<EOT>& continuator = dim::do_make::continuator<EOT>(parser, state, eval);
	    dim::utils::CheckPoint<EOT>& checkpoint = dim::do_make::checkpoint<EOT>(parser, state, continuator, *(islandData[i]), 1, stepTimer);

	    dim::algo::Base<EOT>* ptIsland = new dim::algo::smp::Easy<EOT>( *ptEvolver, *ptFeedbacker, *ptUpdater, *ptMemorizer, *ptMigrator, checkpoint, islandPop, islandData, monitorPrefix );
	    state_dim.storeFunctor(ptIsland);

	    ptEvolver->size(nislands);
	    ptFeedbacker->size(nislands);
	    ptReward->size(nislands);
	    ptUpdater->size(nislands);
	    ptMemorizer->size(nislands);
	    ptMigrator->size(nislands);
	    ptIsland->size(nislands);

	    ptEvolver->rank(i);
	    ptFeedbacker->rank(i);
	    ptReward->rank(i);
	    ptUpdater->rank(i);
	    ptMemorizer->rank(i);
	    ptMigrator->rank(i);
	    ptIsland->rank(i);

	    tr.add(*ptIsland);
	}

    dim::core::IslandData<EOT> data(nislands);
    tr(pop, data);

    for (size_t i = 0; i < nislands; ++i)
	{
	    delete islandPop[i];
	    delete islandData[i];
	}

    for ( std::map< std::string, eoMonOp<EOT>* >::iterator it = mapOperators.begin(); it != mapOperators.end(); ++it )
    	{
    	    delete it->second;
    	}

    return 0;
}
<commit_msg>* ../../../application/TSP/tsp.cpp: fixed a missing param value for result location<commit_after>// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-

/* This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2
 * as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 *
 * Authors:
 * Caner Candan <caner.candan@univ-angers.fr>
 */

#include <boost/algorithm/string.hpp>
#include <boost/mpi.hpp>
#include <eo>
#include <eoSwapMutation.h>
#include <eoShiftMutation.h>
#include <eoInversionMutation.h>
#include <eoTwoOptMutation.h>
#include <dim/dim>
#include <dim/algo/Easy.h>
#include <dim/evolver/Easy.h>
#include <dim/feedbacker/Easy.h>
#include <dim/migrator/Easy.h>
#include <dim/vectorupdater/Easy.h>
#include <dim/core/State.h>

#if __cplusplus > 199711L
namespace std_or_boost = std;
#include <mutex>
#include <condition_variable>
#else
#include <boost/thread/thread.hpp>
#include <boost/chrono/chrono_io.hpp>
#include <boost/thread/mutex.hpp>
namespace std_or_boost = boost;
#endif

typedef dim::representation::Route<double> EOT;

int main (int argc, char *argv[])
{
    /*************************
     * Initialisation de MPI *
     *************************/

    // boost::mpi::environment env(argc, argv, MPI_THREAD_MULTIPLE, true);
    // boost::mpi::communicator world;

    /****************************
     * Il faut au moins 4 nœuds *
     ****************************/

    // const size_t ALL = world.size();
    // const size_t RANK = world.rank();

    /************************
     * Initialisation de EO *
     ************************/

    eoParser parser(argc, argv);
    eoState state;    // keeps all things allocated
    dim::core::State state_dim;    // keeps all things allocated

    /*****************************
     * Definition des paramètres *
     *****************************/

    // N
    unsigned nislands = parser.createParam(unsigned(4), "nislands", "Number of islands (see --smp)", 'N', "Islands Model").value();
    // a
    double alphaP = parser.createParam(double(0.2), "alpha", "Alpha Probability", 'a', "Islands Model").value();
    // A
    double alphaF = parser.createParam(double(0.01), "alphaF", "Alpha Fitness", 'A', "Islands Model").value();
    // b
    double betaP = parser.createParam(double(0.01), "beta", "Beta Probability", 'b', "Islands Model").value();
    // d
    double probaSame = parser.createParam(double(100./nislands), "probaSame", "Probability for an individual to stay in the same island", 'd', "Islands Model").value();
    // I
    bool initG = parser.createParam(bool(true), "initG", "initG", 'I', "Islands Model").value();
    unsigned nmigrations = parser.createParam(unsigned(1), "nmigrations", "Number of migrations to do at each generation (0=all individuals are migrated)", 0, "Islands Model").value();
    unsigned stepTimer = parser.createParam(unsigned(0), "stepTimer", "stepTimer", 0, "Islands Model").value();
    bool deltaUpdate = parser.createParam(bool(true), "deltaUpdate", "deltaUpdate", 0, "Islands Model").value();
    bool deltaFeedback = parser.createParam(bool(true), "deltaFeedback", "deltaFeedback", 0, "Islands Model").value();
    double sensitivity = 1 / parser.createParam(double(1.), "sensitivity", "sensitivity of delta{t} (1/sensitivity)", 0, "Islands Model").value();
    std::string rewardStrategy = parser.createParam(std::string("best"), "rewardStrategy", "Strategy of rewarding: best or avg", 0, "Islands Model").value();

    /*********************************
     * Déclaration des composants EO *
     *********************************/

    std::string tspInstance =  parser.getORcreateParam(std::string("benchs/ali535.xml"), "tspInstance", "filename of the instance for TSP problem", 0, "Problem").value();

    dim::evaluation::Route<double> mainEval;
    eoEvalFuncCounter<EOT> eval(mainEval);

    unsigned popSize = parser.getORcreateParam(unsigned(100), "popSize", "Population Size", 'P', "Evolution Engine").value();

    double targetFitness = parser.getORcreateParam(double(0), "targetFitness", "Stop when fitness reaches",'T', "Stopping criterion").value();
    unsigned maxGen = parser.getORcreateParam(unsigned(10000), "maxGen", "Maximum number of generations () = none)",'G',"Stopping criterion").value();

    std::string monitorPrefix = parser.getORcreateParam(std::string("result"), "monitorPrefix", "Monitor prefix filenames", '\0', "Output").value();

    std::map< std::string, eoMonOp<EOT>* > mapOperators;
    std::vector< std::string > operatorsOrder;

    mapOperators["swap"] = new eoSwapMutation<EOT>;		operatorsOrder.push_back("swap");
    mapOperators["shift"] = new eoShiftMutation<EOT>;		operatorsOrder.push_back("shift");
    mapOperators["inversion"] = new eoInversionMutation<EOT>;	operatorsOrder.push_back("inversion");

    mapOperators["first_improve_swap"] = new eoFirstImprovementSwapMutation<EOT>(eval);
    operatorsOrder.push_back("first_improve_swap");
    mapOperators["first_improve_shift"] = new eoFirstImprovementShiftMutation<EOT>(eval);
    operatorsOrder.push_back("first_improve_shift");
    mapOperators["first_improve_inversion"] = new eoFirstImprovementInversionMutation<EOT>(eval);
    operatorsOrder.push_back("first_improve_inversion");

    mapOperators["relative_best_improve_swap"] = new eoRelativeBestImprovementSwapMutation<EOT>(eval);
    operatorsOrder.push_back("relative_best_improve_swap");
    mapOperators["relative_best_improve_shift"] = new eoRelativeBestImprovementShiftMutation<EOT>(eval);
    operatorsOrder.push_back("relative_best_improve_shift");
    mapOperators["relative_best_improve_inversion"] = new eoRelativeBestImprovementInversionMutation<EOT>(eval);
    operatorsOrder.push_back("relative_best_improve_inversion");

    mapOperators["best_improve_swap"] = new eoBestImprovementSwapMutation<EOT>(eval);
    operatorsOrder.push_back("best_improve_swap");
    mapOperators["best_improve_shift"] = new eoBestImprovementShiftMutation<EOT>(eval);
    operatorsOrder.push_back("best_improve_shift");
    mapOperators["best_improve_inversion"] = new eoBestImprovementInversionMutation<EOT>(eval);
    operatorsOrder.push_back("best_improve_inversion");

    mapOperators["2swap"] = new eoSwapMutation<EOT>(2);	operatorsOrder.push_back("2swap");
    mapOperators["2opt"] = new eoTwoOptMutation<EOT>;	operatorsOrder.push_back("2opt");

    std::ostringstream ssOrder, ssOrder2;
    ssOrder << "Set an operator between " << operatorsOrder[0];
    ssOrder2 << "List of operators separeted by a comma. Select operators between " << operatorsOrder[0];
    for ( size_t k = 1; k < operatorsOrder.size(); ++k )
	{
	    ssOrder << "," << operatorsOrder[k];
	    ssOrder2 << "," << operatorsOrder[k];
	}

    std::vector<std::string> operatorsVec(nislands, "");

    for (size_t i = 0; i < nislands; ++i)
	{
	    std::ostringstream ss;
	    ss << "operator" << i;
	    operatorsVec[i] = parser.createParam(std::string(operatorsOrder[ i % operatorsOrder.size() ]), ss.str(), ssOrder.str(), 0, "Islands Model").value();
	}

    // O
    std::string operators = parser.createParam(std::string(""), "operators", ssOrder2.str(), 'O', "Islands Model").value();

    if (!operators.empty())
	{
	    boost::split(operatorsVec, operators, boost::is_any_of(","));
	}

    /**************
     * EO routine *
     **************/

    make_parallel(parser);
    make_verbose(parser);
    make_help(parser);

    dim::initialization::TSPLibGraph::load( tspInstance ); // Instance
    dim::initialization::Route<double> init ; // Sol. Random Init.
    dim::core::Pop<EOT>& pop = dim::do_make::detail::pop(parser, state, init);

    // smp

    /**********************************
     * Déclaration des composants DIM *
     **********************************/

    dim::core::ThreadsRunner< EOT > tr;

    std::vector< dim::core::Pop<EOT>* > islandPop(nislands);
    std::vector< dim::core::IslandData<EOT>* > islandData(nislands);

    dim::core::MigrationMatrix probabilities( nislands );
    dim::core::InitMatrix initmatrix( initG, probaSame );

    initmatrix( probabilities );
    std::cout << probabilities;

    std::cout << "size: " << dim::initialization::TSPLibGraph::size() << std::endl;

    for (size_t i = 0; i < nislands; ++i)
	{
	    std::cout << "island " << i << std::endl;

	    islandPop[i] = new dim::core::Pop<EOT>(popSize, init);
	    islandData[i] = new dim::core::IslandData<EOT>(nislands, i);

	    std::cout << islandData[i]->size() << " " << islandData[i]->rank() << " " << operatorsVec[ islandData[i]->rank() ] << std::endl;

	    islandData[i]->proba = probabilities(i);
	    apply<EOT>(eval, *(islandPop[i]));

	    /****************************************
	     * Distribution des opérateurs aux iles *
	     ****************************************/

	    eoMonOp<EOT>* ptMon = mapOperators[ operatorsVec[ islandData[i]->rank() ] ];

	    dim::evolver::Base<EOT>* ptEvolver = new dim::evolver::Easy<EOT>( /*eval*/mainEval, *ptMon );
	    state_dim.storeFunctor(ptEvolver);

	    dim::feedbacker::Base<EOT>* ptFeedbacker = new dim::feedbacker::smp::Easy<EOT>(islandPop, islandData, alphaF, monitorPrefix);
	    state_dim.storeFunctor(ptFeedbacker);

	    dim::vectorupdater::Reward<EOT>* ptReward = NULL;
	    if (rewardStrategy == "best")
		{
		    ptReward = new dim::vectorupdater::Best<EOT>(alphaP, betaP);
		}
	    else
		{
		    ptReward = new dim::vectorupdater::Average<EOT>(alphaP, betaP);
		}
	    state_dim.storeFunctor(ptReward);

	    dim::vectorupdater::Base<EOT>* ptUpdater = new dim::vectorupdater::Easy<EOT>(*ptReward);
	    state_dim.storeFunctor(ptUpdater);

	    dim::memorizer::Base<EOT>* ptMemorizer = new dim::memorizer::Easy<EOT>();
	    state_dim.storeFunctor(ptMemorizer);

	    dim::migrator::Base<EOT>* ptMigrator = new dim::migrator::smp::Easy<EOT>(islandPop, islandData, monitorPrefix);
	    state_dim.storeFunctor(ptMigrator);

	    dim::continuator::Base<EOT>& continuator = dim::do_make::continuator<EOT>(parser, state, eval);
	    dim::utils::CheckPoint<EOT>& checkpoint = dim::do_make::checkpoint<EOT>(parser, state, continuator, *(islandData[i]), 1, stepTimer);

	    dim::algo::Base<EOT>* ptIsland = new dim::algo::smp::Easy<EOT>( *ptEvolver, *ptFeedbacker, *ptUpdater, *ptMemorizer, *ptMigrator, checkpoint, islandPop, islandData, monitorPrefix );
	    state_dim.storeFunctor(ptIsland);

	    ptEvolver->size(nislands);
	    ptFeedbacker->size(nislands);
	    ptReward->size(nislands);
	    ptUpdater->size(nislands);
	    ptMemorizer->size(nislands);
	    ptMigrator->size(nislands);
	    ptIsland->size(nislands);

	    ptEvolver->rank(i);
	    ptFeedbacker->rank(i);
	    ptReward->rank(i);
	    ptUpdater->rank(i);
	    ptMemorizer->rank(i);
	    ptMigrator->rank(i);
	    ptIsland->rank(i);

	    tr.add(*ptIsland);
	}

    dim::core::IslandData<EOT> data(nislands);
    tr(pop, data);

    for (size_t i = 0; i < nislands; ++i)
	{
	    delete islandPop[i];
	    delete islandData[i];
	}

    for ( std::map< std::string, eoMonOp<EOT>* >::iterator it = mapOperators.begin(); it != mapOperators.end(); ++it )
    	{
    	    delete it->second;
    	}

    return 0;
}
<|endoftext|>


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

#include "appinit.hxx"
#include "cmdlineargs.hxx"
#include "officeacceptthread.hxx"

#ifndef _COM_SUN_STAR_REGISTRY_XSIMPLEREGISTRY_HPP_
#include <com/sun/star/registry/XSimpleRegistry.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XCOMPONENT_HPP_
#include <com/sun/star/lang/XComponent.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XINITIALIZATION_HPP_
#include <com/sun/star/lang/XInitialization.hpp>
#endif
#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
#include <com/sun/star/beans/XPropertySet.hpp>
#endif

#ifndef _CPPUHELPER_SERVICEFACTORY_HXX_
#include <cppuhelper/servicefactory.hxx>
#endif
#ifndef _CPPUHELPER_BOOTSTRAP_HXX_
#include <cppuhelper/bootstrap.hxx>
#endif
#ifndef _OSL_FILE_HXX_
#include <osl/file.hxx>
#endif
#ifndef _VOS_PROCESS_HXX_
#include <vos/process.hxx>
#endif
#ifndef _RTL_URI_HXX_
#include <rtl/uri.hxx>
#endif
#ifndef _RTL_USTRBUF_HXX_
#include <rtl/ustrbuf.hxx>
#endif
#ifndef _COMPHELPER_REGPATHHELPER_HXX_
#include <comphelper/regpathhelper.hxx>
#endif
#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif
#ifndef _TOOLS_TEMPFILE_HXX
#include <tools/tempfile.hxx>
#endif
#ifndef _UCBHELPER_CONFIGURATIONKEYS_HXX_
#include <ucbhelper/configurationkeys.hxx>
#endif

#include <cppuhelper/bootstrap.hxx>
#include <tools/urlobj.hxx>

#include <rtl/logfile.hxx>
#include <comphelper/processfactory.hxx>
#include <unotools/localfilehelper.hxx>
#include <unotools/ucbhelper.hxx>
#include <unotools/tempfile.hxx>
#include <ucbhelper/contentbroker.hxx>
#include <vcl/svapp.hxx>
#ifndef INCLUDED_SVTOOLS_STARTOPTIONS_HXX
#include <svtools/startoptions.hxx>
#endif
#ifndef INCLUDED_SVTOOLS_PATHOPTIONS_HXX
#include <svtools/pathoptions.hxx>
#endif
#ifndef INCLUDED_SVTOOLS_INTERNALOPTIONS_HXX
#include <svtools/internaloptions.hxx>
#endif

#define DEFINE_CONST_UNICODE(CONSTASCII)        UniString(RTL_CONSTASCII_USTRINGPARAM(CONSTASCII))
#define DEFINE_CONST_OUSTRING(CONSTASCII)       OUString(RTL_CONSTASCII_USTRINGPARAM(CONSTASCII))

#define DESKTOP_TEMPDIRNAME                     "soffice.tmp"

using namespace rtl;
using namespace vos;
using namespace desktop;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::registry;

extern desktop::CommandLineArgs*        GetCommandLineArgs();
extern desktop::OOfficeAcceptorThread*  pOfficeAcceptThread;

static String aCurrentTempURL;

// -----------------------------------------------------------------------------

static bool configureUcb(bool bServer, rtl::OUString const & rPortalConnect)
{
    RTL_LOGFILE_CONTEXT( aLog, "desktop (sb93797) ::configureUcb" );
    Reference< XMultiServiceFactory >
        xServiceFactory( comphelper::getProcessServiceFactory() );
    if (!xServiceFactory.is())
    {
        DBG_ERROR("configureUcb(): No XMultiServiceFactory");
        return false;
    }

    rtl::OUString aPipe;
    vos::OSecurity().getUserIdent(aPipe);

    rtl::OUStringBuffer aPortal;
    if (rPortalConnect.getLength() != 0)
    {
        aPortal.append(sal_Unicode(','));
        aPortal.append(rPortalConnect);
    }

    Sequence< Any > aArgs(6);
    aArgs[0]
        <<= rtl::OUString::createFromAscii(bServer ?
                                               UCB_CONFIGURATION_KEY1_SERVER :
                                               UCB_CONFIGURATION_KEY1_LOCAL);
    aArgs[1]
        <<= rtl::OUString::createFromAscii(UCB_CONFIGURATION_KEY2_OFFICE);
    aArgs[2] <<= rtl::OUString::createFromAscii("PIPE");
    aArgs[3] <<= aPipe;
    aArgs[4] <<= rtl::OUString::createFromAscii("PORTAL");
    aArgs[5] <<= aPortal.makeStringAndClear();

    return ::ucb::ContentBroker::initialize( xServiceFactory, aArgs ) != false;
}

Reference< XMultiServiceFactory > createApplicationServiceManager()
{
    RTL_LOGFILE_CONTEXT( aLog, "desktop (cd100003) ::createApplicationServiceManager" );

    try
    {
        Reference<XComponentContext> xComponentContext = ::cppu::defaultBootstrap_InitialComponentContext();
        Reference<XMultiServiceFactory> xMS(xComponentContext->getServiceManager(), UNO_QUERY);

        return xMS;
    }
    catch( ::com::sun::star::uno::Exception& )
    {
    }

    return Reference< XMultiServiceFactory >();
}

void destroyApplicationServiceManager( Reference< XMultiServiceFactory >& xSMgr )
{
    Reference< XPropertySet > xProps( xSMgr, UNO_QUERY );
    if ( xProps.is() )
    {
        try
        {
            Reference< XComponent > xComp;
            if (xProps->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ))) >>= xComp )
            {
                xComp->dispose();
            }
        }
        catch ( UnknownPropertyException& )
        {
        }
    }
}

void registerServices( Reference< XMultiServiceFactory >& xSMgr )
{
    RTL_LOGFILE_CONTEXT( aLog, "desktop (cd100003) ::registerServices" );

    // read command line parameters
    ::rtl::OUString conDcp;
    ::rtl::OUString aClientDisplay;
    ::rtl::OUString aUserDir;
    ::rtl::OUString aTmpString;
    sal_Bool        bHeadlessMode = sal_False;

    // interpret command line arguments
    CommandLineArgs* pCmdLine = GetCommandLineArgs();

    // read accept string from configuration
    if ( !Application::IsRemoteServer() )
        conDcp = SvtStartOptions().GetConnectionURL();

    if ( pCmdLine->GetAcceptString( aTmpString ))
        conDcp = aTmpString;
    pCmdLine->GetUserDir( aUserDir );

    if ( Application::IsRemoteServer() )
    {
        bHeadlessMode   = pCmdLine->IsHeadless();
        pCmdLine->GetClientDisplay( aClientDisplay );
    }

    if ( bHeadlessMode )
        Application::EnableHeadlessMode();

    if ( conDcp.getLength() > 0 )
    {
        // accept incoming connections (scripting and one rvp)
        RTL_LOGFILE_CONTEXT( aLog, "desktop (cd100003) ::OOfficeAcceptorThread::OOfficeAcceptorThread" );
        pOfficeAcceptThread = new OOfficeAcceptorThread( xSMgr, conDcp, bHeadlessMode, aClientDisplay, aUserDir );
        pOfficeAcceptThread->create();
    }

    // improves parallel processing on Sun ONE Webtop
    // servicemanager up -> copy user installation
    if ( Application::IsRemoteServer() )
    {
        RTL_LOGFILE_CONTEXT( aLog, "desktop (cd100003) createInstance com.sun.star.portal.InstallUser" );
        Any aAny;
        Reference <XInterface> xRef =  xSMgr->createInstanceWithArguments(
            OUString::createFromAscii( "com.sun.star.portal.InstallUser" ),
            Sequence<Any>( &aAny, 1 ) );
    }

    ::rtl::OUString aPortalConnect;
    bool bServer = (bool) pCmdLine->IsServer();

    pCmdLine->GetPortalConnectString( aPortalConnect );
    if ( !configureUcb( bServer, aPortalConnect ) )
    {
        DBG_ERROR( "Can't configure UCB" );
        exit(-1);
    }

//  UCB_Helper::Initialize(); !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    createTemporaryDirectory();
}

void createTemporaryDirectory()
{
    RTL_LOGFILE_CONTEXT( aLog, "desktop (cd100003) ::createTemporaryDirectory" );

    // remove possible old directory and base directory
    SvtPathOptions      aOpt;
    SvtInternalOptions  aInternalOpt;

    // set temp base directory
    ::rtl::OUString aTempBaseURL( aOpt.GetTempPath() );
    sal_Int32 nLength = aTempBaseURL.getLength();
    if ( aTempBaseURL.matchAsciiL( "/", 1, nLength-1 ) )
        aTempBaseURL = aTempBaseURL.copy( 0, nLength - 1 );

    String aOldTempURL = aInternalOpt.GetCurrentTempURL();
    if ( aOldTempURL.Len() > 0 )
    {
        // remove old temporary directory
        ::utl::UCBContentHelper::Kill( aOldTempURL );
    }

    String aRet;
    ::rtl::OUString aTempPath( aTempBaseURL );

    // create new current temporary directory
    ::utl::LocalFileHelper::ConvertURLToPhysicalName( aTempBaseURL, aRet );
    ::osl::FileBase::getFileURLFromSystemPath( aRet, aTempPath );
    aTempPath = ::utl::TempFile::SetTempNameBaseDirectory( aTempPath );
    if ( !aTempPath.getLength() )
    {
        ::osl::File::getTempDirURL( aTempBaseURL );

        sal_Int32 nLength = aTempBaseURL.getLength();
        if ( aTempBaseURL.matchAsciiL( "/", 1, nLength-1 ) )
            aTempBaseURL = aTempBaseURL.copy( 0, nLength - 1 );

        aTempPath = aTempBaseURL;
        ::osl::FileBase::getFileURLFromSystemPath( aRet, aTempPath );
        aTempPath = ::utl::TempFile::SetTempNameBaseDirectory( aTempPath );
    }

    // set new current temporary directory
    ::utl::LocalFileHelper::ConvertPhysicalNameToURL( aTempPath, aRet );
    aInternalOpt.SetCurrentTempURL( aRet );
    aCurrentTempURL = aRet;
}

void removeTemporaryDirectory()
{
    RTL_LOGFILE_CONTEXT( aLog, "desktop (cd100003) ::removeTemporaryDirectory" );

    // remove current temporary directory
    if ( aCurrentTempURL.Len() > 0 )
    {
        if ( ::utl::UCBContentHelper::Kill( aCurrentTempURL ) )
            SvtInternalOptions().SetCurrentTempURL( String() );
    }
}
<commit_msg>#103426# Ignore -server cmdline parameter if not correcr env<commit_after>/*************************************************************************
 *
 *  $RCSfile: appinit.cxx,v $
 *
 *  $Revision: 1.12 $
 *
 *  last change: $Author: cd $ $Date: 2002-09-23 11:05:07 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#include "appinit.hxx"
#include "cmdlineargs.hxx"
#include "officeacceptthread.hxx"

#ifndef _COM_SUN_STAR_REGISTRY_XSIMPLEREGISTRY_HPP_
#include <com/sun/star/registry/XSimpleRegistry.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XCOMPONENT_HPP_
#include <com/sun/star/lang/XComponent.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XINITIALIZATION_HPP_
#include <com/sun/star/lang/XInitialization.hpp>
#endif
#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
#include <com/sun/star/beans/XPropertySet.hpp>
#endif
#ifndef _COM_SUN_STAR_CONTAINER_XCONTENTENUMERATIONACCESS_HPP_
#include <com/sun/star/container/XContentEnumerationAccess.hpp>
#endif

#ifndef _CPPUHELPER_SERVICEFACTORY_HXX_
#include <cppuhelper/servicefactory.hxx>
#endif
#ifndef _CPPUHELPER_BOOTSTRAP_HXX_
#include <cppuhelper/bootstrap.hxx>
#endif
#ifndef _OSL_FILE_HXX_
#include <osl/file.hxx>
#endif
#ifndef _VOS_PROCESS_HXX_
#include <vos/process.hxx>
#endif
#ifndef _RTL_URI_HXX_
#include <rtl/uri.hxx>
#endif
#ifndef _RTL_USTRBUF_HXX_
#include <rtl/ustrbuf.hxx>
#endif
#ifndef _COMPHELPER_REGPATHHELPER_HXX_
#include <comphelper/regpathhelper.hxx>
#endif
#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif
#ifndef _TOOLS_TEMPFILE_HXX
#include <tools/tempfile.hxx>
#endif
#ifndef _UCBHELPER_CONFIGURATIONKEYS_HXX_
#include <ucbhelper/configurationkeys.hxx>
#endif

#include <cppuhelper/bootstrap.hxx>
#include <tools/urlobj.hxx>

#include <rtl/logfile.hxx>
#include <comphelper/processfactory.hxx>
#include <unotools/localfilehelper.hxx>
#include <unotools/ucbhelper.hxx>
#include <unotools/tempfile.hxx>
#include <ucbhelper/contentbroker.hxx>
#include <vcl/svapp.hxx>
#ifndef INCLUDED_SVTOOLS_STARTOPTIONS_HXX
#include <svtools/startoptions.hxx>
#endif
#ifndef INCLUDED_SVTOOLS_PATHOPTIONS_HXX
#include <svtools/pathoptions.hxx>
#endif
#ifndef INCLUDED_SVTOOLS_INTERNALOPTIONS_HXX
#include <svtools/internaloptions.hxx>
#endif

#define DEFINE_CONST_UNICODE(CONSTASCII)        UniString(RTL_CONSTASCII_USTRINGPARAM(CONSTASCII))
#define DEFINE_CONST_OUSTRING(CONSTASCII)       OUString(RTL_CONSTASCII_USTRINGPARAM(CONSTASCII))

#define DESKTOP_TEMPDIRNAME                     "soffice.tmp"

using namespace rtl;
using namespace vos;
using namespace desktop;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::registry;

extern desktop::CommandLineArgs*        GetCommandLineArgs();
extern desktop::OOfficeAcceptorThread*  pOfficeAcceptThread;

static String aCurrentTempURL;

// -----------------------------------------------------------------------------

static bool configureUcb(bool bServer, rtl::OUString const & rPortalConnect)
{
    RTL_LOGFILE_CONTEXT( aLog, "desktop (sb93797) ::configureUcb" );
    Reference< XMultiServiceFactory >
        xServiceFactory( comphelper::getProcessServiceFactory() );
    if (!xServiceFactory.is())
    {
        DBG_ERROR("configureUcb(): No XMultiServiceFactory");
        return false;
    }

    rtl::OUString aPipe;
    vos::OSecurity().getUserIdent(aPipe);

    rtl::OUStringBuffer aPortal;
    if (rPortalConnect.getLength() != 0)
    {
        aPortal.append(sal_Unicode(','));
        aPortal.append(rPortalConnect);
    }

    Sequence< Any > aArgs(6);
    aArgs[0]
        <<= rtl::OUString::createFromAscii(bServer ?
                                               UCB_CONFIGURATION_KEY1_SERVER :
                                               UCB_CONFIGURATION_KEY1_LOCAL);
    aArgs[1]
        <<= rtl::OUString::createFromAscii(UCB_CONFIGURATION_KEY2_OFFICE);
    aArgs[2] <<= rtl::OUString::createFromAscii("PIPE");
    aArgs[3] <<= aPipe;
    aArgs[4] <<= rtl::OUString::createFromAscii("PORTAL");
    aArgs[5] <<= aPortal.makeStringAndClear();

    return ::ucb::ContentBroker::initialize( xServiceFactory, aArgs ) != false;
}

Reference< XMultiServiceFactory > createApplicationServiceManager()
{
    RTL_LOGFILE_CONTEXT( aLog, "desktop (cd100003) ::createApplicationServiceManager" );

    try
    {
        Reference<XComponentContext> xComponentContext = ::cppu::defaultBootstrap_InitialComponentContext();
        Reference<XMultiServiceFactory> xMS(xComponentContext->getServiceManager(), UNO_QUERY);

        return xMS;
    }
    catch( ::com::sun::star::uno::Exception& )
    {
    }

    return Reference< XMultiServiceFactory >();
}

void destroyApplicationServiceManager( Reference< XMultiServiceFactory >& xSMgr )
{
    Reference< XPropertySet > xProps( xSMgr, UNO_QUERY );
    if ( xProps.is() )
    {
        try
        {
            Reference< XComponent > xComp;
            if (xProps->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ))) >>= xComp )
            {
                xComp->dispose();
            }
        }
        catch ( UnknownPropertyException& )
        {
        }
    }
}

void registerServices( Reference< XMultiServiceFactory >& xSMgr )
{
    RTL_LOGFILE_CONTEXT( aLog, "desktop (cd100003) ::registerServices" );

    // read command line parameters
    ::rtl::OUString conDcp;
    ::rtl::OUString aClientDisplay;
    ::rtl::OUString aUserDir;
    ::rtl::OUString aTmpString;
    sal_Bool        bHeadlessMode = sal_False;

    // interpret command line arguments
    CommandLineArgs* pCmdLine = GetCommandLineArgs();

    // read accept string from configuration
    if ( !Application::IsRemoteServer() )
        conDcp = SvtStartOptions().GetConnectionURL();

    if ( pCmdLine->GetAcceptString( aTmpString ))
        conDcp = aTmpString;
    pCmdLine->GetUserDir( aUserDir );

    if ( Application::IsRemoteServer() )
    {
        bHeadlessMode   = pCmdLine->IsHeadless();
        pCmdLine->GetClientDisplay( aClientDisplay );
    }

    if ( bHeadlessMode )
        Application::EnableHeadlessMode();

    if ( conDcp.getLength() > 0 )
    {
        // accept incoming connections (scripting and one rvp)
        RTL_LOGFILE_CONTEXT( aLog, "desktop (cd100003) ::OOfficeAcceptorThread::OOfficeAcceptorThread" );
        pOfficeAcceptThread = new OOfficeAcceptorThread( xSMgr, conDcp, bHeadlessMode, aClientDisplay, aUserDir );
        pOfficeAcceptThread->create();
    }

    // improves parallel processing on Sun ONE Webtop
    // servicemanager up -> copy user installation
    if ( Application::IsRemoteServer() )
    {
        RTL_LOGFILE_CONTEXT( aLog, "desktop (cd100003) createInstance com.sun.star.portal.InstallUser" );
        Any aAny;
        Reference <XInterface> xRef =  xSMgr->createInstanceWithArguments(
            OUString::createFromAscii( "com.sun.star.portal.InstallUser" ),
            Sequence<Any>( &aAny, 1 ) );
    }
    else if ( pCmdLine->IsServer() )
    {
        // Check some mandatory environment states if "-server" is possible. Otherwise ignore
        // this parameter.
        Reference< com::sun::star::container::XContentEnumerationAccess > rContent( xSMgr , UNO_QUERY );
        if( rContent.is() )
        {
            OUString sPortalService = OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.portal.InstallUser" ) );
            Reference < com::sun::star::container::XEnumeration > rEnum = rContent->createContentEnumeration( sPortalService );
            if ( !rEnum.is() )
            {
                // Reset server parameter so it is ignored in the furthermore startup process
                pCmdLine->SetBoolParam( CommandLineArgs::CMD_BOOLPARAM_SERVER, sal_False );
            }
        }
    }

    ::rtl::OUString aPortalConnect;
    bool bServer = (bool) pCmdLine->IsServer();

    pCmdLine->GetPortalConnectString( aPortalConnect );
    if ( !configureUcb( bServer, aPortalConnect ) )
    {
        DBG_ERROR( "Can't configure UCB" );
        exit(-1);
    }

//  UCB_Helper::Initialize(); !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    createTemporaryDirectory();
}

void createTemporaryDirectory()
{
    RTL_LOGFILE_CONTEXT( aLog, "desktop (cd100003) ::createTemporaryDirectory" );

    // remove possible old directory and base directory
    SvtPathOptions      aOpt;
    SvtInternalOptions  aInternalOpt;

    // set temp base directory
    ::rtl::OUString aTempBaseURL( aOpt.GetTempPath() );
    sal_Int32 nLength = aTempBaseURL.getLength();
    if ( aTempBaseURL.matchAsciiL( "/", 1, nLength-1 ) )
        aTempBaseURL = aTempBaseURL.copy( 0, nLength - 1 );

    String aOldTempURL = aInternalOpt.GetCurrentTempURL();
    if ( aOldTempURL.Len() > 0 )
    {
        // remove old temporary directory
        ::utl::UCBContentHelper::Kill( aOldTempURL );
    }

    String aRet;
    ::rtl::OUString aTempPath( aTempBaseURL );

    // create new current temporary directory
    ::utl::LocalFileHelper::ConvertURLToPhysicalName( aTempBaseURL, aRet );
    ::osl::FileBase::getFileURLFromSystemPath( aRet, aTempPath );
    aTempPath = ::utl::TempFile::SetTempNameBaseDirectory( aTempPath );
    if ( !aTempPath.getLength() )
    {
        ::osl::File::getTempDirURL( aTempBaseURL );

        sal_Int32 nLength = aTempBaseURL.getLength();
        if ( aTempBaseURL.matchAsciiL( "/", 1, nLength-1 ) )
            aTempBaseURL = aTempBaseURL.copy( 0, nLength - 1 );

        aTempPath = aTempBaseURL;
        ::osl::FileBase::getFileURLFromSystemPath( aRet, aTempPath );
        aTempPath = ::utl::TempFile::SetTempNameBaseDirectory( aTempPath );
    }

    // set new current temporary directory
    ::utl::LocalFileHelper::ConvertPhysicalNameToURL( aTempPath, aRet );
    aInternalOpt.SetCurrentTempURL( aRet );
    aCurrentTempURL = aRet;
}

void removeTemporaryDirectory()
{
    RTL_LOGFILE_CONTEXT( aLog, "desktop (cd100003) ::removeTemporaryDirectory" );

    // remove current temporary directory
    if ( aCurrentTempURL.Len() > 0 )
    {
        if ( ::utl::UCBContentHelper::Kill( aCurrentTempURL ) )
            SvtInternalOptions().SetCurrentTempURL( String() );
    }
}
<|endoftext|>


<commit_before>// @(#)root/reflex:$Id$
// Author: Stefan Roiser 2006

// Copyright CERN, CH-1211 Geneva 23, 2004-2010, All rights reserved.
//
// Permission to use, copy, modify, and distribute this software for any
// purpose is hereby granted without fee, provided that this copyright and
// permissions notice appear in all copies and derivatives.
//
// This software is provided "as is" without express or implied warranty.

#ifndef REFLEX_BUILD
# define REFLEX_BUILD
#endif

#include "NameLookup.h"
#include "Reflex/Base.h"
#include "Reflex/Scope.h"
#include "Reflex/Type.h"
#include "Reflex/Tools.h"
#include "Reflex/internal/OwnedMember.h"

#include <sstream>
#include <string.h>

//______________________________________________________________________________
Reflex::NameLookup::NameLookup(const std::string& name, const Scope& current):
   fLookupName(name),
   fPosNamePart(0),
   fPosNamePartLen(std::string::npos),
   fCurrentScope(current),
   fPartialSuccess(false) {
   // Initialize a NameLookup object used internally to keep track of lookup
   // states.
}

//______________________________________________________________________________
Reflex::Type
Reflex::NameLookup::LookupType(const std::string& nam,
                               const Scope& current) {
   // Lookup up a (possibly scoped) type name appearing in the scope context
   // current. This is the public interface for type lookup.
   NameLookup lookup(nam, current);
   return lookup.Lookup<Type>();
}

//______________________________________________________________________________
Reflex::Scope
Reflex::NameLookup::LookupScope(const std::string& nam,
                                const Scope& current) {
   // Lookup up a (possibly scoped) scope name appearing in the scope context
   // current. This is the public interface for scope lookup.
   NameLookup lookup(nam, current);
   return lookup.Lookup<Scope>();
}

/*
   //______________________________________________________________________________
   Reflex::Member LookupMember(const std::string& nam, const Scope& current )
   {
   // Lookup up a (possibly scoped) member name appearing in the scope context
   // current. This is the public interface for member lookup.
   NameLookup lookup(nam, current);
   // this will not work, member lookup is too different from type lookup...
   return lookup.Lookup<Member>();
   }
 */

//______________________________________________________________________________
template <class T> T
Reflex::NameLookup::Lookup(bool isTemplateExpanded /* = false */) {
   // Lookup a type using fLookupName, fCurrentScope.

   Scope startScope = fCurrentScope;
   T result;

   fPartialSuccess = false;
   fPosNamePart = 0;
   fPosNamePartLen = std::string::npos;
   FindNextScopePos();

   if (fPosNamePart == 2) {
      fLookedAtUsingDir.clear();
      // ::A...
      fCurrentScope = Scope::GlobalScope();
      result = LookupInScope<T>();
   } else {
      // A...
      result = LookupInUnknownScope<T>();
   }

   if (!isTemplateExpanded && !result && fLookupName.find('<') != std::string::npos) {
      // We need to replace the template argument both of this type
      // and any of it enclosing type:
      //    myspace::mytop<A,B>::mytype<C>

      std::ostringstream tmp;

      for (size_t i = 0, level = 0, sofar = 0; i < fLookupName.size(); ++i) {
         if (level == 0) {
            tmp << fLookupName.substr(sofar, i + 1 - sofar);
            sofar = i + 1;
         }

         switch (fLookupName[i]) {
         case '<': ++level; break;
         case '>': --level;    // intentional fall through to the ',' case
         case ',':

            if (level == (1 - (unsigned int) (fLookupName[i] == '>'))) {
               std::string arg(fLookupName.substr(sofar, i - sofar));

               size_t p = arg.size();

               while (p > 0 && (arg[p - 1] == '*' || arg[p - 1] == '&' || arg[p - 1] == ' '))
                  --p;

               std::string end(arg.substr(p));
               arg.erase(p);

               const char* start = arg.c_str();

               while (strncmp(start, "const ", 6) == 0)
                  start += 6;

               tmp << arg.substr(0, start - arg.c_str());

               while (strncmp(start, "std::", 5) == 0)
                  start += 5;

               arg.erase(0, start - arg.c_str());

               Reflex::Type type(LookupType(arg, startScope));

               if (type) {
                  if (type.Name() != "Double32_t" && type.Name() != "Float16_t") {
                     // Use the real type rather than the typedef unless
                     // this is Double32_t or Float16_t
                     type = type.FinalType();
                  }
                  tmp << type.Name(Reflex::SCOPED | Reflex::QUALIFIED);
               } else {
                  tmp << arg;
               }
               tmp << end;

               tmp << fLookupName[i];

               sofar = i + 1;
            }
            break;
         } // switch
      }
      NameLookup next(tmp.str(), startScope);
      return next.Lookup<T>(true);
   }

   return result;
} // Lookup

//______________________________________________________________________________
template <class T> T
Reflex::NameLookup::LookupInScope() {
   // Lookup a type in fCurrentScope.
   // Checks sub-types, sub-scopes, using directives, and base classes for
   // the name given by fLookupName, fPosNamePart, and fPosNamePartLen.
   // If the name part is found, and another name part follows in fPosNamePart,
   // LookupTypeInScope requests the scope found to lookup the next name
   // part. fPartialMatch reflexts that the left part of the name was matched;
   // even if the trailing part of fLookupName cannot be found, the lookup
   // cannot continue on declaring scopes and has to fail.
   // A list of lookups performed in namespaces pulled in via using directives is
   // kept in fLookedAtUsingDir, to prevent infinite loops due to
   //   namespace A{using namespace B;} namespace B{using namespace A;}
   // loops.
   // The lookup does not take the declaration order into account; the result of
   // parts of the lookup algorithm which depend on the order will be unpredictable.

   if (!fCurrentScope) {
      return Dummy::Get<T>();
   }

   // prevent inf loop from
   // ns A { using ns B; } ns B {using ns A;}
   if (fLookedAtUsingDir.find(fCurrentScope) != fLookedAtUsingDir.end()) {
      return Dummy::Get<T>();
   }

   // global scope can use hashed containers:
   if (fCurrentScope == Scope::GlobalScope()) {
      Type freeType(Type::ByName(fLookupName.c_str() + fPosNamePart));

      if (freeType.Id()) {
         //fprintf(stderr, "Reflex::NameLookup::LookupInScope<T>: lookup up '%s', partial success with subscope '%s' ...\n", fLookupName.c_str(), name.c_str());
         fPartialSuccess = true;
         fLookedAtUsingDir.clear();
         FindNextScopePos();

         if (fPosNamePart == std::string::npos) {
            return freeType;
         }

         if (freeType.IsTypedef()) {
            fCurrentScope = freeType.FinalType();
         } else {
            fCurrentScope = freeType;
         }
         return LookupInScope<T>();
      }

      Scope freeScope(Scope::ByName(fLookupName.c_str() + fPosNamePart));

      // only take namespaces into account - classes were checked as part of SubType
      if (freeScope.Id() && freeScope.IsNamespace()) {
         fPartialSuccess = true;
         fLookedAtUsingDir.clear();
         FindNextScopePos();

         if (fPosNamePart == std::string::npos) {
            return (T) (freeScope);
         }
         fCurrentScope = freeScope;
         return LookupInScope<T>();
      }
   } // end of: if global scope
   else {
      // if not global scope

      size_t len = fCurrentScope.SubTypeSize();
      size_t i = 0;

      for (Type_Iterator it = fCurrentScope.SubType_Begin(); i < len; ++it, ++i) {
         const Type& type = *it;
         const TypeBase* base = type.ToTypeBase();

         if (base) {
            size_t pos;
            const std::string& name(base->SimpleName(pos));

            //fprintf(stderr, "Reflex::NameLookup::LookupInScope<T>: looking up '%s', considering subscope '%s' ...\n", fLookupName.c_str(), name.c_str());
            if (
               (fLookupName[fPosNamePart] == name[pos]) &&
               !fLookupName.compare(fPosNamePart, fPosNamePartLen, name, pos, name.length())
            ) {
               //fprintf(stderr, "Reflex::NameLookup::LookupInScope<T>: lookup up '%s', partial success with subscope '%s' ...\n", fLookupName.c_str(), name.c_str());
               fPartialSuccess = true;
               fLookedAtUsingDir.clear();
               FindNextScopePos();

               if (fPosNamePart == std::string::npos) {
                  return type;
               }

               if (it->IsTypedef()) {
                  fCurrentScope = it->FinalType();
               } else {
                  fCurrentScope = type;
               }
               return LookupInScope<T>();
            }
         }
      }

      Scope_Iterator subscope_end(fCurrentScope.SubScope_End());

      for (Scope_Iterator in = fCurrentScope.SubScope_Begin(); in != subscope_end; ++in) {
         // only take namespaces into account - classes were checked as part of SubType
         if (in->IsNamespace()) {
            const Scope& scope = *in;
            const ScopeBase* base = scope.ToScopeBase();

            if (base) {
               size_t pos;
               const std::string& name(base->SimpleName(pos));

               if (
                  (fLookupName[fPosNamePart] == name[pos]) &&
                  !fLookupName.compare(fPosNamePart, fPosNamePartLen, name, pos, name.length())
               ) {
                  fPartialSuccess = true;
                  fLookedAtUsingDir.clear();
                  FindNextScopePos();

                  if (fPosNamePart == std::string::npos) {
                     return (T) (*in);
                  }
                  fCurrentScope = (Scope) (*in);
                  return LookupInScope<T>();
               }
            }
         }
      }
   } // end of: if not global scope

   if (fCurrentScope.UsingDirectiveSize()) {
      fLookedAtUsingDir.insert(fCurrentScope);
      Scope storeCurrentScope = fCurrentScope;
      Scope_Iterator usingscope_end(storeCurrentScope.UsingDirective_End());

      for (Scope_Iterator si = storeCurrentScope.UsingDirective_Begin(); si != usingscope_end; ++si) {
         fCurrentScope = *si;
         T t = LookupInScope<T>();

         if (fPartialSuccess) {
            return t;
         }
      }
      fCurrentScope = storeCurrentScope;
   }

   if (!fPosNamePart) { // only for "BaseClass...", not for "A::BaseClass..."
      Base_Iterator base_end(fCurrentScope.Base_End());

      for (Base_Iterator bi = fCurrentScope.Base_Begin(); bi != base_end; ++bi) {
         if (!fLookupName.compare(fPosNamePart, fPosNamePartLen, bi->Name())) {
            fPartialSuccess = true;
            fLookedAtUsingDir.clear();
            FindNextScopePos();

            if (fPosNamePart == std::string::npos) {
               return bi->ToType();
            }
            fCurrentScope = bi->ToType().FinalType();
            return LookupInScope<T>();
         }
      }
   }

   if (fCurrentScope.BaseSize()) {
      Scope storeCurrentScope = fCurrentScope;
      Base_Iterator base_end(storeCurrentScope.Base_End());

      for (Base_Iterator bi = storeCurrentScope.Base_Begin(); bi != base_end; ++bi) {
         fCurrentScope = bi->ToScope();
         T t = LookupInScope<T>();

         if (fPartialSuccess) {
            return t;
         }
      }
      fCurrentScope = storeCurrentScope;
   }

   return Dummy::Get<T>();
} // LookupInScope

//______________________________________________________________________________
template <class T> T
Reflex::NameLookup::LookupInUnknownScope() {
   // Lookup a type in fCurrentScope and its declaring scopes.
   for (fPartialSuccess = false; !fPartialSuccess && fCurrentScope; fCurrentScope = fCurrentScope.DeclaringScope()) {
      fLookedAtUsingDir.clear();
      T t = LookupInScope<T>();

      if (fPartialSuccess) {
         return t;
      }

      if (fCurrentScope.IsTopScope()) {
         break;
      }
   }
   return Dummy::Get<T>();
}

//______________________________________________________________________________
Reflex::Member
Reflex::NameLookup::LookupMember(const std::string& nam,
                                 const Scope& current) {
   // Lookup a member.
   if (Tools::GetBasePosition(nam)) {
      return LookupMemberQualified(nam);
   }
   return LookupMemberUnqualified(nam, current);
}

//______________________________________________________________________________
Reflex::Member
Reflex::NameLookup::LookupMemberQualified(const std::string& nam) {
   // Lookup of a qualified member.
   Scope bscope = Scope::ByName(Tools::GetScopeName(nam));

   if (bscope) {
      return LookupMemberUnqualified(Tools::GetBaseName(nam), bscope);
   }
   return Dummy::Member();
}

//______________________________________________________________________________
Reflex::Member
Reflex::NameLookup::LookupMemberUnqualified(const std::string& nam,
                                            const Scope& current) {
   // Lookup of an unqualified member.
   {
      Member m = current.MemberByName(nam);

      if (m) {
         return m;
      }
   }

   for (Scope_Iterator si = current.UsingDirective_Begin(); si != current.UsingDirective_End(); ++si) {
      Member m = LookupMember(nam, *si);

      if (m) {
         return m;
      }
   }

   for (Base_Iterator bi = current.Base_Begin(); bi != current.Base_End(); ++bi) {
      Member m = LookupMember(nam, bi->ToScope());

      if (m) {
         return m;
      }
   }

   if (!current.IsTopScope()) {
      return LookupMember(nam, current.DeclaringScope());
   }
   return Dummy::Member();
} // LookupMemberUnqualified

//______________________________________________________________________________
Reflex::Type
Reflex::NameLookup::AccessControl(const Type& typ,
                                  const Scope& /*current*/) {
   // Check access.
   // if (typ.IsPublic()) {
   //    return true;
   // }
   // else if (typ.IsProtected() && current.HasBase(typ.DeclaringScope())) {
   //    return true;
   // }
   return typ;
}

//______________________________________________________________________________
void
Reflex::NameLookup::FindNextScopePos() {
   // Move fPosNamePart to point to the next scope in fLookupName, updating
   // fPosNamePartLen. If fPosNamePartLen == std::string::npos, initialize
   // fPosNamePart and fPosNamePartLen. If there is no next scope left, fPosNamePart
   // will be set to std::string::npos and fPosNamePartLen will be set to 0.
   if (fPosNamePartLen != std::string::npos) {
      // we know the length, so jump
      fPosNamePart += fPosNamePartLen + 2;

      if (fPosNamePart > fLookupName.length()) {
         // past the string's end?
         fPosNamePart = std::string::npos;
         fPosNamePartLen = 0;
         return;
      }
   } else {
      // uninitialized
      // set fPosNamePartLen and check that fLookupName doesn't start with '::'
      fPosNamePart = 0;

      if (!fLookupName.compare(0, 2, "::")) {
         fPosNamePart = 2;
      }
   }
   size_t start = 0; // yes, we should use it... Think of "int MyClass::*" where the scope is "MyClass", not "int MyClass"
   fPosNamePartLen = Tools::GetFirstScopePosition(fLookupName.substr(fPosNamePart), start);

   if (!fPosNamePartLen) { // no next "::"
      fPosNamePartLen = fLookupName.length();
   } else { // no "::"
      fPosNamePartLen -= 2;
   }
} // FindNextScopePos
<commit_msg>fix illegal initialisation of a const string& from a const char*<commit_after>// @(#)root/reflex:$Id$
// Author: Stefan Roiser 2006

// Copyright CERN, CH-1211 Geneva 23, 2004-2010, All rights reserved.
//
// Permission to use, copy, modify, and distribute this software for any
// purpose is hereby granted without fee, provided that this copyright and
// permissions notice appear in all copies and derivatives.
//
// This software is provided "as is" without express or implied warranty.

#ifndef REFLEX_BUILD
# define REFLEX_BUILD
#endif

#include "NameLookup.h"
#include "Reflex/Base.h"
#include "Reflex/Scope.h"
#include "Reflex/Type.h"
#include "Reflex/Tools.h"
#include "Reflex/internal/OwnedMember.h"

#include <sstream>
#include <cstring>

//______________________________________________________________________________
Reflex::NameLookup::NameLookup(const std::string& name, const Scope& current):
   fLookupName(name),
   fPosNamePart(0),
   fPosNamePartLen(std::string::npos),
   fCurrentScope(current),
   fPartialSuccess(false) {
   // Initialize a NameLookup object used internally to keep track of lookup
   // states.
}

//______________________________________________________________________________
Reflex::Type
Reflex::NameLookup::LookupType(const std::string& nam,
                               const Scope& current) {
   // Lookup up a (possibly scoped) type name appearing in the scope context
   // current. This is the public interface for type lookup.
   NameLookup lookup(nam, current);
   return lookup.Lookup<Type>();
}

//______________________________________________________________________________
Reflex::Scope
Reflex::NameLookup::LookupScope(const std::string& nam,
                                const Scope& current) {
   // Lookup up a (possibly scoped) scope name appearing in the scope context
   // current. This is the public interface for scope lookup.
   NameLookup lookup(nam, current);
   return lookup.Lookup<Scope>();
}

/*
   //______________________________________________________________________________
   Reflex::Member LookupMember(const std::string& nam, const Scope& current )
   {
   // Lookup up a (possibly scoped) member name appearing in the scope context
   // current. This is the public interface for member lookup.
   NameLookup lookup(nam, current);
   // this will not work, member lookup is too different from type lookup...
   return lookup.Lookup<Member>();
   }
 */

//______________________________________________________________________________
template <class T> T
Reflex::NameLookup::Lookup(bool isTemplateExpanded /* = false */) {
   // Lookup a type using fLookupName, fCurrentScope.

   Scope startScope = fCurrentScope;
   T result;

   fPartialSuccess = false;
   fPosNamePart = 0;
   fPosNamePartLen = std::string::npos;
   FindNextScopePos();

   if (fPosNamePart == 2) {
      fLookedAtUsingDir.clear();
      // ::A...
      fCurrentScope = Scope::GlobalScope();
      result = LookupInScope<T>();
   } else {
      // A...
      result = LookupInUnknownScope<T>();
   }

   if (!isTemplateExpanded && !result && fLookupName.find('<') != std::string::npos) {
      // We need to replace the template argument both of this type
      // and any of it enclosing type:
      //    myspace::mytop<A,B>::mytype<C>

      std::ostringstream tmp;

      for (size_t i = 0, level = 0, sofar = 0; i < fLookupName.size(); ++i) {
         if (level == 0) {
            tmp << fLookupName.substr(sofar, i + 1 - sofar);
            sofar = i + 1;
         }

         switch (fLookupName[i]) {
         case '<': ++level; break;
         case '>': --level;    // intentional fall through to the ',' case
         case ',':

            if (level == (1 - (unsigned int) (fLookupName[i] == '>'))) {
               std::string arg(fLookupName.substr(sofar, i - sofar));

               size_t p = arg.size();

               while (p > 0 && (arg[p - 1] == '*' || arg[p - 1] == '&' || arg[p - 1] == ' '))
                  --p;

               std::string end(arg.substr(p));
               arg.erase(p);

               const char* start = arg.c_str();

               while (strncmp(start, "const ", 6) == 0)
                  start += 6;

               tmp << arg.substr(0, start - arg.c_str());

               while (strncmp(start, "std::", 5) == 0)
                  start += 5;

               arg.erase(0, start - arg.c_str());

               Reflex::Type type(LookupType(arg, startScope));

               if (type) {
                  if (type.Name() != "Double32_t" && type.Name() != "Float16_t") {
                     // Use the real type rather than the typedef unless
                     // this is Double32_t or Float16_t
                     type = type.FinalType();
                  }
                  tmp << type.Name(Reflex::SCOPED | Reflex::QUALIFIED);
               } else {
                  tmp << arg;
               }
               tmp << end;

               tmp << fLookupName[i];

               sofar = i + 1;
            }
            break;
         } // switch
      }
      NameLookup next(tmp.str(), startScope);
      return next.Lookup<T>(true);
   }

   return result;
} // Lookup

//______________________________________________________________________________
template <class T> T
Reflex::NameLookup::LookupInScope() {
   // Lookup a type in fCurrentScope.
   // Checks sub-types, sub-scopes, using directives, and base classes for
   // the name given by fLookupName, fPosNamePart, and fPosNamePartLen.
   // If the name part is found, and another name part follows in fPosNamePart,
   // LookupTypeInScope requests the scope found to lookup the next name
   // part. fPartialMatch reflexts that the left part of the name was matched;
   // even if the trailing part of fLookupName cannot be found, the lookup
   // cannot continue on declaring scopes and has to fail.
   // A list of lookups performed in namespaces pulled in via using directives is
   // kept in fLookedAtUsingDir, to prevent infinite loops due to
   //   namespace A{using namespace B;} namespace B{using namespace A;}
   // loops.
   // The lookup does not take the declaration order into account; the result of
   // parts of the lookup algorithm which depend on the order will be unpredictable.

   if (!fCurrentScope) {
      return Dummy::Get<T>();
   }

   // prevent inf loop from
   // ns A { using ns B; } ns B {using ns A;}
   if (fLookedAtUsingDir.find(fCurrentScope) != fLookedAtUsingDir.end()) {
      return Dummy::Get<T>();
   }

   // global scope can use hashed containers:
   if (fCurrentScope == Scope::GlobalScope()) {
      Type freeType(Type::ByName(fLookupName.c_str() + fPosNamePart));

      if (freeType.Id()) {
         //fprintf(stderr, "Reflex::NameLookup::LookupInScope<T>: lookup up '%s', partial success with subscope '%s' ...\n", fLookupName.c_str(), name.c_str());
         fPartialSuccess = true;
         fLookedAtUsingDir.clear();
         FindNextScopePos();

         if (fPosNamePart == std::string::npos) {
            return freeType;
         }

         if (freeType.IsTypedef()) {
            fCurrentScope = freeType.FinalType();
         } else {
            fCurrentScope = freeType;
         }
         return LookupInScope<T>();
      }

      Scope freeScope(Scope::ByName(fLookupName.c_str() + fPosNamePart));

      // only take namespaces into account - classes were checked as part of SubType
      if (freeScope.Id() && freeScope.IsNamespace()) {
         fPartialSuccess = true;
         fLookedAtUsingDir.clear();
         FindNextScopePos();

         if (fPosNamePart == std::string::npos) {
            return (T) (freeScope);
         }
         fCurrentScope = freeScope;
         return LookupInScope<T>();
      }
   } // end of: if global scope
   else {
      // if not global scope

      size_t len = fCurrentScope.SubTypeSize();
      size_t i = 0;

      for (Type_Iterator it = fCurrentScope.SubType_Begin(); i < len; ++it, ++i) {
         const Type& type = *it;
         const TypeBase* base = type.ToTypeBase();

         if (base) {
            size_t pos;
            const std::string name(base->SimpleName(pos));

            //fprintf(stderr, "Reflex::NameLookup::LookupInScope<T>: looking up '%s', considering subscope '%s' ...\n", fLookupName.c_str(), name.c_str());
            if (
               (fLookupName[fPosNamePart] == name[pos]) &&
               !fLookupName.compare(fPosNamePart, fPosNamePartLen, name, pos, name.length())
            ) {
               //fprintf(stderr, "Reflex::NameLookup::LookupInScope<T>: lookup up '%s', partial success with subscope '%s' ...\n", fLookupName.c_str(), name.c_str());
               fPartialSuccess = true;
               fLookedAtUsingDir.clear();
               FindNextScopePos();

               if (fPosNamePart == std::string::npos) {
                  return type;
               }

               if (it->IsTypedef()) {
                  fCurrentScope = it->FinalType();
               } else {
                  fCurrentScope = type;
               }
               return LookupInScope<T>();
            }
         }
      }

      Scope_Iterator subscope_end(fCurrentScope.SubScope_End());

      for (Scope_Iterator in = fCurrentScope.SubScope_Begin(); in != subscope_end; ++in) {
         // only take namespaces into account - classes were checked as part of SubType
         if (in->IsNamespace()) {
            const Scope& scope = *in;
            const ScopeBase* base = scope.ToScopeBase();

            if (base) {
               size_t pos;
               const std::string name(base->SimpleName(pos));

               if (
                  (fLookupName[fPosNamePart] == name[pos]) &&
                  !fLookupName.compare(fPosNamePart, fPosNamePartLen, name, pos, name.length())
               ) {
                  fPartialSuccess = true;
                  fLookedAtUsingDir.clear();
                  FindNextScopePos();

                  if (fPosNamePart == std::string::npos) {
                     return (T) (*in);
                  }
                  fCurrentScope = (Scope) (*in);
                  return LookupInScope<T>();
               }
            }
         }
      }
   } // end of: if not global scope

   if (fCurrentScope.UsingDirectiveSize()) {
      fLookedAtUsingDir.insert(fCurrentScope);
      Scope storeCurrentScope = fCurrentScope;
      Scope_Iterator usingscope_end(storeCurrentScope.UsingDirective_End());

      for (Scope_Iterator si = storeCurrentScope.UsingDirective_Begin(); si != usingscope_end; ++si) {
         fCurrentScope = *si;
         T t = LookupInScope<T>();

         if (fPartialSuccess) {
            return t;
         }
      }
      fCurrentScope = storeCurrentScope;
   }

   if (!fPosNamePart) { // only for "BaseClass...", not for "A::BaseClass..."
      Base_Iterator base_end(fCurrentScope.Base_End());

      for (Base_Iterator bi = fCurrentScope.Base_Begin(); bi != base_end; ++bi) {
         if (!fLookupName.compare(fPosNamePart, fPosNamePartLen, bi->Name())) {
            fPartialSuccess = true;
            fLookedAtUsingDir.clear();
            FindNextScopePos();

            if (fPosNamePart == std::string::npos) {
               return bi->ToType();
            }
            fCurrentScope = bi->ToType().FinalType();
            return LookupInScope<T>();
         }
      }
   }

   if (fCurrentScope.BaseSize()) {
      Scope storeCurrentScope = fCurrentScope;
      Base_Iterator base_end(storeCurrentScope.Base_End());

      for (Base_Iterator bi = storeCurrentScope.Base_Begin(); bi != base_end; ++bi) {
         fCurrentScope = bi->ToScope();
         T t = LookupInScope<T>();

         if (fPartialSuccess) {
            return t;
         }
      }
      fCurrentScope = storeCurrentScope;
   }

   return Dummy::Get<T>();
} // LookupInScope

//______________________________________________________________________________
template <class T> T
Reflex::NameLookup::LookupInUnknownScope() {
   // Lookup a type in fCurrentScope and its declaring scopes.
   for (fPartialSuccess = false; !fPartialSuccess && fCurrentScope; fCurrentScope = fCurrentScope.DeclaringScope()) {
      fLookedAtUsingDir.clear();
      T t = LookupInScope<T>();

      if (fPartialSuccess) {
         return t;
      }

      if (fCurrentScope.IsTopScope()) {
         break;
      }
   }
   return Dummy::Get<T>();
}

//______________________________________________________________________________
Reflex::Member
Reflex::NameLookup::LookupMember(const std::string& nam,
                                 const Scope& current) {
   // Lookup a member.
   if (Tools::GetBasePosition(nam)) {
      return LookupMemberQualified(nam);
   }
   return LookupMemberUnqualified(nam, current);
}

//______________________________________________________________________________
Reflex::Member
Reflex::NameLookup::LookupMemberQualified(const std::string& nam) {
   // Lookup of a qualified member.
   Scope bscope = Scope::ByName(Tools::GetScopeName(nam));

   if (bscope) {
      return LookupMemberUnqualified(Tools::GetBaseName(nam), bscope);
   }
   return Dummy::Member();
}

//______________________________________________________________________________
Reflex::Member
Reflex::NameLookup::LookupMemberUnqualified(const std::string& nam,
                                            const Scope& current) {
   // Lookup of an unqualified member.
   {
      Member m = current.MemberByName(nam);

      if (m) {
         return m;
      }
   }

   for (Scope_Iterator si = current.UsingDirective_Begin(); si != current.UsingDirective_End(); ++si) {
      Member m = LookupMember(nam, *si);

      if (m) {
         return m;
      }
   }

   for (Base_Iterator bi = current.Base_Begin(); bi != current.Base_End(); ++bi) {
      Member m = LookupMember(nam, bi->ToScope());

      if (m) {
         return m;
      }
   }

   if (!current.IsTopScope()) {
      return LookupMember(nam, current.DeclaringScope());
   }
   return Dummy::Member();
} // LookupMemberUnqualified

//______________________________________________________________________________
Reflex::Type
Reflex::NameLookup::AccessControl(const Type& typ,
                                  const Scope& /*current*/) {
   // Check access.
   // if (typ.IsPublic()) {
   //    return true;
   // }
   // else if (typ.IsProtected() && current.HasBase(typ.DeclaringScope())) {
   //    return true;
   // }
   return typ;
}

//______________________________________________________________________________
void
Reflex::NameLookup::FindNextScopePos() {
   // Move fPosNamePart to point to the next scope in fLookupName, updating
   // fPosNamePartLen. If fPosNamePartLen == std::string::npos, initialize
   // fPosNamePart and fPosNamePartLen. If there is no next scope left, fPosNamePart
   // will be set to std::string::npos and fPosNamePartLen will be set to 0.
   if (fPosNamePartLen != std::string::npos) {
      // we know the length, so jump
      fPosNamePart += fPosNamePartLen + 2;

      if (fPosNamePart > fLookupName.length()) {
         // past the string's end?
         fPosNamePart = std::string::npos;
         fPosNamePartLen = 0;
         return;
      }
   } else {
      // uninitialized
      // set fPosNamePartLen and check that fLookupName doesn't start with '::'
      fPosNamePart = 0;

      if (!fLookupName.compare(0, 2, "::")) {
         fPosNamePart = 2;
      }
   }
   size_t start = 0; // yes, we should use it... Think of "int MyClass::*" where the scope is "MyClass", not "int MyClass"
   fPosNamePartLen = Tools::GetFirstScopePosition(fLookupName.substr(fPosNamePart), start);

   if (!fPosNamePartLen) { // no next "::"
      fPosNamePartLen = fLookupName.length();
   } else { // no "::"
      fPosNamePartLen -= 2;
   }
} // FindNextScopePos
<|endoftext|>


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

#include "remoting/base/encoder_vp8.h"

#include "base/logging.h"
#include "media/base/callback.h"
#include "remoting/base/capture_data.h"
#include "remoting/proto/video.pb.h"

extern "C" {
#define VPX_CODEC_DISABLE_COMPAT 1
#include "third_party/libvpx/source/libvpx/vpx/vpx_codec.h"
#include "third_party/libvpx/source/libvpx/vpx/vpx_encoder.h"
#include "third_party/libvpx/source/libvpx/vpx/vp8cx.h"
}

namespace remoting {

EncoderVp8::EncoderVp8()
    : initialized_(false),
      codec_(NULL),
      image_(NULL),
      last_timestamp_(0) {
}

EncoderVp8::~EncoderVp8() {
  if (initialized_) {
    vpx_codec_err_t ret = vpx_codec_destroy(codec_.get());
    DCHECK(ret == VPX_CODEC_OK) << "Failed to destroy codec";
  }
}

bool EncoderVp8::Init(int width, int height) {
  codec_.reset(new vpx_codec_ctx_t());
  image_.reset(new vpx_image_t());
  memset(image_.get(), 0, sizeof(vpx_image_t));

  image_->fmt = VPX_IMG_FMT_YV12;

  // libvpx seems to require both to be assigned.
  image_->d_w = width;
  image_->w = width;
  image_->d_h = height;
  image_->h = height;

  vpx_codec_enc_cfg_t config;
  const vpx_codec_iface_t* algo = vpx_codec_vp8_cx();
  CHECK(algo);
  vpx_codec_err_t ret = vpx_codec_enc_config_default(algo, &config, 0);
  if (ret != VPX_CODEC_OK)
    return false;

  // TODO(hclam): Tune the parameters to better suit the application.
  config.rc_target_bitrate = width * height * config.rc_target_bitrate
      / config.g_w / config.g_h;
  config.g_w = width;
  config.g_h = height;
  config.g_pass = VPX_RC_ONE_PASS;
  config.g_profile = 1;
  config.g_threads = 2;
  config.rc_min_quantizer = 0;
  config.rc_max_quantizer = 15;
  config.g_timebase.num = 1;
  config.g_timebase.den = 30;

  if (vpx_codec_enc_init(codec_.get(), algo, &config, 0))
    return false;
  return true;
}

static int clip_byte(int x) {
  if (x > 255)
    return 255;
  else if (x < 0)
    return 0;
  else
    return x;
}

bool EncoderVp8::PrepareImage(scoped_refptr<CaptureData> capture_data) {
  const int plane_size = capture_data->width() * capture_data->height();

  if (!yuv_image_.get()) {

    // YUV image size is 1.5 times of a plane. Multiplication is performed first
    // to avoid rounding error.
    const int size = plane_size * 3 / 2;

    yuv_image_.reset(new uint8[size]);

    // Reset image value to 128 so we just need to fill in the y plane.
    memset(yuv_image_.get(), 128, size);

    // Fill in the information for |image_|.
    unsigned char* image = reinterpret_cast<unsigned char*>(yuv_image_.get());
    image_->planes[0] = image;
    image_->planes[1] = image + plane_size;

    // The V plane starts from 1.25 of the plane size.
    image_->planes[2] = image + plane_size + plane_size / 4;

    // In YV12 Y plane has full width, UV plane has half width because of
    // subsampling.
    image_->stride[0] = image_->w;
    image_->stride[1] = image_->w / 2;
    image_->stride[2] = image_->w / 2;
  }

  // And then do RGB->YUV conversion.
  // Currently we just produce the Y channel as the average of RGB. This will
  // giv ae gray scale image after conversion.
  // TODO(sergeyu): Move this code to a separate routine.
  // TODO(sergeyu): Optimize this code.
  DCHECK(capture_data->pixel_format() == media::VideoFrame::RGB32)
      << "Only RGB32 is supported";
  uint8* in = capture_data->data_planes().data[0];
  const int in_stride = capture_data->data_planes().strides[0];
  uint8* y_out = yuv_image_.get();
  uint8* u_out = yuv_image_.get() + plane_size;
  uint8* v_out = yuv_image_.get() + plane_size + plane_size / 4;
  const int out_stride = image_->stride[0];
  for (int i = 0; i < capture_data->height(); ++i) {
    for (int j = 0; j < capture_data->width(); ++j) {
      // Since the input pixel format is RGB32, there are 4 bytes per pixel.
      uint8* pixel = in + 4 * j;
      y_out[j] = clip_byte(((pixel[2] * 66 + pixel[1] * 129 +
                             pixel[0] * 25 + 128) >> 8) + 16);
      if (i % 2 == 0 && j % 2 == 0) {
        u_out[j / 2] = clip_byte(((pixel[2] * -38 + pixel[1] * -74 +
                                   pixel[0] * 112 + 128) >> 8) + 128);
        v_out[j / 2] = clip_byte(((pixel[2] * 112 + pixel[1] * -94 +
                                   pixel[1] * -18 + 128) >> 8) + 128);
      }
    }
    in += in_stride;
    y_out += out_stride;
    if (i % 2 == 0) {
      u_out += out_stride / 2;
      v_out += out_stride / 2;
    }
  }
  return true;
}

void EncoderVp8::Encode(scoped_refptr<CaptureData> capture_data,
                        bool key_frame,
                        DataAvailableCallback* data_available_callback) {
  if (!initialized_) {
    bool ret = Init(capture_data->width(), capture_data->height());
    // TODO(hclam): Handle error better.
    DCHECK(ret) << "Initialization of encoder failed";
    initialized_ = ret;
  }

  if (!PrepareImage(capture_data)) {
    NOTREACHED() << "Can't image data for encoding";
  }

  // Do the actual encoding.
  vpx_codec_err_t ret = vpx_codec_encode(codec_.get(), image_.get(),
                                         last_timestamp_,
                                         1, 0, VPX_DL_REALTIME);
  DCHECK_EQ(ret, VPX_CODEC_OK)
      << "Encoding error: " << vpx_codec_err_to_string(ret) << "\n"
      << "Details: " << vpx_codec_error(codec_.get()) << "\n"
      << vpx_codec_error_detail(codec_.get());

  // TODO(hclam): fix this.
  last_timestamp_ += 100;

  // Read the encoded data.
  vpx_codec_iter_t iter = NULL;
  bool got_data = false;

  // TODO(hclam): Make sure we get exactly one frame from the packet.
  // TODO(hclam): We should provide the output buffer to avoid one copy.
  VideoPacket* message = new VideoPacket();

  while (!got_data) {
    const vpx_codec_cx_pkt_t* packet = vpx_codec_get_cx_data(codec_.get(),
                                                             &iter);
    if (!packet)
      continue;

    switch (packet->kind) {
      case VPX_CODEC_CX_FRAME_PKT:
        got_data = true;
        // TODO(sergeyu): Split each frame into multiple partitions.
        message->set_data(packet->data.frame.buf, packet->data.frame.sz);
        break;
      default:
        break;
    }
  }

  message->mutable_format()->set_encoding(VideoPacketFormat::ENCODING_VP8);
  message->set_flags(VideoPacket::FIRST_PACKET | VideoPacket::LAST_PACKET |
                     VideoPacket::LAST_PARTITION);

  data_available_callback->Run(message);
  delete data_available_callback;
}

}  // namespace remoting
<commit_msg>Chromoting host to convert only changed regions<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "remoting/base/encoder_vp8.h"

#include "base/logging.h"
#include "media/base/callback.h"
#include "media/base/yuv_convert.h"
#include "remoting/base/capture_data.h"
#include "remoting/proto/video.pb.h"

extern "C" {
#define VPX_CODEC_DISABLE_COMPAT 1
#include "third_party/libvpx/source/libvpx/vpx/vpx_codec.h"
#include "third_party/libvpx/source/libvpx/vpx/vpx_encoder.h"
#include "third_party/libvpx/source/libvpx/vpx/vp8cx.h"
}

namespace remoting {

EncoderVp8::EncoderVp8()
    : initialized_(false),
      codec_(NULL),
      image_(NULL),
      last_timestamp_(0) {
}

EncoderVp8::~EncoderVp8() {
  if (initialized_) {
    vpx_codec_err_t ret = vpx_codec_destroy(codec_.get());
    DCHECK(ret == VPX_CODEC_OK) << "Failed to destroy codec";
  }
}

bool EncoderVp8::Init(int width, int height) {
  codec_.reset(new vpx_codec_ctx_t());
  image_.reset(new vpx_image_t());
  memset(image_.get(), 0, sizeof(vpx_image_t));

  image_->fmt = VPX_IMG_FMT_YV12;

  // libvpx seems to require both to be assigned.
  image_->d_w = width;
  image_->w = width;
  image_->d_h = height;
  image_->h = height;

  vpx_codec_enc_cfg_t config;
  const vpx_codec_iface_t* algo = vpx_codec_vp8_cx();
  CHECK(algo);
  vpx_codec_err_t ret = vpx_codec_enc_config_default(algo, &config, 0);
  if (ret != VPX_CODEC_OK)
    return false;

  // TODO(hclam): Tune the parameters to better suit the application.
  config.rc_target_bitrate = width * height * config.rc_target_bitrate
      / config.g_w / config.g_h;
  config.g_w = width;
  config.g_h = height;
  config.g_pass = VPX_RC_ONE_PASS;
  config.g_profile = 1;
  config.g_threads = 2;
  config.rc_min_quantizer = 0;
  config.rc_max_quantizer = 15;
  config.g_timebase.num = 1;
  config.g_timebase.den = 30;

  if (vpx_codec_enc_init(codec_.get(), algo, &config, 0))
    return false;
  return true;
}

static int RoundToTwosMultiple(int x) {
  return x & (~1);
}

// Align the sides of the rectange to multiples of 2.
static gfx::Rect AlignRect(const gfx::Rect& rect, int width, int height) {
  CHECK(rect.width() > 0 && rect.height() > 0);
  int x = RoundToTwosMultiple(rect.x());
  int y = RoundToTwosMultiple(rect.y());
  int right = std::min(RoundToTwosMultiple(rect.right() + 1),
                       RoundToTwosMultiple(width));
  int bottom = std::min(RoundToTwosMultiple(rect.bottom() + 1),
                        RoundToTwosMultiple(height));

  // Do the final check to make sure the width and height are not negative.
  gfx::Rect r(x, y, right - x, bottom - y);
  if (r.width() <= 0 || r.height() <= 0) {
    r.set_width(0);
    r.set_height(0);
  }
  return r;
}

bool EncoderVp8::PrepareImage(scoped_refptr<CaptureData> capture_data) {
  const int plane_size = capture_data->width() * capture_data->height();

  if (!yuv_image_.get()) {

    // YUV image size is 1.5 times of a plane. Multiplication is performed first
    // to avoid rounding error.
    const int size = plane_size * 3 / 2;

    yuv_image_.reset(new uint8[size]);

    // Reset image value to 128 so we just need to fill in the y plane.
    memset(yuv_image_.get(), 128, size);

    // Fill in the information for |image_|.
    unsigned char* image = reinterpret_cast<unsigned char*>(yuv_image_.get());
    image_->planes[0] = image;
    image_->planes[1] = image + plane_size;

    // The V plane starts from 1.25 of the plane size.
    image_->planes[2] = image + plane_size + plane_size / 4;

    // In YV12 Y plane has full width, UV plane has half width because of
    // subsampling.
    image_->stride[0] = image_->w;
    image_->stride[1] = image_->w / 2;
    image_->stride[2] = image_->w / 2;
  }

  // Perform RGB->YUV conversion.
  if (capture_data->pixel_format() != media::VideoFrame::RGB32) {
    LOG(ERROR) << "Only RGB32 is supported";
    return false;
  }

  const InvalidRects& rects = capture_data->dirty_rects();
  const uint8* in = capture_data->data_planes().data[0];
  const int in_stride = capture_data->data_planes().strides[0];
  uint8* y_out = yuv_image_.get();
  uint8* u_out = yuv_image_.get() + plane_size;
  uint8* v_out = yuv_image_.get() + plane_size + plane_size / 4;
  const int y_stride = image_->stride[0];
  const int uv_stride = image_->stride[1];

  for (InvalidRects::const_iterator r = rects.begin(); r != rects.end(); ++r) {
    gfx::Rect rect = AlignRect(*r, image_->w, image_->h);
    int in_offset = in_stride * rect.y() + 4 * rect.x();
    int y_offset = y_stride * rect.y() + rect.x();
    int uv_offset = (uv_stride * rect.y() + rect.x()) / 2;

    media::ConvertRGB32ToYUV(in + in_offset,
                             y_out + y_offset,
                             u_out + uv_offset,
                             v_out + uv_offset,
                             rect.width(),
                             rect.height(),
                             in_stride,
                             y_stride,
                             uv_stride);
  }
  return true;
}

void EncoderVp8::Encode(scoped_refptr<CaptureData> capture_data,
                        bool key_frame,
                        DataAvailableCallback* data_available_callback) {
  if (!initialized_) {
    bool ret = Init(capture_data->width(), capture_data->height());
    // TODO(hclam): Handle error better.
    DCHECK(ret) << "Initialization of encoder failed";
    initialized_ = ret;
  }

  if (!PrepareImage(capture_data)) {
    NOTREACHED() << "Can't image data for encoding";
  }

  // Do the actual encoding.
  vpx_codec_err_t ret = vpx_codec_encode(codec_.get(), image_.get(),
                                         last_timestamp_,
                                         1, 0, VPX_DL_REALTIME);
  DCHECK_EQ(ret, VPX_CODEC_OK)
      << "Encoding error: " << vpx_codec_err_to_string(ret) << "\n"
      << "Details: " << vpx_codec_error(codec_.get()) << "\n"
      << vpx_codec_error_detail(codec_.get());

  // TODO(hclam): fix this.
  last_timestamp_ += 100;

  // Read the encoded data.
  vpx_codec_iter_t iter = NULL;
  bool got_data = false;

  // TODO(hclam): Make sure we get exactly one frame from the packet.
  // TODO(hclam): We should provide the output buffer to avoid one copy.
  VideoPacket* message = new VideoPacket();

  while (!got_data) {
    const vpx_codec_cx_pkt_t* packet = vpx_codec_get_cx_data(codec_.get(),
                                                             &iter);
    if (!packet)
      continue;

    switch (packet->kind) {
      case VPX_CODEC_CX_FRAME_PKT:
        got_data = true;
        // TODO(sergeyu): Split each frame into multiple partitions.
        message->set_data(packet->data.frame.buf, packet->data.frame.sz);
        break;
      default:
        break;
    }
  }

  message->mutable_format()->set_encoding(VideoPacketFormat::ENCODING_VP8);
  message->set_flags(VideoPacket::FIRST_PACKET | VideoPacket::LAST_PACKET |
                     VideoPacket::LAST_PARTITION);

  data_available_callback->Run(message);
  delete data_available_callback;
}

}  // namespace remoting
<|endoftext|>