<commit_before>#pragma once

#include <string>
#include <json/json.h>

/// Wrapper for OpenAL buffers.
class ScriptFile {
    public:

        ///The directory path of the script.
        std::string path;

        ///The module the script executes in.
        std::string module = "";

        ///The module the script executes in.
        std::string name = "";

        ///Saves the scriptfile to Json value.
        Json::Value Save() const;

        ///Loads the script from a Json value.
        /**
         * @param node JSON node to load from.
         */
        void ScriptFile::Load(const Json::Value& node);

};
<commit_msg>removed unnecesary ::<commit_after>#pragma once

#include <string>
#include <json/json.h>

/// Wrapper for OpenAL buffers.
class ScriptFile {
    public:

        ///The directory path of the script.
        std::string path;

        ///The module the script executes in.
        std::string module = "";

        ///The module the script executes in.
        std::string name = "";

        ///Saves the scriptfile to Json value.
        Json::Value Save() const;

        ///Loads the script from a Json value.
        /**
         * @param node JSON node to load from.
         */
        void Load(const Json::Value& node);

};
<|endoftext|>


<commit_before>// Copyright (c) 2021 ASMlover. All rights reserved.
//
//  ______             __                  ___
// /\__  _\           /\ \                /\_ \
// \/_/\ \/    __     \_\ \  _____     ___\//\ \      __
//    \ \ \  /'__`\   /'_` \/\ '__`\  / __`\\ \ \   /'__`\
//     \ \ \/\ \L\.\_/\ \L\ \ \ \L\ \/\ \L\ \\_\ \_/\  __/
//      \ \_\ \__/.\_\ \___,_\ \ ,__/\ \____//\____\ \____\
//       \/_/\/__/\/_/\/__,_ /\ \ \/  \/___/ \/____/\/____/
//                             \ \_\
//                              \/_/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
//  * Redistributions of source code must retain the above copyright
//    notice, this list ofconditions and the following disclaimer.
//
//  * Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in
//    the documentation and/or other materialsprovided with the
//    distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
#include <fstream>
#include <iostream>
#include <Common/Common.hh>
#include <Common/Harness.hh>

int main(int argc, char* argv[]) {
  TADPOLE_UNUSED(argc), TADPOLE_UNUSED(argv);

#if defined(_TADPOLE_RUN_HARNESS)
  Tadpole::Common::Harness::run_all_harness();
#endif

  return 0;
}
<commit_msg>:construction: chore(main-entry): add main entry of Tadpole<commit_after>// Copyright (c) 2021 ASMlover. All rights reserved.
//
//  ______             __                  ___
// /\__  _\           /\ \                /\_ \
// \/_/\ \/    __     \_\ \  _____     ___\//\ \      __
//    \ \ \  /'__`\   /'_` \/\ '__`\  / __`\\ \ \   /'__`\
//     \ \ \/\ \L\.\_/\ \L\ \ \ \L\ \/\ \L\ \\_\ \_/\  __/
//      \ \_\ \__/.\_\ \___,_\ \ ,__/\ \____//\____\ \____\
//       \/_/\/__/\/_/\/__,_ /\ \ \/  \/___/ \/____/\/____/
//                             \ \_\
//                              \/_/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
//  * Redistributions of source code must retain the above copyright
//    notice, this list ofconditions and the following disclaimer.
//
//  * Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in
//    the documentation and/or other materialsprovided with the
//    distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
#include <fstream>
#include <iostream>
#include <Common/Common.hh>
#include <Common/Colorful.hh>
#include <Common/Harness.hh>
#include <Core/TadpoleVM.hh>
#include <GC/GC.hh>

namespace Tp = Tadpole;

static int eval(Tp::Core::TadpoleVM& vm, const Tp::str_t& source_bytes) {
  Tp::Core::InterpretRet r = vm.interpret(source_bytes);
  if (r == Tp::Core::InterpretRet::ERUNTIME)
    return -1;
  else if (r == Tp::Core::InterpretRet::ECOMPILE)
    return -2;
  return 0;
}

int main(int argc, char* argv[]) {
  TADPOLE_UNUSED(argc), TADPOLE_UNUSED(argv);

#if defined(_TADPOLE_RUN_HARNESS)
  Tp::Common::Harness::run_all_harness();
#endif

  Tp::Core::TadpoleVM vm;
  if (argc < 2) {
    std::cout
      << Tp::Common::Colorful::fg::lightgreen
      << "W E L C O M E   T O   T A D P O L E !!!"
      << Tp::Common::Colorful::reset
      << std::endl;

    Tp::str_t line;
    for (;;) {
      if (!vm.is_running())
        break;

      std::cout << ">>> ";
      if (!std::getline(std::cin, line))
        break;

      eval(vm, line);
      Tp::GC::GC::get_instance().collect();
    }
  }
  else {
    std::fstream fp(argv[1]);
    if (fp.is_open()) {
      std::stringstream ss;
      ss << fp.rdbuf();

      if (int ec = eval(vm, ss.str()); ec != 0)
        std::exit(ec);
    }
    else {
      std::cerr
        << Tp::Common::Colorful::fg::red
        << "ERROR LOAD `" << argv[1] << "` FAILED !!!"
        << Tp::Common::Colorful::reset
        << std::endl;
      std::exit(-1);
    }
  }

  return 0;
}
<|endoftext|>


<commit_before>/** \file   EmailSender.cc
 *  \brief  Utility functions etc. related to the sending of email messages.
 *  \author Dr. Johannes Ruscheinski (johannes.ruscheinski@uni-tuebingen.de)
 *
 *  \copyright 2015 Universitätsbiblothek Tübingen.  All rights reserved.
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Affero General Public License as
 *  published by the Free Software Foundation, either version 3 of the
 *  License, or (at your option) any later version.
 *
 *  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 Affero General Public License for more details.
 *
 *  You should have received a copy of the GNU Affero General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#include "EmailSender.h"
#include <stdexcept>
#include <vector>
#include <cstdlib>
#include "Compiler.h"
#include "ExecUtil.h"
#include "FileUtil.h"
#include "util.h"

namespace {

/** \brief Temorarily replace an environment variable's value. */
class ReplaceEnvVar {
    std::string variable_name_;
    std::string old_value_;
public:
    /** \brief Replace the value w/ "temp_value". */
    ReplaceEnvVar(const std::string &variable_name, const std::string &temp_value) ;

    /** \brief Restore the old value. */
    ~ReplaceEnvVar();
};

ReplaceEnvVar::ReplaceEnvVar(const std::string &variable_name, const std::string &temp_value) {
    const char * const old_value(::getenv(variable_name.c_str()));
    if (old_value != nullptr) {
        variable_name_ = variable_name;
        old_value_     = old_value;
    }

    if (unlikely(::setenv(variable_name.c_str(), temp_value.c_str(), /* overwrite = */ true) != 0))
        Error("setenv(3) failed in ReplaceEnvVar::ReplaceEnvVar! (errno: " + std::to_string(errno) + ")");
}

ReplaceEnvVar:: ~ReplaceEnvVar() {
    if (not variable_name_.empty()) {
        if (unlikely(::setenv(variable_name_.c_str(), old_value_.c_str(), /* overwrite = */ true) != 0))
            Error("setenv(3) failed in ReplaceEnvVar::~ReplaceEnvVar! (errno: " + std::to_string(errno) + ")");
    }
}

} // unnamed namespace

namespace EmailSender {

bool SendEmail(const std::string &sender, const std::string &recipient, const std::string &subject,
               const std::string &message_body, const Priority priority, const Format format)
{
    static std::string mutt_path;
    if (mutt_path.empty()) {
        ReplaceEnvVar replace_env_var("PATH", "/bin:/usr/bin");
        mutt_path = ExecUtil::Which("mutt");
        if (unlikely(mutt_path.empty()))
            Error("in EmailSender::SendEmail: can't find \"mutt\"!");
    }

    FileUtil::AutoTempFile auto_temp_file;
    const std::string &stdin_replacement_for_mutt(auto_temp_file.getFilePath());

    std::string message;
    message += "From: " + sender + "\n";
    message += "To: " + recipient + "\n";
    message += "Subject: " + subject + "\n";
    if (priority != DO_NOT_SET_PRIORITY)
        message += "X-Priority: " + std::to_string(priority) + "\n";
    message += '\n';
    message += message_body;

    if (not FileUtil::WriteString(stdin_replacement_for_mutt, message))
        Error("in EmailSender::SendEmail: can't write the message body into a temporary file!");

    if (format == PLAIN_TEXT)
        return ExecUtil::Exec(mutt_path, { "-H", "-" }, stdin_replacement_for_mutt) == 0;
    else // Send icky HTML email.
        return ExecUtil::Exec(mutt_path, { "-H", "-", "-e set content_type=text/html" },
                              stdin_replacement_for_mutt) == 0;
}

} // namespace EmailSender
<commit_msg>Prevent mutt from sending a message copy<commit_after>/** \file   EmailSender.cc
 *  \brief  Utility functions etc. related to the sending of email messages.
 *  \author Dr. Johannes Ruscheinski (johannes.ruscheinski@uni-tuebingen.de)
 *
 *  \copyright 2015 Universitätsbiblothek Tübingen.  All rights reserved.
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Affero General Public License as
 *  published by the Free Software Foundation, either version 3 of the
 *  License, or (at your option) any later version.
 *
 *  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 Affero General Public License for more details.
 *
 *  You should have received a copy of the GNU Affero General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#include "EmailSender.h"
#include <stdexcept>
#include <vector>
#include <cstdlib>
#include "Compiler.h"
#include "ExecUtil.h"
#include "FileUtil.h"
#include "util.h"

namespace {

/** \brief Temorarily replace an environment variable's value. */
class ReplaceEnvVar {
    std::string variable_name_;
    std::string old_value_;
public:
    /** \brief Replace the value w/ "temp_value". */
    ReplaceEnvVar(const std::string &variable_name, const std::string &temp_value) ;

    /** \brief Restore the old value. */
    ~ReplaceEnvVar();
};

