<commit_before>#include <iostream>
#include <map>
#include <string>

class Elem {};
class FaceInfo {};
class Variable
{
  double _x;

public:
  Variable(const double x) : _x(x) {}
  double operator()(const Elem & elem) const { return _x; }
  double operator()(const FaceInfo & fi) const { return _x; }
  double operator()(const unsigned int qp) const { return _x; }
};

class MaterialProperty
{
public:
  using ElemFn = std::function<double(const Elem &)>;
  using FiFn = std::function<double(const FaceInfo &)>;
  using QpFn = std::function<double(const unsigned int &)>;

  template <typename PolymorphicLambda>
  MaterialProperty & operator=(PolymorphicLambda my_lammy)
    {
      elem_functor = my_lammy;
      fi_functor = my_lammy;
      qp_functor = my_lammy;
      return *this;
    }

  double operator()(const Elem & elem) const
    {
      return elem_functor(elem);
    }

  double operator()(const FaceInfo & fi) const
    {
      return fi_functor(fi);
    }

  double operator()(const unsigned int qp) const
    {
      return qp_functor(qp);
    }

private:
  ElemFn elem_functor;
  FiFn fi_functor;
  QpFn qp_functor;
};

class Material
{
public:
  Material()
    {
      Variable u(2);
      _mat_props["u2"] = [&u](const auto & geom_entity) -> double { return u(geom_entity) * u(geom_entity); };
      _mat_props["u3"] = [&u](const auto & geom_entity) -> double { return u(geom_entity) * u(geom_entity) * u(geom_entity); };
    }

  const MaterialProperty & getMatProp(const std::string & name) const
    {
      return _mat_props.at(name);
    }

private:
  std::map<std::string, MaterialProperty> _mat_props;
};

class ResidualObject
{
public:
  void assignMatProp(const MaterialProperty & prop)
    {
      _mat_prop = ∝
    }

protected:
  const MaterialProperty * _mat_prop;
};

class Kernel : public ResidualObject
{
public:
  void computeResidual(const Elem & elem)
    {
      std::cout << (*_mat_prop)(elem) << std::endl;
    }
};

class FVFluxKernel : public ResidualObject
{
public:
  void computeResidual(const FaceInfo & fi)
    {
      std::cout << (*_mat_prop)(fi) << std::endl;
    }
};

int main()
{
  Material mat;
  Kernel kern;
  kern.assignMatProp(mat.getMatProp("u2"));
  FVFluxKernel fv;
  fv.assignMatProp(mat.getMatProp("u3"));

  kern.computeResidual(Elem());
  fv.computeResidual(FaceInfo());
}
<commit_msg>eliminate dangling reference<commit_after>#include <iostream>
#include <map>
#include <string>
#include <functional>

class Elem
{
};
class FaceInfo
{
};
class Variable
{
  double _x;

public:
  Variable(const double x) : _x(x) {}
  double operator()(const Elem & elem) const { return _x; }
  double operator()(const FaceInfo & fi) const { return _x; }
  double operator()(const unsigned int qp) const { return _x; }
};

class MaterialProperty
{
public:
  using ElemFn = std::function<double(const Elem &)>;
  using FiFn = std::function<double(const FaceInfo &)>;
  using QpFn = std::function<double(const unsigned int &)>;

  template <typename PolymorphicLambda>
  MaterialProperty & operator=(PolymorphicLambda my_lammy)
  {
    elem_functor = my_lammy;
    fi_functor = my_lammy;
    qp_functor = my_lammy;
    return *this;
  }

  double operator()(const Elem & elem) const { return elem_functor(elem); }

  double operator()(const FaceInfo & fi) const { return fi_functor(fi); }

  double operator()(const unsigned int qp) const { return qp_functor(qp); }

private:
  ElemFn elem_functor;
  FiFn fi_functor;
  QpFn qp_functor;
};

class Material
{
public:
  Material() : _u(2)
  {
    _mat_props["u2"] = [this](const auto & geom_entity) -> double {
      return _u(geom_entity) * _u(geom_entity);
    };
    _mat_props["u3"] = [this](const auto & geom_entity) -> double {
      return _u(geom_entity) * _u(geom_entity) * _u(geom_entity);
    };
  }

  const MaterialProperty & getMatProp(const std::string & name) const
  {
    return _mat_props.at(name);
  }

private:
  std::map<std::string, MaterialProperty> _mat_props;
  Variable _u;
};

class ResidualObject
{
public:
  void assignMatProp(const MaterialProperty & prop) { _mat_prop = ∝ }

protected:
  const MaterialProperty * _mat_prop;
};

class Kernel : public ResidualObject
{
public:
  void computeResidual(const Elem & elem) { std::cout << (*_mat_prop)(elem) << std::endl; }
};

class FVFluxKernel : public ResidualObject
{
public:
  void computeResidual(const FaceInfo & fi) { std::cout << (*_mat_prop)(fi) << std::endl; }
};

int
main()
{
  Material mat;
  Kernel kern;
  kern.assignMatProp(mat.getMatProp("u2"));
  FVFluxKernel fv;
  fv.assignMatProp(mat.getMatProp("u3"));

  kern.computeResidual(Elem());
  fv.computeResidual(FaceInfo());
}
<|endoftext|>


<commit_before>/*
 * #%L
 * %%
 * Copyright (C) 2020 BMW Car IT GmbH
 * %%
 * 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.
 * #L%
 */

#include <string>
#include <vector>

#include "tests/utils/Gmock.h"
#include "tests/utils/Gtest.h"

#include "joynr/BroadcastFilterParameters.h"
#include "joynr/BroadcastSubscriptionRequest.h"
#include "joynr/ImmutableMessage.h"
#include "joynr/Message.h"
#include "joynr/MessageSender.h"
#include "joynr/MessagingQos.h"
#include "joynr/MulticastSubscriptionQos.h"
#include "joynr/MulticastSubscriptionRequest.h"
#include "joynr/MutableMessage.h"
#include "joynr/MutableMessageFactory.h"
#include "joynr/OnChangeSubscriptionQos.h"
#include "joynr/PeriodicSubscriptionQos.h"
#include "joynr/Reply.h"
#include "joynr/Request.h"
#include "joynr/SingleThreadedIOService.h"
#include "joynr/SubscriptionPublication.h"
#include "joynr/SubscriptionReply.h"
#include "joynr/SubscriptionRequest.h"

#include "tests/JoynrTest.h"
#include "tests/mock/MockDispatcher.h"
#include "tests/mock/MockMessageRouter.h"
#include "tests/mock/MockMessagingStub.h"

using ::testing::_;
using ::testing::A;
using ::testing::AllOf;
using ::testing::Eq;
using ::testing::NotNull;
using ::testing::Property;
using namespace joynr;

class MessageSenderTest : public ::testing::Test
{
public:
    MessageSenderTest()
            : messageFactory(),
              postFix(),
              senderID(),
              receiverID(),
              requestID(),
              qosSettings(),
              mockDispatcher(std::make_shared<MockDispatcher>()),
              mockMessagingStub(),
              callBack(),
              singleThreadedIOService(std::make_shared<SingleThreadedIOService>()),
              mockMessageRouter(
                      std::make_shared<MockMessageRouter>(singleThreadedIOService->getIOService())),
              isLocalMessage(true)
    {
        singleThreadedIOService->start();
    }

    ~MessageSenderTest()
    {
        singleThreadedIOService->stop();
    }

    void SetUp()
    {
        postFix = "_" + util::createUuid();
        senderID = "senderId" + postFix;
        receiverID = "receiverID" + postFix;
        requestID = "requestId" + postFix;
        qosSettings = MessagingQos(456000);
    }

    void expectRoutedMessage(const std::string& type, const std::string& payload)
    {
        EXPECT_CALL(*(mockMessageRouter.get()),
                    route(AllOf(MessageHasType(type), ImmutableMessageHasPayload(payload)), _));
    }

protected:
    MutableMessageFactory messageFactory;
    std::string postFix;
    std::string senderID;
    std::string receiverID;
    std::string requestID;
    MessagingQos qosSettings;
    std::shared_ptr<MockDispatcher> mockDispatcher;
    MockMessagingStub mockMessagingStub;
    std::shared_ptr<IReplyCaller> callBack;
    std::shared_ptr<SingleThreadedIOService> singleThreadedIOService;
    std::shared_ptr<MockMessageRouter> mockMessageRouter;
    const bool isLocalMessage;
};

typedef MessageSenderTest MessageSenderDeathTest;

TEST_F(MessageSenderTest, sendRequest_normal)
{
    Request request;
    request.setMethodName("methodName");
    request.setParams(42, std::string("value"));
    std::vector<std::string> paramDatatypes;
    paramDatatypes.push_back("java.lang.Integer");
    paramDatatypes.push_back("java.lang.String");
    request.setParamDatatypes(paramDatatypes);

    MutableMessage mutableMessage = messageFactory.createRequest(
            senderID, receiverID, qosSettings, request, isLocalMessage);

    expectRoutedMessage(Message::VALUE_MESSAGE_TYPE_REQUEST(), mutableMessage.getPayload());

    MessageSender messageSender(mockMessageRouter, nullptr);
    messageSender.registerDispatcher(mockDispatcher);
    messageSender.sendRequest(senderID, receiverID, qosSettings, request, callBack, isLocalMessage);
}

TEST_F(MessageSenderTest, sendOneWayRequest_normal)
{
    OneWayRequest oneWayRequest;
    oneWayRequest.setMethodName("methodName");
    oneWayRequest.setParams(42, std::string("value"));
    std::vector<std::string> paramDatatypes;
    paramDatatypes.push_back("java.lang.Integer");
    paramDatatypes.push_back("java.lang.String");
    oneWayRequest.setParamDatatypes(paramDatatypes);

    MutableMessage mutableMessage = messageFactory.createOneWayRequest(
            senderID, receiverID, qosSettings, oneWayRequest, isLocalMessage);

    expectRoutedMessage(Message::VALUE_MESSAGE_TYPE_ONE_WAY(), mutableMessage.getPayload());

    MessageSender messageSender(mockMessageRouter, nullptr);
    messageSender.registerDispatcher(mockDispatcher);
    messageSender.sendOneWayRequest(
            senderID, receiverID, qosSettings, oneWayRequest, isLocalMessage);
}

TEST_F(MessageSenderTest, sendReply_normal)
{
    MessageSender messageSender(mockMessageRouter, nullptr);
    messageSender.registerDispatcher(mockDispatcher);
    Reply reply;
    reply.setRequestReplyId(util::createUuid());
    reply.setResponse(std::string("response"));

    MutableMessage mutableMessage =
            messageFactory.createReply(senderID, receiverID, qosSettings, {}, reply);

    expectRoutedMessage(Message::VALUE_MESSAGE_TYPE_REPLY(), mutableMessage.getPayload());

    messageSender.sendReply(senderID, receiverID, qosSettings, {}, reply);
}

