<commit_before>// Copyright (c) 2012 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.

// A binary wrapper for QuicClient.
// Connects to a host using QUIC, sends a request to the provided URL, and
// displays the response.

#include <iostream>

#include "base/at_exit.h"
#include "base/command_line.h"
#include "base/logging.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "net/base/ip_endpoint.h"
#include "net/base/ip_address_number.h"
#include "net/base/net_errors.h"
#include "net/base/privacy_mode.h"
//#include "net/cert/cert_verifier.h"
//#include "net/http/transport_security_state.h"
//#include "net/log/net_log.h"
//#include "net/quic/crypto/proof_verifier_chromium.h"
#include "net/quic/quic_protocol.h"
#include "net/quic/quic_server_id.h"
#include "net/quic/quic_utils.h"
#include "net/quic/quic_config.h"
#include "net/tools/epoll_server/epoll_server.h"
#include "net/tools/quic/quic_client.h"
//#include "net/tools/quic/spdy_balsa_utils.h"
//#include "net/tools/quic/synchronous_host_resolver.h"
//#include "url/gurl.h"

using base::StringPiece;
//using net::CertVerifier;
//using net::ProofVerifierChromium;
//using net::TransportSecurityState;
using std::cout;
using std::cerr;
using std::map;
using std::string;
using std::vector;
using std::endl;

// The IP or hostname the quic client will connect to.
string FLAGS_host = "127.0.0.1";
// The port to connect to.
int32 FLAGS_port = 6121;
// Set to true for a quieter output experience.
bool FLAGS_quiet = false;
// QUIC version to speak, e.g. 21. If not set, then all available versions are
// offered in the handshake.
int32 FLAGS_quic_version = -1;
// If true, a version mismatch in the handshake is not considered a failure.
// Useful for probing a server to determine if it speaks any version of QUIC.
bool FLAGS_version_mismatch_ok = false;
// Enable mTCP-like N-stream simulation for congestion control.
bool FLAGS_mtcp_enabled = false;
// Enable FEC.
bool FLAGS_fec_enabled = false;
// Disable packet pacing.
bool FLAGS_pacing_enabled = true;
// Send N parallel requests.
int32 FLAGS_requests = 1;
// Congestion control with N emulated connections.
int32 FLAGS_emulated_connections = 0;
// Set ICWND to 3.
bool FLAGS_icwnd03 = false;
// Set ICWND to 10.
bool FLAGS_icwnd10 = false;
// Set ICWND to 10.
bool FLAGS_icwnd50 = false;

int main(int argc, char *argv[]) {
  base::CommandLine::Init(argc, argv);
  base::CommandLine* line = base::CommandLine::ForCurrentProcess();
  const base::CommandLine::StringVector& urls = line->GetArgs();

  logging::LoggingSettings settings;
  settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
  CHECK(logging::InitLogging(settings));

  if (line->HasSwitch("h") || line->HasSwitch("help") || urls.empty()) {
    const char* help_str =
        "Usage: quic_client [options] <file-to-download>\n"
        "\n"
        "Options:\n"
        "-h, --help                  show this help message and exit\n"
        "--host=<host>               specify the IP address of the hostname to "
        "connect to\n"
        "--port=<port>               specify the port to connect to\n"
        "--mtcp                      enable mTCP like behavior for congestion control\n"
        "--fec                       enable FEC\n"
        "--emulated-connections=<N>  congestion control with N emulated connections (4,8,16,32,64)\n"
        "--requests=<requests>       send multiple requests of the specified file\n"
        "--disable-pacing            disable packet pacing\n"
        "--icwnd03                   set ICWND to 3\n"
        "--icwnd10                   set ICWND to 10\n"
        "--icwnd50                   set ICWND to 50\n"
        "--quiet                     specify for a quieter output experience\n"
        "--quic-version=<quic version> specify QUIC version to speak\n"
        "--version_mismatch_ok       if specified a version mismatch in the "
        "handshake is not considered a failure\n";
    cout << help_str;
    exit(0);
  }
  if (line->HasSwitch("host")) {
    FLAGS_host = line->GetSwitchValueASCII("host");
  }
  if (line->HasSwitch("port")) {
    if (!base::StringToInt(line->GetSwitchValueASCII("port"), &FLAGS_port)) {
      std::cerr << "--port must be an integer\n";
      return 1;
    }
  }
  if (line->HasSwitch("requests")) {
    if (!base::StringToInt(line->GetSwitchValueASCII("requests"), &FLAGS_requests)) {
      std::cerr << "--requests must be an integer\n";
      return 1;
    }
  }
  if (line->HasSwitch("emulated-connections")) {
    if (!base::StringToInt(line->GetSwitchValueASCII("emulated-connections"),
             &FLAGS_emulated_connections)) {
      std::cerr << "--emulated-connections must be an integer\n";
      return 1;
    }
    if (FLAGS_emulated_connections < 4 || FLAGS_emulated_connections > 64 ||
        (FLAGS_emulated_connections & (FLAGS_emulated_connections - 1)) != 0) {
      std::cerr << "--emulated-connections can be one of the following values: 4,8,16,32,64.";
      return 1;
    }
  }
  if (line->HasSwitch("quiet")) {
    FLAGS_quiet = true;
  }
  if (line->HasSwitch("quic-version")) {
    int quic_version;
    if (base::StringToInt(line->GetSwitchValueASCII("quic-version"),
                          &quic_version)) {
      FLAGS_quic_version = quic_version;
    }
  }
  if (line->HasSwitch("version_mismatch_ok")) {
    FLAGS_version_mismatch_ok = true;
  }
  if (line->HasSwitch("mtcp")) {
    if (FLAGS_emulated_connections == 0) {
      FLAGS_mtcp_enabled = true;
    } else {
      std::cerr << "--mtcp has been suppressed because --emulated-connections is used";
    }
  }
  if (line->HasSwitch("fec")) {
    FLAGS_fec_enabled = true;
  }
  if (line->HasSwitch("disable-pacing")) {
    FLAGS_pacing_enabled = false;
  }
  if (line->HasSwitch("icwnd03")) {
    FLAGS_icwnd03 = true;
  }
  if (line->HasSwitch("icwnd10")) {
    FLAGS_icwnd10 = true;
  }
  if (line->HasSwitch("icwnd50")) {
    FLAGS_icwnd50 = true;
  }

  VLOG(1) << "server host: " << FLAGS_host << " port: " << FLAGS_port
          << " quiet: " << FLAGS_quiet
          << " quic-version: " << FLAGS_quic_version
          << " version_mismatch_ok: " << FLAGS_version_mismatch_ok;

  base::AtExitManager exit_manager;

  net::IPAddressNumber ip_addr;
  if (!net::ParseIPLiteralToNumber(FLAGS_host, &ip_addr)) {
    LOG(ERROR) << "Unable to parse " << FLAGS_host;
    return 1;
  }

  string host_port = net::IPAddressToStringWithPort(ip_addr, FLAGS_port);
  VLOG(1) << "Resolved " << FLAGS_host << " to " << host_port << endl;

  // Build the client, and try to connect.
  net::EpollServer epoll_server;
  net::QuicServerId server_id(FLAGS_host, FLAGS_port, false /*is_https*/,
                              net::PRIVACY_MODE_DISABLED);
  net::QuicVersionVector versions = net::QuicSupportedVersions();
  if (FLAGS_quic_version != -1) {
    versions.clear();
    versions.push_back(static_cast<net::QuicVersion>(FLAGS_quic_version));
  }

  net::QuicConfig config;
  net::QuicTagVector copt;
  if (FLAGS_mtcp_enabled) {
    copt.push_back(net::kNCON);
  }
#if 0
  if (FLAGS_fec_enabled) {
    copt.push_back(net::kFHDR);
    copt.push_back(net::kFSTR);
  }
  if (FLAGS_pacing_enabled) {
    copt.push_back(net::kDPAC);
  }
  if (FLAGS_emulated_connections == 4) {
    copt.push_back(net::k4CON);
  }
  if (FLAGS_emulated_connections == 8) {
    copt.push_back(net::k8CON);
  }
  if (FLAGS_emulated_connections == 16) {
    copt.push_back(net::kDCON);
  }
  if (FLAGS_emulated_connections == 32) {
    copt.push_back(net::kQCON);
  }
  if (FLAGS_emulated_connections == 64) {
    copt.push_back(net::kOCON);
  }
#endif
  if (FLAGS_icwnd03) {
    copt.push_back(net::kIW03);
  }
  if (FLAGS_icwnd10) {
    copt.push_back(net::kIW10);
  }
  if (FLAGS_icwnd50) {
    copt.push_back(net::kIW50);
  }
  config.SetConnectionOptionsToSend(copt);

  net::tools::QuicClient client(net::IPEndPoint(ip_addr, FLAGS_port), server_id,
                                versions, config, &epoll_server);
  if (!client.Initialize()) {
    cerr << "Failed to initialize client." << endl;
    return 1;
  }
  if (!client.Connect()) {
    net::QuicErrorCode error = client.session()->error();
    if (FLAGS_version_mismatch_ok && error == net::QUIC_INVALID_VERSION) {
      cout << "Server talks QUIC, but none of the versions supported by "
           << "this client: " << QuicVersionVectorToString(versions) << endl;
      // Version mismatch is not deemed a failure.
      return 0;
    }
    cerr << "Failed to connect to " << host_port
         << ". Error: " << net::QuicUtils::ErrorToString(error) << endl;
    return 1;
  }
  cout << "Connected to " << host_port << endl;

  // Make sure to store the response, for later output.
  client.set_store_response(true);
  client.SendRequestsAndWaitForResponse(urls);
}
<commit_msg>Added --local-port=<port> option.<commit_after>// Copyright (c) 2012 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.

// A binary wrapper for QuicClient.
// Connects to a host using QUIC, sends a request to the provided URL, and
// displays the response.

#include <iostream>

