<commit_before>/**
 * The goal of these tests is to verify the behavior of all blob commands given
 * the current state is verificationCompleted.  This state is achieved as a out
 * of verificationStarted.
 */
#include "firmware_handler.hpp"
#include "firmware_unittest.hpp"
#include "status.hpp"
#include "util.hpp"

#include <cstdint>
#include <string>
#include <vector>

#include <gtest/gtest.h>

namespace ipmi_flash
{
namespace
{

using ::testing::Return;

/*
 * There are the following calls (parameters may vary):
 * canHandleBlob(blob)
 * getBlobIds
 * deleteBlob(blob)
 * stat(blob)
 * stat(session)
 * open(blob)
 * close(session)
 * writemeta(session)
 * write(session)
 * read(session)
 * commit(session)
 *
 * Like the state verificationStarted, there is a file open in
 * verificationCompleted.  This state is transitioned to after a stat() command
 * indicates a successful verification.
 */

class FirmwareHandlerVerificationCompletedTest
    : public IpmiOnlyFirmwareStaticTest
{
  protected:
    void getToVerificationCompleted(VerifyCheckResponses checkResponse)
    {
        /* The hash was not sent up, as it's technically optional.  Therefore,
         * there is no active hash file.
         */
        EXPECT_CALL(imageMock, open(staticLayoutBlobId)).WillOnce(Return(true));
        EXPECT_TRUE(handler->open(session, flags, staticLayoutBlobId));
        expectedState(FirmwareBlobHandler::UpdateState::uploadInProgress);

        EXPECT_CALL(imageMock, close()).WillRepeatedly(Return());
        handler->close(session);
        expectedState(FirmwareBlobHandler::UpdateState::verificationPending);

        EXPECT_TRUE(handler->open(session, flags, verifyBlobId));
        EXPECT_CALL(*verifyMockPtr, triggerVerification())
            .WillOnce(Return(true));

        EXPECT_TRUE(handler->commit(session, {}));
        expectedState(FirmwareBlobHandler::UpdateState::verificationStarted);

        EXPECT_CALL(*verifyMockPtr, checkVerificationState())
            .WillOnce(Return(checkResponse));
        blobs::BlobMeta meta;
        EXPECT_TRUE(handler->stat(session, &meta));
        expectedState(FirmwareBlobHandler::UpdateState::verificationCompleted);
    }

    std::uint16_t session = 1;
    std::uint16_t flags =
        blobs::OpenFlags::write | FirmwareBlobHandler::UpdateFlags::ipmi;
};

/* TODO:
 * canHandleBlob(blob)
 * getBlobIds
 * deleteBlob(blob)
 *
 */

/*
 * stat(blob)
 */
TEST_F(FirmwareHandlerVerificationCompletedTest,
       StatOnActiveImageReturnsFailure)
{
    getToVerificationCompleted(VerifyCheckResponses::success);
    ASSERT_TRUE(handler->canHandleBlob(activeImageBlobId));

    blobs::BlobMeta meta;
    EXPECT_FALSE(handler->stat(activeImageBlobId, &meta));
}

TEST_F(FirmwareHandlerVerificationCompletedTest, StatOnVerifyBlobReturnsFailure)
{
    getToVerificationCompleted(VerifyCheckResponses::success);
    ASSERT_TRUE(handler->canHandleBlob(verifyBlobId));

    blobs::BlobMeta meta;
    EXPECT_FALSE(handler->stat(verifyBlobId, &meta));
}

TEST_F(FirmwareHandlerVerificationCompletedTest,
       StatOnNormalBlobsReturnsSuccess)
{
    getToVerificationCompleted(VerifyCheckResponses::success);

    blobs::BlobMeta expected;
    expected.blobState = FirmwareBlobHandler::UpdateFlags::ipmi;
    expected.size = 0;

    std::vector<std::string> testBlobs = {staticLayoutBlobId, hashBlobId};
    for (const auto& blob : testBlobs)
    {
        ASSERT_TRUE(handler->canHandleBlob(blob));

        blobs::BlobMeta meta = {};
        EXPECT_TRUE(handler->stat(blob, &meta));
        EXPECT_EQ(expected, meta);
    }
}

/*
 * stat(session) - the verify blobid is open in this state, so stat on that once
 * completed should have no effect.
 *
 * open(blob) - all open should fail
 *
 * close(session) - close on the verify blobid:
 *   1. if successful adds update blob id, changes state to UpdatePending
 *   2. if unsuccessful doesn't add update blob id, changes state to?
 */

/*
 * writemeta(session) - write meta should fail.
 * write(session) - write should fail.
 * read(session) - read returns empty.
 * commit(session) - ?
 */

} // namespace
} // namespace ipmi_flash
<commit_msg>test: firmware verificationCompleted: stat(activehash)<commit_after>/**
 * The goal of these tests is to verify the behavior of all blob commands given
 * the current state is verificationCompleted.  This state is achieved as a out
 * of verificationStarted.
 */
#include "firmware_handler.hpp"
#include "firmware_unittest.hpp"
#include "status.hpp"
#include "util.hpp"

#include <cstdint>
#include <string>
#include <vector>

#include <gtest/gtest.h>

namespace ipmi_flash
{
namespace
{

using ::testing::Return;

/*
 * There are the following calls (parameters may vary):
 * canHandleBlob(blob)
 * getBlobIds
 * deleteBlob(blob)
 * stat(blob)
 * stat(session)
 * open(blob)
 * close(session)
 * writemeta(session)
 * write(session)
 * read(session)
 * commit(session)
 *
 * Like the state verificationStarted, there is a file open in
 * verificationCompleted.  This state is transitioned to after a stat() command
 * indicates a successful verification.
 */

class FirmwareHandlerVerificationCompletedTest
    : public IpmiOnlyFirmwareStaticTest
{
  protected:
    void getToVerificationCompleted(VerifyCheckResponses checkResponse)
    {
        /* The hash was not sent up, as it's technically optional.  Therefore,
         * there is no active hash file.
         */
        EXPECT_CALL(imageMock, open(staticLayoutBlobId)).WillOnce(Return(true));
        EXPECT_TRUE(handler->open(session, flags, staticLayoutBlobId));
        expectedState(FirmwareBlobHandler::UpdateState::uploadInProgress);

        EXPECT_CALL(imageMock, close()).WillRepeatedly(Return());
        handler->close(session);
        expectedState(FirmwareBlobHandler::UpdateState::verificationPending);

        EXPECT_TRUE(handler->open(session, flags, verifyBlobId));
        EXPECT_CALL(*verifyMockPtr, triggerVerification())
            .WillOnce(Return(true));

        EXPECT_TRUE(handler->commit(session, {}));
        expectedState(FirmwareBlobHandler::UpdateState::verificationStarted);

        EXPECT_CALL(*verifyMockPtr, checkVerificationState())
            .WillOnce(Return(checkResponse));
        blobs::BlobMeta meta;
        EXPECT_TRUE(handler->stat(session, &meta));
        expectedState(FirmwareBlobHandler::UpdateState::verificationCompleted);
    }

    std::uint16_t session = 1;
    std::uint16_t flags =
        blobs::OpenFlags::write | FirmwareBlobHandler::UpdateFlags::ipmi;
};

/* TODO:
 * canHandleBlob(blob)
 * getBlobIds
 * deleteBlob(blob)
 *
 */

/*
 * stat(blob)
 */
TEST_F(FirmwareHandlerVerificationCompletedTest,
       StatOnActiveImageReturnsFailure)
{
    getToVerificationCompleted(VerifyCheckResponses::success);
    ASSERT_TRUE(handler->canHandleBlob(activeImageBlobId));

    blobs::BlobMeta meta;
    EXPECT_FALSE(handler->stat(activeImageBlobId, &meta));
}

TEST_F(FirmwareHandlerVerificationCompletedTest,
       VerifyActiveHashIdMissingInThisCase)
{
    /* The path taken to get to this state never opened the hash blob Id, which
     * is fine.  But let's verify it behaved as intended.
     */
    getToVerificationCompleted(VerifyCheckResponses::success);
    EXPECT_FALSE(handler->canHandleBlob(activeHashBlobId));
}

/* TODO: Add sufficient warning that you can get to verificationCompleted
 * without ever opening the image blob id (or the tarball one).
 *
 * Although in this case, it's expected that any verification triggered would
 * certainly fail.  So, although it's possible, it's uninteresting.
 */

TEST_F(FirmwareHandlerVerificationCompletedTest, StatOnVerifyBlobReturnsFailure)
{
    getToVerificationCompleted(VerifyCheckResponses::success);
    ASSERT_TRUE(handler->canHandleBlob(verifyBlobId));

    blobs::BlobMeta meta;
    EXPECT_FALSE(handler->stat(verifyBlobId, &meta));
}

TEST_F(FirmwareHandlerVerificationCompletedTest,
       StatOnNormalBlobsReturnsSuccess)
{
    getToVerificationCompleted(VerifyCheckResponses::success);

    blobs::BlobMeta expected;
    expected.blobState = FirmwareBlobHandler::UpdateFlags::ipmi;
    expected.size = 0;

    std::vector<std::string> testBlobs = {staticLayoutBlobId, hashBlobId};
    for (const auto& blob : testBlobs)
    {
        ASSERT_TRUE(handler->canHandleBlob(blob));

        blobs::BlobMeta meta = {};
        EXPECT_TRUE(handler->stat(blob, &meta));
        EXPECT_EQ(expected, meta);
    }
}

/*
 * stat(session) - the verify blobid is open in this state, so stat on that once
 * completed should have no effect.
 *
 * open(blob) - all open should fail
 *
 * close(session) - close on the verify blobid:
 *   1. if successful adds update blob id, changes state to UpdatePending
 *   2. if unsuccessful doesn't add update blob id, changes state to?
 */

/*
 * writemeta(session) - write meta should fail.
 * write(session) - write should fail.
 * read(session) - read returns empty.
 * commit(session) - ?
 */

} // namespace
} // namespace ipmi_flash
<|endoftext|>


<commit_before><commit_msg>Make debug build happy again.<commit_after><|endoftext|>


<commit_before>/*
  Copyright (c) 2014 DataStax

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
*/

#define BOOST_TEST_DYN_LINK
#ifdef STAND_ALONE
#   define BOOST_TEST_MODULE cassandra
#endif

#include "testing.hpp"

#include "cql_ccm_bridge.hpp"
#include "test_utils.hpp"

#include <boost/test/unit_test.hpp>
#include <boost/thread.hpp>
#include <boost/chrono.hpp>
#include <boost/lexical_cast.hpp>

#include <set>
#include <sstream>
#include <stdarg.h>

struct ControlConnectionTests {
  ControlConnectionTests() {}

  void check_for_live_hosts(test_utils::CassSessionPtr session,
                            const std::set<std::string>& should_be_present) {
    std::set<std::string> hosts;

    for (size_t i = 0; i < should_be_present.size() + 1; ++i) {
      CassString query = cass_string_init("SELECT * FROM system.schema_keyspaces");
      test_utils::CassStatementPtr statement(cass_statement_new(query, 0));
      test_utils::CassFuturePtr future(cass_session_execute(session.get(), statement.get()));
      BOOST_REQUIRE(cass_future_error_code(future.get()) == CASS_OK);
      hosts.insert(cass::get_host_from_future(future.get()));
    }

    BOOST_CHECK(hosts.size() == should_be_present.size());
    for (std::set<std::string>::const_iterator it = should_be_present.begin();
         it != should_be_present.end(); ++it) {
      BOOST_CHECK(hosts.count(*it) > 0);
    }
  }

  std::set<std::string> build_single_ip(const std::string& ip_prefix, int n) {
    std::set<std::string> range;
    range.insert(ip_prefix + boost::lexical_cast<std::string>(n));
    return range;
  }

  std::set<std::string> build_ip_range(const std::string& ip_prefix, int start, int end) {
    std::set<std::string> range;
    for (int i = start; i <= end; ++i) {
      range.insert(ip_prefix + boost::lexical_cast<std::string>(i));
    }
    return range;
  }
};

BOOST_FIXTURE_TEST_SUITE(control_connection, ControlConnectionTests)

BOOST_AUTO_TEST_CASE(connect_invalid_ip)
{
  boost::scoped_ptr<test_utils::LogData> log_data(new test_utils::LogData("Connection: Host 1.1.1.1 had the following error on startup: 'Connection timeout'"));

  test_utils::CassClusterPtr cluster(cass_cluster_new());
  cass_cluster_set_contact_points(cluster.get(), "1.1.1.1");
  cass_cluster_set_log_callback(cluster.get(), test_utils::count_message_log_callback, log_data.get());
  {
    test_utils::CassFuturePtr session_future(cass_cluster_connect(cluster.get()));
    CassError code = test_utils::wait_and_return_error(session_future.get());
    BOOST_CHECK_EQUAL(code, CASS_ERROR_LIB_NO_HOSTS_AVAILABLE);
  }
  BOOST_CHECK(log_data->message_count > 0);
}

