<commit_before>/* The goal of these tests is to verify the behavior of all blob commands given
 * the current state is verificationStarted.  This state is achieved as a out of
 * verificationPending.
 */
#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::IsEmpty;
using ::testing::Return;
using ::testing::UnorderedElementsAreArray;

/*
 * 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)
 *
 * Testing canHandleBlob is uninteresting in this state.  Getting the BlobIDs
 * will inform what canHandleBlob will return.
 */

class FirmwareHandlerVerificationStartedTest : public IpmiOnlyFirmwareStaticTest
{
  protected:
    void getToVerificationStarted(const std::string& blobId)
    {
        EXPECT_CALL(imageMock, open(blobId)).WillOnce(Return(true));
        EXPECT_TRUE(handler->open(session, flags, blobId));
        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);
    }

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

/*
 * canHandleBlob(blob)
 * getBlobIds()
 */
TEST_F(FirmwareHandlerVerificationStartedTest, GetBlobIdsReturnsExpectedList)
{
    getToVerificationStarted(staticLayoutBlobId);

    std::vector<std::string> expectedList = {
        activeImageBlobId, staticLayoutBlobId, hashBlobId, verifyBlobId};

    EXPECT_THAT(handler->getBlobIds(), UnorderedElementsAreArray(expectedList));

    for (const auto& blob : expectedList)
    {
        EXPECT_TRUE(handler->canHandleBlob(blob));
    }
}

/*
 * stat(session)
 */
TEST_F(FirmwareHandlerVerificationStartedTest,
       StatOnVerifyBlobIdAfterCommitChecksStateAndReturnsRunning)
{
    getToVerificationStarted(staticLayoutBlobId);
    EXPECT_CALL(*verifyMockPtr, checkVerificationState())
        .WillOnce(Return(VerifyCheckResponses::running));

    blobs::BlobMeta meta, expectedMeta = {};
    expectedMeta.size = 0;
    expectedMeta.blobState = flags | blobs::StateFlags::committing;
    expectedMeta.metadata.push_back(
        static_cast<std::uint8_t>(VerifyCheckResponses::running));

    EXPECT_TRUE(handler->stat(session, &meta));
    EXPECT_EQ(expectedMeta, meta);
}

TEST_F(FirmwareHandlerVerificationStartedTest,
       StatOnVerifyBlobIdAfterCommitCheckStateAndReturnsFailed)
{
    /* If the returned state from the verification handler is failed, it sets
     * commit_error and transitions to verificationCompleted.
     */
    getToVerificationStarted(staticLayoutBlobId);
    EXPECT_CALL(*verifyMockPtr, checkVerificationState())
        .WillOnce(Return(VerifyCheckResponses::failed));

    blobs::BlobMeta meta, expectedMeta = {};
    expectedMeta.size = 0;
    expectedMeta.blobState = flags | blobs::StateFlags::commit_error;
    expectedMeta.metadata.push_back(
        static_cast<std::uint8_t>(VerifyCheckResponses::failed));

    EXPECT_TRUE(handler->stat(session, &meta));
    EXPECT_EQ(expectedMeta, meta);
    expectedState(FirmwareBlobHandler::UpdateState::verificationCompleted);
}

TEST_F(FirmwareHandlerVerificationStartedTest,
       StatOnVerifyBlobIdAfterCommitCheckStateAndReturnsSuccess)
{
    /* If the returned state from the verification handler is success, it sets
     * committed and transitions to verificationCompleted.
     */
    getToVerificationStarted(staticLayoutBlobId);
    EXPECT_CALL(*verifyMockPtr, checkVerificationState())
        .WillOnce(Return(VerifyCheckResponses::success));

    blobs::BlobMeta meta, expectedMeta = {};
    expectedMeta.size = 0;
    expectedMeta.blobState = flags | blobs::StateFlags::committed;
    expectedMeta.metadata.push_back(
        static_cast<std::uint8_t>(VerifyCheckResponses::success));

    EXPECT_TRUE(handler->stat(session, &meta));
    EXPECT_EQ(expectedMeta, meta);
    expectedState(FirmwareBlobHandler::UpdateState::verificationCompleted);
}

/* TODO: Once verificationCompleted is the state, canHandleBlob should accept
 * updateBlobId.
 */

/* TODO: deleteBlob(blob) */

/*
 * stat(blob)
 */
TEST_F(FirmwareHandlerVerificationStartedTest, StatOnActiveImageReturnsFailure)
{
    getToVerificationStarted(staticLayoutBlobId);
    ASSERT_TRUE(handler->canHandleBlob(activeImageBlobId));

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

TEST_F(FirmwareHandlerVerificationStartedTest, StatOnActiveHashReturnsFailure)
{
    getToVerificationStarted(hashBlobId);
    ASSERT_TRUE(handler->canHandleBlob(activeHashBlobId));

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

TEST_F(FirmwareHandlerVerificationStartedTest, StatOnVerifyBlobReturnsFailure)
{
    /* the verifyBlobId is available starting at verificationPending. */
    getToVerificationStarted(staticLayoutBlobId);
    ASSERT_TRUE(handler->canHandleBlob(verifyBlobId));

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

TEST_F(FirmwareHandlerVerificationStartedTest, StatOnNormalBlobsReturnsSuccess)
{
    getToVerificationStarted(staticLayoutBlobId);

    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);
    }
}

/*
 * writemeta(session)
 */
TEST_F(FirmwareHandlerVerificationStartedTest,
       WriteMetaOnVerifySessionReturnsFailure)
{
    getToVerificationStarted(staticLayoutBlobId);

    std::vector<std::uint8_t> bytes = {0x01, 0x02};
    EXPECT_FALSE(handler->writeMeta(session, 0, bytes));
}

/*
 * write(session)
 */
TEST_F(FirmwareHandlerVerificationStartedTest,
       WriteOnVerifySessionReturnsFailure)
{
    getToVerificationStarted(staticLayoutBlobId);

    std::vector<std::uint8_t> bytes = {0x01, 0x02};
    EXPECT_FALSE(handler->write(session, 0, bytes));
}

/*
 * open(blob) - there is nothing you can open, this state has an open file.
 */
TEST_F(FirmwareHandlerVerificationStartedTest,
       AttemptToOpenImageFileReturnsFailure)
{
    /* Attempt to open a file one normally can open, however, as there is
     * already a file open, this will fail.
     */
    getToVerificationStarted(staticLayoutBlobId);

    auto blobsToOpen = handler->getBlobIds();
    for (const auto& blob : blobsToOpen)
    {
        EXPECT_FALSE(handler->open(session + 1, flags, blob));
    }
}

/*
 * read(session)
 */
TEST_F(FirmwareHandlerVerificationStartedTest, ReadOfVerifyBlobReturnsEmpty)
{
    getToVerificationStarted(staticLayoutBlobId);
    EXPECT_THAT(handler->read(session, 0, 1), IsEmpty());
}

/*
 * commit(session)
 */
TEST_F(FirmwareHandlerVerificationStartedTest,
       CommitOnVerifyDuringVerificationHasNoImpact)
{
    getToVerificationStarted(staticLayoutBlobId);
    EXPECT_TRUE(handler->commit(session, {}));
    expectedState(FirmwareBlobHandler::UpdateState::verificationStarted);
}

/*
 * close(session) - close while state if verificationStarted without calling
 * stat first will abort.
 * TODO: implement this test when we implement abort.
 */

} // namespace
} // namespace ipmi_flash
<commit_msg>test: firmware verificationStarted: additional stat()<commit_after>/* The goal of these tests is to verify the behavior of all blob commands given
 * the current state is verificationStarted.  This state is achieved as a out of
 * verificationPending.
 */
#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::IsEmpty;
using ::testing::Return;
using ::testing::UnorderedElementsAreArray;

/*
 * 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)
 *
 * Testing canHandleBlob is uninteresting in this state.  Getting the BlobIDs
 * will inform what canHandleBlob will return.
 */

class FirmwareHandlerVerificationStartedTest : public IpmiOnlyFirmwareStaticTest
{
  protected:
    void getToVerificationStarted(const std::string& blobId)
    {
        EXPECT_CALL(imageMock, open(blobId)).WillOnce(Return(true));
        EXPECT_TRUE(handler->open(session, flags, blobId));
        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);
    }

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

/*
 * canHandleBlob(blob)
 * getBlobIds()
 */
TEST_F(FirmwareHandlerVerificationStartedTest, GetBlobIdsReturnsExpectedList)
{
    getToVerificationStarted(staticLayoutBlobId);

    std::vector<std::string> expectedList = {
        activeImageBlobId, staticLayoutBlobId, hashBlobId, verifyBlobId};

    EXPECT_THAT(handler->getBlobIds(), UnorderedElementsAreArray(expectedList));

    for (const auto& blob : expectedList)
    {
        EXPECT_TRUE(handler->canHandleBlob(blob));
    }
}

/*
 * stat(session)
 */
TEST_F(FirmwareHandlerVerificationStartedTest,
       StatOnVerifyBlobIdAfterCommitChecksStateAndReturnsRunning)
{
    getToVerificationStarted(staticLayoutBlobId);
    EXPECT_CALL(*verifyMockPtr, checkVerificationState())
        .WillOnce(Return(VerifyCheckResponses::running));

    blobs::BlobMeta meta, expectedMeta = {};
    expectedMeta.size = 0;
    expectedMeta.blobState = flags | blobs::StateFlags::committing;
    expectedMeta.metadata.push_back(
        static_cast<std::uint8_t>(VerifyCheckResponses::running));

    EXPECT_TRUE(handler->stat(session, &meta));
    EXPECT_EQ(expectedMeta, meta);
}

TEST_F(FirmwareHandlerVerificationStartedTest,
       StatOnVerifyBlobIdAfterCommitChecksStateAndReturnsOther)
{
    getToVerificationStarted(staticLayoutBlobId);
    EXPECT_CALL(*verifyMockPtr, checkVerificationState())
        .WillOnce(Return(VerifyCheckResponses::other));

    blobs::BlobMeta meta, expectedMeta = {};
    expectedMeta.size = 0;
    expectedMeta.blobState = flags | blobs::StateFlags::committing;
    expectedMeta.metadata.push_back(
        static_cast<std::uint8_t>(VerifyCheckResponses::other));

    EXPECT_TRUE(handler->stat(session, &meta));
    EXPECT_EQ(expectedMeta, meta);
}

TEST_F(FirmwareHandlerVerificationStartedTest,
       StatOnVerifyBlobIdAfterCommitCheckStateAndReturnsFailed)
{
    /* If the returned state from the verification handler is failed, it sets
     * commit_error and transitions to verificationCompleted.
     */
    getToVerificationStarted(staticLayoutBlobId);
    EXPECT_CALL(*verifyMockPtr, checkVerificationState())
        .WillOnce(Return(VerifyCheckResponses::failed));

    blobs::BlobMeta meta, expectedMeta = {};
    expectedMeta.size = 0;
    expectedMeta.blobState = flags | blobs::StateFlags::commit_error;
    expectedMeta.metadata.push_back(
        static_cast<std::uint8_t>(VerifyCheckResponses::failed));

    EXPECT_TRUE(handler->stat(session, &meta));
    EXPECT_EQ(expectedMeta, meta);
    expectedState(FirmwareBlobHandler::UpdateState::verificationCompleted);
}

TEST_F(FirmwareHandlerVerificationStartedTest,
       StatOnVerifyBlobIdAfterCommitCheckStateAndReturnsSuccess)
{
    /* If the returned state from the verification handler is success, it sets
     * committed and transitions to verificationCompleted.
     */
    getToVerificationStarted(staticLayoutBlobId);
    EXPECT_CALL(*verifyMockPtr, checkVerificationState())
        .WillOnce(Return(VerifyCheckResponses::success));

    blobs::BlobMeta meta, expectedMeta = {};
    expectedMeta.size = 0;
    expectedMeta.blobState = flags | blobs::StateFlags::committed;
    expectedMeta.metadata.push_back(
        static_cast<std::uint8_t>(VerifyCheckResponses::success));

    EXPECT_TRUE(handler->stat(session, &meta));
    EXPECT_EQ(expectedMeta, meta);
    expectedState(FirmwareBlobHandler::UpdateState::verificationCompleted);
}

/* TODO: Once verificationCompleted is the state, canHandleBlob should accept
 * updateBlobId.
 */

/* TODO: deleteBlob(blob) */

/*
 * stat(blob)
 */