#include "base/at_exit.h"
#include "base/command_line.h"
#include "base/logging.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "net/base/ip_endpoint.h"
#include "net/base/ip_address_number.h"
#include "net/base/net_errors.h"
#include "net/base/privacy_mode.h"
//#include "net/cert/cert_verifier.h"
//#include "net/http/transport_security_state.h"
//#include "net/log/net_log.h"
//#include "net/quic/crypto/proof_verifier_chromium.h"
#include "net/quic/quic_protocol.h"
#include "net/quic/quic_server_id.h"
#include "net/quic/quic_utils.h"
#include "net/quic/quic_config.h"
#include "net/tools/epoll_server/epoll_server.h"
#include "net/tools/quic/quic_client.h"
//#include "net/tools/quic/spdy_balsa_utils.h"
//#include "net/tools/quic/synchronous_host_resolver.h"
//#include "url/gurl.h"

using base::StringPiece;
//using net::CertVerifier;
//using net::ProofVerifierChromium;
//using net::TransportSecurityState;
using std::cout;
using std::cerr;
using std::map;
using std::string;
using std::vector;
using std::endl;

// The IP or hostname the quic client will connect to.
string FLAGS_host = "127.0.0.1";
// The port to connect to.
int32 FLAGS_port = 6121;
// The local port to connect from.
int32 FLAGS_local_port = 0;
// Set to true for a quieter output experience.
bool FLAGS_quiet = false;
// QUIC version to speak, e.g. 21. If not set, then all available versions are
// offered in the handshake.
int32 FLAGS_quic_version = -1;
// If true, a version mismatch in the handshake is not considered a failure.
// Useful for probing a server to determine if it speaks any version of QUIC.
bool FLAGS_version_mismatch_ok = false;
// Enable mTCP-like N-stream simulation for congestion control.
bool FLAGS_mtcp_enabled = false;
// Enable FEC.
bool FLAGS_fec_enabled = false;
// Disable packet pacing.
bool FLAGS_pacing_enabled = true;
// Send N parallel requests.
int32 FLAGS_requests = 1;
// Congestion control with N emulated connections.
int32 FLAGS_emulated_connections = 0;
// Set ICWND to 3.
bool FLAGS_icwnd03 = false;
// Set ICWND to 10.
bool FLAGS_icwnd10 = false;
// Set ICWND to 10.
bool FLAGS_icwnd50 = false;

int main(int argc, char *argv[]) {
  base::CommandLine::Init(argc, argv);
  base::CommandLine* line = base::CommandLine::ForCurrentProcess();
  const base::CommandLine::StringVector& urls = line->GetArgs();

  logging::LoggingSettings settings;
  settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
  CHECK(logging::InitLogging(settings));

  if (line->HasSwitch("h") || line->HasSwitch("help") || urls.empty()) {
    const char* help_str =
        "Usage: quic_client [options] <file-to-download>\n"
        "\n"
        "Options:\n"
        "-h, --help                  show this help message and exit\n"
        "--host=<host>               specify the IP address of the hostname to "
        "connect to\n"
        "--port=<port>               specify the port to connect to\n"
        "--local-port=<port>         specify the local-port to connect from\n"
        "--mtcp                      enable mTCP like behavior for congestion control\n"
        "--fec                       enable FEC\n"
        "--emulated-connections=<N>  congestion control with N emulated connections (4,8,16,32,64)\n"
        "--requests=<requests>       send multiple requests of the specified file\n"
        "--disable-pacing            disable packet pacing\n"
        "--icwnd03                   set ICWND to 3\n"
        "--icwnd10                   set ICWND to 10\n"
        "--icwnd50                   set ICWND to 50\n"
        "--quiet                     specify for a quieter output experience\n"
        "--quic-version=<quic version> specify QUIC version to speak\n"
        "--version_mismatch_ok       if specified a version mismatch in the "
        "handshake is not considered a failure\n";
    cout << help_str;
    exit(0);
  }
  if (line->HasSwitch("host")) {
    FLAGS_host = line->GetSwitchValueASCII("host");
  }
  if (line->HasSwitch("port")) {
    if (!base::StringToInt(line->GetSwitchValueASCII("port"), &FLAGS_port)) {
      std::cerr << "--port must be an integer\n";
      return 1;
    }
  }
  if (line->HasSwitch("local-port")) {
    if (!base::StringToInt(line->GetSwitchValueASCII("local-port"), &FLAGS_local_port)) {
      std::cerr << "--local-port must be an integer\n";
      return 1;
    }
  }
  if (line->HasSwitch("requests")) {
    if (!base::StringToInt(line->GetSwitchValueASCII("requests"), &FLAGS_requests)) {
      std::cerr << "--requests must be an integer\n";
      return 1;
    }
  }
  if (line->HasSwitch("emulated-connections")) {
    if (!base::StringToInt(line->GetSwitchValueASCII("emulated-connections"),
             &FLAGS_emulated_connections)) {
      std::cerr << "--emulated-connections must be an integer\n";
      return 1;
    }
    if (FLAGS_emulated_connections < 4 || FLAGS_emulated_connections > 64 ||
        (FLAGS_emulated_connections & (FLAGS_emulated_connections - 1)) != 0) {
      std::cerr << "--emulated-connections can be one of the following values: 4,8,16,32,64.";
      return 1;
    }
  }
  if (line->HasSwitch("quiet")) {
    FLAGS_quiet = true;
  }
  if (line->HasSwitch("quic-version")) {
    int quic_version;
    if (base::StringToInt(line->GetSwitchValueASCII("quic-version"),
                          &quic_version)) {
      FLAGS_quic_version = quic_version;
    }
  }
  if (line->HasSwitch("version_mismatch_ok")) {
    FLAGS_version_mismatch_ok = true;
  }
  if (line->HasSwitch("mtcp")) {
    if (FLAGS_emulated_connections == 0) {
      FLAGS_mtcp_enabled = true;
    } else {
      std::cerr << "--mtcp has been suppressed because --emulated-connections is used";
    }
  }
  if (line->HasSwitch("fec")) {
    FLAGS_fec_enabled = true;
  }
  if (line->HasSwitch("disable-pacing")) {
    FLAGS_pacing_enabled = false;
  }
  if (line->HasSwitch("icwnd03")) {
    FLAGS_icwnd03 = true;
  }
  if (line->HasSwitch("icwnd10")) {
    FLAGS_icwnd10 = true;
  }
  if (line->HasSwitch("icwnd50")) {
    FLAGS_icwnd50 = true;
  }

  VLOG(1) << "server host: " << FLAGS_host << " port: " << FLAGS_port
          << " quiet: " << FLAGS_quiet
          << " quic-version: " << FLAGS_quic_version
          << " version_mismatch_ok: " << FLAGS_version_mismatch_ok;

  base::AtExitManager exit_manager;

  net::IPAddressNumber ip_addr;
  if (!net::ParseIPLiteralToNumber(FLAGS_host, &ip_addr)) {
    LOG(ERROR) << "Unable to parse " << FLAGS_host;
    return 1;
  }

  string host_port = net::IPAddressToStringWithPort(ip_addr, FLAGS_port);
  VLOG(1) << "Resolved " << FLAGS_host << " to " << host_port << endl;

  // Build the client, and try to connect.
  net::EpollServer epoll_server;
  net::QuicServerId server_id(FLAGS_host, FLAGS_port, false /*is_https*/,
                              net::PRIVACY_MODE_DISABLED);
  net::QuicVersionVector versions = net::QuicSupportedVersions();
  if (FLAGS_quic_version != -1) {
    versions.clear();
    versions.push_back(static_cast<net::QuicVersion>(FLAGS_quic_version));
  }

  net::QuicConfig config;
  net::QuicTagVector copt;
  if (FLAGS_mtcp_enabled) {
    copt.push_back(net::kNCON);
  }
#if 0
  if (FLAGS_fec_enabled) {
    copt.push_back(net::kFHDR);
    copt.push_back(net::kFSTR);
  }
  if (FLAGS_pacing_enabled) {
    copt.push_back(net::kDPAC);
  }
  if (FLAGS_emulated_connections == 4) {
    copt.push_back(net::k4CON);
  }
  if (FLAGS_emulated_connections == 8) {
    copt.push_back(net::k8CON);
  }
  if (FLAGS_emulated_connections == 16) {
    copt.push_back(net::kDCON);
  }
  if (FLAGS_emulated_connections == 32) {
    copt.push_back(net::kQCON);
  }
  if (FLAGS_emulated_connections == 64) {
    copt.push_back(net::kOCON);
  }
#endif
  if (FLAGS_icwnd03) {
    copt.push_back(net::kIW03);
  }
  if (FLAGS_icwnd10) {
    copt.push_back(net::kIW10);
  }
  if (FLAGS_icwnd50) {
    copt.push_back(net::kIW50);
  }
  config.SetConnectionOptionsToSend(copt);

  net::tools::QuicClient client(net::IPEndPoint(ip_addr, FLAGS_port), server_id,
                                versions, config, &epoll_server);
  client.set_local_port(FLAGS_local_port);

  if (!client.Initialize()) {
    cerr << "Failed to initialize client." << endl;
    return 1;
  }
  if (!client.Connect()) {
    net::QuicErrorCode error = client.session()->error();
    if (FLAGS_version_mismatch_ok && error == net::QUIC_INVALID_VERSION) {
      cout << "Server talks QUIC, but none of the versions supported by "
           << "this client: " << QuicVersionVectorToString(versions) << endl;
      // Version mismatch is not deemed a failure.
      return 0;
    }
    cerr << "Failed to connect to " << host_port
         << ". Error: " << net::QuicUtils::ErrorToString(error) << endl;
    return 1;
  }
  cout << "Connected to " << host_port << endl;

  // Make sure to store the response, for later output.
  client.set_store_response(true);
  client.SendRequestsAndWaitForResponse(urls);
}
<|endoftext|>


<commit_before>//===--- UsePrespecialized.cpp - use pre-specialized functions ------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
/// An optimization which marks functions and types as inlinable or usable
/// from inline. This lets such functions be serialized (later in the pipeline),
/// which makes them available for other modules.
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "cross-module-serialization-setup"
#include "swift/SILOptimizer/PassManager/Passes.h"
#include "swift/SILOptimizer/PassManager/Transforms.h"
#include "swift/SILOptimizer/Utils/InstOptUtils.h"
#include "swift/SIL/ApplySite.h"
#include "swift/SIL/SILFunction.h"
#include "swift/SIL/SILModule.h"
#include "swift/SIL/SILCloner.h"
#include "swift/AST/Module.h"
#include "llvm/Support/Debug.h"

using namespace swift;