ReplaceEnvVar::ReplaceEnvVar(const std::string &variable_name, const std::string &temp_value) {
    const char * const old_value(::getenv(variable_name.c_str()));
    if (old_value != nullptr) {
        variable_name_ = variable_name;
        old_value_     = old_value;
    }

    if (unlikely(::setenv(variable_name.c_str(), temp_value.c_str(), /* overwrite = */ true) != 0))
        Error("setenv(3) failed in ReplaceEnvVar::ReplaceEnvVar! (errno: " + std::to_string(errno) + ")");
}

ReplaceEnvVar:: ~ReplaceEnvVar() {
    if (not variable_name_.empty()) {
        if (unlikely(::setenv(variable_name_.c_str(), old_value_.c_str(), /* overwrite = */ true) != 0))
            Error("setenv(3) failed in ReplaceEnvVar::~ReplaceEnvVar! (errno: " + std::to_string(errno) + ")");
    }
}

} // unnamed namespace

namespace EmailSender {

bool SendEmail(const std::string &sender, const std::string &recipient, const std::string &subject,
               const std::string &message_body, const Priority priority, const Format format)
{
    static std::string mutt_path;
    if (mutt_path.empty()) {
        ReplaceEnvVar replace_env_var("PATH", "/bin:/usr/bin");
        mutt_path = ExecUtil::Which("mutt");
        if (unlikely(mutt_path.empty()))
            Error("in EmailSender::SendEmail: can't find \"mutt\"!");
    }

    FileUtil::AutoTempFile auto_temp_file;
    const std::string &stdin_replacement_for_mutt(auto_temp_file.getFilePath());

    std::string message;
    message += "From: " + sender + "\n";
    message += "To: " + recipient + "\n";
    message += "Subject: " + subject + "\n";
    if (priority != DO_NOT_SET_PRIORITY)
        message += "X-Priority: " + std::to_string(priority) + "\n";
    message += '\n';
    message += message_body;

    if (not FileUtil::WriteString(stdin_replacement_for_mutt, message))
        Error("in EmailSender::SendEmail: can't write the message body into a temporary file!");

    if (format == PLAIN_TEXT)
        return ExecUtil::Exec(mutt_path, { "-e set copy=no", "-H", "-" }, stdin_replacement_for_mutt) == 0;
    else // Send icky HTML email.
        return ExecUtil::Exec(mutt_path, { "-e set copy=no", "-H", "-", "-e set content_type=text/html" },
                              stdin_replacement_for_mutt) == 0;
}

} // namespace EmailSender
<|endoftext|>


<commit_before><commit_msg>canvas unit test - tolerate canvas non-creation: really no X server...<commit_after><|endoftext|>


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

/*
 * Copyright (C) 2015 ScyllaDB
 *
 * Modified by ScyllaDB
 */

/*
 * This file is part of Scylla.
 *
 * Scylla is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Scylla 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 Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#pragma once

#include <vector>
#include "cql3/assignment_testable.hh"
#include "types.hh"
#include "schema.hh"

namespace cql3 {

namespace selection {

class result_set_builder;

/**
 * A selector is used to convert the data returned by the storage engine into the data requested by the
 * user. They correspond to the <selector> elements from the select clause.
 *
Since the introduction of aggregation, selectors cannot be called anymore by multiple threads
 * as they have an internal state.

 */
class selector : public assignment_testable {
public:
    class factory;

    virtual ~selector() {}

    /**
     * Add the current value from the specified result_set_builder.
     *
     * @param protocol_version protocol version used for serialization
     * @param rs the result_set_builder
     * @throws InvalidRequestException if a problem occurs while add the input value
     */
    virtual void add_input(cql_serialization_format sf, result_set_builder& rs) = 0;

    /**
     * Returns the selector output.
     *
     * @param protocol_version protocol version used for serialization
     * @return the selector output
     * @throws InvalidRequestException if a problem occurs while computing the output value
     */
    virtual bytes_opt get_output(cql_serialization_format sf) = 0;

    /**
     * Returns the selector output type.
     *
     * @return the selector output type.
     */
    virtual data_type get_type() = 0;

    /**
     * Checks if this selector is creating aggregates.
     *
     * @return true if this selector is creating aggregates false
     * otherwise.
     */
    virtual bool is_aggregate() {
        return false;
    }

    /**
     * Reset the internal state of this selector.
     */
    virtual void reset() = 0;

    virtual assignment_testable::test_result test_assignment(database& db, const sstring& keyspace, ::shared_ptr<column_specification> receiver) override {
        if (receiver->type == get_type()) {
            return assignment_testable::test_result::EXACT_MATCH;
        } else if (receiver->type->is_value_compatible_with(*get_type())) {
            return assignment_testable::test_result::WEAKLY_ASSIGNABLE;
        } else {
            return assignment_testable::test_result::NOT_ASSIGNABLE;
        }
    }
};

/**
 * A factory for selector instances.
 */
class selector::factory {
public:
    virtual ~factory() {}

    virtual bool uses_function(const sstring& ks_name, const sstring& function_name) {
        return false;
    }

    /**
     * Returns the column specification corresponding to the output value of the selector instances created by
     * this factory.
     *
     * @param schema the column family schema
     * @return a column specification
     */
    ::shared_ptr<column_specification> get_column_specification(schema_ptr schema);

    /**
     * Creates a new selector instance.
     *
     * @return a new selector instance
     */
    virtual ::shared_ptr<selector> new_instance() = 0;

    /**
     * Checks if this factory creates selectors instances that creates aggregates.
     *
     * @return true if this factory creates selectors instances that creates aggregates,
     * false otherwise
     */
    virtual bool is_aggregate_selector_factory() {
        return false;
    }

    /**
     * Checks if this factory creates writetime selectors instances.
     *
     * @return true if this factory creates writetime selectors instances,
     * false otherwise
     */
    virtual bool is_write_time_selector_factory() {
        return false;
    }

    /**
     * Checks if this factory creates TTL selectors instances.
     *
     * @return true if this factory creates TTL selectors instances,
     * false otherwise
     */
    virtual bool is_ttl_selector_factory() {
        return false;
    }

    /**
     * Returns the name of the column corresponding to the output value of the selector instances created by
     * this factory.
     *
     * @return a column name
     */
    virtual sstring column_name() = 0;

    /**
     * Returns the type of the values returned by the selector instances created by this factory.
     *
     * @return the selector output type
     */
    virtual data_type get_return_type() = 0;
};

}

}
<commit_msg>cql3/selection/selector: Unwrap types when validating assignment<commit_after>/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * Copyright (C) 2015 ScyllaDB
 *
 * Modified by ScyllaDB
 */

/*
 * This file is part of Scylla.
 *
 * Scylla is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Scylla 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 Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#pragma once

#include <vector>
#include "cql3/assignment_testable.hh"
#include "types.hh"
#include "schema.hh"

namespace cql3 {

namespace selection {

class result_set_builder;

/**
 * A selector is used to convert the data returned by the storage engine into the data requested by the
 * user. They correspond to the <selector> elements from the select clause.
 *
Since the introduction of aggregation, selectors cannot be called anymore by multiple threads
 * as they have an internal state.

 */
class selector : public assignment_testable {
public:
    class factory;

    virtual ~selector() {}

    /**
     * Add the current value from the specified result_set_builder.
     *
     * @param protocol_version protocol version used for serialization
     * @param rs the result_set_builder
     * @throws InvalidRequestException if a problem occurs while add the input value
     */
    virtual void add_input(cql_serialization_format sf, result_set_builder& rs) = 0;

    /**
     * Returns the selector output.
     *
     * @param protocol_version protocol version used for serialization
     * @return the selector output
     * @throws InvalidRequestException if a problem occurs while computing the output value
     */
    virtual bytes_opt get_output(cql_serialization_format sf) = 0;

    /**
     * Returns the selector output type.
     *
     * @return the selector output type.
     */
    virtual data_type get_type() = 0;

    /**
     * Checks if this selector is creating aggregates.
     *
     * @return true if this selector is creating aggregates false
     * otherwise.
     */
    virtual bool is_aggregate() {
        return false;
    }

    /**
     * Reset the internal state of this selector.
     */
    virtual void reset() = 0;

    virtual assignment_testable::test_result test_assignment(database& db, const sstring& keyspace, ::shared_ptr<column_specification> receiver) override {
        auto t1 = receiver->type->underlying_type();
        auto t2 = get_type()->underlying_type();
        if (t1 == t2) {
            return assignment_testable::test_result::EXACT_MATCH;
        } else if (t1->is_value_compatible_with(*t2)) {
            return assignment_testable::test_result::WEAKLY_ASSIGNABLE;
        } else {
            return assignment_testable::test_result::NOT_ASSIGNABLE;
        }
    }
};

/**
 * A factory for selector instances.
 */
class selector::factory {
public:
    virtual ~factory() {}

    virtual bool uses_function(const sstring& ks_name, const sstring& function_name) {
        return false;
    }

    /**
     * Returns the column specification corresponding to the output value of the selector instances created by
     * this factory.
     *
     * @param schema the column family schema
     * @return a column specification
     */
    ::shared_ptr<column_specification> get_column_specification(schema_ptr schema);

    /**
     * Creates a new selector instance.
     *
     * @return a new selector instance
     */
    virtual ::shared_ptr<selector> new_instance() = 0;

    /**
     * Checks if this factory creates selectors instances that creates aggregates.
     *
     * @return true if this factory creates selectors instances that creates aggregates,
     * false otherwise
     */
    virtual bool is_aggregate_selector_factory() {
        return false;
    }

    /**
     * Checks if this factory creates writetime selectors instances.
     *
     * @return true if this factory creates writetime selectors instances,
     * false otherwise
     */
    virtual bool is_write_time_selector_factory() {
        return false;
    }

    /**
     * Checks if this factory creates TTL selectors instances.
     *
     * @return true if this factory creates TTL selectors instances,
     * false otherwise
     */
    virtual bool is_ttl_selector_factory() {
        return false;
    }

    /**
     * Returns the name of the column corresponding to the output value of the selector instances created by
     * this factory.
     *
     * @return a column name
     */
    virtual sstring column_name() = 0;

    /**
     * Returns the type of the values returned by the selector instances created by this factory.
     *
     * @return the selector output type
     */
    virtual data_type get_return_type() = 0;
};

}

}
<|endoftext|>