TEST_F(MessageSenderTest, sendSubscriptionRequest_normal)
{
    std::int64_t period = 2000;
    std::int64_t validity = 100000;
    std::int64_t publicationTtl = 1000;
    std::int64_t alert = 4000;
    auto qos = std::make_shared<PeriodicSubscriptionQos>(validity, publicationTtl, period, alert);

    SubscriptionRequest subscriptionRequest;
    subscriptionRequest.setSubscriptionId("subscriptionId");
    subscriptionRequest.setSubscribeToName("attributeName");
    subscriptionRequest.setQos(qos);

    MutableMessage mutableMessage = messageFactory.createSubscriptionRequest(
            senderID, receiverID, qosSettings, subscriptionRequest, isLocalMessage);

    expectRoutedMessage(
            Message::VALUE_MESSAGE_TYPE_SUBSCRIPTION_REQUEST(), mutableMessage.getPayload());

    MessageSender messageSender(mockMessageRouter, nullptr);
    messageSender.registerDispatcher(mockDispatcher);

    messageSender.sendSubscriptionRequest(
            senderID, receiverID, qosSettings, subscriptionRequest, isLocalMessage);
}

TEST_F(MessageSenderTest, sendBroadcastSubscriptionRequest_normal)
{
    std::int64_t minInterval = 2000;
    std::int64_t validity = 100000;
    std::int64_t publicationTtl = 1000;
    auto qos = std::make_shared<OnChangeSubscriptionQos>(validity, publicationTtl, minInterval);

    BroadcastSubscriptionRequest subscriptionRequest;
    BroadcastFilterParameters filter;
    filter.setFilterParameter("MyParameter", "MyValue");
    subscriptionRequest.setFilterParameters(filter);
    subscriptionRequest.setSubscriptionId("subscriptionId");
    subscriptionRequest.setSubscribeToName("broadcastName");
    subscriptionRequest.setQos(qos);

    MutableMessage mutableMessage = messageFactory.createBroadcastSubscriptionRequest(
            senderID, receiverID, qosSettings, subscriptionRequest, isLocalMessage);

    expectRoutedMessage(Message::VALUE_MESSAGE_TYPE_BROADCAST_SUBSCRIPTION_REQUEST(),
                        mutableMessage.getPayload());

    MessageSender messageSender(mockMessageRouter, nullptr);
    messageSender.registerDispatcher(mockDispatcher);

    messageSender.sendBroadcastSubscriptionRequest(
            senderID, receiverID, qosSettings, subscriptionRequest, isLocalMessage);
}

// TODO implement sending a reply to a subscription request!
TEST_F(MessageSenderTest, DISABLED_sendSubscriptionReply_normal)
{
    std::string payload("subscriptionReply");

    expectRoutedMessage(Message::VALUE_MESSAGE_TYPE_SUBSCRIPTION_REPLY(), payload);

    MessageSender messageSender(mockMessageRouter, nullptr);
    messageSender.registerDispatcher(mockDispatcher);

    //    messageSender.sendSubscriptionReply(util::createUuid(), payload, senderID, receiverID,
    //    qosSettings);
}

TEST_F(MessageSenderTest, removeRoutingEntry)
{
    std::string participantId("participantId");

    EXPECT_CALL(*(mockMessageRouter.get()), removeNextHop(participantId, _, _));

    MessageSender messageSender(mockMessageRouter, nullptr);
    messageSender.removeRoutingEntry(participantId);
}

TEST_F(MessageSenderTest, sendPublication_normal)
{
    MessageSender messageSender(mockMessageRouter, nullptr);
    messageSender.registerDispatcher(mockDispatcher);
    SubscriptionPublication publication;
    publication.setSubscriptionId("ignoresubscriptionid");
    publication.setResponse(std::string("publication"));

    MutableMessage mutableMessage = messageFactory.createSubscriptionPublication(
            senderID, receiverID, qosSettings, publication);

    expectRoutedMessage(Message::VALUE_MESSAGE_TYPE_PUBLICATION(), mutableMessage.getPayload());

    messageSender.sendSubscriptionPublication(
            senderID, receiverID, qosSettings, std::move(publication));
}

TEST_F(MessageSenderTest, sendMulticastSubscriptionRequest)
{
    const std::string senderParticipantId("senderParticipantId");
    const std::string receiverParticipantId("receiverParticipantId");
    const std::string subscriptionId("subscriptionId");
    MessagingQos messagingQos(1, MessagingQosEffort::Enum::BEST_EFFORT);
    auto subscriptionQos = std::make_shared<MulticastSubscriptionQos>();

    MulticastSubscriptionRequest subscriptionRequest;
    subscriptionRequest.setSubscribeToName("subscribeToName");
    subscriptionRequest.setSubscriptionId(subscriptionId);
    subscriptionRequest.setQos(subscriptionQos);
    subscriptionRequest.setMulticastId("multicastId");

    MutableMessage mutableMessage =
            messageFactory.createMulticastSubscriptionRequest(senderParticipantId,
                                                              receiverParticipantId,
                                                              messagingQos,
                                                              subscriptionRequest,
                                                              isLocalMessage);

    SubscriptionReply subscriptionReply;
    subscriptionReply.setSubscriptionId("subscriptionId");

    MutableMessage mutableReplyMessage = messageFactory.createSubscriptionReply(
            receiverParticipantId, senderParticipantId, messagingQos, subscriptionReply);

    expectRoutedMessage(
            Message::VALUE_MESSAGE_TYPE_SUBSCRIPTION_REPLY(), mutableReplyMessage.getPayload());

    MessageSender messageSender(mockMessageRouter, nullptr);

    messageSender.sendMulticastSubscriptionRequest(senderParticipantId,
                                                   receiverParticipantId,
                                                   messagingQos,
                                                   subscriptionRequest,
                                                   isLocalMessage);
}
<commit_msg>[c++] Fix MessageSenderTest<commit_after>/*
 * #%L
 * %%
 * Copyright (C) 2020 BMW Car IT GmbH
 * %%
 * 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.
 * #L%
 */

#include <string>
#include <vector>

#include "tests/utils/Gmock.h"
#include "tests/utils/Gtest.h"

#include "joynr/BroadcastFilterParameters.h"
#include "joynr/BroadcastSubscriptionRequest.h"
#include "joynr/ImmutableMessage.h"
#include "joynr/Message.h"
#include "joynr/MessageSender.h"
#include "joynr/MessagingQos.h"
#include "joynr/MulticastSubscriptionQos.h"
#include "joynr/MulticastSubscriptionRequest.h"
#include "joynr/MutableMessage.h"
#include "joynr/MutableMessageFactory.h"
#include "joynr/OnChangeSubscriptionQos.h"
#include "joynr/PeriodicSubscriptionQos.h"
#include "joynr/Reply.h"
#include "joynr/Request.h"
#include "joynr/SingleThreadedIOService.h"
#include "joynr/SubscriptionPublication.h"
#include "joynr/SubscriptionReply.h"
#include "joynr/SubscriptionRequest.h"

#include "tests/JoynrTest.h"
#include "tests/mock/MockDispatcher.h"
#include "tests/mock/MockMessageRouter.h"
#include "tests/mock/MockMessagingStub.h"

using ::testing::_;
using ::testing::A;
using ::testing::AllOf;
using ::testing::Eq;
using ::testing::NotNull;
using ::testing::Property;
using namespace joynr;

class MessageSenderTest : public ::testing::Test
{
public:
    MessageSenderTest()
            : messageFactory(),
              postFix(),
              senderID(),
              receiverID(),
              requestID(),
              qosSettings(),
              mockDispatcher(std::make_shared<MockDispatcher>()),
              mockMessagingStub(),
              callBack(),
              singleThreadedIOService(std::make_shared<SingleThreadedIOService>()),
              mockMessageRouter(
                      std::make_shared<MockMessageRouter>(singleThreadedIOService->getIOService())),
              isLocalMessage(true)
    {
        singleThreadedIOService->start();
    }

    ~MessageSenderTest()
    {
        singleThreadedIOService->stop();
    }

    void SetUp()
    {
        postFix = "_" + util::createUuid();
        senderID = "senderId" + postFix;
        receiverID = "receiverID" + postFix;
        requestID = "requestId" + postFix;
        qosSettings = MessagingQos(456000);
    }

    void expectRoutedMessage(const std::string& type, const std::string& payload)
    {
        EXPECT_CALL(*(mockMessageRouter.get()),
                    route(AllOf(MessageHasType(type), ImmutableMessageHasPayload(payload)), _));
    }

protected:
    MutableMessageFactory messageFactory;
    std::string postFix;
    std::string senderID;
    std::string receiverID;
    std::string requestID;
    MessagingQos qosSettings;
    std::shared_ptr<MockDispatcher> mockDispatcher;
    MockMessagingStub mockMessagingStub;
    std::shared_ptr<IReplyCaller> callBack;
    std::shared_ptr<SingleThreadedIOService> singleThreadedIOService;
    std::shared_ptr<MockMessageRouter> mockMessageRouter;
    const bool isLocalMessage;
};

typedef MessageSenderTest MessageSenderDeathTest;

TEST_F(MessageSenderTest, sendRequest_normal)
{
    Request request;
    request.setMethodName("methodName");
    request.setParams(42, std::string("value"));
    std::vector<std::string> paramDatatypes;
    paramDatatypes.push_back("java.lang.Integer");
    paramDatatypes.push_back("java.lang.String");
    request.setParamDatatypes(paramDatatypes);

    MutableMessage mutableMessage = messageFactory.createRequest(
            senderID, receiverID, qosSettings, request, isLocalMessage);

    expectRoutedMessage(Message::VALUE_MESSAGE_TYPE_REQUEST(), mutableMessage.getPayload());

    MessageSender messageSender(mockMessageRouter, nullptr);
    messageSender.registerDispatcher(mockDispatcher);
    messageSender.sendRequest(senderID, receiverID, qosSettings, request, callBack, isLocalMessage);
}

TEST_F(MessageSenderTest, sendOneWayRequest_normal)
{
    OneWayRequest oneWayRequest;
    oneWayRequest.setMethodName("methodName");
    oneWayRequest.setParams(42, std::string("value"));
    std::vector<std::string> paramDatatypes;
    paramDatatypes.push_back("java.lang.Integer");
    paramDatatypes.push_back("java.lang.String");
    oneWayRequest.setParamDatatypes(paramDatatypes);

    MutableMessage mutableMessage = messageFactory.createOneWayRequest(
            senderID, receiverID, qosSettings, oneWayRequest, isLocalMessage);

    expectRoutedMessage(Message::VALUE_MESSAGE_TYPE_ONE_WAY(), mutableMessage.getPayload());

    MessageSender messageSender(mockMessageRouter, nullptr);
    messageSender.registerDispatcher(mockDispatcher);
    messageSender.sendOneWayRequest(
            senderID, receiverID, qosSettings, oneWayRequest, isLocalMessage);
}

TEST_F(MessageSenderTest, sendReply_normal)
{
    Reply reply;
    reply.setRequestReplyId(util::createUuid());
    reply.setResponse(std::string("response"));

    MutableMessage mutableMessage =
            messageFactory.createReply(senderID, receiverID, qosSettings, {}, reply);

    expectRoutedMessage(Message::VALUE_MESSAGE_TYPE_REPLY(), mutableMessage.getPayload());

    MessageSender messageSender(mockMessageRouter, nullptr);
    messageSender.registerDispatcher(mockDispatcher);
    messageSender.sendReply(senderID, receiverID, qosSettings, {}, reply);
}