namespace {

/// Scans a whole module and marks functions and types as inlinable or usable
/// from inline.
class CrossModuleSerializationSetup {
  friend class InstructionVisitor;

  // The worklist of function which should be serialized.
  llvm::SmallVector<SILFunction *, 16> workList;
  llvm::SmallPtrSet<SILFunction *, 16> functionsHandled;

  llvm::SmallPtrSet<TypeBase *, 16> typesHandled;

  SILModule &M;

  void addToWorklistIfNotHandled(SILFunction *F) {
    if (functionsHandled.count(F) == 0) {
      workList.push_back(F);
      functionsHandled.insert(F);
    }
  }

  bool setUpForSerialization(SILFunction *F);

  void prepareInstructionForSerialization(SILInstruction *inst);

  void handleReferencedFunction(SILFunction *F);

  void handleReferencedMethod(SILDeclRef method);

  void makeTypeUsableFromInline(CanType type);

  void makeSubstUsableFromInline(const SubstitutionMap &substs);

public:
  CrossModuleSerializationSetup(SILModule &M) : M(M) { }

  void scanModule();
};

static bool canUseFromInline(SILFunction *F) {
  if (!F)
    return false;

  switch (F->getLinkage()) {
  case SILLinkage::PublicNonABI:
  case SILLinkage::Shared:
    return F->isSerialized() != IsNotSerialized;
  case SILLinkage::Public:
  case SILLinkage::Hidden:
  case SILLinkage::Private:
  case SILLinkage::PublicExternal:
  case SILLinkage::SharedExternal:
  case SILLinkage::PrivateExternal:
  case SILLinkage::HiddenExternal:
    break;
  }

  return true;
}

/// Visitor for making used types of an intruction inlinable.
///
/// We use the SILCloner for visiting types, though it sucks that we allocate
/// instructions just to delete them immediately. But it's better than to
/// reimplement the logic.
/// TODO: separate the type visiting logic in SILCloner from the instruction
/// creation.
class InstructionVisitor : public SILCloner<InstructionVisitor> {
  friend class SILCloner<InstructionVisitor>;
  friend class SILInstructionVisitor<InstructionVisitor>;

private:
  CrossModuleSerializationSetup &CMS;
  SILInstruction *result = nullptr;

public:
  InstructionVisitor(SILFunction *F, CrossModuleSerializationSetup &CMS) :
    SILCloner(*F), CMS(CMS) {}

  SILType remapType(SILType Ty) {
    CMS.makeTypeUsableFromInline(Ty.getASTType());
    return Ty;
  }

  CanType remapASTType(CanType Ty) {
    CMS.makeTypeUsableFromInline(Ty);
    return Ty;
  }

  SubstitutionMap remapSubstitutionMap(SubstitutionMap Subs) {
    CMS.makeSubstUsableFromInline(Subs);
    return Subs;
  }

  void postProcess(SILInstruction *Orig, SILInstruction *Cloned) {
    result = Cloned;
    SILCloner<InstructionVisitor>::postProcess(Orig, Cloned);
  }

  SILValue getMappedValue(SILValue Value) { return Value; }

  SILBasicBlock *remapBasicBlock(SILBasicBlock *BB) { return BB; }

  static void visitInst(SILInstruction *I, CrossModuleSerializationSetup &CMS) {
    InstructionVisitor visitor(I->getFunction(), CMS);
    visitor.visit(I);

    SILInstruction::destroy(visitor.result);
    CMS.M.deallocateInst(visitor.result);
  }
};

/// Make a nominal type, including it's context, usable from inline.
static void makeDeclUsableFromInline(ValueDecl *decl, SILModule &M) {
  if (decl->getEffectiveAccess() >= AccessLevel::Public)
    return;

  if (!decl->isUsableFromInline()) {
    // Mark the nominal type as "usableFromInline".
    // TODO: find a way to do this without modifying the AST. The AST should be
    // immutable at this point.
    auto &ctx = decl->getASTContext();
    auto *attr = new (ctx) UsableFromInlineAttr(/*implicit=*/true);
    decl->getAttrs().add(attr);
  }
  if (auto *nominalCtx = dyn_cast<NominalTypeDecl>(decl->getDeclContext())) {
    makeDeclUsableFromInline(nominalCtx, M);
  } else if (auto *extCtx = dyn_cast<ExtensionDecl>(decl->getDeclContext())) {
    if (auto *extendedNominal = extCtx->getExtendedNominal()) {
      makeDeclUsableFromInline(extendedNominal, M);
    }
  } else if (decl->getDeclContext()->isLocalContext()) {
    // TODO
  }
}

/// Ensure that the \p type is usable from serialized functions.
void CrossModuleSerializationSetup::makeTypeUsableFromInline(CanType type) {
  if (!typesHandled.insert(type.getPointer()).second)
    return;

  if (NominalTypeDecl *NT = type->getNominalOrBoundGenericNominal()) {
    makeDeclUsableFromInline(NT, M);
  }

  // Also make all sub-types usable from inline.
  type.visit([this](Type rawSubType) {
    CanType subType = rawSubType->getCanonicalType();
    if (typesHandled.insert(subType.getPointer()).second) {
      if (NominalTypeDecl *subNT = subType->getNominalOrBoundGenericNominal()) {
        makeDeclUsableFromInline(subNT, M);
      }
    }
  });
}

/// Ensure that all replacement types of \p substs are usable from serialized
/// functions.
void CrossModuleSerializationSetup::
makeSubstUsableFromInline(const SubstitutionMap &substs) {
  for (Type replType : substs.getReplacementTypes()) {
    makeTypeUsableFromInline(replType->getCanonicalType());
  }
  for (ProtocolConformanceRef pref : substs.getConformances()) {
    if (pref.isConcrete()) {
      ProtocolConformance *concrete = pref.getConcrete();
      makeDeclUsableFromInline(concrete->getProtocol(), M);
    }
  }
}

/// Decide whether to serialize a function.
static bool shouldSerialize(SILFunction *F) {
  // The basic heursitic: serialize all generic functions, because it makes a
  // huge difference if generic functions can be specialized or not.
  if (!F->getLoweredFunctionType()->isPolymorphic())
    return false;

  // Check if we already handled this function before.
  if (F->isSerialized() == IsSerialized)
    return false;

  if (F->hasSemanticsAttr("optimize.no.crossmodule"))
    return false;

  return true;
}

static void makeFunctionUsableFromInline(SILFunction *F) {
  if (!isAvailableExternally(F->getLinkage()))
    F->setLinkage(SILLinkage::Public);
}

/// Prepare \p inst for serialization and in case it's a function_ref, put the
/// referenced function onto the worklist.
void CrossModuleSerializationSetup::
prepareInstructionForSerialization(SILInstruction *inst) {
  // Make all types of the instruction usable from inline.
  InstructionVisitor::visitInst(inst, *this);

  // Put callees onto the worklist if they should be serialized as well.
  if (auto *FRI = dyn_cast<FunctionRefBaseInst>(inst)) {
    SILFunction *callee = FRI->getReferencedFunctionOrNull();
    assert(callee);
    handleReferencedFunction(callee);
    return;
  }
  if (auto *MI = dyn_cast<MethodInst>(inst)) {
    handleReferencedMethod(MI->getMember());
    return;
  }
  if (auto *KPI = dyn_cast<KeyPathInst>(inst)) {
    KPI->getPattern()->visitReferencedFunctionsAndMethods(
        [this](SILFunction *func) { handleReferencedFunction(func); },
        [this](SILDeclRef method) { handleReferencedMethod(method); });
    return;
  }
  if (auto *REAI = dyn_cast<RefElementAddrInst>(inst)) {
    makeDeclUsableFromInline(REAI->getField(), M);
  }
}

void CrossModuleSerializationSetup::handleReferencedFunction(SILFunction *func) {
  if (!func->isDefinition() || func->isAvailableExternally())
    return;
  if (shouldSerialize(func)) {
    addToWorklistIfNotHandled(func);
  } else {
    makeFunctionUsableFromInline(func);
  }
}

void CrossModuleSerializationSetup::handleReferencedMethod(SILDeclRef method) {
  if (method.isForeign)
    return;
  // Prevent the method from dead-method elimination.
  auto *methodDecl = cast<AbstractFunctionDecl>(method.getDecl());
  M.addExternallyVisibleDecl(getBaseMethod(methodDecl));
}

/// Setup the function \p param F for serialization and put callees onto the
/// worklist for further processing.
///
/// Returns false in case this is not possible for some reason.
bool CrossModuleSerializationSetup::setUpForSerialization(SILFunction *F) {
  // First step: check if serializing F is even possible.
  for (SILBasicBlock &block : *F) {
    for (SILInstruction &inst : block) {
      if (auto *FRI = dyn_cast<FunctionRefBaseInst>(&inst)) {
        SILFunction *callee = FRI->getReferencedFunctionOrNull();
        if (!canUseFromInline(callee))
          return false;
      } else if (auto *KPI = dyn_cast<KeyPathInst>(&inst)) {
        bool canUse = true;
        KPI->getPattern()->visitReferencedFunctionsAndMethods(
            [&](SILFunction *func) {
              if (!canUseFromInline(func))
                canUse = false;
            },
            [](SILDeclRef method) { });
        if (!canUse)
          return false;
      }
    }
  }

  // Second step: go through all instructions and prepare them for
  // for serialization.
  for (SILBasicBlock &block : *F) {
    for (SILInstruction &inst : block) {
      prepareInstructionForSerialization(&inst);
    }
  }
  return true;
}

/// Select functions in the module which should be serialized.
void CrossModuleSerializationSetup::scanModule() {

  // Start with public functions.
  for (SILFunction &F : M) {
    if (F.getLinkage() == SILLinkage::Public)
      addToWorklistIfNotHandled(&F);
  }

  // Continue with called functions.
  while (!workList.empty()) {
    SILFunction *F = workList.pop_back_val();
    // Decide whether we want to serialize the function.
    if (shouldSerialize(F)) {
      // Try to serialize.
      if (setUpForSerialization(F)) {
        F->setSerialized(IsSerialized);

        // As a code size optimization, make serialized functions
        // @alwaysEmitIntoClient.
        F->setLinkage(SILLinkage::PublicNonABI);
      } else {
        // If for some reason the function cannot be serialized, we mark it as
        // usable-from-inline.
        makeFunctionUsableFromInline(F);
      }
    }
  }
}

class CrossModuleSerializationSetupPass: public SILModuleTransform {
  void run() override {

    auto &M = *getModule();
    if (M.getSwiftModule()->isResilient())
      return;
    if (!M.isWholeModule())
      return;
    if (!M.getOptions().CrossModuleOptimization)
      return;

    CrossModuleSerializationSetup CMSS(M);
    CMSS.scanModule();
  }
};

} // end anonymous namespace