<commit_before>#include "../../analysis/src/analysis.h" //for sgn()
#include "hill_climbing.h"

namespace mo {

template<typename F1, typename F2> double Hill_climbing::linear_search(F1 f, F2 df, const double& x0){
    double step = step0_;
    double x = x0;

    //search until |df(x)/dx| ~ 0
    while(fabs(df(x)) > thre_df_){
        int loop_count{0};
        //init x_next
        step = sgn(df(x)) * fabs(step);
        double x_next = x + step;

        if(f(x) < f(x_next)){ //in case f(x_next) does not yet reached the neighborhood of maximal
            while(f(x) < f(x_next)){ //loop until over maximal
                step *= 2.0;
                x = x_next;
                x_next = x + step;
                check_loopcount(++loop_count);
            }
            step /= 2.0;
        }else{ //in case f(x_next) over the neighborhood of maximal
            while(f(x) >= f(x_next)){ //loop until it finds
                step /= 2.0;
                x_next -= step;
                check_loopcount(++loop_count);
            }
            x = x_next;
            step *= 2.0;
        }

        if(opt_vis_){
            linsearch_vis_.record(x,f(x));
            linsearch_vis_.show();
        }
    }

    return x;
}

} //namespace mo
<commit_msg>update Hill_climbing<commit_after>#include "../../analysis/src/analysis.h" //for sgn()
#include "hill_climbing.h"

namespace mo {

template<typename F1, typename F2> double Hill_climbing::linear_search(F1 f, F2 df, const double& x0){
    double step = step0_;
    double x = x0;

    //search until |df(x)/dx| ~ 0
    double dfx = df(x);
    while(fabs(dfx) > thre_df_){
        int loop_count{0};
        //init x_next
        step = sgn(dfx) * fabs(step);
        double x_next = x + step;

        if(f(x) < f(x_next)){ //in case f(x_next) does not yet reached the neighborhood of maximal
            while(f(x) < f(x_next)){ //loop until over maximal
                step *= 2.0;
                x = x_next;
                x_next = x + step;
                check_loopcount(++loop_count);
            }
            step /= 2.0;
        }else{ //in case f(x_next) over the neighborhood of maximal
            while(f(x) >= f(x_next)){ //loop until it finds
                step /= 2.0;
                x_next -= step;
                check_loopcount(++loop_count);
            }
            x = x_next;
            step *= 2.0;
        }

        if(opt_vis_){
            linsearch_vis_.record(x,f(x));
            linsearch_vis_.show();
        }

        //update
        dfx = df(x);
    }

    return x;
}

} //namespace mo
<|endoftext|>


<commit_before>//
//                 INTEL CORPORATION PROPRIETARY INFORMATION
//
//    This software is supplied under the terms of a license agreement or
//    nondisclosure agreement with Intel Corporation and may not be copied
//    or disclosed except in accordance with the terms of that agreement.
//    Copyright (C) 2014 Intel Corporation. All Rights Reserved.
//
//    Authors: Gregory S. Johnson and Ingo Wald
//

#include <map>
#include "ospray/common/Data.h"
#include "ospray/common/Library.h"
#include "ospray/fileio/VolumeFile.h"
#include "ospray/volume/StructuredVolume.h"

namespace ospray {

    void StructuredVolume::commit() {

        //! Some parameters can be changed after the volume has been allocated and filled.
        if (ispcEquivalent != NULL) return(updateEditableParameters());

        //! Check for a file name.
        std::string filename = getParamString("filename", "");

        //! The volume may be initialized from the contents of a file or from memory.
        if (!filename.empty()) VolumeFile::importVolume(filename, this);  else getVolumeFromMemory();

    }

    OSPDataType StructuredVolume::getVoxelType() const {

        //! Separate out the base type and vector width.
        char kind[voxelType.size()];  unsigned int width = 1;  sscanf(voxelType.c_str(), "%[^0-9]%u", kind, &width);

        //! Single precision scalar floating point.
        if (!strcmp(kind, "float") && width == 1) return(OSP_FLOAT);

        //! Unsigned 8-bit scalar integer.
        if (!strcmp(kind, "uchar") && width == 1) return(OSP_UCHAR);

        //! Unknown type.
        return(OSP_UNKNOWN);

    }

    void StructuredVolume::getVolumeFromMemory() {

        //! Create the equivalent ISPC volume container and allocate memory for voxel data.
        createEquivalentISPC();

        //! Get a pointer to the source voxel data.
        const Data *voxelData = getParamData("voxelData", NULL);  exitOnCondition(voxelData == NULL, "no voxel data was specified");

        //! The dimensions of the source voxel data and target volume must match.
        exitOnCondition(volumeDimensions.x * volumeDimensions.y * volumeDimensions.z != voxelData->numItems, "unexpected dimensions of source voxel data");

        //! The source and target voxel types must match.
        exitOnCondition(getVoxelType() != voxelData->type, "unexpected source voxel type");

        //! Copy voxel data into the volume.
        setRegion(voxelData->data, vec3i(0, 0, 0), volumeDimensions);

    }

    size_t StructuredVolume::getVoxelSizeInBytes() const {

        //! Separate out the base type and vector width.
        char kind[voxelType.size()];  unsigned int width = 1;  sscanf(voxelType.c_str(), "%[^0-9]%u", kind, &width);

        //! Unsigned character scalar and vector types.
        if (!strcmp(kind, "uchar") && width >= 1 && width <= 4) return(sizeof(unsigned char) * width);

        //! Floating point scalar and vector types.
        if (!strcmp(kind, "float") && width >= 1 && width <= 4) return(sizeof(float) * width);

        //! Unsigned integer scalar and vector types.
        if (!strcmp(kind, "uint") && width >= 1 && width <= 4) return(sizeof(unsigned int) * width);

        //! Signed integer scalar and vector types.
        if (!strcmp(kind, "int") && width >= 1 && width <= 4) return(sizeof(int) * width);  return(0);

    }

} // namespace ospray

<commit_msg>Workaround for 32-bit ISPC offsets.<commit_after>//
//                 INTEL CORPORATION PROPRIETARY INFORMATION
//
//    This software is supplied under the terms of a license agreement or
//    nondisclosure agreement with Intel Corporation and may not be copied
//    or disclosed except in accordance with the terms of that agreement.
//    Copyright (C) 2014 Intel Corporation. All Rights Reserved.
//
//    Authors: Gregory S. Johnson and Ingo Wald
//

#include <map>
#include "ospray/common/Data.h"
#include "ospray/common/Library.h"
#include "ospray/fileio/VolumeFile.h"
#include "ospray/volume/StructuredVolume.h"

namespace ospray {

    void StructuredVolume::commit() {

        //! Some parameters can be changed after the volume has been allocated and filled.
        if (ispcEquivalent != NULL) return(updateEditableParameters());

        //! Check for a file name.
        std::string filename = getParamString("filename", "");

        //! The volume may be initialized from the contents of a file or from memory.
        if (!filename.empty()) VolumeFile::importVolume(filename, this);  else getVolumeFromMemory();

    }

    OSPDataType StructuredVolume::getVoxelType() const {

        //! Separate out the base type and vector width.
        char kind[voxelType.size()];  unsigned int width = 1;  sscanf(voxelType.c_str(), "%[^0-9]%u", kind, &width);

        //! Single precision scalar floating point.
        if (!strcmp(kind, "float") && width == 1) return(OSP_FLOAT);

        //! Unsigned 8-bit scalar integer.
        if (!strcmp(kind, "uchar") && width == 1) return(OSP_UCHAR);

        //! Unknown type.
        return(OSP_UNKNOWN);

    }

    void StructuredVolume::getVolumeFromMemory() {

        //! Create the equivalent ISPC volume container and allocate memory for voxel data.
        createEquivalentISPC();

        //! Get a pointer to the source voxel data.
        const Data *voxelData = getParamData("voxelData", NULL);  exitOnCondition(voxelData == NULL, "no voxel data specified");  const uint8 *data = (const uint8 *) voxelData->data;

        //! The dimensions of the source voxel data and target volume must match.
        exitOnCondition(volumeDimensions.x * volumeDimensions.y * volumeDimensions.z != voxelData->numItems, "unexpected source voxel data dimensions");

        //! The source and target voxel types must match.
        exitOnCondition(getVoxelType() != voxelData->type, "unexpected source voxel type");

        //! Size of a volume slice in bytes.
        size_t sliceSizeInBytes = volumeDimensions.x * volumeDimensions.y * getVoxelSizeInBytes();

        //! Copy voxel data into the volume in slices to avoid overflow in ISPC offset calculations.
        for (size_t z=0 ; z < volumeDimensions.z ; z++) setRegion(&data[z * sliceSizeInBytes], vec3i(0, 0, z), vec3i(volumeDimensions.x, volumeDimensions.y, 1));

    }

    size_t StructuredVolume::getVoxelSizeInBytes() const {

        //! Separate out the base type and vector width.
        char kind[voxelType.size()];  unsigned int width = 1;  sscanf(voxelType.c_str(), "%[^0-9]%u", kind, &width);

        //! Unsigned character scalar and vector types.
        if (!strcmp(kind, "uchar") && width >= 1 && width <= 4) return(sizeof(unsigned char) * width);

        //! Floating point scalar and vector types.
        if (!strcmp(kind, "float") && width >= 1 && width <= 4) return(sizeof(float) * width);

        //! Unsigned integer scalar and vector types.
        if (!strcmp(kind, "uint") && width >= 1 && width <= 4) return(sizeof(unsigned int) * width);

        //! Signed integer scalar and vector types.
        if (!strcmp(kind, "int") && width >= 1 && width <= 4) return(sizeof(int) * width);  return(0);

    }

} // namespace ospray

<|endoftext|>


<commit_before>// RUN: %clang_analyze_cc1 -analyzer-checker=core -verify %s
class C {};

// expected-no-diagnostics
void f(C i) {
  auto lambda = [&] { f(i); };
  typedef decltype(lambda) T;
  T* blah = new T(lambda);
  (*blah)();
  delete blah;
}
<commit_msg>[analyzer] Explicitly set an -std level for the analyzer test.<commit_after>// RUN: %clang_analyze_cc1 -analyzer-checker=core -std=c++11 -verify %s
class C {};