TEST_F(MessageSenderTest, sendSubscriptionRequest_normal)
{
    std::int64_t period = 2000;
    std::int64_t validity = 100000;
    std::int64_t publicationTtl = 1000;
    std::int64_t alert = 4000;
    auto qos = std::make_shared<PeriodicSubscriptionQos>(validity, publicationTtl, period, alert);

    SubscriptionRequest subscriptionRequest;
    subscriptionRequest.setSubscriptionId("subscriptionId");
    subscriptionRequest.setSubscribeToName("attributeName");
    subscriptionRequest.setQos(qos);

    MutableMessage mutableMessage = messageFactory.createSubscriptionRequest(
            senderID, receiverID, qosSettings, subscriptionRequest, isLocalMessage);

    expectRoutedMessage(
            Message::VALUE_MESSAGE_TYPE_SUBSCRIPTION_REQUEST(), mutableMessage.getPayload());

    MessageSender messageSender(mockMessageRouter, nullptr);
    messageSender.registerDispatcher(mockDispatcher);

    messageSender.sendSubscriptionRequest(
            senderID, receiverID, qosSettings, subscriptionRequest, isLocalMessage);
}

TEST_F(MessageSenderTest, sendBroadcastSubscriptionRequest_normal)
{
    std::int64_t minInterval = 2000;
    std::int64_t validity = 100000;
    std::int64_t publicationTtl = 1000;
    auto qos = std::make_shared<OnChangeSubscriptionQos>(validity, publicationTtl, minInterval);

    BroadcastSubscriptionRequest subscriptionRequest;
    BroadcastFilterParameters filter;
    filter.setFilterParameter("MyParameter", "MyValue");
    subscriptionRequest.setFilterParameters(filter);
    subscriptionRequest.setSubscriptionId("subscriptionId");
    subscriptionRequest.setSubscribeToName("broadcastName");
    subscriptionRequest.setQos(qos);

    MutableMessage mutableMessage = messageFactory.createBroadcastSubscriptionRequest(
            senderID, receiverID, qosSettings, subscriptionRequest, isLocalMessage);

    expectRoutedMessage(Message::VALUE_MESSAGE_TYPE_BROADCAST_SUBSCRIPTION_REQUEST(),
                        mutableMessage.getPayload());

    MessageSender messageSender(mockMessageRouter, nullptr);
    messageSender.registerDispatcher(mockDispatcher);

    messageSender.sendBroadcastSubscriptionRequest(
            senderID, receiverID, qosSettings, subscriptionRequest, isLocalMessage);
}

// TODO implement sending a reply to a subscription request!
TEST_F(MessageSenderTest, DISABLED_sendSubscriptionReply_normal)
{
    std::string payload("subscriptionReply");

    expectRoutedMessage(Message::VALUE_MESSAGE_TYPE_SUBSCRIPTION_REPLY(), payload);

    MessageSender messageSender(mockMessageRouter, nullptr);
    messageSender.registerDispatcher(mockDispatcher);

    //    messageSender.sendSubscriptionReply(util::createUuid(), payload, senderID, receiverID,
    //    qosSettings);
}

TEST_F(MessageSenderTest, removeRoutingEntry)
{
    std::string participantId("participantId");

    EXPECT_CALL(*(mockMessageRouter.get()), removeNextHop(participantId, _, _));

    MessageSender messageSender(mockMessageRouter, nullptr);
    messageSender.removeRoutingEntry(participantId);
}

TEST_F(MessageSenderTest, sendPublication_normal)
{

    SubscriptionPublication publication;
    publication.setSubscriptionId("ignoresubscriptionid");
    publication.setResponse(std::string("publication"));

    MutableMessage mutableMessage = messageFactory.createSubscriptionPublication(
            senderID, receiverID, qosSettings, publication);

    expectRoutedMessage(Message::VALUE_MESSAGE_TYPE_PUBLICATION(), mutableMessage.getPayload());

    MessageSender messageSender(mockMessageRouter, nullptr);
    messageSender.registerDispatcher(mockDispatcher);
    messageSender.sendSubscriptionPublication(
            senderID, receiverID, qosSettings, std::move(publication));
}

TEST_F(MessageSenderTest, sendMulticastSubscriptionRequest)
{
    const std::string senderParticipantId("senderParticipantId");
    const std::string receiverParticipantId("receiverParticipantId");
    const std::string subscriptionId("subscriptionId");
    MessagingQos messagingQos(1, MessagingQosEffort::Enum::BEST_EFFORT);
    auto subscriptionQos = std::make_shared<MulticastSubscriptionQos>();

    MulticastSubscriptionRequest subscriptionRequest;
    subscriptionRequest.setSubscribeToName("subscribeToName");
    subscriptionRequest.setSubscriptionId(subscriptionId);
    subscriptionRequest.setQos(subscriptionQos);
    subscriptionRequest.setMulticastId("multicastId");

    MutableMessage mutableMessage =
            messageFactory.createMulticastSubscriptionRequest(senderParticipantId,
                                                              receiverParticipantId,
                                                              messagingQos,
                                                              subscriptionRequest,
                                                              isLocalMessage);

    SubscriptionReply subscriptionReply;
    subscriptionReply.setSubscriptionId("subscriptionId");

    MutableMessage mutableReplyMessage = messageFactory.createSubscriptionReply(
            receiverParticipantId, senderParticipantId, messagingQos, subscriptionReply);

    expectRoutedMessage(
            Message::VALUE_MESSAGE_TYPE_SUBSCRIPTION_REPLY(), mutableReplyMessage.getPayload());

    MessageSender messageSender(mockMessageRouter, nullptr);

    messageSender.sendMulticastSubscriptionRequest(senderParticipantId,
                                                   receiverParticipantId,
                                                   messagingQos,
                                                   subscriptionRequest,
                                                   isLocalMessage);
}
<|endoftext|>


<commit_before>/**
 * Copyright (c) 2017 Darius Rückert
 * Licensed under the MIT License.
 * See LICENSE file for more information.
 */

#include "saiga/image/freeimage.h"
#include "saiga/util/assert.h"

#ifdef SAIGA_USE_FREEIMAGE
#include <FreeImagePlus.h>
#include <cstring>

namespace Saiga {
namespace FIP {

bool load(const std::string &path, Image &img, ImageMetadata *metaData)
{
    fipImage fimg;
    if(!loadFIP(path,fimg)){
        return false;
    }

    if(metaData){
        getMetaData(fimg,*metaData);
        //        printAllMetaData(fimg);
    }

    convert(fimg,img);

    return true;
}

bool save(const std::string &path, const Image &img)
{
    fipImage fimg;
    convert(img,fimg);

    return saveFIP(path,fimg);
}

bool loadFIP(const std::string &path, fipImage &img){
    auto ret = img.load(path.c_str(),JPEG_EXIFROTATE);
    return ret;
}

bool saveFIP(const std::string &path, const fipImage &img){
    auto ret = img.save(path.c_str());
    return ret;
}

void convert(const Image &_src, fipImage &dest)
{

    auto src = _src;

#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR
    if(src.type == UC3)
    {
        ImageView<ucvec3> img = src.getImageView<ucvec3>();
        img.swapChannels(0,2);
    }
    if(src.type == UC4)
    {
        ImageView<ucvec4> img = src.getImageView<ucvec4>();
        img.swapChannels(0,2);
    }
#endif

    int bpp = elementSize(src.type) * 8;

    FREE_IMAGE_TYPE t = FIT_BITMAP;

    switch(_src.type)
    {
        case US1:
        t = FIT_UINT16;
        break;
    default:
        break;
    }

    auto res = dest.setSize(
                t,
                src.width,src.height,
                bpp
                );

    SAIGA_ASSERT(res);

    for(int i =0; i < src.rows; ++i)
    {
        memcpy(dest.getScanLine(i),src.rowPtr(i), std::min<int>(dest.getScanWidth(),src.pitchBytes));
    }

}

void convert(const fipImage &src, Image& dest){

    SAIGA_ASSERT(src.isValid());
    dest.width = src.getWidth();
    dest.height = src.getHeight();

    int channels = -1;
    switch(src.getColorType()){
    case FIC_MINISBLACK:
        channels = 1;
        break;
    case FIC_RGB:
        channels = 3;
        break;
    case FIC_RGBALPHA:
        channels = 4;
        break;
    default:
        break;
    }
    SAIGA_ASSERT(channels != -1);

    if(src.getBitsPerPixel() == 32 && channels ==3)
    {
        channels = 4;
    }

    int bitDepth= src.getBitsPerPixel() / channels;
    ImageElementType elementType = IET_ELEMENT_UNKNOWN;
    switch(bitDepth)
    {
    case 8:
        elementType = IET_UCHAR;
        break;
    case 16:
        elementType = IET_USHORT;
        break;
    case 32:
        elementType = IET_UINT;
        break;
    }
    SAIGA_ASSERT(elementType != IET_ELEMENT_UNKNOWN);

    //    cout << "Channels: " << format.getChannels() << " BitsPerPixel: " << src.getBitsPerPixel() << " Bitdepth: " << format.getBitDepth() << endl;

    //    cout << format << endl;

    dest.type =  getType(channels,elementType);
    dest.create();

    for(int i =0; i < dest.rows; ++i)
    {
        memcpy(dest.rowPtr(i),src.getScanLine(i), std::min<int>(dest.pitchBytes,src.getScanWidth()));
    }

#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR
    if(dest.type == UC3)
    {
        ImageView<ucvec3> img = dest.getImageView<ucvec3>();
        img.swapChannels(0,2);
    }
    if(dest.type == UC4)
    {
        ImageView<ucvec4> img = dest.getImageView<ucvec4>();
        img.swapChannels(0,2);
    }
#endif

}

#endif

static double parseFraction(const void* data){
    const int* idata = reinterpret_cast<const int*>(data);

    return double(idata[0]) / double(idata[1]);
}

void getMetaData(fipImage &img, ImageMetadata& metaData){
    metaData.width = img.getWidth();
    metaData.height = img.getHeight();

    fipTag tag;
    fipMetadataFind finder;
    if( finder.findFirstMetadata(FIMD_EXIF_MAIN, img, tag) ) {
        do {
            std::string t = tag.getKey();

            if(t == "DateTime"){
                metaData.DateTime = tag.toString(FIMD_EXIF_MAIN);
            }else if(t == "Make"){
                metaData.Make = (char*)tag.getValue();
            }else if(t == "Model"){
                metaData.Model = (char*)tag.getValue();
            }else{
                //                cout << "Tag: " << tag.getKey() << " Value: " << tag.toString(FIMD_EXIF_MAIN) << endl;
            }

        } while( finder.findNextMetadata(tag) );
    }

    // the class can be called again with another metadata model
    if( finder.findFirstMetadata(FIMD_EXIF_EXIF, img, tag) ) {
        do {
            std::string t = tag.getKey();
            if(t == "FocalLength"){
                metaData.FocalLengthMM = parseFraction(tag.getValue());
            }else if(t == "FocalLengthIn35mmFilm"){
                metaData.FocalLengthMM35 = reinterpret_cast<const short*>(tag.getValue())[0];
            }else if(t == "FocalPlaneResolutionUnit"){
                metaData.FocalPlaneResolutionUnit = (ImageMetadata::ResolutionUnit) reinterpret_cast<const short*>(tag.getValue())[0];
            }else if(t == "FocalPlaneXResolution"){
                metaData.FocalPlaneXResolution = parseFraction(tag.getValue());
            }else if(t == "FocalPlaneYResolution"){
                metaData.FocalPlaneYResolution = parseFraction(tag.getValue());
            }else{
                //                cout << "Tag: " << tag.getKey() << " Value: " << tag.toString(FIMD_EXIF_MAIN) << endl;
            }
        } while( finder.findNextMetadata(tag) );
    }

}

void printAllMetaData(fipImage &img)
{
    for(int i = -1; i <= 11; ++i){
        FREE_IMAGE_MDMODEL model = (FREE_IMAGE_MDMODEL)i;
        cout << "Model: " << model << endl;
        fipTag tag;
        fipMetadataFind finder;
        if( finder.findFirstMetadata(model, img, tag) ) {
            do {
                std::string t = tag.getKey();

                cout << tag.getKey() << " : " << tag.toString(model) << " Type: " << tag.getType() << endl;

            } while( finder.findNextMetadata(tag) );
        }
    }

}

}
}
<commit_msg>no freeimage fix<commit_after>/**
 * Copyright (c) 2017 Darius Rückert
 * Licensed under the MIT License.
 * See LICENSE file for more information.
 */

