<commit_before>////////////////////////////////////////////////////////////////////////////////
/// @brief connection endpoint, ip-based
///
/// @file
///
/// DISCLAIMER
///
/// Copyright 2014 ArangoDB GmbH, Cologne, Germany
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
///
/// 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.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Dr. Oreste Costa-Panaia
/// @author Jan Steemann
/// @author Copyright 2014, ArangoDB GmbH, Cologne, Germany
/// @author Copyright 2012-2013, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////

#include "EndpointIp.h"

#include "Basics/FileUtils.h"
#include "Basics/StringUtils.h"
#include "Basics/logging.h"

#include "Rest/Endpoint.h"

using namespace triagens::basics;
using namespace triagens::rest;

// -----------------------------------------------------------------------------
// --SECTION--                                                        EndpointIp
// -----------------------------------------------------------------------------

// -----------------------------------------------------------------------------
// --SECTION--                                               static initialisers
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @brief set port if none specified
////////////////////////////////////////////////////////////////////////////////

const uint16_t EndpointIp::_defaultPort = 8529;

////////////////////////////////////////////////////////////////////////////////
/// @brief default host if none specified
////////////////////////////////////////////////////////////////////////////////

const std::string EndpointIp::_defaultHost = "127.0.0.1";

// -----------------------------------------------------------------------------
// --SECTION--                                        constructors / destructors
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @brief creates an IP socket endpoint
////////////////////////////////////////////////////////////////////////////////

EndpointIp::EndpointIp (const Endpoint::EndpointType type,
                        const Endpoint::DomainType domainType,
                        const Endpoint::EncryptionType encryption,
                        const std::string& specification,
                        int listenBacklog,
                        bool reuseAddress,
                        const std::string& host,
                        const uint16_t port)
  : Endpoint(type, domainType, encryption, specification, listenBacklog),
    _reuseAddress(reuseAddress),
    _host(host),
    _port(port) {

  TRI_ASSERT(domainType == DOMAIN_IPV4 || domainType == Endpoint::DOMAIN_IPV6);
}

////////////////////////////////////////////////////////////////////////////////
/// @brief destroys an IP socket endpoint
////////////////////////////////////////////////////////////////////////////////

EndpointIp::~EndpointIp () {
  if (_connected) {
    disconnect();
  }
}

// -----------------------------------------------------------------------------
// --SECTION--                                                   private methods
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @brief connects a socket
////////////////////////////////////////////////////////////////////////////////

TRI_socket_t EndpointIp::connectSocket (const struct addrinfo* aip,
                                        double connectTimeout,
                                        double requestTimeout) {
  // set address and port
  char host[NI_MAXHOST];
  char serv[NI_MAXSERV];

  if (::getnameinfo(aip->ai_addr, (socklen_t) aip->ai_addrlen,
                    host, sizeof(host),
                    serv, sizeof(serv), NI_NUMERICHOST | NI_NUMERICSERV) == 0) {

    LOG_TRACE("bind to address '%s', port %d", host, (int) _port);
  }

  TRI_socket_t listenSocket;
  listenSocket = TRI_socket(aip->ai_family, aip->ai_socktype, aip->ai_protocol);

  if (! TRI_isvalidsocket(listenSocket)) {
    LOG_ERROR("socket() failed with %d (%s)", errno, strerror(errno));
    return listenSocket;
  }

  if (_type == ENDPOINT_SERVER) {

#ifdef _WIN32
    int excl = 1;
    if (TRI_setsockopt(listenSocket, SOL_SOCKET, SO_EXCLUSIVEADDRUSE,
          reinterpret_cast<char*> (&excl), sizeof (excl)) == -1) {
      LOG_ERROR("setsockopt() failed with %d", WSAGetLastError());

      TRI_CLOSE_SOCKET(listenSocket);
      TRI_invalidatesocket(&listenSocket);
      return listenSocket;
    }
#else
    // try to reuse address
    if (_reuseAddress) {
      int opt = 1;
      if (TRI_setsockopt(listenSocket, SOL_SOCKET, SO_REUSEADDR, reinterpret_cast<char*> (&opt), sizeof (opt)) == -1) {
        LOG_ERROR("setsockopt() failed with %d (%s)", errno, strerror(errno));

        TRI_CLOSE_SOCKET(listenSocket);
        TRI_invalidatesocket(&listenSocket);
        return listenSocket;
      }
    }
#endif

    // server needs to bind to socket
    int result = TRI_bind(listenSocket, aip->ai_addr, (int) aip->ai_addrlen);

    if (result != 0) {
      // error
#ifndef _WIN32
      LOG_ERROR("bind() failed with %d (%s)", errno, strerror(errno));
#else
      LOG_ERROR("bind() failed with %d", WSAGetLastError());
#endif
      TRI_CLOSE_SOCKET(listenSocket);

      TRI_invalidatesocket(&listenSocket);
      return listenSocket;
    }

    // listen for new connection, executed for server endpoints only
    LOG_TRACE("using backlog size %d", (int) _listenBacklog);
    result = TRI_listen(listenSocket, _listenBacklog);

    if (result != 0) {
      // todo: get the correct error code using WSAGetLastError for windows
      LOG_ERROR("listen() failed with %d (%s)", errno, strerror(errno));

      TRI_CLOSE_SOCKET(listenSocket);
      TRI_invalidatesocket(&listenSocket);
      return listenSocket;
    }
  }
  else if (_type == ENDPOINT_CLIENT) {
    // connect to endpoint, executed for client endpoints only

    // set timeout
    setTimeout(listenSocket, connectTimeout);

    int result = TRI_connect(listenSocket, (const struct sockaddr*) aip->ai_addr, (int) aip->ai_addrlen);

    if (result != 0) {
      TRI_CLOSE_SOCKET(listenSocket);
      TRI_invalidatesocket(&listenSocket);
      return listenSocket;
    }
  }

  if (! setSocketFlags(listenSocket)) { // set some common socket flags for client and server
    TRI_CLOSE_SOCKET(listenSocket);
    TRI_invalidatesocket(&listenSocket);
    return listenSocket;
  }

  if (_type == ENDPOINT_CLIENT) {
    setTimeout(listenSocket, requestTimeout);
  }

  _connected = true;
  _socket = listenSocket;

  return _socket;
}

// -----------------------------------------------------------------------------
// --SECTION--                                                    public methods
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @brief connect the endpoint
////////////////////////////////////////////////////////////////////////////////

#ifdef _WIN32

TRI_socket_t EndpointIp::connect (double connectTimeout,
                                  double requestTimeout) {
  struct addrinfo* result = 0;
  struct addrinfo* aip;
  struct addrinfo hints;
  int error;
  TRI_socket_t listenSocket;
  TRI_invalidatesocket(&listenSocket);

  LOG_DEBUG("connecting to ip endpoint '%s'", _specification.c_str());

  TRI_ASSERT(!TRI_isvalidsocket(_socket));
  TRI_ASSERT(!_connected);

  memset(&hints, 0, sizeof (struct addrinfo));
  hints.ai_family = getDomain(); // Allow IPv4 or IPv6
  hints.ai_flags = TRI_CONNECT_AI_FLAGS;
  hints.ai_socktype = SOCK_STREAM;

  std::string portString = StringUtils::itoa(_port);

  error = getaddrinfo(_host.c_str(), portString.c_str(), &hints, &result);

  if (error != 0) {
    int lastError = WSAGetLastError();

    if (error == WSANOTINITIALISED) {
      // can not call WSAGetLastError - since the socket layer hasn't been initialised yet!
      lastError = error;
    }
    else {
      lastError = WSAGetLastError();
    }

    switch (lastError) {
      case WSANOTINITIALISED: {
        LOG_ERROR("getaddrinfo for host '%s': WSAStartup was not called or not called successfully.", _host.c_str());
        break;
      }
      default: {
        LOG_ERROR("getaddrinfo for host '%s': %s", _host.c_str(), gai_strerror(error));
        break;
      }
    }

    if (result != 0) {
      freeaddrinfo(result);
    }

    return listenSocket;
  }

  // Try all returned addresses until one works
  for (aip = result; aip != NULL; aip = aip->ai_next) {
    // try to bind the address info pointer
    listenSocket = connectSocket(aip, connectTimeout, requestTimeout);
    if (TRI_isvalidsocket(listenSocket)) {
      // OK
      break;
    }
  }

  freeaddrinfo(result);

  return listenSocket;
}

#else

TRI_socket_t EndpointIp::connect (double connectTimeout, double requestTimeout) {
  struct addrinfo* result = 0;
  struct addrinfo* aip;
  struct addrinfo hints;
  int error;
  TRI_socket_t listenSocket;
  TRI_invalidatesocket(&listenSocket);

  LOG_DEBUG("connecting to ip endpoint '%s'", _specification.c_str());

  TRI_ASSERT(!TRI_isvalidsocket(_socket));
  TRI_ASSERT(!_connected);

  memset(&hints, 0, sizeof (struct addrinfo));
  hints.ai_family = getDomain(); // Allow IPv4 or IPv6
  hints.ai_flags = TRI_CONNECT_AI_FLAGS;
  hints.ai_socktype = SOCK_STREAM;

  std::string portString = StringUtils::itoa(_port);

  error = getaddrinfo(_host.c_str(), portString.c_str(), &hints, &result);

  if (error != 0) {
    LOG_ERROR("getaddrinfo for host '%s': %s", _host.c_str(), gai_strerror(error));

    if (result != 0) {
      freeaddrinfo(result);
    }
    return listenSocket;
  }

  // Try all returned addresses until one works
  for (aip = result; aip != NULL; aip = aip->ai_next) {
    // try to bind the address info pointer
    listenSocket = connectSocket(aip, connectTimeout, requestTimeout);
    if (TRI_isvalidsocket(listenSocket)) {
      // OK
      break;
    }
  }

  freeaddrinfo(result);

  return listenSocket;
}

#endif

////////////////////////////////////////////////////////////////////////////////
/// @brief destroys an IPv4 socket endpoint
////////////////////////////////////////////////////////////////////////////////

void EndpointIp::disconnect () {
  if (_connected) {
    TRI_ASSERT(TRI_isvalidsocket(_socket));

    _connected = false;
    TRI_CLOSE_SOCKET(_socket);
    TRI_invalidatesocket(&_socket);
  }
}

////////////////////////////////////////////////////////////////////////////////
/// @brief init an incoming connection
////////////////////////////////////////////////////////////////////////////////

bool EndpointIp::initIncoming (TRI_socket_t incoming) {
  // disable nagle's algorithm
  int n = 1;
  int res = TRI_setsockopt(incoming, IPPROTO_TCP, TCP_NODELAY, (char*) &n, sizeof(n));

  if (res != 0 ) {
    // todo: get correct windows error code
    LOG_WARNING("setsockopt failed with %d (%s)", errno, strerror(errno));

    return false;
  }

  return setSocketFlags(incoming);
}

// -----------------------------------------------------------------------------
// --SECTION--                                                       END-OF-FILE
// -----------------------------------------------------------------------------

// Local Variables:
// mode: outline-minor
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @page\\|// --SECTION--\\|/// @\\}"
// End:
<commit_msg>Output which ip/port we fail to bind.<commit_after>////////////////////////////////////////////////////////////////////////////////
/// @brief connection endpoint, ip-based
///
/// @file
///
/// DISCLAIMER
///
/// Copyright 2014 ArangoDB GmbH, Cologne, Germany
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
///
/// 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.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Dr. Oreste Costa-Panaia
/// @author Jan Steemann
/// @author Copyright 2014, ArangoDB GmbH, Cologne, Germany
/// @author Copyright 2012-2013, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////

#include "EndpointIp.h"