// expected-no-diagnostics
void f(C i) {
  auto lambda = [&] { f(i); };
  typedef decltype(lambda) T;
  T* blah = new T(lambda);
  (*blah)();
  delete blah;
}
<|endoftext|>


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

#include <deque>
#include <map>

template<class KeyType, class ValueType, class CompareType>
class XalanArrayKeyMap
{
public:

#if defined(XALAN_NO_NAMESPACES)
	typedef vector<KeyType>									VectorType;
	typedef map<const KeyType*, ValueType, CompareType>		MapType;
	typedef deque<VectorType>								VectorHolderType;
#else
	typedef std::vector<KeyType>								VectorType;
	typedef std::map<const KeyType*, ValueType, CompareType>	MapType;
	typedef std::deque<VectorType>								VectorHolderType;
#endif

	typedef typename MapType::key_type					key_type;
	typedef typename MapType::value_type				value_type;
	typedef ValueType									referent_type;
	typedef CompareType									key_compare;
#if !defined(XALAN_NO_STD_ALLOCATORS)
	typedef typename MapType::allocator_type			allocator_type;
#endif
	typedef typename MapType::size_type					size_type;
	typedef typename MapType::difference_type			difference_type;
	typedef typename MapType::reference					reference;
	typedef typename MapType::const_reference			const_reference;
	typedef typename MapType::iterator					iterator;
	typedef typename MapType::const_iterator			const_iterator;
	typedef typename MapType::reverse_iterator			reverse_iterator;
	typedef typename MapType::const_reverse_iterator	const_reverse_iterator;

#if defined(XALAN_NO_NAMESPACES)
	typedef pair<iterator, bool>					insert_pair_type;
	typedef pair<iterator, iterator>				range_pair_type;
	typedef pair<const_iterator, const_iterator>	const_range_pair_type;
#else
	typedef std::pair<iterator, bool>					insert_pair_type;
	typedef std::pair<iterator, iterator>				range_pair_type;
	typedef std::pair<const_iterator, const_iterator>	const_range_pair_type;
#endif

	explicit
	XalanArrayKeyMap() :
		m_map(),
		m_keyData()
	{
	}

	XalanArrayKeyMap(const XalanArrayKeyMap<KeyType, ValueType, CompareType>&	theOther)
	{
		*this = theOther;
	}

	~XalanArrayKeyMap()
	{
	}

	XalanArrayKeyMap<KeyType, ValueType, CompareType>&
	operator=(const XalanArrayKeyMap<KeyType, ValueType, CompareType>&	theRHS)
	{
		if (&theRHS != this)
		{
			XalanArrayKeyMap<KeyType, ValueType, CompareType>	theTemp;

			const const_iterator	theEnd =
				theRHS.end();

			const_iterator	i = theRHS.begin();

			while(i != theEnd)
			{
				theTemp.insert(*i);

				++i;
			}

			swap(theTemp);
		}

		return *this;
	}

	bool
	operator==(const XalanArrayKeyMap<KeyType, ValueType, CompareType>&		theRHS) const
	{
		return m_map == theRHS.m_map;
	}

	size_type
	size() const
	{
		return m_map.size();
	}

	size_type
	max_size() const
	{
		return m_map.max_size();
	}

	bool
	empty() const
	{
		return m_map.empty();
	}

	iterator
	begin()
	{
		return m_map.begin();
	}

	const_iterator
	begin() const
	{
		return m_map.begin();
	}

	iterator
	end()
	{
		return m_map.end();
	}

	const_iterator
	end() const
	{
		return m_map.end();
	}

	reverse_iterator
	rbegin()
	{
		return m_map.rbegin();
	}

	const_reverse_iterator
	rbegin() const
	{
		return m_map.rbegin();
	}

	reverse_iterator
	rend()
	{
		return m_map.rend();
	}

	const_reverse_iterator
	rend() const
	{
		return m_map.rend();
	}

	insert_pair_type
	insert(const value_type&	thePair)
	{
		m_keyData.push_back(VectorHolderType::value_type(thePair.first, thePair.first + (length(thePair.first) + 1)));

		return m_map.insert(value_type(m_keyData.back().begin(), thePair.second));
	}

	referent_type&
	operator[](const key_type&	theKey)
	{
		const iterator	i = find(theKey);

		if (i == end())
		{
			return (*(insert(value_type(theKey, referent_type()))).first).second;
		}
		else
		{
			return (*i).second;
		}
	}

	iterator
	find(const key_type&	theKey)
	{
		return m_map.find(theKey);
	}

	const_iterator
	find(const key_type&	theKey) const
	{
		return m_map.find(theKey);
	}

	iterator
	lower_bound(const key_type&		theKey)
	{
		return m_map.lower_bound(theKey);
	}

	const_iterator
	lower_bound(const key_type&		theKey) const
	{
		return m_map.lower_bound(theKey);
	}

	iterator
	upper_bound(const key_type&		theKey)
	{
		return m_map.upper_bound(theKey);
	}

	const_iterator
	upper_bound(const key_type&		theKey) const
	{
		return m_map.upper_bound(theKey);
	}

	range_pair_type
	equal_range(const key_type&		theKey)
	{
		return m_map.equal_range(theKey);
	}

	const_range_pair_type
	equal_range(const key_type&		theKey) const
	{
		return m_map.equal_range(theKey);
	}

#if defined(XALAN_STLPORT_STL) && !defined(__STL_MEMBER_TEMPLATES)
	void
	erase(iterator	theIterator)
	{
		// $$$ ToDo: Does not empty vector in the
		// deque!!!
		m_map.erase(theIterator);
	}

	void
	erase(
			iterator	theFirst,
			iterator	theLast)
	{
		// $$$ ToDo: Does not empty vector in the
		// deque!!!
		m_map.erase(theFirst, theLast);
	}
#else
	iterator
	erase(iterator	theIterator)
	{
		// $$$ ToDo: Does not empty vector in the
		// deque!!!
		return m_map.erase(theIterator);
	}

	iterator
	erase(
			iterator	theFirst,
			iterator	theLast)
	{
		// $$$ ToDo: Does not empty vector in the
		// deque!!!
		return m_map.erase(theFirst, theLast);
	}
#endif

	size_type
	erase(const key_type&	theKey)
	{
		// $$$ ToDo: Does not empty vector in the
		// deque!!!
		return m_map.erase(theKey);
	}

	void
	swap(XalanArrayKeyMap<KeyType, ValueType, CompareType>&		theOther)
	{
		m_map.swap(theOther.m_map);

		m_keyData.swap(theOther.m_keyData);
	}

private:

	size_type
	length(const key_type&	theKey)
	{
		key_type	theCurrent = theKey;

		while(*theCurrent != 0)
		{
			++theCurrent;
		}

		return theCurrent - theKey;
	}

	MapType				m_map;

	VectorHolderType	m_keyData;
};

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

#include <deque>
#include <map>
#include <vector>

template<class KeyType, class ValueType, class CompareType>
class XalanArrayKeyMap
{
public:

#if defined(XALAN_NO_NAMESPACES)
	typedef vector<KeyType>									VectorType;
	typedef map<const KeyType*, ValueType, CompareType>		MapType;
	typedef deque<VectorType>								VectorHolderType;
#else
	typedef std::vector<KeyType>								VectorType;
	typedef std::map<const KeyType*, ValueType, CompareType>	MapType;
	typedef std::deque<VectorType>								VectorHolderType;
#endif

	typedef typename MapType::key_type					key_type;
	typedef typename MapType::value_type				value_type;
	typedef ValueType									referent_type;
	typedef CompareType									key_compare;
#if !defined(XALAN_NO_STD_ALLOCATORS)
	typedef typename MapType::allocator_type			allocator_type;
#endif
	typedef typename MapType::size_type					size_type;
	typedef typename MapType::difference_type			difference_type;
	typedef typename MapType::reference					reference;
	typedef typename MapType::const_reference			const_reference;
	typedef typename MapType::iterator					iterator;
	typedef typename MapType::const_iterator			const_iterator;
	typedef typename MapType::reverse_iterator			reverse_iterator;
	typedef typename MapType::const_reverse_iterator	const_reverse_iterator;

#if defined(XALAN_NO_NAMESPACES)
	typedef pair<iterator, bool>					insert_pair_type;
	typedef pair<iterator, iterator>				range_pair_type;
	typedef pair<const_iterator, const_iterator>	const_range_pair_type;
#else
	typedef std::pair<iterator, bool>					insert_pair_type;
	typedef std::pair<iterator, iterator>				range_pair_type;
	typedef std::pair<const_iterator, const_iterator>	const_range_pair_type;
#endif

	explicit
	XalanArrayKeyMap() :
		m_map(),
		m_keyData()
	{
	}

	XalanArrayKeyMap(const XalanArrayKeyMap<KeyType, ValueType, CompareType>&	theOther)
	{
		*this = theOther;
	}

	~XalanArrayKeyMap()
	{
	}

	XalanArrayKeyMap<KeyType, ValueType, CompareType>&
	operator=(const XalanArrayKeyMap<KeyType, ValueType, CompareType>&	theRHS)
	{
		if (&theRHS != this)
		{
			XalanArrayKeyMap<KeyType, ValueType, CompareType>	theTemp;

			const const_iterator	theEnd =
				theRHS.end();

			const_iterator	i = theRHS.begin();

			while(i != theEnd)
			{
				theTemp.insert(*i);

				++i;
			}

			swap(theTemp);
		}

		return *this;
	}

	bool
	operator==(const XalanArrayKeyMap<KeyType, ValueType, CompareType>&		theRHS) const
	{
		return m_map == theRHS.m_map;
	}

	size_type
	size() const
	{
		return m_map.size();
	}

	size_type
	max_size() const
	{
		return m_map.max_size();
	}

	bool
	empty() const
	{
		return m_map.empty();
	}

	iterator
	begin()
	{
		return m_map.begin();
	}

	const_iterator
	begin() const
	{
		return m_map.begin();
	}

	iterator
	end()
	{
		return m_map.end();
	}

	const_iterator
	end() const
	{
		return m_map.end();
	}

	reverse_iterator
	rbegin()
	{
		return m_map.rbegin();
	}

	const_reverse_iterator
	rbegin() const
	{
		return m_map.rbegin();
	}

