<commit_before>// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/base/x509_certificate.h"

// Work around https://bugzilla.mozilla.org/show_bug.cgi?id=455424
// until NSS 3.12.2 comes out and we update to it.
#define Lock FOO_NSS_Lock
#include <cert.h>
#include <prtime.h>
#include <secder.h>
#include <sechash.h>
#undef Lock

#include "base/logging.h"
#include "base/pickle.h"
#include "base/time.h"
#include "base/nss_init.h"
#include "net/base/net_errors.h"

namespace net {

namespace {

// TODO(port): Implement this more simply, and put it in the right place
base::Time PRTimeToBaseTime(PRTime prtime) {
  PRExplodedTime prxtime;
  PR_ExplodeTime(prtime, PR_GMTParameters, &prxtime);

  base::Time::Exploded exploded;
  exploded.year         = prxtime.tm_year;
  exploded.month        = prxtime.tm_month + 1;
  exploded.day_of_week  = prxtime.tm_wday;
  exploded.day_of_month = prxtime.tm_mday;
  exploded.hour         = prxtime.tm_hour;
  exploded.minute       = prxtime.tm_min;
  exploded.second       = prxtime.tm_sec;
  exploded.millisecond  = prxtime.tm_usec / 1000;

  return base::Time::FromUTCExploded(exploded);
}

void ParsePrincipal(SECItem* der_name,
                    X509Certificate::Principal* principal) {

  CERTName name;
  PRArenaPool* arena = NULL;

  arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
  DCHECK(arena != NULL);
  if (arena == NULL)
    return;

  // TODO(dkegel): is CERT_NameTemplate what we always want here?
  SECStatus rv;
  rv = SEC_QuickDERDecodeItem(arena, &name, CERT_NameTemplate, der_name);
  DCHECK(rv == SECSuccess);
  if ( rv != SECSuccess ) {
    PORT_FreeArena(arena, PR_FALSE);
    return;
  }

  std::vector<std::string> common_names, locality_names, state_names,
      country_names;

  // TODO(jcampan): add business_category and serial_number.
  static const SECOidTag kOIDs[] = {
      SEC_OID_AVA_COMMON_NAME,
      SEC_OID_AVA_LOCALITY,
      SEC_OID_AVA_STATE_OR_PROVINCE,
      SEC_OID_AVA_COUNTRY_NAME,
      SEC_OID_AVA_STREET_ADDRESS,
      SEC_OID_AVA_ORGANIZATION_NAME,
      SEC_OID_AVA_ORGANIZATIONAL_UNIT_NAME,
      SEC_OID_AVA_DC };

  std::vector<std::string>* values[] = {
      &common_names, &locality_names,
      &state_names, &country_names,
      &principal->street_addresses,
      &principal->organization_names,
      &principal->organization_unit_names,
      &principal->domain_components };
  DCHECK(arraysize(kOIDs) == arraysize(values));

  CERTRDN** rdns = name.rdns;
  for (size_t rdn = 0; rdns[rdn]; ++rdn) {
    CERTAVA** avas = rdns[rdn]->avas;
    for (size_t pair = 0; avas[pair] != 0; ++pair) {
      SECOidTag tag = CERT_GetAVATag(avas[pair]);
      for (size_t oid = 0; oid < arraysize(kOIDs); ++oid) {
        if (kOIDs[oid] == tag) {
          SECItem* decode_item = CERT_DecodeAVAValue(&avas[pair]->value);
          if (!decode_item)
            break;
          std::string value(reinterpret_cast<char*>(decode_item->data),
                            decode_item->len);
          values[oid]->push_back(value);
          SECITEM_FreeItem(decode_item, PR_TRUE);
          break;
        }
      }
    }
  }

  // We don't expect to have more than one CN, L, S, and C.
  std::vector<std::string>* single_value_lists[4] = {
      &common_names, &locality_names, &state_names, &country_names };
  std::string* single_values[4] = {
      &principal->common_name, &principal->locality_name,
      &principal->state_or_province_name, &principal->country_name };
  for (size_t i = 0; i < arraysize(single_value_lists); ++i) {
    DCHECK(single_value_lists[i]->size() <= 1);
    if (single_value_lists[i]->size() > 0)
      *(single_values[i]) = (*(single_value_lists[i]))[0];
  }
  PORT_FreeArena(arena, PR_FALSE);
}

void ParseDate(SECItem* der_date, base::Time* result) {
  PRTime prtime;
  SECStatus rv = DER_DecodeTimeChoice(&prtime, der_date);
  DCHECK(rv == SECSuccess);
  *result = PRTimeToBaseTime(prtime);
}

void GetCertSubjectAltNamesOfType(X509Certificate::OSCertHandle cert_handle,
                                  CERTGeneralNameType name_type,
                                  std::vector<std::string>* result) {

  SECItem alt_name;
  SECStatus rv = CERT_FindCertExtension(cert_handle,
      SEC_OID_X509_SUBJECT_ALT_NAME, &alt_name);
  if (rv != SECSuccess)
    return;

  PRArenaPool* arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
  DCHECK(arena != NULL);

  CERTGeneralName* alt_name_list;
  alt_name_list = CERT_DecodeAltNameExtension(arena, &alt_name);

  CERTGeneralName* name = alt_name_list;
  while (name) {
    // For future extension: We're assuming that these values are of types
    // RFC822Name, DNSName or URI.  See the mac code for notes.
    DCHECK(name->type == certRFC822Name ||
           name->type == certDNSName ||
           name->type == certURI);
    if (name->type == name_type) {
      unsigned char* p = name->name.other.data;
      int len = name->name.other.len;
      std::string value = std::string(reinterpret_cast<char*>(p), len);
      result->push_back(value);
    }
    name = CERT_GetNextGeneralName(name);
    if (name == alt_name_list)
      break;
  }
  PORT_FreeArena(arena, PR_FALSE);
  PORT_Free(alt_name.data);
}

} // namespace

void X509Certificate::Initialize() {
  ParsePrincipal(&cert_handle_->derSubject, &subject_);
  ParsePrincipal(&cert_handle_->derIssuer, &issuer_);

  ParseDate(&cert_handle_->validity.notBefore, &valid_start_);
  ParseDate(&cert_handle_->validity.notAfter, &valid_expiry_);

  fingerprint_ = CalculateFingerprint(cert_handle_);

  // Store the certificate in the cache in case we need it later.
  X509Certificate::Cache::GetInstance()->Insert(this);
}

// static
X509Certificate* X509Certificate::CreateFromPickle(const Pickle& pickle,
                                                   void** pickle_iter) {
  const char* data;
  int length;
  if (!pickle.ReadData(pickle_iter, &data, &length))
    return NULL;

  return CreateFromBytes(data, length);
}

void X509Certificate::Persist(Pickle* pickle) {
  pickle->WriteData(reinterpret_cast<const char*>(cert_handle_->derCert.data),
                    cert_handle_->derCert.len);
}

void X509Certificate::GetDNSNames(std::vector<std::string>* dns_names) const {
  dns_names->clear();

  // Compare with CERT_VerifyCertName().
  GetCertSubjectAltNamesOfType(cert_handle_, certDNSName, dns_names);

  // TODO(port): suppress nss's support of the obsolete extension
  //  SEC_OID_NS_CERT_EXT_SSL_SERVER_NAME
  // by providing our own authCertificate callback.

  if (dns_names->empty())
    dns_names->push_back(subject_.common_name);
}

bool X509Certificate::HasExpired() const {
  NOTIMPLEMENTED();
  return false;
}

int X509Certificate::Verify(const std::string& hostname,
                            bool rev_checking_enabled,
                            CertVerifyResult* verify_result) const {
  NOTIMPLEMENTED();
  return ERR_NOT_IMPLEMENTED;
}

// static
X509Certificate::OSCertHandle X509Certificate::CreateOSCertHandleFromBytes(
    const char* data, int length) {
  base::EnsureNSSInit();

  SECItem der_cert;
  der_cert.data = reinterpret_cast<unsigned char*>(const_cast<char*>(data));
  der_cert.len = length;
  return CERT_NewTempCertificate(CERT_GetDefaultCertDB(), &der_cert,
                                 NULL, PR_FALSE, PR_TRUE);
}

// static
void X509Certificate::FreeOSCertHandle(OSCertHandle cert_handle) {
  CERT_DestroyCertificate(cert_handle);
}

// static
X509Certificate::Fingerprint X509Certificate::CalculateFingerprint(
    OSCertHandle cert) {
  Fingerprint sha1;
  memset(sha1.data, 0, sizeof(sha1.data));

  DCHECK(NULL != cert->derCert.data);
  DCHECK(0 != cert->derCert.len);

  SECStatus rv = HASH_HashBuf(HASH_AlgSHA1, sha1.data,
                              cert->derCert.data, cert->derCert.len);
  DCHECK(rv == SECSuccess);

  return sha1;
}

// TODO(port): Implement properly on Linux.
bool X509Certificate::IsEV(int status) const {
  NOTIMPLEMENTED();
  return false;
}

}  // namespace net
<commit_msg>Remove another NOTIMPLEMENTED<commit_after>// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/base/x509_certificate.h"

// Work around https://bugzilla.mozilla.org/show_bug.cgi?id=455424
// until NSS 3.12.2 comes out and we update to it.
#define Lock FOO_NSS_Lock
#include <cert.h>
#include <prtime.h>
#include <secder.h>
#include <sechash.h>
#undef Lock

#include "base/logging.h"
#include "base/pickle.h"
#include "base/time.h"
#include "base/nss_init.h"
#include "net/base/net_errors.h"