BOOST_AUTO_TEST_CASE(connect_invalid_port)
{
  test_utils::CassClusterPtr cluster(cass_cluster_new());

  const cql::cql_ccm_bridge_configuration_t& conf = cql::get_ccm_bridge_configuration();
  boost::shared_ptr<cql::cql_ccm_bridge_t> ccm = cql::cql_ccm_bridge_t::create_and_start(conf, "test", 1);

  test_utils::initialize_contact_points(cluster.get(), conf.ip_prefix(), 1, 0);

  cass_cluster_set_port(cluster.get(), 9999); // Invalid port

  test_utils::CassFuturePtr session_future(cass_cluster_connect(cluster.get()));
  CassError code = test_utils::wait_and_return_error(session_future.get());

  BOOST_CHECK_EQUAL(code, CASS_ERROR_LIB_NO_HOSTS_AVAILABLE);
}

BOOST_AUTO_TEST_CASE(reconnection)
{
  test_utils::CassClusterPtr cluster(cass_cluster_new());

  const cql::cql_ccm_bridge_configuration_t& conf = cql::get_ccm_bridge_configuration();
  boost::shared_ptr<cql::cql_ccm_bridge_t> ccm = cql::cql_ccm_bridge_t::create_and_start(conf, "test", 2);

  // Ensure RR policy
  cass_cluster_set_load_balance_round_robin(cluster.get());;

  test_utils::initialize_contact_points(cluster.get(), conf.ip_prefix(), 1, 0);

  test_utils::CassSessionPtr session(test_utils::create_session(cluster.get()));

  // Stop the node of the current control connection
  ccm->stop(1);

  // Add a new node to make sure the node gets added on the new control connection to node 2
  ccm->bootstrap(3);
  boost::this_thread::sleep_for(boost::chrono::seconds(10));

  // Stop the other node
  ccm->stop(2);

  check_for_live_hosts(session, build_single_ip(conf.ip_prefix(), 3));
}

BOOST_AUTO_TEST_CASE(topology_change)
{
  test_utils::CassClusterPtr cluster(cass_cluster_new());

  const cql::cql_ccm_bridge_configuration_t& conf = cql::get_ccm_bridge_configuration();
  boost::shared_ptr<cql::cql_ccm_bridge_t> ccm = cql::cql_ccm_bridge_t::create_and_start(conf, "test", 1);

  // Ensure RR policy
  cass_cluster_set_load_balance_round_robin(cluster.get());;

  test_utils::initialize_contact_points(cluster.get(), conf.ip_prefix(), 1, 0);

  test_utils::CassSessionPtr session(test_utils::create_session(cluster.get()));

  // Adding a new node will trigger a "NEW_NODE" event
  ccm->bootstrap(2);
  boost::this_thread::sleep_for(boost::chrono::seconds(10));

  std::set<std::string> should_be_present = build_ip_range(conf.ip_prefix(), 1, 2);
  check_for_live_hosts(session, should_be_present);

  // Decommissioning a node will trigger a "REMOVED_NODE" event
  ccm->decommission(2);

  should_be_present.erase(conf.ip_prefix() + "2");
  check_for_live_hosts(session, should_be_present);
}

BOOST_AUTO_TEST_CASE(status_change)
{
  test_utils::CassClusterPtr cluster(cass_cluster_new());

  const cql::cql_ccm_bridge_configuration_t& conf = cql::get_ccm_bridge_configuration();
  boost::shared_ptr<cql::cql_ccm_bridge_t> ccm = cql::cql_ccm_bridge_t::create_and_start(conf, "test", 2);

  // Ensure RR policy
  cass_cluster_set_load_balance_round_robin(cluster.get());;

  test_utils::initialize_contact_points(cluster.get(), conf.ip_prefix(), 1, 0);

  test_utils::CassSessionPtr session(test_utils::create_session(cluster.get()));

  std::set<std::string> should_be_present = build_ip_range(conf.ip_prefix(), 1, 2);
  check_for_live_hosts(session, should_be_present);

  // Stopping a node will trigger a "DOWN" event
  ccm->stop(2);

  should_be_present.erase(conf.ip_prefix() + "2");
  check_for_live_hosts(session, should_be_present);

  // Starting a node will trigger an "UP" event
  ccm->start(2);
  boost::this_thread::sleep_for(boost::chrono::seconds(10));

  should_be_present.insert(conf.ip_prefix() + "2");
  check_for_live_hosts(session, should_be_present);
}

BOOST_AUTO_TEST_CASE(node_discovery)
{
  test_utils::CassClusterPtr cluster(cass_cluster_new());

  const cql::cql_ccm_bridge_configuration_t& conf = cql::get_ccm_bridge_configuration();
  boost::shared_ptr<cql::cql_ccm_bridge_t> ccm = cql::cql_ccm_bridge_t::create_and_start(conf, "test", 3);

  // Ensure RR policy
  cass_cluster_set_load_balance_round_robin(cluster.get());;

  // Only add a single IP
  test_utils::initialize_contact_points(cluster.get(), conf.ip_prefix(), 1, 0);

  test_utils::CassSessionPtr session(test_utils::create_session(cluster.get()));

  check_for_live_hosts(session, build_ip_range(conf.ip_prefix(), 1, 3));
}

BOOST_AUTO_TEST_CASE(node_discovery_invalid_ips)
{
  boost::scoped_ptr<test_utils::LogData> log_data(new test_utils::LogData("Unable to reach contact point 192.0.2."));

  {
    test_utils::CassClusterPtr cluster(cass_cluster_new());

    const cql::cql_ccm_bridge_configuration_t& conf = cql::get_ccm_bridge_configuration();
    boost::shared_ptr<cql::cql_ccm_bridge_t> ccm = cql::cql_ccm_bridge_t::create_and_start(conf, "test", 3);

    cass_cluster_set_log_callback(cluster.get(), test_utils::count_message_log_callback, log_data.get());

    // Ensure RR policy
    cass_cluster_set_load_balance_round_robin(cluster.get());;

    // Add invalid IPs first (http://tools.ietf.org/html/rfc5737)
    cass_cluster_set_contact_points(cluster.get(), "192.0.2.0,192.0.2.1,192.0.2.3");

    // Only add a single valid IP
    test_utils::initialize_contact_points(cluster.get(), conf.ip_prefix(), 1, 0);

    test_utils::CassSessionPtr session(test_utils::create_session(cluster.get()));

    check_for_live_hosts(session, build_ip_range(conf.ip_prefix(), 1, 3));
  }

  BOOST_CHECK_EQUAL(log_data->message_count, 3ul);
}

BOOST_AUTO_TEST_CASE(node_discovery_no_local_rows)
{
  test_utils::CassClusterPtr cluster(cass_cluster_new());

  const cql::cql_ccm_bridge_configuration_t& conf = cql::get_ccm_bridge_configuration();
  boost::shared_ptr<cql::cql_ccm_bridge_t> ccm = cql::cql_ccm_bridge_t::create_and_start(conf, "test", 3);

  // Ensure RR policy
  cass_cluster_set_load_balance_round_robin(cluster.get());;

  // Only add a single valid IP
  test_utils::initialize_contact_points(cluster.get(), conf.ip_prefix(), 1, 0);

  {
    test_utils::CassSessionPtr session(test_utils::create_session(cluster.get()));
    test_utils::execute_query(session.get(), "DELETE FROM system.local WHERE key = 'local'");
  }

  test_utils::CassSessionPtr session(test_utils::create_session(cluster.get()));

  check_for_live_hosts(session, build_ip_range(conf.ip_prefix(), 1, 3));
}

BOOST_AUTO_TEST_CASE(node_discovery_no_rpc_addresss)
{
  boost::scoped_ptr<test_utils::LogData> log_data(new test_utils::LogData("No rpc_address for host 127.0.0.3 in system.peers on 127.0.0.1. Ignoring this entry."));

  {
    test_utils::CassClusterPtr cluster(cass_cluster_new());

    const cql::cql_ccm_bridge_configuration_t& conf = cql::get_ccm_bridge_configuration();
    boost::shared_ptr<cql::cql_ccm_bridge_t> ccm = cql::cql_ccm_bridge_t::create_and_start(conf, "test", 3);

    cass_cluster_set_log_callback(cluster.get(), test_utils::count_message_log_callback, log_data.get());

    // Ensure RR policy
    cass_cluster_set_load_balance_round_robin(cluster.get());;

    // Only add a single valid IP
    test_utils::initialize_contact_points(cluster.get(), conf.ip_prefix(), 1, 0);

    {
      test_utils::CassSessionPtr session(test_utils::create_session(cluster.get()));
      std::ostringstream ss;
      ss << "UPDATE system.peers SET rpc_address = null WHERE peer = '" << conf.ip_prefix() << "3'";
      test_utils::execute_query(session.get(), ss.str());
    }

    test_utils::CassSessionPtr session(test_utils::create_session(cluster.get()));

    // This should only contain 2 address because one peer is ignored
    check_for_live_hosts(session, build_ip_range(conf.ip_prefix(), 1, 2));
  }

  BOOST_CHECK(log_data->message_count > 0);
}

BOOST_AUTO_TEST_CASE(full_outage)
{
  test_utils::CassClusterPtr cluster(cass_cluster_new());

  const char* query = "SELECT * FROM system.local";

  const cql::cql_ccm_bridge_configuration_t& conf = cql::get_ccm_bridge_configuration();
  boost::shared_ptr<cql::cql_ccm_bridge_t> ccm = cql::cql_ccm_bridge_t::create_and_start(conf, "test", 1);

  test_utils::initialize_contact_points(cluster.get(), conf.ip_prefix(), 1, 0);
  test_utils::CassSessionPtr session(test_utils::create_session(cluster.get()));
  test_utils::execute_query(session.get(), query);

  ccm->stop();
  BOOST_CHECK(test_utils::execute_query_with_error(session.get(), query) == CASS_ERROR_LIB_NO_HOSTS_AVAILABLE);

  ccm->start();

  boost::this_thread::sleep_for(boost::chrono::seconds(10));

  test_utils::execute_query(session.get(), query);
}

BOOST_AUTO_TEST_SUITE_END()
<commit_msg>Fixed control connection integration test<commit_after>/*
  Copyright (c) 2014 DataStax

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
*/

#define BOOST_TEST_DYN_LINK
#ifdef STAND_ALONE
#   define BOOST_TEST_MODULE cassandra
#endif

#include "testing.hpp"

#include "cql_ccm_bridge.hpp"
#include "test_utils.hpp"

#include <boost/test/unit_test.hpp>
#include <boost/thread.hpp>
#include <boost/chrono.hpp>
#include <boost/lexical_cast.hpp>

#include <set>
#include <sstream>
#include <stdarg.h>

struct ControlConnectionTests {
  ControlConnectionTests() {}

  void check_for_live_hosts(test_utils::CassSessionPtr session,
                            const std::set<std::string>& should_be_present) {
    std::set<std::string> hosts;

    for (size_t i = 0; i < should_be_present.size() + 1; ++i) {
      CassString query = cass_string_init("SELECT * FROM system.schema_keyspaces");
      test_utils::CassStatementPtr statement(cass_statement_new(query, 0));
      test_utils::CassFuturePtr future(cass_session_execute(session.get(), statement.get()));
      BOOST_REQUIRE(cass_future_error_code(future.get()) == CASS_OK);
      hosts.insert(cass::get_host_from_future(future.get()));
    }

    BOOST_CHECK(hosts.size() == should_be_present.size());
    for (std::set<std::string>::const_iterator it = should_be_present.begin();
         it != should_be_present.end(); ++it) {
      BOOST_CHECK(hosts.count(*it) > 0);
    }
  }

  std::set<std::string> build_single_ip(const std::string& ip_prefix, int n) {
    std::set<std::string> range;
    range.insert(ip_prefix + boost::lexical_cast<std::string>(n));
    return range;
  }

  std::set<std::string> build_ip_range(const std::string& ip_prefix, int start, int end) {
    std::set<std::string> range;
    for (int i = start; i <= end; ++i) {
      range.insert(ip_prefix + boost::lexical_cast<std::string>(i));
    }
    return range;
  }
};

BOOST_FIXTURE_TEST_SUITE(control_connection, ControlConnectionTests)

BOOST_AUTO_TEST_CASE(connect_invalid_ip)
{
  boost::scoped_ptr<test_utils::LogData> log_data(new test_utils::LogData("Connection: Host 1.1.1.1 had the following error on startup: 'Connection timeout'"));

  test_utils::CassClusterPtr cluster(cass_cluster_new());
  cass_cluster_set_contact_points(cluster.get(), "1.1.1.1");
  cass_cluster_set_log_callback(cluster.get(), test_utils::count_message_log_callback, log_data.get());
  {
    test_utils::CassFuturePtr session_future(cass_cluster_connect(cluster.get()));
    CassError code = test_utils::wait_and_return_error(session_future.get());
    BOOST_CHECK_EQUAL(code, CASS_ERROR_LIB_NO_HOSTS_AVAILABLE);
  }
  BOOST_CHECK(log_data->message_count > 0);
}