	reverse_iterator
	rend()
	{
		return m_map.rend();
	}

	const_reverse_iterator
	rend() const
	{
		return m_map.rend();
	}

	insert_pair_type
	insert(const value_type&	thePair)
	{
		m_keyData.push_back(VectorHolderType::value_type(thePair.first, thePair.first + (length(thePair.first) + 1)));

		return m_map.insert(value_type(m_keyData.back().begin(), thePair.second));
	}

	referent_type&
	operator[](const key_type&	theKey)
	{
		const iterator	i = find(theKey);

		if (i == end())
		{
			return (*(insert(value_type(theKey, referent_type()))).first).second;
		}
		else
		{
			return (*i).second;
		}
	}

	iterator
	find(const key_type&	theKey)
	{
		return m_map.find(theKey);
	}

	const_iterator
	find(const key_type&	theKey) const
	{
		return m_map.find(theKey);
	}

	iterator
	lower_bound(const key_type&		theKey)
	{
		return m_map.lower_bound(theKey);
	}

	const_iterator
	lower_bound(const key_type&		theKey) const
	{
		return m_map.lower_bound(theKey);
	}

	iterator
	upper_bound(const key_type&		theKey)
	{
		return m_map.upper_bound(theKey);
	}

	const_iterator
	upper_bound(const key_type&		theKey) const
	{
		return m_map.upper_bound(theKey);
	}

	range_pair_type
	equal_range(const key_type&		theKey)
	{
		return m_map.equal_range(theKey);
	}

	const_range_pair_type
	equal_range(const key_type&		theKey) const
	{
		return m_map.equal_range(theKey);
	}

#if defined(XALAN_STLPORT_STL) && !defined(__STL_MEMBER_TEMPLATES)
	void
	erase(iterator	theIterator)
	{
		// $$$ ToDo: Does not empty vector in the
		// deque!!!
		m_map.erase(theIterator);
	}

	void
	erase(
			iterator	theFirst,
			iterator	theLast)
	{
		// $$$ ToDo: Does not empty vector in the
		// deque!!!
		m_map.erase(theFirst, theLast);
	}
#else
	iterator
	erase(iterator	theIterator)
	{
		// $$$ ToDo: Does not empty vector in the
		// deque!!!
		return m_map.erase(theIterator);
	}

	iterator
	erase(
			iterator	theFirst,
			iterator	theLast)
	{
		// $$$ ToDo: Does not empty vector in the
		// deque!!!
		return m_map.erase(theFirst, theLast);
	}
#endif

	size_type
	erase(const key_type&	theKey)
	{
		// $$$ ToDo: Does not empty vector in the
		// deque!!!
		return m_map.erase(theKey);
	}

	void
	swap(XalanArrayKeyMap<KeyType, ValueType, CompareType>&		theOther)
	{
		m_map.swap(theOther.m_map);

		m_keyData.swap(theOther.m_keyData);
	}

private:

	size_type
	length(const key_type&	theKey)
	{
		key_type	theCurrent = theKey;

		while(*theCurrent != 0)
		{
			++theCurrent;
		}

		return theCurrent - theKey;
	}

	MapType				m_map;

	VectorHolderType	m_keyData;
};

#endif
<|endoftext|>


<commit_before>/*
 * Copyright 2011 Intel Corporation.
 *
 * This program is licensed under the terms and conditions of the
 * Apache License, version 2.0.  The full text of the Apache License is at
 * http://www.apache.org/licenses/LICENSE-2.0
 */

#include "memoryleak.h"

#include <QDebug>

#include <QCoreApplication>
#include <QPluginLoader>
#include <QDir>
#include <QFileSystemWatcher>
#include <QSettings>
#include <QModelIndex>
#include <QThread>
#include <QDBusConnection>

#include "feedmanager.h"
//#include "feedplugin.h"
#include "feedplugincontainer.h"
#include "aggregatedmodel.h"
#include "settings.h"
#include "serviceadapter.h"
#include "searchablecontainer.h"
#include "serviceproxybase.h"
#include "dbusdefines.h"

#include "memoryleak-defines.h"

#include "threadtest.h"

//
// Overview of McaFeedManager
//    - loads content plugins
//    - assembles aggregation of service models from all plugins
//    - passes on feed requests to the right plugin and service
//    - generates unique ids for services and stores some info in QSettings
//

const char PLUGIN_RELPATH[] = "/MeeGo/Content";

//
// static members
//

static McaFeedManager *s_manager = NULL;
static int s_refCount = 0;

McaFeedManager *McaFeedManager::takeManager()
{
    if (!s_manager)
        s_manager = new McaFeedManager;
    s_refCount++;

    return s_manager;
}

void McaFeedManager::releaseManager()
{
    if (s_manager) {
        s_refCount--;
        if (s_refCount == 0) {
            delete s_manager;
            s_manager = NULL;
        }
    }
}

//
// members
//

McaFeedManager::McaFeedManager()
{
    // work around QtDBus problem in QTBUG-11413
    QDBusConnection::sessionBus();

    m_requestIdCounter = 0;
    m_destroying = false;

    qRegisterMetaType<QModelIndex>("QModelIndex");

    m_watcher = new QFileSystemWatcher;
    m_services = new McaAggregatedModel;
    m_serviceProxy = new McaServiceProxyBase(m_services, this);

    QDBusConnection::sessionBus().registerObject(CONTENT_DBUS_RAWSERVICE_OBJECT, m_serviceProxy, QDBusConnection::ExportAllContents);
    loadPlugins();

    // watch for new plugins getting installed and load them
    QStringList paths;
    foreach (QString path, QCoreApplication::libraryPaths())
        paths << path + PLUGIN_RELPATH;
    m_watcher->addPaths(paths);
    connect(m_watcher, SIGNAL(directoryChanged(QString)),
            this, SLOT(loadPlugins()));

    // TODO: watch for plugin updates, removals too?

}

McaFeedManager::~McaFeedManager()
{
    m_destroying = true;
    delete m_watcher;
    delete m_services;

    QDBusConnection::sessionBus().unregisterObject("serviceFeed");
    delete m_serviceProxy;

    foreach (McaFeedPluginContainer *plugin, m_pluginToPaths.keys())
    {
        removePlugin(plugin);
    }
}

void McaFeedManager::removePlugin(McaFeedPluginContainer *plugin)
{
    disconnect(plugin, SIGNAL(loadCompleted(McaFeedPluginContainer*,QString)),
            this, SLOT(onLoadCompleted(McaFeedPluginContainer*,QString)));
    disconnect(plugin, SIGNAL(loadError(McaFeedPluginContainer*,QString)),
            this, SLOT(onLoadError(McaFeedPluginContainer*,QString)));
    disconnect(plugin, SIGNAL(feedModelCreated(QObject*,McaFeedAdapter*,int)),
            this, SIGNAL(feedCreated(QObject*,McaFeedAdapter*,int)));
    disconnect(plugin, SIGNAL(createFeedError(QString,int)),
            this, SIGNAL(createFeedError(QString,int)));

    // allow remaining signals from threads to be dispatched to the feedmanager
    QCoreApplication::sendPostedEvents(qobject_cast<QObject*>(this), 0);

    qDebug() << "Terminating plugin " << m_pluginToPaths.value(plugin);
    QThread *plugin_thread = plugin->thread();

    // remove service
    foreach (const QAbstractItemModel *serviceModel, m_modelToPlugin.keys()) {
        if (m_modelToPlugin[serviceModel] == plugin) {
            const McaServiceAdapter *serviceAdapter = qobject_cast<const McaServiceAdapter*>(serviceModel);
            if (serviceAdapter) {
                //const_cast<McaServiceAdapter*>(serviceAdapter)->deleteLater();
                delete const_cast<McaServiceAdapter*>(serviceAdapter);
            }
            else {
                qDebug() << "NOT A SERVICE ADAPTER";
            }
            m_modelToPlugin.remove(serviceModel);
            break;
        }
    }

    plugin->deleteLater();
    plugin_thread->quit();
    if (!plugin_thread->wait(3000)) {
        qWarning() << "Plugin thread is not responding";
    }

    qDebug() << "Done terminating plugin " << m_pluginToPaths.value(plugin);
    m_pluginToPaths.remove(plugin);
}

QAbstractItemModel *McaFeedManager::serviceModel()
{
    return m_services;
}

int McaFeedManager::createFeed(const QAbstractItemModel *serviceModel,
                                               const QString& name)
{
    // TODO: clean up destroyed models

    McaFeedPluginContainer *plugin = m_modelToPlugin.value(serviceModel);
    if (plugin) {
        QMetaObject::invokeMethod(plugin, "createFeedModel", Qt::QueuedConnection, Q_ARG(QString, name), Q_ARG(int, m_requestIdCounter), Q_ARG(QString, serviceId(serviceModel, name)));
        return m_requestIdCounter++;
    }

    return -1;
}

int McaFeedManager::createSearchFeed(const QAbstractItemModel *serviceModel, const QString& name, const QString& searchText)
{
    // TODO: clean up destroyed models

    McaFeedPluginContainer *plugin = m_modelToPlugin.value(serviceModel);
    if (plugin) {
        QMetaObject::invokeMethod(plugin, "createSearchModel", Qt::QueuedConnection, Q_ARG(QString, name), Q_ARG(QString, searchText), Q_ARG(int, m_requestIdCounter));
        return m_requestIdCounter++;
    }
    return -1;
}

QString McaFeedManager::getHash(QSettings *settings, const QString& path, const QString& name, int pass)
{
    QString key = path + ":" + name;
    if (pass > 0)
        key.append(QString::number(pass));

    QString hash = QString::number(qHash(key), 16);
    settings->beginGroup(hash);
    QString settingsPath = settings->value(McaSettings::KeyPluginPath).toString();
    QString settingsName = settings->value(McaSettings::KeyServiceName).toString();

    if (settingsPath.isEmpty()) {
        // no such section, so create one
        settings->setValue(McaSettings::KeyPluginPath, path);
        settings->setValue(McaSettings::KeyServiceName, name);
    }
    else if (settingsPath != path || settingsName != name) {
        // found non-matching section, return to iterate
        hash.clear();
    }

    // otherwise, hash is good so return it
    settings->endGroup();
    return hash;
}