namespace net {

namespace {

// TODO(port): Implement this more simply, and put it in the right place
base::Time PRTimeToBaseTime(PRTime prtime) {
  PRExplodedTime prxtime;
  PR_ExplodeTime(prtime, PR_GMTParameters, &prxtime);

  base::Time::Exploded exploded;
  exploded.year         = prxtime.tm_year;
  exploded.month        = prxtime.tm_month + 1;
  exploded.day_of_week  = prxtime.tm_wday;
  exploded.day_of_month = prxtime.tm_mday;
  exploded.hour         = prxtime.tm_hour;
  exploded.minute       = prxtime.tm_min;
  exploded.second       = prxtime.tm_sec;
  exploded.millisecond  = prxtime.tm_usec / 1000;

  return base::Time::FromUTCExploded(exploded);
}

void ParsePrincipal(SECItem* der_name,
                    X509Certificate::Principal* principal) {

  CERTName name;
  PRArenaPool* arena = NULL;

  arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
  DCHECK(arena != NULL);
  if (arena == NULL)
    return;

  // TODO(dkegel): is CERT_NameTemplate what we always want here?
  SECStatus rv;
  rv = SEC_QuickDERDecodeItem(arena, &name, CERT_NameTemplate, der_name);
  DCHECK(rv == SECSuccess);
  if ( rv != SECSuccess ) {
    PORT_FreeArena(arena, PR_FALSE);
    return;
  }

  std::vector<std::string> common_names, locality_names, state_names,
      country_names;

  // TODO(jcampan): add business_category and serial_number.
  static const SECOidTag kOIDs[] = {
      SEC_OID_AVA_COMMON_NAME,
      SEC_OID_AVA_LOCALITY,
      SEC_OID_AVA_STATE_OR_PROVINCE,
      SEC_OID_AVA_COUNTRY_NAME,
      SEC_OID_AVA_STREET_ADDRESS,
      SEC_OID_AVA_ORGANIZATION_NAME,
      SEC_OID_AVA_ORGANIZATIONAL_UNIT_NAME,
      SEC_OID_AVA_DC };

  std::vector<std::string>* values[] = {
      &common_names, &locality_names,
      &state_names, &country_names,
      &principal->street_addresses,
      &principal->organization_names,
      &principal->organization_unit_names,
      &principal->domain_components };
  DCHECK(arraysize(kOIDs) == arraysize(values));

  CERTRDN** rdns = name.rdns;
  for (size_t rdn = 0; rdns[rdn]; ++rdn) {
    CERTAVA** avas = rdns[rdn]->avas;
    for (size_t pair = 0; avas[pair] != 0; ++pair) {
      SECOidTag tag = CERT_GetAVATag(avas[pair]);
      for (size_t oid = 0; oid < arraysize(kOIDs); ++oid) {
        if (kOIDs[oid] == tag) {
          SECItem* decode_item = CERT_DecodeAVAValue(&avas[pair]->value);
          if (!decode_item)
            break;
          std::string value(reinterpret_cast<char*>(decode_item->data),
                            decode_item->len);
          values[oid]->push_back(value);
          SECITEM_FreeItem(decode_item, PR_TRUE);
          break;
        }
      }
    }
  }

  // We don't expect to have more than one CN, L, S, and C.
  std::vector<std::string>* single_value_lists[4] = {
      &common_names, &locality_names, &state_names, &country_names };
  std::string* single_values[4] = {
      &principal->common_name, &principal->locality_name,
      &principal->state_or_province_name, &principal->country_name };
  for (size_t i = 0; i < arraysize(single_value_lists); ++i) {
    DCHECK(single_value_lists[i]->size() <= 1);
    if (single_value_lists[i]->size() > 0)
      *(single_values[i]) = (*(single_value_lists[i]))[0];
  }
  PORT_FreeArena(arena, PR_FALSE);
}

void ParseDate(SECItem* der_date, base::Time* result) {
  PRTime prtime;
  SECStatus rv = DER_DecodeTimeChoice(&prtime, der_date);
  DCHECK(rv == SECSuccess);
  *result = PRTimeToBaseTime(prtime);
}

void GetCertSubjectAltNamesOfType(X509Certificate::OSCertHandle cert_handle,
                                  CERTGeneralNameType name_type,
                                  std::vector<std::string>* result) {

  SECItem alt_name;
  SECStatus rv = CERT_FindCertExtension(cert_handle,
      SEC_OID_X509_SUBJECT_ALT_NAME, &alt_name);
  if (rv != SECSuccess)
    return;

  PRArenaPool* arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
  DCHECK(arena != NULL);

  CERTGeneralName* alt_name_list;
  alt_name_list = CERT_DecodeAltNameExtension(arena, &alt_name);

  CERTGeneralName* name = alt_name_list;
  while (name) {
    // For future extension: We're assuming that these values are of types
    // RFC822Name, DNSName or URI.  See the mac code for notes.
    DCHECK(name->type == certRFC822Name ||
           name->type == certDNSName ||
           name->type == certURI);
    if (name->type == name_type) {
      unsigned char* p = name->name.other.data;
      int len = name->name.other.len;
      std::string value = std::string(reinterpret_cast<char*>(p), len);
      result->push_back(value);
    }
    name = CERT_GetNextGeneralName(name);
    if (name == alt_name_list)
      break;
  }
  PORT_FreeArena(arena, PR_FALSE);
  PORT_Free(alt_name.data);
}

} // namespace

void X509Certificate::Initialize() {
  ParsePrincipal(&cert_handle_->derSubject, &subject_);
  ParsePrincipal(&cert_handle_->derIssuer, &issuer_);

  ParseDate(&cert_handle_->validity.notBefore, &valid_start_);
  ParseDate(&cert_handle_->validity.notAfter, &valid_expiry_);

  fingerprint_ = CalculateFingerprint(cert_handle_);

  // Store the certificate in the cache in case we need it later.
  X509Certificate::Cache::GetInstance()->Insert(this);
}

// static
X509Certificate* X509Certificate::CreateFromPickle(const Pickle& pickle,
                                                   void** pickle_iter) {
  const char* data;
  int length;
  if (!pickle.ReadData(pickle_iter, &data, &length))
    return NULL;

  return CreateFromBytes(data, length);
}

void X509Certificate::Persist(Pickle* pickle) {
  pickle->WriteData(reinterpret_cast<const char*>(cert_handle_->derCert.data),
                    cert_handle_->derCert.len);
}

void X509Certificate::GetDNSNames(std::vector<std::string>* dns_names) const {
  dns_names->clear();

  // Compare with CERT_VerifyCertName().
  GetCertSubjectAltNamesOfType(cert_handle_, certDNSName, dns_names);

  // TODO(port): suppress nss's support of the obsolete extension
  //  SEC_OID_NS_CERT_EXT_SSL_SERVER_NAME
  // by providing our own authCertificate callback.

  if (dns_names->empty())
    dns_names->push_back(subject_.common_name);
}

bool X509Certificate::HasExpired() const {
  NOTIMPLEMENTED();
  return false;
}

int X509Certificate::Verify(const std::string& hostname,
                            bool rev_checking_enabled,
                            CertVerifyResult* verify_result) const {
  NOTIMPLEMENTED();
  return ERR_NOT_IMPLEMENTED;
}

// static
X509Certificate::OSCertHandle X509Certificate::CreateOSCertHandleFromBytes(
    const char* data, int length) {
  base::EnsureNSSInit();

  SECItem der_cert;
  der_cert.data = reinterpret_cast<unsigned char*>(const_cast<char*>(data));
  der_cert.len = length;
  return CERT_NewTempCertificate(CERT_GetDefaultCertDB(), &der_cert,
                                 NULL, PR_FALSE, PR_TRUE);
}

// static
void X509Certificate::FreeOSCertHandle(OSCertHandle cert_handle) {
  CERT_DestroyCertificate(cert_handle);
}

// static
X509Certificate::Fingerprint X509Certificate::CalculateFingerprint(
    OSCertHandle cert) {
  Fingerprint sha1;
  memset(sha1.data, 0, sizeof(sha1.data));

  DCHECK(NULL != cert->derCert.data);
  DCHECK(0 != cert->derCert.len);

  SECStatus rv = HASH_HashBuf(HASH_AlgSHA1, sha1.data,
                              cert->derCert.data, cert->derCert.len);
  DCHECK(rv == SECSuccess);

  return sha1;
}

// TODO(port): Implement properly on Linux.
bool X509Certificate::IsEV(int status) const {
  // http://code.google.com/p/chromium/issues/detail?id=10911
  return false;
}

}  // namespace net
<|endoftext|>


<commit_before>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/http/http_network_session.h"

#include <utility>

#include "base/logging.h"
#include "base/stl_util-inl.h"
#include "base/string_util.h"
#include "net/http/http_auth_handler_factory.h"
#include "net/http/url_security_manager.h"
#include "net/spdy/spdy_session_pool.h"

namespace net {

namespace {

// Total limit of sockets.
int g_max_sockets = 256;

// Default to allow up to 6 connections per host. Experiment and tuning may
// try other values (greater than 0).  Too large may cause many problems, such
// as home routers blocking the connections!?!?  See http://crbug.com/12066.
int g_max_sockets_per_group = 6;

// The max number of sockets to allow per proxy server.  This applies both to
// http and SOCKS proxies.  See http://crbug.com/12066 for details about proxy
// server connection limits.
int g_max_sockets_per_proxy_server = 15;

uint16 g_fixed_http_port = 0;
uint16 g_fixed_https_port = 0;

}  // namespace

HttpNetworkSession::HttpNetworkSession(
    NetworkChangeNotifier* network_change_notifier,
    HostResolver* host_resolver,
    ProxyService* proxy_service,
    ClientSocketFactory* client_socket_factory,
    SSLConfigService* ssl_config_service,
    SpdySessionPool* spdy_session_pool,
    HttpAuthHandlerFactory* http_auth_handler_factory)
    : network_change_notifier_(network_change_notifier),
      // TODO(vandebo) when we've completely converted to pools, the base TCP
      // pool name should get changed to TCP instead of Transport.
      tcp_pool_histograms_(new ClientSocketPoolHistograms("Transport")),
      http_proxy_pool_histograms_(new ClientSocketPoolHistograms("HTTPProxy")),
      tcp_for_socks_pool_histograms_(
          new ClientSocketPoolHistograms("TCPforSOCKS")),
      socks_pool_histograms_(new ClientSocketPoolHistograms("SOCK")),
      tcp_socket_pool_(new TCPClientSocketPool(
          g_max_sockets, g_max_sockets_per_group, tcp_pool_histograms_,
          host_resolver, client_socket_factory, network_change_notifier_)),
      socket_factory_(client_socket_factory),
      host_resolver_(host_resolver),
      proxy_service_(proxy_service),
      ssl_config_service_(ssl_config_service),
      spdy_session_pool_(spdy_session_pool),
      http_auth_handler_factory_(http_auth_handler_factory) {
  DCHECK(proxy_service);
  DCHECK(ssl_config_service);
}

HttpNetworkSession::~HttpNetworkSession() {
}

const scoped_refptr<TCPClientSocketPool>&
HttpNetworkSession::GetSocketPoolForHTTPProxy(const HostPortPair& http_proxy) {
  HTTPProxySocketPoolMap::const_iterator it =
      http_proxy_socket_pool_.find(http_proxy);
  if (it != http_proxy_socket_pool_.end())
    return it->second;

  std::pair<HTTPProxySocketPoolMap::iterator, bool> ret =
      http_proxy_socket_pool_.insert(
          std::make_pair(
              http_proxy,
              new TCPClientSocketPool(
                  g_max_sockets_per_proxy_server, g_max_sockets_per_group,
                  http_proxy_pool_histograms_, host_resolver_, socket_factory_,
                  network_change_notifier_)));

  return ret.first->second;
}

const scoped_refptr<SOCKSClientSocketPool>&
HttpNetworkSession::GetSocketPoolForSOCKSProxy(
    const HostPortPair& socks_proxy) {
  SOCKSSocketPoolMap::const_iterator it = socks_socket_pool_.find(socks_proxy);
  if (it != socks_socket_pool_.end())
    return it->second;

  std::pair<SOCKSSocketPoolMap::iterator, bool> ret =
      socks_socket_pool_.insert(
          std::make_pair(
              socks_proxy,
              new SOCKSClientSocketPool(
                  g_max_sockets_per_proxy_server, g_max_sockets_per_group,
                  socks_pool_histograms_, host_resolver_,
                  new TCPClientSocketPool(g_max_sockets_per_proxy_server,
                                          g_max_sockets_per_group,
                                          tcp_for_socks_pool_histograms_,
                                          host_resolver_, socket_factory_,
                                          network_change_notifier_),
                  network_change_notifier_)));

  return ret.first->second;
}

// static
void HttpNetworkSession::set_max_sockets_per_group(int socket_count) {
  DCHECK_LT(0, socket_count);
  // The following is a sanity check... but we should NEVER be near this value.
  DCHECK_GT(100, socket_count);
  g_max_sockets_per_group = socket_count;
}

// static
uint16 HttpNetworkSession::fixed_http_port() {
  return g_fixed_http_port;
}

// static
void HttpNetworkSession::set_fixed_http_port(uint16 port) {
  g_fixed_http_port = port;
}

// static
uint16 HttpNetworkSession::fixed_https_port() {
  return g_fixed_https_port;
}

// static
void HttpNetworkSession::set_fixed_https_port(uint16 port) {
  g_fixed_https_port = port;
}

void HttpNetworkSession::ReplaceTCPSocketPool() {
  tcp_socket_pool_ = new TCPClientSocketPool(g_max_sockets,
                                             g_max_sockets_per_group,
                                             tcp_pool_histograms_,
                                             host_resolver_,
                                             socket_factory_,
                                             network_change_notifier_);
}

}  //  namespace net
<commit_msg>Increase the socket limit for proxy servers to 32. BUG=44501<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/http/http_network_session.h"

#include <utility>

#include "base/logging.h"
#include "base/stl_util-inl.h"
#include "base/string_util.h"
#include "net/http/http_auth_handler_factory.h"
#include "net/http/url_security_manager.h"
#include "net/spdy/spdy_session_pool.h"

namespace net {

namespace {

// Total limit of sockets.
int g_max_sockets = 256;

// Default to allow up to 6 connections per host. Experiment and tuning may
// try other values (greater than 0).  Too large may cause many problems, such
// as home routers blocking the connections!?!?  See http://crbug.com/12066.
int g_max_sockets_per_group = 6;

// The max number of sockets to allow per proxy server.  This applies both to
// http and SOCKS proxies.  See http://crbug.com/12066 and
// http://crbug.com/44501 for details about proxy server connection limits.
int g_max_sockets_per_proxy_server = 32;

uint16 g_fixed_http_port = 0;
uint16 g_fixed_https_port = 0;

}  // namespace

HttpNetworkSession::HttpNetworkSession(
    NetworkChangeNotifier* network_change_notifier,
    HostResolver* host_resolver,
    ProxyService* proxy_service,
    ClientSocketFactory* client_socket_factory,
    SSLConfigService* ssl_config_service,
    SpdySessionPool* spdy_session_pool,
    HttpAuthHandlerFactory* http_auth_handler_factory)
    : network_change_notifier_(network_change_notifier),
      // TODO(vandebo) when we've completely converted to pools, the base TCP
      // pool name should get changed to TCP instead of Transport.
      tcp_pool_histograms_(new ClientSocketPoolHistograms("Transport")),
      http_proxy_pool_histograms_(new ClientSocketPoolHistograms("HTTPProxy")),
      tcp_for_socks_pool_histograms_(
          new ClientSocketPoolHistograms("TCPforSOCKS")),
      socks_pool_histograms_(new ClientSocketPoolHistograms("SOCK")),
      tcp_socket_pool_(new TCPClientSocketPool(
          g_max_sockets, g_max_sockets_per_group, tcp_pool_histograms_,
          host_resolver, client_socket_factory, network_change_notifier_)),
      socket_factory_(client_socket_factory),
      host_resolver_(host_resolver),
      proxy_service_(proxy_service),
      ssl_config_service_(ssl_config_service),
      spdy_session_pool_(spdy_session_pool),
      http_auth_handler_factory_(http_auth_handler_factory) {
  DCHECK(proxy_service);
  DCHECK(ssl_config_service);
}

HttpNetworkSession::~HttpNetworkSession() {
}

const scoped_refptr<TCPClientSocketPool>&
HttpNetworkSession::GetSocketPoolForHTTPProxy(const HostPortPair& http_proxy) {
  HTTPProxySocketPoolMap::const_iterator it =
      http_proxy_socket_pool_.find(http_proxy);
  if (it != http_proxy_socket_pool_.end())
    return it->second;

  std::pair<HTTPProxySocketPoolMap::iterator, bool> ret =
      http_proxy_socket_pool_.insert(
          std::make_pair(
              http_proxy,
              new TCPClientSocketPool(
                  g_max_sockets_per_proxy_server, g_max_sockets_per_group,
                  http_proxy_pool_histograms_, host_resolver_, socket_factory_,
                  network_change_notifier_)));

  return ret.first->second;
}

const scoped_refptr<SOCKSClientSocketPool>&
HttpNetworkSession::GetSocketPoolForSOCKSProxy(
    const HostPortPair& socks_proxy) {
  SOCKSSocketPoolMap::const_iterator it = socks_socket_pool_.find(socks_proxy);
  if (it != socks_socket_pool_.end())
    return it->second;

  std::pair<SOCKSSocketPoolMap::iterator, bool> ret =
      socks_socket_pool_.insert(
          std::make_pair(
              socks_proxy,
              new SOCKSClientSocketPool(
                  g_max_sockets_per_proxy_server, g_max_sockets_per_group,
                  socks_pool_histograms_, host_resolver_,
                  new TCPClientSocketPool(g_max_sockets_per_proxy_server,
                                          g_max_sockets_per_group,
                                          tcp_for_socks_pool_histograms_,
                                          host_resolver_, socket_factory_,
                                          network_change_notifier_),
                  network_change_notifier_)));

  return ret.first->second;
}

// static
void HttpNetworkSession::set_max_sockets_per_group(int socket_count) {
  DCHECK_LT(0, socket_count);
  // The following is a sanity check... but we should NEVER be near this value.
  DCHECK_GT(100, socket_count);
  g_max_sockets_per_group = socket_count;
}

// static
uint16 HttpNetworkSession::fixed_http_port() {
  return g_fixed_http_port;
}

// static
void HttpNetworkSession::set_fixed_http_port(uint16 port) {
  g_fixed_http_port = port;
}

// static
uint16 HttpNetworkSession::fixed_https_port() {
  return g_fixed_https_port;
}

// static
void HttpNetworkSession::set_fixed_https_port(uint16 port) {
  g_fixed_https_port = port;
}

void HttpNetworkSession::ReplaceTCPSocketPool() {
  tcp_socket_pool_ = new TCPClientSocketPool(g_max_sockets,
                                             g_max_sockets_per_group,
                                             tcp_pool_histograms_,
                                             host_resolver_,
                                             socket_factory_,
                                             network_change_notifier_);
}

}  //  namespace net
<|endoftext|>