BOOST_AUTO_TEST_CASE(connect_invalid_port)
{
  test_utils::CassClusterPtr cluster(cass_cluster_new());

  const cql::cql_ccm_bridge_configuration_t& conf = cql::get_ccm_bridge_configuration();
  boost::shared_ptr<cql::cql_ccm_bridge_t> ccm = cql::cql_ccm_bridge_t::create_and_start(conf, "test", 1);

  test_utils::initialize_contact_points(cluster.get(), conf.ip_prefix(), 1, 0);

  cass_cluster_set_port(cluster.get(), 9999); // Invalid port

  test_utils::CassFuturePtr session_future(cass_cluster_connect(cluster.get()));
  CassError code = test_utils::wait_and_return_error(session_future.get());

  BOOST_CHECK_EQUAL(code, CASS_ERROR_LIB_NO_HOSTS_AVAILABLE);
}

BOOST_AUTO_TEST_CASE(reconnection)
{
  test_utils::CassClusterPtr cluster(cass_cluster_new());

  const cql::cql_ccm_bridge_configuration_t& conf = cql::get_ccm_bridge_configuration();
  boost::shared_ptr<cql::cql_ccm_bridge_t> ccm = cql::cql_ccm_bridge_t::create_and_start(conf, "test", 2);

  // Ensure RR policy
  cass_cluster_set_load_balance_round_robin(cluster.get());

  test_utils::initialize_contact_points(cluster.get(), conf.ip_prefix(), 1, 0);

  test_utils::CassSessionPtr session(test_utils::create_session(cluster.get()));

  // Stop the node of the current control connection
  ccm->stop(1);

  // Add a new node to make sure the node gets added on the new control connection to node 2
  ccm->add_node(3);
   // Allow this node to come up without node1
  ccm->start(3, "-Dcassandra.consistent.rangemovement=false");
  boost::this_thread::sleep_for(boost::chrono::seconds(10));

  // Stop the other node
  ccm->stop(2);

  check_for_live_hosts(session, build_single_ip(conf.ip_prefix(), 3));
}

BOOST_AUTO_TEST_CASE(topology_change)
{
  test_utils::CassClusterPtr cluster(cass_cluster_new());

  const cql::cql_ccm_bridge_configuration_t& conf = cql::get_ccm_bridge_configuration();
  boost::shared_ptr<cql::cql_ccm_bridge_t> ccm = cql::cql_ccm_bridge_t::create_and_start(conf, "test", 1);

  // Ensure RR policy
  cass_cluster_set_load_balance_round_robin(cluster.get());;

  test_utils::initialize_contact_points(cluster.get(), conf.ip_prefix(), 1, 0);

  test_utils::CassSessionPtr session(test_utils::create_session(cluster.get()));

  // Adding a new node will trigger a "NEW_NODE" event
  ccm->bootstrap(2);
  boost::this_thread::sleep_for(boost::chrono::seconds(10));

  std::set<std::string> should_be_present = build_ip_range(conf.ip_prefix(), 1, 2);
  check_for_live_hosts(session, should_be_present);

  // Decommissioning a node will trigger a "REMOVED_NODE" event
  ccm->decommission(2);

  should_be_present.erase(conf.ip_prefix() + "2");
  check_for_live_hosts(session, should_be_present);
}

BOOST_AUTO_TEST_CASE(status_change)
{
  test_utils::CassClusterPtr cluster(cass_cluster_new());

  const cql::cql_ccm_bridge_configuration_t& conf = cql::get_ccm_bridge_configuration();
  boost::shared_ptr<cql::cql_ccm_bridge_t> ccm = cql::cql_ccm_bridge_t::create_and_start(conf, "test", 2);

  // Ensure RR policy
  cass_cluster_set_load_balance_round_robin(cluster.get());;

  test_utils::initialize_contact_points(cluster.get(), conf.ip_prefix(), 1, 0);

  test_utils::CassSessionPtr session(test_utils::create_session(cluster.get()));

  std::set<std::string> should_be_present = build_ip_range(conf.ip_prefix(), 1, 2);
  check_for_live_hosts(session, should_be_present);

  // Stopping a node will trigger a "DOWN" event
  ccm->stop(2);

  should_be_present.erase(conf.ip_prefix() + "2");
  check_for_live_hosts(session, should_be_present);

  // Starting a node will trigger an "UP" event
  ccm->start(2);
  boost::this_thread::sleep_for(boost::chrono::seconds(10));

  should_be_present.insert(conf.ip_prefix() + "2");
  check_for_live_hosts(session, should_be_present);
}

BOOST_AUTO_TEST_CASE(node_discovery)
{
  test_utils::CassClusterPtr cluster(cass_cluster_new());

  const cql::cql_ccm_bridge_configuration_t& conf = cql::get_ccm_bridge_configuration();
  boost::shared_ptr<cql::cql_ccm_bridge_t> ccm = cql::cql_ccm_bridge_t::create_and_start(conf, "test", 3);

  // Ensure RR policy
  cass_cluster_set_load_balance_round_robin(cluster.get());;

  // Only add a single IP
  test_utils::initialize_contact_points(cluster.get(), conf.ip_prefix(), 1, 0);

  test_utils::CassSessionPtr session(test_utils::create_session(cluster.get()));

  check_for_live_hosts(session, build_ip_range(conf.ip_prefix(), 1, 3));
}

BOOST_AUTO_TEST_CASE(node_discovery_invalid_ips)
{
  boost::scoped_ptr<test_utils::LogData> log_data(new test_utils::LogData("Unable to reach contact point 192.0.2."));

  {
    test_utils::CassClusterPtr cluster(cass_cluster_new());

    const cql::cql_ccm_bridge_configuration_t& conf = cql::get_ccm_bridge_configuration();
    boost::shared_ptr<cql::cql_ccm_bridge_t> ccm = cql::cql_ccm_bridge_t::create_and_start(conf, "test", 3);

    cass_cluster_set_log_callback(cluster.get(), test_utils::count_message_log_callback, log_data.get());

    // Ensure RR policy
    cass_cluster_set_load_balance_round_robin(cluster.get());;

    // Add invalid IPs first (http://tools.ietf.org/html/rfc5737)
    cass_cluster_set_contact_points(cluster.get(), "192.0.2.0,192.0.2.1,192.0.2.3");

    // Only add a single valid IP
    test_utils::initialize_contact_points(cluster.get(), conf.ip_prefix(), 1, 0);

    test_utils::CassSessionPtr session(test_utils::create_session(cluster.get()));

    check_for_live_hosts(session, build_ip_range(conf.ip_prefix(), 1, 3));
  }

  BOOST_CHECK_EQUAL(log_data->message_count, 3ul);
}

BOOST_AUTO_TEST_CASE(node_discovery_no_local_rows)
{
  test_utils::CassClusterPtr cluster(cass_cluster_new());

  const cql::cql_ccm_bridge_configuration_t& conf = cql::get_ccm_bridge_configuration();
  boost::shared_ptr<cql::cql_ccm_bridge_t> ccm = cql::cql_ccm_bridge_t::create_and_start(conf, "test", 3);

  // Ensure RR policy
  cass_cluster_set_load_balance_round_robin(cluster.get());;

  // Only add a single valid IP
  test_utils::initialize_contact_points(cluster.get(), conf.ip_prefix(), 1, 0);

  {
    test_utils::CassSessionPtr session(test_utils::create_session(cluster.get()));
    test_utils::execute_query(session.get(), "DELETE FROM system.local WHERE key = 'local'");
  }

  test_utils::CassSessionPtr session(test_utils::create_session(cluster.get()));

  check_for_live_hosts(session, build_ip_range(conf.ip_prefix(), 1, 3));
}

BOOST_AUTO_TEST_CASE(node_discovery_no_rpc_addresss)
{
  boost::scoped_ptr<test_utils::LogData> log_data(new test_utils::LogData("No rpc_address for host 127.0.0.3 in system.peers on 127.0.0.1. Ignoring this entry."));

  {
    test_utils::CassClusterPtr cluster(cass_cluster_new());

    const cql::cql_ccm_bridge_configuration_t& conf = cql::get_ccm_bridge_configuration();
    boost::shared_ptr<cql::cql_ccm_bridge_t> ccm = cql::cql_ccm_bridge_t::create_and_start(conf, "test", 3);

    cass_cluster_set_log_callback(cluster.get(), test_utils::count_message_log_callback, log_data.get());

    // Ensure RR policy
    cass_cluster_set_load_balance_round_robin(cluster.get());;

    // Only add a single valid IP
    test_utils::initialize_contact_points(cluster.get(), conf.ip_prefix(), 1, 0);

    {
      test_utils::CassSessionPtr session(test_utils::create_session(cluster.get()));
      std::ostringstream ss;
      ss << "UPDATE system.peers SET rpc_address = null WHERE peer = '" << conf.ip_prefix() << "3'";
      test_utils::execute_query(session.get(), ss.str());
    }

    test_utils::CassSessionPtr session(test_utils::create_session(cluster.get()));

    // This should only contain 2 address because one peer is ignored
    check_for_live_hosts(session, build_ip_range(conf.ip_prefix(), 1, 2));
  }

  BOOST_CHECK(log_data->message_count > 0);
}

BOOST_AUTO_TEST_CASE(full_outage)
{
  test_utils::CassClusterPtr cluster(cass_cluster_new());

  const char* query = "SELECT * FROM system.local";

  const cql::cql_ccm_bridge_configuration_t& conf = cql::get_ccm_bridge_configuration();
  boost::shared_ptr<cql::cql_ccm_bridge_t> ccm = cql::cql_ccm_bridge_t::create_and_start(conf, "test", 1);

  test_utils::initialize_contact_points(cluster.get(), conf.ip_prefix(), 1, 0);
  test_utils::CassSessionPtr session(test_utils::create_session(cluster.get()));
  test_utils::execute_query(session.get(), query);

  ccm->stop();
  BOOST_CHECK(test_utils::execute_query_with_error(session.get(), query) == CASS_ERROR_LIB_NO_HOSTS_AVAILABLE);

  ccm->start();

  boost::this_thread::sleep_for(boost::chrono::seconds(10));

  test_utils::execute_query(session.get(), query);
}

BOOST_AUTO_TEST_SUITE_END()
<|endoftext|>


<commit_before>/*
===============================================================================

  FILE:  mydefs.hpp

  CONTENTS:

    Basic data type definitions to be robust across platforms.

  PROGRAMMERS:

    martin.isenburg@gmail.com

  COPYRIGHT:

    (c) 2005-2011, Martin Isenburg, LASSO - tools to catch reality

    This is free software; you can redistribute and/or modify it under the
    terms of the GNU Lesser General Licence as published by the Free Software
    Foundation. See the COPYING file for more information.

    This software is distributed WITHOUT ANY WARRANTY and without even the
    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

  CHANGE HISTORY:

    10 January 2011 -- licensing change for LGPL release and liblas integration
    13 July 2005 -- created after returning with many mosquito bites from OBX

===============================================================================
*/
#ifndef MYDEFS_HPP
#define MYDEFS_HPP

typedef int                I32;
typedef short              I16;
typedef char               I8;

typedef unsigned int       U32;
typedef unsigned short     U16;
typedef unsigned char      U8;

#if defined(_WIN32)            // 64 byte integer under Windows
typedef unsigned __int64   U64;
typedef __int64            I64;
#else                          // 64 byte integer elsewhere ...
typedef unsigned long long U64;
typedef long long          I64;
#endif

typedef float              F32;
typedef double             F64;

#if defined(_MSC_VER) && (_MSC_VER < 1300)
typedef int                BOOL;
#else
typedef bool               BOOL;
#endif

typedef union U32I32F32 { U32 u32; I32 i32; F32 f32; } U32I32F32;
typedef union U64I64F64 { U64 u64; I64 i64; F64 f64; } U64I64F64;

#define F32_MAX            +1.0e+30f
#define F32_MIN            -1.0e+30f

#define U8_MIN             ((U8)0x0)  // 0
#define U8_MAX             ((U8)0xFF) // 255
#define U8_MAX_PLUS_ONE    0x0100     // 256

#define U16_MIN            ((U16)0x0)    // 0
#define U16_MAX            ((U16)0xFFFF) // 65535
#define U16_MAX_PLUS_ONE   0x00010000    // 65536

#define U32_MIN            ((U32)0x0)            // 0
#define U32_MAX            ((U32)0xFFFFFFFF)     // 4294967295
#if defined(WIN32)            // 64 byte unsigned int constant under Windows
#define U32_MAX_PLUS_ONE   0x0000000100000000    // 4294967296
#else                         // 64 byte unsigned int constant elsewhere ...
#define U32_MAX_PLUS_ONE   0x0000000100000000ull // 4294967296
#endif

