<commit_before>#ifndef __STAN__IO__STAN_CSV_READER_HPP__
#define __STAN__IO__STAN_CSV_READER_HPP__

#include <istream>
#include <iostream>
#include <sstream>
#include <string>
#include <boost/algorithm/string.hpp>
#include <boost/lexical_cast.hpp>
#include <stan/math/matrix.hpp>

namespace stan {
  namespace io {

    // FIXME: should consolidate with the options from the command line in stan::gm
    struct stan_csv_metadata {
      int stan_version_major;
      int stan_version_minor;
      int stan_version_patch;

      std::string model;
      std::string data;
      std::string init;
      bool append_samples;
      bool save_warmup;
      size_t seed;
      bool random_seed;
      size_t chain_id;
      size_t iter;
      size_t warmup;
      size_t thin;
      bool equal_step_sizes;
      bool nondiag_mass;
      int leapfrog_steps;
      int max_treedepth;
      double epsilon;
      double epsilon_pm;
      double delta;
      double gamma;
      std::string algorithm;
    };

    struct stan_csv_adaptation {
      double step_size;
      Eigen::MatrixXd metric;
    };

    struct stan_csv_timing {
      double warmup;
      double sampling;
    };

    struct stan_csv {
      stan_csv_metadata metadata;
      Eigen::Matrix<std::string, Eigen::Dynamic, 1> header;
      stan_csv_adaptation adaptation;
      Eigen::MatrixXd samples;
      stan_csv_timing timing;
    };

    /**
     * Reads from a Stan output csv file.
     */
    class stan_csv_reader {

    public:

      stan_csv_reader() {}
      ~stan_csv_reader() {}

      static bool read_metadata(std::istream& in, stan_csv_metadata& metadata) {

        std::stringstream ss;
        std::string line;

        if (in.peek() != '#')
          return false;
        while (in.peek() == '#') {
          std::getline(in, line);
          ss << line << '\n';
        }
        ss.seekg(std::ios_base::beg);

        char comment;
        std::string lhs;

        // Skip first two lines
        std::getline(ss, line);
        std::getline(ss, line);

        while (ss.good()) {

          ss >> comment;
          std::getline(ss, lhs, '=');
          boost::trim(lhs);

          if (lhs.compare("") == 0) { // no-op
          } else if (lhs.compare("stan_version_major") == 0) {
            ss >> metadata.stan_version_major;
          } else if (lhs.compare("stan_version_minor") == 0) {
            ss >> metadata.stan_version_minor;
          } else if (lhs.compare("stan_version_patch") == 0) {
            ss >> metadata.stan_version_patch;
          } else if (lhs.compare("model") == 0) {
            ss >> metadata.model;
          } else if (lhs.compare("data") == 0) {
            ss >> metadata.data;
          } else if (lhs.compare("init") == 0) {
            std::getline(ss, metadata.init);
            boost::trim(metadata.init);
            ss.unget();
          } else if (lhs.compare("append_samples") == 0) {
            ss >> metadata.append_samples;
          } else if (lhs.compare("save_warmup") == 0) {
            ss >> metadata.save_warmup;
          } else if (lhs.compare("seed") == 0) {
            ss >> metadata.seed;
            metadata.random_seed = false;
          } else if (lhs.compare("chain_id") == 0) {
            ss >> metadata.chain_id;
          } else if (lhs.compare("iter") == 0) {
            ss >> metadata.iter;
          } else if (lhs.compare("warmup") == 0) {
            ss >> metadata.warmup;
          } else if (lhs.compare("thin") == 0) {
            ss >> metadata.thin;
          } else if (lhs.compare("equal_step_sizes") == 0) {
            ss >> metadata.equal_step_sizes;
                } else if (lhs.compare("nondiag_mass") == 0) {
            ss >> metadata.nondiag_mass;
          } else if (lhs.compare("leapfrog_steps") == 0) {
            ss >> metadata.leapfrog_steps;
          } else if (lhs.compare("max_treedepth") == 0) {
            ss >> metadata.max_treedepth;
          } else if (lhs.compare("epsilon") == 0) {
            ss >> metadata.epsilon;
          } else if (lhs.compare("epsilon_pm") == 0) {
            ss >> metadata.epsilon_pm;
          } else if (lhs.compare("delta") == 0) {
            ss >> metadata.delta;
          } else if (lhs.compare("gamma") == 0) {
            ss >> metadata.gamma;
          } else if (lhs.compare("algorithm") == 0) {
            std::getline(ss, metadata.algorithm);
            boost::trim(metadata.algorithm);
            ss.unget();
          } else {
            std::cout << "unused option: " << lhs << std::endl;
          }

          std::getline(ss, line);

        }

        if (ss.good() == true)
          return false;

        return true;

      } // read_metadata

      static bool read_header(std::istream& in, Eigen::Matrix<std::string, Eigen::Dynamic, 1>& header) {

        std::string line;

        if (in.peek() != 'l')
          return false;

        std::getline(in, line);
        std::stringstream ss(line);

        header.resize(std::count(line.begin(), line.end(), ',') + 1);
        int idx = 0;
        while (ss.good()) {
          std::string token;
          std::getline(ss, token, ',');
          boost::trim(token);

          int pos = token.find('.');
          if (pos > 0) {
            token.replace(pos, 1, "[");
            std::replace(token.begin(), token.end(), '.', ',');
            token += "]";
          }
          header(idx++) = token;
        }
        return true;
      }

      static bool read_adaptation(std::istream& in, stan_csv_adaptation& adaptation) {

        std::stringstream ss;
        std::string line;
        int lines = 0;

        if (in.peek() != '#' || in.good() == false)
          return false;

        while (in.peek() == '#') {
          std::getline(in, line);
          ss << line << std::endl;
          lines++;
        }
        ss.seekg(std::ios_base::beg);

        char comment; // Buffer for comment indicator, #

        // Skip first two lines
        std::getline(ss, line);

        // Stepsize
        std::getline(ss, line, '=');
        boost::trim(line);
        ss >> adaptation.step_size;

        // Metric parameters
        std::getline(ss, line);
        std::getline(ss, line);
        std::getline(ss, line);

        int rows = lines - 3;
        int cols = std::count(line.begin(), line.end(), ',') + 1;
        adaptation.metric.resize(rows, cols);

        for (int row = 0; row < rows; row++) {

          std::stringstream line_ss;
          line_ss.str(line);
          line_ss >> comment;

          for (int col = 0; col < cols; col++) {
            std::string token;
            std::getline(line_ss, token, ',');
            boost::trim(token);
            adaptation.metric(row, col) = boost::lexical_cast<double>(token);
          }

          std::getline(ss, line); // Read in next line

        }

        if (ss.good())
          return false;
        else
          return true;

      }

      static bool read_samples(std::istream& in, Eigen::MatrixXd& samples, stan_csv_timing& timing) {

        std::stringstream ss;
        std::string line;

        int rows = 0;
        int cols = -1;

        if (in.peek() == '#' || in.good() == false)
          return false;

        while (in.good()) {

          bool comment_line = (in.peek() == '#');
          bool empty_line   = (in.peek() == '\n');

          std::getline(in, line);

          if (empty_line) continue;
          if (!line.length()) break;

          if (comment_line) {

            if (line.find("(Warm-up)") != std::string::npos) {
              int left = 16;
              int right = line.find(" seconds");
              timing.warmup += boost::lexical_cast<double>(line.substr(left, right - left));
            } else if (line.find("(Sampling)") != std::string::npos) {
              int left = 16;
              int right = line.find(" seconds");
              timing.sampling += boost::lexical_cast<double>(line.substr(left, right - left));
            }

          }
          else {

            ss << line << '\n';

            int current_cols = std::count(line.begin(), line.end(), ',') + 1;
            if (cols == -1) {
              cols = current_cols;
            } else if (cols != current_cols) {
              std::cout << "Error: expected " << cols << " columns, but found "
                        << current_cols << " instead for row " << rows + 1 << std::endl;
              return false;
            }
            rows++;

          }

          in.peek();

        }

        ss.seekg(std::ios_base::beg);

        if (rows > 0) {
          samples.resize(rows, cols);
          for (int row = 0; row < rows; row++) {
            std::getline(ss, line);
            std::stringstream ls(line);
            for (int col = 0; col < cols; col++) {
              std::getline(ls, line, ',');
              boost::trim(line);
              samples(row, col) = boost::lexical_cast<double>(line);
            }
          }
        }
        return true;
      }

      /**
       * Parses the file.
       *
       */
      static stan_csv parse(std::istream& in) {

        stan_csv data;

        if (!read_metadata(in, data.metadata)) {
          std::cout << "Warning: non-fatal error reading metadata" << std::endl;
        }

        if (!read_header(in, data.header)) {
          std::cout << "Error: error reading header" << std::endl;
          throw std::invalid_argument("Error with header of input file in parse");
        }

        if (!read_adaptation(in, data.adaptation)) {
          std::cout << "Warning: non-fatal error reading adapation data" << std::endl;
        }

        data.timing.warmup = 0;
        data.timing.sampling = 0;

        if (!read_samples(in, data.samples, data.timing)) {
          std::cout << "Warning: non-fatal error reading samples" << std::endl;
        }

        return data;

      }

    };

  } // io

} // stan

#endif
<commit_msg>adding default constructor for stan_csv_timing. Windows doesn't set the members to 0<commit_after>#ifndef __STAN__IO__STAN_CSV_READER_HPP__
#define __STAN__IO__STAN_CSV_READER_HPP__

#include <istream>
#include <iostream>
#include <sstream>
#include <string>
#include <boost/algorithm/string.hpp>
#include <boost/lexical_cast.hpp>
#include <stan/math/matrix.hpp>

namespace stan {
  namespace io {

    // FIXME: should consolidate with the options from the command line in stan::gm
    struct stan_csv_metadata {
      int stan_version_major;
      int stan_version_minor;
      int stan_version_patch;

      std::string model;
      std::string data;
      std::string init;
      bool append_samples;
      bool save_warmup;
      size_t seed;
      bool random_seed;
      size_t chain_id;
      size_t iter;
      size_t warmup;
      size_t thin;
      bool equal_step_sizes;
      bool nondiag_mass;
      int leapfrog_steps;
      int max_treedepth;
      double epsilon;
      double epsilon_pm;
      double delta;
      double gamma;
      std::string algorithm;
    };

    struct stan_csv_adaptation {
      double step_size;
      Eigen::MatrixXd metric;
    };

    struct stan_csv_timing {
      double warmup;
      double sampling;

      stan_csv_timing()
        : warmup(0), sampling(0) { }
    };

    struct stan_csv {
      stan_csv_metadata metadata;
      Eigen::Matrix<std::string, Eigen::Dynamic, 1> header;
      stan_csv_adaptation adaptation;
      Eigen::MatrixXd samples;
      stan_csv_timing timing;
    };

    /**
     * Reads from a Stan output csv file.
     */
    class stan_csv_reader {

    public:

      stan_csv_reader() {}
      ~stan_csv_reader() {}