<commit_before>/*
	Copyright (C) 2015 Claude SIMON (http://q37.info/contact/).

	This file is part of dmnzq.

    dmnzq is free software: you can redistribute it and/or
	modify it under the terms of the GNU Affero General Public License as
	published by the Free Software Foundation, either version 3 of the
	License, or (at your option) any later version.

    dmnzq is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
	Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with dmnzq.  If not, see <http://www.gnu.org/licenses/>
*/

#include "registry.h"

#include "scltool.h"
#include "sclerror.h"

#include "csdlec.h"
#include "csdbns.h"
#include "csdsns.h"

#include "err.h"
#include "cio.h"
#include "epsmsc.h"
#include "xpp.h"
#include "fnm.h"
#include "flf.h"

using cio::CErr;
using cio::COut;
using cio::CIn;

# define NAME_MC			"dmnzq"
# define NAME_LC			"dmnzq"
# define NAME_UC			"DMNZQ"
# define WEBSITE_URL		"http://q37.info/"
# define AUTHOR_NAME		"Claude SIMON"
# define AUTHOR_CONTACT		"http://q37.info/contact/"
# define OWNER_NAME			"Claude SIMON"
# define OWNER_CONTACT		"http://q37.info/contact/"
# define COPYRIGHT			COPYRIGHT_YEARS " " OWNER_NAME " (" OWNER_CONTACT ")"

static void PrintHeader_( void )
{
	COut << NAME_MC " V" VERSION << " (" WEBSITE_URL ")" << txf::nl;
	COut << "Copyright (C) " COPYRIGHT << txf::nl;
	COut << txf::pad << "Build : " __DATE__ " " __TIME__ << " (" << cpe::GetDescription() << ')' << txf::nl;
}