#define I8_MIN             ((I8)0x80) // -128
#define I8_MAX             ((I8)0x7F) // 127

#define I16_MIN            ((I16)0x8000) // -32768
#define I16_MAX            ((I16)0x7FFF) // 32767

#define I32_MIN            ((I32)0x80000000) // -2147483648
#define I32_MAX            ((I32)0x7FFFFFFF) //  2147483647

#define I8_CLAMP(n)     ((n <= I8_MIN) ? I8_MIN : ((n >= I8_MAX) ? I8_MAX : ((I8)n)))
#define U8_CLAMP(n)     ((n <= U8_MIN) ? U8_MIN : ((n >= U8_MAX) ? U8_MAX : ((U8)n)))

#define I16_CLAMP(n)    ((n <= I16_MIN) ? I16_MIN : ((n >= I16_MAX) ? I16_MAX : ((I16)n)))
#define U16_CLAMP(n)    ((n <= U16_MIN) ? U16_MIN : ((n >= U16_MAX) ? U16_MAX : ((U16)n)))

#define I32_CLAMP(n)    ((n <= I32_MIN) ? I32_MIN : ((n >= I32_MAX) ? I32_MAX : ((I32)n)))
#define U32_CLAMP(n)    ((n <= U32_MIN) ? U32_MIN : ((n >= U32_MAX) ? U32_MAX : ((U32)n)))

#ifndef FALSE
#define FALSE   0
#endif

#ifndef TRUE
#define TRUE    1
#endif

#ifndef NULL
#define NULL    0
#endif

inline BOOL IS_LITTLE_ENDIAN()
{
  const U32 i = 1;
  return (*((U8*)&i) == 1);
}

#define ENDIANSWAP16(n) \
	( ((((U16) n) << 8) & 0xFF00) | \
	  ((((U16) n) >> 8) & 0x00FF) )

#define ENDIANSWAP32(n) \
	( ((((U32) n) << 24) & 0xFF000000) |	\
	  ((((U32) n) <<  8) & 0x00FF0000) |	\
	  ((((U32) n) >>  8) & 0x0000FF00) |	\
	  ((((U32) n) >> 24) & 0x000000FF) )

inline void ENDIAN_SWAP_16(U8* field)
{
  U8 help = field[0];
  field[0] = field[1];
  field[1] = help;
}

inline void ENDIAN_SWAP_32(U8* field)
{
  U8 help;
  help = field[0];
  field[0] = field[3];
  field[3] = help;
  help = field[1];
  field[1] = field[2];
  field[2] = help;
}

inline void ENDIAN_SWAP_64(U8* field)
{
  U8 help;
  help = field[0];
  field[0] = field[7];
  field[7] = help;
  help = field[1];
  field[1] = field[6];
  field[6] = help;
  help = field[2];
  field[2] = field[5];
  field[5] = help;
  help = field[3];
  field[3] = field[4];
  field[4] = help;
}

inline void ENDIAN_SWAP_16(const U8* from, U8* to)
{
  to[0] = from[1];
  to[1] = from[0];
}

inline void ENDIAN_SWAP_32(const U8* from, U8* to)
{
  to[0] = from[3];
  to[1] = from[2];
  to[2] = from[1];
  to[3] = from[0];
}

inline void ENDIAN_SWAP_64(const U8* from, U8* to)
{
  to[0] = from[7];
  to[1] = from[6];
  to[2] = from[5];
  to[3] = from[4];
  to[4] = from[3];
  to[5] = from[2];
  to[6] = from[1];
  to[7] = from[0];
}

#endif
<commit_msg>i always forget one<commit_after>/*
===============================================================================

  FILE:  mydefs.hpp

  CONTENTS:

    Basic data type definitions to be robust across platforms.

  PROGRAMMERS:

    martin.isenburg@gmail.com

  COPYRIGHT:

    (c) 2005-2011, Martin Isenburg, LASSO - tools to catch reality

    This is free software; you can redistribute and/or modify it under the
    terms of the GNU Lesser General Licence as published by the Free Software
    Foundation. See the COPYING file for more information.

    This software is distributed WITHOUT ANY WARRANTY and without even the
    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

  CHANGE HISTORY:

    10 January 2011 -- licensing change for LGPL release and liblas integration
    13 July 2005 -- created after returning with many mosquito bites from OBX

===============================================================================
*/
#ifndef MYDEFS_HPP
#define MYDEFS_HPP

typedef int                I32;
typedef short              I16;
typedef char               I8;

typedef unsigned int       U32;
typedef unsigned short     U16;
typedef unsigned char      U8;

#if defined(_WIN32)            // 64 byte integer under Windows
typedef unsigned __int64   U64;
typedef __int64            I64;
#else                          // 64 byte integer elsewhere ...
typedef unsigned long long U64;
typedef long long          I64;
#endif

typedef float              F32;
typedef double             F64;

#if defined(_MSC_VER) && (_MSC_VER < 1300)
typedef int                BOOL;
#else
typedef bool               BOOL;
#endif

typedef union U32I32F32 { U32 u32; I32 i32; F32 f32; } U32I32F32;
typedef union U64I64F64 { U64 u64; I64 i64; F64 f64; } U64I64F64;

#define F32_MAX            +2.0e+37f
#define F32_MIN            -2.0e+37f

#define U8_MIN             ((U8)0x0)  // 0
#define U8_MAX             ((U8)0xFF) // 255
#define U8_MAX_PLUS_ONE    0x0100     // 256

#define U16_MIN            ((U16)0x0)    // 0
#define U16_MAX            ((U16)0xFFFF) // 65535
#define U16_MAX_PLUS_ONE   0x00010000    // 65536

#define U32_MIN            ((U32)0x0)            // 0
#define U32_MAX            ((U32)0xFFFFFFFF)     // 4294967295
#if defined(WIN32)            // 64 byte unsigned int constant under Windows
#define U32_MAX_PLUS_ONE   0x0000000100000000    // 4294967296
#else                         // 64 byte unsigned int constant elsewhere ...
#define U32_MAX_PLUS_ONE   0x0000000100000000ull // 4294967296
#endif

#define I8_MIN             ((I8)0x80) // -128
#define I8_MAX             ((I8)0x7F) // 127

#define I16_MIN            ((I16)0x8000) // -32768
#define I16_MAX            ((I16)0x7FFF) // 32767

#define I32_MIN            ((I32)0x80000000) // -2147483648
#define I32_MAX            ((I32)0x7FFFFFFF) //  2147483647

#define U8_FOLD(n)      (((n) < U8_MIN) ? (n+U8_MAX_PLUS_ONE) : (((n) > U8_MAX) ? (n-U8_MAX_PLUS_ONE) : (n)))

#define I8_CLAMP(n)     (((n) <= I8_MIN) ? I8_MIN : (((n) >= I8_MAX) ? I8_MAX : ((I8)(n))))
#define U8_CLAMP(n)     (((n) <= U8_MIN) ? U8_MIN : (((n) >= U8_MAX) ? U8_MAX : ((U8)(n))))

#define I16_CLAMP(n)    (((n) <= I16_MIN) ? I16_MIN : (((n) >= I16_MAX) ? I16_MAX : ((I16)(n))))
#define U16_CLAMP(n)    (((n) <= U16_MIN) ? U16_MIN : (((n) >= U16_MAX) ? U16_MAX : ((U16)(n))))

#define I32_CLAMP(n)    (((n) <= I32_MIN) ? I32_MIN : (((n) >= I32_MAX) ? I32_MAX : ((I32)(n))))
#define U32_CLAMP(n)    (((n) <= U32_MIN) ? U32_MIN : (((n) >= U32_MAX) ? U32_MAX : ((U32)(n))))

#define I16_QUANTIZE(n) (((n) >= 0) ? (I16)((n)+0.5f) : (I16)((n)-0.5f))
#define U16_QUANTIZE(n) (((n) >= 0) ? (U16)((n)+0.5f) : (U16)(0))

#define I32_QUANTIZE(n) (((n) >= 0) ? (I32)((n)+0.5f) : (I32)((n)-0.5f))
#define U32_QUANTIZE(n) (((n) >= 0) ? (U32)((n)+0.5f) : (U32)(0))

#define I16_FLOOR(n) ((((I16)(n)) < (n)) ? (I16)(n) : (((I16)(n))-1))
#define I32_FLOOR(n) ((((I32)(n)) < (n)) ? (I32)(n) : (((I32)(n))-1))
#define I64_FLOOR(n) ((((I64)(n)) < (n)) ? (I64)(n) : (((I64)(n))-1))

#define I16_CEIL(n) ((((I16)(n)) > (n)) ? (I16)(n) : (((I16)(n))+1))
#define I32_CEIL(n) ((((I32)(n)) > (n)) ? (I32)(n) : (((I32)(n))+1))
#define I64_CEIL(n) ((((I64)(n)) > (n)) ? (I64)(n) : (((I64)(n))+1))

#define U32_ZERO_BIT_0(n) (((n)&(U32)0xFFFFFFFE))

#ifndef FALSE
#define FALSE   0
#endif

#ifndef TRUE
#define TRUE    1
#endif

#ifndef NULL
#define NULL    0
#endif

inline BOOL IS_LITTLE_ENDIAN()
{
  const U32 i = 1;
  return (*((U8*)&i) == 1);
}

#define ENDIANSWAP16(n) \
	( ((((U16) n) << 8) & 0xFF00) | \
	  ((((U16) n) >> 8) & 0x00FF) )

#define ENDIANSWAP32(n) \
	( ((((U32) n) << 24) & 0xFF000000) |	\
	  ((((U32) n) <<  8) & 0x00FF0000) |	\
	  ((((U32) n) >>  8) & 0x0000FF00) |	\
	  ((((U32) n) >> 24) & 0x000000FF) )

inline void ENDIAN_SWAP_16(U8* field)
{
  U8 help = field[0];
  field[0] = field[1];
  field[1] = help;
}

inline void ENDIAN_SWAP_32(U8* field)
{
  U8 help;
  help = field[0];
  field[0] = field[3];
  field[3] = help;
  help = field[1];
  field[1] = field[2];
  field[2] = help;
}

inline void ENDIAN_SWAP_64(U8* field)
{
  U8 help;
  help = field[0];
  field[0] = field[7];
  field[7] = help;
  help = field[1];
  field[1] = field[6];
  field[6] = help;
  help = field[2];
  field[2] = field[5];
  field[5] = help;
  help = field[3];
  field[3] = field[4];
  field[4] = help;
}

inline void ENDIAN_SWAP_16(const U8* from, U8* to)
{
  to[0] = from[1];
  to[1] = from[0];
}

inline void ENDIAN_SWAP_32(const U8* from, U8* to)
{
  to[0] = from[3];
  to[1] = from[2];
  to[2] = from[1];
  to[3] = from[0];
}

inline void ENDIAN_SWAP_64(const U8* from, U8* to)
{
  to[0] = from[7];
  to[1] = from[6];
  to[2] = from[5];
  to[3] = from[4];
  to[4] = from[3];
  to[5] = from[2];
  to[6] = from[1];
  to[7] = from[0];
}

#endif
<|endoftext|>


<commit_before>/* -*- mode: C++; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
// vim:sts=4:sw=4:ts=4:noet:sr:cino=>s,f0,{0,g0,(0,\:0,t0,+0,=s

/*
 * Copyright (C) 2016 FFLAS-FFPACK group.
 *
 * Written by Clément Pernet <clement.pernet@imag.fr>
 *
 *
 * ========LICENCE========
 * This file is part of the library FFLAS-FFPACK.
 *
 * FFLAS-FFPACK is free software: you can redistribute it and/or modify
 * it under the terms of the  GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 * ========LICENCE========
 *
 */

#include "fflas-ffpack/fflas-ffpack-config.h"
#include "fflas-ffpack/utils/fflas_randommatrix.h"
#include <iostream>
#include <givaro/modular-balanced.h>
#include "fflas-ffpack/utils/timer.h"
#include "fflas-ffpack/ffpack/ffpack.h"

#ifdef __GIVARO_USE_OPENMP
typedef Givaro::OMPTimer TTimer;
#else
typedef Givaro::Timer TTimer;
#endif

#include <ctime>
#define CUBE(x) ((x)*(x)*(x))
#define GFOPS(m,n,r,t) (2.0/3.0*CUBE(double(n)/1000.0) +2*m/1000.0*n/1000.0*double(r)/1000.0  - double(r)/1000.0*double(r)/1000.0*(m+n)/1000)/t