TEST_F(FirmwareHandlerVerificationStartedTest, StatOnActiveImageReturnsFailure)
{
    getToVerificationStarted(staticLayoutBlobId);
    ASSERT_TRUE(handler->canHandleBlob(activeImageBlobId));

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

TEST_F(FirmwareHandlerVerificationStartedTest, StatOnActiveHashReturnsFailure)
{
    getToVerificationStarted(hashBlobId);
    ASSERT_TRUE(handler->canHandleBlob(activeHashBlobId));

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

TEST_F(FirmwareHandlerVerificationStartedTest, StatOnVerifyBlobReturnsFailure)
{
    /* the verifyBlobId is available starting at verificationPending. */
    getToVerificationStarted(staticLayoutBlobId);
    ASSERT_TRUE(handler->canHandleBlob(verifyBlobId));

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

TEST_F(FirmwareHandlerVerificationStartedTest, StatOnNormalBlobsReturnsSuccess)
{
    getToVerificationStarted(staticLayoutBlobId);

    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);
    }
}

/*
 * writemeta(session)
 */
TEST_F(FirmwareHandlerVerificationStartedTest,
       WriteMetaOnVerifySessionReturnsFailure)
{
    getToVerificationStarted(staticLayoutBlobId);

    std::vector<std::uint8_t> bytes = {0x01, 0x02};
    EXPECT_FALSE(handler->writeMeta(session, 0, bytes));
}

/*
 * write(session)
 */
TEST_F(FirmwareHandlerVerificationStartedTest,
       WriteOnVerifySessionReturnsFailure)
{
    getToVerificationStarted(staticLayoutBlobId);

    std::vector<std::uint8_t> bytes = {0x01, 0x02};
    EXPECT_FALSE(handler->write(session, 0, bytes));
}

/*
 * open(blob) - there is nothing you can open, this state has an open file.
 */
TEST_F(FirmwareHandlerVerificationStartedTest,
       AttemptToOpenImageFileReturnsFailure)
{
    /* Attempt to open a file one normally can open, however, as there is
     * already a file open, this will fail.
     */
    getToVerificationStarted(staticLayoutBlobId);

    auto blobsToOpen = handler->getBlobIds();
    for (const auto& blob : blobsToOpen)
    {
        EXPECT_FALSE(handler->open(session + 1, flags, blob));
    }
}

/*
 * read(session)
 */
TEST_F(FirmwareHandlerVerificationStartedTest, ReadOfVerifyBlobReturnsEmpty)
{
    getToVerificationStarted(staticLayoutBlobId);
    EXPECT_THAT(handler->read(session, 0, 1), IsEmpty());
}

/*
 * commit(session)
 */
TEST_F(FirmwareHandlerVerificationStartedTest,
       CommitOnVerifyDuringVerificationHasNoImpact)
{
    getToVerificationStarted(staticLayoutBlobId);
    EXPECT_TRUE(handler->commit(session, {}));
    expectedState(FirmwareBlobHandler::UpdateState::verificationStarted);
}

/*
 * close(session) - close while state if verificationStarted without calling
 * stat first will abort.
 * TODO: implement this test when we implement abort.
 */

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


<commit_before>#include "dioptre/graphics/graphics_interface.h"
#include "dioptre/graphics/perspective_camera.h"

namespace dioptre {
namespace graphics {

// TODO(Tobscher) use aspect ratio from window
GraphicsInterface::GraphicsInterface() :
  Module("dioptre.graphics"),
  scene_(new Scene()),
  camera_(new PerspectiveCamera(28.0, 800/600, 1, 10000))
{
  camera_->getTransform()->setPosition(0,100,25);
  camera_->getTransform()->lookAt(0.0f, 0.0f, 0.0f);
}

void GraphicsInterface::update() {
  render();
}

Scene* GraphicsInterface::getScene() {
  return scene_.get();
}

Camera* GraphicsInterface::getCamera() {
  return camera_.get();
}

} // graphics
} // dioptre
<commit_msg>use 16:10 aspect ratio<commit_after>#include "dioptre/graphics/graphics_interface.h"
#include "dioptre/graphics/perspective_camera.h"

namespace dioptre {
namespace graphics {

// TODO(Tobscher) use aspect ratio from window
// Add method to define camera
GraphicsInterface::GraphicsInterface() :
  Module("dioptre.graphics"),
  scene_(new Scene()),
  camera_(new PerspectiveCamera(28.0, 1280/800, 1, 10000))
{
  camera_->getTransform()->setPosition(0,100,25);
  camera_->getTransform()->lookAt(0.0f, 0.0f, 0.0f);
}

void GraphicsInterface::update() {
  render();
}

Scene* GraphicsInterface::getScene() {
  return scene_.get();
}

Camera* GraphicsInterface::getCamera() {
  return camera_.get();
}

} // graphics
} // dioptre
<|endoftext|>


<commit_before>#include<ros/ros.h>
#include<servo_msgs/IdBased.h>
#include<ics3/ics>

ics::ICS3* driver {nullptr};
ros::Publisher pub;

void move(const servo_msgs::IdBased::ConstPtr& msg) {
  servo_msgs::IdBased result;
  try {
    auto&& now_pos = driver->move(msg->id, ics::Angle::newDegree(msg->angle));
    result.angle = std::move(std::move(now_pos)); // now_pos is universal reference, but now use after code it. use move
    result.id = msg->id;
    pub.publish(std::move(result));
  } catch (std::runtime_error e) {
    ROS_INFO("Communicate error: %s", e.what());
  }
}

int main(int argc, char** argv) {
  ros::init(argc, argv, "servo_krs_node");
  ros::NodeHandle pn {"~"};
  std::string path {"/dev/ttyUSB0"};
  pn.param<std::string>("path", path, path);
  ROS_INFO("Open servo motor path: %s", path.c_str());
  ics::ICS3 ics {std::move(path)};
  driver = &ics;
  ros::NodeHandle n {};
  ros::Subscriber sub {n.subscribe("cmd_krs", 100, move)};
  pub = n.advertise<servo_msgs::IdBased>("pose_krs", 10);
  ros::spin();
  return 0;
}
<commit_msg>Fix double move, duplication<commit_after>#include<ros/ros.h>
#include<servo_msgs/IdBased.h>
#include<ics3/ics>

ics::ICS3* driver {nullptr};
ros::Publisher pub;

void move(const servo_msgs::IdBased::ConstPtr& msg) {
  servo_msgs::IdBased result;
  try {
    auto&& now_pos = driver->move(msg->id, ics::Angle::newDegree(msg->angle));
    result.angle = std::move(now_pos); // now_pos is universal reference, but now use after code it. use move
    result.id = msg->id;
    pub.publish(std::move(result));
  } catch (std::runtime_error e) {
    ROS_INFO("Communicate error: %s", e.what());
  }
}

int main(int argc, char** argv) {
  ros::init(argc, argv, "servo_krs_node");
  ros::NodeHandle pn {"~"};
  std::string path {"/dev/ttyUSB0"};
  pn.param<std::string>("path", path, path);
  ROS_INFO("Open servo motor path: %s", path.c_str());
  ics::ICS3 ics {std::move(path)};
  driver = &ics;
  ros::NodeHandle n {};
  ros::Subscriber sub {n.subscribe("cmd_krs", 100, move)};
  pub = n.advertise<servo_msgs::IdBased>("pose_krs", 10);
  ros::spin();
  return 0;
}
<|endoftext|>


<commit_before>/**
 * This file is part of the "libfnord" project
 *   Copyright (c) 2015 Paul Asmuth
 *
 * FnordMetric is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License v3.0. You should have received a
 * copy of the GNU General Public License along with this program. If not, see
 * <http://www.gnu.org/licenses/>.
 */
#include <eventql/sql/qtree/SequentialScanNode.h>
#include <eventql/sql/qtree/ColumnReferenceNode.h>
#include <eventql/sql/qtree/CallExpressionNode.h>
#include <eventql/sql/qtree/LiteralExpressionNode.h>
#include <eventql/sql/qtree/QueryTreeUtil.h>

using namespace stx;

namespace csql {

bool ScanConstraint::operator==(const ScanConstraint& other) const {
  return
      column_name == other.column_name &&
      type == other.type &&
      value == other.value;
}

bool ScanConstraint::operator!=(const ScanConstraint& other) const {
  return !(*this == other);
}

SequentialScanNode::SequentialScanNode(
    const TableInfo& table_info,
    RefPtr<TableProvider> table_provider,
    Vector<RefPtr<SelectListNode>> select_list,
    Option<RefPtr<ValueExpressionNode>> where_expr) :
    SequentialScanNode(
        table_info,
        table_provider,
        select_list,
        where_expr,
        AggregationStrategy::NO_AGGREGATION) {}

SequentialScanNode::SequentialScanNode(
    const TableInfo& table_info,
    RefPtr<TableProvider> table_provider,
    Vector<RefPtr<SelectListNode>> select_list,
    Option<RefPtr<ValueExpressionNode>> where_expr,
    AggregationStrategy aggr_strategy) :
    table_name_(table_info.table_name),
    table_provider_(table_provider),
    select_list_(select_list),
    where_expr_(where_expr),
    aggr_strategy_(aggr_strategy) {
  for (const auto& col : table_info.columns) {
    table_columns_.emplace_back(col.column_name);
  }

  if (!where_expr_.isEmpty()) {
    QueryTreeUtil::findConstraints(where_expr_.get(), &constraints_);
  }
}

SequentialScanNode::SequentialScanNode(
    const SequentialScanNode& other) :
    table_name_(other.table_name_),
    output_columns_(other.output_columns_),
    aggr_strategy_(other.aggr_strategy_),
    constraints_(other.constraints_) {
  for (const auto& e : other.select_list_) {
    select_list_.emplace_back(e->deepCopyAs<SelectListNode>());
  }

  if (!other.where_expr_.isEmpty()) {
    where_expr_ = Some(
        other.where_expr_.get()->deepCopyAs<ValueExpressionNode>());
  }
}

Option<RefPtr<ValueExpressionNode>> SequentialScanNode::whereExpression() const {
  return where_expr_;
}

void SequentialScanNode::setWhereExpression(RefPtr<ValueExpressionNode> e) {
  where_expr_ = Some(e);
  constraints_.clear();
  QueryTreeUtil::findConstraints(e, &constraints_);
}

const String& SequentialScanNode::tableName() const {
  return table_name_;
}

const String& SequentialScanNode::tableAlias() const {
  return table_alias_;
}

void SequentialScanNode::setTableName(const String& table_name) {
  table_name_ = table_name;
}

void SequentialScanNode::setTableAlias(const String& table_alias) {
  table_alias_ = table_alias;
}

Vector<RefPtr<SelectListNode>> SequentialScanNode::selectList() const {
  return select_list_;
}

void SequentialScanNode::findSelectedColumnNames(
    RefPtr<ValueExpressionNode> expr,
    Set<String>* columns) const {
  auto colname = dynamic_cast<ColumnReferenceNode*>(expr.get());
  if (colname) {
    columns->emplace(normalizeColumnName(colname->fieldName()));
  }

  for (const auto& a : expr->arguments()) {
    findSelectedColumnNames(a, columns);
  }
}

Set<String> SequentialScanNode::selectedColumns() const {
  Set<String> columns;

  for (const auto& sl : select_list_) {
    findSelectedColumnNames(sl->expression(), &columns);
  }

  return columns;
}

Vector<String> SequentialScanNode::outputColumns() const {
  return output_columns_;
}

Vector<QualifiedColumn> SequentialScanNode::allColumns() const {
  String qualifier;
  if (table_alias_.empty()) {
    qualifier = table_name_ + ".";
  } else {
    qualifier = table_alias_ + ".";
  }

  Vector<QualifiedColumn> cols;
  for (const auto& c : table_columns_) {
    QualifiedColumn qc;
    qc.short_name = c;
    qc.qualified_name = qualifier + c;
    cols.emplace_back(qc);
  }

  return cols;
}

void SequentialScanNode::normalizeColumnNames() {
  auto normalizer = [this] (RefPtr<ColumnReferenceNode> expr) {
    expr->setColumnName(normalizeColumnName(expr->columnName()));
  };

  for (auto& sl : select_list_) {
    QueryTreeUtil::findColumns(sl->expression(), normalizer);
    output_columns_.emplace_back(sl->columnName());
  }

  if (!where_expr_.isEmpty()) {
    QueryTreeUtil::findColumns(where_expr_.get(), normalizer);
  }
}

String SequentialScanNode::normalizeColumnName(const String& column_name) const {
  if (!table_name_.empty() &&
      StringUtil::beginsWith(column_name, table_name_ + ".")) {
    return column_name.substr(table_name_.size() + 1);
  }

  if (!table_alias_.empty() &&
      StringUtil::beginsWith(column_name, table_alias_ + ".")) {
    return column_name.substr(table_alias_.size() + 1);
  }

  return column_name;
}

size_t SequentialScanNode::getColumnIndex(
    const String& column_name,
    bool allow_add /* = false */) {
  bool have_name = !table_name_.empty();
  bool have_alias = !table_alias_.empty();
  auto col = normalizeColumnName(column_name);
  auto col_with_name = table_name_ + "." + col;
  auto col_with_alias = table_alias_ + "." + col;

  for (size_t i = 0; i < select_list_.size(); ++i) {
    if ((select_list_[i]->columnName() == col) ||
        (have_name && select_list_[i]->columnName() == col_with_name) ||
        (have_alias && select_list_[i]->columnName() == col_with_alias)) {
      return i;
    }
  }

  bool found = false;
  for (const auto& c : table_columns_) {
    if (c == col) {
      found = true;
      break;
    }
  }

  if (!found) {
    return -1;
  }

  auto slnode = new SelectListNode(new ColumnReferenceNode(col));
  slnode->setAlias(col);
  select_list_.emplace_back(slnode);
  return select_list_.size() - 1;
}

AggregationStrategy SequentialScanNode::aggregationStrategy() const {
  return aggr_strategy_;
}

void SequentialScanNode::setAggregationStrategy(AggregationStrategy strategy) {
  aggr_strategy_ = strategy;
}

RefPtr<QueryTreeNode> SequentialScanNode::deepCopy() const {
  return new SequentialScanNode(*this);
}

String SequentialScanNode::toString() const {
  String aggr;
  switch (aggr_strategy_) {

    case AggregationStrategy::NO_AGGREGATION:
      aggr = "NO_AGGREGATION";
      break;

    case AggregationStrategy::AGGREGATE_WITHIN_RECORD_FLAT:
      aggr = "AGGREGATE_WITHIN_RECORD_FLAT";
      break;

    case AggregationStrategy::AGGREGATE_WITHIN_RECORD_DEEP:
      aggr = "AGGREGATE_WITHIN_RECORD_DEEP";
      break;

    case AggregationStrategy::AGGREGATE_ALL:
      aggr = "AGGREGATE_ALL";
      break;

  };

  auto str = StringUtil::format(
      "(seqscan (table $0) (aggregate $1) (select-list",
      table_name_,
      aggr);

  for (const auto& e : select_list_) {
    str += " " + e->toString();
  }
  str += ")";

  if (!where_expr_.isEmpty()) {
    str += StringUtil::format(" (where $0)", where_expr_.get()->toString());
  }

  str += ")";
  return str;
}

const Vector<ScanConstraint>& SequentialScanNode::constraints() const {
  return constraints_;
}

void SequentialScanNode::encode(
    QueryTreeCoder* coder,
    const SequentialScanNode& node,
    stx::OutputStream* os) {
  RAISE(kNotYetImplementedError, "nyi");
}

RefPtr<QueryTreeNode> SequentialScanNode::decode(
    QueryTreeCoder* coder,
    stx::InputStream* os) {
  RAISE(kNotYetImplementedError, "nyi");
}

} // namespace csql
<commit_msg>SeqScanNode decode and encode<commit_after>/*
 * This file is part of the "libfnord" project
 *   Copyright (c) 2015 Paul Asmuth
 *
 * FnordMetric is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License v3.0. You should have received a
 * copy of the GNU General Public License along with this program. If not, see
 * <http://www.gnu.org/licenses/>.
 */
#include <eventql/sql/qtree/SequentialScanNode.h>
#include <eventql/sql/qtree/ColumnReferenceNode.h>
#include <eventql/sql/qtree/CallExpressionNode.h>
#include <eventql/sql/qtree/LiteralExpressionNode.h>
#include <eventql/sql/qtree/QueryTreeUtil.h>

using namespace stx;

namespace csql {

bool ScanConstraint::operator==(const ScanConstraint& other) const {
  return
      column_name == other.column_name &&
      type == other.type &&
      value == other.value;
}

bool ScanConstraint::operator!=(const ScanConstraint& other) const {
  return !(*this == other);
}

SequentialScanNode::SequentialScanNode(
    const TableInfo& table_info,
    RefPtr<TableProvider> table_provider,
    Vector<RefPtr<SelectListNode>> select_list,
    Option<RefPtr<ValueExpressionNode>> where_expr) :
    SequentialScanNode(
        table_info,
        table_provider,
        select_list,
        where_expr,
        AggregationStrategy::NO_AGGREGATION) {}

SequentialScanNode::SequentialScanNode(
    const TableInfo& table_info,
    RefPtr<TableProvider> table_provider,
    Vector<RefPtr<SelectListNode>> select_list,
    Option<RefPtr<ValueExpressionNode>> where_expr,
    AggregationStrategy aggr_strategy) :
    table_name_(table_info.table_name),
    table_provider_(table_provider),
    select_list_(select_list),
    where_expr_(where_expr),
    aggr_strategy_(aggr_strategy) {
  for (const auto& col : table_info.columns) {
    table_columns_.emplace_back(col.column_name);
  }

  if (!where_expr_.isEmpty()) {
    QueryTreeUtil::findConstraints(where_expr_.get(), &constraints_);
  }
}

SequentialScanNode::SequentialScanNode(
    const SequentialScanNode& other) :
    table_name_(other.table_name_),
    output_columns_(other.output_columns_),
    aggr_strategy_(other.aggr_strategy_),
    constraints_(other.constraints_) {
  for (const auto& e : other.select_list_) {
    select_list_.emplace_back(e->deepCopyAs<SelectListNode>());
  }

  if (!other.where_expr_.isEmpty()) {
    where_expr_ = Some(
        other.where_expr_.get()->deepCopyAs<ValueExpressionNode>());
  }
}

Option<RefPtr<ValueExpressionNode>> SequentialScanNode::whereExpression() const {
  return where_expr_;
}

void SequentialScanNode::setWhereExpression(RefPtr<ValueExpressionNode> e) {
  where_expr_ = Some(e);
  constraints_.clear();
  QueryTreeUtil::findConstraints(e, &constraints_);
}

const String& SequentialScanNode::tableName() const {
  return table_name_;
}

const String& SequentialScanNode::tableAlias() const {
  return table_alias_;
}

void SequentialScanNode::setTableName(const String& table_name) {
  table_name_ = table_name;
}

void SequentialScanNode::setTableAlias(const String& table_alias) {
  table_alias_ = table_alias;
}

Vector<RefPtr<SelectListNode>> SequentialScanNode::selectList() const {
  return select_list_;
}

void SequentialScanNode::findSelectedColumnNames(
    RefPtr<ValueExpressionNode> expr,
    Set<String>* columns) const {
  auto colname = dynamic_cast<ColumnReferenceNode*>(expr.get());
  if (colname) {
    columns->emplace(normalizeColumnName(colname->fieldName()));
  }

  for (const auto& a : expr->arguments()) {
    findSelectedColumnNames(a, columns);
  }
}

Set<String> SequentialScanNode::selectedColumns() const {
  Set<String> columns;

  for (const auto& sl : select_list_) {
    findSelectedColumnNames(sl->expression(), &columns);
  }

  return columns;
}

Vector<String> SequentialScanNode::outputColumns() const {
  return output_columns_;
}

Vector<QualifiedColumn> SequentialScanNode::allColumns() const {
  String qualifier;
  if (table_alias_.empty()) {
    qualifier = table_name_ + ".";
  } else {
    qualifier = table_alias_ + ".";
  }

  Vector<QualifiedColumn> cols;
  for (const auto& c : table_columns_) {
    QualifiedColumn qc;
    qc.short_name = c;
    qc.qualified_name = qualifier + c;
    cols.emplace_back(qc);
  }

  return cols;
}

void SequentialScanNode::normalizeColumnNames() {
  auto normalizer = [this] (RefPtr<ColumnReferenceNode> expr) {
    expr->setColumnName(normalizeColumnName(expr->columnName()));
  };

  for (auto& sl : select_list_) {
    QueryTreeUtil::findColumns(sl->expression(), normalizer);
    output_columns_.emplace_back(sl->columnName());
  }

  if (!where_expr_.isEmpty()) {
    QueryTreeUtil::findColumns(where_expr_.get(), normalizer);
  }
}

String SequentialScanNode::normalizeColumnName(const String& column_name) const {
  if (!table_name_.empty() &&
      StringUtil::beginsWith(column_name, table_name_ + ".")) {
    return column_name.substr(table_name_.size() + 1);
  }

  if (!table_alias_.empty() &&
      StringUtil::beginsWith(column_name, table_alias_ + ".")) {
    return column_name.substr(table_alias_.size() + 1);
  }

  return column_name;
}

size_t SequentialScanNode::getColumnIndex(
    const String& column_name,
    bool allow_add /* = false */) {
  bool have_name = !table_name_.empty();
  bool have_alias = !table_alias_.empty();
  auto col = normalizeColumnName(column_name);
  auto col_with_name = table_name_ + "." + col;
  auto col_with_alias = table_alias_ + "." + col;

  for (size_t i = 0; i < select_list_.size(); ++i) {
    if ((select_list_[i]->columnName() == col) ||
        (have_name && select_list_[i]->columnName() == col_with_name) ||
        (have_alias && select_list_[i]->columnName() == col_with_alias)) {
      return i;
    }
  }

  bool found = false;
  for (const auto& c : table_columns_) {
    if (c == col) {
      found = true;
      break;
    }
  }

  if (!found) {
    return -1;
  }

  auto slnode = new SelectListNode(new ColumnReferenceNode(col));
  slnode->setAlias(col);
  select_list_.emplace_back(slnode);
  return select_list_.size() - 1;
}

AggregationStrategy SequentialScanNode::aggregationStrategy() const {
  return aggr_strategy_;
}

void SequentialScanNode::setAggregationStrategy(AggregationStrategy strategy) {
  aggr_strategy_ = strategy;
}

RefPtr<QueryTreeNode> SequentialScanNode::deepCopy() const {
  return new SequentialScanNode(*this);
}

String SequentialScanNode::toString() const {
  String aggr;
  switch (aggr_strategy_) {

    case AggregationStrategy::NO_AGGREGATION:
      aggr = "NO_AGGREGATION";
      break;

    case AggregationStrategy::AGGREGATE_WITHIN_RECORD_FLAT:
      aggr = "AGGREGATE_WITHIN_RECORD_FLAT";
      break;

    case AggregationStrategy::AGGREGATE_WITHIN_RECORD_DEEP:
      aggr = "AGGREGATE_WITHIN_RECORD_DEEP";
      break;

    case AggregationStrategy::AGGREGATE_ALL:
      aggr = "AGGREGATE_ALL";
      break;

  };

  auto str = StringUtil::format(
      "(seqscan (table $0) (aggregate $1) (select-list",
      table_name_,
      aggr);

  for (const auto& e : select_list_) {
    str += " " + e->toString();
  }
  str += ")";

  if (!where_expr_.isEmpty()) {
    str += StringUtil::format(" (where $0)", where_expr_.get()->toString());
  }

  str += ")";
  return str;
}

const Vector<ScanConstraint>& SequentialScanNode::constraints() const {
  return constraints_;
}

void SequentialScanNode::encode(
    QueryTreeCoder* coder,
    const SequentialScanNode& node,
    stx::OutputStream* os) {

  os->appendLenencString(node.table_name_);
  os->appendVarUInt(node.select_list_.size());
  for (size_t i = 0; i < node.select_list_.size(); ++i) {
   coder->encode(node.select_list_[i].get(), os);
  }

  os->appendUInt8((uint8_t) node.aggr_strategy_);

  if (!node.where_expr_.isEmpty()) {
    os->appendUInt8(1);
    coder->encode(node.where_expr_.get().get(), os);
  } else {
    os->appendUInt8(0);
  }
}

RefPtr<QueryTreeNode> SequentialScanNode::decode(
    QueryTreeCoder* coder,
    stx::InputStream* is) {
  auto table_provider = coder->getTransaction()->getTableProvider();
  Option<TableInfo> table_info = table_provider->describe(is->readLenencString());
  if (table_info.isEmpty()) {
    RAISE(kIllegalArgumentError, "table not found");
  }

  auto select_list_size = is->readVarUInt();
  Vector<RefPtr<SelectListNode>> select_list;
  for (auto i = 0; i < select_list_size; ++i) {
    select_list.emplace_back(coder->decode(is).asInstanceOf<SelectListNode>());
  }

  auto aggr_strategy = (AggregationStrategy) is->readUInt8();

  Option<RefPtr<ValueExpressionNode>> where_expr;
  if (is->readUInt8()) {
    where_expr = coder->decode(is).asInstanceOf<ValueExpressionNode>();
  }

  return new SequentialScanNode(
      table_info.get(),
      table_provider,
      select_list,
      where_expr,
      aggr_strategy);
}

} // namespace csql
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com>
 */

#include <gtest/gtest.h>
#include <uavcan/internal/marshalling/integer_spec.hpp>
#include <uavcan/internal/marshalling/types.hpp>

TEST(Integer, Limits)
{
    using uavcan::IntegerSpec;
    using uavcan::SignednessSigned;
    using uavcan::SignednessUnsigned;
    using uavcan::CastModeSaturate;
    using uavcan::CastModeTruncate;

    typedef IntegerSpec<8,  SignednessUnsigned, CastModeSaturate> UInt8;
    typedef IntegerSpec<4,    SignednessSigned, CastModeTruncate> SInt4;
    typedef IntegerSpec<32, SignednessUnsigned, CastModeTruncate> UInt32;
    typedef IntegerSpec<40, SignednessUnsigned, CastModeSaturate> UInt40;
    typedef IntegerSpec<64, SignednessUnsigned, CastModeTruncate> UInt64;
    typedef IntegerSpec<64,   SignednessSigned, CastModeSaturate> SInt64;
    typedef IntegerSpec<63, SignednessUnsigned, CastModeSaturate> UInt63;

    ASSERT_EQ(255, UInt8::max());
    ASSERT_EQ(0, UInt8::min());

    ASSERT_EQ(7, SInt4::max());
    ASSERT_EQ(-8, SInt4::min());

    ASSERT_EQ(0xFFFFFFFF, UInt32::max());
    ASSERT_EQ(0, UInt32::min());

    ASSERT_EQ(0xFFFFFFFFFF, UInt40::max());
    ASSERT_EQ(0, UInt40::min());

    ASSERT_EQ(0xFFFFFFFFFFFFFFFF, UInt64::max());
    ASSERT_EQ(0, UInt64::min());

    ASSERT_EQ(0x7FFFFFFFFFFFFFFF, SInt64::max());
    ASSERT_EQ(-0x8000000000000000, SInt64::min());

    ASSERT_EQ(0x7FFFFFFFFFFFFFFF, UInt63::max());
    ASSERT_EQ(0, UInt63::min());

    ASSERT_EQ(SInt64::max(), UInt63::max());
}

TEST(Integer, Basic)
{
    using uavcan::IntegerSpec;
    using uavcan::SignednessSigned;
    using uavcan::SignednessUnsigned;
    using uavcan::CastModeSaturate;
    using uavcan::CastModeTruncate;
    using uavcan::StorageType;

    uavcan::StaticTransferBuffer<100> buf;
    uavcan::BitStream bs_wr(buf);
    uavcan::ScalarCodec sc_wr(bs_wr);

    typedef IntegerSpec<8,  SignednessUnsigned, CastModeSaturate> UInt8S;
    typedef IntegerSpec<4,    SignednessSigned, CastModeTruncate> SInt4T;
    typedef IntegerSpec<32, SignednessUnsigned, CastModeTruncate> UInt32T;
    typedef IntegerSpec<40, SignednessUnsigned, CastModeSaturate> UInt40S;
    typedef IntegerSpec<64, SignednessUnsigned, CastModeTruncate> UInt64T;
    typedef IntegerSpec<58,   SignednessSigned, CastModeSaturate> SInt58S;
    typedef IntegerSpec<63, SignednessUnsigned, CastModeSaturate> UInt63S;
    typedef IntegerSpec<10,   SignednessSigned, CastModeSaturate> SInt10S;
    typedef IntegerSpec<1,  SignednessUnsigned, CastModeSaturate> UInt1S;

    ASSERT_EQ(1, UInt8S::encode(UInt8S::StorageType(123), sc_wr));
    ASSERT_EQ(1, SInt4T::encode(SInt4T::StorageType(-0x44), sc_wr));
    ASSERT_EQ(1, UInt32T::encode(UInt32T::StorageType(0xFFFFFFFF), sc_wr));
    ASSERT_EQ(1, UInt40S::encode(UInt40S::StorageType(0xFFFFFFFFFFFFFFFF), sc_wr));
    ASSERT_EQ(1, UInt64T::encode(UInt64T::StorageType(0xFFFFFFFFFFFFFFFF), sc_wr));
    ASSERT_EQ(1, SInt58S::encode(SInt58S::StorageType(0xFFFFFFFFFFFFFFF), sc_wr));
    ASSERT_EQ(1, UInt63S::encode(UInt63S::StorageType(0xFFFFFFFFFFFFFFFF), sc_wr));
    ASSERT_EQ(1, SInt10S::encode(SInt10S::StorageType(-30000), sc_wr));
    ASSERT_EQ(1, UInt1S::encode(UInt1S::StorageType(42), sc_wr));

    std::cout << bs_wr.toString() << std::endl;

    uavcan::BitStream bs_rd(buf);
    uavcan::ScalarCodec sc_rd(bs_rd);

#define CHECK(IntType, expected_value) \
    do { \
        StorageType<IntType>::Type var(IntType::init()); \
        ASSERT_EQ(1, IntType::decode(var, sc_rd)); \
        ASSERT_EQ(expected_value, var); \
    } while (0)

    CHECK(UInt8S,  123);
    CHECK(SInt4T,  -4);
    CHECK(UInt32T, 0xFFFFFFFF);
    CHECK(UInt40S, 0xFFFFFFFFFF);
    CHECK(UInt64T, 0xFFFFFFFFFFFFFFFF);
    CHECK(SInt58S, 0x1FFFFFFFFFFFFFF);
    CHECK(UInt63S, 0x7FFFFFFFFFFFFFFF);
    CHECK(SInt10S, -512);
    CHECK(UInt1S,  1);

#undef CHECK

    StorageType<UInt1S>::Type var;
    ASSERT_EQ(0, UInt1S::decode(var, sc_rd));
}
<commit_msg>IntegerSpec test name fix<commit_after>/*
 * Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com>
 */

#include <gtest/gtest.h>
#include <uavcan/internal/marshalling/integer_spec.hpp>
#include <uavcan/internal/marshalling/types.hpp>

TEST(IntegerSpec, Limits)
{
    using uavcan::IntegerSpec;
    using uavcan::SignednessSigned;
    using uavcan::SignednessUnsigned;
    using uavcan::CastModeSaturate;
    using uavcan::CastModeTruncate;

    typedef IntegerSpec<8,  SignednessUnsigned, CastModeSaturate> UInt8;
    typedef IntegerSpec<4,    SignednessSigned, CastModeTruncate> SInt4;
    typedef IntegerSpec<32, SignednessUnsigned, CastModeTruncate> UInt32;
    typedef IntegerSpec<40, SignednessUnsigned, CastModeSaturate> UInt40;
    typedef IntegerSpec<64, SignednessUnsigned, CastModeTruncate> UInt64;
    typedef IntegerSpec<64,   SignednessSigned, CastModeSaturate> SInt64;
    typedef IntegerSpec<63, SignednessUnsigned, CastModeSaturate> UInt63;

    ASSERT_EQ(255, UInt8::max());
    ASSERT_EQ(0, UInt8::min());

    ASSERT_EQ(7, SInt4::max());
    ASSERT_EQ(-8, SInt4::min());

    ASSERT_EQ(0xFFFFFFFF, UInt32::max());
    ASSERT_EQ(0, UInt32::min());

    ASSERT_EQ(0xFFFFFFFFFF, UInt40::max());
    ASSERT_EQ(0, UInt40::min());

    ASSERT_EQ(0xFFFFFFFFFFFFFFFF, UInt64::max());
    ASSERT_EQ(0, UInt64::min());

    ASSERT_EQ(0x7FFFFFFFFFFFFFFF, SInt64::max());
    ASSERT_EQ(-0x8000000000000000, SInt64::min());

    ASSERT_EQ(0x7FFFFFFFFFFFFFFF, UInt63::max());
    ASSERT_EQ(0, UInt63::min());

    ASSERT_EQ(SInt64::max(), UInt63::max());
}

TEST(IntegerSpec, Basic)
{
    using uavcan::IntegerSpec;
    using uavcan::SignednessSigned;
    using uavcan::SignednessUnsigned;
    using uavcan::CastModeSaturate;
    using uavcan::CastModeTruncate;
    using uavcan::StorageType;

    uavcan::StaticTransferBuffer<100> buf;
    uavcan::BitStream bs_wr(buf);
    uavcan::ScalarCodec sc_wr(bs_wr);

    typedef IntegerSpec<8,  SignednessUnsigned, CastModeSaturate> UInt8S;
    typedef IntegerSpec<4,    SignednessSigned, CastModeTruncate> SInt4T;
    typedef IntegerSpec<32, SignednessUnsigned, CastModeTruncate> UInt32T;
    typedef IntegerSpec<40, SignednessUnsigned, CastModeSaturate> UInt40S;
    typedef IntegerSpec<64, SignednessUnsigned, CastModeTruncate> UInt64T;
    typedef IntegerSpec<58,   SignednessSigned, CastModeSaturate> SInt58S;
    typedef IntegerSpec<63, SignednessUnsigned, CastModeSaturate> UInt63S;
    typedef IntegerSpec<10,   SignednessSigned, CastModeSaturate> SInt10S;
    typedef IntegerSpec<1,  SignednessUnsigned, CastModeSaturate> UInt1S;

    ASSERT_EQ(1, UInt8S::encode(UInt8S::StorageType(123), sc_wr));
    ASSERT_EQ(1, SInt4T::encode(SInt4T::StorageType(-0x44), sc_wr));
    ASSERT_EQ(1, UInt32T::encode(UInt32T::StorageType(0xFFFFFFFF), sc_wr));
    ASSERT_EQ(1, UInt40S::encode(UInt40S::StorageType(0xFFFFFFFFFFFFFFFF), sc_wr));
    ASSERT_EQ(1, UInt64T::encode(UInt64T::StorageType(0xFFFFFFFFFFFFFFFF), sc_wr));
    ASSERT_EQ(1, SInt58S::encode(SInt58S::StorageType(0xFFFFFFFFFFFFFFF), sc_wr));
    ASSERT_EQ(1, UInt63S::encode(UInt63S::StorageType(0xFFFFFFFFFFFFFFFF), sc_wr));
    ASSERT_EQ(1, SInt10S::encode(SInt10S::StorageType(-30000), sc_wr));
    ASSERT_EQ(1, UInt1S::encode(UInt1S::StorageType(42), sc_wr));

    std::cout << bs_wr.toString() << std::endl;

    uavcan::BitStream bs_rd(buf);
    uavcan::ScalarCodec sc_rd(bs_rd);

#define CHECK(IntType, expected_value) \
    do { \
        StorageType<IntType>::Type var(IntType::init()); \
        ASSERT_EQ(1, IntType::decode(var, sc_rd)); \
        ASSERT_EQ(expected_value, var); \
    } while (0)

    CHECK(UInt8S,  123);
    CHECK(SInt4T,  -4);
    CHECK(UInt32T, 0xFFFFFFFF);
    CHECK(UInt40S, 0xFFFFFFFFFF);
    CHECK(UInt64T, 0xFFFFFFFFFFFFFFFF);
    CHECK(SInt58S, 0x1FFFFFFFFFFFFFF);
    CHECK(UInt63S, 0x7FFFFFFFFFFFFFFF);
    CHECK(SInt10S, -512);
    CHECK(UInt1S,  1);

#undef CHECK

    StorageType<UInt1S>::Type var;
    ASSERT_EQ(0, UInt1S::decode(var, sc_rd));
}
<|endoftext|>


<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/hwpf/fapi2/include/return_code.H $                 */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2012,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* 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.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
/**
 * @file return_code.H
 * @brief definitions for fapi2 return codes
 */

#ifndef __FAPI2_RETURN_CODE__
#define __FAPI2_RETURN_CODE__

#include <stdint.h>

#ifndef FAPI2_NO_FFDC
    #include <ffdc.H>
#endif

namespace fapi2
{
///
/// @brief Class representing a FAPI2 ReturnCode
///
// Remove the inheritance relationship with FirstFailureData if
// the platform doesn't support FFDC.
#ifdef FAPI2_NO_FFDC
class ReturnCode
#else
class ReturnCode : public FirstFailureData<ReturnCode>
#endif
{
    public:

        ///
        /// @brief Constructor.
        /// @param[in] i_rc the rc to set
        ///
        ReturnCode(const uint32_t i_rc = FAPI2_RC_SUCCESS):
            iv_rc(i_rc)
        {};

        ///
        /// @brief integral type conversion function. Returns the error code
        /// @return The error code
        ///
        inline operator uint32_t() const
        {
            return iv_rc;
        }

        ///
        /// @brief integral type conversion function. Returns the error code
        /// @return The error code
        ///
        inline operator uint64_t() const
        {
            return iv_rc;
        }

        ///
        /// @brief Returns true iff iv_rc != SUCCESS
        /// @return true or false
        ///
        inline operator bool() const
        {
            return iv_rc != FAPI2_RC_SUCCESS;
        }

        ///
        /// @brief Assignement operator
        ///
#ifdef DOXYGEN
        inline ReturnCode& operator=(const uint32_t& rhs);
        inline ReturnCode& operator=(const ReturnCodes& rhs);
#endif

        inline bool operator==(const uint32_t& rhs) const
        {
            return rhs == iv_rc;
        }

        inline bool operator==(const ReturnCodes& rhs) const
        {
            return rhs == iv_rc;
        }

        inline bool operator!=(const uint32_t& rhs) const
        {
            return rhs != iv_rc;
        }

        inline bool operator!=(const ReturnCodes& rhs) const
        {
            return rhs != iv_rc;
        }

        ///
        /// @brief Enumeration of return code creators
        ///
        enum returnCodeCreator
        {
            CREATOR_FAPI = 1,
            CREATOR_PLAT = 2,
            CREATOR_HWP = 3,
        };

        ///
        /// @brief Gets the creator of the return code
        /// @return ReturnCodeCreator
        ///
        inline returnCodeCreator getCreator(void) const
        {
            returnCodeCreator l_creator = CREATOR_HWP;

            if (iv_rc & FAPI2_RC_FAPI2_MASK)
            {
                l_creator = CREATOR_FAPI;
            }
            else if (iv_rc & FAPI2_RC_PLAT_MASK)
            {
                l_creator = CREATOR_PLAT;
            }

            return l_creator;
        }

        ///
        /// @brief explicit check for RC value
        /// @return true if this instance has a matching RC
        ///
        inline bool isRC(const ReturnCodes i_rc) const
        {
            return static_cast<uint32_t>(i_rc) == iv_rc;
        }

        ///
        /// @brief explicit check for RC value
        /// @return true if this instance has a matching RC
        ///
        inline bool isRC(const uint32_t i_rc) const
        {
            return i_rc == iv_rc;
        }

    private:
        uint32_t iv_rc;
};

/// This implementation assumes no exception handling and leverages thread-local
/// storage. For platforms without thread support, a global variable will
/// suffice for the error state.

extern thread_local uint64_t pib_error_mask;     /// the pib mask
extern thread_local uint64_t operational_state;  /// the operational mode
#ifndef PLAT_NO_THREAD_LOCAL_STORAGE
    extern thread_local ReturnCode current_err;      /// the current error state
#else
    extern ReturnCode current_err;
#endif

}

#endif
<commit_msg>Some updates to FAPI files<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/hwpf/fapi2/include/return_code.H $                 */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2012,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* 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.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
/**
 * @file return_code.H
 * @brief definitions for fapi2 return codes
 */

#ifndef __FAPI2_RETURN_CODE__
#define __FAPI2_RETURN_CODE__

#include <stdint.h>
#include <return_code_defs.H>

#ifndef FAPI2_NO_FFDC
    #include <ffdc.H>
#endif

namespace fapi2
{
///
/// @brief Class representing a FAPI2 ReturnCode
///
// Remove the inheritance relationship with FirstFailureData if
// the platform doesn't support FFDC.
#if defined (FAPI2_NO_FFDC) || defined (MINIMUM_FFDC)
class ReturnCode
#else
class ReturnCode : public FirstFailureData<ReturnCode>
#endif
{
    public:

        ///
        /// @brief Constructor.
        /// @param[in] i_rc the rc to set
        ///
        ReturnCode(const uint32_t i_rc = FAPI2_RC_SUCCESS):
            iv_rc(i_rc)
        {};

        ///
        /// @brief integral type conversion function. Returns the error code
        /// @return The error code
        ///
        inline operator uint32_t() const
        {
            return iv_rc;
        }

        ///
        /// @brief integral type conversion function. Returns the error code
        /// @return The error code
        ///
        inline operator uint64_t() const
        {
            return iv_rc;
        }

        ///
        /// @brief Returns true iff iv_rc != SUCCESS
        /// @return true or false
        ///
        inline operator bool() const
        {
            return iv_rc != FAPI2_RC_SUCCESS;
        }

        ///
        /// @brief Assignement operator
        ///
#ifdef DOXYGEN
        inline ReturnCode& operator=(const uint32_t& rhs);
        inline ReturnCode& operator=(const ReturnCodes& rhs);
#endif

        inline bool operator==(const uint32_t& rhs) const
        {
            return rhs == iv_rc;
        }

        inline bool operator==(const ReturnCodes& rhs) const
        {
            return rhs == iv_rc;
        }

        inline bool operator!=(const uint32_t& rhs) const
        {
            return rhs != iv_rc;
        }

        inline bool operator!=(const ReturnCodes& rhs) const
        {
            return rhs != iv_rc;
        }

        ///
        /// @brief Enumeration of return code creators
        ///
        enum returnCodeCreator
        {
            CREATOR_FAPI = 1,
            CREATOR_PLAT = 2,
            CREATOR_HWP = 3,
        };

        ///
        /// @brief Gets the creator of the return code
        /// @return ReturnCodeCreator
        ///
        inline returnCodeCreator getCreator(void) const
        {
            returnCodeCreator l_creator = CREATOR_HWP;

            if (iv_rc & FAPI2_RC_FAPI2_MASK)
            {
                l_creator = CREATOR_FAPI;
            }
            else if (iv_rc & FAPI2_RC_PLAT_MASK)
            {
                l_creator = CREATOR_PLAT;
            }

            return l_creator;
        }

        ///
        /// @brief explicit check for RC value
        /// @return true if this instance has a matching RC
        ///
        inline bool isRC(const ReturnCodes i_rc) const
        {
            return static_cast<uint32_t>(i_rc) == iv_rc;
        }

        ///
        /// @brief explicit check for RC value
        /// @return true if this instance has a matching RC
        ///
        inline bool isRC(const uint32_t i_rc) const
        {
            return i_rc == iv_rc;
        }

    private:
        uint32_t iv_rc;
};

/// This implementation assumes no exception handling and leverages thread-local
/// storage. For platforms without thread support, a global variable will
/// suffice for the error state.

extern thread_local uint64_t pib_error_mask;     /// the pib mask
extern thread_local uint64_t operational_state;  /// the operational mode
#ifndef PLAT_NO_THREAD_LOCAL_STORAGE
    extern thread_local ReturnCode current_err;      /// the current error state
#else
    extern ReturnCode current_err;
#endif

}

#endif
<|endoftext|>


<commit_before>#pragma once

#include <array>
#include <tuple>
#include <utility>

namespace cu
{

/// Returns the size of a tuple as compile-time constant.
template <typename ...Ts>
constexpr std::size_t get_tuple_size( const std::tuple<Ts...> & )
{
  return sizeof...(Ts);
}

template <typename ...Ts>
constexpr auto make_index_sequence( const std::tuple<Ts...> & )
{
  return std::make_index_sequence<sizeof...(Ts)>();
}

namespace detail
{

  template <typename Tuple, typename F, std::size_t ...indexes>
  void for_each_impl( Tuple && tuple,
                      F && f, std::index_sequence<indexes...> )
  {
    const auto _ = {(static_cast<void>(std::forward<F>(f)(
        std::get<indexes>(std::forward<Tuple>(tuple)) ) ),1)...};
    static_cast<void>(_);
  }

  template <typename Tuple1, typename Tuple2, typename F, std::size_t ...indexes>
  void for_each_impl( Tuple1 && tuple1,
                      Tuple2 && tuple2,
                      F && f,
                      std::index_sequence<indexes...> )
  {
    const auto _ = { (static_cast<void>( std::forward<F>(f)(
        std::get<indexes>(std::forward<Tuple1>(tuple1)),
        std::get<indexes>(std::forward<Tuple2>(tuple2)) ) ),1)... };
    static_cast<void>(_);
  }

} // namespace detail

/// Applies a functor to each element of a tuple.
///
/// The types of the elements can differ and it still works.
template <typename Tuple, typename F>
void for_each( Tuple && tuple, F && f )
{
  detail::for_each_impl(
        std::forward<Tuple>(tuple),
        std::forward<F>(f),
        make_index_sequence(tuple) );
}

/// Applies a functor to the elements of two tuples.
///
/// In effect, the following is called:
///   @code
///     f( get< 0 >(std::forward<Tuple1>(tuple1)),
///        get< 0 >(std::forward<Tuple2>(tuple2)) );
///         .
///         .
///         .
///     f( get<N-1>(std::forward<Tuple1>(tuple1)),
///        get<N-1>(std::forward<Tuple2>(tuple2)) );
///   @endcode
/// where @c N ist the size of both tuples. Note also, that proper forwarding
/// is applied to the elements of the tuples.
template <typename Tuple1, typename Tuple2, typename F>
void for_each( Tuple1 && tuple1,
               Tuple2 && tuple2,
               F && f )
{
  static_assert( get_tuple_size(tuple1) ==
                 get_tuple_size(tuple2),
                 "Tuples must have the same length." );
  detail::for_each_impl(
        std::forward<Tuple1>(tuple1),
        std::forward<Tuple2>(tuple2),
        std::forward<F>(f),
        make_index_sequence(tuple1) );
}

namespace detail
{

  template <typename Tuple, typename F, std::size_t ...indexes>
  decltype(auto) transform_impl( Tuple && tuple,
                                 F && f,
                                 std::index_sequence<indexes...> )
  {
    return std::make_tuple( f( std::get<indexes>( std::forward<Tuple>(tuple) ) )... );
  }

} // namespace detail

/// A functor is applied to every element of a tuple and the returned values
/// are returned in a tuple.
template <typename Tuple, typename F>
decltype(auto) transform( Tuple && tuple,
                          F && f )
{
  return detail::transform_impl(
        std::forward<Tuple>(tuple),
        std::forward<F>(f),
        make_index_sequence(tuple) );
}

constexpr bool all_of()
{
  return true;
}

template <typename ...T>
constexpr bool all_of( bool head, T ... tail )
{
  return head ? all_of( tail... ) : false;
}

namespace detail
{

  template <typename T, typename Tuple, std::size_t ...indexes>
  auto to_array_impl1( Tuple && tuple, std::index_sequence<indexes...> )
  {
    return std::array<T,get_tuple_size(tuple)>{
      std::get<indexes>( std::forward<Tuple>(tuple))... };
  }

}

/// Turns a tuple into an array.
///
/// The element type is not inferred, but must be specified.
template <typename T, typename Tuple>
auto to_array( Tuple && tuple )
{
  return detail::to_array_impl1<T>(
        std::forward<Tuple>(tuple),
        make_index_sequence(tuple) );
}

namespace detail
{

  template <typename T, std::size_t ...indexes>
  auto to_array_impl2( T * arr, std::index_sequence<indexes...> )
  {
    return std::array<std::decay_t<T>,sizeof...(indexes)>{ {
          arr[indexes]...
          } };
  }

} // namespace detail

template <typename T, std::size_t N>
auto to_array( T(&arr)[N] )
{
  return detail::to_array_impl2( arr, std::make_index_sequence<N>() );
}

template <typename ...Ts>
constexpr auto make_array( Ts &&... elems )
  -> std::array<std::common_type_t<Ts...>, sizeof...(Ts) >
{
  return { std::forward<Ts>(elems)... };
}

namespace detail
{

  template <typename F>
  struct ReverseAccumulator
  {
    ReverseAccumulator( F && f_ )
      : f(std::forward<F>(f_))
    {}

    template <typename ...Ts, typename T>
    decltype(auto) operator()( T && arg, Ts &&...args ) const
    {
      return f( std::move(*this)( std::forward<Ts>(args)... ),
                std::forward<T>(arg) );
    }

    template <typename T>
    T && operator()( T && arg ) const
    {
      return std::forward<T>(arg);
    }

  private:
    F && f;
  };

  template <typename ...Ts, typename F, std::size_t ...indexes>
  decltype(auto) accumulate_impl( const std::tuple<Ts...> & tuple,
                        F && f,
                        std::index_sequence<indexes...> )
  {
    // The reverse accumulator is used for left to right associativity.
    // It must be reverse because elements of an argument pack must be
    // removed from the front while inferring parameters. In other words,
    // a template of the form
    //   @code
    //     template <typename ...Ts, typename T>
    //     void f( Ts &&...args, T && arg );
    //   @endcode
    // is ill-formed code, while
    //   @code
    //     template <typename ...Ts, typename T>
    //     void f( T && arg, Ts &&...args );
    //   @endcode
    // is perfectly valid.
    return ReverseAccumulator<F>(std::forward<F>(f))(
          std::get<sizeof...(Ts)-indexes-1>( tuple )... );
  }

} // namespace detail

/// Accumulates the elements of a tuple given a specific functor.
///
/// If the elements of the tuple shall be added together, then the functor
/// parameter should be something like this:
///   @code
///     []( auto && rhs, auto && lhs ) { return rhs + lhs; }
///   @endcode
/// Note that the operation will be performed left to right associative
/// independent of the type of functor used.
template <typename Tuple, typename F>
decltype(auto) accumulate( Tuple && tuple,
                 F && f )
{
  return detail::accumulate_impl(
        std::forward<Tuple>(tuple),
        std::forward<F>(f),
        make_index_sequence(tuple) );
}

namespace detail
{

  template <typename Tuple, typename F, std::size_t ... indexes>
  bool any_of_impl( Tuple && tuple,
                    F && f,
                    std::index_sequence<indexes...> )
  {
    const std::array<bool,sizeof...(indexes)> values =
    { f( std::get<indexes>(tuple) )... };
    for ( bool value : values )
      if ( value )
        return true;
    return false;
  }

} // namespace detail

/// Returns @c true, iff any of the @c tuple elements evaluates to @c true.
template <typename Tuple, typename F>
bool any_of( Tuple && tuple,
             F && f )
{
  return detail::any_of_impl(
        std::forward<Tuple>(tuple),
        std::forward<F>(f),
        make_index_sequence(tuple) );
}

namespace detail
{

template <bool>
struct StaticIfImpl;

template <>
struct StaticIfImpl<true>
{
  template <typename T, typename U>
  decltype(auto) operator()( T && t, U && )
  {
    return std::forward<T>(t);
  }
};

template <>
struct StaticIfImpl<false>
{
  template <typename T, typename U>
  decltype(auto) operator()( T &&, U && u )
  {
    return std::forward<U>(u);
  }
};

} // namespace detail

/// Returns a perfectly forwarded @c then_ or @c else_, depending on the
/// compile-time value of @c cond.
///
/// The types of @c then_ and @c else_ may be different.
template <bool cond,
          typename ThenVal,
          typename ElseVal>
decltype(auto) static_if(
    ThenVal && then_,
    ElseVal && else_ )
{
  return detail::StaticIfImpl<cond>()(
        std::forward<ThenVal>(then_),
        std::forward<ElseVal>(else_) );
}

} // namespace cu
<commit_msg>Implemented transform function taking two tuples and a binary function.<commit_after>#pragma once

#include <array>
#include <tuple>
#include <utility>

namespace cu
{

/// Returns the size of a tuple as compile-time constant.
template <typename ...Ts>
constexpr std::size_t get_tuple_size( const std::tuple<Ts...> & )
{
  return sizeof...(Ts);
}

template <typename ...Ts>
constexpr auto make_index_sequence( const std::tuple<Ts...> & )
{
  return std::make_index_sequence<sizeof...(Ts)>();
}

namespace detail
{

  template <typename Tuple, typename F, std::size_t ...indexes>
  void for_each_impl( Tuple && tuple,
                      F && f, std::index_sequence<indexes...> )
  {
    const auto _ = {(static_cast<void>(std::forward<F>(f)(
        std::get<indexes>(std::forward<Tuple>(tuple)) ) ),1)...};
    static_cast<void>(_);
  }

  template <typename Tuple1, typename Tuple2, typename F, std::size_t ...indexes>
  void for_each_impl( Tuple1 && tuple1,
                      Tuple2 && tuple2,
                      F && f,
                      std::index_sequence<indexes...> )
  {
    const auto _ = { (static_cast<void>( std::forward<F>(f)(
        std::get<indexes>(std::forward<Tuple1>(tuple1)),
        std::get<indexes>(std::forward<Tuple2>(tuple2)) ) ),1)... };
    static_cast<void>(_);
  }

} // namespace detail

/// Applies a functor to each element of a tuple.
///
/// The types of the elements can differ and it still works.
template <typename Tuple, typename F>
void for_each( Tuple && tuple, F && f )
{
  detail::for_each_impl(
        std::forward<Tuple>(tuple),
        std::forward<F>(f),
        make_index_sequence(tuple) );
}

/// Applies a functor to the elements of two tuples.
///
/// In effect, the following is called:
///   @code
///     f( get< 0 >(std::forward<Tuple1>(tuple1)),
///        get< 0 >(std::forward<Tuple2>(tuple2)) );
///         .
///         .
///         .
///     f( get<N-1>(std::forward<Tuple1>(tuple1)),
///        get<N-1>(std::forward<Tuple2>(tuple2)) );
///   @endcode
/// where @c N ist the size of both tuples. Note also, that proper forwarding
/// is applied to the elements of the tuples.
template <typename Tuple1, typename Tuple2, typename F>
void for_each( Tuple1 && tuple1,
               Tuple2 && tuple2,
               F && f )
{
  static_assert( get_tuple_size(tuple1) ==
                 get_tuple_size(tuple2),
                 "Tuples must have the same length." );
  detail::for_each_impl(
        std::forward<Tuple1>(tuple1),
        std::forward<Tuple2>(tuple2),
        std::forward<F>(f),
        make_index_sequence(tuple1) );
}

namespace detail
{

  template <typename Tuple, typename F, std::size_t ...indexes>
  decltype(auto) transform_impl( Tuple && tuple,
                                 F && f,
                                 std::index_sequence<indexes...> )
  {
    return std::make_tuple(
        f( std::get<indexes>( std::forward<Tuple>(tuple) ) )... );
  }

  template <typename Tuple1, typename Tuple2, typename F, std::size_t ...indexes>
  decltype(auto) transform_impl( Tuple1 && tuple1,
                                 Tuple2 && tuple2,
                                 F && f,
                                 std::index_sequence<indexes...> )
  {
    return std::make_tuple(
        f( std::get<indexes>( std::forward<Tuple1>(tuple1) ),
           std::get<indexes>( std::forward<Tuple2>(tuple2) ) )... );
  }

} // namespace detail

/// A functor is applied to every element of a tuple and the returned values
/// are returned in a tuple.
template <typename Tuple, typename F>
decltype(auto) transform( Tuple && tuple,
                          F && f )
{
  return detail::transform_impl(
        std::forward<Tuple>(tuple),
        std::forward<F>(f),
        make_index_sequence(tuple) );
}

/// A binary functor is applied to the elements of two tuples and the returned values
/// are returned in a tuple.
template <typename Tuple1, typename Tuple2, typename F>
decltype(auto) transform( Tuple1 && tuple1,
                          Tuple2 && tuple2,
                          F && f )
{
  static_assert( get_tuple_size(tuple1) == get_tuple_size(tuple2),
                 "The tuple sized must coincide." );
  return detail::transform_impl(
        std::forward<Tuple1>(tuple1),
        std::forward<Tuple2>(tuple2),
        std::forward<F>(f),
        make_index_sequence(tuple1) );
}

constexpr bool all_of()
{
  return true;
}

template <typename ...T>
constexpr bool all_of( bool head, T ... tail )
{
  return head ? all_of( tail... ) : false;
}

namespace detail
{

  template <typename T, typename Tuple, std::size_t ...indexes>
  auto to_array_impl1( Tuple && tuple, std::index_sequence<indexes...> )
  {
    return std::array<T,get_tuple_size(tuple)>{
      std::get<indexes>( std::forward<Tuple>(tuple))... };
  }

}

/// Turns a tuple into an array.
///
/// The element type is not inferred, but must be specified.
template <typename T, typename Tuple>
auto to_array( Tuple && tuple )
{
  return detail::to_array_impl1<T>(
        std::forward<Tuple>(tuple),
        make_index_sequence(tuple) );
}

namespace detail
{

  template <typename T, std::size_t ...indexes>
  auto to_array_impl2( T * arr, std::index_sequence<indexes...> )
  {
    return std::array<std::decay_t<T>,sizeof...(indexes)>{ {
          arr[indexes]...
          } };
  }

} // namespace detail

template <typename T, std::size_t N>
auto to_array( T(&arr)[N] )
{
  return detail::to_array_impl2( arr, std::make_index_sequence<N>() );
}

template <typename ...Ts>
constexpr auto make_array( Ts &&... elems )
  -> std::array<std::common_type_t<Ts...>, sizeof...(Ts) >
{
  return { std::forward<Ts>(elems)... };
}

namespace detail
{

  template <typename F>
  struct ReverseAccumulator
  {
    ReverseAccumulator( F && f_ )
      : f(std::forward<F>(f_))
    {}

    template <typename ...Ts, typename T>
    decltype(auto) operator()( T && arg, Ts &&...args ) const
    {
      return f( std::move(*this)( std::forward<Ts>(args)... ),
                std::forward<T>(arg) );
    }

    template <typename T>
    T && operator()( T && arg ) const
    {
      return std::forward<T>(arg);
    }

  private:
    F && f;
  };

  template <typename ...Ts, typename F, std::size_t ...indexes>
  decltype(auto) accumulate_impl( const std::tuple<Ts...> & tuple,
                        F && f,
                        std::index_sequence<indexes...> )
  {
    // The reverse accumulator is used for left to right associativity.
    // It must be reverse because elements of an argument pack must be
    // removed from the front while inferring parameters. In other words,
    // a template of the form
    //   @code
    //     template <typename ...Ts, typename T>
    //     void f( Ts &&...args, T && arg );
    //   @endcode
    // is ill-formed code, while
    //   @code
    //     template <typename ...Ts, typename T>
    //     void f( T && arg, Ts &&...args );
    //   @endcode
    // is perfectly valid.
    return ReverseAccumulator<F>(std::forward<F>(f))(
          std::get<sizeof...(Ts)-indexes-1>( tuple )... );
  }

} // namespace detail

/// Accumulates the elements of a tuple given a specific functor.
///
/// If the elements of the tuple shall be added together, then the functor
/// parameter should be something like this:
///   @code
///     []( auto && rhs, auto && lhs ) { return rhs + lhs; }
///   @endcode
/// Note that the operation will be performed left to right associative
/// independent of the type of functor used.
template <typename Tuple, typename F>
decltype(auto) accumulate( Tuple && tuple,
                 F && f )
{
  return detail::accumulate_impl(
        std::forward<Tuple>(tuple),
        std::forward<F>(f),
        make_index_sequence(tuple) );
}

namespace detail
{

  template <typename Tuple, typename F, std::size_t ... indexes>
  bool any_of_impl( Tuple && tuple,
                    F && f,
                    std::index_sequence<indexes...> )
  {
    const std::array<bool,sizeof...(indexes)> values =
    { f( std::get<indexes>(tuple) )... };
    for ( bool value : values )
      if ( value )
        return true;
    return false;
  }

} // namespace detail

/// Returns @c true, iff any of the @c tuple elements evaluates to @c true.
template <typename Tuple, typename F>
bool any_of( Tuple && tuple,
             F && f )
{
  return detail::any_of_impl(
        std::forward<Tuple>(tuple),
        std::forward<F>(f),
        make_index_sequence(tuple) );
}

namespace detail
{

template <bool>
struct StaticIfImpl;

template <>
struct StaticIfImpl<true>
{
  template <typename T, typename U>
  decltype(auto) operator()( T && t, U && )
  {
    return std::forward<T>(t);
  }
};

template <>
struct StaticIfImpl<false>
{
  template <typename T, typename U>
  decltype(auto) operator()( T &&, U && u )
  {
    return std::forward<U>(u);
  }
};

} // namespace detail

/// Returns a perfectly forwarded @c then_ or @c else_, depending on the
/// compile-time value of @c cond.
///
/// The types of @c then_ and @c else_ may be different.
template <bool cond,
          typename ThenVal,
          typename ElseVal>
decltype(auto) static_if(
    ThenVal && then_,
    ElseVal && else_ )
{
  return detail::StaticIfImpl<cond>()(
        std::forward<ThenVal>(then_),
        std::forward<ElseVal>(else_) );
}

} // namespace cu
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: LayerTabBar.cxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: rt $ $Date: 2007-04-26 08:36:45 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 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
 *
 ************************************************************************/

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

#include "LayerTabBar.hxx"

#ifndef _SVDLAYER_HXX
#include <svx/svdlayer.hxx>
#endif
#ifndef _SVDPAGV_HXX //autogen
#include <svx/svdpagv.hxx>
#endif
#ifndef _SV_MSGBOX_HXX //autogen
#include <vcl/msgbox.hxx>
#endif
#ifndef _SFXDISPATCH_HXX //autogen
#include <sfx2/dispatch.hxx>
#endif

#include "sdattr.hxx"
#include "app.hxx"
#include "helpids.h"
#include "app.hrc"
#include "glob.hrc"
#include "strings.hrc"
#include "res_bmp.hrc"
#ifndef SD_DRAW_VIEW_SHELL_HXX
#include "DrawViewShell.hxx"
#endif
#ifndef SD_WINDOW_HXX
#include "Window.hxx"
#endif
#ifndef SD_VIEW_HXX
#include "View.hxx"
#endif
#include "drawdoc.hxx"
#include "sdresid.hxx"
#include "DrawDocShell.hxx"
#ifndef SD_DRAW_VIEW_HXX
#include "drawview.hxx"
#endif
#include "undolayer.hxx"

namespace sd {

#define SWITCH_TIMEOUT  20

/*************************************************************************
|*
|* Standard-Konstruktor
|*
\************************************************************************/

LayerTabBar::LayerTabBar(DrawViewShell* pViewSh, Window* pParent)
    : TabBar( pParent, WinBits( WB_BORDER | WB_3DLOOK | WB_SCROLL | WB_SIZEABLE ) ),
    DropTargetHelper( this ),
    pDrViewSh(pViewSh)
{
    EnableEditMode();
    SetSizePixel(Size(0, 0));
    SetMaxPageWidth( 150 );
    SetHelpId( HID_SD_TABBAR_LAYERS );
}

LayerTabBar::LayerTabBar (
    DrawViewShell* pViewSh,
    Window* pParent,
    const ResId& rResId)
    : TabBar (pParent, rResId.GetWinBits()),
    DropTargetHelper( this ),
    pDrViewSh(pViewSh)
{
    EnableEditMode();
}

/*************************************************************************
|*
|* Destruktor
|*
\************************************************************************/

LayerTabBar::~LayerTabBar()
{
}

/*************************************************************************
|*
\************************************************************************/

void LayerTabBar::Select()
{
    SfxDispatcher* pDispatcher = pDrViewSh->GetViewFrame()->GetDispatcher();
    pDispatcher->Execute(SID_SWITCHLAYER, SFX_CALLMODE_ASYNCHRON);
}

/*************************************************************************
|*
\************************************************************************/

void LayerTabBar::MouseButtonDown(const MouseEvent& rMEvt)
{
    BOOL bSetPageID=FALSE;

    if (rMEvt.IsLeft() && !rMEvt.IsMod1() && !rMEvt.IsMod2())
    {
        Point aPosPixel = rMEvt.GetPosPixel();
        USHORT aLayerId = GetPageId( PixelToLogic(aPosPixel) );

        if (aLayerId == 0)
        {
            SfxDispatcher* pDispatcher = pDrViewSh->GetViewFrame()->GetDispatcher();
            pDispatcher->Execute(SID_INSERTLAYER, SFX_CALLMODE_SYNCHRON);

            bSetPageID=TRUE;
        }
        else if (rMEvt.IsShift())
        {
            // Toggle zw. Layer sichtbar / unsichtbar
            String aName(GetPageText(aLayerId));
            SdrPageView* pPV = pDrViewSh->GetView()->GetSdrPageView();
            BOOL bVisible = pPV->IsLayerVisible(aName);
            pPV->SetLayerVisible(aName, !bVisible);
            pDrViewSh->ResetActualLayer();
        }
    }

    // If you insert a new layer you must not call TabBar::MouseButtonDown(rMEvt);
    // because you want to activate the new layer
    if( !bSetPageID )
        TabBar::MouseButtonDown(rMEvt);
}

/*************************************************************************
|*
\************************************************************************/

void LayerTabBar::DoubleClick()
{
    if (GetCurPageId() != 0)
    {
        SfxDispatcher* pDispatcher = pDrViewSh->GetViewFrame()->GetDispatcher();
        pDispatcher->Execute( SID_MODIFYLAYER, SFX_CALLMODE_SYNCHRON );
    }
}

/*************************************************************************
|*
|* AcceptDrop-Event
|*
\************************************************************************/

sal_Int8 LayerTabBar::AcceptDrop( const AcceptDropEvent& rEvt )
{
    sal_Int8 nRet = DND_ACTION_NONE;

    if( rEvt.mbLeaving )
        EndSwitchPage();

    if( !pDrViewSh->GetDocSh()->IsReadOnly() )
    {
        USHORT          nPageId = SDRPAGE_NOTFOUND;
        Point           aPos( PixelToLogic( rEvt.maPosPixel ) );
        USHORT          nLayerId = pDrViewSh->GetView()->GetDoc()->GetLayerAdmin().GetLayerID( GetPageText( GetPageId( aPos ) ), FALSE );

        nRet = pDrViewSh->AcceptDrop( rEvt, *this, NULL, nPageId, nLayerId );

        SwitchPage( aPos );
    }

    return nRet;
}

/*************************************************************************
|*
|* ExecuteDrop-Event
|*
\************************************************************************/

sal_Int8 LayerTabBar::ExecuteDrop( const ExecuteDropEvent& rEvt )
{
    USHORT          nPageId = SDRPAGE_NOTFOUND;
    USHORT          nLayerId = pDrViewSh->GetView()->GetDoc()->GetLayerAdmin().GetLayerID( GetPageText( GetPageId( PixelToLogic( rEvt.maPosPixel ) ) ), FALSE );
    sal_Int8        nRet = pDrViewSh->ExecuteDrop( rEvt, *this, NULL, nPageId, nLayerId );

    EndSwitchPage();

    return nRet;

}

/*************************************************************************
|*
\************************************************************************/

void  LayerTabBar::Command(const CommandEvent& rCEvt)
{
    if ( rCEvt.GetCommand() == COMMAND_CONTEXTMENU )
    {
        SfxDispatcher* pDispatcher = pDrViewSh->GetViewFrame()->GetDispatcher();
        pDispatcher->ExecutePopup(SdResId(RID_LAYERTAB_POPUP));
    }
}

/*************************************************************************
|*
\************************************************************************/
long LayerTabBar::StartRenaming()
{
    BOOL bOK = TRUE;
    String aLayerName = GetPageText( GetEditPageId() );
    String aLayoutLayer ( SdResId(STR_LAYER_LAYOUT) );
    String aControlsLayer ( SdResId(STR_LAYER_CONTROLS) );
    String aMeasureLinesLayer ( SdResId(STR_LAYER_MEASURELINES) );
    String aBackgroundLayer( SdResId(STR_LAYER_BCKGRND) );
    String aBackgroundObjLayer( SdResId(STR_LAYER_BCKGRNDOBJ) );

    if ( aLayerName == aLayoutLayer       || aLayerName == aControlsLayer  ||
         aLayerName == aMeasureLinesLayer ||
         aLayerName == aBackgroundLayer   || aLayerName == aBackgroundObjLayer )
    {
        // Diese Namen duerfen nicht veraendert werden
        bOK = FALSE;
    }
    else
    {
        ::sd::View* pView = pDrViewSh->GetView();

        if ( pView->IsTextEdit() )
        {
            pView->SdrEndTextEdit();
        }
    }

    return(bOK);
}

/*************************************************************************
|*
\************************************************************************/

long LayerTabBar::AllowRenaming()
{
    BOOL bOK = TRUE;

    // Ueberpruefung auf schon vorhandene Namen
    ::sd::View* pView = pDrViewSh->GetView();
    SdDrawDocument* pDoc = pView->GetDoc();
    String aLayerName = pView->GetActiveLayer();
    SdrLayerAdmin& rLayerAdmin = pDoc->GetLayerAdmin();
    String aNewName( GetEditText() );

    if ( aNewName.Len() == 0 ||
        (rLayerAdmin.GetLayer( aNewName, FALSE ) && aLayerName != aNewName) )
    {
        // Name ist schon vorhanden
        WarningBox aWarningBox( &pDrViewSh->GetViewFrame()->GetWindow(), WinBits( WB_OK ),
                                String(SdResId( STR_WARN_NAME_DUPLICATE ) ) );
        aWarningBox.Execute();
        bOK = FALSE;
    }

    if (bOK)
    {
        String aLayoutLayer ( SdResId(STR_LAYER_LAYOUT) );
        String aControlsLayer ( SdResId(STR_LAYER_CONTROLS) );
        String aMeasureLinesLayer ( SdResId(STR_LAYER_MEASURELINES) );
        String aBackgroundLayer( SdResId(STR_LAYER_BCKGRND) );
        String aBackgroundObjLayer( SdResId(STR_LAYER_BCKGRNDOBJ) );

        if ( aNewName == aLayoutLayer       || aNewName == aControlsLayer  ||
             aNewName == aMeasureLinesLayer ||
             aNewName == aBackgroundLayer   || aNewName == aBackgroundObjLayer )
        {
            // Diese Namen duerfen nicht vergeben werden
            bOK = FALSE;
        }
    }

    return(bOK);
}

/*************************************************************************
|*
\************************************************************************/

void LayerTabBar::EndRenaming()
{
    if( !IsEditModeCanceled() )
    {
        ::sd::View* pView = pDrViewSh->GetView();
        DrawView* pDrView = PTR_CAST( DrawView, pView );

        SdDrawDocument* pDoc = pView->GetDoc();
        String aLayerName = pView->GetActiveLayer();
        SdrLayerAdmin& rLayerAdmin = pDoc->GetLayerAdmin();
        SdrLayer* pLayer = rLayerAdmin.GetLayer(aLayerName, FALSE);

        if (pLayer)
        {
            String aNewName( GetEditText() );

            DBG_ASSERT( pDrView, "Rename layer undo action is only working with a SdDrawView" );
            if( pDrView )
            {
                SfxUndoManager* pManager = pDoc->GetDocSh()->GetUndoManager();
                SdLayerModifyUndoAction* pAction = new SdLayerModifyUndoAction(
                    pDoc,
                    pLayer,
                    aLayerName,
                    pDrView->IsLayerVisible(aLayerName),
                    pDrView->IsLayerLocked(aLayerName),
                    pDrView->IsLayerPrintable(aLayerName),
                    aNewName,
                    pDrView->IsLayerVisible(aLayerName),
                    pDrView->IsLayerLocked(aLayerName),
                    pDrView->IsLayerPrintable(aLayerName)
                    );
                pManager->AddUndoAction( pAction );
            }

            // Zuerst View benachrichtigen, da innerhalb von SetName() schon
            // ResetActualLayer() gerufen wird und an der View der Layer dann
            // schon bekannt sein muss.
            pView->SetActiveLayer(aNewName);
            pLayer->SetName(aNewName);
            pDoc->SetChanged(TRUE);
        }
    }
}

/*************************************************************************
|*
\************************************************************************/

void LayerTabBar::ActivatePage()
{
    if ( /*IsInSwitching*/ 1 && pDrViewSh!=NULL)
    {

        SfxDispatcher* pDispatcher = pDrViewSh->GetViewFrame()->GetDispatcher();
        pDispatcher->Execute(SID_SWITCHLAYER, SFX_CALLMODE_ASYNCHRON);
    }
}

void LayerTabBar::SendActivatePageEvent (void)
{
    CallEventListeners (VCLEVENT_TABBAR_PAGEACTIVATED,
        reinterpret_cast<void*>(GetCurPageId()));
}

void LayerTabBar::SendDeactivatePageEvent (void)
{
    CallEventListeners (VCLEVENT_TABBAR_PAGEDEACTIVATED,
        reinterpret_cast<void*>(GetCurPageId()));
}

} // end of namespace sd
<commit_msg>INTEGRATION: CWS impressalternativtext (1.6.20); FILE MERGED 2007/05/24 13:10:38 cl 1.6.20.1: #i68100# adding Title and Description to layers<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: LayerTabBar.cxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: hr $ $Date: 2007-06-26 13:38:18 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 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
 *
 ************************************************************************/

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

#include "LayerTabBar.hxx"

#ifndef _SVDLAYER_HXX
#include <svx/svdlayer.hxx>
#endif
#ifndef _SVDPAGV_HXX //autogen
#include <svx/svdpagv.hxx>
#endif
#ifndef _SV_MSGBOX_HXX //autogen
#include <vcl/msgbox.hxx>
#endif
#ifndef _SFXDISPATCH_HXX //autogen
#include <sfx2/dispatch.hxx>
#endif

#include "sdattr.hxx"
#include "app.hxx"
#include "helpids.h"
#include "app.hrc"
#include "glob.hrc"
#include "strings.hrc"
#include "res_bmp.hrc"
#ifndef SD_DRAW_VIEW_SHELL_HXX
#include "DrawViewShell.hxx"
#endif
#ifndef SD_WINDOW_HXX
#include "Window.hxx"
#endif
#ifndef SD_VIEW_HXX
#include "View.hxx"
#endif
#include "drawdoc.hxx"
#include "sdresid.hxx"
#include "DrawDocShell.hxx"
#ifndef SD_DRAW_VIEW_HXX
#include "drawview.hxx"
#endif
#include "undolayer.hxx"

namespace sd {

#define SWITCH_TIMEOUT  20

/*************************************************************************
|*
|* Standard-Konstruktor
|*
\************************************************************************/

LayerTabBar::LayerTabBar(DrawViewShell* pViewSh, Window* pParent)
    : TabBar( pParent, WinBits( WB_BORDER | WB_3DLOOK | WB_SCROLL | WB_SIZEABLE ) ),
    DropTargetHelper( this ),
    pDrViewSh(pViewSh)
{
    EnableEditMode();
    SetSizePixel(Size(0, 0));
    SetMaxPageWidth( 150 );
    SetHelpId( HID_SD_TABBAR_LAYERS );
}

LayerTabBar::LayerTabBar (
    DrawViewShell* pViewSh,
    Window* pParent,
    const ResId& rResId)
    : TabBar (pParent, rResId.GetWinBits()),
    DropTargetHelper( this ),
    pDrViewSh(pViewSh)
{
    EnableEditMode();
}

/*************************************************************************
|*
|* Destruktor
|*
\************************************************************************/

LayerTabBar::~LayerTabBar()
{
}

/*************************************************************************
|*
\************************************************************************/

void LayerTabBar::Select()
{
    SfxDispatcher* pDispatcher = pDrViewSh->GetViewFrame()->GetDispatcher();
    pDispatcher->Execute(SID_SWITCHLAYER, SFX_CALLMODE_ASYNCHRON);
}

/*************************************************************************
|*
\************************************************************************/

void LayerTabBar::MouseButtonDown(const MouseEvent& rMEvt)
{
    BOOL bSetPageID=FALSE;

    if (rMEvt.IsLeft() && !rMEvt.IsMod1() && !rMEvt.IsMod2())
    {
        Point aPosPixel = rMEvt.GetPosPixel();
        USHORT aLayerId = GetPageId( PixelToLogic(aPosPixel) );

        if (aLayerId == 0)
        {
            SfxDispatcher* pDispatcher = pDrViewSh->GetViewFrame()->GetDispatcher();
            pDispatcher->Execute(SID_INSERTLAYER, SFX_CALLMODE_SYNCHRON);

            bSetPageID=TRUE;
        }
        else if (rMEvt.IsShift())
        {
            // Toggle zw. Layer sichtbar / unsichtbar
            String aName(GetPageText(aLayerId));
            SdrPageView* pPV = pDrViewSh->GetView()->GetSdrPageView();
            BOOL bVisible = pPV->IsLayerVisible(aName);
            pPV->SetLayerVisible(aName, !bVisible);
            pDrViewSh->ResetActualLayer();
        }
    }

    // If you insert a new layer you must not call TabBar::MouseButtonDown(rMEvt);
    // because you want to activate the new layer
    if( !bSetPageID )
        TabBar::MouseButtonDown(rMEvt);
}

/*************************************************************************
|*
\************************************************************************/

void LayerTabBar::DoubleClick()
{
    if (GetCurPageId() != 0)
    {
        SfxDispatcher* pDispatcher = pDrViewSh->GetViewFrame()->GetDispatcher();
        pDispatcher->Execute( SID_MODIFYLAYER, SFX_CALLMODE_SYNCHRON );
    }
}

/*************************************************************************
|*
|* AcceptDrop-Event
|*
\************************************************************************/

sal_Int8 LayerTabBar::AcceptDrop( const AcceptDropEvent& rEvt )
{
    sal_Int8 nRet = DND_ACTION_NONE;

    if( rEvt.mbLeaving )
        EndSwitchPage();

    if( !pDrViewSh->GetDocSh()->IsReadOnly() )
    {
        USHORT          nPageId = SDRPAGE_NOTFOUND;
        Point           aPos( PixelToLogic( rEvt.maPosPixel ) );
        USHORT          nLayerId = pDrViewSh->GetView()->GetDoc()->GetLayerAdmin().GetLayerID( GetPageText( GetPageId( aPos ) ), FALSE );

        nRet = pDrViewSh->AcceptDrop( rEvt, *this, NULL, nPageId, nLayerId );

        SwitchPage( aPos );
    }

    return nRet;
}

/*************************************************************************
|*
|* ExecuteDrop-Event
|*
\************************************************************************/

sal_Int8 LayerTabBar::ExecuteDrop( const ExecuteDropEvent& rEvt )
{
    USHORT          nPageId = SDRPAGE_NOTFOUND;
    USHORT          nLayerId = pDrViewSh->GetView()->GetDoc()->GetLayerAdmin().GetLayerID( GetPageText( GetPageId( PixelToLogic( rEvt.maPosPixel ) ) ), FALSE );
    sal_Int8        nRet = pDrViewSh->ExecuteDrop( rEvt, *this, NULL, nPageId, nLayerId );

    EndSwitchPage();

    return nRet;

}

/*************************************************************************
|*
\************************************************************************/

void  LayerTabBar::Command(const CommandEvent& rCEvt)
{
    if ( rCEvt.GetCommand() == COMMAND_CONTEXTMENU )
    {
        SfxDispatcher* pDispatcher = pDrViewSh->GetViewFrame()->GetDispatcher();
        pDispatcher->ExecutePopup(SdResId(RID_LAYERTAB_POPUP));
    }
}

/*************************************************************************
|*
\************************************************************************/
long LayerTabBar::StartRenaming()
{
    BOOL bOK = TRUE;
    String aLayerName = GetPageText( GetEditPageId() );
    String aLayoutLayer ( SdResId(STR_LAYER_LAYOUT) );
    String aControlsLayer ( SdResId(STR_LAYER_CONTROLS) );
    String aMeasureLinesLayer ( SdResId(STR_LAYER_MEASURELINES) );
    String aBackgroundLayer( SdResId(STR_LAYER_BCKGRND) );
    String aBackgroundObjLayer( SdResId(STR_LAYER_BCKGRNDOBJ) );

    if ( aLayerName == aLayoutLayer       || aLayerName == aControlsLayer  ||
         aLayerName == aMeasureLinesLayer ||
         aLayerName == aBackgroundLayer   || aLayerName == aBackgroundObjLayer )
    {
        // Diese Namen duerfen nicht veraendert werden
        bOK = FALSE;
    }
    else
    {
        ::sd::View* pView = pDrViewSh->GetView();

        if ( pView->IsTextEdit() )
        {
            pView->SdrEndTextEdit();
        }
    }

    return(bOK);
}

/*************************************************************************
|*
\************************************************************************/

long LayerTabBar::AllowRenaming()
{
    BOOL bOK = TRUE;

    // Ueberpruefung auf schon vorhandene Namen
    ::sd::View* pView = pDrViewSh->GetView();
    SdDrawDocument* pDoc = pView->GetDoc();
    String aLayerName = pView->GetActiveLayer();
    SdrLayerAdmin& rLayerAdmin = pDoc->GetLayerAdmin();
    String aNewName( GetEditText() );

    if ( aNewName.Len() == 0 ||
        (rLayerAdmin.GetLayer( aNewName, FALSE ) && aLayerName != aNewName) )
    {
        // Name ist schon vorhanden
        WarningBox aWarningBox( &pDrViewSh->GetViewFrame()->GetWindow(), WinBits( WB_OK ),
                                String(SdResId( STR_WARN_NAME_DUPLICATE ) ) );
        aWarningBox.Execute();
        bOK = FALSE;
    }

    if (bOK)
    {
        String aLayoutLayer ( SdResId(STR_LAYER_LAYOUT) );
        String aControlsLayer ( SdResId(STR_LAYER_CONTROLS) );
        String aMeasureLinesLayer ( SdResId(STR_LAYER_MEASURELINES) );
        String aBackgroundLayer( SdResId(STR_LAYER_BCKGRND) );
        String aBackgroundObjLayer( SdResId(STR_LAYER_BCKGRNDOBJ) );

        if ( aNewName == aLayoutLayer       || aNewName == aControlsLayer  ||
             aNewName == aMeasureLinesLayer ||
             aNewName == aBackgroundLayer   || aNewName == aBackgroundObjLayer )
        {
            // Diese Namen duerfen nicht vergeben werden
            bOK = FALSE;
        }
    }

    return(bOK);
}

/*************************************************************************
|*
\************************************************************************/

void LayerTabBar::EndRenaming()
{
    if( !IsEditModeCanceled() )
    {
        ::sd::View* pView = pDrViewSh->GetView();
        DrawView* pDrView = PTR_CAST( DrawView, pView );

        SdDrawDocument* pDoc = pView->GetDoc();
        String aLayerName = pView->GetActiveLayer();
        SdrLayerAdmin& rLayerAdmin = pDoc->GetLayerAdmin();
        SdrLayer* pLayer = rLayerAdmin.GetLayer(aLayerName, FALSE);

        if (pLayer)
        {
            String aNewName( GetEditText() );

            DBG_ASSERT( pDrView, "Rename layer undo action is only working with a SdDrawView" );
            if( pDrView )
            {
                SfxUndoManager* pManager = pDoc->GetDocSh()->GetUndoManager();
                SdLayerModifyUndoAction* pAction = new SdLayerModifyUndoAction(
                    pDoc,
                    pLayer,
                    aLayerName,
                    pLayer->GetTitle(),
                    pLayer->GetDescription(),
                    pDrView->IsLayerVisible(aLayerName),
                    pDrView->IsLayerLocked(aLayerName),
                    pDrView->IsLayerPrintable(aLayerName),
                    aNewName,
                    pLayer->GetTitle(),
                    pLayer->GetDescription(),
                    pDrView->IsLayerVisible(aLayerName),
                    pDrView->IsLayerLocked(aLayerName),
                    pDrView->IsLayerPrintable(aLayerName)
                    );
                pManager->AddUndoAction( pAction );
            }

            // Zuerst View benachrichtigen, da innerhalb von SetName() schon
            // ResetActualLayer() gerufen wird und an der View der Layer dann
            // schon bekannt sein muss.
            pView->SetActiveLayer(aNewName);
            pLayer->SetName(aNewName);
            pDoc->SetChanged(TRUE);
        }
    }
}

/*************************************************************************
|*
\************************************************************************/

void LayerTabBar::ActivatePage()
{
    if ( /*IsInSwitching*/ 1 && pDrViewSh!=NULL)
    {

        SfxDispatcher* pDispatcher = pDrViewSh->GetViewFrame()->GetDispatcher();
        pDispatcher->Execute(SID_SWITCHLAYER, SFX_CALLMODE_ASYNCHRON);
    }
}

void LayerTabBar::SendActivatePageEvent (void)
{
    CallEventListeners (VCLEVENT_TABBAR_PAGEACTIVATED,
        reinterpret_cast<void*>(GetCurPageId()));
}

void LayerTabBar::SendDeactivatePageEvent (void)
{
    CallEventListeners (VCLEVENT_TABBAR_PAGEDEACTIVATED,
        reinterpret_cast<void*>(GetCurPageId()));
}

} // end of namespace sd
<|endoftext|>