SILTransform *swift::createCrossModuleSerializationSetup() {
  return new CrossModuleSerializationSetupPass();
}
<commit_msg>CrossModuleSerializationSetup: don't make shared functions usableFromInline<commit_after>//===--- UsePrespecialized.cpp - use pre-specialized functions ------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
/// An optimization which marks functions and types as inlinable or usable
/// from inline. This lets such functions be serialized (later in the pipeline),
/// which makes them available for other modules.
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "cross-module-serialization-setup"
#include "swift/SILOptimizer/PassManager/Passes.h"
#include "swift/SILOptimizer/PassManager/Transforms.h"
#include "swift/SILOptimizer/Utils/InstOptUtils.h"
#include "swift/SIL/ApplySite.h"
#include "swift/SIL/SILFunction.h"
#include "swift/SIL/SILModule.h"
#include "swift/SIL/SILCloner.h"
#include "swift/AST/Module.h"
#include "llvm/Support/Debug.h"

using namespace swift;

namespace {

/// Scans a whole module and marks functions and types as inlinable or usable
/// from inline.
class CrossModuleSerializationSetup {
  friend class InstructionVisitor;

  // The worklist of function which should be serialized.
  llvm::SmallVector<SILFunction *, 16> workList;
  llvm::SmallPtrSet<SILFunction *, 16> functionsHandled;

  llvm::SmallPtrSet<TypeBase *, 16> typesHandled;

  SILModule &M;

  void addToWorklistIfNotHandled(SILFunction *F) {
    if (functionsHandled.count(F) == 0) {
      workList.push_back(F);
      functionsHandled.insert(F);
    }
  }

  bool canUseFromInline(SILFunction *F, bool lookIntoThunks);

  bool canSerialize(SILFunction *F, bool lookIntoThunks);

  void setUpForSerialization(SILFunction *F);

  void prepareInstructionForSerialization(SILInstruction *inst);

  void handleReferencedFunction(SILFunction *F);

  void handleReferencedMethod(SILDeclRef method);

  void makeTypeUsableFromInline(CanType type);

  void makeSubstUsableFromInline(const SubstitutionMap &substs);

public:
  CrossModuleSerializationSetup(SILModule &M) : M(M) { }

  void scanModule();
};

/// Visitor for making used types of an intruction inlinable.
///
/// We use the SILCloner for visiting types, though it sucks that we allocate
/// instructions just to delete them immediately. But it's better than to
/// reimplement the logic.
/// TODO: separate the type visiting logic in SILCloner from the instruction
/// creation.
class InstructionVisitor : public SILCloner<InstructionVisitor> {
  friend class SILCloner<InstructionVisitor>;
  friend class SILInstructionVisitor<InstructionVisitor>;

private:
  CrossModuleSerializationSetup &CMS;
  SILInstruction *result = nullptr;

public:
  InstructionVisitor(SILFunction *F, CrossModuleSerializationSetup &CMS) :
    SILCloner(*F), CMS(CMS) {}

  SILType remapType(SILType Ty) {
    CMS.makeTypeUsableFromInline(Ty.getASTType());
    return Ty;
  }

  CanType remapASTType(CanType Ty) {
    CMS.makeTypeUsableFromInline(Ty);
    return Ty;
  }

  SubstitutionMap remapSubstitutionMap(SubstitutionMap Subs) {
    CMS.makeSubstUsableFromInline(Subs);
    return Subs;
  }

  void postProcess(SILInstruction *Orig, SILInstruction *Cloned) {
    result = Cloned;
    SILCloner<InstructionVisitor>::postProcess(Orig, Cloned);
  }

  SILValue getMappedValue(SILValue Value) { return Value; }

  SILBasicBlock *remapBasicBlock(SILBasicBlock *BB) { return BB; }

  static void visitInst(SILInstruction *I, CrossModuleSerializationSetup &CMS) {
    InstructionVisitor visitor(I->getFunction(), CMS);
    visitor.visit(I);

    SILInstruction::destroy(visitor.result);
    CMS.M.deallocateInst(visitor.result);
  }
};

/// Make a nominal type, including it's context, usable from inline.
static void makeDeclUsableFromInline(ValueDecl *decl, SILModule &M) {
  if (decl->getEffectiveAccess() >= AccessLevel::Public)
    return;

  if (!decl->isUsableFromInline()) {
    // Mark the nominal type as "usableFromInline".
    // TODO: find a way to do this without modifying the AST. The AST should be
    // immutable at this point.
    auto &ctx = decl->getASTContext();
    auto *attr = new (ctx) UsableFromInlineAttr(/*implicit=*/true);
    decl->getAttrs().add(attr);
  }
  if (auto *nominalCtx = dyn_cast<NominalTypeDecl>(decl->getDeclContext())) {
    makeDeclUsableFromInline(nominalCtx, M);
  } else if (auto *extCtx = dyn_cast<ExtensionDecl>(decl->getDeclContext())) {
    if (auto *extendedNominal = extCtx->getExtendedNominal()) {
      makeDeclUsableFromInline(extendedNominal, M);
    }
  } else if (decl->getDeclContext()->isLocalContext()) {
    // TODO
  }
}

/// Ensure that the \p type is usable from serialized functions.
void CrossModuleSerializationSetup::makeTypeUsableFromInline(CanType type) {
  if (!typesHandled.insert(type.getPointer()).second)
    return;

  if (NominalTypeDecl *NT = type->getNominalOrBoundGenericNominal()) {
    makeDeclUsableFromInline(NT, M);
  }

  // Also make all sub-types usable from inline.
  type.visit([this](Type rawSubType) {
    CanType subType = rawSubType->getCanonicalType();
    if (typesHandled.insert(subType.getPointer()).second) {
      if (NominalTypeDecl *subNT = subType->getNominalOrBoundGenericNominal()) {
        makeDeclUsableFromInline(subNT, M);
      }
    }
  });
}

/// Ensure that all replacement types of \p substs are usable from serialized
/// functions.
void CrossModuleSerializationSetup::
makeSubstUsableFromInline(const SubstitutionMap &substs) {
  for (Type replType : substs.getReplacementTypes()) {
    makeTypeUsableFromInline(replType->getCanonicalType());
  }
  for (ProtocolConformanceRef pref : substs.getConformances()) {
    if (pref.isConcrete()) {
      ProtocolConformance *concrete = pref.getConcrete();
      makeDeclUsableFromInline(concrete->getProtocol(), M);
    }
  }
}

/// Decide whether to serialize a function.
static bool shouldSerialize(SILFunction *F) {
  // The basic heursitic: serialize all generic functions, because it makes a
  // huge difference if generic functions can be specialized or not.
  if (!F->getLoweredFunctionType()->isPolymorphic())
    return false;

  // Check if we already handled this function before.
  if (F->isSerialized() == IsSerialized)
    return false;

  if (F->hasSemanticsAttr("optimize.no.crossmodule"))
    return false;

  return true;
}

static void makeFunctionUsableFromInline(SILFunction *F) {
  if (!isAvailableExternally(F->getLinkage()))
    F->setLinkage(SILLinkage::Public);
}

/// Prepare \p inst for serialization and in case it's a function_ref, put the
/// referenced function onto the worklist.
void CrossModuleSerializationSetup::
prepareInstructionForSerialization(SILInstruction *inst) {
  // Make all types of the instruction usable from inline.
  InstructionVisitor::visitInst(inst, *this);

  // Put callees onto the worklist if they should be serialized as well.
  if (auto *FRI = dyn_cast<FunctionRefBaseInst>(inst)) {
    SILFunction *callee = FRI->getReferencedFunctionOrNull();
    assert(callee);
    handleReferencedFunction(callee);
    return;
  }
  if (auto *MI = dyn_cast<MethodInst>(inst)) {
    handleReferencedMethod(MI->getMember());
    return;
  }
  if (auto *KPI = dyn_cast<KeyPathInst>(inst)) {
    KPI->getPattern()->visitReferencedFunctionsAndMethods(
        [this](SILFunction *func) { handleReferencedFunction(func); },
        [this](SILDeclRef method) { handleReferencedMethod(method); });
    return;
  }
  if (auto *REAI = dyn_cast<RefElementAddrInst>(inst)) {
    makeDeclUsableFromInline(REAI->getField(), M);
  }
}

void CrossModuleSerializationSetup::handleReferencedFunction(SILFunction *func) {
  if (!func->isDefinition() || func->isAvailableExternally())
    return;
  if (func->getLinkage() == SILLinkage::Shared) {
    assert(func->isThunk() != IsNotThunk &&
      "only thunks are accepted to have shared linkage");
    assert(canSerialize(func, /*lookIntoThunks*/ false) &&
      "we should already have checked that the thunk is serializable");

    if (func->isSerialized() == IsSerialized)
      return;

    // We cannot make shared functions "usableFromInline", i.e. make them Public
    // because this could result in duplicate-symbol errors. Instead we make
    // them "@alwaysEmitIntoClient"
    setUpForSerialization(func);
    return;
  }
  if (shouldSerialize(func)) {
    addToWorklistIfNotHandled(func);
    return;
  }
  makeFunctionUsableFromInline(func);
  return;
}

void CrossModuleSerializationSetup::handleReferencedMethod(SILDeclRef method) {
  if (method.isForeign)
    return;
  // Prevent the method from dead-method elimination.
  auto *methodDecl = cast<AbstractFunctionDecl>(method.getDecl());
  M.addExternallyVisibleDecl(getBaseMethod(methodDecl));
}

/// Check if the function \p F can be serialized.
///
/// If \p lookIntoThunks is true, function_ref instructions of shared
/// thunks are also accepted.
bool CrossModuleSerializationSetup::canSerialize(SILFunction *F,
                                                 bool lookIntoThunks) {
  // First step: check if serializing F is even possible.
  for (SILBasicBlock &block : *F) {
    for (SILInstruction &inst : block) {
      if (auto *FRI = dyn_cast<FunctionRefBaseInst>(&inst)) {
        SILFunction *callee = FRI->getReferencedFunctionOrNull();
        if (!canUseFromInline(callee, lookIntoThunks))
          return false;
      } else if (auto *KPI = dyn_cast<KeyPathInst>(&inst)) {
        bool canUse = true;
        KPI->getPattern()->visitReferencedFunctionsAndMethods(
            [&](SILFunction *func) {
              if (!canUseFromInline(func, lookIntoThunks))
                canUse = false;
            },
            [](SILDeclRef method) { });
        if (!canUse)
          return false;
      }
    }
  }
  return true;
}

/// Returns true if the function \p func can be used from a serialized function.
///
/// If \p lookIntoThunks is true, serializable shared thunks are also accepted.
bool CrossModuleSerializationSetup::canUseFromInline(SILFunction *func,
                                                     bool lookIntoThunks) {
  if (!func)
    return false;

  switch (func->getLinkage()) {
  case SILLinkage::PublicNonABI:
    return func->isSerialized() != IsNotSerialized;
  case SILLinkage::Shared:
    if (func->isThunk() != IsNotThunk && lookIntoThunks &&
        // Don't recursively lookIntoThunks to avoid infinite loops.
        canSerialize(func, /*lookIntoThunks*/ false)) {
      return true;
    }
    return false;
  case SILLinkage::Public:
  case SILLinkage::Hidden:
  case SILLinkage::Private:
  case SILLinkage::PublicExternal:
  case SILLinkage::SharedExternal:
  case SILLinkage::PrivateExternal:
  case SILLinkage::HiddenExternal:
    break;
  }
  return true;
}

/// Setup the function \p param F for serialization and put callees onto the
/// worklist for further processing.
///
/// Returns false in case this is not possible for some reason.
void CrossModuleSerializationSetup::setUpForSerialization(SILFunction *F) {
  assert(F->isSerialized() != IsSerialized);

  // Second step: go through all instructions and prepare them for
  // for serialization.
  for (SILBasicBlock &block : *F) {
    for (SILInstruction &inst : block) {
      prepareInstructionForSerialization(&inst);
    }
  }
  F->setSerialized(IsSerialized);

  // As a code size optimization, make serialized functions
  // @alwaysEmitIntoClient.
  // Also, for shared thunks it's required to make them @alwaysEmitIntoClient.
  // SILLinkage::Public would not work for shared functions, because it could
  // result in duplicate-symbol linker errors.
  F->setLinkage(SILLinkage::PublicNonABI);
}

/// Select functions in the module which should be serialized.
void CrossModuleSerializationSetup::scanModule() {

  // Start with public functions.
  for (SILFunction &F : M) {
    if (F.getLinkage() == SILLinkage::Public)
      addToWorklistIfNotHandled(&F);
  }

  // Continue with called functions.
  while (!workList.empty()) {
    SILFunction *F = workList.pop_back_val();
    // Decide whether we want to serialize the function.
    if (shouldSerialize(F)) {
      // Try to serialize.
      if (canSerialize(F, /*lookIntoThunks*/ true)) {
        setUpForSerialization(F);
      } else {
        // If for some reason the function cannot be serialized, we mark it as
        // usable-from-inline.
        makeFunctionUsableFromInline(F);
      }
    }
  }
}

class CrossModuleSerializationSetupPass: public SILModuleTransform {
  void run() override {

    auto &M = *getModule();
    if (M.getSwiftModule()->isResilient())
      return;
    if (!M.isWholeModule())
      return;
    if (!M.getOptions().CrossModuleOptimization)
      return;

    CrossModuleSerializationSetup CMSS(M);
    CMSS.scanModule();
  }
};

} // end anonymous namespace