#include "Basics/FileUtils.h"
#include "Basics/StringUtils.h"
#include "Basics/logging.h"

#include "Rest/Endpoint.h"

using namespace triagens::basics;
using namespace triagens::rest;

// -----------------------------------------------------------------------------
// --SECTION--                                                        EndpointIp
// -----------------------------------------------------------------------------

// -----------------------------------------------------------------------------
// --SECTION--                                               static initialisers
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @brief set port if none specified
////////////////////////////////////////////////////////////////////////////////

const uint16_t EndpointIp::_defaultPort = 8529;

////////////////////////////////////////////////////////////////////////////////
/// @brief default host if none specified
////////////////////////////////////////////////////////////////////////////////

const std::string EndpointIp::_defaultHost = "127.0.0.1";

// -----------------------------------------------------------------------------
// --SECTION--                                        constructors / destructors
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @brief creates an IP socket endpoint
////////////////////////////////////////////////////////////////////////////////

EndpointIp::EndpointIp (const Endpoint::EndpointType type,
                        const Endpoint::DomainType domainType,
                        const Endpoint::EncryptionType encryption,
                        const std::string& specification,
                        int listenBacklog,
                        bool reuseAddress,
                        const std::string& host,
                        const uint16_t port)
  : Endpoint(type, domainType, encryption, specification, listenBacklog),
    _reuseAddress(reuseAddress),
    _host(host),
    _port(port) {

  TRI_ASSERT(domainType == DOMAIN_IPV4 || domainType == Endpoint::DOMAIN_IPV6);
}

////////////////////////////////////////////////////////////////////////////////
/// @brief destroys an IP socket endpoint
////////////////////////////////////////////////////////////////////////////////

EndpointIp::~EndpointIp () {
  if (_connected) {
    disconnect();
  }
}

// -----------------------------------------------------------------------------
// --SECTION--                                                   private methods
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @brief connects a socket
////////////////////////////////////////////////////////////////////////////////

TRI_socket_t EndpointIp::connectSocket (const struct addrinfo* aip,
                                        double connectTimeout,
                                        double requestTimeout) {
  // set address and port
  char host[NI_MAXHOST];
  char serv[NI_MAXSERV];

  if (::getnameinfo(aip->ai_addr, (socklen_t) aip->ai_addrlen,
                    host, sizeof(host),
                    serv, sizeof(serv), NI_NUMERICHOST | NI_NUMERICSERV) == 0) {

    LOG_TRACE("bind to address '%s', port %d", host, (int) _port);
  }

  TRI_socket_t listenSocket;
  listenSocket = TRI_socket(aip->ai_family, aip->ai_socktype, aip->ai_protocol);

  if (! TRI_isvalidsocket(listenSocket)) {
    LOG_ERROR("socket() failed with %d (%s)", errno, strerror(errno));
    return listenSocket;
  }

  if (_type == ENDPOINT_SERVER) {

#ifdef _WIN32
    int excl = 1;
    if (TRI_setsockopt(listenSocket, SOL_SOCKET, SO_EXCLUSIVEADDRUSE,
          reinterpret_cast<char*> (&excl), sizeof (excl)) == -1) {
      LOG_ERROR("setsockopt() failed with %d", WSAGetLastError());

      TRI_CLOSE_SOCKET(listenSocket);
      TRI_invalidatesocket(&listenSocket);
      return listenSocket;
    }
#else
    // try to reuse address
    if (_reuseAddress) {
      int opt = 1;
      if (TRI_setsockopt(listenSocket, SOL_SOCKET, SO_REUSEADDR, reinterpret_cast<char*> (&opt), sizeof (opt)) == -1) {
        LOG_ERROR("setsockopt() failed with %d (%s)", errno, strerror(errno));

        TRI_CLOSE_SOCKET(listenSocket);
        TRI_invalidatesocket(&listenSocket);
        return listenSocket;
      }
    }
#endif

    // server needs to bind to socket
    int result = TRI_bind(listenSocket, aip->ai_addr, (int) aip->ai_addrlen);

    if (result != 0) {
      // error
#ifndef _WIN32
      LOG_ERROR("bind(address '%s', port %d) failed with %d (%s)", host, (int) _port, errno, strerror(errno));
#else
      LOG_ERROR("bind(address '%s', port %d) failed with %d", host, (int) _port, WSAGetLastError());
#endif
      TRI_CLOSE_SOCKET(listenSocket);

      TRI_invalidatesocket(&listenSocket);
      return listenSocket;
    }

    // listen for new connection, executed for server endpoints only
    LOG_TRACE("using backlog size %d", (int) _listenBacklog);
    result = TRI_listen(listenSocket, _listenBacklog);

    if (result != 0) {
      // todo: get the correct error code using WSAGetLastError for windows
      LOG_ERROR("listen() failed with %d (%s)", errno, strerror(errno));

      TRI_CLOSE_SOCKET(listenSocket);
      TRI_invalidatesocket(&listenSocket);
      return listenSocket;
    }
  }
  else if (_type == ENDPOINT_CLIENT) {
    // connect to endpoint, executed for client endpoints only

    // set timeout
    setTimeout(listenSocket, connectTimeout);

    int result = TRI_connect(listenSocket, (const struct sockaddr*) aip->ai_addr, (int) aip->ai_addrlen);

    if (result != 0) {
      TRI_CLOSE_SOCKET(listenSocket);
      TRI_invalidatesocket(&listenSocket);
      return listenSocket;
    }
  }

  if (! setSocketFlags(listenSocket)) { // set some common socket flags for client and server
    TRI_CLOSE_SOCKET(listenSocket);
    TRI_invalidatesocket(&listenSocket);
    return listenSocket;
  }

  if (_type == ENDPOINT_CLIENT) {
    setTimeout(listenSocket, requestTimeout);
  }

  _connected = true;
  _socket = listenSocket;

  return _socket;
}

// -----------------------------------------------------------------------------
// --SECTION--                                                    public methods
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @brief connect the endpoint
////////////////////////////////////////////////////////////////////////////////

#ifdef _WIN32

TRI_socket_t EndpointIp::connect (double connectTimeout,
                                  double requestTimeout) {
  struct addrinfo* result = 0;
  struct addrinfo* aip;
  struct addrinfo hints;
  int error;
  TRI_socket_t listenSocket;
  TRI_invalidatesocket(&listenSocket);

  LOG_DEBUG("connecting to ip endpoint '%s'", _specification.c_str());

  TRI_ASSERT(!TRI_isvalidsocket(_socket));
  TRI_ASSERT(!_connected);

  memset(&hints, 0, sizeof (struct addrinfo));
  hints.ai_family = getDomain(); // Allow IPv4 or IPv6
  hints.ai_flags = TRI_CONNECT_AI_FLAGS;
  hints.ai_socktype = SOCK_STREAM;

  std::string portString = StringUtils::itoa(_port);

  error = getaddrinfo(_host.c_str(), portString.c_str(), &hints, &result);

  if (error != 0) {
    int lastError = WSAGetLastError();

    if (error == WSANOTINITIALISED) {
      // can not call WSAGetLastError - since the socket layer hasn't been initialised yet!
      lastError = error;
    }
    else {
      lastError = WSAGetLastError();
    }

    switch (lastError) {
      case WSANOTINITIALISED: {
        LOG_ERROR("getaddrinfo for host '%s': WSAStartup was not called or not called successfully.", _host.c_str());
        break;
      }
      default: {
        LOG_ERROR("getaddrinfo for host '%s': %s", _host.c_str(), gai_strerror(error));
        break;
      }
    }

    if (result != 0) {
      freeaddrinfo(result);
    }

    return listenSocket;
  }

  // Try all returned addresses until one works
  for (aip = result; aip != NULL; aip = aip->ai_next) {
    // try to bind the address info pointer
    listenSocket = connectSocket(aip, connectTimeout, requestTimeout);
    if (TRI_isvalidsocket(listenSocket)) {
      // OK
      break;
    }
  }

  freeaddrinfo(result);

  return listenSocket;
}

#else

TRI_socket_t EndpointIp::connect (double connectTimeout, double requestTimeout) {
  struct addrinfo* result = 0;
  struct addrinfo* aip;
  struct addrinfo hints;
  int error;
  TRI_socket_t listenSocket;
  TRI_invalidatesocket(&listenSocket);

  LOG_DEBUG("connecting to ip endpoint '%s'", _specification.c_str());

  TRI_ASSERT(!TRI_isvalidsocket(_socket));
  TRI_ASSERT(!_connected);

  memset(&hints, 0, sizeof (struct addrinfo));
  hints.ai_family = getDomain(); // Allow IPv4 or IPv6
  hints.ai_flags = TRI_CONNECT_AI_FLAGS;
  hints.ai_socktype = SOCK_STREAM;

  std::string portString = StringUtils::itoa(_port);

  error = getaddrinfo(_host.c_str(), portString.c_str(), &hints, &result);

  if (error != 0) {
    LOG_ERROR("getaddrinfo for host '%s': %s", _host.c_str(), gai_strerror(error));

    if (result != 0) {
      freeaddrinfo(result);
    }
    return listenSocket;
  }

  // Try all returned addresses until one works
  for (aip = result; aip != NULL; aip = aip->ai_next) {
    // try to bind the address info pointer
    listenSocket = connectSocket(aip, connectTimeout, requestTimeout);
    if (TRI_isvalidsocket(listenSocket)) {
      // OK
      break;
    }
  }

  freeaddrinfo(result);

  return listenSocket;
}

#endif

////////////////////////////////////////////////////////////////////////////////
/// @brief destroys an IPv4 socket endpoint
////////////////////////////////////////////////////////////////////////////////

void EndpointIp::disconnect () {
  if (_connected) {
    TRI_ASSERT(TRI_isvalidsocket(_socket));

    _connected = false;
    TRI_CLOSE_SOCKET(_socket);
    TRI_invalidatesocket(&_socket);
  }
}

////////////////////////////////////////////////////////////////////////////////
/// @brief init an incoming connection
////////////////////////////////////////////////////////////////////////////////

bool EndpointIp::initIncoming (TRI_socket_t incoming) {
  // disable nagle's algorithm
  int n = 1;
  int res = TRI_setsockopt(incoming, IPPROTO_TCP, TCP_NODELAY, (char*) &n, sizeof(n));

  if (res != 0 ) {
    // todo: get correct windows error code
    LOG_WARNING("setsockopt failed with %d (%s)", errno, strerror(errno));

    return false;
  }

  return setSocketFlags(incoming);
}

// -----------------------------------------------------------------------------
// --SECTION--                                                       END-OF-FILE
// -----------------------------------------------------------------------------

// Local Variables:
// mode: outline-minor
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @page\\|// --SECTION--\\|/// @\\}"
// End:
<|endoftext|>


<commit_before>/**
 ** \file object/float-class.cc
 ** \brief Creation of the URBI object float.
 */

#include <boost/format.hpp>

#include <libport/cmath>

#include <kernel/config.h>
#ifndef HAVE_ROUND
# include <libport/ufloat.h>
#endif
#include <libport/ufloat.hh>

#include <object/float.hh>
#include <object/list.hh>
#include <object/object.hh>
#include <object/string.hh>
#include <object/urbi-exception.hh>

namespace object
{
  Float::Float()
    : value_(0)
  {
    proto_add(proto);
  }

  Float::Float(value_type value)
    : value_(value)
  {
    proto_add(proto);
  }

  Float::Float(const rFloat& model)
    : value_(model->value_get())
  {
    proto_add(model);
    proto_remove(proto);
  }

  const Float::value_type&
  Float::value_get() const
  {
    return value_;
  }