#include "saiga/image/freeimage.h"
#include "saiga/util/assert.h"

#ifdef SAIGA_USE_FREEIMAGE
#include <FreeImagePlus.h>
#include <cstring>

namespace Saiga {
namespace FIP {

bool load(const std::string &path, Image &img, ImageMetadata *metaData)
{
    fipImage fimg;
    if(!loadFIP(path,fimg)){
        return false;
    }

    if(metaData){
        getMetaData(fimg,*metaData);
        //        printAllMetaData(fimg);
    }

    convert(fimg,img);

    return true;
}

bool save(const std::string &path, const Image &img)
{
    fipImage fimg;
    convert(img,fimg);

    return saveFIP(path,fimg);
}

bool loadFIP(const std::string &path, fipImage &img){
    auto ret = img.load(path.c_str(),JPEG_EXIFROTATE);
    return ret;
}

bool saveFIP(const std::string &path, const fipImage &img){
    auto ret = img.save(path.c_str());
    return ret;
}

void convert(const Image &_src, fipImage &dest)
{

    auto src = _src;

#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR
    if(src.type == UC3)
    {
        ImageView<ucvec3> img = src.getImageView<ucvec3>();
        img.swapChannels(0,2);
    }
    if(src.type == UC4)
    {
        ImageView<ucvec4> img = src.getImageView<ucvec4>();
        img.swapChannels(0,2);
    }
#endif

    int bpp = elementSize(src.type) * 8;

    FREE_IMAGE_TYPE t = FIT_BITMAP;

    switch(_src.type)
    {
        case US1:
        t = FIT_UINT16;
        break;
    default:
        break;
    }

    auto res = dest.setSize(
                t,
                src.width,src.height,
                bpp
                );

    SAIGA_ASSERT(res);

    for(int i =0; i < src.rows; ++i)
    {
        memcpy(dest.getScanLine(i),src.rowPtr(i), std::min<int>(dest.getScanWidth(),src.pitchBytes));
    }

}

void convert(const fipImage &src, Image& dest){

    SAIGA_ASSERT(src.isValid());
    dest.width = src.getWidth();
    dest.height = src.getHeight();

    int channels = -1;
    switch(src.getColorType()){
    case FIC_MINISBLACK:
        channels = 1;
        break;
    case FIC_RGB:
        channels = 3;
        break;
    case FIC_RGBALPHA:
        channels = 4;
        break;
    default:
        break;
    }
    SAIGA_ASSERT(channels != -1);

    if(src.getBitsPerPixel() == 32 && channels ==3)
    {
        channels = 4;
    }

    int bitDepth= src.getBitsPerPixel() / channels;
    ImageElementType elementType = IET_ELEMENT_UNKNOWN;
    switch(bitDepth)
    {
    case 8:
        elementType = IET_UCHAR;
        break;
    case 16:
        elementType = IET_USHORT;
        break;
    case 32:
        elementType = IET_UINT;
        break;
    }
    SAIGA_ASSERT(elementType != IET_ELEMENT_UNKNOWN);

    //    cout << "Channels: " << format.getChannels() << " BitsPerPixel: " << src.getBitsPerPixel() << " Bitdepth: " << format.getBitDepth() << endl;

    //    cout << format << endl;

    dest.type =  getType(channels,elementType);
    dest.create();

    for(int i =0; i < dest.rows; ++i)
    {
        memcpy(dest.rowPtr(i),src.getScanLine(i), std::min<int>(dest.pitchBytes,src.getScanWidth()));
    }

#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR
    if(dest.type == UC3)
    {
        ImageView<ucvec3> img = dest.getImageView<ucvec3>();
        img.swapChannels(0,2);
    }
    if(dest.type == UC4)
    {
        ImageView<ucvec4> img = dest.getImageView<ucvec4>();
        img.swapChannels(0,2);
    }
#endif

}

static double parseFraction(const void* data){
    const int* idata = reinterpret_cast<const int*>(data);

    return double(idata[0]) / double(idata[1]);
}

void getMetaData(fipImage &img, ImageMetadata& metaData){
    metaData.width = img.getWidth();
    metaData.height = img.getHeight();

    fipTag tag;
    fipMetadataFind finder;
    if( finder.findFirstMetadata(FIMD_EXIF_MAIN, img, tag) ) {
        do {
            std::string t = tag.getKey();

            if(t == "DateTime"){
                metaData.DateTime = tag.toString(FIMD_EXIF_MAIN);
            }else if(t == "Make"){
                metaData.Make = (char*)tag.getValue();
            }else if(t == "Model"){
                metaData.Model = (char*)tag.getValue();
            }else{
                //                cout << "Tag: " << tag.getKey() << " Value: " << tag.toString(FIMD_EXIF_MAIN) << endl;
            }

        } while( finder.findNextMetadata(tag) );
    }

    // the class can be called again with another metadata model
    if( finder.findFirstMetadata(FIMD_EXIF_EXIF, img, tag) ) {
        do {
            std::string t = tag.getKey();
            if(t == "FocalLength"){
                metaData.FocalLengthMM = parseFraction(tag.getValue());
            }else if(t == "FocalLengthIn35mmFilm"){
                metaData.FocalLengthMM35 = reinterpret_cast<const short*>(tag.getValue())[0];
            }else if(t == "FocalPlaneResolutionUnit"){
                metaData.FocalPlaneResolutionUnit = (ImageMetadata::ResolutionUnit) reinterpret_cast<const short*>(tag.getValue())[0];
            }else if(t == "FocalPlaneXResolution"){
                metaData.FocalPlaneXResolution = parseFraction(tag.getValue());
            }else if(t == "FocalPlaneYResolution"){
                metaData.FocalPlaneYResolution = parseFraction(tag.getValue());
            }else{
                //                cout << "Tag: " << tag.getKey() << " Value: " << tag.toString(FIMD_EXIF_MAIN) << endl;
            }
        } while( finder.findNextMetadata(tag) );
    }

}

void printAllMetaData(fipImage &img)
{
    for(int i = -1; i <= 11; ++i){
        FREE_IMAGE_MDMODEL model = (FREE_IMAGE_MDMODEL)i;
        cout << "Model: " << model << endl;
        fipTag tag;
        fipMetadataFind finder;
        if( finder.findFirstMetadata(model, img, tag) ) {
            do {
                std::string t = tag.getKey();

                cout << tag.getKey() << " : " << tag.toString(model) << " Type: " << tag.getType() << endl;

            } while( finder.findNextMetadata(tag) );
        }
    }

}

}
}

#endif
<|endoftext|>


<commit_before>#include <cmath>
#include <array>
#include <chrono>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <algorithm>

#include <sys/stat.h>

#include "simulation.h"
#include "codes/codes.h"

namespace detail {
inline bool file_exists(const std::string &fname) {
  struct stat buf;
  return (stat(fname.c_str(), &buf) != -1);
}
}

static std::array<double, 131> rates{
  { 0.01,  0.02,  0.03,  0.04,  0.05,  0.06,  0.07,  0.08,  0.09,  0.10,  0.11,
    0.12,  0.13,  0.14,  0.15,  0.16,  0.17,  0.18,  0.19,  0.20,  0.21,  0.22,
    0.23,  0.24,  0.25,  0.26,  0.27,  0.28,  0.29,  0.30,  0.31,  0.32,  0.33,
    0.34,  0.35,  0.36,  0.37,  0.38,  0.39,  0.40,  0.41,  0.42,  0.43,  0.44,
    0.45,  0.46,  0.47,  0.48,  0.49,  0.50,  0.51,  0.52,  0.53,  0.54,  0.55,
    0.56,  0.57,  0.58,  0.59,  0.60,  0.61,  0.62,  0.63,  0.64,  0.65,  0.66,
    0.67,  0.68,  0.69,  0.70,  0.71,  0.72,  0.73,  0.74,  0.75,  0.76,  0.77,
    0.78,  0.79,  0.800, 0.807, 0.817, 0.827, 0.837, 0.846, 0.855, 0.864, 0.872,
    0.880, 0.887, 0.894, 0.900, 0.907, 0.913, 0.918, 0.924, 0.929, 0.934, 0.938,
    0.943, 0.947, 0.951, 0.954, 0.958, 0.961, 0.964, 0.967, 0.970, 0.972, 0.974,
    0.976, 0.978, 0.980, 0.982, 0.983, 0.984, 0.985, 0.986, 0.987, 0.988, 0.989,
    0.990, 0.991, 0.992, 0.993, 0.994, 0.995, 0.996, 0.997, 0.998, 0.999 }
};

static std::array<double, 131> limits = {
  { -1.548, -1.531, -1.500, -1.470, -1.440, -1.409, -1.378, -1.347, -1.316,
    -1.285, -1.254, -1.222, -1.190, -1.158, -1.126, -1.094, -1.061, -1.028,
    -0.995, -0.963, -0.928, -0.896, -0.861, -0.827, -0.793, -0.757, -0.724,
    -0.687, -0.651, -0.616, -0.579, -0.544, -0.507, -0.469, -0.432, -0.394,
    -0.355, -0.314, -0.276, -0.236, -0.198, -0.156, -0.118, -0.074, -0.032,
    0.010,  0.055,  0.097,  0.144,  0.188,  0.233,  0.279,  0.326,  0.374,
    0.424,  0.474,  0.526,  0.574,  0.628,  0.682,  0.734,  0.791,  0.844,
    0.904,  0.960,  1.021,  1.084,  1.143,  1.208,  1.275,  1.343,  1.412,
    1.483,  1.554,  1.628,  1.708,  1.784,  1.867,  1.952,  2.045,  2.108,
    2.204,  2.302,  2.402,  2.503,  2.600,  2.712,  2.812,  2.913,  3.009,
    3.114,  3.205,  3.312,  3.414,  3.500,  3.612,  3.709,  3.815,  3.906,
    4.014,  4.115,  4.218,  4.304,  4.425,  4.521,  4.618,  4.725,  4.841,
    4.922,  5.004,  5.104,  5.196,  5.307,  5.418,  5.484,  5.549,  5.615,
    5.681,  5.756,  5.842,  5.927,  6.023,  6.119,  6.234,  6.360,  6.495,
    6.651,  6.837,  7.072,  7.378,  7.864 }
};

static constexpr double ebno(const double rate) {
  if (rate <= 0.800) {
    const size_t index = static_cast<size_t>(rate * 100);
    return limits.at(index);
  } else if (rate >= 0.999) {
    return limits.back();
  } else {
    const size_t offset = 80;
    const size_t index = static_cast<size_t>(std::distance(
        std::cbegin(rates),
        std::find_if(std::cbegin(rates) + offset, std::cend(rates) - 1,
                     [=](const double r) { return r >= rate; })));
    return limits.at(index);
  }
}