      static bool read_metadata(std::istream& in, stan_csv_metadata& metadata) {

        std::stringstream ss;
        std::string line;

        if (in.peek() != '#')
          return false;
        while (in.peek() == '#') {
          std::getline(in, line);
          ss << line << '\n';
        }
        ss.seekg(std::ios_base::beg);

        char comment;
        std::string lhs;

        // Skip first two lines
        std::getline(ss, line);
        std::getline(ss, line);

        while (ss.good()) {

          ss >> comment;
          std::getline(ss, lhs, '=');
          boost::trim(lhs);

          if (lhs.compare("") == 0) { // no-op
          } else if (lhs.compare("stan_version_major") == 0) {
            ss >> metadata.stan_version_major;
          } else if (lhs.compare("stan_version_minor") == 0) {
            ss >> metadata.stan_version_minor;
          } else if (lhs.compare("stan_version_patch") == 0) {
            ss >> metadata.stan_version_patch;
          } else if (lhs.compare("model") == 0) {
            ss >> metadata.model;
          } else if (lhs.compare("data") == 0) {
            ss >> metadata.data;
          } else if (lhs.compare("init") == 0) {
            std::getline(ss, metadata.init);
            boost::trim(metadata.init);
            ss.unget();
          } else if (lhs.compare("append_samples") == 0) {
            ss >> metadata.append_samples;
          } else if (lhs.compare("save_warmup") == 0) {
            ss >> metadata.save_warmup;
          } else if (lhs.compare("seed") == 0) {
            ss >> metadata.seed;
            metadata.random_seed = false;
          } else if (lhs.compare("chain_id") == 0) {
            ss >> metadata.chain_id;
          } else if (lhs.compare("iter") == 0) {
            ss >> metadata.iter;
          } else if (lhs.compare("warmup") == 0) {
            ss >> metadata.warmup;
          } else if (lhs.compare("thin") == 0) {
            ss >> metadata.thin;
          } else if (lhs.compare("equal_step_sizes") == 0) {
            ss >> metadata.equal_step_sizes;
                } else if (lhs.compare("nondiag_mass") == 0) {
            ss >> metadata.nondiag_mass;
          } else if (lhs.compare("leapfrog_steps") == 0) {
            ss >> metadata.leapfrog_steps;
          } else if (lhs.compare("max_treedepth") == 0) {
            ss >> metadata.max_treedepth;
          } else if (lhs.compare("epsilon") == 0) {
            ss >> metadata.epsilon;
          } else if (lhs.compare("epsilon_pm") == 0) {
            ss >> metadata.epsilon_pm;
          } else if (lhs.compare("delta") == 0) {
            ss >> metadata.delta;
          } else if (lhs.compare("gamma") == 0) {
            ss >> metadata.gamma;
          } else if (lhs.compare("algorithm") == 0) {
            std::getline(ss, metadata.algorithm);
            boost::trim(metadata.algorithm);
            ss.unget();
          } else {
            std::cout << "unused option: " << lhs << std::endl;
          }

          std::getline(ss, line);

        }

        if (ss.good() == true)
          return false;

        return true;

      } // read_metadata

      static bool read_header(std::istream& in, Eigen::Matrix<std::string, Eigen::Dynamic, 1>& header) {

        std::string line;

        if (in.peek() != 'l')
          return false;

        std::getline(in, line);
        std::stringstream ss(line);

        header.resize(std::count(line.begin(), line.end(), ',') + 1);
        int idx = 0;
        while (ss.good()) {
          std::string token;
          std::getline(ss, token, ',');
          boost::trim(token);

          int pos = token.find('.');
          if (pos > 0) {
            token.replace(pos, 1, "[");
            std::replace(token.begin(), token.end(), '.', ',');
            token += "]";
          }
          header(idx++) = token;
        }
        return true;
      }

      static bool read_adaptation(std::istream& in, stan_csv_adaptation& adaptation) {

        std::stringstream ss;
        std::string line;
        int lines = 0;

        if (in.peek() != '#' || in.good() == false)
          return false;

        while (in.peek() == '#') {
          std::getline(in, line);
          ss << line << std::endl;
          lines++;
        }
        ss.seekg(std::ios_base::beg);

        char comment; // Buffer for comment indicator, #

        // Skip first two lines
        std::getline(ss, line);

        // Stepsize
        std::getline(ss, line, '=');
        boost::trim(line);
        ss >> adaptation.step_size;

        // Metric parameters
        std::getline(ss, line);
        std::getline(ss, line);
        std::getline(ss, line);

        int rows = lines - 3;
        int cols = std::count(line.begin(), line.end(), ',') + 1;
        adaptation.metric.resize(rows, cols);

        for (int row = 0; row < rows; row++) {

          std::stringstream line_ss;
          line_ss.str(line);
          line_ss >> comment;

          for (int col = 0; col < cols; col++) {
            std::string token;
            std::getline(line_ss, token, ',');
            boost::trim(token);
            adaptation.metric(row, col) = boost::lexical_cast<double>(token);
          }

          std::getline(ss, line); // Read in next line

        }

        if (ss.good())
          return false;
        else
          return true;

      }

      static bool read_samples(std::istream& in, Eigen::MatrixXd& samples, stan_csv_timing& timing) {

        std::stringstream ss;
        std::string line;

        int rows = 0;
        int cols = -1;

        if (in.peek() == '#' || in.good() == false)
          return false;

        while (in.good()) {

          bool comment_line = (in.peek() == '#');
          bool empty_line   = (in.peek() == '\n');

          std::getline(in, line);

          if (empty_line) continue;
          if (!line.length()) break;

          if (comment_line) {

            if (line.find("(Warm-up)") != std::string::npos) {
              int left = 16;
              int right = line.find(" seconds");
              timing.warmup += boost::lexical_cast<double>(line.substr(left, right - left));
            } else if (line.find("(Sampling)") != std::string::npos) {
              int left = 16;
              int right = line.find(" seconds");
              timing.sampling += boost::lexical_cast<double>(line.substr(left, right - left));
            }

          }
          else {

            ss << line << '\n';

            int current_cols = std::count(line.begin(), line.end(), ',') + 1;
            if (cols == -1) {
              cols = current_cols;
            } else if (cols != current_cols) {
              std::cout << "Error: expected " << cols << " columns, but found "
                        << current_cols << " instead for row " << rows + 1 << std::endl;
              return false;
            }
            rows++;

          }

          in.peek();

        }

        ss.seekg(std::ios_base::beg);

        if (rows > 0) {
          samples.resize(rows, cols);
          for (int row = 0; row < rows; row++) {
            std::getline(ss, line);
            std::stringstream ls(line);
            for (int col = 0; col < cols; col++) {
              std::getline(ls, line, ',');
              boost::trim(line);
              //std::cout << "line: !" << line << "@" << std::endl;
              samples(row, col) = boost::lexical_cast<double>(line);
              //std::cout << "after" << std::endl << std::endl;
            }
          }
        }
        return true;
      }

      /**
       * Parses the file.
       *
       */
      static stan_csv parse(std::istream& in) {

        stan_csv data;

        if (!read_metadata(in, data.metadata)) {
          std::cout << "Warning: non-fatal error reading metadata" << std::endl;
        }

        if (!read_header(in, data.header)) {
          std::cout << "Error: error reading header" << std::endl;
          throw std::invalid_argument("Error with header of input file in parse");
        }

        if (!read_adaptation(in, data.adaptation)) {
          std::cout << "Warning: non-fatal error reading adapation data" << std::endl;
        }

        data.timing.warmup = 0;
        data.timing.sampling = 0;

        if (!read_samples(in, data.samples, data.timing)) {
          std::cout << "Warning: non-fatal error reading samples" << std::endl;
        }

        return data;

      }

    };

  } // io

} // stan

#endif
<|endoftext|>


<commit_before>// An example how to display PS, EPS, PDF files in canvas
// To load a PS file in a TCanvas, the ghostscript program needs to be install.
// - On most unix systems it is installed by default.
// - On Windows it has to be installed from http://pages.cs.wisc.edu/~ghost/
//   also the place where gswin32c.exe sits should be added in the PATH. One
//   way to do it is:
//     1. Start the Control Panel
//     2. Double click on System
//     3, Open the "Advanced" tab
//     4. Click on the "Environment Variables" button
//     5. Find "Path" in "System varibale list", click on it.
//     6. Click on the "Edit" button.
//     7. In the "Variable value" field add the path of gswin32c
//        (after a ";") it should be something like:
//        "C:\Program Files\gs\gs8.13\bin"
//     8. click "OK" as much as needed.
//
//Author: Valeriy Onoutchin

#include "TROOT.h"
#include "TCanvas.h"
#include "TImage.h"

void psview()
{
   // set to batch mode -> do not display graphics
   gROOT->SetBatch(1);

   // create a PostScript file
   gROOT->Macro("feynman.C");
   gPad->Print("feynman.ps");

   // back to graphics mode
   gROOT->SetBatch(0);

   // create an image from PS file
   TImage *ps = TImage::Open("feynman.ps");

   if (!ps) {
      printf("GhostScript (gs) program must be installed\n");
      return;
   }

   new TCanvas("psexam", "Example how to display PS file in canvas", 500, 650);
   ps->Draw("xxx");
}
<commit_msg>- Better version.<commit_after>// An example how to display PS, EPS, PDF files in canvas
// To load a PS file in a TCanvas, the ghostscript program needs to be install.
// - On most unix systems it is installed by default.
// - On Windows it has to be installed from http://pages.cs.wisc.edu/~ghost/
//   also the place where gswin32c.exe sits should be added in the PATH. One
//   way to do it is:
//     1. Start the Control Panel
//     2. Double click on System
//     3, Open the "Advanced" tab
//     4. Click on the "Environment Variables" button
//     5. Find "Path" in "System varibale list", click on it.
//     6. Click on the "Edit" button.
//     7. In the "Variable value" field add the path of gswin32c
//        (after a ";") it should be something like:
//        "C:\Program Files\gs\gs8.13\bin"
//     8. click "OK" as much as needed.
//
//Author: Valeriy Onoutchin

#include "TROOT.h"
#include "TCanvas.h"
#include "TImage.h"

void psview()
{
   // set to batch mode -> do not display graphics
   gROOT->SetBatch(1);

   // create a PostScript file
   gROOT->Macro("feynman.C");
   gPad->Print("feynman.eps");

   // back to graphics mode
   gROOT->SetBatch(0);

   // create an image from PS file
   TImage *ps = TImage::Open("feynman.eps");

   if (!ps) {
      printf("GhostScript (gs) program must be installed\n");
      return;
   }

   new TCanvas("psexam", "Example how to display PS file in canvas", 600, 400);
   TLatex *tex = new TLatex(0.06,0.9,"The picture below has been loaded from a PS file:");
   tex->Draw();

   TPad *eps = new TPad("eps", "eps", 0., 0., 1., 0.75);
   eps->Draw();
   eps->cd();
   ps->Draw("xxx");
}
<|endoftext|>


<commit_before>////////////////////////////////////////////////////////////////////////////////
//                                                                            //
// This file is part of Swift2D.                                              //
//                                                                            //
// Copyright: (c) 2011-2014 Simon Schneegans & Felix Lauer                    //
//                                                                            //
////////////////////////////////////////////////////////////////////////////////

// includes  -------------------------------------------------------------------
#include <swift2d/network/Network.hpp>