  Float::value_type&
  Float::value_get()
  {
    return value_;
  }

  int
  Float::to_int(const libport::Symbol func) const
  {
    try
    {
      return libport::ufloat_to_int(value_);
    }
    catch (libport::bad_numeric_cast& ue)
    {
      throw BadInteger(value_, func);
      return 0;  // Keep the compiler happy
    }
  }

  unsigned int
  Float::to_unsigned_int(const libport::Symbol func,
			 const std::string fmt) const
  {
    try
    {
      int res = libport::ufloat_to_int(value_);
      if (res < 0)
	throw libport::bad_numeric_cast();
      return res;
    }
    catch (libport::bad_numeric_cast& ue)
    {
      throw BadInteger(value_, func, fmt);
      return 0;  // Keep the compiler happy
    }
  }

  Float::value_type
  Float::inf()
  {
    return std::numeric_limits<libport::ufloat>::infinity();
  }

  Float::value_type
  Float::nan()
  {
    return std::numeric_limits<libport::ufloat>::quiet_NaN();
  }

  std::string
  Float::as_string(const rObject& from)
  {
    if (from == proto)
      return SYMBOL(LT_Float_GT);
    {
      type_check(from, proto, 1);
      float fl = from->as<Float>()->value_get();
      // Do not rely on boost::format to print inf and nan since
      // behavior differs under Win32
      if (std::isinf(fl))
        return fl > 0 ? SYMBOL(inf) : SYMBOL(MINUS_inf);
      if (std::isnan(fl))
        return SYMBOL(nan);
      static boost::format f("%g");
      return str(f % fl);
    }
  }

#define BOUNCE_OP(Op, ResType, Check)					\
  ResType								\
  Float::operator Op(value_type rhs)					\
  {                                                                     \
    static libport::Symbol op(#Op);                                     \
    WHEN(Check,                                                         \
         if (!rhs)							\
           throw PrimitiveError(op, "division by 0"));                  \
    return value_get() Op rhs;						\
  }

  BOUNCE_OP(*, Float::value_type, false)
  BOUNCE_OP(/, Float::value_type, true)
  BOUNCE_OP(<, bool, false)

#undef BOUNCE_OP

  Float::value_type
  Float::operator %(value_type rhs)
  {
    if (!rhs)
      throw PrimitiveError(SYMBOL(PERCENT), "modulo by 0");
    return fmod(value_get(), rhs);
  }

  Float::value_type
  Float::pow(value_type rhs)
  {
    return powf(value_get(), rhs);
  }

  /*------------------.
  | Unary operators.  |
  `------------------*/
#define BOUNCE_INT_OP(Op)			\
  int						\
  Float::operator Op()				\
  {						\
    static libport::Symbol op(#Op);		\
    return Op to_int(op);			\
  }
BOUNCE_INT_OP(~)
#undef BOUNCE_INT_OP

  /*-------------------.
  | Binary operators.  |
  `-------------------*/
#define BOUNCE_INT_OP(Op)			\
  int						\
  Float::operator Op(int rhs)			\
  {						\
    static libport::Symbol op(#Op);		\
    return to_int(op) Op rhs;			\
}

  BOUNCE_INT_OP(^)
  BOUNCE_INT_OP(|)
  BOUNCE_INT_OP(&)
#undef BOUNCE_INT_OP

#define BOUNCE_UNSIGNED_INT_OP(Op)		\
  int						\
  Float::operator Op(unsigned int rhs)		\
  {						\
    static libport::Symbol op(#Op);		\
    return to_int(op) Op rhs;			\
}

  BOUNCE_UNSIGNED_INT_OP(<<)
  BOUNCE_UNSIGNED_INT_OP(>>)
#undef BOUNCE_UNSIGNED_INT_OP

#define CHECK_POSITIVE(F)                                       \
  if (value_ < 0)                                               \
    throw PrimitiveError(F, "argument has to be positive");

#define CHECK_TRIGO_RANGE(F)                                    \
  if (value_ < -1 || value_ > 1)                                \
    throw PrimitiveError(F, "invalid range");

#define BOUNCE(F, Pos, Range)                           \
  Float::value_type					\
  Float::F()                                            \
  {                                                     \
    WHEN(Pos, CHECK_POSITIVE(SYMBOL(F)));               \
    WHEN(Range, CHECK_TRIGO_RANGE(SYMBOL(F)));          \
    return ::F(value_get());				\
  }

  BOUNCE(acos,  false, true);
  BOUNCE(asin,  false, true);
  BOUNCE(atan,  false, false);
  BOUNCE(cos,   false, false);
  BOUNCE(exp,   false, false);
  BOUNCE(fabs,  false, false);
  BOUNCE(log,   true,  false);
  BOUNCE(round, false, false);
  BOUNCE(sin,   false, false);
  BOUNCE(sqrt,  true,  false);
  BOUNCE(tan,   false, false);
  BOUNCE(trunc, false, false);

#undef CHECK_POSITIVE
#undef CHECK_TRIGO_RANGE
#undef BOUNCE

  int
  Float::random()
  {
    static const std::string fmt = "expected positive integer, got %1%";
    unsigned int upper_bound = to_unsigned_int(SYMBOL(random), fmt);
    if (!upper_bound)
      throw BadInteger(value_get(), SYMBOL(random), fmt);
    return rand() % upper_bound;
  }

  rFloat
  Float::plus(objects_type& args)
  {
    check_arg_count(args.size(), 0, 1);
    if (args.empty())
      return this;
    else
    {
      type_check(args[0], proto, 1);
      return new Float(value_get() + args[0]->as<Float>()->value_get());
    }
  }

  rFloat
  Float::minus(objects_type& args)
  {
    check_arg_count(args.size(), 0, 1);
    if (args.empty())
      return new Float(-value_get());
    else
    {
      type_check(args[0], proto, 1);
      return new Float(value_get() - args[0]->as<Float>()->value_get());
    }
  }

  rList
  Float::seq()
  {
    unsigned int n = to_unsigned_int(SYMBOL(seq));
    List::value_type res;
    for (unsigned int i = 0; i < n; i++)
      res.push_back(new Float(i));
    return new List(res);
  }

  rFloat
  Float::set(value_type rhs)
  {
    value_ = rhs;
    return this;
  }

  /*--------.
  | Details |
  `--------*/

  std::ostream& Float::special_slots_dump(std::ostream& o,
                                          runner::Runner&) const
  {
    o << "value = " << value_ << libport::iendl;
    return o;
  }

  /*---------------.
  | Binding system |
  `---------------*/

  void
  Float::initialize(CxxObject::Binder<Float>& bind)
  {
    bind(SYMBOL(CARET), &Float::operator^);
    bind(SYMBOL(GT_GT), &Float::operator>>);
    bind(SYMBOL(LT), static_cast<bool (Float::*)(value_type)>(&Float::operator<));
    bind(SYMBOL(LT_LT), &Float::operator<<);
    bind(SYMBOL(MINUS), &Float::minus);
    bind(SYMBOL(PERCENT), &Float::operator%);
    bind(SYMBOL(PLUS), &Float::plus);
    bind(SYMBOL(SLASH), &Float::operator/);
    bind(SYMBOL(STAR), &Float::operator*);
    bind(SYMBOL(STAR_STAR), &Float::pow);
    bind(SYMBOL(abs), &Float::fabs);
    bind(SYMBOL(acos), &Float::acos);
    bind(SYMBOL(asString), &Float::as_string);
    bind(SYMBOL(asin), &Float::asin);
    bind(SYMBOL(atan), &Float::atan);
    bind(SYMBOL(bitand), &Float::operator&);
    bind(SYMBOL(bitor), &Float::operator|);
    bind(SYMBOL(compl), &Float::operator~);
    bind(SYMBOL(cos), &Float::cos);
    bind(SYMBOL(exp), &Float::exp);
    bind(SYMBOL(inf), &Float::inf);
    bind(SYMBOL(log), &Float::log);
    bind(SYMBOL(nan), &Float::nan);
    bind(SYMBOL(random), &Float::random);
    bind(SYMBOL(round), &Float::round);
    bind(SYMBOL(seq), &Float::seq);
    bind(SYMBOL(set), &Float::set);
    bind(SYMBOL(sin), &Float::sin);
    bind(SYMBOL(sqrt), &Float::sqrt);
    bind(SYMBOL(tan), &Float::tan);
    bind(SYMBOL(trunc), &Float::trunc);
  }

  bool Float::float_added = CxxObject::add<Float>("Float", Float::proto);
  const std::string Float::type_name = "Float";
  rObject Float::proto;
  std::string
  Float::type_name_get() const
  {
    return type_name;
  }

}; // namespace object
<commit_msg>Print integers in non-scientific notation.<commit_after>/**
 ** \file object/float-class.cc
 ** \brief Creation of the URBI object float.
 */

#include <boost/format.hpp>

#include <libport/cmath>

#include <kernel/config.h>
#ifndef HAVE_ROUND
# include <libport/ufloat.h>
#endif
#include <libport/ufloat.hh>

#include <object/float.hh>
#include <object/list.hh>
#include <object/object.hh>
#include <object/string.hh>
#include <object/urbi-exception.hh>

namespace object
{
  Float::Float()
    : value_(0)
  {
    proto_add(proto);
  }

  Float::Float(value_type value)
    : value_(value)
  {
    proto_add(proto);
  }

  Float::Float(const rFloat& model)
    : value_(model->value_get())
  {
    proto_add(model);
    proto_remove(proto);
  }

  const Float::value_type&
  Float::value_get() const
  {
    return value_;
  }

  Float::value_type&
  Float::value_get()
  {
    return value_;
  }

  int
  Float::to_int(const libport::Symbol func) const
  {
    try
    {
      return libport::ufloat_to_int(value_);
    }
    catch (libport::bad_numeric_cast& ue)
    {
      throw BadInteger(value_, func);
      return 0;  // Keep the compiler happy
    }
  }

  unsigned int
  Float::to_unsigned_int(const libport::Symbol func,
			 const std::string fmt) const
  {
    try
    {
      int res = libport::ufloat_to_int(value_);
      if (res < 0)
	throw libport::bad_numeric_cast();
      return res;
    }
    catch (libport::bad_numeric_cast& ue)
    {
      throw BadInteger(value_, func, fmt);
      return 0;  // Keep the compiler happy
    }
  }

  Float::value_type
  Float::inf()
  {
    return std::numeric_limits<libport::ufloat>::infinity();
  }

  Float::value_type
  Float::nan()
  {
    return std::numeric_limits<libport::ufloat>::quiet_NaN();
  }

  std::string
  Float::as_string(const rObject& from)
  {
    if (from == proto)
      return SYMBOL(LT_Float_GT);

    type_check(from, proto, 1);
    Float::value_type fl = from->as<Float>()->value_get();
    // Do not rely on boost::format to print inf and nan since
    // behavior differs under Win32.
    if (std::isinf(fl))
      return fl > 0 ? SYMBOL(inf) : SYMBOL(MINUS_inf);
    if (std::isnan(fl))
      return SYMBOL(nan);
    // Print integers with a different format string to avoid
    // the scientific notation with loss of precision.
    if (::round(fl) == fl)
    {
      // This format string is enough for a 64 bits integer.
      static boost::format f("%.20g");
      return str(f % fl);
    }
    else
    {
      static boost::format f("%g");
      return str(f % fl);
    }
  }

#define BOUNCE_OP(Op, ResType, Check)					\
  ResType								\
  Float::operator Op(value_type rhs)					\
  {                                                                     \
    static libport::Symbol op(#Op);                                     \
    WHEN(Check,                                                         \
         if (!rhs)							\
           throw PrimitiveError(op, "division by 0"));                  \
    return value_get() Op rhs;						\
  }

  BOUNCE_OP(*, Float::value_type, false)
  BOUNCE_OP(/, Float::value_type, true)
  BOUNCE_OP(<, bool, false)

#undef BOUNCE_OP

  Float::value_type
  Float::operator %(value_type rhs)
  {
    if (!rhs)
      throw PrimitiveError(SYMBOL(PERCENT), "modulo by 0");
    return fmod(value_get(), rhs);
  }

  Float::value_type
  Float::pow(value_type rhs)
  {
    return powf(value_get(), rhs);
  }

  /*------------------.
  | Unary operators.  |
  `------------------*/
#define BOUNCE_INT_OP(Op)			\
  int						\
  Float::operator Op()				\
  {						\
    static libport::Symbol op(#Op);		\
    return Op to_int(op);			\
  }
BOUNCE_INT_OP(~)
#undef BOUNCE_INT_OP

  /*-------------------.
  | Binary operators.  |
  `-------------------*/
#define BOUNCE_INT_OP(Op)			\
  int						\
  Float::operator Op(int rhs)			\
  {						\
    static libport::Symbol op(#Op);		\
    return to_int(op) Op rhs;			\
}

  BOUNCE_INT_OP(^)
  BOUNCE_INT_OP(|)
  BOUNCE_INT_OP(&)
#undef BOUNCE_INT_OP

#define BOUNCE_UNSIGNED_INT_OP(Op)		\
  int						\
  Float::operator Op(unsigned int rhs)		\
  {						\
    static libport::Symbol op(#Op);		\
    return to_int(op) Op rhs;			\
}

  BOUNCE_UNSIGNED_INT_OP(<<)
  BOUNCE_UNSIGNED_INT_OP(>>)
#undef BOUNCE_UNSIGNED_INT_OP

#define CHECK_POSITIVE(F)                                       \
  if (value_ < 0)                                               \
    throw PrimitiveError(F, "argument has to be positive");

#define CHECK_TRIGO_RANGE(F)                                    \
  if (value_ < -1 || value_ > 1)                                \
    throw PrimitiveError(F, "invalid range");

#define BOUNCE(F, Pos, Range)                           \
  Float::value_type					\
  Float::F()                                            \
  {                                                     \
    WHEN(Pos, CHECK_POSITIVE(SYMBOL(F)));               \
    WHEN(Range, CHECK_TRIGO_RANGE(SYMBOL(F)));          \
    return ::F(value_get());				\
  }

  BOUNCE(acos,  false, true);
  BOUNCE(asin,  false, true);
  BOUNCE(atan,  false, false);
  BOUNCE(cos,   false, false);
  BOUNCE(exp,   false, false);
  BOUNCE(fabs,  false, false);
  BOUNCE(log,   true,  false);
  BOUNCE(round, false, false);
  BOUNCE(sin,   false, false);
  BOUNCE(sqrt,  true,  false);
  BOUNCE(tan,   false, false);
  BOUNCE(trunc, false, false);

#undef CHECK_POSITIVE
#undef CHECK_TRIGO_RANGE
#undef BOUNCE

  int
  Float::random()
  {
    static const std::string fmt = "expected positive integer, got %1%";
    unsigned int upper_bound = to_unsigned_int(SYMBOL(random), fmt);
    if (!upper_bound)
      throw BadInteger(value_get(), SYMBOL(random), fmt);
    return rand() % upper_bound;
  }

  rFloat
  Float::plus(objects_type& args)
  {
    check_arg_count(args.size(), 0, 1);
    if (args.empty())
      return this;
    else
    {
      type_check(args[0], proto, 1);
      return new Float(value_get() + args[0]->as<Float>()->value_get());
    }
  }

  rFloat
  Float::minus(objects_type& args)
  {
    check_arg_count(args.size(), 0, 1);
    if (args.empty())
      return new Float(-value_get());
    else
    {
      type_check(args[0], proto, 1);
      return new Float(value_get() - args[0]->as<Float>()->value_get());
    }
  }

  rList
  Float::seq()
  {
    unsigned int n = to_unsigned_int(SYMBOL(seq));
    List::value_type res;
    for (unsigned int i = 0; i < n; i++)
      res.push_back(new Float(i));
    return new List(res);
  }

  rFloat
  Float::set(value_type rhs)
  {
    value_ = rhs;
    return this;
  }

  /*--------.
  | Details |
  `--------*/

  std::ostream& Float::special_slots_dump(std::ostream& o,
                                          runner::Runner&) const
  {
    o << "value = " << value_ << libport::iendl;
    return o;
  }

  /*---------------.
  | Binding system |
  `---------------*/

  void
  Float::initialize(CxxObject::Binder<Float>& bind)
  {
    bind(SYMBOL(CARET), &Float::operator^);
    bind(SYMBOL(GT_GT), &Float::operator>>);
    bind(SYMBOL(LT), static_cast<bool (Float::*)(value_type)>(&Float::operator<));
    bind(SYMBOL(LT_LT), &Float::operator<<);
    bind(SYMBOL(MINUS), &Float::minus);
    bind(SYMBOL(PERCENT), &Float::operator%);
    bind(SYMBOL(PLUS), &Float::plus);
    bind(SYMBOL(SLASH), &Float::operator/);
    bind(SYMBOL(STAR), &Float::operator*);
    bind(SYMBOL(STAR_STAR), &Float::pow);
    bind(SYMBOL(abs), &Float::fabs);
    bind(SYMBOL(acos), &Float::acos);
    bind(SYMBOL(asString), &Float::as_string);
    bind(SYMBOL(asin), &Float::asin);
    bind(SYMBOL(atan), &Float::atan);
    bind(SYMBOL(bitand), &Float::operator&);
    bind(SYMBOL(bitor), &Float::operator|);
    bind(SYMBOL(compl), &Float::operator~);
    bind(SYMBOL(cos), &Float::cos);
    bind(SYMBOL(exp), &Float::exp);
    bind(SYMBOL(inf), &Float::inf);
    bind(SYMBOL(log), &Float::log);
    bind(SYMBOL(nan), &Float::nan);
    bind(SYMBOL(random), &Float::random);
    bind(SYMBOL(round), &Float::round);
    bind(SYMBOL(seq), &Float::seq);
    bind(SYMBOL(set), &Float::set);
    bind(SYMBOL(sin), &Float::sin);
    bind(SYMBOL(sqrt), &Float::sqrt);
    bind(SYMBOL(tan), &Float::tan);
    bind(SYMBOL(trunc), &Float::trunc);
  }

  bool Float::float_added = CxxObject::add<Float>("Float", Float::proto);
  const std::string Float::type_name = "Float";
  rObject Float::proto;
  std::string
  Float::type_name_get() const
  {
    return type_name;
  }

}; // namespace object
<|endoftext|>


<commit_before>// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2006-2010 Benoit Jacob <jacob.benoit.1@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.

#ifndef EIGEN_NO_STATIC_ASSERT
#define EIGEN_NO_STATIC_ASSERT // turn static asserts into runtime asserts in order to check them
#endif

#include "main.h"

template<typename VectorType> void map_class_vector(const VectorType& m)
{
  typedef typename VectorType::Index Index;
  typedef typename VectorType::Scalar Scalar;

  Index size = m.size();

  // test Map.h
  Scalar* array1 = internal::aligned_new<Scalar>(size);
  Scalar* array2 = internal::aligned_new<Scalar>(size);
  Scalar* array3 = new Scalar[size+1];
  Scalar* array3unaligned = size_t(array3)%16 == 0 ? array3+1 : array3;

  Map<VectorType, Aligned>(array1, size) = VectorType::Random(size);
  Map<VectorType, Aligned>(array2, size) = Map<VectorType,Aligned>(array1, size);
  Map<VectorType>(array3unaligned, size) = Map<VectorType>(array1, size);
  VectorType ma1 = Map<VectorType, Aligned>(array1, size);
  VectorType ma2 = Map<VectorType, Aligned>(array2, size);
  VectorType ma3 = Map<VectorType>(array3unaligned, size);
  VERIFY_IS_EQUAL(ma1, ma2);
  VERIFY_IS_EQUAL(ma1, ma3);
  #ifdef EIGEN_VECTORIZE
  if(internal::packet_traits<Scalar>::Vectorizable)
    VERIFY_RAISES_ASSERT((Map<VectorType,Aligned>(array3unaligned, size)))
  #endif

  internal::aligned_delete(array1, size);
  internal::aligned_delete(array2, size);
  delete[] array3;
}

template<typename MatrixType> void map_class_matrix(const MatrixType& m)
{
  typedef typename MatrixType::Index Index;
  typedef typename MatrixType::Scalar Scalar;

  Index rows = m.rows(), cols = m.cols(), size = rows*cols;

  // test Map.h
  Scalar* array1 = internal::aligned_new<Scalar>(size);
  for(int i = 0; i < size; i++) array1[i] = Scalar(1);
  Scalar* array2 = internal::aligned_new<Scalar>(size);
  for(int i = 0; i < size; i++) array2[i] = Scalar(1);
  Scalar* array3 = new Scalar[size+1];
  for(int i = 0; i < size+1; i++) array3[i] = Scalar(1);
  Scalar* array3unaligned = size_t(array3)%16 == 0 ? array3+1 : array3;
  Map<MatrixType, Aligned>(array1, rows, cols) = MatrixType::Ones(rows,cols);
  Map<MatrixType>(array2, rows, cols) = Map<MatrixType>(array1, rows, cols);
  Map<MatrixType>(array3unaligned, rows, cols) = Map<MatrixType>(array1, rows, cols);
  MatrixType ma1 = Map<MatrixType>(array1, rows, cols);
  MatrixType ma2 = Map<MatrixType, Aligned>(array2, rows, cols);
  VERIFY_IS_EQUAL(ma1, ma2);
  MatrixType ma3 = Map<MatrixType>(array3unaligned, rows, cols);
  VERIFY_IS_EQUAL(ma1, ma3);

  internal::aligned_delete(array1, size);
  internal::aligned_delete(array2, size);
  delete[] array3;
}

template<typename VectorType> void map_static_methods(const VectorType& m)
{
  typedef typename VectorType::Index Index;
  typedef typename VectorType::Scalar Scalar;

  Index size = m.size();

  // test Map.h
  Scalar* array1 = internal::aligned_new<Scalar>(size);
  Scalar* array2 = internal::aligned_new<Scalar>(size);
  Scalar* array3 = new Scalar[size+1];
  Scalar* array3unaligned = size_t(array3)%16 == 0 ? array3+1 : array3;

  VectorType::MapAligned(array1, size) = VectorType::Random(size);
  VectorType::Map(array2, size) = VectorType::Map(array1, size);
  VectorType::Map(array3unaligned, size) = VectorType::Map(array1, size);
  VectorType ma1 = VectorType::Map(array1, size);
  VectorType ma2 = VectorType::MapAligned(array2, size);
  VectorType ma3 = VectorType::Map(array3unaligned, size);
  VERIFY_IS_EQUAL(ma1, ma2);
  VERIFY_IS_EQUAL(ma1, ma3);

  internal::aligned_delete(array1, size);
  internal::aligned_delete(array2, size);
  delete[] array3;
}

template<typename PlainObjectType> void check_const_correctness(const PlainObjectType&)
{
  // there's a lot that we can't test here while still having this test compile!
  // the only possible approach would be to run a script trying to compile stuff and checking that it fails.
  // CMake can help with that.

  // verify that map-to-const don't have LvalueBit
  typedef typename internal::add_const<PlainObjectType>::type ConstPlainObjectType;
  VERIFY( !(internal::traits<Map<ConstPlainObjectType> >::Flags & LvalueBit) );
  VERIFY( !(internal::traits<Map<ConstPlainObjectType, Aligned> >::Flags & LvalueBit) );
  VERIFY( !(Map<ConstPlainObjectType>::Flags & LvalueBit) );
  VERIFY( !(Map<ConstPlainObjectType, Aligned>::Flags & LvalueBit) );
}

void test_mapped_matrix()
{
  for(int i = 0; i < g_repeat; i++) {
    CALL_SUBTEST_1( map_class_vector(Matrix<float, 1, 1>()) );
    CALL_SUBTEST_1( check_const_correctness(Matrix<float, 1, 1>()) );
    CALL_SUBTEST_2( map_class_vector(Vector4d()) );
    CALL_SUBTEST_2( check_const_correctness(Matrix4d()) );
    CALL_SUBTEST_3( map_class_vector(RowVector4f()) );
    CALL_SUBTEST_4( map_class_vector(VectorXcf(8)) );
    CALL_SUBTEST_5( map_class_vector(VectorXi(12)) );
    CALL_SUBTEST_5( check_const_correctness(VectorXi(12)) );

    CALL_SUBTEST_1( map_class_matrix(Matrix<float, 1, 1>()) );
    CALL_SUBTEST_2( map_class_matrix(Matrix4d()) );
    CALL_SUBTEST_11( map_class_matrix(Matrix<float,3,5>()) );
    CALL_SUBTEST_4( map_class_matrix(MatrixXcf(internal::random<int>(1,10),internal::random<int>(1,10))) );
    CALL_SUBTEST_5( map_class_matrix(MatrixXi(internal::random<int>(1,10),internal::random<int>(1,10))) );

    CALL_SUBTEST_6( map_static_methods(Matrix<double, 1, 1>()) );
    CALL_SUBTEST_7( map_static_methods(Vector3f()) );
    CALL_SUBTEST_8( map_static_methods(RowVector3d()) );
    CALL_SUBTEST_9( map_static_methods(VectorXcd(8)) );
    CALL_SUBTEST_10( map_static_methods(VectorXf(12)) );
  }
}
<commit_msg>extend Map unit test to check buffers allocated on the stack<commit_after>// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2006-2010 Benoit Jacob <jacob.benoit.1@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.

#ifndef EIGEN_NO_STATIC_ASSERT
#define EIGEN_NO_STATIC_ASSERT // turn static asserts into runtime asserts in order to check them
#endif

#include "main.h"

#define EIGEN_TESTMAP_MAX_SIZE 256

template<typename VectorType> void map_class_vector(const VectorType& m)
{
  typedef typename VectorType::Index Index;
  typedef typename VectorType::Scalar Scalar;

  Index size = m.size();

  // test Map.h
  Scalar* array1 = internal::aligned_new<Scalar>(size);
  Scalar* array2 = internal::aligned_new<Scalar>(size);
  Scalar* array3 = new Scalar[size+1];
  Scalar* array3unaligned = size_t(array3)%16 == 0 ? array3+1 : array3;
  Scalar  array4[EIGEN_TESTMAP_MAX_SIZE];

  Map<VectorType, Aligned>(array1, size) = VectorType::Random(size);
  Map<VectorType, Aligned>(array2, size) = Map<VectorType,Aligned>(array1, size);
  Map<VectorType>(array3unaligned, size) = Map<VectorType>(array1, size);
  Map<VectorType>(array4, size)          = Map<VectorType,Aligned>(array1, size);
  VectorType ma1 = Map<VectorType, Aligned>(array1, size);
  VectorType ma2 = Map<VectorType, Aligned>(array2, size);
  VectorType ma3 = Map<VectorType>(array3unaligned, size);
  VectorType ma4 = Map<VectorType>(array4, size);
  VERIFY_IS_EQUAL(ma1, ma2);
  VERIFY_IS_EQUAL(ma1, ma3);
  VERIFY_IS_EQUAL(ma1, ma4);
  #ifdef EIGEN_VECTORIZE
  if(internal::packet_traits<Scalar>::Vectorizable)
    VERIFY_RAISES_ASSERT((Map<VectorType,Aligned>(array3unaligned, size)))
  #endif

  internal::aligned_delete(array1, size);
  internal::aligned_delete(array2, size);
  delete[] array3;
}

template<typename MatrixType> void map_class_matrix(const MatrixType& m)
{
  typedef typename MatrixType::Index Index;
  typedef typename MatrixType::Scalar Scalar;

  Index rows = m.rows(), cols = m.cols(), size = rows*cols;

  // test Map.h
  Scalar* array1 = internal::aligned_new<Scalar>(size);
  for(int i = 0; i < size; i++) array1[i] = Scalar(1);
  Scalar* array2 = internal::aligned_new<Scalar>(size);
  for(int i = 0; i < size; i++) array2[i] = Scalar(1);
  Scalar* array3 = new Scalar[size+1];
  for(int i = 0; i < size+1; i++) array3[i] = Scalar(1);
  Scalar* array3unaligned = size_t(array3)%16 == 0 ? array3+1 : array3;
  Map<MatrixType, Aligned>(array1, rows, cols) = MatrixType::Ones(rows,cols);
  Map<MatrixType>(array2, rows, cols) = Map<MatrixType>(array1, rows, cols);
  Map<MatrixType>(array3unaligned, rows, cols) = Map<MatrixType>(array1, rows, cols);
  MatrixType ma1 = Map<MatrixType>(array1, rows, cols);
  MatrixType ma2 = Map<MatrixType, Aligned>(array2, rows, cols);
  VERIFY_IS_EQUAL(ma1, ma2);
  MatrixType ma3 = Map<MatrixType>(array3unaligned, rows, cols);
  VERIFY_IS_EQUAL(ma1, ma3);

  internal::aligned_delete(array1, size);
  internal::aligned_delete(array2, size);
  delete[] array3;
}

template<typename VectorType> void map_static_methods(const VectorType& m)
{
  typedef typename VectorType::Index Index;
  typedef typename VectorType::Scalar Scalar;

  Index size = m.size();

  // test Map.h
  Scalar* array1 = internal::aligned_new<Scalar>(size);
  Scalar* array2 = internal::aligned_new<Scalar>(size);
  Scalar* array3 = new Scalar[size+1];
  Scalar* array3unaligned = size_t(array3)%16 == 0 ? array3+1 : array3;

  VectorType::MapAligned(array1, size) = VectorType::Random(size);
  VectorType::Map(array2, size) = VectorType::Map(array1, size);
  VectorType::Map(array3unaligned, size) = VectorType::Map(array1, size);
  VectorType ma1 = VectorType::Map(array1, size);
  VectorType ma2 = VectorType::MapAligned(array2, size);
  VectorType ma3 = VectorType::Map(array3unaligned, size);
  VERIFY_IS_EQUAL(ma1, ma2);
  VERIFY_IS_EQUAL(ma1, ma3);

  internal::aligned_delete(array1, size);
  internal::aligned_delete(array2, size);
  delete[] array3;
}

template<typename PlainObjectType> void check_const_correctness(const PlainObjectType&)
{
  // there's a lot that we can't test here while still having this test compile!
  // the only possible approach would be to run a script trying to compile stuff and checking that it fails.
  // CMake can help with that.

  // verify that map-to-const don't have LvalueBit
  typedef typename internal::add_const<PlainObjectType>::type ConstPlainObjectType;
  VERIFY( !(internal::traits<Map<ConstPlainObjectType> >::Flags & LvalueBit) );
  VERIFY( !(internal::traits<Map<ConstPlainObjectType, Aligned> >::Flags & LvalueBit) );
  VERIFY( !(Map<ConstPlainObjectType>::Flags & LvalueBit) );
  VERIFY( !(Map<ConstPlainObjectType, Aligned>::Flags & LvalueBit) );
}

void test_mapped_matrix()
{
  for(int i = 0; i < g_repeat; i++) {
    CALL_SUBTEST_1( map_class_vector(Matrix<float, 1, 1>()) );
    CALL_SUBTEST_1( check_const_correctness(Matrix<float, 1, 1>()) );
    CALL_SUBTEST_2( map_class_vector(Vector4d()) );
    CALL_SUBTEST_2( map_class_vector(VectorXd(13)) );
    CALL_SUBTEST_2( check_const_correctness(Matrix4d()) );
    CALL_SUBTEST_3( map_class_vector(RowVector4f()) );
    CALL_SUBTEST_4( map_class_vector(VectorXcf(8)) );
    CALL_SUBTEST_5( map_class_vector(VectorXi(12)) );
    CALL_SUBTEST_5( check_const_correctness(VectorXi(12)) );

    CALL_SUBTEST_1( map_class_matrix(Matrix<float, 1, 1>()) );
    CALL_SUBTEST_2( map_class_matrix(Matrix4d()) );
    CALL_SUBTEST_11( map_class_matrix(Matrix<float,3,5>()) );
    CALL_SUBTEST_4( map_class_matrix(MatrixXcf(internal::random<int>(1,10),internal::random<int>(1,10))) );
    CALL_SUBTEST_5( map_class_matrix(MatrixXi(internal::random<int>(1,10),internal::random<int>(1,10))) );

    CALL_SUBTEST_6( map_static_methods(Matrix<double, 1, 1>()) );
    CALL_SUBTEST_7( map_static_methods(Vector3f()) );
    CALL_SUBTEST_8( map_static_methods(RowVector3d()) );
    CALL_SUBTEST_9( map_static_methods(VectorXcd(8)) );
    CALL_SUBTEST_10( map_static_methods(VectorXf(12)) );
  }
}
<|endoftext|>


<commit_before>#include "mitkPrimStripInteractor.h"
#include <mitkInteractionConst.h>
#include <mitkPositionEvent.h>
#include <mitkDataTreeNode.h>
#include <mitkMesh.h>
#include <vtkTransform.h>
#include <mitkAction.h>
#include <mitkLineOperation.h>
#include <mitkProperties.h>

mitk::PrimStripInteractor::PrimStripInteractor(const char * type, DataTreeNode* dataTreeNode)
: HierarchicalInteractor(type, dataTreeNode)
{
  m_LineInteractor = new mitk::LineInteractor("lineinteractor",dataTreeNode);
  this->AddInteractor((Interactor::Pointer)m_LineInteractor);
}

mitk::PrimStripInteractor::~PrimStripInteractor()
{
  //delete m_LineInteractor;
}

float mitk::PrimStripInteractor::CalculateJurisdiction(StateEvent const* stateEvent) const
{
  float returnValue = 0;

  mitk::PositionEvent const  *posEvent = dynamic_cast <const mitk::PositionEvent *> (stateEvent->GetEvent());
  //checking if a keyevent can be handled:
  if (posEvent == NULL)
  {
    //check, if the current state has a transition waiting for that key event.
    if (this->GetCurrentState()->GetTransition(stateEvent->GetId())!=NULL)
    {
      return 0.5;
    }
    else
    {
      return 0;
    }
  }

  //Mouse event handling:
  //on MouseMove do nothing! reimplement if needed differently
  if (stateEvent->GetEvent()->GetType() == mitk::Type_MouseMove)
  {
    return 0;
  }

  //check on the right data-type
  mitk::Mesh* mesh = dynamic_cast<mitk::Mesh*>(m_DataTreeNode->GetData());
	if (mesh == NULL)
		return false;

  //go throgh all cells and get the BoundingBox:
  Mesh::ConstCellIterator cellIt = mesh->GetMesh()->GetCells()->Begin();
  Mesh::ConstCellIterator cellEnd = mesh->GetMesh()->GetCells()->End();
  while( cellIt != cellEnd )
  {

    Mesh::DataType::BoundingBoxPointer bBox = mesh->GetBoundingBoxFromCell( cellIt->Index() );
    if (bBox.IsNull())
      return 0;

    //since we now have 3D picking in GlobalInteraction and all events send are DisplayEvents with 3D information,
    //we concentrate on 3D coordinates
    mitk::Point3D worldPoint = posEvent->GetWorldPosition();
    float p[3];
    itk2vtk(worldPoint, p);
    //transforming the Worldposition to local coordinatesystem
    m_DataTreeNode->GetData()->GetGeometry()->GetVtkTransform()->GetInverse()->TransformPoint(p, p);
    vtk2itk(p, worldPoint);

    //distance between center and point
    mitk::BoundingBox::PointType center = bBox->GetCenter();
    returnValue = worldPoint.EuclideanDistanceTo(center);

    //now compared to size of boundingbox to get between 0 and 1;
    returnValue = returnValue/( (bBox->GetMaximum().EuclideanDistanceTo(bBox->GetMinimum() ) ) );

    //shall be 1 if short length to center
    returnValue = 1 - returnValue;

    //check if the given position lies inside the data-object
    if (bBox->IsInside(worldPoint))
    {
      //mapped between 0,5 and 1
      returnValue = 0.5 + (returnValue / 2);
    }
    else
    {
      //set it in range between 0 and 0.5
      returnValue = returnValue / 2;
    }
    ++cellIt;
  }

//now check all lower statemachines:
  float lowerJurisdiction = this->CalculateLowerJurisdiction(stateEvent);

  if (returnValue < lowerJurisdiction)
    returnValue = lowerJurisdiction;

  return returnValue;
}

bool mitk::PrimStripInteractor::ExecuteAction(Action* action, mitk::StateEvent const* stateEvent)
{
  bool ok = false;//for return type bool

  //checking corresponding Data; has to be a PointSet or a subclass
  mitk::Mesh* mesh = dynamic_cast<mitk::Mesh*>(m_DataTreeNode->GetData());
	if (mesh == NULL)
		return false;

  switch (action->GetActionId())
	{
  case AcINITNEWOBJECT:
    {
      //get the next cellId and set m_CurrentCellId
      m_CurrentCellId = mesh->GetNewCellId();

      //now reserv a new cell in m_ItkData
      LineOperation* doOp = new mitk::LineOperation(OpNEWCELL, m_CurrentCellId);
		  if (m_UndoEnabled)
		  {
			  LineOperation* undoOp = new mitk::LineOperation(OpDELETECELL, m_CurrentCellId);
			  OperationEvent *operationEvent = new OperationEvent(mesh, doOp, undoOp);
			  m_UndoController->SetOperationEvent(operationEvent);
		  }
      mesh->ExecuteOperation(doOp);
    }
    ok = true;
    break;
  case AcCHECKLINE:
    //check, if a line is hit
    {
      mitk::PositionEvent const  *posEvent = dynamic_cast <const mitk::PositionEvent *> (stateEvent->GetEvent());
			if (posEvent == NULL)
        return false;

      //converting from Point3D to itk::Point
      mitk::Point3D worldPoint = posEvent->GetWorldPosition();

      //searching for a point
      unsigned long lineId = 0;
      unsigned long cellId = 0;
      int PRECISION = 1;
      mitk::IntProperty *precision = dynamic_cast<IntProperty*>(action->GetProperty("PRECISION"));
      if (precision != NULL)
      {
        PRECISION = precision->GetValue();
      }

      if(mesh->SearchLine(worldPoint, PRECISION, lineId, cellId))//line found
      {
        m_CurrentCellId = cellId;
        mitk::StateEvent* newStateEvent = new mitk::StateEvent(EIDYES, stateEvent->GetEvent());
        this->HandleEvent( newStateEvent );
        ok = true;
      }
      else
		  {
			  //new Event with information NO
        mitk::StateEvent* newStateEvent = new mitk::StateEvent(EIDNO, stateEvent->GetEvent());
        this->HandleEvent( newStateEvent );
			  ok = true;
			}
    }
    break;
  case AcCHECKBOUNDINGBOX:
    //check if the MousePosition lies inside the BoundingBox of the current Cell
    {
      mitk::PositionEvent const  *posEvent = dynamic_cast <const mitk::PositionEvent *> (stateEvent->GetEvent());
  		if (posEvent == NULL)
        return false;

      mitk::Point3D worldPoint = posEvent->GetWorldPosition();

      //Axis-aligned bounding box(AABB)
      mitk::Mesh::DataType::BoundingBoxPointer aABB = mesh->GetBoundingBoxFromCell(m_CurrentCellId);
      if (aABB.IsNull())
        return false;

      //check if the given point lies inside the boundingbox
      if (aABB->IsInside(worldPoint))
      {
        mitk::StateEvent* newStateEvent = new mitk::StateEvent(EIDYES, stateEvent->GetEvent());
        this->HandleEvent( newStateEvent );

      }
      else
      {
        mitk::StateEvent* newStateEvent = new mitk::StateEvent(EIDNO, stateEvent->GetEvent());
        this->HandleEvent(newStateEvent );
      }
    }
    ok = true;
    break;
  case AcCHECKOBJECT:
    {
      //picking if this object is hit. then set the m_CurrentCellId Variable
      //this object is hit, if the transmitted position of the event is hitting a point or a line of that cell
      mitk::PositionEvent const  *posEvent = dynamic_cast <const mitk::PositionEvent *> (stateEvent->GetEvent());
  		if (posEvent == NULL)
        return false;

      bool hit = true;
      //var's for EvaluatePosition
      mitk::Point3D point = posEvent->GetWorldPosition();
      unsigned long cellId = 0;

      int precision = 5;
      mitk::IntProperty *precisionProperty = dynamic_cast<IntProperty*>(action->GetProperty("PRECISION"));
      if (precisionProperty != NULL)
      {
        precision = precisionProperty->GetValue();
      }

      //check wheather the mesh is hit.
      if (mesh->EvaluatePosition(point, cellId, precision))
      {
        m_CurrentCellId = cellId;
        mitk::StateEvent* newStateEvent = new mitk::StateEvent(EIDYES, stateEvent->GetEvent());
        this->HandleEvent( newStateEvent );

      }
      else
      {
        m_CurrentCellId = 0;
        mitk::StateEvent* newStateEvent = new mitk::StateEvent(EIDNO, stateEvent->GetEvent());
        this->HandleEvent(newStateEvent );
      }
    }
    ok = true;
    break;
  case AcSELECTCELL:
    {
      LineOperation* lineDoOp = new mitk::LineOperation(OpSELECTCELL, m_CurrentCellId);
		  if (m_UndoEnabled)
		  {
		  	LineOperation* lineUndoOp = new mitk::LineOperation(OpDESELECTCELL, m_CurrentCellId);
			  OperationEvent *operationEvent = new OperationEvent(mesh, lineDoOp, lineUndoOp);
			  m_UndoController->SetOperationEvent(operationEvent);
		  }
      mesh->ExecuteOperation(lineDoOp );
    }
    ok = true;
    break;
  case AcDESELECTCELL:
    {
      //if number of cell is >0
      if (mesh->GetNumberOfCells()>0)
      {
        LineOperation* lineDoOp = new mitk::LineOperation(OpDESELECTCELL, m_CurrentCellId);
		    if (m_UndoEnabled)
		    {
		  	  LineOperation* lineUndoOp = new mitk::LineOperation(OpSELECTCELL, m_CurrentCellId);
			    OperationEvent *operationEvent = new OperationEvent(mesh, lineDoOp, lineUndoOp);
			    m_UndoController->SetOperationEvent(operationEvent);
		    }
        mesh->ExecuteOperation(lineDoOp );
      }
    }
    ok = true;
    break;
  case AcINITMOVEMENT:
    //prepare everything for movement of one cell
    {
      mitk::PositionEvent const  *posEvent = dynamic_cast <const mitk::PositionEvent *> (stateEvent->GetEvent());
		  if (posEvent == NULL)
        return false;

      //start of the Movement is stored to calculate the undoCoordinate in FinishMovement
      m_MovementStart = posEvent->GetWorldPosition();
      m_OldPoint = m_MovementStart;
    }
    ok = true;
    break;
  case AcMOVE:
    //move the cell without undo
    {
      mitk::PositionEvent const  *posEvent = dynamic_cast <const mitk::PositionEvent *> (stateEvent->GetEvent());
	  	if (posEvent == NULL)
        return false;

      mitk::Point3D newPoint = posEvent->GetWorldPosition();

      //calculate a vector between the oldPoint and the newPoint
      Vector3D vector = newPoint - m_OldPoint;

      CellOperation* doOp = new mitk::CellOperation(OpMOVECELL, m_CurrentCellId, vector);

      m_OldPoint = newPoint;

      //execute the Operation
      //here no undo is stored. only the start and the end is stored for undo.
		  mesh->ExecuteOperation(doOp);
    }
    ok = true;
    break;
  case AcFINISHMOVEMENT:
    //move the cell to the final position and send undo-information
    {
      mitk::PositionEvent const *posEvent = dynamic_cast <const mitk::PositionEvent *> (stateEvent->GetEvent());
		  if (posEvent == NULL)
        return false;

      //finish the movement:
      // set undo-information and move it to the last position.
      mitk::Point3D newPoint = posEvent->GetWorldPosition();

      Vector3D vector = newPoint - m_OldPoint;

      CellOperation* doOp = new mitk::CellOperation(OpMOVECELL, m_CurrentCellId, vector);
	    if ( m_UndoEnabled )
      {
        Vector3D vectorBack = m_MovementStart - newPoint;
        CellOperation* undoOp = new mitk::CellOperation(OpMOVECELL, m_CurrentCellId, vectorBack);
        OperationEvent *operationEvent = new OperationEvent(m_DataTreeNode->GetData(), doOp, undoOp);
        m_UndoController->SetOperationEvent(operationEvent);
      }
		  //execute the Operation
		  m_DataTreeNode->GetData()->ExecuteOperation(doOp);
    }
    ok = true;
    break;
  case AcREMOVE:
    ok = true;
    break;
  default:
    return Superclass::ExecuteAction(action, stateEvent);
  }
  return ok;
}
<commit_msg>FIX: warning<commit_after>#include "mitkPrimStripInteractor.h"
#include <mitkInteractionConst.h>
#include <mitkPositionEvent.h>
#include <mitkDataTreeNode.h>
#include <mitkMesh.h>
#include <vtkTransform.h>
#include <mitkAction.h>
#include <mitkLineOperation.h>
#include <mitkProperties.h>

mitk::PrimStripInteractor::PrimStripInteractor(const char * type, DataTreeNode* dataTreeNode)
: HierarchicalInteractor(type, dataTreeNode)
{
  m_LineInteractor = new mitk::LineInteractor("lineinteractor",dataTreeNode);
  this->AddInteractor((Interactor::Pointer)m_LineInteractor);
}

mitk::PrimStripInteractor::~PrimStripInteractor()
{
  //delete m_LineInteractor;
}

float mitk::PrimStripInteractor::CalculateJurisdiction(StateEvent const* stateEvent) const
{
  float returnValue = 0;

  mitk::PositionEvent const  *posEvent = dynamic_cast <const mitk::PositionEvent *> (stateEvent->GetEvent());
  //checking if a keyevent can be handled:
  if (posEvent == NULL)
  {
    //check, if the current state has a transition waiting for that key event.
    if (this->GetCurrentState()->GetTransition(stateEvent->GetId())!=NULL)
    {
      return 0.5;
    }
    else
    {
      return 0;
    }
  }

  //Mouse event handling:
  //on MouseMove do nothing! reimplement if needed differently
  if (stateEvent->GetEvent()->GetType() == mitk::Type_MouseMove)
  {
    return 0;
  }

  //check on the right data-type
  mitk::Mesh* mesh = dynamic_cast<mitk::Mesh*>(m_DataTreeNode->GetData());
	if (mesh == NULL)
		return false;

  //go throgh all cells and get the BoundingBox:
  Mesh::ConstCellIterator cellIt = mesh->GetMesh()->GetCells()->Begin();
  Mesh::ConstCellIterator cellEnd = mesh->GetMesh()->GetCells()->End();
  while( cellIt != cellEnd )
  {

    Mesh::DataType::BoundingBoxPointer bBox = mesh->GetBoundingBoxFromCell( cellIt->Index() );
    if (bBox.IsNull())
      return 0;

    //since we now have 3D picking in GlobalInteraction and all events send are DisplayEvents with 3D information,
    //we concentrate on 3D coordinates
    mitk::Point3D worldPoint = posEvent->GetWorldPosition();
    float p[3];
    itk2vtk(worldPoint, p);
    //transforming the Worldposition to local coordinatesystem
    m_DataTreeNode->GetData()->GetGeometry()->GetVtkTransform()->GetInverse()->TransformPoint(p, p);
    vtk2itk(p, worldPoint);

    //distance between center and point
    mitk::BoundingBox::PointType center = bBox->GetCenter();
    returnValue = worldPoint.EuclideanDistanceTo(center);

    //now compared to size of boundingbox to get between 0 and 1;
    returnValue = returnValue/( (bBox->GetMaximum().EuclideanDistanceTo(bBox->GetMinimum() ) ) );

    //shall be 1 if short length to center
    returnValue = 1 - returnValue;

    //check if the given position lies inside the data-object
    if (bBox->IsInside(worldPoint))
    {
      //mapped between 0,5 and 1
      returnValue = 0.5 + (returnValue / 2);
    }
    else
    {
      //set it in range between 0 and 0.5
      returnValue = returnValue / 2;
    }
    ++cellIt;
  }

//now check all lower statemachines:
  float lowerJurisdiction = this->CalculateLowerJurisdiction(stateEvent);

  if (returnValue < lowerJurisdiction)
    returnValue = lowerJurisdiction;

  return returnValue;
}

bool mitk::PrimStripInteractor::ExecuteAction(Action* action, mitk::StateEvent const* stateEvent)
{
  bool ok = false;//for return type bool

  //checking corresponding Data; has to be a PointSet or a subclass
  mitk::Mesh* mesh = dynamic_cast<mitk::Mesh*>(m_DataTreeNode->GetData());
	if (mesh == NULL)
		return false;

  switch (action->GetActionId())
	{
  case AcINITNEWOBJECT:
    {
      //get the next cellId and set m_CurrentCellId
      m_CurrentCellId = mesh->GetNewCellId();

      //now reserv a new cell in m_ItkData
      LineOperation* doOp = new mitk::LineOperation(OpNEWCELL, m_CurrentCellId);
		  if (m_UndoEnabled)
		  {
			  LineOperation* undoOp = new mitk::LineOperation(OpDELETECELL, m_CurrentCellId);
			  OperationEvent *operationEvent = new OperationEvent(mesh, doOp, undoOp);
			  m_UndoController->SetOperationEvent(operationEvent);
		  }
      mesh->ExecuteOperation(doOp);
    }
    ok = true;
    break;
  case AcCHECKLINE:
    //check, if a line is hit
    {
      mitk::PositionEvent const  *posEvent = dynamic_cast <const mitk::PositionEvent *> (stateEvent->GetEvent());
			if (posEvent == NULL)
        return false;

      //converting from Point3D to itk::Point
      mitk::Point3D worldPoint = posEvent->GetWorldPosition();

      //searching for a point
      unsigned long lineId = 0;
      unsigned long cellId = 0;
      int PRECISION = 1;
      mitk::IntProperty *precision = dynamic_cast<IntProperty*>(action->GetProperty("PRECISION"));
      if (precision != NULL)
      {
        PRECISION = precision->GetValue();
      }

      if(mesh->SearchLine(worldPoint, PRECISION, lineId, cellId))//line found
      {
        m_CurrentCellId = cellId;
        mitk::StateEvent* newStateEvent = new mitk::StateEvent(EIDYES, stateEvent->GetEvent());
        this->HandleEvent( newStateEvent );
        ok = true;
      }
      else
		  {
			  //new Event with information NO
        mitk::StateEvent* newStateEvent = new mitk::StateEvent(EIDNO, stateEvent->GetEvent());
        this->HandleEvent( newStateEvent );
			  ok = true;
			}
    }
    break;
  case AcCHECKBOUNDINGBOX:
    //check if the MousePosition lies inside the BoundingBox of the current Cell
    {
      mitk::PositionEvent const  *posEvent = dynamic_cast <const mitk::PositionEvent *> (stateEvent->GetEvent());
  		if (posEvent == NULL)
        return false;

      mitk::Point3D worldPoint = posEvent->GetWorldPosition();

      //Axis-aligned bounding box(AABB)
      mitk::Mesh::DataType::BoundingBoxPointer aABB = mesh->GetBoundingBoxFromCell(m_CurrentCellId);
      if (aABB.IsNull())
        return false;

      //check if the given point lies inside the boundingbox
      if (aABB->IsInside(worldPoint))
      {
        mitk::StateEvent* newStateEvent = new mitk::StateEvent(EIDYES, stateEvent->GetEvent());
        this->HandleEvent( newStateEvent );

      }
      else
      {
        mitk::StateEvent* newStateEvent = new mitk::StateEvent(EIDNO, stateEvent->GetEvent());
        this->HandleEvent(newStateEvent );
      }
    }
    ok = true;
    break;
  case AcCHECKOBJECT:
    {
      //picking if this object is hit. then set the m_CurrentCellId Variable
      //this object is hit, if the transmitted position of the event is hitting a point or a line of that cell
      mitk::PositionEvent const  *posEvent = dynamic_cast <const mitk::PositionEvent *> (stateEvent->GetEvent());
  		if (posEvent == NULL)
        return false;

		//bool hit = true; /* \todo remove line */
      //var's for EvaluatePosition
      mitk::Point3D point = posEvent->GetWorldPosition();
      unsigned long cellId = 0;

      int precision = 5;
      mitk::IntProperty *precisionProperty = dynamic_cast<IntProperty*>(action->GetProperty("PRECISION"));
      if (precisionProperty != NULL)
      {
        precision = precisionProperty->GetValue();
      }

      //check wheather the mesh is hit.
      if (mesh->EvaluatePosition(point, cellId, precision))
      {
        m_CurrentCellId = cellId;
        mitk::StateEvent* newStateEvent = new mitk::StateEvent(EIDYES, stateEvent->GetEvent());
        this->HandleEvent( newStateEvent );

      }
      else
      {
        m_CurrentCellId = 0;
        mitk::StateEvent* newStateEvent = new mitk::StateEvent(EIDNO, stateEvent->GetEvent());
        this->HandleEvent(newStateEvent );
      }
    }
    ok = true;
    break;
  case AcSELECTCELL:
    {
      LineOperation* lineDoOp = new mitk::LineOperation(OpSELECTCELL, m_CurrentCellId);
		  if (m_UndoEnabled)
		  {
		  	LineOperation* lineUndoOp = new mitk::LineOperation(OpDESELECTCELL, m_CurrentCellId);
			  OperationEvent *operationEvent = new OperationEvent(mesh, lineDoOp, lineUndoOp);
			  m_UndoController->SetOperationEvent(operationEvent);
		  }
      mesh->ExecuteOperation(lineDoOp );
    }
    ok = true;
    break;
  case AcDESELECTCELL:
    {
      //if number of cell is >0
      if (mesh->GetNumberOfCells()>0)
      {
        LineOperation* lineDoOp = new mitk::LineOperation(OpDESELECTCELL, m_CurrentCellId);
		    if (m_UndoEnabled)
		    {
		  	  LineOperation* lineUndoOp = new mitk::LineOperation(OpSELECTCELL, m_CurrentCellId);
			    OperationEvent *operationEvent = new OperationEvent(mesh, lineDoOp, lineUndoOp);
			    m_UndoController->SetOperationEvent(operationEvent);
		    }
        mesh->ExecuteOperation(lineDoOp );
      }
    }
    ok = true;
    break;
  case AcINITMOVEMENT:
    //prepare everything for movement of one cell
    {
      mitk::PositionEvent const  *posEvent = dynamic_cast <const mitk::PositionEvent *> (stateEvent->GetEvent());
		  if (posEvent == NULL)
        return false;

      //start of the Movement is stored to calculate the undoCoordinate in FinishMovement
      m_MovementStart = posEvent->GetWorldPosition();
      m_OldPoint = m_MovementStart;
    }
    ok = true;
    break;
  case AcMOVE:
    //move the cell without undo
    {
      mitk::PositionEvent const  *posEvent = dynamic_cast <const mitk::PositionEvent *> (stateEvent->GetEvent());
	  	if (posEvent == NULL)
        return false;

      mitk::Point3D newPoint = posEvent->GetWorldPosition();

      //calculate a vector between the oldPoint and the newPoint
      Vector3D vector = newPoint - m_OldPoint;

      CellOperation* doOp = new mitk::CellOperation(OpMOVECELL, m_CurrentCellId, vector);

      m_OldPoint = newPoint;

      //execute the Operation
      //here no undo is stored. only the start and the end is stored for undo.
		  mesh->ExecuteOperation(doOp);
    }
    ok = true;
    break;
  case AcFINISHMOVEMENT:
    //move the cell to the final position and send undo-information
    {
      mitk::PositionEvent const *posEvent = dynamic_cast <const mitk::PositionEvent *> (stateEvent->GetEvent());
		  if (posEvent == NULL)
        return false;

      //finish the movement:
      // set undo-information and move it to the last position.
      mitk::Point3D newPoint = posEvent->GetWorldPosition();

      Vector3D vector = newPoint - m_OldPoint;

      CellOperation* doOp = new mitk::CellOperation(OpMOVECELL, m_CurrentCellId, vector);
	    if ( m_UndoEnabled )
      {
        Vector3D vectorBack = m_MovementStart - newPoint;
        CellOperation* undoOp = new mitk::CellOperation(OpMOVECELL, m_CurrentCellId, vectorBack);
        OperationEvent *operationEvent = new OperationEvent(m_DataTreeNode->GetData(), doOp, undoOp);
        m_UndoController->SetOperationEvent(operationEvent);
      }
		  //execute the Operation
		  m_DataTreeNode->GetData()->ExecuteOperation(doOp);
    }
    ok = true;
    break;
  case AcREMOVE:
    ok = true;
    break;
  default:
    return Superclass::ExecuteAction(action, stateEvent);
  }
  return ok;
}
<|endoftext|>


<commit_before>/*
 * ModSecurity, http://www.modsecurity.org/
 * Copyright (c) 2015 Trustwave Holdings, Inc. (http://www.trustwave.com/)
 *
 * 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
 *
 * If any of the files related to licensing are missing or if you have any
 * other questions related to licensing please contact Trustwave Holdings, Inc.
 * directly using the email address security@modsecurity.org.
 *
 */

#include "src/operators/rx.h"

#include <string>
#include <list>

#include "src/operators/operator.h"
#include "src/macro_expansion.h"

namespace modsecurity {
namespace operators {

bool Rx::evaluate(Transaction *transaction, const std::string& input) {
    SMatch match;

    if (m_param.empty()) {
        return true;
    }

    if (regex_search(input, &match, *m_re) && match.size() >= 1) {
        if (transaction) {
            transaction->m_matched.push_back(match.match);
        }
        return true;
    }

    return false;
}

}  // namespace operators
}  // namespace modsecurity
<commit_msg>Changes operator rx to use regexp::searchAll<commit_after>/*
 * ModSecurity, http://www.modsecurity.org/
 * Copyright (c) 2015 Trustwave Holdings, Inc. (http://www.trustwave.com/)
 *
 * 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
 *
 * If any of the files related to licensing are missing or if you have any
 * other questions related to licensing please contact Trustwave Holdings, Inc.
 * directly using the email address security@modsecurity.org.
 *
 */

#include "src/operators/rx.h"

#include <string>
#include <list>

#include "src/operators/operator.h"
#include "src/macro_expansion.h"

namespace modsecurity {
namespace operators {

bool Rx::evaluate(Transaction *transaction, const std::string& input) {
    SMatch match;
    std::list<SMatch> matches;

    if (m_param.empty()) {
        return true;
    }

    matches = m_re->searchAll(input);
    for (const SMatch& a : matches) {
        if (transaction) {
            transaction->m_matched.push_back(a.match);
            transaction->debug(7, "Added regex subexpression: " + a.match);
        }
    }

    if (matches.size() > 0) {
        return true;
    }

    return false;
}

}  // namespace operators
}  // namespace modsecurity
<|endoftext|>


<commit_before>/***********************************************************************************************************************
 **
 ** Copyright (c) 2011, 2015 ETH Zurich
 ** All rights reserved.
 **
 ** Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
 ** following conditions are met:
 **
 **    * Redistributions of source code must retain the above copyright notice, this list of conditions and the
 **      following disclaimer.
 **    * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
 **      following disclaimer in the documentation and/or other materials provided with the distribution.
 **    * Neither the name of the ETH Zurich nor the names of its contributors may be used to endorse or promote products
 **      derived from this software without specific prior written permission.
 **
 **
 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 ** INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 ** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 ** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 ** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 **
 **********************************************************************************************************************/

#include "CodeUnitPart.h"
#include "CodeUnit.h"

#include "Export/src/tree/CompositeFragment.h"
#include "OOModel/src/allOOModelNodes.h"
#include "OOModel/src/types/ClassType.h"
#include "OOModel/src/types/PointerType.h"

namespace CppExport {

CodeUnitPart::CodeUnitPart(CodeUnit* parent) : parent_{parent} {}

bool CodeUnitPart::isSourceFragmentEmpty() const
{
	if (!sourceFragment_) return true;

	QList<Export::SourceFragment*> workList{sourceFragment_};
	while (!workList.empty())
	{
		auto current = workList.takeLast();
		if (dynamic_cast<Export::TextFragment*>(current))
			return false;
		else if (auto compositeFragment = dynamic_cast<Export::CompositeFragment*>(current))
			workList << compositeFragment->fragments();
	}
	return true;
}

void CodeUnitPart::setSourceFragment(Export::SourceFragment* sourceFragment)
{
	sourceFragment_ = sourceFragment;

	// calculate name and reference nodes
	nameNodes_.clear();
	referenceNodes_.clear();
	QList<Export::SourceFragment*> workStack{sourceFragment};
	while (!workStack.empty())
	{
		auto fragment = workStack.takeLast();

		auto node = fragment->node();
		if (node->definesSymbol())
			nameNodes_.insert(node);
		else if (auto reference = DCast<OOModel::ReferenceExpression>(node))
			referenceNodes_.insert(reference);

		if (auto compositeFragment = dynamic_cast<Export::CompositeFragment*>(fragment))
			workStack << compositeFragment->fragments();
	}

	// calculate targets
	softTargets_.clear();
	hardTargets_.clear();
	for (auto reference : referenceNodes_)
		if (auto target = fixedTarget(reference))
		{
			if (isNameOnlyDependency(reference))
				softTargets_.insert(target);
			else
			{
				hardTargets_.insert(target);

				// member access
				auto parentMethodCall = DCast<OOModel::MethodCallExpression>(reference->parent());
				if (parentMethodCall || DCast<OOModel::ReferenceExpression>(reference->parent()))
				{
					const OOModel::Type* type{};

					if (parentMethodCall && parentMethodCall->callee()->isAncestorOf(reference))
						type = parentMethodCall->type();
					else
						type = reference->type();

					if (auto pointerType = dynamic_cast<const OOModel::PointerType*>(type))
						type = pointerType->baseType();

					if (auto classType = dynamic_cast<const OOModel::ClassType*>(type))
						hardTargets_.insert(classType->classDefinition());
				}
			}
		}
}

bool CodeUnitPart::isNameOnlyDependency(OOModel::ReferenceExpression* reference)
{
	auto parent = reference->parent();
	Q_ASSERT(parent);

	if (reference->firstAncestorOfType<OOModel::MethodCallExpression>()) return false;

	if (DCast<OOModel::TypeQualifierExpression>(parent)) parent = parent->parent();
	if (!DCast<OOModel::PointerTypeExpression>(parent) && !DCast<OOModel::ReferenceTypeExpression>(parent)) return false;
	if (auto tryCatchFinally = reference->firstAncestorOfType<OOModel::TryCatchFinallyStatement>())
		if (tryCatchFinally->catchClauses()->isAncestorOf(reference)) return false;

	return true;
}

Model::Node* CodeUnitPart::fixedTarget(OOModel::ReferenceExpression* referenceExpression)
{
	if (auto target = referenceExpression->target()) return target;

	// insert custom resolution adjustments here

	return nullptr;
}

void CodeUnitPart::calculateDependencies(QList<CodeUnit*>& allUnits)
{
	dependencies_.clear();
	if (this == parent()->sourcePart())
		dependencies_.insert(parent()->headerPart());

	for (auto target : hardTargets_)
		for (auto unit : allUnits)
			if (unit->headerPart() != this && unit->headerPart()->nameNodes().contains(target))
					dependencies_.insert(unit->headerPart());
}

QSet<CodeUnitPart*> CodeUnitPart::sourceDependencies(QList<CodeUnit*> units)
{
	QSet<CodeUnitPart*> result;
	for (auto referenceNode : referenceNodes_)
		if (auto target = referenceNode->target())
			for (auto unit : units)
				if (unit->sourcePart() != this &&
					 unit->sourcePart()->nameNodes().contains(target))
						result.insert(unit->sourcePart());
	return result;
}

}
<commit_msg>improve member access dependency code<commit_after>/***********************************************************************************************************************
 **
 ** Copyright (c) 2011, 2015 ETH Zurich
 ** All rights reserved.
 **
 ** Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
 ** following conditions are met:
 **
 **    * Redistributions of source code must retain the above copyright notice, this list of conditions and the
 **      following disclaimer.
 **    * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
 **      following disclaimer in the documentation and/or other materials provided with the distribution.
 **    * Neither the name of the ETH Zurich nor the names of its contributors may be used to endorse or promote products
 **      derived from this software without specific prior written permission.
 **
 **
 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 ** INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 ** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 ** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 ** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 **
 **********************************************************************************************************************/

#include "CodeUnitPart.h"
#include "CodeUnit.h"

#include "Export/src/tree/CompositeFragment.h"
#include "OOModel/src/allOOModelNodes.h"
#include "OOModel/src/types/ClassType.h"
#include "OOModel/src/types/PointerType.h"
#include "OOModel/src/types/ReferenceType.h"

namespace CppExport {

CodeUnitPart::CodeUnitPart(CodeUnit* parent) : parent_{parent} {}

bool CodeUnitPart::isSourceFragmentEmpty() const
{
	if (!sourceFragment_) return true;

	QList<Export::SourceFragment*> workList{sourceFragment_};
	while (!workList.empty())
	{
		auto current = workList.takeLast();
		if (dynamic_cast<Export::TextFragment*>(current))
			return false;
		else if (auto compositeFragment = dynamic_cast<Export::CompositeFragment*>(current))
			workList << compositeFragment->fragments();
	}
	return true;
}

void CodeUnitPart::setSourceFragment(Export::SourceFragment* sourceFragment)
{
	sourceFragment_ = sourceFragment;

	// calculate name and reference nodes
	nameNodes_.clear();
	referenceNodes_.clear();
	QList<Export::SourceFragment*> workStack{sourceFragment};
	while (!workStack.empty())
	{
		auto fragment = workStack.takeLast();

		auto node = fragment->node();
		if (node->definesSymbol())
			nameNodes_.insert(node);
		else if (auto reference = DCast<OOModel::ReferenceExpression>(node))
			referenceNodes_.insert(reference);

		if (auto compositeFragment = dynamic_cast<Export::CompositeFragment*>(fragment))
			workStack << compositeFragment->fragments();
	}

	// calculate targets
	softTargets_.clear();
	hardTargets_.clear();
	for (auto reference : referenceNodes_)
		if (auto target = fixedTarget(reference))
		{
			if (isNameOnlyDependency(reference))
				softTargets_.insert(target);
			else
			{
				hardTargets_.insert(target);

				// member access
				auto parentMethodCall = DCast<OOModel::MethodCallExpression>(reference->parent());
				if (parentMethodCall || DCast<OOModel::ReferenceExpression>(reference->parent()))
				{
					const OOModel::Type* baseType{};
					if (parentMethodCall && parentMethodCall->callee()->isAncestorOf(reference))
						baseType = parentMethodCall->type();
					else
						baseType = reference->type();

					auto finalType = baseType;
					if (auto pointerType = dynamic_cast<const OOModel::PointerType*>(baseType))
						finalType = pointerType->baseType();
					else if (auto referenceType = dynamic_cast<const OOModel::ReferenceType*>(baseType))
						finalType = referenceType->baseType();

					if (auto classType = dynamic_cast<const OOModel::ClassType*>(finalType))
						hardTargets_.insert(classType->classDefinition());

					SAFE_DELETE(baseType);
				}
			}
		}
}

bool CodeUnitPart::isNameOnlyDependency(OOModel::ReferenceExpression* reference)
{
	auto parent = reference->parent();
	Q_ASSERT(parent);

	if (reference->firstAncestorOfType<OOModel::MethodCallExpression>()) return false;

	if (DCast<OOModel::TypeQualifierExpression>(parent)) parent = parent->parent();
	if (!DCast<OOModel::PointerTypeExpression>(parent) && !DCast<OOModel::ReferenceTypeExpression>(parent)) return false;
	if (auto tryCatchFinally = reference->firstAncestorOfType<OOModel::TryCatchFinallyStatement>())
		if (tryCatchFinally->catchClauses()->isAncestorOf(reference)) return false;

	return true;
}

Model::Node* CodeUnitPart::fixedTarget(OOModel::ReferenceExpression* referenceExpression)
{
	if (auto target = referenceExpression->target()) return target;

	// insert custom resolution adjustments here

	return nullptr;
}

void CodeUnitPart::calculateDependencies(QList<CodeUnit*>& allUnits)
{
	dependencies_.clear();
	if (this == parent()->sourcePart())
		dependencies_.insert(parent()->headerPart());

	for (auto target : hardTargets_)
		for (auto unit : allUnits)
			if (unit->headerPart() != this && unit->headerPart()->nameNodes().contains(target))
					dependencies_.insert(unit->headerPart());
}

QSet<CodeUnitPart*> CodeUnitPart::sourceDependencies(QList<CodeUnit*> units)
{
	QSet<CodeUnitPart*> result;
	for (auto referenceNode : referenceNodes_)
		if (auto target = referenceNode->target())
			for (auto unit : units)
				if (unit->sourcePart() != this &&
					 unit->sourcePart()->nameNodes().contains(target))
						result.insert(unit->sourcePart());
	return result;
}

}
<|endoftext|>