SILTransform *swift::createCrossModuleSerializationSetup() {
  return new CrossModuleSerializationSetupPass();
}
<|endoftext|>


<commit_before>#include <iostream>
#include "server.h"
#include <vector>
#include "tclap/CmdLine.h"
#include "packets/Packet.h"

int main(int argc, char **argv) {
    using namespace TCLAP;
    using namespace std;
  try {

    CmdLine cmd("RADIUS Server with EAP-MD5", ' ');

    ValueArg<string> logpathArg("l", "log",
                                "The path where log file shall be written",
                                false, "server.log", "string");
    cmd.add(logpathArg);

    ValueArg<string> dbArg("d", "database",
                           "The path to the plain text file with user data",
                           false, "users.txt", "string");
    cmd.add(dbArg);

    ValueArg<string> secretArg("s", "secret", "The secret shared with NAS",
                               true, "", "string");
    cmd.add(secretArg);

    ValueArg<int> portArg("p", "port", "Binded port", true, -1, "number");
    cmd.add(portArg);

    ValueArg<string> ipArg("a", "address", "Binded IP address", true, "", "IP");

    cmd.add(ipArg);

    cmd.parse(argc, argv);

    int port = portArg.getValue();
    string ip = ipArg.getValue();
    string secret = secretArg.getValue();
    string logpath = logpathArg.getValue();
    string dbpath = dbArg.getValue();
    start(ip.c_str());
  } catch (CmdLineParseException &ce) {
    cerr << "error: " << ce.error() << ce.argId() << endl;
  }
}

void start(const char *addr) {
SOCKET s;
    const int BUFLEN = 1000;
    const int PORT = 32000;
    struct sockaddr_in server, dest_addr;
    int slen , recv_len;
    vector<char> buf(BUFLEN,'\0');

    WSADATA wsa;

    slen = sizeof(dest_addr) ;

    //Initialise winsock
    printf("\nInitialising Winsock...");
    if (WSAStartup(MAKEWORD(2,2),&wsa) != 0)
    {
        printf("Failed. Error Code : %d",WSAGetLastError());
        exit(EXIT_FAILURE);
    }
    printf("Initialised.\n");

    //Create a socket
    if((s = socket(AF_INET , SOCK_DGRAM , 0 )) == INVALID_SOCKET)
    {
        printf("Could not create socket : %d" , WSAGetLastError());
    }
    printf("Socket created.\n");

    //Prepare the sockaddr_in structure
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = INADDR_ANY;
    server.sin_port = htons( PORT );

    //Bind
    if( bind(s ,(struct sockaddr *)&server , sizeof(server)) == SOCKET_ERROR)
    {
        printf("Bind failed with error code : %d" , WSAGetLastError());
        exit(EXIT_FAILURE);
    }
    puts("Bind done");

    //keep listening for data
    while(1)
    {
        printf("Waiting for data...");
        fflush(stdout);

        //clear the buffer by filling null, it might have previously received data
        //memset(buf,'\0', BUFLEN);

        //try to receive some data, this is a blocking call
        if ((recv_len = recvfrom(s, &buf[0], BUFLEN, 0, (struct sockaddr *) &dest_addr, &slen)) == SOCKET_ERROR)
        {
            printf("recvfrom() failed with error code : %d" , WSAGetLastError());
            exit(EXIT_FAILURE);
        }
		//vector<byte> buffr(&buf[0],&buf[BUFLEN]);
         radius::packets::Packet rec_pack(buf,dest_addr);
        //print details of the client/peer and the data received
        printf("Received packet from %s:%d\n", inet_ntoa(dest_addr.sin_addr), ntohs(dest_addr.sin_port));
        printf("Data: %s\n" , buf);

        //now reply the client with the same data
        if (sendto(s, &buf[0], recv_len, 0, (struct sockaddr*) &dest_addr, slen) == SOCKET_ERROR)

        {
            printf("sendto() failed with error code : %d" , WSAGetLastError());
            exit(EXIT_FAILURE);
        }
    }

    closesocket(s);
    WSACleanup();
}

<commit_msg>czyszczenie bufora w petli<commit_after>#include <iostream>
#include "server.h"
#include <vector>
#include "tclap/CmdLine.h"
#include "packets/Packet.h"

int main(int argc, char **argv) {
    using namespace TCLAP;
    using namespace std;
  try {

    CmdLine cmd("RADIUS Server with EAP-MD5", ' ');

    ValueArg<string> logpathArg("l", "log",
                                "The path where log file shall be written",
                                false, "server.log", "string");
    cmd.add(logpathArg);

    ValueArg<string> dbArg("d", "database",
                           "The path to the plain text file with user data",
                           false, "users.txt", "string");
    cmd.add(dbArg);

    ValueArg<string> secretArg("s", "secret", "The secret shared with NAS",
                               true, "", "string");
    cmd.add(secretArg);

    ValueArg<int> portArg("p", "port", "Binded port", true, -1, "number");
    cmd.add(portArg);

    ValueArg<string> ipArg("a", "address", "Binded IP address", true, "", "IP");

    cmd.add(ipArg);

    cmd.parse(argc, argv);

    int port = portArg.getValue();
    string ip = ipArg.getValue();
    string secret = secretArg.getValue();
    string logpath = logpathArg.getValue();
    string dbpath = dbArg.getValue();
    start(ip.c_str());
  } catch (CmdLineParseException &ce) {
    cerr << "error: " << ce.error() << ce.argId() << endl;
  }
}