int main () {
	using namespace std;

	typedef Givaro::ModularBalanced<double> Field;
	Field F(131071);
	typedef Field::Element Element ;
	size_t n=128, nmax=1000, prec=64, nbest=0, count=0;
	TTimer chrono,tim;
	bool bound=false;

	Element * A = FFLAS::fflas_new (F, nmax, nmax);
	Element * B = FFLAS::fflas_new (F, nmax, nmax);
	size_t lda = nmax;
	size_t r;
	size_t * P = new size_t[nmax];
	size_t * Q = new size_t[nmax];
	FFPACK::RandomMatrix (F, A, nmax, nmax, nmax);
	FFLAS::fassign (F, nmax,nmax, A, nmax, B, nmax);
	time_t result = std::time(NULL);
	cout << std::endl
		  << "---------------------------------------------------------------------"
		  << std::endl << std::asctime(std::localtime(&result))
		  << std::endl
		  << "Threshold for PLUQ base case" ;
	F.write(cout << " (using ") << ')' << endl << endl;

	cout << "PLUQ:  n                   Base case                        Recursive 1 level" << std::endl;
	cout << "                    seconds            Gfops          seconds            Gfops" << std::endl;
		do {
		double BCTime, RecTime;
		int iter=10;
			//Element * A = FFLAS::fflas_new (F, n, n);
			//Element * B = FFLAS::fflas_new (F, n, n);
			// size_t r;
			//size_t * P = new size_t[n];
			//size_t * Q = new size_t[n];
			//FFPACK::RandomMatrix (F, A, n, n, n);
			//FFLAS::fassign (F, n, n, A, n, B, n);
			//size_t lda=n;
	    //warm up computation
		r=FFPACK::PLUQ_basecaseCrout (F, FFLAS::FflasNonUnit, n, n, A, lda, P, Q);
		FFLAS::fassign (F, n, n, B, lda, A, lda);
		chrono.clear();tim.clear();
		for (int i=0;i<iter;i++){
			chrono.start();
			r=FFPACK::PLUQ_basecaseCrout (F, FFLAS::FflasNonUnit, n, n, A, lda, P, Q);
			chrono.stop();
			tim+=chrono;
			FFLAS::fassign (F, n, n, B, lda, A, lda);
		}
		BCTime = tim.realtime()/iter;

		tim.clear();chrono.clear();
		for (int i=0;i<iter;i++){
			chrono.start();
			r=FFPACK::_PLUQ (F, FFLAS::FflasNonUnit, n, n, A, lda, P, Q, n);
			chrono.stop();
			tim+=chrono;
			FFLAS::fassign (F, n, n, B, lda, A, lda);
		}
			//FFLAS::fflas_delete(A);
			//FFLAS::fflas_delete(B);
		RecTime = tim.realtime()/iter;

		cout << "      ";
		cout.width(4);
		cout << n;
		cout << "  ";
		cout.width(15);
		cout << BCTime;
		cout << "  ";
		cout.width(15);
		cout << GFOPS(n,n,r, BCTime) << "  ";
		cout.width(15);
		cout << RecTime;
		cout << "  ";
		cout.width(15);
		cout << GFOPS(n,n,r, RecTime) << endl;

		if (BCTime > RecTime){
			count++;
			if (count > 1){
				nbest = n;
				bound = true;
				prec = prec >> 1;
				n -= prec;
			}
		}
		else{
			count=0;
			if (bound)
				prec=prec>>1;
			n+=prec;
		}
	} while ((prec > 4 ) && (n < nmax));

	cout<<endl;
	if (nbest != 0 ) {
		cerr << "#ifndef __FFLASFFPACK_PLUQ_THRESHOLD"  << endl;
		cerr << "#define __FFLASFFPACK_PLUQ_THRESHOLD" << ' ' <<  nbest << endl;
		cout << "defined __FFLASFFPACK_PLUQ_THRESHOLD to " << nbest << "" << std::endl;
		std::cerr << "#endif" << endl  << endl;
	}
	FFLAS::fflas_delete(A);
	FFLAS::fflas_delete(B);

	return 0;
}
<commit_msg>update autotuner's pluq.C to the new RandomMatrix interface<commit_after>/* -*- mode: C++; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
// vim:sts=4:sw=4:ts=4:noet:sr:cino=>s,f0,{0,g0,(0,\:0,t0,+0,=s

/*
 * Copyright (C) 2016 FFLAS-FFPACK group.
 *
 * Written by Clément Pernet <clement.pernet@imag.fr>
 *
 *
 * ========LICENCE========
 * This file is part of the library FFLAS-FFPACK.
 *
 * FFLAS-FFPACK is free software: you can redistribute it and/or modify
 * it under the terms of the  GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 * ========LICENCE========
 *
 */

#include "fflas-ffpack/fflas-ffpack-config.h"
#include "fflas-ffpack/utils/fflas_randommatrix.h"
#include <iostream>
#include <givaro/modular-balanced.h>
#include "fflas-ffpack/utils/timer.h"
#include "fflas-ffpack/ffpack/ffpack.h"

#ifdef __GIVARO_USE_OPENMP
typedef Givaro::OMPTimer TTimer;
#else
typedef Givaro::Timer TTimer;
#endif

#include <ctime>
#define CUBE(x) ((x)*(x)*(x))
#define GFOPS(m,n,r,t) (2.0/3.0*CUBE(double(n)/1000.0) +2*m/1000.0*n/1000.0*double(r)/1000.0  - double(r)/1000.0*double(r)/1000.0*(m+n)/1000)/t

int main () {
	using namespace std;

	typedef Givaro::ModularBalanced<double> Field;
	Field F(131071);
	typedef Field::Element Element ;
	size_t n=128, nmax=1000, prec=64, nbest=0, count=0;
	TTimer chrono,tim;
	bool bound=false;

	Element * A = FFLAS::fflas_new (F, nmax, nmax);
	Element * B = FFLAS::fflas_new (F, nmax, nmax);
	size_t lda = nmax;
	size_t r;
	size_t * P = new size_t[nmax];
	size_t * Q = new size_t[nmax];
	FFPACK::RandomMatrix (F, nmax, nmax, A,nmax);
	FFLAS::fassign (F, nmax,nmax, A, nmax, B, nmax);
	time_t result = std::time(NULL);
	cout << std::endl
		  << "---------------------------------------------------------------------"
		  << std::endl << std::asctime(std::localtime(&result))
		  << std::endl
		  << "Threshold for PLUQ base case" ;
	F.write(cout << " (using ") << ')' << endl << endl;

	cout << "PLUQ:  n                   Base case                        Recursive 1 level" << std::endl;
	cout << "                    seconds            Gfops          seconds            Gfops" << std::endl;
		do {
		double BCTime, RecTime;
		int iter=10;

			//warm up computation
		r=FFPACK::PLUQ_basecaseCrout (F, FFLAS::FflasNonUnit, n, n, A, lda, P, Q);
		FFLAS::fassign (F, n, n, B, lda, A, lda);
		chrono.clear();tim.clear();
		for (int i=0;i<iter;i++){
			chrono.start();
			r=FFPACK::PLUQ_basecaseCrout (F, FFLAS::FflasNonUnit, n, n, A, lda, P, Q);
			chrono.stop();
			tim+=chrono;
			FFLAS::fassign (F, n, n, B, lda, A, lda);
		}
		BCTime = tim.realtime()/iter;

		tim.clear();chrono.clear();
		for (int i=0;i<iter;i++){
			chrono.start();
			r=FFPACK::_PLUQ (F, FFLAS::FflasNonUnit, n, n, A, lda, P, Q, n);
			chrono.stop();
			tim+=chrono;
			FFLAS::fassign (F, n, n, B, lda, A, lda);
		}
			//FFLAS::fflas_delete(A);
			//FFLAS::fflas_delete(B);
		RecTime = tim.realtime()/iter;

		cout << "      ";
		cout.width(4);
		cout << n;
		cout << "  ";
		cout.width(15);
		cout << BCTime;
		cout << "  ";
		cout.width(15);
		cout << GFOPS(n,n,r, BCTime) << "  ";
		cout.width(15);
		cout << RecTime;
		cout << "  ";
		cout.width(15);
		cout << GFOPS(n,n,r, RecTime) << endl;

		if (BCTime > RecTime){
			count++;
			if (count > 1){
				nbest = n;
				bound = true;
				prec = prec >> 1;
				n -= prec;
			}
		}
		else{
			count=0;
			if (bound)
				prec=prec>>1;
			n+=prec;
		}
	} while ((prec > 4 ) && (n < nmax));

	cout<<endl;
	if (nbest != 0 ) {
		cerr << "#ifndef __FFLASFFPACK_PLUQ_THRESHOLD"  << endl;
		cerr << "#define __FFLASFFPACK_PLUQ_THRESHOLD" << ' ' <<  nbest << endl;
		cout << "defined __FFLASFFPACK_PLUQ_THRESHOLD to " << nbest << "" << std::endl;
		std::cerr << "#endif" << endl  << endl;
	}
	FFLAS::fflas_delete(A);
	FFLAS::fflas_delete(B);

	return 0;
}
<|endoftext|>


<commit_before>#ifndef ncurses_hh_INCLUDED
#define ncurses_hh_INCLUDED

#include <ncursesw/ncurses.h>
#include <ncursesw/menu.h>

#include "user_interface.hh"
#include "display_buffer.hh"
#include "event_manager.hh"

namespace Kakoune
{

class NCursesUI : public UserInterface
{
public:
    NCursesUI();
    ~NCursesUI();

    NCursesUI(const NCursesUI&) = delete;
    NCursesUI& operator=(const NCursesUI&) = delete;

    void draw(const DisplayBuffer& display_buffer,
              const String& mode_line) override;
    void print_status(const String& status, CharCount cursor_pos) override;

    bool   is_key_available() override;
    Key    get_key() override;

    void menu_show(const memoryview<String>& choices,
                   const DisplayCoord& anchor, MenuStyle style) override;
    void menu_select(int selected) override;
    void menu_hide() override;

    void info_show(const String& content,
                   const DisplayCoord& anchor, MenuStyle style) override;
    void info_hide() override;

    void set_input_callback(InputCallback callback) override;

    DisplayCoord dimensions() override;
private:
    friend void on_term_resize(int);
    void redraw();

    DisplayCoord m_dimensions;
    void update_dimensions();

    String    m_status_line;
    CharCount m_status_cursor = -1;
    void      draw_status();

    MENU* m_menu = nullptr;
    WINDOW* m_menu_win = nullptr;
    std::vector<ITEM*> m_items;
    std::vector<String> m_choices;

    int m_menu_fg;
    int m_menu_bg;

    WINDOW* m_info_win = nullptr;

    FDWatcher     m_stdin_watcher;
    InputCallback m_input_callback;
};

}

#endif // ncurses_hh_INCLUDED

<commit_msg>NCurses: go back to non ncursesw/ headers<commit_after>#ifndef ncurses_hh_INCLUDED
#define ncurses_hh_INCLUDED

#include <ncurses.h>
#include <menu.h>

#include "user_interface.hh"
#include "display_buffer.hh"
#include "event_manager.hh"

namespace Kakoune
{

class NCursesUI : public UserInterface
{
public:
    NCursesUI();
    ~NCursesUI();

    NCursesUI(const NCursesUI&) = delete;
    NCursesUI& operator=(const NCursesUI&) = delete;

    void draw(const DisplayBuffer& display_buffer,
              const String& mode_line) override;
    void print_status(const String& status, CharCount cursor_pos) override;

    bool   is_key_available() override;
    Key    get_key() override;

    void menu_show(const memoryview<String>& choices,
                   const DisplayCoord& anchor, MenuStyle style) override;
    void menu_select(int selected) override;
    void menu_hide() override;

    void info_show(const String& content,
                   const DisplayCoord& anchor, MenuStyle style) override;
    void info_hide() override;

    void set_input_callback(InputCallback callback) override;

    DisplayCoord dimensions() override;
private:
    friend void on_term_resize(int);
    void redraw();

    DisplayCoord m_dimensions;
    void update_dimensions();

    String    m_status_line;
    CharCount m_status_cursor = -1;
    void      draw_status();

    MENU* m_menu = nullptr;
    WINDOW* m_menu_win = nullptr;
    std::vector<ITEM*> m_items;
    std::vector<String> m_choices;

    int m_menu_fg;
    int m_menu_bg;

    WINDOW* m_info_win = nullptr;

    FDWatcher     m_stdin_watcher;
    InputCallback m_input_callback;
};

}

#endif // ncurses_hh_INCLUDED

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: ManifestDefines.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: mtg $ $Date: 2001-09-05 19:19:12 $
 *
 *  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): Martin Gallwey (gallwey@sun.com)
 *
 *
 ************************************************************************/
#ifndef _MANIFEST_DEFINES_HXX
#define _MANIFEST_DEFINES_HXX