static std::ofstream open_file(const std::string &fname) {
  if (detail::file_exists(fname)) {
    std::ostringstream os;
    os << "File " << fname << " already exists.";
    throw std::runtime_error(os.str());
  }

  std::ofstream log_file(fname.c_str(), std::ofstream::out);
  return log_file;
}

double awgn_simulation::sigma(const double eb_no) const {
  return 1.0f / sqrt((2 * decoder.rate() * pow(10, eb_no / 10.0)));
}

awgn_simulation::awgn_simulation(const class decoder &decoder_,
                                 const double step_, const uint64_t seed_)
    : decoder(decoder_), step(step_), seed(seed_) {}

void awgn_simulation::operator()() {
  const size_t wer_width = std::numeric_limits<double>::digits10;
  const size_t ebno_width = 6;
  std::ofstream log_file(open_file(decoder.to_string() + ".log"));
  std::vector<float> b(decoder.n());

  log_file << std::setw(ebno_width + 1) << "ebno"
           << " ";
  log_file << std::setw(wer_width + 6) << "wer" << std::endl;

  const size_t factor = static_cast<size_t>(1.0 / step);
  const size_t tmp = static_cast<size_t>(ebno(decoder.rate()) / step);
  const double start = (tmp + (1.0 / step)) * step;
  const double max = std::max(8.0, start) + step / 2;

  /* TODO round ebno() up to next step */
  for (double eb_no = start; eb_no < max; eb_no += step) {
    std::normal_distribution<float> distribution(
        1.0, static_cast<float>(sigma(eb_no)));
    auto noise = std::bind(std::ref(distribution), std::ref(generator));
    size_t word_errors = 0;
    size_t samples = 10000;

    std::cout << std::this_thread::get_id() << " " << decoder.to_string()
              << ": E_b/N_0 = " << eb_no << " with " << samples << " … ";
    std::cout.flush();
    auto start_time = std::chrono::high_resolution_clock::now();

    for (size_t i = 0; i < samples; i++) {
      std::generate(std::begin(b), std::end(b), noise);
      try {
        auto result = decoder.correct(b);
        if (std::any_of(std::cbegin(result), std::cend(result),
                        [](const auto &bit) { return bool(bit); })) {
          word_errors++;
        }
      }
      catch (const decoding_failure &) {
        word_errors++;
      }
    }

    auto end_time = std::chrono::high_resolution_clock::now();
    auto seconds = std::chrono::duration_cast<std::chrono::seconds>(
        end_time - start_time).count();
    std::cout << seconds << " s" << std::endl;

    log_file << std::setw(ebno_width + 1) << std::setprecision(ebno_width)
             << std::defaultfloat << eb_no << " ";
    log_file << std::setw(wer_width + 1) << std::setprecision(wer_width)
             << std::scientific << static_cast<double>(word_errors) / samples
             << std::endl;
  }
}

bitflip_simulation::bitflip_simulation(const class decoder &decoder,
                                       const size_t errors)
    : decoder(decoder), errors(errors) {}

void bitflip_simulation::operator()() const {
  const size_t wer_width = std::numeric_limits<double>::digits10;
  const size_t ebno_width = 6;

  std::ofstream log_file(open_file(decoder.to_string() + ".log"));
  std::vector<float> b(decoder.n());

  log_file << std::setw(ebno_width + 1) << "errors"
           << " ";
  log_file << std::setw(wer_width + 6) << "wer" << std::endl;

  const size_t length = decoder.n();

  for (size_t error = 0; error <= errors; error++) {
    size_t patterns = 0;
    size_t word_errors = 0;
    std::vector<int> b;

    std::fill_n(std::back_inserter(b), length - error, 0);
    std::fill_n(std::back_inserter(b), error, 1);

    std::cout << std::this_thread::get_id() << " " << decoder.to_string()
              << ": errors = " << error << " … ";
    std::cout.flush();
    auto start = std::chrono::high_resolution_clock::now();

    do {
      std::vector<float> x;
      x.reserve(length);

      std::transform(std::cbegin(b), std::cend(b), std::back_inserter(x),
                     [](const auto &bit) { return -2 * bit + 1; });

      patterns++;
      try {
        auto result = decoder.correct(x);
        if (std::any_of(std::cbegin(result), std::cend(result),
                        [](const auto &bit) { return bool(bit); })) {
          word_errors++;
        }
      }
      catch (const decoding_failure &) {
        word_errors++;
      }
    } while (std::next_permutation(std::begin(b), std::end(b)));

    auto end = std::chrono::high_resolution_clock::now();
    auto seconds =
        std::chrono::duration_cast<std::chrono::seconds>(end - start).count();
    std::cout << seconds << " s " << word_errors << " " << patterns
              << std::endl;

    log_file << std::setw(ebno_width + 1) << std::setprecision(ebno_width)
             << std::defaultfloat << error << " ";
    log_file << std::setw(wer_width + 1) << std::setprecision(wer_width)
             << std::scientific << (double)word_errors / patterns << std::endl;
  }
}

std::atomic_bool thread_pool::running{ true };
std::mutex thread_pool::lock;
std::condition_variable thread_pool::cv;
std::list<std::function<void(void)> > thread_pool::queue;

thread_pool::thread_pool() {
  for (unsigned i = 0; i < std::thread::hardware_concurrency(); i++) {
    pool.emplace_back(std::bind(&thread_pool::thread_function, this));
  }
}

thread_pool::~thread_pool() {
  running = false;
  cv.notify_all();
  for (auto &&t : pool)
    t.join();
}

void thread_pool::thread_function() const {
  for (;;) {
    bool have_work = false;
    std::function<void(void)> work;
    {
      std::unique_lock<std::mutex> m(lock);

      /*
       * empty running wait
       * 0     0       0
       * 0     1       0
       * 1     0       0
       * 1     1       1
      */
      cv.wait(m, [&]() { return !(queue.empty() && running); });
      if (!queue.empty()) {
        work = queue.front();
        queue.pop_front();
        have_work = true;
      }
    }

    if (have_work) {
      try {
        work();
      }
      catch (const std::exception &e) {
        std::cerr << e.what() << std::endl;
      }
    } else if (!running) {
      return;
    }
  }
}

<commit_msg>Remove unused variable<commit_after>#include <cmath>
#include <array>
#include <chrono>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <algorithm>

#include <sys/stat.h>

#include "simulation.h"
#include "codes/codes.h"

namespace detail {
inline bool file_exists(const std::string &fname) {
  struct stat buf;
  return (stat(fname.c_str(), &buf) != -1);
}
}

static std::array<double, 131> rates{
  { 0.01,  0.02,  0.03,  0.04,  0.05,  0.06,  0.07,  0.08,  0.09,  0.10,  0.11,
    0.12,  0.13,  0.14,  0.15,  0.16,  0.17,  0.18,  0.19,  0.20,  0.21,  0.22,
    0.23,  0.24,  0.25,  0.26,  0.27,  0.28,  0.29,  0.30,  0.31,  0.32,  0.33,
    0.34,  0.35,  0.36,  0.37,  0.38,  0.39,  0.40,  0.41,  0.42,  0.43,  0.44,
    0.45,  0.46,  0.47,  0.48,  0.49,  0.50,  0.51,  0.52,  0.53,  0.54,  0.55,
    0.56,  0.57,  0.58,  0.59,  0.60,  0.61,  0.62,  0.63,  0.64,  0.65,  0.66,
    0.67,  0.68,  0.69,  0.70,  0.71,  0.72,  0.73,  0.74,  0.75,  0.76,  0.77,
    0.78,  0.79,  0.800, 0.807, 0.817, 0.827, 0.837, 0.846, 0.855, 0.864, 0.872,
    0.880, 0.887, 0.894, 0.900, 0.907, 0.913, 0.918, 0.924, 0.929, 0.934, 0.938,
    0.943, 0.947, 0.951, 0.954, 0.958, 0.961, 0.964, 0.967, 0.970, 0.972, 0.974,
    0.976, 0.978, 0.980, 0.982, 0.983, 0.984, 0.985, 0.986, 0.987, 0.988, 0.989,
    0.990, 0.991, 0.992, 0.993, 0.994, 0.995, 0.996, 0.997, 0.998, 0.999 }
};

static std::array<double, 131> limits = {
  { -1.548, -1.531, -1.500, -1.470, -1.440, -1.409, -1.378, -1.347, -1.316,
    -1.285, -1.254, -1.222, -1.190, -1.158, -1.126, -1.094, -1.061, -1.028,
    -0.995, -0.963, -0.928, -0.896, -0.861, -0.827, -0.793, -0.757, -0.724,
    -0.687, -0.651, -0.616, -0.579, -0.544, -0.507, -0.469, -0.432, -0.394,
    -0.355, -0.314, -0.276, -0.236, -0.198, -0.156, -0.118, -0.074, -0.032,
    0.010,  0.055,  0.097,  0.144,  0.188,  0.233,  0.279,  0.326,  0.374,
    0.424,  0.474,  0.526,  0.574,  0.628,  0.682,  0.734,  0.791,  0.844,
    0.904,  0.960,  1.021,  1.084,  1.143,  1.208,  1.275,  1.343,  1.412,
    1.483,  1.554,  1.628,  1.708,  1.784,  1.867,  1.952,  2.045,  2.108,
    2.204,  2.302,  2.402,  2.503,  2.600,  2.712,  2.812,  2.913,  3.009,
    3.114,  3.205,  3.312,  3.414,  3.500,  3.612,  3.709,  3.815,  3.906,
    4.014,  4.115,  4.218,  4.304,  4.425,  4.521,  4.618,  4.725,  4.841,
    4.922,  5.004,  5.104,  5.196,  5.307,  5.418,  5.484,  5.549,  5.615,
    5.681,  5.756,  5.842,  5.927,  6.023,  6.119,  6.234,  6.360,  6.495,
    6.651,  6.837,  7.072,  7.378,  7.864 }
};

static constexpr double ebno(const double rate) {
  if (rate <= 0.800) {
    const size_t index = static_cast<size_t>(rate * 100);
    return limits.at(index);
  } else if (rate >= 0.999) {
    return limits.back();
  } else {
    const size_t offset = 80;
    const size_t index = static_cast<size_t>(std::distance(
        std::cbegin(rates),
        std::find_if(std::cbegin(rates) + offset, std::cend(rates) - 1,
                     [=](const double r) { return r >= rate; })));
    return limits.at(index);
  }
}

static std::ofstream open_file(const std::string &fname) {
  if (detail::file_exists(fname)) {
    std::ostringstream os;
    os << "File " << fname << " already exists.";
    throw std::runtime_error(os.str());
  }

  std::ofstream log_file(fname.c_str(), std::ofstream::out);
  return log_file;
}

double awgn_simulation::sigma(const double eb_no) const {
  return 1.0f / sqrt((2 * decoder.rate() * pow(10, eb_no / 10.0)));
}

awgn_simulation::awgn_simulation(const class decoder &decoder_,
                                 const double step_, const uint64_t seed_)
    : decoder(decoder_), step(step_), seed(seed_) {}