void start(const char *addr) {
SOCKET s;
    const int BUFLEN = 1000;
    const int PORT = 32000;
    struct sockaddr_in server, dest_addr;
    int slen , recv_len;
    vector<char> buf(BUFLEN,'\0');

    WSADATA wsa;

    slen = sizeof(dest_addr) ;

    //Initialise winsock
    printf("\nInitialising Winsock...");
    if (WSAStartup(MAKEWORD(2,2),&wsa) != 0)
    {
        printf("Failed. Error Code : %d",WSAGetLastError());
        exit(EXIT_FAILURE);
    }
    printf("Initialised.\n");

    //Create a socket
    if((s = socket(AF_INET , SOCK_DGRAM , 0 )) == INVALID_SOCKET)
    {
        printf("Could not create socket : %d" , WSAGetLastError());
    }
    printf("Socket created.\n");

    //Prepare the sockaddr_in structure
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = INADDR_ANY;
    server.sin_port = htons( PORT );

    //Bind
    if( bind(s ,(struct sockaddr *)&server , sizeof(server)) == SOCKET_ERROR)
    {
        printf("Bind failed with error code : %d" , WSAGetLastError());
        exit(EXIT_FAILURE);
    }
    puts("Bind done");

    //keep listening for data
    while(1)
    {
        printf("Waiting for data...");
        fflush(stdout);

        //clear the buffer by filling null, it might have previously received data
        //memset(buf,'\0', BUFLEN);
         buf.clear();
		 buf.resize(BUFLEN,'/0');
        //try to receive some data, this is a blocking call
        if ((recv_len = recvfrom(s, &buf[0], BUFLEN, 0, (struct sockaddr *) &dest_addr, &slen)) == SOCKET_ERROR)
        {
            printf("recvfrom() failed with error code : %d" , WSAGetLastError());
            exit(EXIT_FAILURE);
        }
		//vector<byte> buffr(&buf[0],&buf[BUFLEN]);
         radius::packets::Packet rec_pack(buf,dest_addr);
        //print details of the client/peer and the data received
        printf("Received packet from %s:%d\n", inet_ntoa(dest_addr.sin_addr), ntohs(dest_addr.sin_port));
        printf("Data: %s\n" , buf);

        //now reply the client with the same data
        if (sendto(s, &buf[0], recv_len, 0, (struct sockaddr*) &dest_addr, slen) == SOCKET_ERROR)

        {
            printf("sendto() failed with error code : %d" , WSAGetLastError());
            exit(EXIT_FAILURE);
        }
    }

    closesocket(s);
    WSACleanup();
}

<|endoftext|>


<commit_before>/* Copyright (c) 2017 Nguyen Viet Giang. All rights reserved. */
#include <ProgramOptions.hxx>
#include <fstream>
#include <vector>
#include <stdexcept>

#include <any/version.h>
#include <any/asm.h>
#include <any/scheduler.h>
#include <any/db.h>
#include <any/loader.h>
#include <any/actor.h>
#include <any/errno.h>
#include <any/std_io.h>
#include <any/std_string.h>
#include <any/std_buffer.h>
#include <any/std_array.h>
#include <any/std_tuple.h>
#include <any/std_table.h>

#include "compiler.h"

struct address_t
{
    std::string host;
    uint16_t port;
};

static void* myalloc(void*, void* old, aint_t sz)
{
    return realloc(old, (size_t)sz);
}

static void error(const char* fmt, ...)
{
    va_list args;
    char buf[512];
    va_start(args, fmt);
    vsnprintf(buf, sizeof(buf), fmt, args);
    va_end(args);
    throw std::logic_error(buf);
}

static std::string file_name_without_extension(const std::string& path)
{
    auto base_filename = path.substr(path.find_last_of("/\\") + 1);
    std::string::size_type const p(base_filename.find_last_of('.'));
    return base_filename.substr(0, p);
}

static void print_version()
{
    std::cout <<
        "amlc version 1.0" << ", " <<
        "target AVM " << AVERSION_MAJOR << "." << AVERSION_MINOR <<
        " [" << AVERSION_NAME << "]\n";
}

static void compile(const std::string& i, const std::string& o, bool verbose)
{
    std::cout << "compiling " << i << "\n";

    std::ifstream is;
    is.open(i, std::fstream::in);
    if (!is.is_open()) {
        error("failed to open `%s`", i.c_str());
    }
    is.seekg(0, std::fstream::end);
    auto sz = (size_t)is.tellg();
    is.seekg(0, std::fstream::beg);
    std::vector<char> buf;
    buf.resize(sz + 1);
    is.read(buf.data(), sz);
    buf[sz] = '\0';
    is.close();

    aasm_t a;
    aasm_init(&a, &myalloc, NULL);
    if (aasm_load(&a, NULL) != AERR_NONE) {
        error("failed to load aasm_t");
    }
    amlc_compile(&a, buf.data(), i.c_str(), verbose);
    aasm_save(&a);
    std::ofstream os;
    os.open(o, std::fstream::out | std::fstream::binary | std::fstream::trunc);
    os.write((const char*)a.chunk, a.chunk_size);
    os.close();
    aasm_cleanup(&a);

    std::cout << " -> " << o << "\n";
}

static void on_panic(aactor_t* a, void*)
{
    aint_t ev_idx = any_top(a);
    if (a->frame->pt) {
        aprototype_t& chunk = a->frame->pt->chunk->prototypes[0];
        std::cout << chunk.strings + chunk.header->source << ":";
        if (a->frame->ip < a->frame->pt->header->num_instructions) {
            std::cout << a->frame->pt->source_lines[a->frame->ip] << " ";
        } else {
            std::cout << a->frame->pt->source_lines[a->frame->ip - 1] << " ";
        }
    }
    std::cout << "panic - ";
    if (any_type(a, ev_idx).type == AVT_STRING) {
        std::cout << any_to_string(a, ev_idx) << "\n";
    } else {
        std::cout << "unknown fatal error\n";
    }
}

static void on_unresolved(
    aloader_t*, const char* module, const char* name, void*)
{
    std::cout << "unresolved import `" << module << ':' << name << "`\n";
}

static void execute(
    const std::string& module, const std::string& name,
    int8_t idx_bits, int8_t gen_bits, aint_t cstack_sz,
    const std::vector<std::string>& chunks,
    address_t* debug, int32_t max_conns, bool alive,
    int32_t realtime_resolution)
{
    aerror_t ec;
    ascheduler_t s;
    adb_t db;

    ec = ascheduler_init(&s, idx_bits, gen_bits, &myalloc, NULL);
    if (ec != AERR_NONE) {
        error("failed to init scheduler %d", ec);
    }
    ascheduler_on_panic(&s, &on_panic, NULL);
    aloader_on_unresolved(&s.loader, &on_unresolved, NULL);

    if (debug) {
        ec = adb_init(
            &db, &myalloc, NULL, &s,
            debug->host.c_str(), debug->port, (aint_t)max_conns);
        if (ec != AERR_NONE) {
            error("failed to init debug service %d", ec);
        } else {
            std::cout <<
                "debug service attached\n" <<
                " -> at " << debug->host << ":" << debug->port << "\n";
        }
    }

    astd_lib_add_io(
        &s.loader, [](void*, const char* str) { std::cout << str; }, NULL);
    astd_lib_add_string(&s.loader);
    astd_lib_add_buffer(&s.loader);
    astd_lib_add_array (&s.loader);
    astd_lib_add_tuple (&s.loader);
    astd_lib_add_table (&s.loader);

    for (size_t i = 0; i < chunks.size(); ++i) {
        auto& c = chunks[i];
        std::ifstream is;
        is.open(c, std::fstream::in | std::fstream::binary);
        if (!is.is_open()) {
            error("failed to open `%s`", c.c_str());
        }
        is.seekg(0, std::fstream::end);
        auto sz = (size_t)is.tellg();
        is.seekg(0, std::fstream::beg);
        auto* chunk = (achunk_header_t*)myalloc(NULL, NULL, sz);
        is.read((char*)chunk, sz);
        is.close();
        std::cout << "add " << c << "\n";
        ec = aloader_add_chunk(&s.loader, chunk, sz, &myalloc, NULL);
        if (ec != AERR_NONE) {
            error("failed to add chunk %d", ec);
        }
    }

    ec = aloader_link(&s.loader, TRUE);
    if (ec != AERR_NONE) {
        error("failed to link %d", ec);
    }
    std::cout << "linking success\n";

    aactor_t* a;
    std::cout << "spawn " << module << ":" << name << "\n";
    ec = ascheduler_new_actor(&s, cstack_sz, &a);
    if (ec != AERR_NONE) {
        error("failed to create actor %d", ec);
    }
    std::cout << " -> pid = " << ascheduler_pid(&s, a) << "\n";
    any_find(a, module.c_str(), name.c_str());
    ascheduler_start(&s, a, 0);

    while (alive || ascheduler_num_processes(&s) > 0) {
        if (debug) adb_run_once(&db);
        ascheduler_run_once(&s);
#ifdef AWINDOWS
        Sleep((DWORD)realtime_resolution * 1000);
#else
        usleep((useconds_t)realtime_resolution);
#endif
    }

    if (debug) adb_cleanup(&db);
    ascheduler_cleanup(&s);
}

int entry(int argc, char** argv)
{
    try {
        po::parser p;

        p["help"]
            .abbreviation('h')
            .description("print this help screen")
            .type(po::void_)
            .callback([&] { std::cout << p << "\n"; });

        p["version"]
            .abbreviation('v')
            .description("display compiler version information")
            .type(po::void_)
            .callback(&print_version);

        p["compile"]
            .abbreviation('c')
            .description("compile an AML source file")
            .type(po::string);

        p["execute"]
            .abbreviation('e')
            .description("run with entry point")
            .type(po::string);

        p["debug"]
            .abbreviation('d')
            .description("run with debug service at host:port")
            .type(po::string);

        p["verbose"]
            .abbreviation('V')
            .description("display debugging log")
            .type(po::void_);

        p["output"]
            .abbreviation('o')
            .description("place the output into file")
            .type(po::string);

        p["idx_bits"]
            .description("number of index bits")
            .type(po::i32)
            .fallback(8);

        p["gen_bits"]
            .description("number of generation bits")
            .type(po::i32)
            .fallback(24);

        p["cstack_sz"]
            .description("size of entry point native stack in bytes")
            .type(po::i32)
            .fallback(4096000);

        p["max_conns"]
            .description("maximum number of debug connections")
            .type(po::i32)
            .fallback(64);

        p["alive"]
            .description("keep AMLC execution session alive")
            .type(po::void_);

        p["rt_res"]
            .description("real-time resolution hint in us")
            .type(po::i32)
            .fallback(1);

        p[""];

        if (!p(argc, argv)) {
            return 1;
        } else {
            if (p["compile"].was_set()) {
                auto i = p["compile"].get().string;
                if (i.length() <= 0) {
                    error("input missing");
                }
                std::string o;
                if (p["output"].was_set()) {
                    o = p["output"].get().string;
                } else {
                    o = file_name_without_extension(i) + ".avmc";
                }
                compile(i, o, p["verbose"].available());
            }
            if (p["execute"].was_set()) {
                auto e = p["execute"].get().string;
                if (e.length() <= 0) {
                    error("entry point missing");
                }
                auto sep = e.find_first_of(':');
                if (sep == std::string::npos) {
                    error(
                        ("bad entry `" + e + "`, missing `:`").c_str());
                }
                if (sep == e.length() - 1) {
                    error(
                        ("bad entry `" + e + "`, missing function").c_str());
                }
                std::unique_ptr<address_t> debug;
                if (p["debug"].was_set()) {
                    debug = std::make_unique<address_t>();
                    auto d = p["debug"].get().string;
                    auto colon = d.find_first_of(':');
                    debug->host = d.substr(0, colon);
                    auto port_str = d.substr(colon + 1);
                    debug->port = (uint16_t)atoi(port_str.c_str());
                }
                execute(
                    e.substr(0, sep), e.substr(sep + 1),
                    (int8_t)p["idx_bits"].get().i32,
                    (int8_t)p["gen_bits"].get().i32,
                    (aint_t)p["cstack_sz"].get().i32,
                    p[""].to_vector<po::string>(),
                    debug.get(), p["max_conns"].get().i32,
                    p["alive"].was_set(),
                    p["rt_res"].get().i32);
            }
            return 0;
        }
    } catch (const std::exception& e) {
        std::cerr << "uncaught exception: " << e.what() << "\n";
        return -1;
    }
}