#include <swift2d/network/ReplicationManager.hpp>
#include <swift2d/utils/Logger.hpp>
#include <swift2d/math/operators.hpp>

#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>

#include <raknet/MessageIdentifiers.h>
#include <raknet/RakNetTypes.h>
#include <raknet/RakPeerInterface.h>
#include <raknet/BitStream.h>
#include <raknet/FullyConnectedMesh2.h>
#include <raknet/PacketLogger.h>
#include <raknet/NatTypeDetectionClient.h>
#include <raknet/ConnectionGraph2.h>
#include <raknet/NatPunchthroughClient.h>
#include <raknet/NetworkIDManager.h>

#include <sstream>

#define USE_UPNP false

namespace swift {

////////////////////////////////////////////////////////////////////////////////

Network::Network()
  : phase_(STARTED)
  , peer_             (RakNet::RakPeerInterface::GetInstance())
  , graph_            (RakNet::ConnectionGraph2::GetInstance())
  , mesh_             (RakNet::FullyConnectedMesh2::GetInstance())
  , npt_              (RakNet::NatPunchthroughClient::GetInstance())
  , id_manager_       (new RakNet::NetworkIDManager())
  , replica_          (new ReplicationManager())
  , internal_id_      ("")
  , external_id_      ("") {

  peer_->AttachPlugin(mesh_);
  peer_->AttachPlugin(graph_);
  peer_->AttachPlugin(npt_);
  peer_->AttachPlugin(replica_);

  replica_->SetNetworkIDManager(id_manager_);
  replica_->SetAutoManageConnections(false,true);

  mesh_->SetAutoparticipateConnections(false);
  mesh_->SetConnectOnNewRemoteConnection(false, "");

  RakNet::SocketDescriptor sd;
  sd.socketFamily = AF_INET;
  sd.port = 0;

  RakNet::StartupResult sr = peer_->Startup(8, &sd, 1);

  if (sr != RakNet::RAKNET_STARTED) {
    LOG_ERROR << "Failed to start peer!" << std::endl;
  }

  peer_->SetMaximumIncomingConnections(8);
  peer_->SetTimeoutTime(1000, RakNet::UNASSIGNED_SYSTEM_ADDRESS);

  phase_ = CONNECTING_TO_NAT_SERVER;
  RakNet::ConnectionAttemptResult car = peer_->Connect("natpunch.jenkinssoftware.com", 61111, 0, 0);
}

////////////////////////////////////////////////////////////////////////////////

Network::~Network() {
  peer_->Shutdown(100);
  RakNet::RakPeerInterface::DestroyInstance(peer_);
  RakNet::ConnectionGraph2::DestroyInstance(graph_);
  RakNet::FullyConnectedMesh2::DestroyInstance(mesh_);

  delete replica_;
  delete id_manager_;
}

////////////////////////////////////////////////////////////////////////////////

void Network::connect(std::string const& other) {
  if (phase_ == STARTED) {

    auto o(RakNet::SystemAddress(other.c_str()));
    auto host(o.ToString(false));

    LOG_MESSAGE << "Connecting to " << host << "." << std::endl;

    if (is_in_same_network(other)) {
      phase_ = CONNECTING_TO_HOST;
      peer_->Connect(host, o.GetPort(), 0, 0);
    } else {
      phase_ = NAT_PUNCH_TO_HOST;
      npt_->OpenNAT(peer_->GetGuidFromSystemAddress(o),
                    RakNet::SystemAddress(nat_server_address_.c_str()));
    }
  }
}

////////////////////////////////////////////////////////////////////////////////

  // upnp_.on_success.connect([&](){
  //   Logger::LOG_MESSAGE << "Successfully opened UPNP." << std::endl;
  //   enter_phase(SEARCHING_FOR_OTHER_INSTANCES);
  // });

  // upnp_.on_fail.connect([&](){
  //   Logger::LOG_MESSAGE << "Failed to open UPNP. Using NAT punch through." << std::endl;
  //   enter_phase(OPENING_UPNP);
  // });

  // enter_phase(HOSTING_INSTANCE);

////////////////////////////////////////////////////////////////////////////////

void Network::update() {

  // auto register_new_peer = [&](RakNet::RakNetGUID guid){
  //   RakNet::Connection_RM3 *connection = replica_->AllocConnection(peer_->GetSystemAddressFromGuid(guid), guid);
  //   if (replica_->PushConnection(connection) == false) {
  //     replica_->DeallocConnection(connection);
  //   }
  // };

  for (RakNet::Packet* packet=peer_->Receive(); packet; peer_->DeallocatePacket(packet), packet=peer_->Receive()) {
    switch (packet->data[0]) {

      // ##################### BASIC PACKETS ###################################
      // -----------------------------------------------------------------------
      case ID_CONNECTION_REQUEST_ACCEPTED:

        if (phase_ == CONNECTING_TO_NAT_SERVER) {

          // the nat server accepted our connection
          LOG_MESSAGE << "Connected to NAT server." << std::endl;
          nat_server_address_ = packet->systemAddress.ToString();

          // save external ip
          external_id_ = peer_->GetExternalID(RakNet::UNASSIGNED_SYSTEM_ADDRESS).ToString();

          // broadcast on LAN to get internal ip
          peer_->AdvertiseSystem("255.255.255.255", peer_->GetInternalID().GetPort(), 0, 0);

        } else if (phase_ == NAT_PUNCH_TO_HOST) {

          // nat punch was successfull, we got a connection!
          phase_ = CONNECTING_TO_HOST;
          request_join(packet->guid.g);

        } else if (phase_ == CONNECTING_TO_HOST) {
          request_join(packet->guid.g);
        }

        break;

      // -----------------------------------------------------------------------
      case ID_ADVERTISE_SYSTEM:
        if (packet->guid.g == peer_->GetMyGUID().g) {
          // save internal ip
          internal_id_ = packet->systemAddress.ToString();
        }

        break;

      // // -----------------------------------------------------------------------
      // case ID_DISCONNECTION_NOTIFICATION:
      //   Logger::LOG_MESSAGE << packet->guid.ToString() << " disconnected." << std::endl;
      //   break;

      // // ################ NAT PUNCH THROUGH PACKETS ############################
      // // -----------------------------------------------------------------------
      // case ID_NAT_PUNCHTHROUGH_SUCCEEDED:
      //   if (phase_ == CONNECTING_TO_HOST || phase_ == CONNECTING_TO_PEERS) {
      //     Logger::LOG_MESSAGE << "NAT punch succeeded. Connecting..." << std::endl;
      //     connect(packet->systemAddress.ToString(false), packet->systemAddress.GetPort());
      //   }
      //   break;

      // // -----------------------------------------------------------------------
      // case ID_NAT_PUNCHTHROUGH_FAILED:
      //   Logger::LOG_MESSAGE << "NAT punch through failed." << std::endl;
      //   break;

      // // -----------------------------------------------------------------------
      // case ID_NAT_TYPE_DETECTION_RESULT: {
      //   auto type = (RakNet::NATTypeDetectionResult) packet->data[1];
      //   Logger::LOG_MESSAGE << "NAT Type is " << RakNet::NATTypeDetectionResultToString(type) << " (" << RakNet::NATTypeDetectionResultToStringFriendly(type) << ")" << std::endl;

      //   if (USE_UPNP) enter_phase(OPENING_UPNP);
      //   else          enter_phase(SEARCHING_FOR_OTHER_INSTANCES);
      //   } break;

      // // ################## FULLY CONNECTED MESH ###############################
      // // -----------------------------------------------------------------------
      // case ID_FCM2_NEW_HOST: {
      //   RakNet::BitStream bs(packet->data, packet->length, false);
      //   bs.IgnoreBytes(1);
      //   RakNet::RakNetGUID old_host;
      //   bs.Read(old_host);

      //   if (packet->guid.g == peer_->GetMyGUID().g) {
      //     if (phase_ != HOSTING_INSTANCE) {
      //       enter_phase(HOSTING_INSTANCE);
      //     }
      //   } else {
      //     Logger::LOG_MESSAGE << packet->guid.ToString() << " is host now." << std::endl;

      //     if (old_host != RakNet::UNASSIGNED_RAKNET_GUID) {
      //       Logger::LOG_MESSAGE << "Old host was " << old_host.ToString() << std::endl;
      //     } else {
      //       Logger::LOG_MESSAGE << "There was no host before." << std::endl;
      //     }
      //   }

      //   if (old_host == RakNet::UNASSIGNED_RAKNET_GUID) {
      //     DataStructures::List<RakNet::RakNetGUID> peers;
      //     mesh_->GetParticipantList(peers);
      //     for (unsigned int i=0; i < peers.Size(); i++) {
      //       register_new_peer(peers[i]);
      //     }
      //   }

      //   } break;

      // -----------------------------------------------------------------------
      case (ID_USER_PACKET_ENUM + REQUEST_JOIN):
        Logger::LOG_MESSAGE << "Got join request from " << packet->guid.ToString() << "." << std::endl;
        start_join(packet->guid.g);
        break;

      // // -----------------------------------------------------------------------
      // case ID_FCM2_VERIFIED_JOIN_CAPABLE:
      //   mesh_->RespondOnVerifiedJoinCapable(packet, true, 0);
      //   break;

      // // -----------------------------------------------------------------------
      // case ID_FCM2_VERIFIED_JOIN_ACCEPTED: {
      //   DataStructures::List<RakNet::RakNetGUID> peers;
      //   bool this_was_accepted;
      //   mesh_->GetVerifiedJoinAcceptedAdditionalData(packet, &this_was_accepted, peers, 0);
      //   if (this_was_accepted) {
      //     Logger::LOG_MESSAGE << "Join accepted." << std::endl;
      //   } else {
      //     Logger::LOG_MESSAGE << "Peer " << peers[0].ToString() << " joined the game." << std::endl;
      //   }

      //   if (mesh_->GetConnectedHost() != RakNet::UNASSIGNED_RAKNET_GUID) {
      //     for (unsigned int i=0; i < peers.Size(); i++) {
      //       register_new_peer(peers[i]);
      //     }
      //   }

      //   if (this_was_accepted) {
      //     enter_phase(PARTICIPATING);
      //   }

      // } break;

      // // -----------------------------------------------------------------------
      // case ID_FCM2_VERIFIED_JOIN_REJECTED:
      //   Logger::LOG_MESSAGE << "Join rejected." << std::endl;
      //   peer_->CloseConnection(packet->guid, true);
      //   break;

      // // -----------------------------------------------------------------------
      // case ID_FCM2_VERIFIED_JOIN_FAILED:
      //   Logger::LOG_MESSAGE << "Join failed." << std::endl;
      //   break;

      // -----------------------------------------------------------------------
      case ID_FCM2_VERIFIED_JOIN_START:
        Logger::LOG_MESSAGE << "Connecting to other peers..." << std::endl;
        // enter_phase(CONNECTING_TO_PEERS);
        // join(packet->guid.g, nat_server_address_);
        break;

      // ##################### OTHER PACKETS ###################################
      // -----------------------------------------------------------------------
      default:
        LOG_DEBUG << "Got " << RakNet::PacketLogger::BaseIDTOString(packet->data[0])
                          << " from " << packet->guid.ToString() << std::endl;
        break;
    }
  }
}

////////////////////////////////////////////////////////////////////////////////

void Network::distribute_object(NetworkObjectBase* object) {
  replica_->Reference(object);
}

////////////////////////////////////////////////////////////////////////////////

bool Network::is_in_same_network(std::string const& other) const {
  RakNet::SystemAddress o;
  RakNet::SystemAddress self;
  if (o.FromString(other.c_str()) && self.FromString(external_id_.c_str())) {
    if (o.EqualsExcludingPort(self)) {
      return true;
    }
  }
  return false;
}

////////////////////////////////////////////////////////////////////////////////

std::string const& Network::get_internal_address() const {
  return internal_id_;
}

////////////////////////////////////////////////////////////////////////////////

std::string const& Network::get_external_address() const {
  return external_id_;
}

////////////////////////////////////////////////////////////////////////////////

bool Network::is_host() const {
  return mesh_->IsConnectedHost();
}

////////////////////////////////////////////////////////////////////////////////

void Network::enter_phase(Phase phase) {
  // phase_ = phase;

  // switch (phase) {

  //   // -------------------------------------------------------------------------
  //   case CONNECTING_TO_SERVER:
  //     Logger::LOG_MESSAGE << "Connecting to NAT server..." << std::endl;
  //     connect("natpunch.jenkinssoftware.com", 61111);
  //     break;

  //   // -------------------------------------------------------------------------
  //   case OPENING_UPNP:
  //     Logger::LOG_MESSAGE << "Opening UPNP..." << std::endl;
  //     // upnp_.open(peer_);
  //     break;

  //   // -------------------------------------------------------------------------
  //   case SEARCHING_FOR_OTHER_INSTANCES:
  //     Logger::LOG_MESSAGE << "Downloading running instances from "
  //                         << "master server..." << std::endl;
  //     http_.get("masterserver2.raknet.com/testServer?__gameId=" + game_ID_,
  //               "masterserver2.raknet.com", 80);
  //     break;

  //   // -------------------------------------------------------------------------
  //   case CONNECTING_TO_HOST:
  //     Logger::LOG_MESSAGE << "Found running instance. Searching route to host "
  //                         << host_guid_ << "..." << std::endl;
  //     open_nat(host_guid_, nat_server_address_);
  //     break;

  //   // -------------------------------------------------------------------------
  //   case STARTING_NEW_INSTANCE:
  //     Logger::LOG_MESSAGE << "No running instances found. "
  //                         << "Starting new instance..." << std::endl;
  //     mesh_->ResetHostCalculation();
  //     // register_game();
  //     // update_timer_.reset();
  //     break;

  //   // -------------------------------------------------------------------------
  //   case HOSTING_INSTANCE:
  //     Logger::LOG_MESSAGE << "I'm host now." << std::endl;
  //     // register_game();
  //     // update_timer_.reset();
  //     break;

  //   // -------------------------------------------------------------------------
  //   case PARTICIPATING:
  //     Logger::LOG_MESSAGE << "Participating game." << std::endl;
  //     break;
  // }
}

////////////////////////////////////////////////////////////////////////////////

void Network::request_join(math::uint64 guid) {
  mesh_->ResetHostCalculation();

  RakNet::BitStream message;
  message.Write((RakNet::MessageID)(ID_USER_PACKET_ENUM + Network::REQUEST_JOIN));
  peer_->Send(&message, HIGH_PRIORITY, RELIABLE_ORDERED, 0, RakNet::RakNetGUID(guid), false);
}

////////////////////////////////////////////////////////////////////////////////

void Network::start_join(math::uint64 guid) {
  mesh_->StartVerifiedJoin(RakNet::RakNetGUID(guid));
}

////////////////////////////////////////////////////////////////////////////////

// void Network::join(math::uint64 guid, std::string const& nat_server) {
//   DataStructures::List<RakNet::SystemAddress> addresses;
//   DataStructures::List<RakNet::RakNetGUID> guids;
//   DataStructures::List<RakNet::BitStream*> userData;
//   mesh_->GetVerifiedJoinRequiredProcessingList(RakNet::RakNetGUID(guid), addresses, guids, userData);
//   for (unsigned int i=0; i < guids.Size(); i++) {
//     // if (guids[i].g != get_guid()) {
//       npt_->OpenNAT(guids[i], RakNet::SystemAddress(nat_server.c_str()));
//     // }
//   }
// }

////////////////////////////////////////////////////////////////////////////////

}
<commit_msg>added LAN connect<commit_after>////////////////////////////////////////////////////////////////////////////////
//                                                                            //
// This file is part of Swift2D.                                              //
//                                                                            //
// Copyright: (c) 2011-2014 Simon Schneegans & Felix Lauer                    //
//                                                                            //
////////////////////////////////////////////////////////////////////////////////