void awgn_simulation::operator()() {
  const size_t wer_width = std::numeric_limits<double>::digits10;
  const size_t ebno_width = 6;
  std::ofstream log_file(open_file(decoder.to_string() + ".log"));
  std::vector<float> b(decoder.n());

  log_file << std::setw(ebno_width + 1) << "ebno"
           << " ";
  log_file << std::setw(wer_width + 6) << "wer" << std::endl;

  const size_t tmp = static_cast<size_t>(ebno(decoder.rate()) / step);
  const double start = (tmp + (1.0 / step)) * step;
  const double max = std::max(8.0, start) + step / 2;

  /* TODO round ebno() up to next step */
  for (double eb_no = start; eb_no < max; eb_no += step) {
    std::normal_distribution<float> distribution(
        1.0, static_cast<float>(sigma(eb_no)));
    auto noise = std::bind(std::ref(distribution), std::ref(generator));
    size_t word_errors = 0;
    size_t samples = 10000;

    std::cout << std::this_thread::get_id() << " " << decoder.to_string()
              << ": E_b/N_0 = " << eb_no << " with " << samples << " … ";
    std::cout.flush();
    auto start_time = std::chrono::high_resolution_clock::now();

    for (size_t i = 0; i < samples; i++) {
      std::generate(std::begin(b), std::end(b), noise);
      try {
        auto result = decoder.correct(b);
        if (std::any_of(std::cbegin(result), std::cend(result),
                        [](const auto &bit) { return bool(bit); })) {
          word_errors++;
        }
      }
      catch (const decoding_failure &) {
        word_errors++;
      }
    }

    auto end_time = std::chrono::high_resolution_clock::now();
    auto seconds = std::chrono::duration_cast<std::chrono::seconds>(
        end_time - start_time).count();
    std::cout << seconds << " s" << std::endl;

    log_file << std::setw(ebno_width + 1) << std::setprecision(ebno_width)
             << std::defaultfloat << eb_no << " ";
    log_file << std::setw(wer_width + 1) << std::setprecision(wer_width)
             << std::scientific << static_cast<double>(word_errors) / samples
             << std::endl;
  }
}

bitflip_simulation::bitflip_simulation(const class decoder &decoder,
                                       const size_t errors)
    : decoder(decoder), errors(errors) {}

void bitflip_simulation::operator()() const {
  const size_t wer_width = std::numeric_limits<double>::digits10;
  const size_t ebno_width = 6;

  std::ofstream log_file(open_file(decoder.to_string() + ".log"));
  std::vector<float> b(decoder.n());

  log_file << std::setw(ebno_width + 1) << "errors"
           << " ";
  log_file << std::setw(wer_width + 6) << "wer" << std::endl;

  const size_t length = decoder.n();

  for (size_t error = 0; error <= errors; error++) {
    size_t patterns = 0;
    size_t word_errors = 0;
    std::vector<int> b;

    std::fill_n(std::back_inserter(b), length - error, 0);
    std::fill_n(std::back_inserter(b), error, 1);

    std::cout << std::this_thread::get_id() << " " << decoder.to_string()
              << ": errors = " << error << " … ";
    std::cout.flush();
    auto start = std::chrono::high_resolution_clock::now();

    do {
      std::vector<float> x;
      x.reserve(length);

      std::transform(std::cbegin(b), std::cend(b), std::back_inserter(x),
                     [](const auto &bit) { return -2 * bit + 1; });

      patterns++;
      try {
        auto result = decoder.correct(x);
        if (std::any_of(std::cbegin(result), std::cend(result),
                        [](const auto &bit) { return bool(bit); })) {
          word_errors++;
        }
      }
      catch (const decoding_failure &) {
        word_errors++;
      }
    } while (std::next_permutation(std::begin(b), std::end(b)));

    auto end = std::chrono::high_resolution_clock::now();
    auto seconds =
        std::chrono::duration_cast<std::chrono::seconds>(end - start).count();
    std::cout << seconds << " s " << word_errors << " " << patterns
              << std::endl;

    log_file << std::setw(ebno_width + 1) << std::setprecision(ebno_width)
             << std::defaultfloat << error << " ";
    log_file << std::setw(wer_width + 1) << std::setprecision(wer_width)
             << std::scientific << (double)word_errors / patterns << std::endl;
  }
}

std::atomic_bool thread_pool::running{ true };
std::mutex thread_pool::lock;
std::condition_variable thread_pool::cv;
std::list<std::function<void(void)> > thread_pool::queue;

thread_pool::thread_pool() {
  for (unsigned i = 0; i < std::thread::hardware_concurrency(); i++) {
    pool.emplace_back(std::bind(&thread_pool::thread_function, this));
  }
}

thread_pool::~thread_pool() {
  running = false;
  cv.notify_all();
  for (auto &&t : pool)
    t.join();
}

void thread_pool::thread_function() const {
  for (;;) {
    bool have_work = false;
    std::function<void(void)> work;
    {
      std::unique_lock<std::mutex> m(lock);

      /*
       * empty running wait
       * 0     0       0
       * 0     1       0
       * 1     0       0
       * 1     1       1
      */
      cv.wait(m, [&]() { return !(queue.empty() && running); });
      if (!queue.empty()) {
        work = queue.front();
        queue.pop_front();
        have_work = true;
      }
    }

    if (have_work) {
      try {
        work();
      }
      catch (const std::exception &e) {
        std::cerr << e.what() << std::endl;
      }
    } else if (!running) {
      return;
    }
  }
}

<|endoftext|>


<commit_before>#ifndef STAN_IO_VALIDATE_DIMS_HPP
#define STAN_IO_VALIDATE_DIMS_HPP

#include <stan/io/var_context.hpp>
#include <string>
#include <vector>

namespace stan {
namespace io {

/**
 * Check variable dimensions against variable declaration.
 *
 * @param context The var context to check.
 * @param stage stan program processing stage
 * @param name variable name
 * @param base_type declared stan variable type
 * @param dims variable dimensions
 * @throw std::runtime_error if mismatch between declared
 *        dimensions and dimensions found in context.
 */
void validate_dims(const stan::io::var_context& context,
                   const std::string& stage, const std::string& name,
                   const std::string& base_type,
                   const std::vector<size_t>& dims_declared) {
  bool is_int_type = base_type == "int";
  if (is_int_type) {
    if (!context.contains_i(name)) {
      std::stringstream msg;
      msg << (context.contains_r(name) ? "int variable contained non-int values"
                                       : "variable does not exist")
          << "; processing stage=" << stage << "; variable name=" << name
          << "; base type=" << base_type;
      throw std::runtime_error(msg.str());
    }
  } else {
    if (!context.contains_r(name)) {
      std::stringstream msg;
      msg << "variable does not exist"
          << "; processing stage=" << stage << "; variable name=" << name
          << "; base type=" << base_type;
      throw std::runtime_error(msg.str());
    }
  }
  std::vector<size_t> dims = context.dims_r(name);
  if (dims.size() != dims_declared.size()) {
    std::stringstream msg;
    msg << "mismatch in number dimensions declared and found in context"
        << "; processing stage=" << stage << "; variable name=" << name
        << "; dims declared=";
    context.dims_msg(msg, dims_declared);
    msg << "; dims found=";
    context.dims_msg(msg, dims);
    throw std::runtime_error(msg.str());
  }
  for (size_t i = 0; i < dims.size(); ++i) {
    if (dims_declared[i] != dims[i]) {
      std::stringstream msg;
      msg << "mismatch in dimension declared and found in context"
          << "; processing stage=" << stage << "; variable name=" << name
          << "; position=" << i << "; dims declared=";
      context.dims_msg(msg, dims_declared);
      msg << "; dims found=";
      context.dims_msg(msg, dims);
      throw std::runtime_error(msg.str());
    }
  }
}

}  // namespace io
}  // namespace stan
#endif
<commit_msg>inline validate dims<commit_after>#ifndef STAN_IO_VALIDATE_DIMS_HPP
#define STAN_IO_VALIDATE_DIMS_HPP

#include <stan/io/var_context.hpp>
#include <string>
#include <vector>

namespace stan {
namespace io {

/**
 * Check variable dimensions against variable declaration.
 *
 * @param context The var context to check.
 * @param stage stan program processing stage
 * @param name variable name
 * @param base_type declared stan variable type
 * @param dims variable dimensions
 * @throw std::runtime_error if mismatch between declared
 *        dimensions and dimensions found in context.
 */
inline void validate_dims(const stan::io::var_context& context,
                   const std::string& stage, const std::string& name,
                   const std::string& base_type,
                   const std::vector<size_t>& dims_declared) {
  bool is_int_type = base_type == "int";
  if (is_int_type) {
    if (!context.contains_i(name)) {
      std::stringstream msg;
      msg << (context.contains_r(name) ? "int variable contained non-int values"
                                       : "variable does not exist")
          << "; processing stage=" << stage << "; variable name=" << name
          << "; base type=" << base_type;
      throw std::runtime_error(msg.str());
    }
  } else {
    if (!context.contains_r(name)) {
      std::stringstream msg;
      msg << "variable does not exist"
          << "; processing stage=" << stage << "; variable name=" << name
          << "; base type=" << base_type;
      throw std::runtime_error(msg.str());
    }
  }
  std::vector<size_t> dims = context.dims_r(name);
  if (dims.size() != dims_declared.size()) {
    std::stringstream msg;
    msg << "mismatch in number dimensions declared and found in context"
        << "; processing stage=" << stage << "; variable name=" << name
        << "; dims declared=";
    context.dims_msg(msg, dims_declared);
    msg << "; dims found=";
    context.dims_msg(msg, dims);
    throw std::runtime_error(msg.str());
  }
  for (size_t i = 0; i < dims.size(); ++i) {
    if (dims_declared[i] != dims[i]) {
      std::stringstream msg;
      msg << "mismatch in dimension declared and found in context"
          << "; processing stage=" << stage << "; variable name=" << name
          << "; position=" << i << "; dims declared=";
      context.dims_msg(msg, dims_declared);
      msg << "; dims found=";
      context.dims_msg(msg, dims);
      throw std::runtime_error(msg.str());
    }
  }
}

}  // namespace io
}  // namespace stan
#endif
<|endoftext|>


<commit_before>// Copyright (c) 2012-2013 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "consensus/consensus.h"
#include "consensus/tx_verify.h"
#include "consensus/validation.h"
#include "random.h"
#include "pubkey.h"
#include "key.h"
#include "script/script.h"
#include "script/standard.h"
#include "uint256.h"
#include "test/test_bitcoin.h"

#include <vector>

#include <boost/foreach.hpp>
#include <boost/test/unit_test.hpp>

using namespace std;

// Helpers:
static std::vector<unsigned char>
Serialize(const CScript& s)
{
    std::vector<unsigned char> sSerialized(s);
    return sSerialized;
}

BOOST_FIXTURE_TEST_SUITE(sigopcount_tests, BasicTestingSetup)