int main(int argc, char** argv)
{
#ifdef AWINDOWS
    WSADATA wsa_data;
    int ws_err = WSAStartup(MAKEWORD(2, 2), &wsa_data);
    if (ws_err != 0) {
        error("WSAStartup failed %d", ws_err);
    }
#endif
    entry(argc, argv);
#ifdef AWINDOWS
    WSACleanup();
#endif
}
<commit_msg>add missing amlc log<commit_after>/* Copyright (c) 2017 Nguyen Viet Giang. All rights reserved. */
#include <ProgramOptions.hxx>
#include <fstream>
#include <vector>
#include <stdexcept>

#include <any/version.h>
#include <any/asm.h>
#include <any/scheduler.h>
#include <any/db.h>
#include <any/loader.h>
#include <any/actor.h>
#include <any/errno.h>
#include <any/std_io.h>
#include <any/std_string.h>
#include <any/std_buffer.h>
#include <any/std_array.h>
#include <any/std_tuple.h>
#include <any/std_table.h>

#include "compiler.h"

struct address_t
{
    std::string host;
    uint16_t port;
};

static void* myalloc(void*, void* old, aint_t sz)
{
    return realloc(old, (size_t)sz);
}

static void error(const char* fmt, ...)
{
    va_list args;
    char buf[512];
    va_start(args, fmt);
    vsnprintf(buf, sizeof(buf), fmt, args);
    va_end(args);
    throw std::logic_error(buf);
}

static std::string file_name_without_extension(const std::string& path)
{
    auto base_filename = path.substr(path.find_last_of("/\\") + 1);
    std::string::size_type const p(base_filename.find_last_of('.'));
    return base_filename.substr(0, p);
}

static void print_version()
{
    std::cout <<
        "amlc version 1.0" << ", " <<
        "target AVM " << AVERSION_MAJOR << "." << AVERSION_MINOR <<
        " [" << AVERSION_NAME << "]\n";
}

static void compile(const std::string& i, const std::string& o, bool verbose)
{
    std::cout << "compiling " << i << "\n";

    std::ifstream is;
    is.open(i, std::fstream::in);
    if (!is.is_open()) {
        error("failed to open `%s`", i.c_str());
    }
    is.seekg(0, std::fstream::end);
    auto sz = (size_t)is.tellg();
    is.seekg(0, std::fstream::beg);
    std::vector<char> buf;
    buf.resize(sz + 1);
    is.read(buf.data(), sz);
    buf[sz] = '\0';
    is.close();

    aasm_t a;
    aasm_init(&a, &myalloc, NULL);
    if (aasm_load(&a, NULL) != AERR_NONE) {
        error("failed to load aasm_t");
    }
    amlc_compile(&a, buf.data(), i.c_str(), verbose);
    aasm_save(&a);
    std::ofstream os;
    os.open(o, std::fstream::out | std::fstream::binary | std::fstream::trunc);
    os.write((const char*)a.chunk, a.chunk_size);
    os.close();
    aasm_cleanup(&a);

    std::cout << " -> " << o << "\n";
}

static void on_panic(aactor_t* a, void*)
{
    aint_t ev_idx = any_top(a);
    std::cout << "[" << ascheduler_pid(a->owner, a) << "] ";
    if (a->frame->pt) {
        aprototype_t& chunk = a->frame->pt->chunk->prototypes[0];
        std::cout << chunk.strings + chunk.header->source << ":";
        if (a->frame->ip < a->frame->pt->header->num_instructions) {
            std::cout << a->frame->pt->source_lines[a->frame->ip] << " ";
        } else {
            std::cout << a->frame->pt->source_lines[a->frame->ip - 1] << " ";
        }
    }
    std::cout << "panic - ";
    if (any_type(a, ev_idx).type == AVT_STRING) {
        std::cout << any_to_string(a, ev_idx) << "\n";
    } else {
        std::cout << "unknown fatal error\n";
    }
}

static void on_unresolved(
    aloader_t*, const char* module, const char* name, void*)
{
    std::cout << "unresolved import `" << module << ':' << name << "`\n";
}

static void execute(
    const std::string& module, const std::string& name,
    int8_t idx_bits, int8_t gen_bits, aint_t cstack_sz,
    const std::vector<std::string>& chunks,
    address_t* debug, int32_t max_conns, bool alive,
    int32_t realtime_resolution)
{
    aerror_t ec;
    ascheduler_t s;
    adb_t db;

    ec = ascheduler_init(&s, idx_bits, gen_bits, &myalloc, NULL);
    if (ec != AERR_NONE) {
        error("failed to init scheduler %d", ec);
    }
    ascheduler_on_panic(&s, &on_panic, NULL);
    aloader_on_unresolved(&s.loader, &on_unresolved, NULL);

    if (debug) {
        ec = adb_init(
            &db, &myalloc, NULL, &s,
            debug->host.c_str(), debug->port, (aint_t)max_conns);
        if (ec != AERR_NONE) {
            error("failed to init debug service %d", ec);
        } else {
            std::cout <<
                "debug service attached\n" <<
                " -> at " << debug->host << ":" << debug->port << "\n";
        }
    }

    astd_lib_add_io(
        &s.loader, [](void*, const char* str) { std::cout << str; }, NULL);
    astd_lib_add_string(&s.loader);
    astd_lib_add_buffer(&s.loader);
    astd_lib_add_array (&s.loader);
    astd_lib_add_tuple (&s.loader);
    astd_lib_add_table (&s.loader);

    for (size_t i = 0; i < chunks.size(); ++i) {
        auto& c = chunks[i];
        std::ifstream is;
        is.open(c, std::fstream::in | std::fstream::binary);
        if (!is.is_open()) {
            error("failed to open `%s`", c.c_str());
        }
        is.seekg(0, std::fstream::end);
        auto sz = (size_t)is.tellg();
        is.seekg(0, std::fstream::beg);
        auto* chunk = (achunk_header_t*)myalloc(NULL, NULL, sz);
        is.read((char*)chunk, sz);
        is.close();
        std::cout << "add " << c << "\n";
        ec = aloader_add_chunk(&s.loader, chunk, sz, &myalloc, NULL);
        if (ec != AERR_NONE) {
            error("failed to add chunk %d", ec);
        }
    }

    ec = aloader_link(&s.loader, TRUE);
    if (ec != AERR_NONE) {
        error("failed to link %d", ec);
    }
    std::cout << "linking success\n";

    aactor_t* a;
    std::cout << "spawn " << module << ":" << name << "\n";
    ec = ascheduler_new_actor(&s, cstack_sz, &a);
    if (ec != AERR_NONE) {
        error("failed to create actor %d", ec);
    }
    std::cout << " -> pid = " << ascheduler_pid(&s, a) << "\n";
    any_find(a, module.c_str(), name.c_str());
    ascheduler_start(&s, a, 0);

    while (alive || ascheduler_num_processes(&s) > 0) {
        if (debug) adb_run_once(&db);
        ascheduler_run_once(&s);
#ifdef AWINDOWS
        Sleep((DWORD)realtime_resolution * 1000);
#else
        usleep((useconds_t)realtime_resolution);
#endif
    }

    if (debug) adb_cleanup(&db);
    ascheduler_cleanup(&s);
}

int entry(int argc, char** argv)
{
    try {
        po::parser p;

        p["help"]
            .abbreviation('h')
            .description("print this help screen")
            .type(po::void_)
            .callback([&] { std::cout << p << "\n"; });

        p["version"]
            .abbreviation('v')
            .description("display compiler version information")
            .type(po::void_)
            .callback(&print_version);

        p["compile"]
            .abbreviation('c')
            .description("compile an AML source file")
            .type(po::string);

        p["execute"]
            .abbreviation('e')
            .description("run with entry point")
            .type(po::string);

        p["debug"]
            .abbreviation('d')
            .description("run with debug service at host:port")
            .type(po::string);

        p["verbose"]
            .abbreviation('V')
            .description("display debugging log")
            .type(po::void_);

        p["output"]
            .abbreviation('o')
            .description("place the output into file")
            .type(po::string);

        p["idx_bits"]
            .description("number of index bits")
            .type(po::i32)
            .fallback(8);

        p["gen_bits"]
            .description("number of generation bits")
            .type(po::i32)
            .fallback(24);

        p["cstack_sz"]
            .description("size of entry point native stack in bytes")
            .type(po::i32)
            .fallback(4096000);

        p["max_conns"]
            .description("maximum number of debug connections")
            .type(po::i32)
            .fallback(64);

        p["alive"]
            .description("keep AMLC execution session alive")
            .type(po::void_);

        p["rt_res"]
            .description("real-time resolution hint in us")
            .type(po::i32)
            .fallback(1);

        p[""];

        if (!p(argc, argv)) {
            return 1;
        } else {
            if (p["compile"].was_set()) {
                auto i = p["compile"].get().string;
                if (i.length() <= 0) {
                    error("input missing");
                }
                std::string o;
                if (p["output"].was_set()) {
                    o = p["output"].get().string;
                } else {
                    o = file_name_without_extension(i) + ".avmc";
                }
                compile(i, o, p["verbose"].available());
            }
            if (p["execute"].was_set()) {
                auto e = p["execute"].get().string;
                if (e.length() <= 0) {
                    error("entry point missing");
                }
                auto sep = e.find_first_of(':');
                if (sep == std::string::npos) {
                    error(
                        ("bad entry `" + e + "`, missing `:`").c_str());
                }
                if (sep == e.length() - 1) {
                    error(
                        ("bad entry `" + e + "`, missing function").c_str());
                }
                std::unique_ptr<address_t> debug;
                if (p["debug"].was_set()) {
                    debug = std::make_unique<address_t>();
                    auto d = p["debug"].get().string;
                    auto colon = d.find_first_of(':');
                    debug->host = d.substr(0, colon);
                    auto port_str = d.substr(colon + 1);
                    debug->port = (uint16_t)atoi(port_str.c_str());
                }
                execute(
                    e.substr(0, sep), e.substr(sep + 1),
                    (int8_t)p["idx_bits"].get().i32,
                    (int8_t)p["gen_bits"].get().i32,
                    (aint_t)p["cstack_sz"].get().i32,
                    p[""].to_vector<po::string>(),
                    debug.get(), p["max_conns"].get().i32,
                    p["alive"].was_set(),
                    p["rt_res"].get().i32);
            }
            return 0;
        }
    } catch (const std::exception& e) {
        std::cerr << "uncaught exception: " << e.what() << "\n";
        return -1;
    }
}