// includes  -------------------------------------------------------------------
#include <swift2d/network/Network.hpp>

#include <swift2d/network/ReplicationManager.hpp>
#include <swift2d/utils/Logger.hpp>
#include <swift2d/math/operators.hpp>

#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>

#include <raknet/MessageIdentifiers.h>
#include <raknet/RakNetTypes.h>
#include <raknet/RakPeerInterface.h>
#include <raknet/BitStream.h>
#include <raknet/FullyConnectedMesh2.h>
#include <raknet/PacketLogger.h>
#include <raknet/NatTypeDetectionClient.h>
#include <raknet/ConnectionGraph2.h>
#include <raknet/NatPunchthroughClient.h>
#include <raknet/NetworkIDManager.h>

#include <sstream>

#define USE_UPNP false

namespace swift {

////////////////////////////////////////////////////////////////////////////////

Network::Network()
  : phase_(STARTED)
  , peer_             (RakNet::RakPeerInterface::GetInstance())
  , graph_            (RakNet::ConnectionGraph2::GetInstance())
  , mesh_             (RakNet::FullyConnectedMesh2::GetInstance())
  , npt_              (RakNet::NatPunchthroughClient::GetInstance())
  , id_manager_       (new RakNet::NetworkIDManager())
  , replica_          (new ReplicationManager())
  , internal_id_      ("")
  , external_id_      ("") {

  peer_->AttachPlugin(mesh_);
  peer_->AttachPlugin(graph_);
  peer_->AttachPlugin(npt_);
  peer_->AttachPlugin(replica_);

  replica_->SetNetworkIDManager(id_manager_);
  replica_->SetAutoManageConnections(false,true);

  mesh_->SetAutoparticipateConnections(false);
  mesh_->SetConnectOnNewRemoteConnection(false, "");

  RakNet::SocketDescriptor sd;
  sd.socketFamily = AF_INET;
  sd.port = 0;

  RakNet::StartupResult sr = peer_->Startup(8, &sd, 1);

  if (sr != RakNet::RAKNET_STARTED) {
    LOG_ERROR << "Failed to start peer!" << std::endl;
  }

  peer_->SetMaximumIncomingConnections(8);
  peer_->SetTimeoutTime(1000, RakNet::UNASSIGNED_SYSTEM_ADDRESS);

  phase_ = CONNECTING_TO_NAT_SERVER;
  RakNet::ConnectionAttemptResult car = peer_->Connect("natpunch.jenkinssoftware.com", 61111, 0, 0);
}

////////////////////////////////////////////////////////////////////////////////

Network::~Network() {
  peer_->Shutdown(100);
  RakNet::RakPeerInterface::DestroyInstance(peer_);
  RakNet::ConnectionGraph2::DestroyInstance(graph_);
  RakNet::FullyConnectedMesh2::DestroyInstance(mesh_);

  delete replica_;
  delete id_manager_;
}

////////////////////////////////////////////////////////////////////////////////

void Network::connect(std::string const& other) {
  auto o(RakNet::SystemAddress(other.c_str()));

  if (is_in_same_network(other)) {
    phase_ = CONNECTING_TO_HOST;
    LOG_MESSAGE << "Connecting to " << o.ToString() << " via LAN..." << std::endl;
    peer_->Connect(o.ToString(false), o.GetPort(), 0, 0);
  } else {
    phase_ = NAT_PUNCH_TO_HOST;
    LOG_MESSAGE << "Connecting to " << o.ToString() << " via NatPunch..." << std::endl;
    npt_->OpenNAT(peer_->GetGuidFromSystemAddress(o),
                  RakNet::SystemAddress(nat_server_address_.c_str()));
  }
}

////////////////////////////////////////////////////////////////////////////////

  // upnp_.on_success.connect([&](){
  //   Logger::LOG_MESSAGE << "Successfully opened UPNP." << std::endl;
  //   enter_phase(SEARCHING_FOR_OTHER_INSTANCES);
  // });

  // upnp_.on_fail.connect([&](){
  //   Logger::LOG_MESSAGE << "Failed to open UPNP. Using NAT punch through." << std::endl;
  //   enter_phase(OPENING_UPNP);
  // });