QString McaFeedManager::serviceId(const QAbstractItemModel *serviceModel, const QString& name)
{
    // returns: empty string on error, unique hash otherwise

    McaFeedPluginContainer *plugin = m_modelToPlugin.value(serviceModel);
    if (!plugin)
        return QString();

    QString pluginPath = m_pluginToPaths.value(plugin);
    QString serviceKey = pluginPath + ":" + name;
    QString hash = m_idToHash.value(serviceKey);

    if (hash.isEmpty()) {
        // haven't seen this service yet, so check QSettings file
        QSettings settings(McaSettings::Organization, McaSettings::ApplicationCore);
        int pass = 0;
        while (true) {
            hash = getHash(&settings, pluginPath, name, pass++);
            if (!hash.isEmpty()) {
                break;
            }
        }
        m_idToHash[serviceKey] = hash;
    }

    return hash;
}

//
// protected slots
//

void McaFeedManager::loadPlugins()
{
    qDebug() << "McaFeedManager::loadPlugins()";
    // effects: checks plugin paths for any new plugins to load
    foreach (QString path, QCoreApplication::libraryPaths()) {
        QDir dir = QDir(path + PLUGIN_RELPATH);
        qDebug() << dir.absolutePath();
        foreach (QString filename, dir.entryList(QStringList() << QString("*.so"))) {
            QString abspath = dir.absoluteFilePath(filename);
            qDebug() << abspath;
            if (m_pluginToPaths.values().contains(abspath))
                continue;

            McaFeedPluginContainer *pluginContainer = new McaFeedPluginContainer();
            pluginContainer->setPath(abspath);

            connect(pluginContainer, SIGNAL(loadCompleted(McaFeedPluginContainer*,QString)),
                    this, SLOT(onLoadCompleted(McaFeedPluginContainer*,QString)));
            connect(pluginContainer, SIGNAL(loadError(McaFeedPluginContainer*, QString)),
                    this, SLOT(onLoadError(McaFeedPluginContainer*,QString)));
            // Service data is accessed when the feed is created, which is why it blocks the thread.
            connect(pluginContainer, SIGNAL(feedModelCreated(QObject*,McaFeedAdapter*,int)),
                    this, SIGNAL(feedCreated(QObject*,McaFeedAdapter*,int)), Qt::BlockingQueuedConnection );
            connect(pluginContainer, SIGNAL(createFeedError(QString,int)),
                    this, SIGNAL(createFeedError(QString,int)));

#ifdef THREADING_DEBUG
            McaThreadTest *pluginThread = new McaThreadTest(this);
#else
            QThread *pluginThread = new QThread(this);
#endif
            connect(pluginThread, SIGNAL(started()), pluginContainer, SLOT(load()));

#ifdef THREADING
            pluginContainer->moveToThread(pluginThread);
#endif
            pluginThread->start();
        }
    }
}

void McaFeedManager::onLoadCompleted(McaFeedPluginContainer *plugin, const QString &absPath)
{
    if (plugin) {
        if(m_destroying) {
            removePlugin(plugin);
        } else {
            addPlugin(plugin, absPath);
        }
    } else {
        qWarning() << "Error loading plugin: received null plugin from threaded loader!";
    }
}

void McaFeedManager::onLoadError(McaFeedPluginContainer *plugin, const QString &errorString)
{
    qWarning() << "Error loading plugin: " << errorString;
    if (plugin) {
        removePlugin(plugin);
    } else {
        qWarning() << "Error deleting plugin: received null plugin from threaded loader!";
    }
}

//
// protected members
//

void McaFeedManager::addPlugin(McaFeedPluginContainer *plugin, const QString& abspath)
{
    m_pluginToPaths.insert(plugin, abspath);
    QAbstractItemModel *model = plugin->serviceModel();
    McaServiceAdapter *adapter = new McaServiceAdapter(this, 0);
    adapter->moveToThread(plugin->thread());
    m_modelToPlugin.insert(adapter, plugin);
    adapter->setSourceModel(model);
    m_services->addSourceModel(adapter);
}
<commit_msg>Fix ifdef's for disabling threading<commit_after>/*
 * Copyright 2011 Intel Corporation.
 *
 * This program is licensed under the terms and conditions of the
 * Apache License, version 2.0.  The full text of the Apache License is at
 * http://www.apache.org/licenses/LICENSE-2.0
 */

#include "memoryleak.h"

#include <QDebug>

#include <QCoreApplication>
#include <QPluginLoader>
#include <QDir>
#include <QFileSystemWatcher>
#include <QSettings>
#include <QModelIndex>
#include <QThread>
#include <QDBusConnection>

#include "feedmanager.h"
//#include "feedplugin.h"
#include "feedplugincontainer.h"
#include "aggregatedmodel.h"
#include "settings.h"
#include "serviceadapter.h"
#include "searchablecontainer.h"
#include "serviceproxybase.h"
#include "dbusdefines.h"

#include "memoryleak-defines.h"

#include "threadtest.h"

//
// Overview of McaFeedManager
//    - loads content plugins
//    - assembles aggregation of service models from all plugins
//    - passes on feed requests to the right plugin and service
//    - generates unique ids for services and stores some info in QSettings
//

const char PLUGIN_RELPATH[] = "/MeeGo/Content";

//
// static members
//

static McaFeedManager *s_manager = NULL;
static int s_refCount = 0;

McaFeedManager *McaFeedManager::takeManager()
{
    if (!s_manager)
        s_manager = new McaFeedManager;
    s_refCount++;

    return s_manager;
}

void McaFeedManager::releaseManager()
{
    if (s_manager) {
        s_refCount--;
        if (s_refCount == 0) {
            delete s_manager;
            s_manager = NULL;
        }
    }
}

//
// members
//

McaFeedManager::McaFeedManager()
{
    // work around QtDBus problem in QTBUG-11413
    QDBusConnection::sessionBus();

    m_requestIdCounter = 0;
    m_destroying = false;

    qRegisterMetaType<QModelIndex>("QModelIndex");

    m_watcher = new QFileSystemWatcher;
    m_services = new McaAggregatedModel;
    m_serviceProxy = new McaServiceProxyBase(m_services, this);

    QDBusConnection::sessionBus().registerObject(CONTENT_DBUS_RAWSERVICE_OBJECT, m_serviceProxy, QDBusConnection::ExportAllContents);
    loadPlugins();

    // watch for new plugins getting installed and load them
    QStringList paths;
    foreach (QString path, QCoreApplication::libraryPaths())
        paths << path + PLUGIN_RELPATH;
    m_watcher->addPaths(paths);
    connect(m_watcher, SIGNAL(directoryChanged(QString)),
            this, SLOT(loadPlugins()));

    // TODO: watch for plugin updates, removals too?

}

McaFeedManager::~McaFeedManager()
{
    m_destroying = true;
    delete m_watcher;
    delete m_services;

    QDBusConnection::sessionBus().unregisterObject("serviceFeed");
    delete m_serviceProxy;

    foreach (McaFeedPluginContainer *plugin, m_pluginToPaths.keys())
    {
        removePlugin(plugin);
    }
}

void McaFeedManager::removePlugin(McaFeedPluginContainer *plugin)
{
    disconnect(plugin, SIGNAL(loadCompleted(McaFeedPluginContainer*,QString)),
            this, SLOT(onLoadCompleted(McaFeedPluginContainer*,QString)));
    disconnect(plugin, SIGNAL(loadError(McaFeedPluginContainer*,QString)),
            this, SLOT(onLoadError(McaFeedPluginContainer*,QString)));
    disconnect(plugin, SIGNAL(feedModelCreated(QObject*,McaFeedAdapter*,int)),
            this, SIGNAL(feedCreated(QObject*,McaFeedAdapter*,int)));
    disconnect(plugin, SIGNAL(createFeedError(QString,int)),
            this, SIGNAL(createFeedError(QString,int)));

    // allow remaining signals from threads to be dispatched to the feedmanager
    QCoreApplication::sendPostedEvents(qobject_cast<QObject*>(this), 0);

#ifdef THREADING
    qDebug() << "Terminating plugin " << m_pluginToPaths.value(plugin);
    QThread *plugin_thread = plugin->thread();
#endif

    // remove service
    foreach (const QAbstractItemModel *serviceModel, m_modelToPlugin.keys()) {
        if (m_modelToPlugin[serviceModel] == plugin) {
            const McaServiceAdapter *serviceAdapter = qobject_cast<const McaServiceAdapter*>(serviceModel);
            if (serviceAdapter) {
                //const_cast<McaServiceAdapter*>(serviceAdapter)->deleteLater();
                delete const_cast<McaServiceAdapter*>(serviceAdapter);
            }
            else {
                qDebug() << "NOT A SERVICE ADAPTER";
            }
            m_modelToPlugin.remove(serviceModel);
            break;
        }
    }

    plugin->deleteLater();

#ifdef THREADING
    plugin_thread->quit();
    if (!plugin_thread->wait(3000)) {
        qWarning() << "Plugin thread is not responding";
    }
#endif

    qDebug() << "Done terminating plugin " << m_pluginToPaths.value(plugin);
    m_pluginToPaths.remove(plugin);
}

QAbstractItemModel *McaFeedManager::serviceModel()
{
    return m_services;
}

int McaFeedManager::createFeed(const QAbstractItemModel *serviceModel,
                                               const QString& name)
{
    // TODO: clean up destroyed models

    McaFeedPluginContainer *plugin = m_modelToPlugin.value(serviceModel);
    if (plugin) {
        QMetaObject::invokeMethod(plugin, "createFeedModel", Qt::QueuedConnection, Q_ARG(QString, name), Q_ARG(int, m_requestIdCounter), Q_ARG(QString, serviceId(serviceModel, name)));
        return m_requestIdCounter++;
    }

    return -1;
}

int McaFeedManager::createSearchFeed(const QAbstractItemModel *serviceModel, const QString& name, const QString& searchText)
{
    // TODO: clean up destroyed models

    McaFeedPluginContainer *plugin = m_modelToPlugin.value(serviceModel);
    if (plugin) {
        QMetaObject::invokeMethod(plugin, "createSearchModel", Qt::QueuedConnection, Q_ARG(QString, name), Q_ARG(QString, searchText), Q_ARG(int, m_requestIdCounter));
        return m_requestIdCounter++;
    }
    return -1;
}