int main(int argc, char** argv)
{
#ifdef AWINDOWS
    WSADATA wsa_data;
    int ws_err = WSAStartup(MAKEWORD(2, 2), &wsa_data);
    if (ws_err != 0) {
        error("WSAStartup failed %d", ws_err);
    }
#endif
    entry(argc, argv);
#ifdef AWINDOWS
    WSACleanup();
#endif
}
<|endoftext|>


<commit_before>/*********************************************************************************
 *
 * Inviwo - Interactive Visualization Workshop
 *
 * Copyright (c) 2014-2017 Inviwo Foundation
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *********************************************************************************/

#include <warn/push>
#include <warn/ignore/all>
#include <gtest/gtest.h>
#include <warn/pop>

#include <inviwo/core/network/processornetwork.h>
#include <inviwo/core/processors/processorfactory.h>
#include <inviwo/core/util/logerrorcounter.h>
#include <inviwo/core/datastructures/transferfunction.h>
#include <inviwo/core/properties/transferfunctionproperty.h>
#include <inviwo/core/common/inviwoapplication.h>
#include <inviwo/core/common/inviwomodule.h>

namespace inviwo {

class ProcessorCreationTests : public ::testing::TestWithParam<std::string> {
protected:
    ProcessorCreationTests() : p(nullptr) {}

    virtual ~ProcessorCreationTests() { EXPECT_TRUE(p == nullptr); }

    virtual void SetUp() {
        isAdded_ = false;
    }

    virtual void TearDown() {
        if (isAdded_) {
            ProcessorNetwork *pn = InviwoApplication::getPtr()->getProcessorNetwork();
            size_t sizeBefore = pn->getProcessors().size();

            pn->removeAndDeleteProcessor(p);

            size_t sizeAfter = pn->getProcessors().size();
            EXPECT_EQ(sizeBefore, sizeAfter + 1);
        } else if (p) {
            delete p;
        }
        p = nullptr;
    }

    void create() {
        size_t warnCount = LogErrorCounter::getPtr()->getWarnCount();
        size_t errCount = LogErrorCounter::getPtr()->getErrorCount();

        auto s = InviwoApplication::getPtr()->getProcessorFactory()->create(GetParam());
        ASSERT_TRUE(s.get() != nullptr);

        p = dynamic_cast<Processor *>(s.get());
        ASSERT_TRUE(p != nullptr);
        s.release();
        EXPECT_EQ(warnCount, LogErrorCounter::getPtr()->getWarnCount());
        EXPECT_EQ(errCount, LogErrorCounter::getPtr()->getErrorCount());
    }

    void resetAllPoperties() {
        size_t warnCount = LogErrorCounter::getPtr()->getWarnCount();
        size_t errCount = LogErrorCounter::getPtr()->getErrorCount();

        p->resetAllPoperties();
        EXPECT_EQ(warnCount, LogErrorCounter::getPtr()->getWarnCount());
        EXPECT_EQ(errCount, LogErrorCounter::getPtr()->getErrorCount());
    }

    void addProcessor() {
        size_t warnCount = LogErrorCounter::getPtr()->getWarnCount();
        size_t errCount = LogErrorCounter::getPtr()->getErrorCount();

        InviwoApplication::getPtr()->getProcessorNetwork()->addProcessor(p);
        EXPECT_EQ(warnCount, LogErrorCounter::getPtr()->getWarnCount());
        EXPECT_EQ(errCount, LogErrorCounter::getPtr()->getErrorCount());
        isAdded_ = true;
    }

    Processor *p;
    bool isAdded_;
};

const std::vector<std::string> getListOfProcessors() {
    std::vector<std::string> theVec;
    for (const auto& module : InviwoApplication::getPtr()->getModules()) {
        for (const auto& processor: module->getProcessors()) {
            theVec.push_back(processor->getClassIdentifier());
        }
    }
    return theVec;
}

//
// TEST_P(ProcessorCreationTests,ProcesorCreate){
//    initialize();
//}
//
// TEST_P(ProcessorCreationTests,ProcesorCreateAndReset){
//    initialize();
//    resetAllPoperties();
//}
//
//
// TEST_P(ProcessorCreationTests,ProcesorCreateAndAddToNetwork){
//    initialize();
//    addProcessor();
//}

// disabled the 3 test above since they are only needed when the following test fails

TEST_P(ProcessorCreationTests, ProcesorCreateAndResetAndAddToNetwork) {
 /*   create();
    resetAllPoperties();
    addProcessor();*/
}

INSTANTIATE_TEST_CASE_P(RegisteredProcessors, ProcessorCreationTests,
                        ::testing::ValuesIn(getListOfProcessors()));
}
<commit_msg>IntegrationTest: Enable the processor creation tests<commit_after>/*********************************************************************************
 *
 * Inviwo - Interactive Visualization Workshop
 *
 * Copyright (c) 2014-2017 Inviwo Foundation
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *********************************************************************************/

#include <warn/push>
#include <warn/ignore/all>
#include <gtest/gtest.h>
#include <warn/pop>

#include <inviwo/core/network/processornetwork.h>
#include <inviwo/core/processors/processorfactory.h>
#include <inviwo/core/util/logerrorcounter.h>
#include <inviwo/core/datastructures/transferfunction.h>
#include <inviwo/core/properties/transferfunctionproperty.h>
#include <inviwo/core/common/inviwoapplication.h>
#include <inviwo/core/common/inviwomodule.h>

namespace inviwo {

class ProcessorCreationTests : public ::testing::TestWithParam<std::string> {
protected:
    ProcessorCreationTests() : p(nullptr) {}

    virtual ~ProcessorCreationTests() { EXPECT_TRUE(p == nullptr); }

    virtual void SetUp() {
        isAdded_ = false;
    }

    virtual void TearDown() {
        if (isAdded_) {
            ProcessorNetwork *pn = InviwoApplication::getPtr()->getProcessorNetwork();
            size_t sizeBefore = pn->getProcessors().size();

            pn->removeAndDeleteProcessor(p);

            size_t sizeAfter = pn->getProcessors().size();
            EXPECT_EQ(sizeBefore, sizeAfter + 1);
        } else if (p) {
            delete p;
        }
        p = nullptr;
    }

    void create() {
        size_t warnCount = LogErrorCounter::getPtr()->getWarnCount();
        size_t errCount = LogErrorCounter::getPtr()->getErrorCount();

        auto s = InviwoApplication::getPtr()->getProcessorFactory()->create(GetParam());
        ASSERT_TRUE(s.get() != nullptr);

        p = dynamic_cast<Processor *>(s.get());
        ASSERT_TRUE(p != nullptr);
        s.release();
        EXPECT_EQ(warnCount, LogErrorCounter::getPtr()->getWarnCount());
        EXPECT_EQ(errCount, LogErrorCounter::getPtr()->getErrorCount());
    }

    void resetAllPoperties() {
        size_t warnCount = LogErrorCounter::getPtr()->getWarnCount();
        size_t errCount = LogErrorCounter::getPtr()->getErrorCount();

        p->resetAllPoperties();
        EXPECT_EQ(warnCount, LogErrorCounter::getPtr()->getWarnCount());
        EXPECT_EQ(errCount, LogErrorCounter::getPtr()->getErrorCount());
    }

    void addProcessor() {
        size_t warnCount = LogErrorCounter::getPtr()->getWarnCount();
        size_t errCount = LogErrorCounter::getPtr()->getErrorCount();

        InviwoApplication::getPtr()->getProcessorNetwork()->addProcessor(p);
        EXPECT_EQ(warnCount, LogErrorCounter::getPtr()->getWarnCount());
        EXPECT_EQ(errCount, LogErrorCounter::getPtr()->getErrorCount());
        isAdded_ = true;
    }

    Processor *p;
    bool isAdded_;
};

const std::vector<std::string> getListOfProcessors() {
    std::vector<std::string> theVec;
    for (const auto& module : InviwoApplication::getPtr()->getModules()) {
        for (const auto& processor: module->getProcessors()) {
            theVec.push_back(processor->getClassIdentifier());
        }
    }
    return theVec;
}

//
// TEST_P(ProcessorCreationTests,ProcesorCreate){
//    initialize();
//}
//
// TEST_P(ProcessorCreationTests,ProcesorCreateAndReset){
//    initialize();
//    resetAllPoperties();
//}
//
//
// TEST_P(ProcessorCreationTests,ProcesorCreateAndAddToNetwork){
//    initialize();
//    addProcessor();
//}

// disabled the 3 test above since they are only needed when the following test fails

TEST_P(ProcessorCreationTests, ProcesorCreateAndResetAndAddToNetwork) {
    create();
    resetAllPoperties();
    addProcessor();
}

INSTANTIATE_TEST_CASE_P(RegisteredProcessors, ProcessorCreationTests,
                        ::testing::ValuesIn(getListOfProcessors()));
}
<|endoftext|>