  // enter_phase(HOSTING_INSTANCE);

////////////////////////////////////////////////////////////////////////////////

void Network::update() {

  // auto register_new_peer = [&](RakNet::RakNetGUID guid){
  //   RakNet::Connection_RM3 *connection = replica_->AllocConnection(peer_->GetSystemAddressFromGuid(guid), guid);
  //   if (replica_->PushConnection(connection) == false) {
  //     replica_->DeallocConnection(connection);
  //   }
  // };

  for (RakNet::Packet* packet=peer_->Receive(); packet; peer_->DeallocatePacket(packet), packet=peer_->Receive()) {
    switch (packet->data[0]) {

      // ##################### BASIC PACKETS ###################################
      // -----------------------------------------------------------------------
      case ID_CONNECTION_REQUEST_ACCEPTED:

        if (phase_ == CONNECTING_TO_NAT_SERVER) {

          // the nat server accepted our connection
          LOG_MESSAGE << "Connected to NAT server." << std::endl;
          nat_server_address_ = packet->systemAddress.ToString();
          peer_->CloseConnection(packet->systemAddress, true);

          // save external ip
          external_id_ = peer_->GetExternalID(RakNet::UNASSIGNED_SYSTEM_ADDRESS).ToString();

          // broadcast on LAN to get internal ip
          peer_->AdvertiseSystem("255.255.255.255", peer_->GetInternalID().GetPort(), 0, 0);

        } else if (phase_ == NAT_PUNCH_TO_HOST) {

          // nat punch was successfull, we got a connection!
          phase_ = CONNECTING_TO_HOST;
          request_join(packet->guid.g);

        } else if (phase_ == CONNECTING_TO_HOST) {
          request_join(packet->guid.g);
        }

        break;

      // -----------------------------------------------------------------------
      case ID_ADVERTISE_SYSTEM:
        if (packet->guid.g == peer_->GetMyGUID().g) {
          // save internal ip
          internal_id_ = packet->systemAddress.ToString();
        }

        break;

      // -----------------------------------------------------------------------
      case ID_DISCONNECTION_NOTIFICATION:
        Logger::LOG_MESSAGE << packet->guid.ToString() << " disconnected." << std::endl;
        break;

      // // ################ NAT PUNCH THROUGH PACKETS ############################
      // // -----------------------------------------------------------------------
      // case ID_NAT_PUNCHTHROUGH_SUCCEEDED:
      //   if (phase_ == CONNECTING_TO_HOST || phase_ == CONNECTING_TO_PEERS) {
      //     Logger::LOG_MESSAGE << "NAT punch succeeded. Connecting..." << std::endl;
      //     connect(packet->systemAddress.ToString(false), packet->systemAddress.GetPort());
      //   }
      //   break;

      // // -----------------------------------------------------------------------
      // case ID_NAT_PUNCHTHROUGH_FAILED:
      //   Logger::LOG_MESSAGE << "NAT punch through failed." << std::endl;
      //   break;

      // // -----------------------------------------------------------------------
      // case ID_NAT_TYPE_DETECTION_RESULT: {
      //   auto type = (RakNet::NATTypeDetectionResult) packet->data[1];
      //   Logger::LOG_MESSAGE << "NAT Type is " << RakNet::NATTypeDetectionResultToString(type) << " (" << RakNet::NATTypeDetectionResultToStringFriendly(type) << ")" << std::endl;

      //   if (USE_UPNP) enter_phase(OPENING_UPNP);
      //   else          enter_phase(SEARCHING_FOR_OTHER_INSTANCES);
      //   } break;

      // // ################## FULLY CONNECTED MESH ###############################
      // // -----------------------------------------------------------------------
      // case ID_FCM2_NEW_HOST: {
      //   RakNet::BitStream bs(packet->data, packet->length, false);
      //   bs.IgnoreBytes(1);
      //   RakNet::RakNetGUID old_host;
      //   bs.Read(old_host);

      //   if (packet->guid.g == peer_->GetMyGUID().g) {
      //     if (phase_ != HOSTING_INSTANCE) {
      //       enter_phase(HOSTING_INSTANCE);
      //     }
      //   } else {
      //     Logger::LOG_MESSAGE << packet->guid.ToString() << " is host now." << std::endl;

      //     if (old_host != RakNet::UNASSIGNED_RAKNET_GUID) {
      //       Logger::LOG_MESSAGE << "Old host was " << old_host.ToString() << std::endl;
      //     } else {
      //       Logger::LOG_MESSAGE << "There was no host before." << std::endl;
      //     }
      //   }

      //   if (old_host == RakNet::UNASSIGNED_RAKNET_GUID) {
      //     DataStructures::List<RakNet::RakNetGUID> peers;
      //     mesh_->GetParticipantList(peers);
      //     for (unsigned int i=0; i < peers.Size(); i++) {
      //       register_new_peer(peers[i]);
      //     }
      //   }

      //   } break;

      // -----------------------------------------------------------------------
      case (ID_USER_PACKET_ENUM + REQUEST_JOIN):
        Logger::LOG_MESSAGE << "Got join request from " << packet->guid.ToString() << "." << std::endl;
        start_join(packet->guid.g);
        break;

      // // -----------------------------------------------------------------------
      // case ID_FCM2_VERIFIED_JOIN_CAPABLE:
      //   mesh_->RespondOnVerifiedJoinCapable(packet, true, 0);
      //   break;

      // // -----------------------------------------------------------------------
      // case ID_FCM2_VERIFIED_JOIN_ACCEPTED: {
      //   DataStructures::List<RakNet::RakNetGUID> peers;
      //   bool this_was_accepted;
      //   mesh_->GetVerifiedJoinAcceptedAdditionalData(packet, &this_was_accepted, peers, 0);
      //   if (this_was_accepted) {
      //     Logger::LOG_MESSAGE << "Join accepted." << std::endl;
      //   } else {
      //     Logger::LOG_MESSAGE << "Peer " << peers[0].ToString() << " joined the game." << std::endl;
      //   }

      //   if (mesh_->GetConnectedHost() != RakNet::UNASSIGNED_RAKNET_GUID) {
      //     for (unsigned int i=0; i < peers.Size(); i++) {
      //       register_new_peer(peers[i]);
      //     }
      //   }

      //   if (this_was_accepted) {
      //     enter_phase(PARTICIPATING);
      //   }

      // } break;

      // // -----------------------------------------------------------------------
      // case ID_FCM2_VERIFIED_JOIN_REJECTED:
      //   Logger::LOG_MESSAGE << "Join rejected." << std::endl;
      //   peer_->CloseConnection(packet->guid, true);
      //   break;

      // // -----------------------------------------------------------------------
      // case ID_FCM2_VERIFIED_JOIN_FAILED:
      //   Logger::LOG_MESSAGE << "Join failed." << std::endl;
      //   break;

      // -----------------------------------------------------------------------
      case ID_FCM2_VERIFIED_JOIN_START:
        Logger::LOG_MESSAGE << "Connecting to other peers..." << std::endl;
        // enter_phase(CONNECTING_TO_PEERS);
        // join(packet->guid.g, nat_server_address_);
        break;

      // ##################### OTHER PACKETS ###################################
      // -----------------------------------------------------------------------
      default:
        LOG_DEBUG << "Got " << RakNet::PacketLogger::BaseIDTOString(packet->data[0])
                          << " from " << packet->guid.ToString() << std::endl;
        break;
    }
  }
}

////////////////////////////////////////////////////////////////////////////////

void Network::distribute_object(NetworkObjectBase* object) {
  replica_->Reference(object);
}

////////////////////////////////////////////////////////////////////////////////

bool Network::is_in_same_network(std::string const& other) const {
  RakNet::SystemAddress o;
  RakNet::SystemAddress self;
  if (o.FromString(other.c_str()) && self.FromString(external_id_.c_str())) {
    if (o.EqualsExcludingPort(self)) {
      return true;
    }
  }
  return false;
}

////////////////////////////////////////////////////////////////////////////////

std::string const& Network::get_internal_address() const {
  return internal_id_;
}

////////////////////////////////////////////////////////////////////////////////

std::string const& Network::get_external_address() const {
  return external_id_;
}

////////////////////////////////////////////////////////////////////////////////

bool Network::is_host() const {
  return mesh_->IsConnectedHost();
}

////////////////////////////////////////////////////////////////////////////////

void Network::enter_phase(Phase phase) {
  // phase_ = phase;

  // switch (phase) {

  //   // -------------------------------------------------------------------------
  //   case CONNECTING_TO_SERVER:
  //     Logger::LOG_MESSAGE << "Connecting to NAT server..." << std::endl;
  //     connect("natpunch.jenkinssoftware.com", 61111);
  //     break;

  //   // -------------------------------------------------------------------------
  //   case OPENING_UPNP:
  //     Logger::LOG_MESSAGE << "Opening UPNP..." << std::endl;
  //     // upnp_.open(peer_);
  //     break;

  //   // -------------------------------------------------------------------------
  //   case SEARCHING_FOR_OTHER_INSTANCES:
  //     Logger::LOG_MESSAGE << "Downloading running instances from "
  //                         << "master server..." << std::endl;
  //     http_.get("masterserver2.raknet.com/testServer?__gameId=" + game_ID_,
  //               "masterserver2.raknet.com", 80);
  //     break;

  //   // -------------------------------------------------------------------------
  //   case CONNECTING_TO_HOST:
  //     Logger::LOG_MESSAGE << "Found running instance. Searching route to host "
  //                         << host_guid_ << "..." << std::endl;
  //     open_nat(host_guid_, nat_server_address_);
  //     break;

  //   // -------------------------------------------------------------------------
  //   case STARTING_NEW_INSTANCE:
  //     Logger::LOG_MESSAGE << "No running instances found. "
  //                         << "Starting new instance..." << std::endl;
  //     mesh_->ResetHostCalculation();
  //     // register_game();
  //     // update_timer_.reset();
  //     break;

  //   // -------------------------------------------------------------------------
  //   case HOSTING_INSTANCE:
  //     Logger::LOG_MESSAGE << "I'm host now." << std::endl;
  //     // register_game();
  //     // update_timer_.reset();
  //     break;

  //   // -------------------------------------------------------------------------
  //   case PARTICIPATING:
  //     Logger::LOG_MESSAGE << "Participating game." << std::endl;
  //     break;
  // }
}

////////////////////////////////////////////////////////////////////////////////

void Network::request_join(math::uint64 guid) {
  mesh_->ResetHostCalculation();

  RakNet::BitStream message;
  message.Write((RakNet::MessageID)(ID_USER_PACKET_ENUM + Network::REQUEST_JOIN));
  peer_->Send(&message, HIGH_PRIORITY, RELIABLE_ORDERED, 0, RakNet::RakNetGUID(guid), false);
}

////////////////////////////////////////////////////////////////////////////////

void Network::start_join(math::uint64 guid) {
  mesh_->StartVerifiedJoin(RakNet::RakNetGUID(guid));
}

////////////////////////////////////////////////////////////////////////////////

// void Network::join(math::uint64 guid, std::string const& nat_server) {
//   DataStructures::List<RakNet::SystemAddress> addresses;
//   DataStructures::List<RakNet::RakNetGUID> guids;
//   DataStructures::List<RakNet::BitStream*> userData;
//   mesh_->GetVerifiedJoinRequiredProcessingList(RakNet::RakNetGUID(guid), addresses, guids, userData);
//   for (unsigned int i=0; i < guids.Size(); i++) {
//     // if (guids[i].g != get_guid()) {
//       npt_->OpenNAT(guids[i], RakNet::SystemAddress(nat_server.c_str()));
//     // }
//   }
// }

////////////////////////////////////////////////////////////////////////////////

}
<|endoftext|>


<commit_before>#include "StableHeaders.h"

#include <sstream>
#include <string>

#include <QApplication>
#include <QWidget>
#include <QPushButton>
#include <QHBoxLayout>

#ifndef Q_WS_WIN
#include <QX11Info>
#endif

#include "Framework.h"

#include "RexQEngine.h"

namespace Foundation
{

RexQEngine::RexQEngine(Framework *owner)
:owner_(owner)
{
    int argc = 0;
    app_ = new QApplication(argc, 0);
    ogre_host_widget_ = new QWidget();

    ogre_host_widget_->setWindowTitle("Ogre3D Window");
#ifndef Q_WS_WIN
    // At the begin render window and widget should be same size.
    ogre_host_widget_->resize(800,600);

#endif
    ogre_host_widget_->show();
}

RexQEngine::~RexQEngine()
{
    delete app_;
    app_ = 0;
}

std::string RexQEngine::GetMainWindowHandle() const
{
  std::stringstream windowHandle;

#ifndef Q_WS_WIN

    QX11Info info = ogre_host_widget_->x11Info();
    windowHandle << (unsigned long)(info.display());
    windowHandle << ":";
    windowHandle << static_cast<unsigned int>(info.screen());
    windowHandle << ":";

  // This which one is used depends that is widget allready created and is show()-method called.
  if (ogre_host_widget_->isHidden())
    windowHandle << static_cast<unsigned long>(ogre_host_widget_->effectiveWinId());
  else
    windowHandle << static_cast<unsigned long>(ogre_host_widget_->winId());

 #else

    windowHandle << (size_t)(HWND)ogre_host_widget_->winId();

#endif

   return windowHandle.str();

}

void RexQEngine::UpdateFrame()
{
    assert(owner_);

    owner_->ProcessOneFrame();

    /// \todo Compute a new delta time. \todo Break down update and render.
    frame_update_timer_.start(16);
}

void RexQEngine::Go()
{
    assert(app_);

    QObject::connect(app_, SIGNAL(aboutToQuit()), this, SLOT(OnQuitQApp()));

    // Application frame updates are processed according to the periodic
    // ticks of this timer.
    QObject::connect(&frame_update_timer_, SIGNAL(timeout()), this, SLOT(UpdateFrame()));
    frame_update_timer_.setSingleShot(true);
    frame_update_timer_.start(16);

    app_->exec();
}

void RexQEngine::OnQuitQApp()
{
    owner_->Exit();
    app_->quit();
}

}
<commit_msg>Qt timer set to 0 for lots of framerate :)<commit_after>#include "StableHeaders.h"