QString McaFeedManager::getHash(QSettings *settings, const QString& path, const QString& name, int pass)
{
    QString key = path + ":" + name;
    if (pass > 0)
        key.append(QString::number(pass));

    QString hash = QString::number(qHash(key), 16);
    settings->beginGroup(hash);
    QString settingsPath = settings->value(McaSettings::KeyPluginPath).toString();
    QString settingsName = settings->value(McaSettings::KeyServiceName).toString();

    if (settingsPath.isEmpty()) {
        // no such section, so create one
        settings->setValue(McaSettings::KeyPluginPath, path);
        settings->setValue(McaSettings::KeyServiceName, name);
    }
    else if (settingsPath != path || settingsName != name) {
        // found non-matching section, return to iterate
        hash.clear();
    }

    // otherwise, hash is good so return it
    settings->endGroup();
    return hash;
}

QString McaFeedManager::serviceId(const QAbstractItemModel *serviceModel, const QString& name)
{
    // returns: empty string on error, unique hash otherwise

    McaFeedPluginContainer *plugin = m_modelToPlugin.value(serviceModel);
    if (!plugin)
        return QString();

    QString pluginPath = m_pluginToPaths.value(plugin);
    QString serviceKey = pluginPath + ":" + name;
    QString hash = m_idToHash.value(serviceKey);

    if (hash.isEmpty()) {
        // haven't seen this service yet, so check QSettings file
        QSettings settings(McaSettings::Organization, McaSettings::ApplicationCore);
        int pass = 0;
        while (true) {
            hash = getHash(&settings, pluginPath, name, pass++);
            if (!hash.isEmpty()) {
                break;
            }
        }
        m_idToHash[serviceKey] = hash;
    }

    return hash;
}

//
// protected slots
//

void McaFeedManager::loadPlugins()
{
    qDebug() << "McaFeedManager::loadPlugins()";
    // effects: checks plugin paths for any new plugins to load
    foreach (QString path, QCoreApplication::libraryPaths()) {
        QDir dir = QDir(path + PLUGIN_RELPATH);
        qDebug() << dir.absolutePath();
        foreach (QString filename, dir.entryList(QStringList() << QString("*.so"))) {
            QString abspath = dir.absoluteFilePath(filename);
            qDebug() << abspath;
            if (m_pluginToPaths.values().contains(abspath))
                continue;

            McaFeedPluginContainer *pluginContainer = new McaFeedPluginContainer();
            pluginContainer->setPath(abspath);

            connect(pluginContainer, SIGNAL(loadCompleted(McaFeedPluginContainer*,QString)),
                    this, SLOT(onLoadCompleted(McaFeedPluginContainer*,QString)));
            connect(pluginContainer, SIGNAL(loadError(McaFeedPluginContainer*, QString)),
                    this, SLOT(onLoadError(McaFeedPluginContainer*,QString)));
            // Service data is accessed when the feed is created, which is why it blocks the thread.
#ifdef THREADING
            connect(pluginContainer, SIGNAL(feedModelCreated(QObject*,McaFeedAdapter*,int)),
                    this, SIGNAL(feedCreated(QObject*,McaFeedAdapter*,int)), Qt::BlockingQueuedConnection );
#else
            connect(pluginContainer, SIGNAL(feedModelCreated(QObject*,McaFeedAdapter*,int)),
                    this, SIGNAL(feedCreated(QObject*,McaFeedAdapter*,int)));
#endif
            connect(pluginContainer, SIGNAL(createFeedError(QString,int)),
                    this, SIGNAL(createFeedError(QString,int)));

#ifdef THREADING
#ifdef THREADING_DEBUG
            McaThreadTest *pluginThread = new McaThreadTest(this);
#else // THREADING_DEBUG
            QThread *pluginThread = new QThread(this);
#endif // THREADING_DEBUG
            connect(pluginThread, SIGNAL(started()), pluginContainer, SLOT(load()));

            pluginContainer->moveToThread(pluginThread);
            pluginThread->start();
#else // THREADING
            pluginContainer->load();
#endif // THREADING
        }
    }
}

void McaFeedManager::onLoadCompleted(McaFeedPluginContainer *plugin, const QString &absPath)
{
    if (plugin) {
        if(m_destroying) {
            removePlugin(plugin);
        } else {
            addPlugin(plugin, absPath);
        }
    } else {
        qWarning() << "Error loading plugin: received null plugin from threaded loader!";
    }
}

void McaFeedManager::onLoadError(McaFeedPluginContainer *plugin, const QString &errorString)
{
    qWarning() << "Error loading plugin: " << errorString;
    if (plugin) {
        removePlugin(plugin);
    } else {
        qWarning() << "Error deleting plugin: received null plugin from threaded loader!";
    }
}

//
// protected members
//

void McaFeedManager::addPlugin(McaFeedPluginContainer *plugin, const QString& abspath)
{
    m_pluginToPaths.insert(plugin, abspath);
    QAbstractItemModel *model = plugin->serviceModel();
    McaServiceAdapter *adapter = new McaServiceAdapter(this, 0);
    adapter->moveToThread(plugin->thread());
    m_modelToPlugin.insert(adapter, plugin);
    adapter->setSourceModel(model);
    m_services->addSourceModel(adapter);
}
<|endoftext|>


<commit_before>/*
    This file is part of Magnum.

    Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz>

    Permission is hereby granted, free of charge, to any person obtaining a
    copy of this software and associated documentation files (the "Software"),
    to deal in the Software without restriction, including without limitation
    the rights to use, copy, modify, merge, publish, distribute, sublicense,
    and/or sell copies of the Software, and to permit persons to whom the
    Software is furnished to do so, subject to the following conditions:

    The above copyright notice and this permission notice shall be included
    in all copies or substantial portions of the Software.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
    THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
    DEALINGS IN THE SOFTWARE.
*/

#include "Sdl2Application.h"

#include <Utility/utilities.h>

#include "Context.h"
#include "ExtensionWrangler.h"

namespace Magnum { namespace Platform {

namespace {

/*
 * Fix up the modifiers -- we want >= operator to work properly on Shift,
 * Ctrl, Alt, but SDL generates different event for left / right keys, thus
 * (modifiers >= Shift) would pass only if both left and right were pressed,
 * which is usually not what the developers wants.
 */
Sdl2Application::InputEvent::Modifiers fixedModifiers(Uint16 mod) {
    Sdl2Application::InputEvent::Modifiers modifiers(static_cast<Sdl2Application::InputEvent::Modifier>(mod));
    if(modifiers & Sdl2Application::InputEvent::Modifier::Shift) modifiers |= Sdl2Application::InputEvent::Modifier::Shift;
    if(modifiers & Sdl2Application::InputEvent::Modifier::Ctrl) modifiers |= Sdl2Application::InputEvent::Modifier::Ctrl;
    if(modifiers & Sdl2Application::InputEvent::Modifier::Alt) modifiers |= Sdl2Application::InputEvent::Modifier::Alt;
    return modifiers;
}

}

Sdl2Application::Sdl2Application(const Arguments&): context(nullptr), flags(Flag::Redraw) {
    initialize();
    createContext(new Configuration);
}

Sdl2Application::Sdl2Application(const Arguments&, Configuration* configuration): context(nullptr), flags(Flag::Redraw) {
    initialize();
    if(configuration) createContext(configuration);
}

void Sdl2Application::initialize() {
    if(SDL_Init(SDL_INIT_VIDEO) < 0) {
        Error() << "Cannot initialize SDL.";
        std::exit(1);
    }
}

void Sdl2Application::createContext(Configuration* configuration) {
    if(!tryCreateContext(configuration)) {
        Error() << "Platform::Sdl2Application::createContext(): cannot create context:" << SDL_GetError();
        delete configuration;
        std::exit(1);

    } else delete configuration;
}

bool Sdl2Application::tryCreateContext(Configuration* configuration) {
    CORRADE_ASSERT(!context, "Platform::Sdl2Application::tryCreateContext(): context already created", false);

    /* Enable double buffering and 24bt depth buffer */
    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
    SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);

    /* Multisampling */
    SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, configuration->sampleCount() > 1 ? 1 : 0);
    SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, configuration->sampleCount());

    /* Flags: if not hidden, set as shown */
    Uint32 flags(configuration->flags());
    if(!(configuration->flags() & Configuration::Flag::Hidden)) flags |= SDL_WINDOW_SHOWN;

    if(!(window = SDL_CreateWindow(configuration->title().c_str(),
            SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
            configuration->size().x(), configuration->size().y(),
            SDL_WINDOW_OPENGL|flags))) {
        Error() << "Platform::Sdl2Application::tryCreateContext(): cannot create window";
        std::exit(2);
    }

    if(!(context = SDL_GL_CreateContext(window))) {
        SDL_DestroyWindow(window);
        window = nullptr;
        return false;
    }

    /* This must be enabled, otherwise (on my NVidia) it crashes when creating
       VAO. WTF. */
    ExtensionWrangler::initialize(ExtensionWrangler::ExperimentalFeatures::Enable);

    /* Push resize event, so viewportEvent() is called at startup */
    SDL_Event* sizeEvent = new SDL_Event;
    sizeEvent->type = SDL_WINDOWEVENT;
    sizeEvent->window.event = SDL_WINDOWEVENT_RESIZED;
    sizeEvent->window.data1 = configuration->size().x();
    sizeEvent->window.data2 = configuration->size().y();
    SDL_PushEvent(sizeEvent);

    c = new Context;
    return true;
}

Sdl2Application::~Sdl2Application() {
    delete c;

    SDL_GL_DeleteContext(context);
    SDL_DestroyWindow(window);
    SDL_Quit();
}