#define ELEMENT_MANIFEST "manifest:manifest"
#define ATTRIBUTE_XMLNS "xmlns:manifest"
#define MANIFEST_NAMESPACE "http://openoffice.org/2001/manifest"
#define MANIFEST_DOCTYPE "<!DOCTYPE manifest:manifest PUBLIC \"-//OpenOffice.org//DTD Manifest 1.0//EN\" \"Manifest.dtd\">"
#define ATTRIBUTE_CDATA "CDATA"

#define ELEMENT_FILE_ENTRY "manifest:file-entry"
#define ATTRIBUTE_FULL_PATH "manifest:full-path"
#define ATTRIBUTE_MEDIA_TYPE "manifest:media-type"
#define ATTRIBUTE_SIZE "manifest:size"

#define ELEMENT_ENCRYPTION_DATA "manifest:encryption-data"
#define ATTRIBUTE_CHECKSUM_TYPE "manifest:checksum-type"
#define ATTRIBUTE_CHECKSUM "manifest:checksum"

#define ELEMENT_ALGORITHM "manifest:algorithm"
#define ATTRIBUTE_ALGORITHM_NAME "manifest:algorithm-name"
#define ATTRIBUTE_INITIALISATION_VECTOR "manifest:initialisation-vector"

#define ELEMENT_KEY_DERIVATION "manifest:key-derivation"
#define ATTRIBUTE_KEY_DERIVATION_NAME "manifest:key-derivation-name"
#define ATTRIBUTE_SALT "manifest:salt"
#define ATTRIBUTE_ITERATION_COUNT "manifest:iteration-count"

#endif
<commit_msg>#90699# new define for checksum type<commit_after>/*************************************************************************
 *
 *  $RCSfile: ManifestDefines.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: mtg $ $Date: 2001-10-02 22:29:42 $
 *
 *  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): Martin Gallwey (gallwey@sun.com)
 *
 *
 ************************************************************************/
#ifndef _MANIFEST_DEFINES_HXX
#define _MANIFEST_DEFINES_HXX

#define ELEMENT_MANIFEST "manifest:manifest"
#define ATTRIBUTE_XMLNS "xmlns:manifest"
#define MANIFEST_NAMESPACE "http://openoffice.org/2001/manifest"
#define MANIFEST_DOCTYPE "<!DOCTYPE manifest:manifest PUBLIC \"-//OpenOffice.org//DTD Manifest 1.0//EN\" \"Manifest.dtd\">"
#define ATTRIBUTE_CDATA "CDATA"

#define ELEMENT_FILE_ENTRY "manifest:file-entry"
#define ATTRIBUTE_FULL_PATH "manifest:full-path"
#define ATTRIBUTE_MEDIA_TYPE "manifest:media-type"
#define ATTRIBUTE_SIZE "manifest:size"

#define ELEMENT_ENCRYPTION_DATA "manifest:encryption-data"
#define ATTRIBUTE_CHECKSUM_TYPE "manifest:checksum-type"
#define ATTRIBUTE_CHECKSUM "manifest:checksum"

#define ELEMENT_ALGORITHM "manifest:algorithm"
#define ATTRIBUTE_ALGORITHM_NAME "manifest:algorithm-name"
#define ATTRIBUTE_INITIALISATION_VECTOR "manifest:initialisation-vector"

#define ELEMENT_KEY_DERIVATION "manifest:key-derivation"
#define ATTRIBUTE_KEY_DERIVATION_NAME "manifest:key-derivation-name"
#define ATTRIBUTE_SALT "manifest:salt"
#define ATTRIBUTE_ITERATION_COUNT "manifest:iteration-count"
#define CHECKSUM_TYPE "SHA1/1K"

#endif
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: ManifestDefines.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: mtg $ $Date: 2001-05-08 13:53:48 $
 *
 *  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): Martin Gallwey (gallwey@sun.com)
 *
 *
 ************************************************************************/
#ifndef _MANIFEST_DEFINES_HXX
#define _MANIFEST_DEFINES_HXX

#define ELEMENT_MANIFEST "manifest:manifest"
#define ATTRIBUTE_XMLNS "xmlns:manifest"
#define MANIFEST_NAMESPACE "http://openoffice.org/2001/manifest"
#define MANIFEST_DOCTYPE "<!DOCTYPE manifest:manifest PUBLIC \"-//OpenOffice.org//DTD Manifest 1.0//EN\" \"Manifest.dtd\">"
#define ATTRIBUTE_CDATA "CDATA"

#define ELEMENT_FILE_ENTRY "manifest:file-entry"
#define ATTRIBUTE_FULL_PATH "manifest:full-path"
#define ATTRIBUTE_MEDIA_TYPE "manifest:media-type"
#define ATTRIBUTE_SIZE "manifest:size"

#define ELEMENT_ENCRYPTION_DATA "manifest:encryption-data"

#define ELEMENT_ALGORITHM "manifest:algorithm"
#define ATTRIBUTE_ALGORITHM_NAME "manifest:algorithm-name"
#define ATTRIBUTE_INITIALISATION_VECTOR "manifest:initialisation-vector"

#define ELEMENT_KEY_DERIVATION "manifest:key-derivation"
#define ATTRIBUTE_KEY_DERIVATION_NAME "manifest:key-derivation-name"
#define ATTRIBUTE_SALT "manifest:salt"
#define ATTRIBUTE_ITERATION_COUNT "manifest:iteration-count"

#endif
<commit_msg>#90699# add defines for MD5 export<commit_after>/*************************************************************************
 *
 *  $RCSfile: ManifestDefines.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: mtg $ $Date: 2001-09-05 19:19:12 $
 *
 *  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): Martin Gallwey (gallwey@sun.com)
 *
 *
 ************************************************************************/
#ifndef _MANIFEST_DEFINES_HXX
#define _MANIFEST_DEFINES_HXX

#define ELEMENT_MANIFEST "manifest:manifest"
#define ATTRIBUTE_XMLNS "xmlns:manifest"
#define MANIFEST_NAMESPACE "http://openoffice.org/2001/manifest"
#define MANIFEST_DOCTYPE "<!DOCTYPE manifest:manifest PUBLIC \"-//OpenOffice.org//DTD Manifest 1.0//EN\" \"Manifest.dtd\">"
#define ATTRIBUTE_CDATA "CDATA"

#define ELEMENT_FILE_ENTRY "manifest:file-entry"
#define ATTRIBUTE_FULL_PATH "manifest:full-path"
#define ATTRIBUTE_MEDIA_TYPE "manifest:media-type"
#define ATTRIBUTE_SIZE "manifest:size"

#define ELEMENT_ENCRYPTION_DATA "manifest:encryption-data"
#define ATTRIBUTE_CHECKSUM_TYPE "manifest:checksum-type"
#define ATTRIBUTE_CHECKSUM "manifest:checksum"

#define ELEMENT_ALGORITHM "manifest:algorithm"
#define ATTRIBUTE_ALGORITHM_NAME "manifest:algorithm-name"
#define ATTRIBUTE_INITIALISATION_VECTOR "manifest:initialisation-vector"

#define ELEMENT_KEY_DERIVATION "manifest:key-derivation"
#define ATTRIBUTE_KEY_DERIVATION_NAME "manifest:key-derivation-name"
#define ATTRIBUTE_SALT "manifest:salt"
#define ATTRIBUTE_ITERATION_COUNT "manifest:iteration-count"

#endif
<|endoftext|>


<commit_before>
#include "allrefs.h"
#include "logging.h"
#include "search.h"

#include <algorithm>
#include <cstdint>
#include <functional>
#include <fstream>
#include <locale>
#include <regex>
#include <sstream>
#include <unordered_set>
#include <vector>

#include <boost/algorithm/string/trim.hpp>
#include <boost/algorithm/string/join.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/optional.hpp>

#include <signal.h>

void RefRecords::saveToFile(const boost::filesystem::path & dataref_filename, const boost::filesystem::path & commandref_filename) const {
	std::vector<const std::string *> dataref_names, commandref_names;
	dataref_names.reserve(datarefs.size());
	for(const DataRefRecord & dr : datarefs) {
		dataref_names.push_back(&dr.getName());
	}

	commandref_names.reserve(commandrefs.size());
	for(const CommandRefRecord & cr : commandrefs) {
		commandref_names.push_back(&cr.getName());
	}

	auto sort_and_write_names = [](std::vector<const std::string *> & names, const boost::filesystem::path & filename) -> bool {
		auto p_str_comparator = [](const std::string * s1, const std::string * s2) -> bool {
			return boost::ilexicographical_compare(*s1, *s2);
		};
		std::sort(names.begin(), names.end(), p_str_comparator);

		std::ofstream f(filename.string());
		for(const std::string * pstr : names) {
			f << *pstr << "\n";
		}
		f.close();
		if(f.fail()) {
			LOG("Error writing file " + filename.string());
		}
		return f.fail();
	};

	sort_and_write_names(dataref_names, dataref_filename);
	sort_and_write_names(commandref_names, commandref_filename);
}

std::vector<RefRecord *> RefRecords::add(const std::vector<std::string> & names, ref_src_t source) {
	std::string name;
	std::vector<RefRecord *> new_records;
	for(const std::string & name_untrimmed : names) {
		name = name_untrimmed;
		boost::algorithm::trim(name);

		//check for duplicates:
        NameMapType::iterator existing_location = ref_names_loaded.find(name);
        if(ref_names_loaded.cend() != existing_location) {
			continue;
		}

		XPLMDataRef dr = XPLMFindDataRef(name.c_str());
		XPLMCommandRef cr = XPLMFindCommand(name.c_str());
        if(nullptr != dr) {
        	datarefs.emplace_back(name, dr, source);
			new_records.emplace_back(&datarefs.back());
			dr_pointers.emplace_back(&datarefs.back());
			ref_names_loaded.insert(name);
		}

		if(nullptr != cr) {
        	commandrefs.emplace_back(name, cr, source);
			new_records.emplace_back(&commandrefs.back());
			cr_pointers.emplace_back(&commandrefs.back());
			ref_names_loaded.insert(name);
		}
	}

	return new_records;
}

const char * current_dr_name = nullptr;

void sig_handler(int) {
	XPLMDebugString("DRT: Crash detected while reading dataref ");
	XPLMDebugString(current_dr_name);
	XPLMDebugString("\n");
	XPLMDebugString("Please add this dataref to X-Plane 11/Resources/plugins/drt_blacklist.txt to prevent this happening again.\n");
	exit(-1);
}

std::vector<RefRecord *> RefRecords::update() {
	std::chrono::system_clock::time_point now = std::chrono::system_clock::now();
	updater.updateTime(now);
	std::vector<RefRecord *> changed_drs;

#if IBM
	typedef SignalHandlerPointer sig_t;
#endif

	sig_t previous_sigsegv = signal(SIGSEGV, sig_handler);
	sig_t previous_sigfpe = signal(SIGFPE, sig_handler);

	for(DataRefRecord & dr : datarefs) {
        if(false == dr.isBlacklisted()) {
			current_dr_name = dr.getName().c_str();

            if(dr.update(updater)) { //if updated
				changed_drs.push_back(&dr);
			}
        }
	}

	signal(SIGSEGV, previous_sigsegv);
	signal(SIGFPE, previous_sigfpe);
	current_dr_name = nullptr;

	return changed_drs;
}
<commit_msg>One more try working around windows signal support<commit_after>
#include "allrefs.h"
#include "logging.h"
#include "search.h"

#include <algorithm>
#include <cstdint>
#include <functional>
#include <fstream>
#include <locale>
#include <regex>
#include <sstream>
#include <unordered_set>
#include <vector>

#include <boost/algorithm/string/trim.hpp>
#include <boost/algorithm/string/join.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/optional.hpp>

#include <signal.h>

void RefRecords::saveToFile(const boost::filesystem::path & dataref_filename, const boost::filesystem::path & commandref_filename) const {
	std::vector<const std::string *> dataref_names, commandref_names;
	dataref_names.reserve(datarefs.size());
	for(const DataRefRecord & dr : datarefs) {
		dataref_names.push_back(&dr.getName());
	}

	commandref_names.reserve(commandrefs.size());
	for(const CommandRefRecord & cr : commandrefs) {
		commandref_names.push_back(&cr.getName());
	}

	auto sort_and_write_names = [](std::vector<const std::string *> & names, const boost::filesystem::path & filename) -> bool {
		auto p_str_comparator = [](const std::string * s1, const std::string * s2) -> bool {
			return boost::ilexicographical_compare(*s1, *s2);
		};
		std::sort(names.begin(), names.end(), p_str_comparator);

		std::ofstream f(filename.string());
		for(const std::string * pstr : names) {
			f << *pstr << "\n";
		}
		f.close();
		if(f.fail()) {
			LOG("Error writing file " + filename.string());
		}
		return f.fail();
	};

	sort_and_write_names(dataref_names, dataref_filename);
	sort_and_write_names(commandref_names, commandref_filename);
}