#include <sstream>
#include <string>

#include <QApplication>
#include <QWidget>
#include <QPushButton>
#include <QHBoxLayout>

#ifndef Q_WS_WIN
#include <QX11Info>
#endif

#include "Framework.h"

#include "RexQEngine.h"

namespace Foundation
{

RexQEngine::RexQEngine(Framework *owner)
:owner_(owner)
{
    int argc = 0;
    app_ = new QApplication(argc, 0);
    ogre_host_widget_ = new QWidget();

    ogre_host_widget_->setWindowTitle("Ogre3D Window");
#ifndef Q_WS_WIN
    // At the begin render window and widget should be same size.
    ogre_host_widget_->resize(800,600);

#endif
    ogre_host_widget_->show();
}

RexQEngine::~RexQEngine()
{
    delete app_;
    app_ = 0;
}

std::string RexQEngine::GetMainWindowHandle() const
{
  std::stringstream windowHandle;

#ifndef Q_WS_WIN

    QX11Info info = ogre_host_widget_->x11Info();
    windowHandle << (unsigned long)(info.display());
    windowHandle << ":";
    windowHandle << static_cast<unsigned int>(info.screen());
    windowHandle << ":";

  // This which one is used depends that is widget allready created and is show()-method called.
  if (ogre_host_widget_->isHidden())
    windowHandle << static_cast<unsigned long>(ogre_host_widget_->effectiveWinId());
  else
    windowHandle << static_cast<unsigned long>(ogre_host_widget_->winId());

 #else

    windowHandle << (size_t)(HWND)ogre_host_widget_->winId();

#endif

   return windowHandle.str();

}

void RexQEngine::UpdateFrame()
{
    assert(owner_);

    owner_->ProcessOneFrame();

    /// \todo Compute a new delta time. \todo Break down update and render.
    frame_update_timer_.start(0);
}

void RexQEngine::Go()
{
    assert(app_);

    QObject::connect(app_, SIGNAL(aboutToQuit()), this, SLOT(OnQuitQApp()));

    // Application frame updates are processed according to the periodic
    // ticks of this timer.
    QObject::connect(&frame_update_timer_, SIGNAL(timeout()), this, SLOT(UpdateFrame()));
    frame_update_timer_.setSingleShot(true);
    frame_update_timer_.start(0);

    app_->exec();
}

void RexQEngine::OnQuitQApp()
{
    owner_->Exit();
    app_->quit();
}

}
<|endoftext|>


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

#if defined(HAVE_CONFIG_H)
#include "config/pivx-config.h"
#endif

#include "consensus/merkle.h"
#include "primitives/block.h"
#include "addrman.h"
#include "chain.h"
#include "coins.h"
#include "compressor.h"
#include "net.h"
#include "protocol.h"
#include "streams.h"
#include "undo.h"
#include "version.h"
#include "pubkey.h"

#include <stdint.h>
#include <unistd.h>

#include <algorithm>
#include <vector>

enum TEST_ID {
    CBLOCK_DESERIALIZE=0,
    CTRANSACTION_DESERIALIZE,
    CBLOCKLOCATOR_DESERIALIZE,
    CBLOCKMERKLEROOT,
    CADDRMAN_DESERIALIZE,
    CBLOCKHEADER_DESERIALIZE,
    CBANENTRY_DESERIALIZE,
    CTXUNDO_DESERIALIZE,
    CBLOCKUNDO_DESERIALIZE,
    CCOINS_DESERIALIZE,
    CNETADDR_DESERIALIZE,
    CSERVICE_DESERIALIZE,
    CMESSAGEHEADER_DESERIALIZE,
    CADDRESS_DESERIALIZE,
    CINV_DESERIALIZE,
    CBLOOMFILTER_DESERIALIZE,
    CDISKBLOCKINDEX_DESERIALIZE,
    CTXOUTCOMPRESSOR_DESERIALIZE,
    TEST_ID_END
};

bool read_stdin(std::vector<uint8_t> &data) {
    uint8_t buffer[1024];
    ssize_t length=0;
    while((length = read(STDIN_FILENO, buffer, 1024)) > 0) {
        data.insert(data.end(), buffer, buffer+length);

        if (data.size() > (1<<20)) return false;
    }
    return length==0;
}

int test_one_input(std::vector<uint8_t> buffer) {
    if (buffer.size() < sizeof(uint32_t)) return 0;

    uint32_t test_id = 0xffffffff;
    memcpy(&test_id, &buffer[0], sizeof(uint32_t));
    buffer.erase(buffer.begin(), buffer.begin() + sizeof(uint32_t));

    if (test_id >= TEST_ID_END) return 0;

    CDataStream ds(buffer, SER_NETWORK, INIT_PROTO_VERSION);
    try {
        int nVersion;
        ds >> nVersion;
        ds.SetVersion(nVersion);
    } catch (const std::ios_base::failure& e) {
        return 0;
    }

    switch(test_id) {
        case CBLOCK_DESERIALIZE:
        {
            try
            {
                CBlock block;
                ds >> block;
            } catch (const std::ios_base::failure& e) {return 0;}
            break;
        }
        case CTRANSACTION_DESERIALIZE:
        {
            try
            {
                CTransaction tx(deserialize, ds);
            } catch (const std::ios_base::failure& e) {return 0;}
            break;
        }
        case CBLOCKLOCATOR_DESERIALIZE:
        {
            try
            {
                CBlockLocator bl;
                ds >> bl;
            } catch (const std::ios_base::failure& e) {return 0;}
            break;
        }
        case CBLOCKMERKLEROOT:
        {
            try
            {
                CBlock block;
                ds >> block;
                bool mutated;
                BlockMerkleRoot(block, &mutated);
            } catch (const std::ios_base::failure& e) {return 0;}
            break;
        }
        case CADDRMAN_DESERIALIZE:
        {
            try
            {
                CAddrMan am;
                ds >> am;
            } catch (const std::ios_base::failure& e) {return 0;}
            break;
        }
        case CBLOCKHEADER_DESERIALIZE:
        {
            try
            {
                CBlockHeader bh;
                ds >> bh;
            } catch (const std::ios_base::failure& e) {return 0;}
            break;
        }
        case CBANENTRY_DESERIALIZE:
        {
            try
            {
                CBanEntry be;
                ds >> be;
            } catch (const std::ios_base::failure& e) {return 0;}
            break;
        }
        case CTXUNDO_DESERIALIZE:
        {
            try
            {
                CTxUndo tu;
                ds >> tu;
            } catch (const std::ios_base::failure& e) {return 0;}
            break;
        }
        case CBLOCKUNDO_DESERIALIZE:
        {
            try
            {
                CBlockUndo bu;
                ds >> bu;
            } catch (const std::ios_base::failure& e) {return 0;}
            break;
        }
        case CCOINS_DESERIALIZE:
        {
            try
            {
                Coin block;
                ds >> block;
            } catch (const std::ios_base::failure& e) {return 0;}
            break;
        }
        case CNETADDR_DESERIALIZE:
        {
            try
            {
                CNetAddr na;
                ds >> na;
            } catch (const std::ios_base::failure& e) {return 0;}
            break;
        }
        case CSERVICE_DESERIALIZE:
        {
            try
            {
                CService s;
                ds >> s;
            } catch (const std::ios_base::failure& e) {return 0;}
            break;
        }
        case CMESSAGEHEADER_DESERIALIZE:
        {
            CMessageHeader::MessageStartChars pchMessageStart = {0x00, 0x00, 0x00, 0x00};
            try
            {
                CMessageHeader mh(pchMessageStart);
                ds >> mh;
                if (!mh.IsValid(pchMessageStart)) {return 0;}
            } catch (const std::ios_base::failure& e) {return 0;}
            break;
        }
        case CADDRESS_DESERIALIZE:
        {
            try
            {
                CAddress a;
                ds >> a;
            } catch (const std::ios_base::failure& e) {return 0;}
            break;
        }
        case CINV_DESERIALIZE:
        {
            try
            {
                CInv i;
                ds >> i;
            } catch (const std::ios_base::failure& e) {return 0;}
            break;
        }
        case CBLOOMFILTER_DESERIALIZE:
        {
            try
            {
                CBloomFilter bf;
                ds >> bf;
            } catch (const std::ios_base::failure& e) {return 0;}
            break;
        }
        case CDISKBLOCKINDEX_DESERIALIZE:
        {
            try
            {
                CDiskBlockIndex dbi;
                ds >> dbi;
            } catch (const std::ios_base::failure& e) {return 0;}
            break;
        }
        case CTXOUTCOMPRESSOR_DESERIALIZE:
        {
            CTxOut to;
            CTxOutCompressor toc(to);
            try
            {
                ds >> toc;
            } catch (const std::ios_base::failure& e) {return 0;}

            break;
        }
        default:
            return 0;
    }
    return 0;
}

static std::unique_ptr<ECCVerifyHandle> globalVerifyHandle;
void initialize() {
    globalVerifyHandle = std::unique_ptr<ECCVerifyHandle>(new ECCVerifyHandle());
    SelectParams(CBaseChainParams::MAIN);
}

// This function is used by libFuzzer
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
    test_one_input(std::vector<uint8_t>(data, data + size));
    return 0;
}

// This function is used by libFuzzer
extern "C" int LLVMFuzzerInitialize(int *argc, char ***argv) {
    initialize();
    return 0;
}

// Disabled under WIN32 due to clash with Cygwin's WinMain.
#ifndef WIN32
// Declare main(...) "weak" to allow for libFuzzer linking. libFuzzer provides
// the main(...) function.
__attribute__((weak))
#endif
int main(int argc, char **argv)
{
    initialize();
#ifdef __AFL_INIT
    // Enable AFL deferred forkserver mode. Requires compilation using
    // afl-clang-fast++. See fuzzing.md for details.
    __AFL_INIT();
#endif

#ifdef __AFL_LOOP
    // Enable AFL persistent mode. Requires compilation using afl-clang-fast++.
    // See fuzzing.md for details.
    int ret = 0;
    while (__AFL_LOOP(1000)) {
        std::vector<uint8_t> buffer;
        if (!read_stdin(buffer)) {
            continue;
        }
        ret = test_one_input(buffer);
    }
    return ret;
#else
    std::vector<uint8_t> buffer;
    if (!read_stdin(buffer)) {
        return 0;
    }
    return test_one_input(buffer);
#endif
}
<commit_msg>[test] fuzz: make test_one_input return void<commit_after>// Copyright (c) 2009-2015 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#if defined(HAVE_CONFIG_H)
#include "config/pivx-config.h"
#endif

#include "consensus/merkle.h"
#include "primitives/block.h"
#include "addrman.h"
#include "chain.h"
#include "coins.h"
#include "compressor.h"
#include "net.h"
#include "protocol.h"
#include "streams.h"
#include "undo.h"
#include "version.h"
#include "pubkey.h"