BOOST_AUTO_TEST_CASE(GetSigOpCount)
{
    // Test CScript::GetSigOpCount()
    CScript s1;
    BOOST_CHECK_EQUAL(s1.GetSigOpCount(false), 0U);
    BOOST_CHECK_EQUAL(s1.GetSigOpCount(true), 0U);

    uint160 dummy;
    s1 << OP_1 << ToByteVector(dummy) << ToByteVector(dummy) << OP_2 << OP_CHECKMULTISIG;
    BOOST_CHECK_EQUAL(s1.GetSigOpCount(true), 2U);
    s1 << OP_IF << OP_CHECKSIG << OP_ENDIF;
    BOOST_CHECK_EQUAL(s1.GetSigOpCount(true), 3U);
    BOOST_CHECK_EQUAL(s1.GetSigOpCount(false), 21U);

    CScript p2sh = GetScriptForDestination(CScriptID(s1));
    CScript scriptSig;
    scriptSig << OP_0 << Serialize(s1);
    BOOST_CHECK_EQUAL(p2sh.GetSigOpCount(scriptSig), 3U);

    std::vector<CPubKey> keys;
    for (int i = 0; i < 3; i++)
    {
        CKey k;
        k.MakeNewKey(true);
        keys.push_back(k.GetPubKey());
    }
    CScript s2 = GetScriptForMultisig(1, keys);
    BOOST_CHECK_EQUAL(s2.GetSigOpCount(true), 3U);
    BOOST_CHECK_EQUAL(s2.GetSigOpCount(false), 20U);

    p2sh = GetScriptForDestination(CScriptID(s2));
    BOOST_CHECK_EQUAL(p2sh.GetSigOpCount(true), 0U);
    BOOST_CHECK_EQUAL(p2sh.GetSigOpCount(false), 0U);
    CScript scriptSig2;
    scriptSig2 << OP_1 << ToByteVector(dummy) << ToByteVector(dummy) << Serialize(s2);
    BOOST_CHECK_EQUAL(p2sh.GetSigOpCount(scriptSig2), 3U);
}

BOOST_AUTO_TEST_CASE(test_max_sigops_per_tx) {
    CMutableTransaction tx;
    tx.nVersion = 1;
    tx.vin.resize(1);
    tx.vin[0].prevout.hash = GetRandHash();
    tx.vin[0].prevout.n = 0;
    tx.vin[0].scriptSig = CScript();
    tx.vout.resize(1);
    tx.vout[0].nValue = 1;
    tx.vout[0].scriptPubKey = CScript();

    {
        CValidationState state;
        BOOST_CHECK(CheckTransaction(tx, state));
    }

    // Get just before the limit.
    for (size_t i = 0; i < MAX_TX_SIGOPS_COUNT; i++) {
        tx.vout[0].scriptPubKey << OP_CHECKSIG;
    }

    {
        CValidationState state;
        BOOST_CHECK(CheckTransaction(tx, state));
    }

    // And go over.
    tx.vout[0].scriptPubKey << OP_CHECKSIG;

    {
        CValidationState state;
        BOOST_CHECK(!CheckTransaction(tx, state));
        BOOST_CHECK_EQUAL(state.GetRejectReason(), "bad-txn-sigops");
    }
}

BOOST_AUTO_TEST_SUITE_END()
<commit_msg>[qa] Add GetTransactionSigOpCost unit tests<commit_after>// Copyright (c) 2012-2013 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "consensus/consensus.h"
#include "consensus/tx_verify.h"
#include "consensus/validation.h"
#include "random.h"
#include "pubkey.h"
#include "key.h"
#include "script/script.h"
#include "script/standard.h"
#include "uint256.h"
#include "test/test_bitcoin.h"

#include <vector>

#include <boost/foreach.hpp>
#include <boost/test/unit_test.hpp>

using namespace std;

// Helpers:
static std::vector<unsigned char>
Serialize(const CScript& s)
{
    std::vector<unsigned char> sSerialized(s);
    return sSerialized;
}

BOOST_FIXTURE_TEST_SUITE(sigopcount_tests, BasicTestingSetup)

BOOST_AUTO_TEST_CASE(GetSigOpCount)
{
    // Test CScript::GetSigOpCount()
    CScript s1;
    BOOST_CHECK_EQUAL(s1.GetSigOpCount(false), 0U);
    BOOST_CHECK_EQUAL(s1.GetSigOpCount(true), 0U);

    uint160 dummy;
    s1 << OP_1 << ToByteVector(dummy) << ToByteVector(dummy) << OP_2 << OP_CHECKMULTISIG;
    BOOST_CHECK_EQUAL(s1.GetSigOpCount(true), 2U);
    s1 << OP_IF << OP_CHECKSIG << OP_ENDIF;
    BOOST_CHECK_EQUAL(s1.GetSigOpCount(true), 3U);
    BOOST_CHECK_EQUAL(s1.GetSigOpCount(false), 21U);

    CScript p2sh = GetScriptForDestination(CScriptID(s1));
    CScript scriptSig;
    scriptSig << OP_0 << Serialize(s1);
    BOOST_CHECK_EQUAL(p2sh.GetSigOpCount(scriptSig), 3U);

    std::vector<CPubKey> keys;
    for (int i = 0; i < 3; i++)
    {
        CKey k;
        k.MakeNewKey(true);
        keys.push_back(k.GetPubKey());
    }
    CScript s2 = GetScriptForMultisig(1, keys);
    BOOST_CHECK_EQUAL(s2.GetSigOpCount(true), 3U);
    BOOST_CHECK_EQUAL(s2.GetSigOpCount(false), 20U);

    p2sh = GetScriptForDestination(CScriptID(s2));
    BOOST_CHECK_EQUAL(p2sh.GetSigOpCount(true), 0U);
    BOOST_CHECK_EQUAL(p2sh.GetSigOpCount(false), 0U);
    CScript scriptSig2;
    scriptSig2 << OP_1 << ToByteVector(dummy) << ToByteVector(dummy) << Serialize(s2);
    BOOST_CHECK_EQUAL(p2sh.GetSigOpCount(scriptSig2), 3U);
}

BOOST_AUTO_TEST_CASE(test_max_sigops_per_tx) {
    CMutableTransaction tx;
    tx.nVersion = 1;
    tx.vin.resize(1);
    tx.vin[0].prevout.hash = GetRandHash();
    tx.vin[0].prevout.n = 0;
    tx.vin[0].scriptSig = CScript();
    tx.vout.resize(1);
    tx.vout[0].nValue = 1;
    tx.vout[0].scriptPubKey = CScript();

    {
        CValidationState state;
        BOOST_CHECK(CheckTransaction(tx, state));
    }

    // Get just before the limit.
    for (size_t i = 0; i < MAX_TX_SIGOPS_COUNT; i++) {
        tx.vout[0].scriptPubKey << OP_CHECKSIG;
    }

    {
        CValidationState state;
        BOOST_CHECK(CheckTransaction(tx, state));
    }

    // And go over.
    tx.vout[0].scriptPubKey << OP_CHECKSIG;

    {
        CValidationState state;
        BOOST_CHECK(!CheckTransaction(tx, state));
        BOOST_CHECK_EQUAL(state.GetRejectReason(), "bad-txn-sigops");
    }
}

/**
 * Verifies script execution of the zeroth scriptPubKey of tx output and
 * zeroth scriptSig of tx input.
 */
ScriptError VerifyWithFlag(const CTransaction& output, const CMutableTransaction& input, int flags)
{
    ScriptError error;
    CTransaction inputi(input);
    bool ret = VerifyScript(inputi.vin[0].scriptSig,
                            output.vout[0].scriptPubKey,
                            flags, TransactionSignatureChecker(&inputi, 0, output.vout[0].nValue), &error);
    BOOST_CHECK((ret == true) == (error == SCRIPT_ERR_OK));

    return error;
}

/**
 * Builds a creationTx from scriptPubKey and a spendingTx from scriptSig
 * such that spendingTx spends output zero of creationTx.
 * Also inserts creationTx's output into the coins view.
 */
void BuildTxs(CMutableTransaction& spendingTx, CCoinsViewCache& coins,
              CMutableTransaction& creationTx, const CScript& scriptPubKey,
              const CScript& scriptSig)
{
    creationTx.nVersion = 1;
    creationTx.vin.resize(1);
    creationTx.vin[0].prevout.SetNull();
    creationTx.vin[0].scriptSig = CScript();
    creationTx.vout.resize(1);
    creationTx.vout[0].nValue = 1;
    creationTx.vout[0].scriptPubKey = scriptPubKey;

    spendingTx.nVersion = 1;
    spendingTx.vin.resize(1);
    spendingTx.vin[0].prevout.hash = creationTx.GetHash();
    spendingTx.vin[0].prevout.n = 0;
    spendingTx.vin[0].scriptSig = scriptSig;
    spendingTx.vout.resize(1);
    spendingTx.vout[0].nValue = 1;
    spendingTx.vout[0].scriptPubKey = CScript();

    AddCoins(coins, CTransaction(creationTx), 0);
}

BOOST_AUTO_TEST_CASE(GetTxSigOpCost)
{
    // Transaction creates outputs
    CMutableTransaction creationTx;
    // Transaction that spends outputs and whose
    // sig op cost is going to be tested
    CMutableTransaction spendingTx;

    // Create utxo set
    CCoinsView coinsDummy;
    CCoinsViewCache coins(&coinsDummy);
    // Create key
    CKey key;
    key.MakeNewKey(true);
    CPubKey pubkey = key.GetPubKey();
    // Default flags
    int flags = SCRIPT_VERIFY_P2SH;

    // Multisig script (legacy counting)
    {
        CScript scriptPubKey = CScript() << 1 << ToByteVector(pubkey) << ToByteVector(pubkey) << 2 << OP_CHECKMULTISIGVERIFY;
        // Do not use a valid signature to avoid using wallet operations.
        CScript scriptSig = CScript() << OP_0 << OP_0;

        BuildTxs(spendingTx, coins, creationTx, scriptPubKey, scriptSig);
        // Legacy counting only includes signature operations in scriptSigs and scriptPubKeys
        // of a transaction and does not take the actual executed sig operations into account.
        // spendingTx in itself does not contain a signature operation.
        BOOST_CHECK(GetLegacySigOpCount(CTransaction(spendingTx)) == 0);
        // creationTx contains two signature operations in its scriptPubKey, but legacy counting
        // is not accurate.
        BOOST_CHECK(GetLegacySigOpCount(CTransaction(creationTx)) == MAX_PUBKEYS_PER_MULTISIG);
        // Sanity check: script verification fails because of an invalid signature.
        BOOST_CHECK(VerifyWithFlag(creationTx, spendingTx, flags) == SCRIPT_ERR_CHECKMULTISIGVERIFY);
    }

    // Multisig nested in P2SH
    {
        CScript redeemScript = CScript() << 1 << ToByteVector(pubkey) << ToByteVector(pubkey) << 2 << OP_CHECKMULTISIGVERIFY;
        CScript scriptPubKey = GetScriptForDestination(CScriptID(redeemScript));
        CScript scriptSig = CScript() << OP_0 << OP_0 << ToByteVector(redeemScript);

        BuildTxs(spendingTx, coins, creationTx, scriptPubKey, scriptSig);
        BOOST_CHECK(GetP2SHSigOpCount(CTransaction(spendingTx), coins) == 2);
        BOOST_CHECK(VerifyWithFlag(creationTx, spendingTx, flags) == SCRIPT_ERR_CHECKMULTISIGVERIFY);
    }
}

BOOST_AUTO_TEST_SUITE_END()
<|endoftext|>


<commit_before>/* conduitConfigDialog.cc                KPilot
**
** Copyright (C) 2001 by Dan Pilone
**
** This file defines a .ui-based configuration dialog for conduits.
*/

/*
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program in a file called COPYING; if not, write to
** the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
** MA 02111-1307, USA.
*/