std::vector<RefRecord *> RefRecords::add(const std::vector<std::string> & names, ref_src_t source) {
	std::string name;
	std::vector<RefRecord *> new_records;
	for(const std::string & name_untrimmed : names) {
		name = name_untrimmed;
		boost::algorithm::trim(name);

		//check for duplicates:
        NameMapType::iterator existing_location = ref_names_loaded.find(name);
        if(ref_names_loaded.cend() != existing_location) {
			continue;
		}

		XPLMDataRef dr = XPLMFindDataRef(name.c_str());
		XPLMCommandRef cr = XPLMFindCommand(name.c_str());
        if(nullptr != dr) {
        	datarefs.emplace_back(name, dr, source);
			new_records.emplace_back(&datarefs.back());
			dr_pointers.emplace_back(&datarefs.back());
			ref_names_loaded.insert(name);
		}

		if(nullptr != cr) {
        	commandrefs.emplace_back(name, cr, source);
			new_records.emplace_back(&commandrefs.back());
			cr_pointers.emplace_back(&commandrefs.back());
			ref_names_loaded.insert(name);
		}
	}

	return new_records;
}

const char * current_dr_name = nullptr;

void sig_handler(int) {
	XPLMDebugString("DRT: Crash detected while reading dataref ");
	XPLMDebugString(current_dr_name);
	XPLMDebugString("\n");
	XPLMDebugString("Please add this dataref to X-Plane 11/Resources/plugins/drt_blacklist.txt to prevent this happening again.\n");
	exit(-1);
}

std::vector<RefRecord *> RefRecords::update() {
	std::chrono::system_clock::time_point now = std::chrono::system_clock::now();
	updater.updateTime(now);
	std::vector<RefRecord *> changed_drs;

#if IBM
    typedef void (*sig_t)(int);
#endif

	sig_t previous_sigsegv = signal(SIGSEGV, sig_handler);
	sig_t previous_sigfpe = signal(SIGFPE, sig_handler);

	for(DataRefRecord & dr : datarefs) {
        if(false == dr.isBlacklisted()) {
			current_dr_name = dr.getName().c_str();

            if(dr.update(updater)) { //if updated
				changed_drs.push_back(&dr);
			}
        }
	}

	signal(SIGSEGV, previous_sigsegv);
	signal(SIGFPE, previous_sigfpe);
	current_dr_name = nullptr;

	return changed_drs;
}
<|endoftext|>


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

#include "SurgSim/Graphics/OsgCamera.h"

#include "SurgSim/Graphics/Material.h"
#include "SurgSim/Graphics/Manager.h"
#include "SurgSim/Graphics/OsgGroup.h"
#include "SurgSim/Graphics/OsgMaterial.h"
#include "SurgSim/Graphics/OsgMatrixConversions.h"
#include "SurgSim/Graphics/OsgQuaternionConversions.h"
#include "SurgSim/Graphics/OsgVectorConversions.h"
#include "SurgSim/Graphics/OsgRenderTarget.h"

#include <osgUtil/CullVisitor>

using SurgSim::Math::makeRigidTransform;

namespace
{
const osg::Camera::BufferComponent ColorBufferEnums[16] =
{
	osg::Camera::COLOR_BUFFER0,
	osg::Camera::COLOR_BUFFER1,
	osg::Camera::COLOR_BUFFER2,
	osg::Camera::COLOR_BUFFER3,
	osg::Camera::COLOR_BUFFER4,
	osg::Camera::COLOR_BUFFER5,
	osg::Camera::COLOR_BUFFER6,
	osg::Camera::COLOR_BUFFER7,
	osg::Camera::COLOR_BUFFER8,
	osg::Camera::COLOR_BUFFER9,
	osg::Camera::COLOR_BUFFER10,
	osg::Camera::COLOR_BUFFER11,
	osg::Camera::COLOR_BUFFER12,
	osg::Camera::COLOR_BUFFER13,
	osg::Camera::COLOR_BUFFER14,
	osg::Camera::COLOR_BUFFER15
};

const osg::Camera::RenderOrder RenderOrderEnums[3] =
{
	osg::Camera::PRE_RENDER,
	osg::Camera::NESTED_RENDER,
	osg::Camera::POST_RENDER
};

SURGSIM_REGISTER(SurgSim::Framework::Component, SurgSim::Graphics::OsgCamera);

};

namespace SurgSim
{
namespace Graphics
{

OsgCamera::OsgCamera(const std::string& name) :
	Representation(name),
	OsgRepresentation(name),
	Camera(name),
	m_camera(new osg::Camera()),
	m_materialProxy(new osg::Group())
{
	m_switch->removeChildren(0, m_switch->getNumChildren());
	m_camera->setName(name + " Camera");

	m_switch->addChild(m_camera);
	m_camera->addChild(m_materialProxy);
	m_materialProxy->setName(name + " MaterialProxy");

	m_camera->setViewMatrix(toOsg(getLocalPose().inverse().matrix()));
	m_camera->setProjectionMatrixAsPerspective(45.0, 1.0, 0.01, 10.0);

	m_camera->setComputeNearFarMode(osgUtil::CullVisitor::DO_NOT_COMPUTE_NEAR_FAR);

	/// Update storage of view and projection matrices
	m_projectionMatrix = fromOsg(m_camera->getProjectionMatrix());
}

bool OsgCamera::setRenderGroup(std::shared_ptr<SurgSim::Graphics::Group> group)
{

	SURGSIM_ASSERT(group->getName() == Camera::getRenderGroupReference())
			<< "Trying to set the wrong group in the camera getRenderGroupName() returns <"
			<< Camera::getRenderGroupReference() << "> group->getName() is <" << group->getName() << ">.";

	std::shared_ptr<OsgGroup> osgGroup = std::dynamic_pointer_cast<OsgGroup>(group);
	if (osgGroup && SurgSim::Graphics::Camera::setRenderGroup(group))
	{
		m_materialProxy->removeChildren(0, m_camera->getNumChildren());  /// Remove any previous group
		m_materialProxy->addChild(osgGroup->getOsgGroup());
		return true;
	}
	else
	{
		return false;
	}
}

void OsgCamera::setVisible(bool visible)
{
	m_switch->setChildValue(m_camera, visible);
}

bool OsgCamera::isVisible() const
{
	return m_switch->getChildValue(m_camera);
}

SurgSim::Math::Matrix44d OsgCamera::getViewMatrix() const
{
	return getPose().inverse().matrix();
}

void OsgCamera::setProjectionMatrix(const SurgSim::Math::Matrix44d& matrix)
{
	m_projectionMatrix = matrix;
	m_camera->setProjectionMatrix(toOsg(matrix));
}

const SurgSim::Math::Matrix44d& OsgCamera::getProjectionMatrix() const
{
	return m_projectionMatrix;
}

void OsgCamera::update(double dt)
{
	m_camera->setViewMatrix(toOsg(getViewMatrix()));
}

bool OsgCamera::setRenderTarget(std::shared_ptr<RenderTarget> renderTarget)
{
	bool result = false;

	// Check for correct dynamic type
	auto osg2dTarget = std::dynamic_pointer_cast<OsgRenderTarget2d>(renderTarget);
	auto osgRectTarget = std::dynamic_pointer_cast<OsgRenderTargetRectangle>(renderTarget);

	if (osg2dTarget != nullptr || osgRectTarget != nullptr)
	{
		if (m_renderTarget == nullptr)
		{
			detachCurrentRenderTarget();
		}

		int width, height;
		renderTarget->getSize(&width, &height);
		m_camera->setViewport(0, 0, width, height);

		attachRenderTargetTexture(osg::Camera::DEPTH_BUFFER, renderTarget->getDepthTarget());

		// OSG has 16 COLOR_BUFFER objects
		for (int i = 0; i < 16; ++i)
		{
			attachRenderTargetTexture(ColorBufferEnums[i], renderTarget->getColorTarget(i));
		}

		m_camera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT, osg::Camera::PIXEL_BUFFER);
		m_camera->setRenderOrder(osg::Camera::PRE_RENDER);
		m_camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
		m_camera->setClearColor(osg::Vec4f(0.0, 0.0, 0.0, 1.0));
		m_renderTarget = renderTarget;
		result = true;
	}
	else if (renderTarget == nullptr && m_renderTarget != nullptr)
	{
		detachCurrentRenderTarget();
		result = true;
	}

	return result;
}

std::shared_ptr<RenderTarget> OsgCamera::getRenderTarget() const
{
	return m_renderTarget;
}

bool OsgCamera::setMaterial(std::shared_ptr<Material> material)
{
	std::shared_ptr<OsgMaterial> osgMaterial = std::dynamic_pointer_cast<OsgMaterial>(material);
	bool result = false;
	if (osgMaterial != nullptr)
	{
		m_materialProxy->setStateSet(osgMaterial->getOsgStateSet());
		result = true;
		m_material = osgMaterial;
	}
	return result;
}

std::shared_ptr<Material> OsgCamera::getMaterial() const
{
	return m_material;
}

void OsgCamera::clearMaterial()
{
	m_materialProxy->setStateSet(new osg::StateSet());
}

void OsgCamera::detachCurrentRenderTarget()
{
	if (m_renderTarget != nullptr)
	{
		if (m_renderTarget->doesUseDepthTarget())
		{
			m_camera->detach(osg::Camera::DEPTH_BUFFER);
		}
		for (int i = 0; i < m_renderTarget->getColorTargetCount(); ++i)
		{
			m_camera->detach(ColorBufferEnums[i]);
		}
	}
	m_renderTarget = nullptr;
}

void OsgCamera::attachRenderTargetTexture(osg::Camera::BufferComponent buffer, std::shared_ptr<Texture> texture)
{
	if (texture == nullptr)
	{
		return;
	}

	std::shared_ptr<OsgTexture> osgTexture = std::dynamic_pointer_cast<OsgTexture>(texture);
	SURGSIM_ASSERT(osgTexture != nullptr) <<
										  "RenderTarget used a texture that was not an OsgTexture subclass";

	osg::Texture* actualTexture = osgTexture->getOsgTexture();
	SURGSIM_ASSERT(actualTexture != nullptr) <<
			"Could not find texture";

	m_camera->attach(buffer, actualTexture, 0, 0);
}

void OsgCamera::setRenderOrder(RenderOrder order, int value)
{
	if (order < RENDER_ORDER_COUNT)
	{
		m_camera->setRenderOrder(RenderOrderEnums[order], value);
	}
}

osg::ref_ptr<osg::Camera> OsgCamera::getOsgCamera() const
{
	return m_camera;
}

osg::ref_ptr<osg::Node> OsgCamera::getOsgNode() const
{
	return m_switch;
}

SurgSim::Math::Matrix44d OsgCamera::getInverseViewMatrix() const
{
	return getPose().matrix();
}

}; // namespace Graphics
}; // namespace SurgSim

<commit_msg>Workaround issue with update to camera projection matrix<commit_after>// This file is a part of the OpenSurgSim project.
// Copyright 2013, SimQuest Solutions Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "SurgSim/Graphics/OsgCamera.h"

#include "SurgSim/Graphics/Material.h"
#include "SurgSim/Graphics/Manager.h"
#include "SurgSim/Graphics/OsgGroup.h"
#include "SurgSim/Graphics/OsgMaterial.h"
#include "SurgSim/Graphics/OsgMatrixConversions.h"
#include "SurgSim/Graphics/OsgQuaternionConversions.h"
#include "SurgSim/Graphics/OsgVectorConversions.h"
#include "SurgSim/Graphics/OsgRenderTarget.h"

#include <osgUtil/CullVisitor>

using SurgSim::Math::makeRigidTransform;

namespace
{
const osg::Camera::BufferComponent ColorBufferEnums[16] =
{
	osg::Camera::COLOR_BUFFER0,
	osg::Camera::COLOR_BUFFER1,
	osg::Camera::COLOR_BUFFER2,
	osg::Camera::COLOR_BUFFER3,
	osg::Camera::COLOR_BUFFER4,
	osg::Camera::COLOR_BUFFER5,
	osg::Camera::COLOR_BUFFER6,
	osg::Camera::COLOR_BUFFER7,
	osg::Camera::COLOR_BUFFER8,
	osg::Camera::COLOR_BUFFER9,
	osg::Camera::COLOR_BUFFER10,
	osg::Camera::COLOR_BUFFER11,
	osg::Camera::COLOR_BUFFER12,
	osg::Camera::COLOR_BUFFER13,
	osg::Camera::COLOR_BUFFER14,
	osg::Camera::COLOR_BUFFER15
};

const osg::Camera::RenderOrder RenderOrderEnums[3] =
{
	osg::Camera::PRE_RENDER,
	osg::Camera::NESTED_RENDER,
	osg::Camera::POST_RENDER
};

SURGSIM_REGISTER(SurgSim::Framework::Component, SurgSim::Graphics::OsgCamera);

};