#include <stdint.h>
#include <unistd.h>

#include <algorithm>
#include <vector>

enum TEST_ID {
    CBLOCK_DESERIALIZE=0,
    CTRANSACTION_DESERIALIZE,
    CBLOCKLOCATOR_DESERIALIZE,
    CBLOCKMERKLEROOT,
    CADDRMAN_DESERIALIZE,
    CBLOCKHEADER_DESERIALIZE,
    CBANENTRY_DESERIALIZE,
    CTXUNDO_DESERIALIZE,
    CBLOCKUNDO_DESERIALIZE,
    CCOINS_DESERIALIZE,
    CNETADDR_DESERIALIZE,
    CSERVICE_DESERIALIZE,
    CMESSAGEHEADER_DESERIALIZE,
    CADDRESS_DESERIALIZE,
    CINV_DESERIALIZE,
    CBLOOMFILTER_DESERIALIZE,
    CDISKBLOCKINDEX_DESERIALIZE,
    CTXOUTCOMPRESSOR_DESERIALIZE,
    TEST_ID_END
};

static bool read_stdin(std::vector<uint8_t>& data)
{
    uint8_t buffer[1024];
    ssize_t length = 0;
    while ((length = read(STDIN_FILENO, buffer, 1024)) > 0) {
        data.insert(data.end(), buffer, buffer + length);

        if (data.size() > (1 << 20)) return false;
    }
    return length == 0;
}

void test_one_input(std::vector<uint8_t> buffer)
{
    if (buffer.size() < sizeof(uint32_t)) return;

    uint32_t test_id = 0xffffffff;
    memcpy(&test_id, &buffer[0], sizeof(uint32_t));
    buffer.erase(buffer.begin(), buffer.begin() + sizeof(uint32_t));

    if (test_id >= TEST_ID_END) return;

    CDataStream ds(buffer, SER_NETWORK, INIT_PROTO_VERSION);
    try {
        int nVersion;
        ds >> nVersion;
        ds.SetVersion(nVersion);
    } catch (const std::ios_base::failure& e) {
        return;
    }

    switch(test_id) {
        case CBLOCK_DESERIALIZE:
        {
            try
            {
                CBlock block;
                ds >> block;
            } catch (const std::ios_base::failure& e) {return;}
            break;
        }
        case CTRANSACTION_DESERIALIZE:
        {
            try
            {
                CTransaction tx(deserialize, ds);
            } catch (const std::ios_base::failure& e) {return;}
            break;
        }
        case CBLOCKLOCATOR_DESERIALIZE:
        {
            try
            {
                CBlockLocator bl;
                ds >> bl;
            } catch (const std::ios_base::failure& e) {return;}
            break;
        }
        case CBLOCKMERKLEROOT:
        {
            try
            {
                CBlock block;
                ds >> block;
                bool mutated;
                BlockMerkleRoot(block, &mutated);
            } catch (const std::ios_base::failure& e) {return;}
            break;
        }
        case CADDRMAN_DESERIALIZE:
        {
            try
            {
                CAddrMan am;
                ds >> am;
            } catch (const std::ios_base::failure& e) {return;}
            break;
        }
        case CBLOCKHEADER_DESERIALIZE:
        {
            try
            {
                CBlockHeader bh;
                ds >> bh;
            } catch (const std::ios_base::failure& e) {return;}
            break;
        }
        case CBANENTRY_DESERIALIZE:
        {
            try
            {
                CBanEntry be;
                ds >> be;
            } catch (const std::ios_base::failure& e) {return;}
            break;
        }
        case CTXUNDO_DESERIALIZE:
        {
            try
            {
                CTxUndo tu;
                ds >> tu;
            } catch (const std::ios_base::failure& e) {return;}
            break;
        }
        case CBLOCKUNDO_DESERIALIZE:
        {
            try
            {
                CBlockUndo bu;
                ds >> bu;
            } catch (const std::ios_base::failure& e) {return;}
            break;
        }
        case CCOINS_DESERIALIZE:
        {
            try
            {
                Coin coin;
                ds >> coin;
            } catch (const std::ios_base::failure& e) {return;}
            break;
        }
        case CNETADDR_DESERIALIZE:
        {
            try
            {
                CNetAddr na;
                ds >> na;
            } catch (const std::ios_base::failure& e) {return;}
            break;
        }
        case CSERVICE_DESERIALIZE:
        {
            try
            {
                CService s;
                ds >> s;
            } catch (const std::ios_base::failure& e) {return;}
            break;
        }
        case CMESSAGEHEADER_DESERIALIZE:
        {
            CMessageHeader::MessageStartChars pchMessageStart = {0x00, 0x00, 0x00, 0x00};
            try
            {
                CMessageHeader mh(pchMessageStart);
                ds >> mh;
                if (!mh.IsValid(pchMessageStart)) {return;}
            } catch (const std::ios_base::failure& e) {return;}
            break;
        }
        case CADDRESS_DESERIALIZE:
        {
            try
            {
                CAddress a;
                ds >> a;
            } catch (const std::ios_base::failure& e) {return;}
            break;
        }
        case CINV_DESERIALIZE:
        {
            try
            {
                CInv i;
                ds >> i;
            } catch (const std::ios_base::failure& e) {return;}
            break;
        }
        case CBLOOMFILTER_DESERIALIZE:
        {
            try
            {
                CBloomFilter bf;
                ds >> bf;
            } catch (const std::ios_base::failure& e) {return;}
            break;
        }
        case CDISKBLOCKINDEX_DESERIALIZE:
        {
            try
            {
                CDiskBlockIndex dbi;
                ds >> dbi;
            } catch (const std::ios_base::failure& e) {return;}
            break;
        }
        case CTXOUTCOMPRESSOR_DESERIALIZE:
        {
            CTxOut to;
            CTxOutCompressor toc(to);
            try
            {
                ds >> toc;
            } catch (const std::ios_base::failure& e) {return;}

            break;
        }
        default:
            return;
    }
    return;
}

static std::unique_ptr<ECCVerifyHandle> globalVerifyHandle;
void initialize() {
    globalVerifyHandle = std::unique_ptr<ECCVerifyHandle>(new ECCVerifyHandle());
    SelectParams(CBaseChainParams::MAIN);
}

// This function is used by libFuzzer
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
{
    test_one_input(std::vector<uint8_t>(data, data + size));
    return 0;
}

// This function is used by libFuzzer
extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv)
{
    initialize();
    return 0;
}

// Disabled under WIN32 due to clash with Cygwin's WinMain.
#ifndef WIN32
// Declare main(...) "weak" to allow for libFuzzer linking. libFuzzer provides
// the main(...) function.
__attribute__((weak))
#endif
int main(int argc, char **argv)
{
    initialize();
#ifdef __AFL_INIT
    // Enable AFL deferred forkserver mode. Requires compilation using
    // afl-clang-fast++. See fuzzing.md for details.
    __AFL_INIT();
#endif

#ifdef __AFL_LOOP
    // Enable AFL persistent mode. Requires compilation using afl-clang-fast++.
    // See fuzzing.md for details.
    while (__AFL_LOOP(1000)) {
        std::vector<uint8_t> buffer;
        if (!read_stdin(buffer)) {
            continue;
        }
        test_one_input(buffer);
    }
#else
    std::vector<uint8_t> buffer;
    if (!read_stdin(buffer)) {
        return 0;
    }
    test_one_input(buffer);
#endif
}
<|endoftext|>


<commit_before>#include "../CssTokenizer.h"
#include "gtest/gtest.h"

/**
 * Test if the tokenizer reckognizes the tokens in the input string.
 */
TEST(CssTokenizerTest, ReckognizesTokens) {
  istringstream in("identifier @atkeyword #hash 1234 100% 1.5em : ; { } ( ) [ ] /* comment */ function( ~= |= ~ ");

  CssTokenizer t(&in);
  EXPECT_EQ(Token::IDENTIFIER, t.readNextToken());
  EXPECT_EQ(Token::WHITESPACE, t.readNextToken());
  EXPECT_EQ(Token::ATKEYWORD, t.readNextToken());
  EXPECT_EQ(Token::WHITESPACE, t.readNextToken());
  EXPECT_EQ(Token::HASH, t.readNextToken());
  EXPECT_EQ(Token::WHITESPACE, t.readNextToken());
  EXPECT_EQ(Token::NUMBER, t.readNextToken());
  EXPECT_EQ(Token::WHITESPACE, t.readNextToken());
  EXPECT_EQ(Token::PERCENTAGE, t.readNextToken());
  EXPECT_EQ(Token::WHITESPACE, t.readNextToken());
  EXPECT_EQ(Token::DIMENSION, t.readNextToken());
  EXPECT_EQ(Token::WHITESPACE, t.readNextToken());
  EXPECT_EQ(Token::COLON, t.readNextToken());
  EXPECT_EQ(Token::WHITESPACE, t.readNextToken());
  EXPECT_EQ(Token::DELIMITER, t.readNextToken());
  EXPECT_EQ(Token::WHITESPACE, t.readNextToken());
  EXPECT_EQ(Token::BRACKET_OPEN, t.readNextToken());
  EXPECT_EQ(Token::WHITESPACE, t.readNextToken());
  EXPECT_EQ(Token::BRACKET_CLOSED, t.readNextToken());
  EXPECT_EQ(Token::WHITESPACE, t.readNextToken());
  EXPECT_EQ(Token::PAREN_OPEN, t.readNextToken());
  EXPECT_EQ(Token::WHITESPACE, t.readNextToken());
  EXPECT_EQ(Token::PAREN_CLOSED, t.readNextToken());
  EXPECT_EQ(Token::WHITESPACE, t.readNextToken());
  EXPECT_EQ(Token::BRACE_OPEN, t.readNextToken());
  EXPECT_EQ(Token::WHITESPACE, t.readNextToken());
  EXPECT_EQ(Token::BRACE_CLOSED, t.readNextToken());
  EXPECT_EQ(Token::WHITESPACE, t.readNextToken());
  EXPECT_EQ(Token::COMMENT, t.readNextToken());
  EXPECT_EQ(Token::WHITESPACE, t.readNextToken());
  EXPECT_EQ(Token::FUNCTION, t.readNextToken());
  EXPECT_EQ(Token::WHITESPACE, t.readNextToken());
  EXPECT_EQ(Token::INCLUDES, t.readNextToken());
  EXPECT_EQ(Token::WHITESPACE, t.readNextToken());
  EXPECT_EQ(Token::DASHMATCH, t.readNextToken());
  EXPECT_EQ(Token::WHITESPACE, t.readNextToken());
  EXPECT_EQ(Token::OTHER, t.readNextToken());
  EXPECT_EQ(Token::WHITESPACE, t.readNextToken());
  EXPECT_EQ(Token::EOS, t.readNextToken());
}

/**
 * Test strings quoted with double quotes, single quotes, strings
 * containing newlines, and strings containing unicode characters.
 */