int Sdl2Application::exec() {
    while(!(flags & Flag::Exit)) {
        SDL_Event event;

        while(SDL_PollEvent(&event)) {
            switch(event.type) {
                case SDL_WINDOWEVENT:
                    switch(event.window.event) {
                        case SDL_WINDOWEVENT_RESIZED:
                            viewportEvent({event.window.data1, event.window.data2});
                            flags |= Flag::Redraw;
                            break;
                        case SDL_WINDOWEVENT_EXPOSED:
                            flags |= Flag::Redraw;
                            break;
                    } break;

                case SDL_KEYDOWN:
                case SDL_KEYUP: {
                    KeyEvent e(static_cast<KeyEvent::Key>(event.key.keysym.sym), fixedModifiers(event.key.keysym.mod));
                    event.type == SDL_KEYDOWN ? keyPressEvent(e) : keyReleaseEvent(e);
                } break;

                case SDL_MOUSEBUTTONDOWN:
                case SDL_MOUSEBUTTONUP: {
                    MouseEvent e(static_cast<MouseEvent::Button>(event.button.button), {event.button.x, event.button.y});
                    event.type == SDL_MOUSEBUTTONDOWN ? mousePressEvent(e) : mouseReleaseEvent(e);
                } break;

                case SDL_MOUSEWHEEL:
                    if(event.wheel.y != 0) {
                        MouseEvent e(event.wheel.y < 0 ? MouseEvent::Button::WheelUp : MouseEvent::Button::WheelDown, {event.wheel.x, event.wheel.y});
                        mousePressEvent(e);
                    } break;

                case SDL_MOUSEMOTION: {
                    MouseMoveEvent e({event.motion.x, event.motion.y}, {event.motion.xrel, event.motion.yrel});
                    mouseMoveEvent(e);
                    break;
                }

                case SDL_QUIT: return 0;
            }
        }

        if(flags & Flag::Redraw) {
            flags &= ~Flag::Redraw;
            drawEvent();
        } else Corrade::Utility::sleep(5);
    }

    return 0;
}

void Sdl2Application::setMouseLocked(bool enabled) {
    SDL_SetWindowGrab(window, enabled ? SDL_TRUE : SDL_FALSE);
    SDL_SetRelativeMouseMode(enabled ? SDL_TRUE : SDL_FALSE);
}

Sdl2Application::Configuration::Configuration(): _title("Magnum SDL2 Application"), _size(800, 600), _flags(Flag::Resizable), _sampleCount(0) {}
Sdl2Application::Configuration::~Configuration() = default;

Sdl2Application::InputEvent::Modifiers Sdl2Application::MouseEvent::modifiers() {
    if(modifiersLoaded) return _modifiers;
    modifiersLoaded = true;
    return _modifiers = fixedModifiers(SDL_GetModState());
}

Sdl2Application::InputEvent::Modifiers Sdl2Application::MouseMoveEvent::modifiers() {
    if(modifiersLoaded) return _modifiers;
    modifiersLoaded = true;
    return _modifiers = fixedModifiers(SDL_GetModState());
}

}}
<commit_msg>Platform: better diagnostic in Sdl2Application::tryCreateContext().<commit_after>/*
    This file is part of Magnum.

    Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz>

    Permission is hereby granted, free of charge, to any person obtaining a
    copy of this software and associated documentation files (the "Software"),
    to deal in the Software without restriction, including without limitation
    the rights to use, copy, modify, merge, publish, distribute, sublicense,
    and/or sell copies of the Software, and to permit persons to whom the
    Software is furnished to do so, subject to the following conditions:

    The above copyright notice and this permission notice shall be included
    in all copies or substantial portions of the Software.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
    THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
    DEALINGS IN THE SOFTWARE.
*/

#include "Sdl2Application.h"

#include <Utility/utilities.h>

#include "Context.h"
#include "ExtensionWrangler.h"

namespace Magnum { namespace Platform {

namespace {

/*
 * Fix up the modifiers -- we want >= operator to work properly on Shift,
 * Ctrl, Alt, but SDL generates different event for left / right keys, thus
 * (modifiers >= Shift) would pass only if both left and right were pressed,
 * which is usually not what the developers wants.
 */
Sdl2Application::InputEvent::Modifiers fixedModifiers(Uint16 mod) {
    Sdl2Application::InputEvent::Modifiers modifiers(static_cast<Sdl2Application::InputEvent::Modifier>(mod));
    if(modifiers & Sdl2Application::InputEvent::Modifier::Shift) modifiers |= Sdl2Application::InputEvent::Modifier::Shift;
    if(modifiers & Sdl2Application::InputEvent::Modifier::Ctrl) modifiers |= Sdl2Application::InputEvent::Modifier::Ctrl;
    if(modifiers & Sdl2Application::InputEvent::Modifier::Alt) modifiers |= Sdl2Application::InputEvent::Modifier::Alt;
    return modifiers;
}

}

Sdl2Application::Sdl2Application(const Arguments&): context(nullptr), flags(Flag::Redraw) {
    initialize();
    createContext(new Configuration);
}

Sdl2Application::Sdl2Application(const Arguments&, Configuration* configuration): context(nullptr), flags(Flag::Redraw) {
    initialize();
    if(configuration) createContext(configuration);
}

void Sdl2Application::initialize() {
    if(SDL_Init(SDL_INIT_VIDEO) < 0) {
        Error() << "Cannot initialize SDL.";
        std::exit(1);
    }
}

void Sdl2Application::createContext(Configuration* configuration) {
    if(!tryCreateContext(configuration)) {
        Error() << "Platform::Sdl2Application::createContext(): cannot create context:" << SDL_GetError();
        delete configuration;
        std::exit(1);

    } else delete configuration;
}

bool Sdl2Application::tryCreateContext(Configuration* configuration) {
    CORRADE_ASSERT(!context, "Platform::Sdl2Application::tryCreateContext(): context already created", false);

    /* Enable double buffering and 24bt depth buffer */
    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
    SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);

    /* Multisampling */
    SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, configuration->sampleCount() > 1 ? 1 : 0);
    SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, configuration->sampleCount());

    /* Flags: if not hidden, set as shown */
    Uint32 flags(configuration->flags());
    if(!(configuration->flags() & Configuration::Flag::Hidden)) flags |= SDL_WINDOW_SHOWN;

    if(!(window = SDL_CreateWindow(configuration->title().c_str(),
            SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
            configuration->size().x(), configuration->size().y(),
            SDL_WINDOW_OPENGL|flags))) {
        Error() << "Platform::Sdl2Application::tryCreateContext(): cannot create window:" << SDL_GetError();
        std::exit(2);
    }

    if(!(context = SDL_GL_CreateContext(window))) {
        SDL_DestroyWindow(window);
        window = nullptr;
        return false;
    }

    /* This must be enabled, otherwise (on my NVidia) it crashes when creating
       VAO. WTF. */
    ExtensionWrangler::initialize(ExtensionWrangler::ExperimentalFeatures::Enable);

    /* Push resize event, so viewportEvent() is called at startup */
    SDL_Event* sizeEvent = new SDL_Event;
    sizeEvent->type = SDL_WINDOWEVENT;
    sizeEvent->window.event = SDL_WINDOWEVENT_RESIZED;
    sizeEvent->window.data1 = configuration->size().x();
    sizeEvent->window.data2 = configuration->size().y();
    SDL_PushEvent(sizeEvent);

    c = new Context;
    return true;
}

Sdl2Application::~Sdl2Application() {
    delete c;

    SDL_GL_DeleteContext(context);
    SDL_DestroyWindow(window);
    SDL_Quit();
}

int Sdl2Application::exec() {
    while(!(flags & Flag::Exit)) {
        SDL_Event event;

        while(SDL_PollEvent(&event)) {
            switch(event.type) {
                case SDL_WINDOWEVENT:
                    switch(event.window.event) {
                        case SDL_WINDOWEVENT_RESIZED:
                            viewportEvent({event.window.data1, event.window.data2});
                            flags |= Flag::Redraw;
                            break;
                        case SDL_WINDOWEVENT_EXPOSED:
                            flags |= Flag::Redraw;
                            break;
                    } break;

                case SDL_KEYDOWN:
                case SDL_KEYUP: {
                    KeyEvent e(static_cast<KeyEvent::Key>(event.key.keysym.sym), fixedModifiers(event.key.keysym.mod));
                    event.type == SDL_KEYDOWN ? keyPressEvent(e) : keyReleaseEvent(e);
                } break;

                case SDL_MOUSEBUTTONDOWN:
                case SDL_MOUSEBUTTONUP: {
                    MouseEvent e(static_cast<MouseEvent::Button>(event.button.button), {event.button.x, event.button.y});
                    event.type == SDL_MOUSEBUTTONDOWN ? mousePressEvent(e) : mouseReleaseEvent(e);
                } break;

                case SDL_MOUSEWHEEL:
                    if(event.wheel.y != 0) {
                        MouseEvent e(event.wheel.y < 0 ? MouseEvent::Button::WheelUp : MouseEvent::Button::WheelDown, {event.wheel.x, event.wheel.y});
                        mousePressEvent(e);
                    } break;

                case SDL_MOUSEMOTION: {
                    MouseMoveEvent e({event.motion.x, event.motion.y}, {event.motion.xrel, event.motion.yrel});
                    mouseMoveEvent(e);
                    break;
                }

                case SDL_QUIT: return 0;
            }
        }

        if(flags & Flag::Redraw) {
            flags &= ~Flag::Redraw;
            drawEvent();
        } else Corrade::Utility::sleep(5);
    }

    return 0;
}

void Sdl2Application::setMouseLocked(bool enabled) {
    SDL_SetWindowGrab(window, enabled ? SDL_TRUE : SDL_FALSE);
    SDL_SetRelativeMouseMode(enabled ? SDL_TRUE : SDL_FALSE);
}

Sdl2Application::Configuration::Configuration(): _title("Magnum SDL2 Application"), _size(800, 600), _flags(Flag::Resizable), _sampleCount(0) {}
Sdl2Application::Configuration::~Configuration() = default;

Sdl2Application::InputEvent::Modifiers Sdl2Application::MouseEvent::modifiers() {
    if(modifiersLoaded) return _modifiers;
    modifiersLoaded = true;
    return _modifiers = fixedModifiers(SDL_GetModState());
}

Sdl2Application::InputEvent::Modifiers Sdl2Application::MouseMoveEvent::modifiers() {
    if(modifiersLoaded) return _modifiers;
    modifiersLoaded = true;
    return _modifiers = fixedModifiers(SDL_GetModState());
}

}}
<|endoftext|>