#define C( name )\
	else if ( Command == #name )\
		name##_()

namespace {
	csdlec::library_embedded_client_core__ *Core_ = NULL;

	void ExitFunction_( void )
	{
	qRH
		str::string Message;
	qRB
		if ( Core_ != NULL ) {
			Message.Init();
			COut << sclmisc::GetBaseTranslation( "TerminatingModule", Message ) << txf::nl << txf::commit;
			delete Core_;
			COut << sclmisc::GetBaseTranslation( "ModuleTerminated", Message ) << txf::nl << txf::commit;
		}

		Core_ = NULL;
	qRR
	qRT
	qRE
	}

	E_ENUM( log_file_handling ) {
		lfhAppend,	// New log are appended to the current ones.
		lfhDrop,		// Old logs are destroyed.
		lfh_amount,
		lfh_Undefined,
	};

	log_file_handling__ GetLogFileHandling_( void )
	{
		log_file_handling__ Handling = lfh_Undefined;
	qRH
		str::string Value;
	qRB
		Value.Init();

		registry::GetRawModuleLogMode( Value );

		if ( ( Value.Amount() == 0 ) ||( Value == "Append" ) )
			Handling = lfhAppend;
		else if ( Value == "Drop" )
			Handling = lfhDrop;
		else
			sclrgstry::ReportBadOrNoValueForEntryErrorAndAbort( registry::ModuleLogMode );
	qRR
	qRT
	qRE
		return Handling;
	}

	inline csdbns::port__ GetService_( void )
	{
		return registry::GetRawModuleService();
	}

	E_ENUM( module_connection_type ) {
		mctStraight,
		mctSwitched,
		mct_amount,
		mct_Undefined
	};

	module_connection_type__ GetModuleConnectionType_( void )
	{
		module_connection_type__ Type = mct_Undefined;
	qRH
		str::string Value;
	qRB
		Value.Init();

		registry::GetRawModuleServiceType( Value );

		if ( Value == "Straight" )
			Type = mctStraight;
		else if ( Value == "Switched" )
			Type = mctSwitched;
		else
			sclrgstry::ReportBadOrNoValueForEntryErrorAndAbort( registry::ModuleServiceType );
	qRR
	qRT
	qRE
		return Type;
	}

	void UseStraightConnections_(
		csdscb::callback__ &Callback,
		const bso::char__ *Module,
		csdbns::port__ Port )
	{
	qRH
		csdbns::server___ Server;
	qRB
		Server.Init( Port, Callback );

		Server.Process();
	qRR
	qRT
	qRE
	}

	void UseSwitchingConnections_(
		csdscb::callback__ &Callback,
		csdsns::log_functions__ &LogFunctions,
		csdbns::port__ Port )
	{
	qRH
		csdsns::server___ Server;
	qRB
		Server.Init( Port, Callback, LogFunctions );

		Server.Process();
	qRR
	qRT
	qRE
	}

	typedef csdsns::log_functions__ _log_functions__;

	class log_functions__
	: public _log_functions__
	{
	private:
		txf::text_oflow__ *_Flow;
	protected:
		virtual void CSDSNSLog(
			csdsns::log__ Log,
			csdsns::id__ Id,
			void *UP,
			sdr::size__ Amount )
		{
			tol::buffer__ Buffer;

			if ( _Flow == NULL )
				qRGnr();

			*_Flow << '[' << tol::DateAndTime( Buffer ) << "] " << csdsns::GetLogLabel( Log ) << ' ' << Id << '/' << Amount << txf::nl << txf::commit;
		}
	public:
		void reset( bso::bool__ P = true )
		{
			_log_functions__::reset( P );
			_Flow = NULL;
		}
		log_functions__( void )
		{
			reset( false );
		}
		~log_functions__( void )
		{
			reset();
		}
		void Init( txf::text_oflow__ &Flow )
		{
			_log_functions__::Init();
			_Flow = &Flow;
		}
	};

	void UseSwitchingConnections_(
		csdscb::callback__ &Callback,
		const char *LogFileName,
		log_file_handling__ LogFileHandling,
		csdbns::port__ Port )
	{
	qRH
		flf::file_oflow___ FFlow;
		txf::text_oflow__ TFlow;
		log_functions__ LogFunctions;
		fil::mode__ Mode = fil::m_Undefined;
		lcl::meaning ErrorMeaning;
		str::string ErrorTranslation;
	qRB

		if ( LogFileName != NULL ) {
			switch ( LogFileHandling ) {
			case lfhAppend:
				Mode = fil::mAppend;
				break;
			case lfhDrop:
				Mode = fil::mRemove;
				break;
			default:
				if ( LogFileName != NULL )
					qRGnr();
				break;
			}

			if ( FFlow.Init( LogFileName, Mode, err::hUserDefined ) != tol::rSuccess ) {
				ErrorMeaning.Init();
				ErrorMeaning.SetValue( "UnableToOpenLogFileError" );
				ErrorMeaning.AddTag( LogFileName );

				ErrorTranslation.Init();
				CErr << sclmisc::GetBaseTranslation( ErrorMeaning, ErrorTranslation ) << txf::nl << txf::commit;
				LogFileName = NULL;	// To notify no to use log functions.
			} else
				TFlow.Init( FFlow );
		}

		UseSwitchingConnections_( Callback, LogFileName == NULL ? *(csdsns::log_functions__ *)NULL : LogFunctions, Port );
	qRR
	qRT
	qRE
	}

	void Process_(
		const bso::char__ *ModuleFilename,
		csdbns::port__ Port,
		module_connection_type__ ConnectionType,
		const char *LogFileName,
		log_file_handling__ LogFileHandling )
	{
	qRH
		lcl::locale SharedLocale;
		rgstry::registry SharedRegistry;
		csdlec::library_data__ LibraryData;
		lcl::meaning Meaning, MeaningBuffer;
		str::string Translation;
		err::buffer__ ErrBuffer;
	qRB
		SharedLocale.Init();
		SharedRegistry.Init();

		LibraryData.Init( csdleo::cRegular, ModuleFilename, err::qRRor, sclerror::SCLERRORError, csdleo::mRemote );

		if ( ( Core_ = new csdlec::library_embedded_client_core__ ) == NULL )
			qRAlc();

		if ( !Core_->Init( ModuleFilename, LibraryData, err::hUserDefined ) ) {
			Meaning.Init();
			Meaning.SetValue( "UnableToLoadModule" );
			Meaning.AddTag( ModuleFilename );
			sclerror::SetMeaning( Meaning );
			qRAbort();
		}

		switch ( ConnectionType ) {
		case mctStraight:
			UseStraightConnections_( Core_->GetCallback(), ModuleFilename, Port );
			break;
		case mctSwitched:
			UseSwitchingConnections_( Core_->GetCallback(), LogFileName, LogFileHandling, Port );
			break;
		default:
			qRGnr();
			break;
		}
	qRR
		Meaning.Init();
		Meaning.SetValue( "ModuleError" );
		Meaning.SetValue( ModuleFilename );

		if ( ERRType >= err::t_amount ) {
			if ( sclerror::IsErrorPending() ) {
				MeaningBuffer.Init();
				Meaning.AddTag( sclerror::GetMeaning( MeaningBuffer ) );
			} else {
				Translation.Init();
				Meaning.AddTag( sclmisc::GetBaseTranslation( "UnkonwnError", Translation ) );
			}
		} else {
			Meaning.AddTag( err::Message( ErrBuffer ) );
		}

		Translation.Init();
		sclmisc::GetBaseTranslation( Meaning, Translation );

		cio::CErr << Translation << txf::nl << txf::commit;
	qRT
	qRE
	}

	void Process_(
		const char *LogFileName,
		log_file_handling__ LogFileHandling )
	{
	qRH
		str::string ModuleFileName;
		TOL_CBUFFER___ Buffer;
	qRB
		ModuleFileName.Init();

		Process_( registry::GetModuleFileName( ModuleFileName ).Convert( Buffer ), GetService_(), GetModuleConnectionType_(), LogFileName, LogFileHandling );
	qRR
	qRT
	qRE
	}

	void Process_( void )
	{
	qRH
		TOL_CBUFFER___ Buffer;
	qRB
		atexit( ExitFunction_ );

		cio::COut.Commit();

		Process_( registry::GetModuleLogFilename( Buffer ), GetLogFileHandling_() );
	qRR
	qRT
	qRE
	}
}

int scltool::SCLTOOLMain(
	const str::string_ &Command,
	const scltool::oddities__ &Oddities )
{
	int ExitValue = EXIT_FAILURE;
qRH
qRB
	if ( Command == "Version" )
		PrintHeader_();
	else if ( Command == "License" )
		epsmsc::PrintLicense( NAME_MC );
	C( Process );
	else
		qRGnr();

	ExitValue = EXIT_SUCCESS;
qRR
qRT
qRE
	return ExitValue;
}

const char *sclmisc::SCLMISCTargetName = NAME_LC;

<commit_msg>06/07/2016 21:32:47<commit_after><|endoftext|>


<commit_before>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/http/http_network_session.h"

#include "base/logging.h"
#include "net/http/http_auth_handler_factory.h"
#include "net/http/url_security_manager.h"
#include "net/spdy/spdy_session_pool.h"

namespace net {

// static
int HttpNetworkSession::max_sockets_ = 100;

// static
int HttpNetworkSession::max_sockets_per_group_ = 6;

// static
uint16 HttpNetworkSession::g_fixed_http_port = 0;
uint16 HttpNetworkSession::g_fixed_https_port = 0;

// TODO(vandebo) when we've completely converted to pools, the base TCP
// pool name should get changed to TCP instead of Transport.
HttpNetworkSession::HttpNetworkSession(
    NetworkChangeNotifier* network_change_notifier,
    HostResolver* host_resolver,
    ProxyService* proxy_service,
    ClientSocketFactory* client_socket_factory,
    SSLConfigService* ssl_config_service,
    SpdySessionPool* spdy_session_pool,
    HttpAuthHandlerFactory* http_auth_handler_factory)
    : network_change_notifier_(network_change_notifier),
      tcp_socket_pool_(new TCPClientSocketPool(
          max_sockets_, max_sockets_per_group_, "Transport",
          host_resolver, client_socket_factory, network_change_notifier_)),
      socks_socket_pool_(new SOCKSClientSocketPool(
          max_sockets_, max_sockets_per_group_, "SOCKS", host_resolver,
          new TCPClientSocketPool(max_sockets_, max_sockets_per_group_,
                                  "TCPForSOCKS", host_resolver,
                                  client_socket_factory,
                                  network_change_notifier_),
          network_change_notifier_)),
      socket_factory_(client_socket_factory),
      host_resolver_(host_resolver),
      proxy_service_(proxy_service),
      ssl_config_service_(ssl_config_service),
      spdy_session_pool_(spdy_session_pool),
      http_auth_handler_factory_(http_auth_handler_factory) {
  DCHECK(proxy_service);
  DCHECK(ssl_config_service);
}

HttpNetworkSession::~HttpNetworkSession() {
}

// static
void HttpNetworkSession::set_max_sockets_per_group(int socket_count) {
  DCHECK(0 < socket_count);
  // The following is a sanity check... but we should NEVER be near this value.
  DCHECK(100 > socket_count);
  max_sockets_per_group_ = socket_count;
}

// TODO(vandebo) when we've completely converted to pools, the base TCP
// pool name should get changed to TCP instead of Transport.
void HttpNetworkSession::ReplaceTCPSocketPool() {
  tcp_socket_pool_ = new TCPClientSocketPool(max_sockets_,
                                             max_sockets_per_group_,
                                             "Transport",
                                             host_resolver_,
                                             socket_factory_,
                                             network_change_notifier_);
}

}  //  namespace net
<commit_msg>Increase the global TCP socket limit.  It's too low. wtc likes powers of 2, so I chose 256 as we discussed earlier.  We need to experiment more in the future. BUG=41289<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/http/http_network_session.h"

#include "base/logging.h"
#include "net/http/http_auth_handler_factory.h"
#include "net/http/url_security_manager.h"
#include "net/spdy/spdy_session_pool.h"

namespace net {

// static
int HttpNetworkSession::max_sockets_ = 256;

// static
int HttpNetworkSession::max_sockets_per_group_ = 6;

// static
uint16 HttpNetworkSession::g_fixed_http_port = 0;
uint16 HttpNetworkSession::g_fixed_https_port = 0;

// TODO(vandebo) when we've completely converted to pools, the base TCP
// pool name should get changed to TCP instead of Transport.
HttpNetworkSession::HttpNetworkSession(
    NetworkChangeNotifier* network_change_notifier,
    HostResolver* host_resolver,
    ProxyService* proxy_service,
    ClientSocketFactory* client_socket_factory,
    SSLConfigService* ssl_config_service,
    SpdySessionPool* spdy_session_pool,
    HttpAuthHandlerFactory* http_auth_handler_factory)
    : network_change_notifier_(network_change_notifier),
      tcp_socket_pool_(new TCPClientSocketPool(
          max_sockets_, max_sockets_per_group_, "Transport",
          host_resolver, client_socket_factory, network_change_notifier_)),
      socks_socket_pool_(new SOCKSClientSocketPool(
          max_sockets_, max_sockets_per_group_, "SOCKS", host_resolver,
          new TCPClientSocketPool(max_sockets_, max_sockets_per_group_,
                                  "TCPForSOCKS", host_resolver,
                                  client_socket_factory,
                                  network_change_notifier_),
          network_change_notifier_)),
      socket_factory_(client_socket_factory),
      host_resolver_(host_resolver),
      proxy_service_(proxy_service),
      ssl_config_service_(ssl_config_service),
      spdy_session_pool_(spdy_session_pool),
      http_auth_handler_factory_(http_auth_handler_factory) {
  DCHECK(proxy_service);
  DCHECK(ssl_config_service);
}

HttpNetworkSession::~HttpNetworkSession() {
}

// static
void HttpNetworkSession::set_max_sockets_per_group(int socket_count) {
  DCHECK(0 < socket_count);
  // The following is a sanity check... but we should NEVER be near this value.
  DCHECK(100 > socket_count);
  max_sockets_per_group_ = socket_count;
}

// TODO(vandebo) when we've completely converted to pools, the base TCP
// pool name should get changed to TCP instead of Transport.
void HttpNetworkSession::ReplaceTCPSocketPool() {
  tcp_socket_pool_ = new TCPClientSocketPool(max_sockets_,
                                             max_sockets_per_group_,
                                             "Transport",
                                             host_resolver_,
                                             socket_factory_,
                                             network_change_notifier_);
}

}  //  namespace net
<|endoftext|>


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

Program:   Visualization Toolkit
Module:    vtkOrderStatistics.cxx

Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
/*-------------------------------------------------------------------------
  Copyright 2008 Sandia Corporation.
  Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
  the U.S. Government retains certain rights in this software.
  -------------------------------------------------------------------------*/

#include "vtkToolkits.h"

#include "vtkOrderStatistics.h"
#include "vtkUnivariateStatisticsAlgorithmPrivate.h"

#include "vtkDoubleArray.h"
#include "vtkIdTypeArray.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkObjectFactory.h"
#include "vtkStringArray.h"
#include "vtkTable.h"
#include "vtkVariantArray.h"

#include <vtkstd/vector>
#include <vtkstd/map>
#include <vtkstd/set>

vtkCxxRevisionMacro(vtkOrderStatistics, "1.19");
vtkStandardNewMacro(vtkOrderStatistics);

// ----------------------------------------------------------------------
vtkOrderStatistics::vtkOrderStatistics()
{
  this->QuantileDefinition = vtkOrderStatistics::InverseCDFAveragedSteps;
  this->NumberOfIntervals = 4; // By default, calculate 5-points statistics
}

// ----------------------------------------------------------------------
vtkOrderStatistics::~vtkOrderStatistics()
{
}

// ----------------------------------------------------------------------
void vtkOrderStatistics::PrintSelf( ostream &os, vtkIndent indent )
{
  this->Superclass::PrintSelf( os, indent );
  os << indent << "NumberOfIntervals: " << this->NumberOfIntervals << endl;
  os << indent << "QuantileDefinition: " << this->QuantileDefinition << endl;
}

// ----------------------------------------------------------------------
void vtkOrderStatistics::ExecuteLearn( vtkTable* dataset,
                                       vtkTable* output,
                                       bool finalize )
{
  vtkIdType nCol = dataset->GetNumberOfColumns();
  if ( ! nCol )
    {
    this->SampleSize = 0;
    return;
    }

  this->SampleSize = dataset->GetNumberOfRows();
  if ( ! this->SampleSize )
    {
    return;
    }

  this->Internals->EffectColumnBuffer();
  this->SetColumnSelection( dataset );
  if ( ! this->Internals->SelectedColumns.size() )
    {
    return;
    }

  vtkStringArray* stringCol = vtkStringArray::New();
  stringCol->SetName( "Variable" );
  output->AddColumn( stringCol );
  stringCol->Delete();

  if ( finalize )
    {
    if ( this->NumberOfIntervals < 1 )
      {
      return;
      }

    vtkDoubleArray* doubleCol;
    double dq = 1. / static_cast<double>( this->NumberOfIntervals );
    for ( int i = 0; i <= this->NumberOfIntervals; ++ i )
      {
      doubleCol = vtkDoubleArray::New();
      if ( ! i )
        {
        doubleCol->SetName( "Minimum" );
        }
      else
        {
        if ( i == this->NumberOfIntervals )
          {
          doubleCol->SetName( "Maximum" );
          }
        else
          {
          doubleCol->SetName( vtkStdString( vtkVariant( i * dq ).ToString() + "-quantile" ).c_str() );
          }
        }

      output->AddColumn( doubleCol );
      doubleCol->Delete();
      }
    }
  else
    {
    vtkWarningMacro( "Parallel implementation: not implemented yet." );
    return;
    }

  for ( vtkstd::set<vtkStdString>::iterator it = this->Internals->SelectedColumns.begin();
        it != this->Internals->SelectedColumns.end(); ++ it )
    {
    vtkStdString col = *it;
    if ( ! dataset->GetColumnByName( col ) )
      {
      vtkWarningMacro( "Dataset table does not have a column "<<col.c_str()<<". Ignoring it." );
      continue;
      }

    vtkstd::map<double,vtkIdType> distr;
    for ( vtkIdType r = 0; r < this->SampleSize; ++ r )
      {
      ++ distr[dataset->GetValueByName( r, col ).ToDouble()];
      }

    vtkVariantArray* row = vtkVariantArray::New();

    if ( finalize )
      {
      row->SetNumberOfValues( this->NumberOfIntervals + 2 );

      int i = 0;
      row->SetValue( i ++, col );

      vtkstd::vector<double> quantileThresholds;
      double dh = this->SampleSize / static_cast<double>( this->NumberOfIntervals );
      for ( int j = 0; j < this->NumberOfIntervals; ++ j )
        {
        quantileThresholds.push_back( j * dh );
        }

      double sum = 0;
      vtkstd::vector<double>::iterator qit = quantileThresholds.begin();
      for ( vtkstd::map<double,vtkIdType>::iterator mit = distr.begin();
            mit != distr.end(); ++ mit  )
        {
        for ( sum += mit->second; qit != quantileThresholds.end() && sum >= *qit; ++ qit )
          {
          if ( sum == *qit
               && this->QuantileDefinition == vtkOrderStatistics::InverseCDFAveragedSteps )
            {
            vtkstd::map<double,vtkIdType>::iterator nit = mit;
            row->SetValue( i ++, ( (++ nit)->first + mit->first ) * .5 );
            }
          else
            {
            row->SetValue( i ++, mit->first );
            }
          }
        }

      row->SetValue( i, distr.rbegin()->first );
      }
    else
      {
      vtkWarningMacro( "Parallel implementation: not implemented yet." );
      return;
      }

    output->InsertNextRow( row );

    row->Delete();
    }

  return;
}

// ----------------------------------------------------------------------
void vtkOrderStatistics::ExecuteValidate( vtkTable*,
                                          vtkTable*,
                                          vtkTable* )
{
  // Not implemented for this statistical engine
}

// ----------------------------------------------------------------------
void vtkOrderStatistics::ExecuteEvince( vtkTable* dataset,
                                        vtkTable* params,
                                        vtkTable* output)
{
  vtkIdType nColD = dataset->GetNumberOfColumns();
  if ( ! nColD )
    {
    return;
    }

  vtkIdType nRowD = dataset->GetNumberOfRows();
  if ( ! nRowD )
    {
    return;
    }

  vtkIdType nColP = params->GetNumberOfColumns();
  if ( nColP != 3 )
    {
    vtkWarningMacro( "Parameter table has "
                     << nColP
                     << " != 3 columns. Doing nothing." );
    return;
    }

  vtkIdType nRowP = params->GetNumberOfRows();
  if ( ! nRowP )
    {
    return;
    }

  this->Internals->EffectColumnBuffer();
  this->SetColumnSelection( dataset );
  if ( ! this->Internals->SelectedColumns.size() )
    {
    return;
    }

  vtkStringArray* stringCol = vtkStringArray::New();
  stringCol->SetName( "Variable" );
  output->AddColumn( stringCol );
  stringCol->Delete();

  vtkIdTypeArray* idTypeCol = vtkIdTypeArray::New();
  idTypeCol->SetName( "Row" );
  output->AddColumn( idTypeCol );
  idTypeCol->Delete();

  vtkDoubleArray* doubleCol = vtkDoubleArray::New();
  doubleCol->SetName( "Relative Deviation" );
  output->AddColumn( doubleCol );
  doubleCol->Delete();

  vtkVariantArray* row = vtkVariantArray::New();
  row->SetNumberOfValues( 3 );

  for ( vtkstd::set<vtkStdString>::iterator it = this->Internals->SelectedColumns.begin();
        it != this->Internals->SelectedColumns.end(); ++ it )
    {
    vtkStdString col = *it;
    if ( ! dataset->GetColumnByName( col ) )
      {
      vtkWarningMacro( "Dataset table does not have a column "<<col.c_str()<<". Ignoring it." );
      continue;
      }

    bool unfound = true;
    for ( int i = 0; i < nRowP; ++ i )
      {
      if ( params->GetValue( i, 0 ).ToString() == col )
        {
        unfound = false;

        double center = params->GetValue( i, 1 ).ToDouble();
        double radius = params->GetValue( i, 2 ).ToDouble();
        double minimum = center - radius;
        double maximum = center + radius;

        double value;
        for ( vtkIdType r = 0; r < nRowD; ++ r )
          {
          value  = dataset->GetValueByName( r, col ).ToDouble();
          if ( value < minimum || value > maximum )
            {
            row->SetValue( 0, col );
            row->SetValue( 1, r );
            row->SetValue( 2, ( value - center ) / radius );

            output->InsertNextRow( row );
            }
          }

        break;
        }
      }

    if ( unfound )
      {
      vtkWarningMacro( "Parameter table does not have a row for dataset table column "
                       <<col.c_str()
                       <<". Ignoring it." );
      continue;
      }
    }
  row->Delete();

  return;
}

// ----------------------------------------------------------------------
void vtkOrderStatistics::SetQuantileDefinition( vtkIdType qd )
{
  switch ( qd )
    {
    case vtkOrderStatistics::InverseCDF:
      break;
    case vtkOrderStatistics::InverseCDFAveragedSteps:
      break;
    default:
      vtkWarningMacro( "Incorrect type of quantile definition: "
                       <<qd
                       <<". Ignoring it." );
      return;
    }

  this->QuantileDefinition =  static_cast<vtkOrderStatistics::QuantileDefinitionType>( qd );
  this->Modified();

  return;
}
<commit_msg>ENH: provide specific labels for special quantiles (quartiles, median).<commit_after>/*=========================================================================

Program:   Visualization Toolkit
Module:    vtkOrderStatistics.cxx

Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
/*-------------------------------------------------------------------------
  Copyright 2008 Sandia Corporation.
  Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
  the U.S. Government retains certain rights in this software.
  -------------------------------------------------------------------------*/

#include "vtkToolkits.h"

#include "vtkOrderStatistics.h"
#include "vtkUnivariateStatisticsAlgorithmPrivate.h"

#include "vtkDoubleArray.h"
#include "vtkIdTypeArray.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkObjectFactory.h"
#include "vtkStringArray.h"
#include "vtkTable.h"
#include "vtkVariantArray.h"

#include <vtkstd/vector>
#include <vtkstd/map>
#include <vtkstd/set>

vtkCxxRevisionMacro(vtkOrderStatistics, "1.20");
vtkStandardNewMacro(vtkOrderStatistics);

// ----------------------------------------------------------------------
vtkOrderStatistics::vtkOrderStatistics()
{
  this->QuantileDefinition = vtkOrderStatistics::InverseCDFAveragedSteps;
  this->NumberOfIntervals = 4; // By default, calculate 5-points statistics
}

// ----------------------------------------------------------------------
vtkOrderStatistics::~vtkOrderStatistics()
{
}

// ----------------------------------------------------------------------
void vtkOrderStatistics::PrintSelf( ostream &os, vtkIndent indent )
{
  this->Superclass::PrintSelf( os, indent );
  os << indent << "NumberOfIntervals: " << this->NumberOfIntervals << endl;
  os << indent << "QuantileDefinition: " << this->QuantileDefinition << endl;
}

// ----------------------------------------------------------------------
void vtkOrderStatistics::ExecuteLearn( vtkTable* dataset,
                                       vtkTable* output,
                                       bool finalize )
{
  vtkIdType nCol = dataset->GetNumberOfColumns();
  if ( ! nCol )
    {
    this->SampleSize = 0;
    return;
    }

  this->SampleSize = dataset->GetNumberOfRows();
  if ( ! this->SampleSize )
    {
    return;
    }

  this->Internals->EffectColumnBuffer();
  this->SetColumnSelection( dataset );
  if ( ! this->Internals->SelectedColumns.size() )
    {
    return;
    }

  vtkStringArray* stringCol = vtkStringArray::New();
  stringCol->SetName( "Variable" );
  output->AddColumn( stringCol );
  stringCol->Delete();

  if ( finalize )
    {
    if ( this->NumberOfIntervals < 1 )
      {
      return;
      }

    vtkDoubleArray* doubleCol;
    double dq = 1. / static_cast<double>( this->NumberOfIntervals );
    for ( int i = 0; i <= this->NumberOfIntervals; ++ i )
      {
      doubleCol = vtkDoubleArray::New();
      div_t q = div( i << 2, this->NumberOfIntervals );

      if ( q.rem )
        {
        doubleCol->SetName( vtkStdString( vtkVariant( i * dq ).ToString() + "-quantile" ).c_str() );
        }
      else
        {
        switch ( q.quot )
          {
          case 0:
            doubleCol->SetName( "Minimum" );
            break;
          case 1:
            doubleCol->SetName( "First Quartile" );
            break;
          case 2:
            doubleCol->SetName( "Median" );
            break;
          case 3:
            doubleCol->SetName( "Third Quartile" );
            break;
          case 4:
            doubleCol->SetName( "Maximum" );
            break;
          default:
            doubleCol->SetName( vtkStdString( vtkVariant( i * dq ).ToString() + "-quantile" ).c_str() );
            break;
          }
        }
      output->AddColumn( doubleCol );
      doubleCol->Delete();
      }
    }
  else
    {
    vtkWarningMacro( "Parallel implementation: not implemented yet." );
    return;
    }

  for ( vtkstd::set<vtkStdString>::iterator it = this->Internals->SelectedColumns.begin();
        it != this->Internals->SelectedColumns.end(); ++ it )
    {
    vtkStdString col = *it;
    if ( ! dataset->GetColumnByName( col ) )
      {
      vtkWarningMacro( "Dataset table does not have a column "<<col.c_str()<<". Ignoring it." );
      continue;
      }

    vtkstd::map<double,vtkIdType> distr;
    for ( vtkIdType r = 0; r < this->SampleSize; ++ r )
      {
      ++ distr[dataset->GetValueByName( r, col ).ToDouble()];
      }

    vtkVariantArray* row = vtkVariantArray::New();

    if ( finalize )
      {
      row->SetNumberOfValues( this->NumberOfIntervals + 2 );

      int i = 0;
      row->SetValue( i ++, col );

      vtkstd::vector<double> quantileThresholds;
      double dh = this->SampleSize / static_cast<double>( this->NumberOfIntervals );
      for ( int j = 0; j < this->NumberOfIntervals; ++ j )
        {
        quantileThresholds.push_back( j * dh );
        }

      double sum = 0;
      vtkstd::vector<double>::iterator qit = quantileThresholds.begin();
      for ( vtkstd::map<double,vtkIdType>::iterator mit = distr.begin();
            mit != distr.end(); ++ mit  )
        {
        for ( sum += mit->second; qit != quantileThresholds.end() && sum >= *qit; ++ qit )
          {
          if ( sum == *qit
               && this->QuantileDefinition == vtkOrderStatistics::InverseCDFAveragedSteps )
            {
            vtkstd::map<double,vtkIdType>::iterator nit = mit;
            row->SetValue( i ++, ( (++ nit)->first + mit->first ) * .5 );
            }
          else
            {
            row->SetValue( i ++, mit->first );
            }
          }
        }

      row->SetValue( i, distr.rbegin()->first );
      }
    else
      {
      vtkWarningMacro( "Parallel implementation: not implemented yet." );
      return;
      }

    output->InsertNextRow( row );

    row->Delete();
    }

  return;
}

// ----------------------------------------------------------------------
void vtkOrderStatistics::ExecuteValidate( vtkTable*,
                                          vtkTable*,
                                          vtkTable* )
{
  // Not implemented for this statistical engine
}

// ----------------------------------------------------------------------
void vtkOrderStatistics::ExecuteEvince( vtkTable* dataset,
                                        vtkTable* params,
                                        vtkTable* output)
{
  vtkIdType nColD = dataset->GetNumberOfColumns();
  if ( ! nColD )
    {
    return;
    }

  vtkIdType nRowD = dataset->GetNumberOfRows();
  if ( ! nRowD )
    {
    return;
    }

  vtkIdType nColP = params->GetNumberOfColumns();
  if ( nColP != 3 )
    {
    vtkWarningMacro( "Parameter table has "
                     << nColP
                     << " != 3 columns. Doing nothing." );
    return;
    }

  vtkIdType nRowP = params->GetNumberOfRows();
  if ( ! nRowP )
    {
    return;
    }

  this->Internals->EffectColumnBuffer();
  this->SetColumnSelection( dataset );
  if ( ! this->Internals->SelectedColumns.size() )
    {
    return;
    }

  vtkStringArray* stringCol = vtkStringArray::New();
  stringCol->SetName( "Variable" );
  output->AddColumn( stringCol );
  stringCol->Delete();

  vtkIdTypeArray* idTypeCol = vtkIdTypeArray::New();
  idTypeCol->SetName( "Row" );
  output->AddColumn( idTypeCol );
  idTypeCol->Delete();

  vtkDoubleArray* doubleCol = vtkDoubleArray::New();
  doubleCol->SetName( "Relative Deviation" );
  output->AddColumn( doubleCol );
  doubleCol->Delete();

  vtkVariantArray* row = vtkVariantArray::New();
  row->SetNumberOfValues( 3 );

  for ( vtkstd::set<vtkStdString>::iterator it = this->Internals->SelectedColumns.begin();
        it != this->Internals->SelectedColumns.end(); ++ it )
    {
    vtkStdString col = *it;
    if ( ! dataset->GetColumnByName( col ) )
      {
      vtkWarningMacro( "Dataset table does not have a column "<<col.c_str()<<". Ignoring it." );
      continue;
      }

    bool unfound = true;
    for ( int i = 0; i < nRowP; ++ i )
      {
      if ( params->GetValue( i, 0 ).ToString() == col )
        {
        unfound = false;

        double center = params->GetValue( i, 1 ).ToDouble();
        double radius = params->GetValue( i, 2 ).ToDouble();
        double minimum = center - radius;
        double maximum = center + radius;

        double value;
        for ( vtkIdType r = 0; r < nRowD; ++ r )
          {
          value  = dataset->GetValueByName( r, col ).ToDouble();
          if ( value < minimum || value > maximum )
            {
            row->SetValue( 0, col );
            row->SetValue( 1, r );
            row->SetValue( 2, ( value - center ) / radius );

            output->InsertNextRow( row );
            }
          }

        break;
        }
      }

    if ( unfound )
      {
      vtkWarningMacro( "Parameter table does not have a row for dataset table column "
                       <<col.c_str()
                       <<". Ignoring it." );
      continue;
      }
    }
  row->Delete();

  return;
}

// ----------------------------------------------------------------------
void vtkOrderStatistics::SetQuantileDefinition( vtkIdType qd )
{
  switch ( qd )
    {
    case vtkOrderStatistics::InverseCDF:
      break;
    case vtkOrderStatistics::InverseCDFAveragedSteps:
      break;
    default:
      vtkWarningMacro( "Incorrect type of quantile definition: "
                       <<qd
                       <<". Ignoring it." );
      return;
    }

  this->QuantileDefinition =  static_cast<vtkOrderStatistics::QuantileDefinitionType>( qd );
  this->Modified();

  return;
}
<|endoftext|>


<commit_before>/*
 * See ffx.h for details.
 *
 * References:
 *   [FFX2] http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/ffx/ffx-spec2.pdf
 */

#include "ffx/ffx.h"

#include <math.h>

#include <string>

#include "third_party/aes/aes.h"

namespace ffx {

static bool ValidateKey(const std::string & key) {
  if (key.length() != kFfxKeyLengthInNibbles) {
    return false;
  }
  for (uint32_t i = 0; i < key.length(); ++i) {
    if (isxdigit(key[i])) {
      continue;
    } else {
      return false;
    }
  }
  return true;
}

/*
 * This function has an unfortunate number of input parameters.
 * However, this is a direct implementation of the round-function algorithm
 * F_K(n,T,i,B) defined in [FFX2].
 */
bool Ffx::RoundFunction(uint32_t n,
                        const mpz_class & tweak,
                        uint32_t tweak_len_in_bits,
                        uint32_t i,
                        const mpz_class & B,
                        uint32_t B_len,
                        mpz_class * retval) {

  // [FFX2] pg 3., line 31
  uint32_t t = (tweak_len_in_bits + 7) >> 3;
  uint32_t beta = (n + 1) >> 1;
  uint32_t b = (beta + 7) >> 3;
  uint32_t d = 4 * ((b + 3) >> 2);

  // [FFX2] pg 3., line 32
  uint32_t m = 0;
  if ((i & 1) == 0) {
    m = n >> 1;
  } else {
    m = (n + 1) >> 1;
  }

  // [FFX2] pg 3., line 33
  mpz_class P = 0;
  uint32_t P_len = (1 + 1 + 1 + 3 + 1 + 1 + 4 + 4) * 8;
  P += mpz_class(1)      << (1 + 1 + 3 + 1 + 1 + 4 + 4) * 8;
  P += mpz_class(2)      << (1 + 3 + 1 + 1 + 4 + 4) * 8;
  P += mpz_class(1)      << (3 + 1 + 1 + 4 + 4) * 8;
  P += mpz_class(2)      << (1 + 1 + 4 + 4) * 8;
  P += mpz_class(10)     << (1 + 4 + 4) * 8;
  P += mpz_class(n / 2)  << (4 + 4) * 8;
  P += mpz_class(n)      << (4) * 8;
  P += t;

  uint32_t B_bits = b * 8;

  // [FFX2] pg 3., line 34
  mpz_class Q = 0;
  uint32_t T_offset = ((((-1 * t) - b - 1) % 16) * 8);
  T_offset += 8;
  T_offset += B_bits;

  uint32_t Q_len = tweak_len_in_bits + T_offset;
  Q += mpz_class(tweak) << T_offset;
  Q += mpz_class(i) << B_bits;
  Q += B;

  mpz_class Y = 0;

  // [FFX2] pg 3., line 35
  bool cbc_success = AesCbcMac((P << Q_len) + Q, P_len + Q_len, &Y);
  if (!cbc_success) {
    return false;
  }

  // [FFX2] pg 3., line 36
  mpz_class Z = Y;
  uint32_t Z_len = 16;
  mpz_class counter = 1;
  mpz_class ctxt = 0;
  while (Z_len < (d + 4)) {
    ctxt = 0;
    AesEcbEncrypt((Y + counter), 128, &ctxt);
    Z_len += 16;
    Z <<= 128;
    mpz_add(Z.get_mpz_t(), Z.get_mpz_t(), ctxt.get_mpz_t());
    ++counter;
  }

  // [FFX2] pg 3., line 37
  BitMask(Z, Z_len * 8, 0, ((d + 4) * 8) - 1, &Y);

  // [FFX2] pg 3., line 38
  mpz_class modulus = 0;
  mpz_ui_pow_ui(modulus.get_mpz_t(), 2, m);
  Y = Y % modulus;

  // [FFX2] pg 3., line 39
  *retval = Y;

  return true;
}

bool Ffx::Encrypt(const mpz_class & tweak,
                  uint32_t tweak_len_in_bits,
                  const mpz_class & plaintext,
                  uint32_t plaintext_len_in_bits,
                  mpz_class * ciphertext) {

  mpz_class & retval = *ciphertext;

  // [FFX2] pg 3., line 14-15
  uint32_t n = plaintext_len_in_bits;
  uint32_t l = plaintext_len_in_bits / 2;
  uint32_t r = kDefaultFfxRounds;
  mpz_class A, B;
  BitMask(plaintext, plaintext_len_in_bits, 0, l - 1, &A);
  BitMask(plaintext, plaintext_len_in_bits, l, n - 1, &B);
  uint32_t B_len = n - l;
  mpz_class C = 0;
  mpz_class D = 0;
  uint32_t m = 0;
  mpz_class modulus = 0;

  // [FFX2] pg 3., line 16
  for (uint32_t i = 0; i <= (r - 1); ++i) {
    if ((i & 1) == 0) {
      m = n / 2;
    } else {
      m = (n+1) / 2;
    }
    mpz_ui_pow_ui(modulus.get_mpz_t(), 2, m);

    RoundFunction(n, tweak, tweak_len_in_bits, i, B, m, &D);
    mpz_add(C.get_mpz_t(),
            A.get_mpz_t(),
            D.get_mpz_t());

    C = C % modulus;
    A = B;
    B = C;
  }

  // [FFX2] pg 3., line 19
  retval = (A << B_len) + B;

  mpz_ui_pow_ui(modulus.get_mpz_t(), 2, plaintext_len_in_bits);
  retval = retval % modulus;

  return true;
}

bool Ffx::Decrypt(const mpz_class & tweak,
                  uint32_t tweak_len_in_bits,
                  const mpz_class & ciphertext,
                  uint32_t ciphertext_len_bits,
                  mpz_class * plaintext) {

  mpz_class & retval = *plaintext;

  // [FFX2] pg 3., line 24-25
  uint32_t n = ciphertext_len_bits;
  uint32_t l = ciphertext_len_bits / 2;
  uint32_t r = kDefaultFfxRounds;
  mpz_class A, B;
  BitMask(ciphertext, ciphertext_len_bits, 0, l - 1, &A);
  BitMask(ciphertext, ciphertext_len_bits, l, n - 1, &B);
  uint32_t B_len = n - l;
  mpz_class C = 0;
  mpz_class D = 0;
  uint32_t m = 0;
  mpz_class modulus = 0;

  // [FFX2] pg 3., line 26
  for (int32_t i = r - 1; i >= 0; --i) {
    if ((i & 1) == 0) {
      m = n / 2;
    } else {
      m = (n+1) / 2;
    }
    mpz_ui_pow_ui(modulus.get_mpz_t(), 2, m);

    C = B;
    B = A;
    RoundFunction(n, tweak, tweak_len_in_bits, i, B, m, &D);
    mpz_sub(A.get_mpz_t(),
            C.get_mpz_t(),
            D.get_mpz_t());

    while(A < 0) A += modulus;
    A = A % modulus;
  }

  // [FFX2] pg 3., line 29
  retval = (A << B_len) + B;

  mpz_ui_pow_ui(modulus.get_mpz_t(), 2, ciphertext_len_bits);
  retval = retval % modulus;

  return true;
}

/*
 * These are the main entry points with NULL tweaks.
 */
bool Ffx::Encrypt(const mpz_class & plaintext,
                  uint32_t plaintext_len_in_bits,
                  mpz_class * ciphertext) {
  return Ffx::Encrypt(0, 0, plaintext, plaintext_len_in_bits, ciphertext);
}

bool Ffx::Decrypt(const mpz_class & ciphertext,
                  uint32_t ciphertext_len_in_bits,
                  mpz_class * plaintext) {
  return Ffx::Decrypt(0, 0, ciphertext, ciphertext_len_in_bits, plaintext);
}

bool Ffx::SetKey(const std::string & key) {
  // [FFX2] pg 3., line 21
  if (!ValidateKey(key)) {
    return false;
  }

  uint32_t key_length_in_bytes = (key.length() + 1) / 2;
  key_ = new unsigned char[key_length_in_bytes];
  Base16ToBase256(key, key_length_in_bytes, key_);

  AesEcbSetKey(key_);
  AesCbcSetKey(key_);

  return true;
}

Ffx::Ffx()
  : radix_(kDefaultFfxRadix)
  , key_(NULL) {
}

Ffx::Ffx(const uint32_t radix)
  : radix_(radix)
  , key_(NULL) {

}

} // namespace ffx
<commit_msg>Issue #18: small perf. improvements<commit_after>/*
 * See ffx.h for details.
 *
 * References:
 *   [FFX2] http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/ffx/ffx-spec2.pdf
 */

#include "ffx/ffx.h"

#include <math.h>

#include <string>

#include "third_party/aes/aes.h"

namespace ffx {

static bool ValidateKey(const std::string & key) {
  if (key.length() != kFfxKeyLengthInNibbles) {
    return false;
  }
  for (uint32_t i = 0; i < key.length(); ++i) {
    if (isxdigit(key[i])) {
      continue;
    } else {
      return false;
    }
  }
  return true;
}

/*
 * This function has an unfortunate number of input parameters.
 * However, this is a direct implementation of the round-function algorithm
 * F_K(n,T,i,B) defined in [FFX2].
 */
bool Ffx::RoundFunction(uint32_t n,
                        const mpz_class & tweak,
                        uint32_t tweak_len_in_bits,
                        uint32_t i,
                        const mpz_class & B,
                        uint32_t B_len,
                        mpz_class * retval) {

  // [FFX2] pg 3., line 31
  uint32_t t = (tweak_len_in_bits + 7) >> 3;
  uint32_t beta = (n + 1) >> 1;
  uint32_t b = (beta + 7) >> 3;
  uint32_t d = 4 * ((b + 3) >> 2);

  // [FFX2] pg 3., line 32
  uint32_t m = 0;
  if ((i & 1) == 0) {
    m = n >> 1;
  } else {
    m = (n + 1) >> 1;
  }

  // [FFX2] pg 3., line 33
  mpz_class P = 0;
  uint32_t P_len = (1 + 1 + 1 + 3 + 1 + 1 + 4 + 4) * 8;
  P += mpz_class(1)      << (1 + 1 + 3 + 1 + 1 + 4 + 4) * 8;
  P += mpz_class(2)      << (1 + 3 + 1 + 1 + 4 + 4) * 8;
  P += mpz_class(1)      << (3 + 1 + 1 + 4 + 4) * 8;
  P += mpz_class(2)      << (1 + 1 + 4 + 4) * 8;
  P += mpz_class(10)     << (1 + 4 + 4) * 8;
  P += mpz_class(n / 2)  << (4 + 4) * 8;
  P += mpz_class(n)      << (4) * 8;
  P += t;

  uint32_t B_bits = b * 8;

  // [FFX2] pg 3., line 34
  mpz_class Q = 0;
  uint32_t T_offset = ((((-1 * t) - b - 1) % 16) * 8);
  T_offset += 8;
  T_offset += B_bits;

  uint32_t Q_len = tweak_len_in_bits + T_offset;
  Q += mpz_class(tweak) << T_offset;
  Q += mpz_class(i) << B_bits;
  Q += B;

  mpz_class Y = 0;

  // [FFX2] pg 3., line 35
  bool cbc_success = AesCbcMac((P << Q_len) + Q, P_len + Q_len, &Y);
  if (!cbc_success) {
    return false;
  }

  // [FFX2] pg 3., line 36
  mpz_class Z = Y;
  uint32_t Z_len = 16;
  mpz_class counter = 1;
  mpz_class ctxt = 0;
  while (Z_len < (d + 4)) {
    ctxt = 0;
    AesEcbEncrypt((Y + counter), 128, &ctxt);
    Z_len += 16;
    Z <<= 128;
    mpz_add(Z.get_mpz_t(), Z.get_mpz_t(), ctxt.get_mpz_t());
    ++counter;
  }

  // [FFX2] pg 3., line 37
  BitMask(Z, Z_len * 8, 0, ((d + 4) * 8) - 1, &Y);

  // [FFX2] pg 3., line 38
  mpz_class modulus = 0;
  mpz_ui_pow_ui(modulus.get_mpz_t(), 2, m);
  Y = Y % modulus;

  // [FFX2] pg 3., line 39
  *retval = Y;

  return true;
}

bool Ffx::Encrypt(const mpz_class & tweak,
                  uint32_t tweak_len_in_bits,
                  const mpz_class & plaintext,
                  uint32_t plaintext_len_in_bits,
                  mpz_class * ciphertext) {

  mpz_class & retval = *ciphertext;

  // [FFX2] pg 3., line 14-15
  uint32_t n = plaintext_len_in_bits;
  uint32_t l = plaintext_len_in_bits / 2;
  uint32_t r = kDefaultFfxRounds;
  mpz_class A, B;
  BitMask(plaintext, plaintext_len_in_bits, 0, l - 1, &A);
  BitMask(plaintext, plaintext_len_in_bits, l, n - 1, &B);
  uint32_t B_len = n - l;
  mpz_class C = 0;
  mpz_class D = 0;
  uint32_t m = 0;
  mpz_class modulus = 0;

  // [FFX2] pg 3., line 16
  for (uint32_t i = 0; i <= (r - 1); ++i) {
    if ((i & 1) == 0) {
      m = n >> 1;
    } else {
      m = (n+1) >> 1;
    }
    mpz_ui_pow_ui(modulus.get_mpz_t(), 2, m);

    RoundFunction(n, tweak, tweak_len_in_bits, i, B, m, &D);
    mpz_add(C.get_mpz_t(),
            A.get_mpz_t(),
            D.get_mpz_t());

    C = C % modulus;
    A = B;
    B = C;
  }

  // [FFX2] pg 3., line 19
  retval = (A << B_len) + B;

  mpz_ui_pow_ui(modulus.get_mpz_t(), 2, plaintext_len_in_bits);
  retval = retval % modulus;

  return true;
}

bool Ffx::Decrypt(const mpz_class & tweak,
                  uint32_t tweak_len_in_bits,
                  const mpz_class & ciphertext,
                  uint32_t ciphertext_len_bits,
                  mpz_class * plaintext) {

  mpz_class & retval = *plaintext;

  // [FFX2] pg 3., line 24-25
  uint32_t n = ciphertext_len_bits;
  uint32_t l = ciphertext_len_bits / 2;
  uint32_t r = kDefaultFfxRounds;
  mpz_class A, B;
  BitMask(ciphertext, ciphertext_len_bits, 0, l - 1, &A);
  BitMask(ciphertext, ciphertext_len_bits, l, n - 1, &B);
  uint32_t B_len = n - l;
  mpz_class C = 0;
  mpz_class D = 0;
  uint32_t m = 0;
  mpz_class modulus = 0;

  // [FFX2] pg 3., line 26
  for (int32_t i = r - 1; i >= 0; --i) {
    if ((i & 1) == 0) {
      m = n >> 1;
    } else {
      m = (n+1) >> 1;
    }
    mpz_ui_pow_ui(modulus.get_mpz_t(), 2, m);

    C = B;
    B = A;
    RoundFunction(n, tweak, tweak_len_in_bits, i, B, m, &D);
    mpz_sub(A.get_mpz_t(),
            C.get_mpz_t(),
            D.get_mpz_t());

    while(A < 0) A += modulus;
    A = A % modulus;
  }

  // [FFX2] pg 3., line 29
  retval = (A << B_len) + B;

  mpz_ui_pow_ui(modulus.get_mpz_t(), 2, ciphertext_len_bits);
  retval = retval % modulus;

  return true;
}

/*
 * These are the main entry points with NULL tweaks.
 */
bool Ffx::Encrypt(const mpz_class & plaintext,
                  uint32_t plaintext_len_in_bits,
                  mpz_class * ciphertext) {
  return Ffx::Encrypt(0, 0, plaintext, plaintext_len_in_bits, ciphertext);
}

bool Ffx::Decrypt(const mpz_class & ciphertext,
                  uint32_t ciphertext_len_in_bits,
                  mpz_class * plaintext) {
  return Ffx::Decrypt(0, 0, ciphertext, ciphertext_len_in_bits, plaintext);
}

bool Ffx::SetKey(const std::string & key) {
  // [FFX2] pg 3., line 21
  if (!ValidateKey(key)) {
    return false;
  }

  uint32_t key_length_in_bytes = (key.length() + 1) / 2;
  key_ = new unsigned char[key_length_in_bytes];
  Base16ToBase256(key, key_length_in_bytes, key_);

  AesEcbSetKey(key_);
  AesCbcSetKey(key_);

  return true;
}

Ffx::Ffx()
  : radix_(kDefaultFfxRadix)
  , key_(NULL) {
}

Ffx::Ffx(const uint32_t radix)
  : radix_(radix)
  , key_(NULL) {

}

} // namespace ffx
<|endoftext|>


<commit_before>#include <mart-netlib/udp.hpp>

#include <mart-common/PrintWrappers.h>

#include <catch2/catch.hpp>

#include <iostream>
TEST_CASE( "udp_socket_simple_member_check1", "[net]" )
{
	using namespace mart::nw::ip;
	udp::endpoint e1 = {mart::nw::ip::address_any, mart::nw::ip::port_nr {1573}};
	udp::endpoint e2 = {mart::nw::ip::address_local_host, mart::nw::ip::port_nr {1455}};
	udp::endpoint e3 {"127.0.0.1:3435"};
	udp::Socket   s1;

	udp::Socket s2 {};

	udp::Socket s3( e1, e3 );
	s3.close();
	udp::Socket s4( std::move( s1 ) );
	s2 = std::move( s4 );

	[[maybe_unused]] mart::nw::socks::RaiiSocket& raw_socket = s2.getRawSocket();

	s2.bind( e1 );
	// socket can't be rebinded to a different one
	CHECK( !s2.try_bind( e1 ) );
	CHECK_NOTHROW( s2.connect( e2 ) );
	CHECK( s2.getLocalEndpoint() == e1 );
	CHECK( s2.getRemoteEndpoint() == e2 );

	CHECK( s2.try_connect( e3 ) );

	CHECK( s2.getLocalEndpoint() == e1 );
	CHECK( s2.getRemoteEndpoint() == e3 );

	CHECK_NOTHROW( s2.send( mart::view_bytes( 5 ) ) );
	CHECK_NOTHROW( s2.sendto( mart::view_bytes( 5 ), e2 ) );

	CHECK_THROWS( s2.sendto( mart::view_bytes( 5 ), e1 ) ); // invalid target address
}

namespace {
template<class Rep, class Period>
std::ostream& operator<<( std::ostream& out, std::chrono::duration<Rep, Period> dur )
{
	out << mart::sformat( dur );
	return out;
}

} // namespace

TEST_CASE( "udp_socket_simple_member_check2", "[net]" )
{
	using namespace mart::nw::ip;
	udp::Socket s {};

	CHECK( s.is_blocking() );

	CHECK_NOTHROW( s.bind( udp::endpoint {"127.0.0.1:3446"} ) );
	using namespace std::chrono_literals;
	CHECK( s.set_rx_timeout( 1ms ) );
	CHECK( s.set_tx_timeout( 2ms ) );
	CHECK( s.get_tx_timeout() == 2ms );
	CHECK( s.get_rx_timeout() == 1ms );

	int buffer = 0;
	CHECK( !s.try_recv( mart::view_bytes_mutable( buffer ) ).isValid() );

	CHECK( s.try_send( mart::view_bytes( buffer ) ).size() != 0 );
	CHECK_THROWS( s.send( mart::view_bytes( buffer ) ).isValid() );
	{
		udp::endpoint e4 {};
		CHECK( s.try_sendto( mart::view_bytes( buffer ), e4 ).size() != 0 );
		CHECK_THROWS( s.sendto( mart::view_bytes( buffer ), e4 ).isValid() );
	}

	CHECK( !s.try_recv( mart::view_bytes_mutable( buffer ) ).isValid() );
	CHECK( !s.try_recvfrom( mart::view_bytes_mutable( buffer ) ).data.isValid() );

	CHECK( !s.recv( mart::view_bytes_mutable( buffer ) ).isValid() );
	CHECK( !s.recvfrom( mart::view_bytes_mutable( buffer ) ).data.isValid() );

	s.clearRxBuff();

	CHECK( s.set_blocking( false ) );
	CHECK( !s.is_blocking() );

	s.close();
	CHECK( !s.is_valid() );
}

TEST_CASE( "invalid_endpoint_strings_fail" )
{
	using namespace mart::nw::ip;
	CHECK_THROWS( udp::endpoint {"127.0.0.1"} );
	CHECK_THROWS( udp::endpoint {"127.0.0:5"} );
	CHECK_THROWS( udp::endpoint {"127005"} );
	CHECK_THROWS( udp::endpoint {"127.0.0.1:66999"} );
	CHECK_THROWS( udp::endpoint {"1.333.0.1:669"} );
}
<commit_msg>[netlib/tests] Remove unnecessary stream operator in test<commit_after>#include <mart-netlib/udp.hpp>

#include <mart-common/PrintWrappers.h>

#include <catch2/catch.hpp>

TEST_CASE( "udp_socket_simple_member_check1", "[net]" )
{
	using namespace mart::nw::ip;
	udp::endpoint e1 = {mart::nw::ip::address_any, mart::nw::ip::port_nr {1573}};
	udp::endpoint e2 = {mart::nw::ip::address_local_host, mart::nw::ip::port_nr {1455}};
	udp::endpoint e3 {"127.0.0.1:3435"};
	udp::Socket   s1;

	udp::Socket s2 {};

	udp::Socket s3( e1, e3 );
	s3.close();
	udp::Socket s4( std::move( s1 ) );
	s2 = std::move( s4 );

	[[maybe_unused]] mart::nw::socks::RaiiSocket& raw_socket = s2.getRawSocket();

	s2.bind( e1 );
	// socket can't be rebinded to a different one
	CHECK( !s2.try_bind( e1 ) );
	CHECK_NOTHROW( s2.connect( e2 ) );
	CHECK( s2.getLocalEndpoint() == e1 );
	CHECK( s2.getRemoteEndpoint() == e2 );

	CHECK( s2.try_connect( e3 ) );

	CHECK( s2.getLocalEndpoint() == e1 );
	CHECK( s2.getRemoteEndpoint() == e3 );

	CHECK_NOTHROW( s2.send( mart::view_bytes( 5 ) ) );
	CHECK_NOTHROW( s2.sendto( mart::view_bytes( 5 ), e2 ) );

	CHECK_THROWS( s2.sendto( mart::view_bytes( 5 ), e1 ) ); // invalid target address
}

TEST_CASE( "udp_socket_simple_member_check2", "[net]" )
{
	using namespace mart::nw::ip;
	udp::Socket s {};

	CHECK( s.is_blocking() );

	CHECK_NOTHROW( s.bind( udp::endpoint {"127.0.0.1:3446"} ) );
	using namespace std::chrono_literals;
	CHECK( s.set_rx_timeout( 1ms ) );
	CHECK( s.set_tx_timeout( 2ms ) );
	CHECK( s.get_tx_timeout() == 2ms );
	CHECK( s.get_rx_timeout() == 1ms );

	int buffer = 0;
	CHECK( !s.try_recv( mart::view_bytes_mutable( buffer ) ).isValid() );

	CHECK( s.try_send( mart::view_bytes( buffer ) ).size() != 0 );
	CHECK_THROWS( s.send( mart::view_bytes( buffer ) ).isValid() );
	{
		udp::endpoint e4 {};
		CHECK( s.try_sendto( mart::view_bytes( buffer ), e4 ).size() != 0 );
		CHECK_THROWS( s.sendto( mart::view_bytes( buffer ), e4 ).isValid() );
	}

	CHECK( !s.try_recv( mart::view_bytes_mutable( buffer ) ).isValid() );
	CHECK( !s.try_recvfrom( mart::view_bytes_mutable( buffer ) ).data.isValid() );

	CHECK( !s.recv( mart::view_bytes_mutable( buffer ) ).isValid() );
	CHECK( !s.recvfrom( mart::view_bytes_mutable( buffer ) ).data.isValid() );

	s.clearRxBuff();

	CHECK( s.set_blocking( false ) );
	CHECK( !s.is_blocking() );

	s.close();
	CHECK( !s.is_valid() );
}

TEST_CASE( "invalid_endpoint_strings_fail" )
{
	using namespace mart::nw::ip;
	CHECK_THROWS( udp::endpoint {"127.0.0.1"} );
	CHECK_THROWS( udp::endpoint {"127.0.0:5"} );
	CHECK_THROWS( udp::endpoint {"127005"} );
	CHECK_THROWS( udp::endpoint {"127.0.0.1:66999"} );
	CHECK_THROWS( udp::endpoint {"1.333.0.1:669"} );
}
<|endoftext|>


<commit_before>#include "Edge.hpp"
#include "Node.hpp"
#include "PathNode.hpp"
#include "../util/Vector2fAdapter.hpp"

#include <cassert>

// Christopher D. Canfield
// October 2013
// Edge.cpp

using cdc::Edge;
using cdc::Node;
using cdc::PathNode;

Edge::Edge(cdc::Node& startNode) :
	startNode(&startNode),
	endNode(nullptr),
	cost(999999),
	nextPheromoneReduction(0)
{
	vertices.setPrimitiveType(sf::Lines);
}

Edge::Edge(cdc::Node& startNode, cdc::Node& endNode, float cost) :
	startNode(&startNode),
	endNode(&endNode),
	cost(cost),
	nextPheromoneReduction(0)
{
	setVertices(startNode, endNode);
}

Edge::Edge(Node& startNode, Node& endNode, int cost) :
	startNode(&startNode),
	endNode(&endNode),
	cost(static_cast<float>(cost)),
	nextPheromoneReduction(0)
{
	setVertices(startNode, endNode);
}

void Edge::setVertices(Node& startNode, Node& endNode)
{
	vertices.setPrimitiveType(sf::Lines);

	vertices.append(sf::Vertex(
			Vector2fAdapter(startNode.getPixelX<uint>(), startNode.getPixelY<uint>()),
			sf::Color(0, 0, 255)));

	vertices.append(sf::Vertex(
			Vector2fAdapter(endNode.getPixelX<uint>(), endNode.getPixelY<uint>()),
			sf::Color(0, 0, 255)));

	pheromoneStrongVertices.setPrimitiveType(sf::Lines);
	sf::Vector2f startPoint(startNode.getPixelX<float>(), startNode.getPixelY<float>());
	sf::Vector2f endPoint(endNode.getPixelX<float>(), endNode.getPixelY<float>());
	pheromoneStrongVertices.append(sf::Vertex(startPoint, sf::Color(255, 0, 0)));
	pheromoneStrongVertices.append(sf::Vertex(endPoint, sf::Color(255, 0, 0)));

	pheromoneMediumVertices.setPrimitiveType(sf::Lines);
	sf::Vector2f startPoint2(startNode.getPixelX<float>(), startNode.getPixelY<float>());
	sf::Vector2f endPoint2(endNode.getPixelX<float>(), endNode.getPixelY<float>());
	pheromoneMediumVertices.append(sf::Vertex(startPoint2, sf::Color(255, 145, 0)));
	pheromoneMediumVertices.append(sf::Vertex(endPoint2, sf::Color(255, 145, 0)));

	pheromoneWeakVertices.setPrimitiveType(sf::Lines);
	sf::Vector2f startPoint3(startNode.getPixelX<float>(), startNode.getPixelY<float>());
	sf::Vector2f endPoint3(endNode.getPixelX<float>(), endNode.getPixelY<float>());
	pheromoneWeakVertices.append(sf::Vertex(startPoint3, sf::Color(255, 195, 0)));
	pheromoneWeakVertices.append(sf::Vertex(endPoint3, sf::Color(255, 195, 0)));
}

Node* Edge::getNode1() const
{
	return startNode;
}

Node* Edge::getNode2() const
{
	return endNode;
}

Node* Edge::getOppositeNode(const Node& node) const
{
	if (*startNode == node)
	{
		return endNode;
	}
	else if (*endNode == node)
	{
		return startNode;
	}
	return nullptr;
}

Node* Edge::getOppositeNode(PathNode node) const
{
	return getOppositeNode(node.getNode());
}

float Edge::getCost() const
{
	return cost;
}

uint Edge::getPheromone() const
{
	return pheromone.getStrength();
}

void Edge::increasePheromone()
{
	pheromone.increase();
}

void Edge::increasePheromoneToMax()
{
	pheromone.increaseToMax();
}

void Edge::decreasePheromone()
{
	pheromone.decrease();
}

void Edge::setPheromoneNextNode(Node& node, uint ticks)
{
	pheromone.setNextNode(node, ticks);
}

uint Edge::getPheromoneNextNodeTickTime() const
{
	return pheromone.getNextNodeTickTime();
}

Node* Edge::getPheromoneNextNode() const
{
	return pheromone.getNextNode();
}

void Edge::update(uint ticks)
{
	const int pheromoneReducationRate = 200;

	if (ticks >= nextPheromoneReduction)
	{
		pheromone.decrease();
		nextPheromoneReduction += pheromoneReducationRate;
	}
}

void Edge::draw(sf::RenderTarget& target, sf::RenderStates states) const
{
	if (endNode != nullptr)
	{
		target.draw(vertices, states);
	}
}

void Edge::draw(sf::RenderTarget &target, sf::RenderStates states, sf::Color color) const
{
	using namespace sf;

	if (endNode != nullptr)
	{
		VertexArray path;
		path.setPrimitiveType(sf::Lines);

		path.append(Vertex(Vector2f(startNode->getPixelX<float>(), startNode->getPixelY<float>()), color));
		path.append(Vertex(Vector2f(endNode->getPixelX<float>(), endNode->getPixelY<float>()), color));

		target.draw(path, states);
	}
}

void Edge::drawPheromone(sf::RenderTarget& target, sf::RenderStates states)
{
	auto pheromoneStrength = getPheromone();

	if (pheromoneStrength > 6)
	{
		target.draw(pheromoneStrongVertices, states);
	}
	else if (pheromoneStrength > 3)
	{
		target.draw(pheromoneMediumVertices, states);
	}
	else if (pheromoneStrength > 0)
	{
		target.draw(pheromoneWeakVertices, states);
	}
}

bool Edge::operator==(const Edge& other) const
{
	return (this->getCost() == other.getCost() &&
			this->getNode1() == other.getNode1() &&
			this->getNode2() == other.getNode2() &&
			this->getPheromone() == other.getPheromone());
}

bool Edge::operator!=(const Edge& other) const
{
	return !(*this == other);
}<commit_msg>Increased pheromone decay rate<commit_after>#include "Edge.hpp"
#include "Node.hpp"
#include "PathNode.hpp"
#include "../util/Vector2fAdapter.hpp"

#include <cassert>

// Christopher D. Canfield
// October 2013
// Edge.cpp

using cdc::Edge;
using cdc::Node;
using cdc::PathNode;

Edge::Edge(cdc::Node& startNode) :
	startNode(&startNode),
	endNode(nullptr),
	cost(999999),
	nextPheromoneReduction(0)
{
	vertices.setPrimitiveType(sf::Lines);
}

Edge::Edge(cdc::Node& startNode, cdc::Node& endNode, float cost) :
	startNode(&startNode),
	endNode(&endNode),
	cost(cost),
	nextPheromoneReduction(0)
{
	setVertices(startNode, endNode);
}

Edge::Edge(Node& startNode, Node& endNode, int cost) :
	startNode(&startNode),
	endNode(&endNode),
	cost(static_cast<float>(cost)),
	nextPheromoneReduction(0)
{
	setVertices(startNode, endNode);
}

void Edge::setVertices(Node& startNode, Node& endNode)
{
	vertices.setPrimitiveType(sf::Lines);

	vertices.append(sf::Vertex(
			Vector2fAdapter(startNode.getPixelX<uint>(), startNode.getPixelY<uint>()),
			sf::Color(0, 0, 255)));

	vertices.append(sf::Vertex(
			Vector2fAdapter(endNode.getPixelX<uint>(), endNode.getPixelY<uint>()),
			sf::Color(0, 0, 255)));

	pheromoneStrongVertices.setPrimitiveType(sf::Lines);
	sf::Vector2f startPoint(startNode.getPixelX<float>(), startNode.getPixelY<float>());
	sf::Vector2f endPoint(endNode.getPixelX<float>(), endNode.getPixelY<float>());
	pheromoneStrongVertices.append(sf::Vertex(startPoint, sf::Color(255, 0, 0)));
	pheromoneStrongVertices.append(sf::Vertex(endPoint, sf::Color(255, 0, 0)));

	pheromoneMediumVertices.setPrimitiveType(sf::Lines);
	sf::Vector2f startPoint2(startNode.getPixelX<float>(), startNode.getPixelY<float>());
	sf::Vector2f endPoint2(endNode.getPixelX<float>(), endNode.getPixelY<float>());
	pheromoneMediumVertices.append(sf::Vertex(startPoint2, sf::Color(255, 145, 0)));
	pheromoneMediumVertices.append(sf::Vertex(endPoint2, sf::Color(255, 145, 0)));

	pheromoneWeakVertices.setPrimitiveType(sf::Lines);
	sf::Vector2f startPoint3(startNode.getPixelX<float>(), startNode.getPixelY<float>());
	sf::Vector2f endPoint3(endNode.getPixelX<float>(), endNode.getPixelY<float>());
	pheromoneWeakVertices.append(sf::Vertex(startPoint3, sf::Color(255, 195, 0)));
	pheromoneWeakVertices.append(sf::Vertex(endPoint3, sf::Color(255, 195, 0)));
}

Node* Edge::getNode1() const
{
	return startNode;
}

Node* Edge::getNode2() const
{
	return endNode;
}

Node* Edge::getOppositeNode(const Node& node) const
{
	if (*startNode == node)
	{
		return endNode;
	}
	else if (*endNode == node)
	{
		return startNode;
	}
	return nullptr;
}

Node* Edge::getOppositeNode(PathNode node) const
{
	return getOppositeNode(node.getNode());
}

float Edge::getCost() const
{
	return cost;
}

uint Edge::getPheromone() const
{
	return pheromone.getStrength();
}

void Edge::increasePheromone()
{
	pheromone.increase();
}

void Edge::increasePheromoneToMax()
{
	pheromone.increaseToMax();
}

void Edge::decreasePheromone()
{
	pheromone.decrease();
}

void Edge::setPheromoneNextNode(Node& node, uint ticks)
{
	pheromone.setNextNode(node, ticks);
}

uint Edge::getPheromoneNextNodeTickTime() const
{
	return pheromone.getNextNodeTickTime();
}

Node* Edge::getPheromoneNextNode() const
{
	return pheromone.getNextNode();
}

void Edge::update(uint ticks)
{
	const int pheromoneReducationRate = 100;

	if (ticks >= nextPheromoneReduction)
	{
		pheromone.decrease();
		nextPheromoneReduction += pheromoneReducationRate;
	}
}

void Edge::draw(sf::RenderTarget& target, sf::RenderStates states) const
{
	if (endNode != nullptr)
	{
		target.draw(vertices, states);
	}
}

void Edge::draw(sf::RenderTarget &target, sf::RenderStates states, sf::Color color) const
{
	using namespace sf;

	if (endNode != nullptr)
	{
		VertexArray path;
		path.setPrimitiveType(sf::Lines);

		path.append(Vertex(Vector2f(startNode->getPixelX<float>(), startNode->getPixelY<float>()), color));
		path.append(Vertex(Vector2f(endNode->getPixelX<float>(), endNode->getPixelY<float>()), color));

		target.draw(path, states);
	}
}

void Edge::drawPheromone(sf::RenderTarget& target, sf::RenderStates states)
{
	auto pheromoneStrength = getPheromone();

	if (pheromoneStrength > 6)
	{
		target.draw(pheromoneStrongVertices, states);
	}
	else if (pheromoneStrength > 3)
	{
		target.draw(pheromoneMediumVertices, states);
	}
	else if (pheromoneStrength > 0)
	{
		target.draw(pheromoneWeakVertices, states);
	}
}

bool Edge::operator==(const Edge& other) const
{
	return (this->getCost() == other.getCost() &&
			this->getNode1() == other.getNode1() &&
			this->getNode2() == other.getNode2() &&
			this->getPheromone() == other.getPheromone());
}

bool Edge::operator!=(const Edge& other) const
{
	return !(*this == other);
}<|endoftext|>


<commit_before>// Petter Strandmark 2013.
//
// The code in this file will be incorporated in the main API
// when more compilers support C++14 generic lambdas.
//

#include <cmath>
#include <limits>
#include <random>

// Check if we’re using November 2013 CTP (or newer).
#ifdef _MSC_FULL_VER
	#if _MSC_FULL_VER > 180021005 // 180021005 is RTM, I believe.
		#define USE_GENERIC_LAMBDAS
	#endif
#endif

#define CATCH_CONFIG_MAIN
#include <catch.hpp>

#ifdef USE_GENERIC_LAMBDAS

#include <spii/auto_diff_term.h>
#include <spii/solver.h>
#include <spii/transformations.h>
using namespace spii;

// Creates a differentiable term from a generic lambda and
// argument sizes.
//
// Examples:
//
//	auto lambda_a =
//		[](auto x)
//		{
//			auto d0 =  x[1] - x[0]*x[0];
//			auto d1 =  1 - x[0];
//			return 100 * d0*d0 + d1*d1;
//		};
//
//	auto term_a = make_term<2>(lambda_a);
//
//
//	auto lambda_b =
//		[](auto x, auto y)
//		{
//			auto d0 =  y[0] - x[0]*x[0];
//			auto d1 =  1 - x[0];
//			return 100 * d0*d0 + d1*d1;
//		};
//
//	auto term_b = make_term<1, 1>(lambda);
//
template<int... arg_sizes, typename GenericLambda>
std::shared_ptr<Term> make_term(const GenericLambda& lambda)
{
	typedef spii::AutoDiffTerm<GenericLambda, arg_sizes...> TermType;
	return std::make_shared<TermType>(lambda);
}

TEST_CASE("make_term_2")
{
	Function function;
	std::vector<double> x = {0, 0};

	auto lambda =
		[](auto x)
		{
			auto d0 =  x[1] - x[0]*x[0];
			auto d1 =  1 - x[0];
			return 100 * d0*d0 + d1*d1;
		};

	auto term = make_term<2>(lambda);

	function.add_term(term, x.data());

	NewtonSolver solver;
	std::stringstream sout;
	solver.log_function =
		[&sout](auto str)
		{
			sout << str << std::endl;
		};

	SolverResults results;
	solver.solve(function, &results);
	INFO(sout.str());
	CHECK(std::abs(x[0] - 1.0) < 1e-8);
	CHECK(std::abs(x[1] - 1.0) < 1e-8);
	CHECK(results.exit_success());
}

TEST_CASE("make_term_1_1")
{
	Function function;
	double x;
	double y;

	auto lambda =
		[](auto x, auto y)
		{
			auto d0 =  y[0] - x[0]*x[0];
			auto d1 =  1 - x[0];
			return 100 * d0*d0 + d1*d1;
		};

	auto term = make_term<1, 1>(lambda);

	function.add_term(term, &x, &y);

	NewtonSolver solver;
	std::stringstream sout;
	solver.log_function =
		[&sout](auto str)
		{
			sout << str << std::endl;
		};

	SolverResults results;
	solver.solve(function, &results);
	INFO(sout.str());
	CHECK(std::abs(x - 1.0) < 1e-8);
	CHECK(std::abs(y - 1.0) < 1e-8);
	CHECK(results.exit_success());
}

#endif  // USE_GENERIC_LAMBDAS.
<commit_msg>Test dynamic sizes for AutoDiffTerm with generic lambdas.<commit_after>// Petter Strandmark 2013.
//
// The code in this file will be incorporated in the main API
// when more compilers support C++14 generic lambdas.
//

#include <cmath>
#include <limits>
#include <random>

// Check if we’re using November 2013 CTP (or newer).
#ifdef _MSC_FULL_VER
	#if _MSC_FULL_VER > 180021005 // 180021005 is RTM, I believe.
		#define USE_GENERIC_LAMBDAS
	#endif
#endif

#define CATCH_CONFIG_MAIN
#include <catch.hpp>

#ifdef USE_GENERIC_LAMBDAS

#include <spii/auto_diff_term.h>
#include <spii/dynamic_auto_diff_term.h>
#include <spii/solver.h>
#include <spii/transformations.h>
using namespace spii;

// Creates a differentiable term from a generic lambda and
// argument sizes.
//
// Examples:
//
//	auto lambda_a =
//		[](auto x)
//		{
//			auto d0 =  x[1] - x[0]*x[0];
//			auto d1 =  1 - x[0];
//			return 100 * d0*d0 + d1*d1;
//		};
//
//	auto term_a = make_term<2>(lambda_a);
//
//
//	auto lambda_b =
//		[](auto x, auto y)
//		{
//			auto d0 =  y[0] - x[0]*x[0];
//			auto d1 =  1 - x[0];
//			return 100 * d0*d0 + d1*d1;
//		};
//
//	auto term_b = make_term<1, 1>(lambda);
//
template<int... arg_sizes, typename GenericLambda, typename... Ints>
std::shared_ptr<Term> make_term(const GenericLambda& lambda, Ints... dimensions)
{
	typedef spii::AutoDiffTerm<GenericLambda, arg_sizes...> TermType;
	return std::make_shared<TermType>(dimensions..., lambda);
}

TEST_CASE("make_term_2")
{
	Function function;
	std::vector<double> x = {0, 0};

	auto lambda =
		[](auto x)
		{
			auto d0 =  x[1] - x[0]*x[0];
			auto d1 =  1 - x[0];
			return 100 * d0*d0 + d1*d1;
		};

	auto term = make_term<2>(lambda);

	function.add_term(term, x.data());

	NewtonSolver solver;
	std::stringstream sout;
	solver.log_function =
		[&sout](auto str)
		{
			sout << str << std::endl;
		};

	SolverResults results;
	solver.solve(function, &results);
	INFO(sout.str());
	CHECK(std::abs(x[0] - 1.0) < 1e-8);
	CHECK(std::abs(x[1] - 1.0) < 1e-8);
	CHECK(results.exit_success());
}

TEST_CASE("make_term_1_1")
{
	Function function;
	double x;
	double y;

	auto lambda =
		[](auto x, auto y)
		{
			auto d0 =  y[0] - x[0]*x[0];
			auto d1 =  1 - x[0];
			return 100 * d0*d0 + d1*d1;
		};

	auto term = make_term<1, 1>(lambda);

	function.add_term(term, &x, &y);

	NewtonSolver solver;
	std::stringstream sout;
	solver.log_function =
		[&sout](auto str)
		{
			sout << str << std::endl;
		};

	SolverResults results;
	solver.solve(function, &results);
	INFO(sout.str());
	CHECK(std::abs(x - 1.0) < 1e-8);
	CHECK(std::abs(y - 1.0) < 1e-8);
	CHECK(results.exit_success());
}

TEST_CASE("make_dynamic_term_1_1")
{
	Function function;
	double x;
	double y;

	auto lambda =
		[](auto x, auto y)
	{
		auto d0 = y[0] - x[0] * x[0];
		auto d1 = 1 - x[0];
		return 100 * d0*d0 + d1*d1;
	};

	auto term = make_term<Dynamic, Dynamic>(lambda, 1, 1);

	function.add_term(term, &x, &y);

	NewtonSolver solver;
	std::stringstream sout;
	solver.log_function =
		[&sout](auto str)
	{
		sout << str << std::endl;
	};

	SolverResults results;
	solver.solve(function, &results);
	INFO(sout.str());
	CHECK(std::abs(x - 1.0) < 1e-8);
	CHECK(std::abs(y - 1.0) < 1e-8);
	CHECK(results.exit_success());
}

#endif  // USE_GENERIC_LAMBDAS.
<|endoftext|>