/*
** Bug reports and questions can be sent to kde-pim@kde.org
*/

static const char *conduitconfigdialog_id =
	"$Id$";

//#include "options.h"

#include <qpushbutton.h>
#include <qbuttongroup.h>
#include <qcheckbox.h>
#include <qlineedit.h>

#include <kmessagebox.h>
#include <kglobal.h>
#include <klocale.h>
#include <kconfigskeleton.h>

#include "kpilotConfig.h"
#include "options.h"

#include "kpilotConfigWizard_base1.h"
#include "kpilotConfigWizard_base2.h"
#include "kpilotConfigWizard_base3.h"

#include "kpilotConfigWizard.moc"

ConfigWizard::ConfigWizard(QWidget *parent, const char *n) :
	KWizard(parent, n)
{
	page1=new ConfigWizard_base1(this);
	addPage( page1, i18n("Select connection type") );
	page2=new ConfigWizard_base2(this);
	addPage( page2, i18n("Pilot info") );
	page3=new ConfigWizard_base3(this);
	addPage( page3, i18n("Application to sync with") );
	setFinishEnabled( page3, true );

	connect( page2->fProbeButton, SIGNAL( pressed() ),
		this, SLOT( probeHandheld() ) );

	KPilotSettings::self()->readConfig();
	page2->fUserName->setText( KPilotSettings::userName() );
	page2->fDeviceName->setText( KPilotSettings::pilotDevice() );
	page2->fPilotRunningPermanently->setChecked( KPilotSettings::startDaemonAtLogin() );
}

ConfigWizard::~ConfigWizard()
{
}

void ConfigWizard::accept()
{
	FUNCTIONSETUP;
	QString username( page2->fUserName->text() );
	QString devicename( page2->fDeviceName->text() );
	int devicetype( page1->fConnectionType->selectedId() );
	enum eSyncApp {
		eAppKDE=0,
		eAppKontact,
		eAppEvolution
	} app;
	app=(eSyncApp)( page3->fAppType->selectedId() );
	bool keepPermanently( page2->fPilotRunningPermanently->isChecked() );
#ifdef DEBUG
	DEBUGCONDUIT<<fname<<"Keep permanently: "<<keepPermanently<<endl;
#endif

	KPilotSettings::setPilotDevice( devicename );
	KPilotSettings::setUserName(username);
	KPilotSettings::setEncoding("iso 8859-15");
	KPilotSettings::setDockDaemon( true );
	KPilotSettings::setKillDaemonAtExit( !keepPermanently);
	KPilotSettings::setQuitAfterSync( !keepPermanently );
	KPilotSettings::setStartDaemonAtLogin( keepPermanently );
	KPilotSettings::setSyncType(0);
	KPilotSettings::setFullSyncOnPCChange( true );
	KPilotSettings::setConflictResolution(0);

	QStringList conduits = KPilotSettings::installedConduits();
	// TODO: enable the right conduits
#define APPEND_CONDUIT(a) if (!conduits.contains(a)) conduits.append(a)
	APPEND_CONDUIT("internal_fileinstall");
	APPEND_CONDUIT("todo-conduit");
	APPEND_CONDUIT("vcal-conduit");
	switch (app) {
		case eAppEvolution:
			conduits.remove("knotes-conduit");
			// TODO: Once the Evolution abook resource is finished, enable it...
			conduits.remove("abbrowser_conduit");
			// TODO: settings for conduits
			break;
		case eAppKDE:
		case eAppKontact:
		default:
			APPEND_CONDUIT("knotes-conduit");
			APPEND_CONDUIT("abbrowser_conduit");
			// TODO: settings for conduits
			break;
	}
	KPilotSettings::setInstalledConduits( conduits );
#undef APPEND_CONDUIT

	KPilotSettings::self()->writeConfig();
	QDialog::accept();
}

void ConfigWizard::probeHandheld()
{
	// TODO
	KMessageBox::information(this, "Probing the handheld, not yet implemented", "Probing");
}

<commit_msg>At the end of the wizard, show a message box that kpilot is now configured to sy nc with {general KDE-PIM,Kontact,Evolution}.<commit_after>/* conduitConfigDialog.cc                KPilot
**
** Copyright (C) 2004 by Dan Pilone
** Written 2004 by Reinhold Kainhofer
**
** This file defines a .ui-based configuration dialog for conduits.
*/

/*
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program in a file called COPYING; if not, write to
** the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
** MA 02111-1307, USA.
*/

/*
** Bug reports and questions can be sent to kde-pim@kde.org
*/

static const char *conduitconfigdialog_id =
	"$Id$";

//#include "options.h"

#include <qpushbutton.h>
#include <qbuttongroup.h>
#include <qcheckbox.h>
#include <qlineedit.h>

#include <kmessagebox.h>
#include <kglobal.h>
#include <klocale.h>
#include <kconfigskeleton.h>

#include "kpilotConfig.h"
#include "options.h"

#include "kpilotConfigWizard_base1.h"
#include "kpilotConfigWizard_base2.h"
#include "kpilotConfigWizard_base3.h"

#include "kpilotConfigWizard.moc"

ConfigWizard::ConfigWizard(QWidget *parent, const char *n) :
	KWizard(parent, n)
{
	page1=new ConfigWizard_base1(this);
	addPage( page1, i18n("Select connection type") );
	page2=new ConfigWizard_base2(this);
	addPage( page2, i18n("Pilot info") );
	page3=new ConfigWizard_base3(this);
	addPage( page3, i18n("Application to sync with") );
	setFinishEnabled( page3, true );

	connect( page2->fProbeButton, SIGNAL( pressed() ),
		this, SLOT( probeHandheld() ) );

	KPilotSettings::self()->readConfig();
	page2->fUserName->setText( KPilotSettings::userName() );
	page2->fDeviceName->setText( KPilotSettings::pilotDevice() );
	page2->fPilotRunningPermanently->setChecked( KPilotSettings::startDaemonAtLogin() );
}

ConfigWizard::~ConfigWizard()
{
}

void ConfigWizard::accept()
{
	FUNCTIONSETUP;
	QString username( page2->fUserName->text() );
	QString devicename( page2->fDeviceName->text() );
//	int devicetype( page1->fConnectionType->selectedId() );
	enum eSyncApp {
		eAppKDE=0,
		eAppKontact,
		eAppEvolution
	} app;
	app=(eSyncApp)( page3->fAppType->selectedId() );
	bool keepPermanently( page2->fPilotRunningPermanently->isChecked() );
#ifdef DEBUG
	DEBUGCONDUIT<<fname<<"Keep permanently: "<<keepPermanently<<endl;
#endif

	KPilotSettings::setPilotDevice( devicename );
	KPilotSettings::setUserName(username);
	KPilotSettings::setEncoding("iso 8859-15");
	KPilotSettings::setDockDaemon( true );
	KPilotSettings::setKillDaemonAtExit( !keepPermanently);
	KPilotSettings::setQuitAfterSync( !keepPermanently );
	KPilotSettings::setStartDaemonAtLogin( keepPermanently );
	KPilotSettings::setSyncType(0);
	KPilotSettings::setFullSyncOnPCChange( true );
	KPilotSettings::setConflictResolution(0);

	QStringList conduits = KPilotSettings::installedConduits();
	// TODO: enable the right conduits
#define APPEND_CONDUIT(a) if (!conduits.contains(a)) conduits.append(a)
	QString applicationName(i18n("general KDE-PIM"));
	APPEND_CONDUIT("internal_fileinstall");
	APPEND_CONDUIT("todo-conduit");
	APPEND_CONDUIT("vcal-conduit");
	switch (app) {
		case eAppEvolution:
			applicationName=i18n("Gnome's PIM suite", "Evolution");
			conduits.remove("knotes-conduit");
			// TODO: Once the Evolution abook resource is finished, enable it...
			conduits.remove("abbrowser_conduit");
			// TODO: settings for conduits
			break;
		case eAppKontact:
			applicationName=i18n("KDE's PIM suite", "Kontact");
		case eAppKDE:
		default:
			APPEND_CONDUIT("knotes-conduit");
			APPEND_CONDUIT("abbrowser_conduit");
			// TODO: settings for conduits
			break;
	}
	KPilotSettings::setInstalledConduits( conduits );
#undef APPEND_CONDUIT

	KMessageBox::information(this, i18n("KPilot is now configured to sync with %1.\n"
		"The remaining options in the config dialog are advanced options and can "
		"be used to fine-tune KPilot.").arg(applicationName), i18n("Automatic configuration finished"));
	KPilotSettings::self()->writeConfig();
	QDialog::accept();
}

// Devices to probe:
//

void ConfigWizard::probeHandheld()
{
	// TODO
	KMessageBox::information(this, "Probing the handheld, not yet implemented", "Probing");
}

<|endoftext|>


<commit_before>/*
 * \copyright Copyright 2014 Xiang Zhang All Rights Reserved.
 * \license @{
 *
 * 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.
 *
 * @}
 */

#ifndef THUNDER_SERIALIZER_SERIALIZER_HPP_
#define THUNDER_SERIALIZER_SERIALIZER_HPP_

#include <memory>
#include <sstream>

#include "thunder/serializer/text.hpp"

namespace thunder {
namespace serializer {

template < typename M = ::std::stringstream, typename P = Text< M > >
class Serializer {
 public:
  typedef M stream_type;
  typedef typename M::char_type char_type;
  typedef ::std::shared_ptr(M) stream_pointer;

  template < typename... G >
  Serializer(G... g);

  ~Serializer();

  stream_pointer stream();

  template < typename T >
  void save(const T &t);
  template < typename T >
  void load (T *t);

 private:
  stream_pointer *stream_;
  ::std::unordered_set< void* > saved_pointers_;
  ::std::unordered_map< void*, void* > loaded_pointers_;
  ::std::unordered_map< void*, void* > loaded_shared_;

  // Const variables to identify types data
  static const char_type kPrimitive = 0;
  static const char_type kClass = 1;
  static const char_type kPointer = 2;
  static const char_type kShared = 3;
};

}  // namespace serializer
}  // namespace thunder

#endif  // THUNDER_SERIALIZER_SERIALIZER_HPP_
<commit_msg>Removed constants<commit_after>/*
 * \copyright Copyright 2014 Xiang Zhang All Rights Reserved.
 * \license @{
 *
 * 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.
 *
 * @}
 */

#ifndef THUNDER_SERIALIZER_SERIALIZER_HPP_
#define THUNDER_SERIALIZER_SERIALIZER_HPP_

#include <memory>
#include <sstream>

#include "thunder/serializer/text.hpp"

namespace thunder {
namespace serializer {

template < typename M = ::std::stringstream, typename P = Text< M > >
class Serializer {
 public:
  typedef M stream_type;
  typedef typename M::char_type char_type;
  typedef ::std::shared_ptr(M) stream_pointer;

  template < typename... G >
  Serializer(G... g);

  ~Serializer();

  stream_pointer stream();

  template < typename T >
  void save(const T &t);
  template < typename T >
  void load (T *t);

 private:
  stream_pointer *stream_;
  ::std::unordered_set< void* > saved_pointers_;
  ::std::unordered_map< void*, void* > loaded_pointers_;
  ::std::unordered_map< void*, void* > loaded_shared_;
};

}  // namespace serializer
}  // namespace thunder

#endif  // THUNDER_SERIALIZER_SERIALIZER_HPP_
<|endoftext|>