namespace SurgSim
{
namespace Graphics
{

OsgCamera::OsgCamera(const std::string& name) :
	Representation(name),
	OsgRepresentation(name),
	Camera(name),
	m_camera(new osg::Camera()),
	m_materialProxy(new osg::Group())
{
	m_switch->removeChildren(0, m_switch->getNumChildren());
	m_camera->setName(name + " Camera");

	m_switch->addChild(m_camera);
	m_camera->addChild(m_materialProxy);
	m_materialProxy->setName(name + " MaterialProxy");

	m_camera->setViewMatrix(toOsg(getLocalPose().inverse().matrix()));
	m_camera->setProjectionMatrixAsPerspective(45.0, 1.0, 0.01, 10.0);

	m_camera->setComputeNearFarMode(osgUtil::CullVisitor::DO_NOT_COMPUTE_NEAR_FAR);

	/// Update storage of view and projection matrices
	m_projectionMatrix = fromOsg(m_camera->getProjectionMatrix());
}

bool OsgCamera::setRenderGroup(std::shared_ptr<SurgSim::Graphics::Group> group)
{

	SURGSIM_ASSERT(group->getName() == Camera::getRenderGroupReference())
			<< "Trying to set the wrong group in the camera getRenderGroupName() returns <"
			<< Camera::getRenderGroupReference() << "> group->getName() is <" << group->getName() << ">.";

	std::shared_ptr<OsgGroup> osgGroup = std::dynamic_pointer_cast<OsgGroup>(group);
	if (osgGroup && SurgSim::Graphics::Camera::setRenderGroup(group))
	{
		m_materialProxy->removeChildren(0, m_camera->getNumChildren());  /// Remove any previous group
		m_materialProxy->addChild(osgGroup->getOsgGroup());
		return true;
	}
	else
	{
		return false;
	}
}

void OsgCamera::setVisible(bool visible)
{
	m_switch->setChildValue(m_camera, visible);
}

bool OsgCamera::isVisible() const
{
	return m_switch->getChildValue(m_camera);
}

SurgSim::Math::Matrix44d OsgCamera::getViewMatrix() const
{
	return getPose().matrix().inverse();
}

void OsgCamera::setProjectionMatrix(const SurgSim::Math::Matrix44d& matrix)
{
	m_projectionMatrix = matrix;
	m_camera->setProjectionMatrix(toOsg(matrix));
}

const SurgSim::Math::Matrix44d& OsgCamera::getProjectionMatrix() const
{
	return m_projectionMatrix;
}

void OsgCamera::update(double dt)
{
	// HS-2014-may-05 There is an issue between setting the projection matrix in the constructor and the
	// instantiation of the viewer with the view port that may change the matrix inbetween, for now ... update
	// every frame
	// #workaround
	m_projectionMatrix = fromOsg(m_camera->getProjectionMatrix());
	m_camera->setViewMatrix(toOsg(getViewMatrix()));
}

bool OsgCamera::setRenderTarget(std::shared_ptr<RenderTarget> renderTarget)
{
	bool result = false;

	// Check for correct dynamic type
	auto osg2dTarget = std::dynamic_pointer_cast<OsgRenderTarget2d>(renderTarget);
	auto osgRectTarget = std::dynamic_pointer_cast<OsgRenderTargetRectangle>(renderTarget);

	if (osg2dTarget != nullptr || osgRectTarget != nullptr)
	{
		if (m_renderTarget == nullptr)
		{
			detachCurrentRenderTarget();
		}

		int width, height;
		renderTarget->getSize(&width, &height);
		m_camera->setViewport(0, 0, width, height);

		attachRenderTargetTexture(osg::Camera::DEPTH_BUFFER, renderTarget->getDepthTarget());

		// OSG has 16 COLOR_BUFFER objects
		for (int i = 0; i < 16; ++i)
		{
			attachRenderTargetTexture(ColorBufferEnums[i], renderTarget->getColorTarget(i));
		}

		m_camera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT, osg::Camera::PIXEL_BUFFER);
		m_camera->setRenderOrder(osg::Camera::PRE_RENDER);
		m_camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
		m_camera->setClearColor(osg::Vec4f(0.0, 0.0, 0.0, 1.0));
		m_renderTarget = renderTarget;
		result = true;
	}
	else if (renderTarget == nullptr && m_renderTarget != nullptr)
	{
		detachCurrentRenderTarget();
		result = true;
	}

	return result;
}

std::shared_ptr<RenderTarget> OsgCamera::getRenderTarget() const
{
	return m_renderTarget;
}

bool OsgCamera::setMaterial(std::shared_ptr<Material> material)
{
	std::shared_ptr<OsgMaterial> osgMaterial = std::dynamic_pointer_cast<OsgMaterial>(material);
	bool result = false;
	if (osgMaterial != nullptr)
	{
		m_materialProxy->setStateSet(osgMaterial->getOsgStateSet());
		result = true;
		m_material = osgMaterial;
	}
	return result;
}

std::shared_ptr<Material> OsgCamera::getMaterial() const
{
	return m_material;
}

void OsgCamera::clearMaterial()
{
	m_materialProxy->setStateSet(new osg::StateSet());
}

void OsgCamera::detachCurrentRenderTarget()
{
	if (m_renderTarget != nullptr)
	{
		if (m_renderTarget->doesUseDepthTarget())
		{
			m_camera->detach(osg::Camera::DEPTH_BUFFER);
		}
		for (int i = 0; i < m_renderTarget->getColorTargetCount(); ++i)
		{
			m_camera->detach(ColorBufferEnums[i]);
		}
	}
	m_renderTarget = nullptr;
}

void OsgCamera::attachRenderTargetTexture(osg::Camera::BufferComponent buffer, std::shared_ptr<Texture> texture)
{
	if (texture == nullptr)
	{
		return;
	}

	std::shared_ptr<OsgTexture> osgTexture = std::dynamic_pointer_cast<OsgTexture>(texture);
	SURGSIM_ASSERT(osgTexture != nullptr) <<
										  "RenderTarget used a texture that was not an OsgTexture subclass";

	osg::Texture* actualTexture = osgTexture->getOsgTexture();
	SURGSIM_ASSERT(actualTexture != nullptr) <<
			"Could not find texture";

	m_camera->attach(buffer, actualTexture, 0, 0);
}

void OsgCamera::setRenderOrder(RenderOrder order, int value)
{
	if (order < RENDER_ORDER_COUNT)
	{
		m_camera->setRenderOrder(RenderOrderEnums[order], value);
	}
}

osg::ref_ptr<osg::Camera> OsgCamera::getOsgCamera() const
{
	return m_camera;
}

osg::ref_ptr<osg::Node> OsgCamera::getOsgNode() const
{
	return m_switch;
}

SurgSim::Math::Matrix44d OsgCamera::getInverseViewMatrix() const
{
	return getPose().matrix();
}

}; // namespace Graphics
}; // namespace SurgSim

<|endoftext|>


<commit_before><?hh //strict

/**
 * This file is part of hhpack\getopt package.
 *
 * (c) Noritaka Horio <holy.shared.design@gmail.com>
 *
 * This source file is subject to the MIT license that is bundled
 * with this source code in the file LICENSE.
 */

namespace HHPack\Getopt\Parser;

use HHPack\Getopt\Spec\{ Option, OptionSet, OptionCollection, HelpDisplayable };
use HHPack\Getopt\Argv\{ ArgumentsConsumer, ArgumentsExtractor };

final class OptionParser implements Parser, HelpDisplayable
{

    public function __construct(
        private OptionCollection $options = new OptionSet(),
        private bool $stopAtNonOption = false
    )
    {
    }

    public function parse(Traversable<string> $input = []) : ImmVector<string>
    {
        if ($this->stopAtNonOption) {
            return $this->parseUntilNonOption($input);
        } else {
            return $this->parseAll($input);
        }
    }

    private function parseAll(Traversable<string> $input = []) : ImmVector<string>
    {
        list($argv, $notFlags) = $this->prepareArgs($input);

        $args = Vector::fromItems($notFlags);

        $extractedArgv = $this->extractArgv($argv);
        $consumer = new ArgumentsConsumer($extractedArgv);

        while ($consumer->valid()) {
            $matches = [];
            $value = $consumer->current();

            if (preg_match('/^(-{1,2}[^-]+)$/', $value, $matches) !== 1) {
                $args->add($value);
                $consumer->consume();
                continue;
            }
            list($_, $name) = $matches;

            $option = $this->options->get($name);
            $option->consume($consumer);
        }

        return $args->immutable();
    }

    private function parseUntilNonOption(Traversable<string> $input = []) : ImmVector<string>
    {
        list($argv, $notFlags) = $this->prepareArgs($input);

        $args = Vector::fromItems($notFlags);

        $extractedArgv = $this->extractArgv($argv);
        $consumer = new ArgumentsConsumer($extractedArgv);

        while ($consumer->valid()) {
            $matches = [];
            $value = $consumer->current();

            if (preg_match('/^(-{1,2}[^-]+)$/', $value, $matches) !== 1) {
                break;
            }

            list($_, $name) = $matches;

            $option = $this->options->get($name);
            $option->consume($consumer);
        }

        return $consumer->applyTo($args)->immutable();
    }

    private function prepareArgs(Traversable<string> $argv = []) : (Traversable<string>, Traversable<string>)
    {
        $arguments = ImmSet::fromItems($argv);

        $notFlags = $arguments->skipWhile(($value) ==> $value !== '--');

        $args = $arguments->slice(0, $arguments->count() - $notFlags->count());

        if (!$notFlags->isEmpty()) {
            $notFlags = $notFlags->slice(1, $notFlags->count() - 1); // Remove --
        }

        return tuple($args, $notFlags);
    }

    private function extractArgv(Traversable<string> $argv) : ImmVector<string>
    {
        $extractor = ArgumentsExtractor::fromOptions($this->options);
        $extractedArgv = $extractor->extract($argv);

        return $extractedArgv;
    }

    public function displayHelp() : void
    {
        $this->options->displayHelp();
    }

    public static function fromOptions(Traversable<Option> $options = []) : this
    {
        $options = new OptionSet($options);
        return new static($options);
    }

}
<commit_msg>fix separate argument logic<commit_after><?hh //strict

/**
 * This file is part of hhpack\getopt package.
 *
 * (c) Noritaka Horio <holy.shared.design@gmail.com>
 *
 * This source file is subject to the MIT license that is bundled
 * with this source code in the file LICENSE.
 */

namespace HHPack\Getopt\Parser;

use HHPack\Getopt\Spec\{ Option, OptionSet, OptionCollection, HelpDisplayable };
use HHPack\Getopt\Argv\{ ArgumentsConsumer, ArgumentsExtractor };

final class OptionParser implements Parser, HelpDisplayable
{

    public function __construct(
        private OptionCollection $options = new OptionSet(),
        private bool $stopAtNonOption = false
    )
    {
    }

    public function parse(Traversable<string> $input = []) : ImmVector<string>
    {
        if ($this->stopAtNonOption) {
            return $this->parseUntilNonOption($input);
        } else {
            return $this->parseAll($input);
        }
    }

    private function parseAll(Traversable<string> $input = []) : ImmVector<string>
    {
        $args = Vector {};

        $extractedArgv = $this->extractArgv($input);
        $consumer = new ArgumentsConsumer($extractedArgv);

        while ($consumer->valid()) {
            $matches = [];
            $value = $consumer->current();

            if (preg_match('/^(--)$/', $value, $matches) === 1) {
                $consumer->consume();
                break;
            } else if (preg_match('/^(-{1,2}[^-]+)$/', $value, $matches) !== 1) {
                $args->add($value);
                $consumer->consume();
                continue;
            }
            list($_, $name) = $matches;

            $option = $this->options->get($name);
            $option->consume($consumer);
        }

        return $consumer->applyTo($args)->immutable();
    }

    private function parseUntilNonOption(Traversable<string> $input = []) : ImmVector<string>
    {
        $args = Vector {};

        $extractedArgv = $this->extractArgv($input);
        $consumer = new ArgumentsConsumer($extractedArgv);

        while ($consumer->valid()) {
            $matches = [];
            $value = $consumer->current();

            if (preg_match('/^(--)$/', $value, $matches) === 1) {
                break;
            }

            if (preg_match('/^(-{1,2}[^-]+)$/', $value, $matches) !== 1) {
                break;
            }

            list($_, $name) = $matches;

            $option = $this->options->get($name);
            $option->consume($consumer);
        }

        return $consumer->applyTo($args)->immutable();
    }

    private function extractArgv(Traversable<string> $argv) : ImmVector<string>
    {
        $extractor = ArgumentsExtractor::fromOptions($this->options);
        $extractedArgv = $extractor->extract($argv);

        return $extractedArgv;
    }

    public function displayHelp() : void
    {
        $this->options->displayHelp();
    }

    public static function fromOptions(Traversable<Option> $options = []) : this
    {
        $options = new OptionSet($options);
        return new static($options);
    }

}
<|endoftext|>