TEST(CssTokenizerTest, String) {
  istringstream in("\"string\" 'string' 'string\\\nstring' '\\12EF'"),
    inBad1("'string\n'"),
    inBad2("'string"),
    newlines("'\\\n \\\r\n \\\r'");

  CssTokenizer t(&in), tBad1(&inBad1), tBad2(&inBad2),
    tNewlines(&newlines);

  EXPECT_EQ(Token::STRING, t.readNextToken());
  EXPECT_EQ(Token::WHITESPACE, t.readNextToken());
  EXPECT_EQ(Token::STRING, t.readNextToken());
  EXPECT_EQ(Token::WHITESPACE, t.readNextToken());
  EXPECT_EQ(Token::STRING, t.readNextToken());
  EXPECT_EQ(Token::WHITESPACE, t.readNextToken());
  EXPECT_EQ(Token::STRING, t.readNextToken());

  EXPECT_THROW(tBad1.readNextToken(), ParseException*);
  EXPECT_THROW(tBad2.readNextToken(), ParseException*);

  ASSERT_EQ(Token::STRING, tNewlines.readNextToken());
  EXPECT_STREQ("'\\\n \\\r\n \\\r'", tNewlines.getToken()->str.c_str());
}

TEST(CssTokenizerTest, URL) {
  istringstream in("url(../img/img.png) url('http://example.com/image.jpg')");

  CssTokenizer t(&in);
  EXPECT_EQ(Token::URL, t.readNextToken());
  EXPECT_EQ(Token::WHITESPACE, t.readNextToken());
  EXPECT_EQ(Token::URL, t.readNextToken());
}

TEST(CssTokenizerTest, UnicodeRange) {
  istringstream in("u+123 u+123DEF-123");
  CssTokenizer t(&in);
  EXPECT_EQ(Token::UNICODE_RANGE, t.readNextToken());
  EXPECT_EQ(Token::WHITESPACE, t.readNextToken());
  EXPECT_EQ(Token::UNICODE_RANGE, t.readNextToken());
}

TEST(CssTokenizerTest, NonAscii) {
  istringstream in("a\xEE€");
  CssTokenizer t(&in);
  EXPECT_EQ(Token::IDENTIFIER, t.readNextToken());
  EXPECT_STREQ("a\xEE€", t.getToken()->str.c_str());
}

TEST(CssTokenizerTest, Minus) {
  istringstream in("-10 -50% -5em -identifier -moz-border-radius( -");
  CssTokenizer t(&in);
  EXPECT_EQ(Token::NUMBER, t.readNextToken());
  EXPECT_EQ(Token::WHITESPACE, t.readNextToken());
  EXPECT_EQ(Token::PERCENTAGE, t.readNextToken());
  EXPECT_EQ(Token::WHITESPACE, t.readNextToken());
  EXPECT_EQ(Token::DIMENSION, t.readNextToken());
  EXPECT_EQ(Token::WHITESPACE, t.readNextToken());
  EXPECT_EQ(Token::IDENTIFIER, t.readNextToken());
  EXPECT_EQ(Token::WHITESPACE, t.readNextToken());
  EXPECT_EQ(Token::FUNCTION, t.readNextToken());
}
<commit_msg>Added test case to CssTokenizer unit test checking if tokens of type Token::OTHER are reckognized.<commit_after>#include "../CssTokenizer.h"
#include "gtest/gtest.h"

/**
 * Test if the tokenizer reckognizes the tokens in the input string.
 */
TEST(CssTokenizerTest, ReckognizesTokens) {
  istringstream in("identifier @atkeyword #hash 1234 100% 1.5em : ; { } ( ) [ ] /* comment */ function( ~= |= ~ ");

  CssTokenizer t(&in);
  EXPECT_EQ(Token::IDENTIFIER, t.readNextToken());
  EXPECT_EQ(Token::WHITESPACE, t.readNextToken());
  EXPECT_EQ(Token::ATKEYWORD, t.readNextToken());
  EXPECT_EQ(Token::WHITESPACE, t.readNextToken());
  EXPECT_EQ(Token::HASH, t.readNextToken());
  EXPECT_EQ(Token::WHITESPACE, t.readNextToken());
  EXPECT_EQ(Token::NUMBER, t.readNextToken());
  EXPECT_EQ(Token::WHITESPACE, t.readNextToken());
  EXPECT_EQ(Token::PERCENTAGE, t.readNextToken());
  EXPECT_EQ(Token::WHITESPACE, t.readNextToken());
  EXPECT_EQ(Token::DIMENSION, t.readNextToken());
  EXPECT_EQ(Token::WHITESPACE, t.readNextToken());
  EXPECT_EQ(Token::COLON, t.readNextToken());
  EXPECT_EQ(Token::WHITESPACE, t.readNextToken());
  EXPECT_EQ(Token::DELIMITER, t.readNextToken());
  EXPECT_EQ(Token::WHITESPACE, t.readNextToken());
  EXPECT_EQ(Token::BRACKET_OPEN, t.readNextToken());
  EXPECT_EQ(Token::WHITESPACE, t.readNextToken());
  EXPECT_EQ(Token::BRACKET_CLOSED, t.readNextToken());
  EXPECT_EQ(Token::WHITESPACE, t.readNextToken());
  EXPECT_EQ(Token::PAREN_OPEN, t.readNextToken());
  EXPECT_EQ(Token::WHITESPACE, t.readNextToken());
  EXPECT_EQ(Token::PAREN_CLOSED, t.readNextToken());
  EXPECT_EQ(Token::WHITESPACE, t.readNextToken());
  EXPECT_EQ(Token::BRACE_OPEN, t.readNextToken());
  EXPECT_EQ(Token::WHITESPACE, t.readNextToken());
  EXPECT_EQ(Token::BRACE_CLOSED, t.readNextToken());
  EXPECT_EQ(Token::WHITESPACE, t.readNextToken());
  EXPECT_EQ(Token::COMMENT, t.readNextToken());
  EXPECT_EQ(Token::WHITESPACE, t.readNextToken());
  EXPECT_EQ(Token::FUNCTION, t.readNextToken());
  EXPECT_EQ(Token::WHITESPACE, t.readNextToken());
  EXPECT_EQ(Token::INCLUDES, t.readNextToken());
  EXPECT_EQ(Token::WHITESPACE, t.readNextToken());
  EXPECT_EQ(Token::DASHMATCH, t.readNextToken());
  EXPECT_EQ(Token::WHITESPACE, t.readNextToken());
  EXPECT_EQ(Token::OTHER, t.readNextToken());
  EXPECT_EQ(Token::WHITESPACE, t.readNextToken());
  EXPECT_EQ(Token::EOS, t.readNextToken());
}

/**
 * Test strings quoted with double quotes, single quotes, strings
 * containing newlines, and strings containing unicode characters.
 */
TEST(CssTokenizerTest, String) {
  istringstream in("\"string\" 'string' 'string\\\nstring' '\\12EF'"),
    inBad1("'string\n'"),
    inBad2("'string"),
    newlines("'\\\n \\\r\n \\\r'");

  CssTokenizer t(&in), tBad1(&inBad1), tBad2(&inBad2),
    tNewlines(&newlines);

  EXPECT_EQ(Token::STRING, t.readNextToken());
  EXPECT_EQ(Token::WHITESPACE, t.readNextToken());
  EXPECT_EQ(Token::STRING, t.readNextToken());
  EXPECT_EQ(Token::WHITESPACE, t.readNextToken());
  EXPECT_EQ(Token::STRING, t.readNextToken());
  EXPECT_EQ(Token::WHITESPACE, t.readNextToken());
  EXPECT_EQ(Token::STRING, t.readNextToken());

  EXPECT_THROW(tBad1.readNextToken(), ParseException*);
  EXPECT_THROW(tBad2.readNextToken(), ParseException*);

  ASSERT_EQ(Token::STRING, tNewlines.readNextToken());
  EXPECT_STREQ("'\\\n \\\r\n \\\r'", tNewlines.getToken()->str.c_str());
}

TEST(CssTokenizerTest, URL) {
  istringstream in("url(../img/img.png) url('http://example.com/image.jpg')");

  CssTokenizer t(&in);
  EXPECT_EQ(Token::URL, t.readNextToken());
  EXPECT_EQ(Token::WHITESPACE, t.readNextToken());
  EXPECT_EQ(Token::URL, t.readNextToken());
}

TEST(CssTokenizerTest, UnicodeRange) {
  istringstream in("u+123 u+123DEF-123");
  CssTokenizer t(&in);
  EXPECT_EQ(Token::UNICODE_RANGE, t.readNextToken());
  EXPECT_EQ(Token::WHITESPACE, t.readNextToken());
  EXPECT_EQ(Token::UNICODE_RANGE, t.readNextToken());
}

TEST(CssTokenizerTest, NonAscii) {
  istringstream in("a\xEE€");
  CssTokenizer t(&in);
  EXPECT_EQ(Token::IDENTIFIER, t.readNextToken());
  EXPECT_STREQ("a\xEE€", t.getToken()->str.c_str());
}

TEST(CssTokenizerTest, Minus) {
  istringstream in("-10 -50% -5em -identifier -moz-border-radius( -");
  CssTokenizer t(&in);
  EXPECT_EQ(Token::NUMBER, t.readNextToken());
  EXPECT_EQ(Token::WHITESPACE, t.readNextToken());
  EXPECT_EQ(Token::PERCENTAGE, t.readNextToken());
  EXPECT_EQ(Token::WHITESPACE, t.readNextToken());
  EXPECT_EQ(Token::DIMENSION, t.readNextToken());
  EXPECT_EQ(Token::WHITESPACE, t.readNextToken());
  EXPECT_EQ(Token::IDENTIFIER, t.readNextToken());
  EXPECT_EQ(Token::WHITESPACE, t.readNextToken());
  EXPECT_EQ(Token::FUNCTION, t.readNextToken());
}
TEST(CssTokenizerTest, Other) {
  istringstream in("@ - ~ | / + =");
  CssTokenizer t(&in);
  EXPECT_EQ(Token::OTHER, t.readNextToken());
  EXPECT_STREQ("@", t.getToken()->str.c_str());
  EXPECT_EQ(Token::WHITESPACE, t.readNextToken());
  EXPECT_EQ(Token::OTHER, t.readNextToken());
  EXPECT_STREQ("-", t.getToken()->str.c_str());
  EXPECT_EQ(Token::WHITESPACE, t.readNextToken());
  EXPECT_EQ(Token::OTHER, t.readNextToken());
  EXPECT_STREQ("~", t.getToken()->str.c_str());
  EXPECT_EQ(Token::WHITESPACE, t.readNextToken());
  EXPECT_EQ(Token::OTHER, t.readNextToken());
  EXPECT_STREQ("|", t.getToken()->str.c_str());
  EXPECT_EQ(Token::WHITESPACE, t.readNextToken());
  EXPECT_EQ(Token::OTHER, t.readNextToken());
  EXPECT_STREQ("/", t.getToken()->str.c_str());
  EXPECT_EQ(Token::WHITESPACE, t.readNextToken());
  EXPECT_EQ(Token::OTHER, t.readNextToken());
  EXPECT_STREQ("+", t.getToken()->str.c_str());
  EXPECT_EQ(Token::WHITESPACE, t.readNextToken());
  EXPECT_EQ(Token::OTHER, t.readNextToken());
  EXPECT_STREQ("=", t.getToken()->str.c_str());
}
<|endoftext|>