<commit_before>#include <leveldb/db.h>
#include <leveldb/slice.h>
#include <leveldb/env.h>
#include <leveldb/write_batch.h>

#include <unistd.h>
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <pthread.h>
#include <errno.h>
#include <time.h>
#include <netinet/tcp.h>
#include <list>

using namespace std;

static const int RESULT_GOOD = 1273252631;
static const int RESULT_BAD = 9999;
static const int RESULT_NOTFOUND = 133133;

leveldb::DB* db;
leveldb::WriteOptions write_options;

void error(const char *msg)
{
  perror(msg);
  exit(1);
}

struct connection_info
{
  int fd;
};

int read_fully(int fd, char* buffer, int len)
{
  int offset = 0;
  while(offset < len)
  {
    int r = read(fd, buffer + offset, len - offset);
    if (r <= 0) return r;
    offset += r;
  }

  return offset;
}

int write_fully(int fd, const char* buffer, int len)
{
  int offset = 0;
  while(offset < len)
  {
    int r = write(fd, buffer + offset, len - offset);
    if (r < 0) cout << "errno:" << errno << " " << strerror(errno) << endl;
    if (r <= 0) return r;
    offset += r;
  }

  return offset;
}

/*
 * The data in the slice will need to be freed
 */
int read_slice(int fd, leveldb::Slice &s)
{
  int sz;
  if(read_fully(fd, (char*)&sz, sizeof(sz)) <= 0) return -1;

  sz = ntohl(sz);

  char* data= NULL;

  if (sz > 0)
  {
    data = new char[sz];

    if(read_fully(fd, data, sz) <= 0)
    {
      return -1;
    }
  }

  s = leveldb::Slice(data,sz);

  //delete data;
  return 0;
}

int write_slice(int fd, leveldb::Slice &s)
{
  int sz = htonl(s.size());

  if (write_fully(fd, (char*)&sz, sizeof(sz)) < 0) return -1;
  if (write_fully(fd, s.data(), s.size()) < 0) return -1;
  return 0;
}

leveldb::Slice cloneSlice(leveldb::Slice a)
{
  char* b = new char[a.size()];
  memcpy(b, a.data(), a.size());

  return leveldb::Slice(b, a.size());
}

void* handle_connection(void* arg)
{
  connection_info* info=(connection_info*)arg;
  int fd = info->fd;

  //FILE* f = fdopen(fd, "w+");

  // [action][options]
  // actions
  //  1 - get (size = bytes of data) (data = key)
  //        [size][keydata]
  //  2 - put (size = number of keyvalues)
  //        [key_size][keydata][value_size][valuedata]
  //  3 - putall
  //        [items]
  //          [key_size][keydata][value_size][valuedata] (item times)
  //  4 - getprefix
  //        [size][keydata]
  // Returns for puts: int status code, 0 = no problems
  // Return for gets: int status code, 0 = no problems, [size][valuedata]
  // Returns for getprefix: int status code
  //   [items]
  //     [key_size][keydata][value_size][valuedata] (item times)

  bool problems=false;

  while(!problems)
  {
    char action[2];

    if (read_fully(fd, action, 2) <= 0) { problems=true; break;}

    if (action[0] == 1)
    {
      leveldb::Slice key;
      if (read_slice(fd, key) < 0) { problems=true; break;}
      string value;
      leveldb::Status db_stat = db->Get(leveldb::ReadOptions(),key, &value);

      delete []key.data();

      int status=RESULT_GOOD;

      if (db_stat.IsNotFound())
      {
        status=RESULT_NOTFOUND;
      }

      int net_status=htonl(status);
      write_fully(fd, (char*)&net_status, sizeof(net_status));

      if (status==RESULT_GOOD)
      {
        leveldb::Slice s = leveldb::Slice(value);
        if (write_slice(fd, s) < 0) { problems=true; break;}
      }

      fsync(fd);

    }
    else if (action[0] == 2)
    {
      leveldb::Slice key;
      leveldb::Slice value;

      if (read_slice(fd, key) < 0) { problems=true; break;}
      if (read_slice(fd, value) < 0) { problems=true; break;}

      leveldb::Status db_stat = db->Put(write_options,key, value);

      delete[] key.data();
      delete[] value.data();

      int status=RESULT_BAD;

      if (db_stat.ok())
      {
        status=RESULT_GOOD;
      }
      else
      {
        cout << db_stat.ToString() << endl;
        if (db_stat.IsCorruption() || db_stat.IsIOError()) exit(10);
      }
      status=htonl(status);
      write_fully(fd, (char*)&status, sizeof(status));
      fsync(fd);

    }
    else if (action[0] == 3)
    {
      int items;
      if(read_fully(fd, (char*)&items, sizeof(items)) <= 0) { problems=true; break;}
      items = ntohl(items);

      leveldb::WriteBatch write_batch;

      list<leveldb::Slice> slices;

      for(int i = 0; i<items; i++)
      {

        leveldb::Slice key;
        leveldb::Slice value;

        if (read_slice(fd, key) < 0) { problems=true; break;}
        if (read_slice(fd, value) < 0) { problems=true; break;}

        write_batch.Put(key, value);
        slices.push_back(key);
        slices.push_back(value);
      }

      if (problems) break;
      leveldb::Status db_stat = db->Write(write_options, &write_batch);

      int status=RESULT_BAD;
      if (db_stat.ok())
      {
        status=RESULT_GOOD;
      }
      else
      {
        cout << db_stat.ToString() << endl;
        if (db_stat.IsCorruption() || db_stat.IsIOError()) exit(10);
      }

      for(list<leveldb::Slice>::iterator I = slices.begin(); I!=slices.end(); I++)
      {
        delete[] I->data();
      }

      status=htonl(status);
      write_fully(fd, (char*)&status, sizeof(status));
      fsync(fd);

    }
    else if (action[0] == 4)
    {
      leveldb::Slice prefix;

      if (read_slice(fd, prefix) < 0) { problems=true; break;}

      list<leveldb::Slice> slices;
      slices.clear();

      leveldb::Iterator* I = db->NewIterator(leveldb::ReadOptions());

      int items=0;
      for(I->Seek(prefix); I->Valid() && I->key().starts_with(prefix) ;I->Next())
      {

        slices.push_back(cloneSlice(I->key()));
        slices.push_back(cloneSlice(I->value()));
        items++;
      }

      int status=RESULT_GOOD;
      status=htonl(status);
      write_fully(fd, (char*)&status, sizeof(status));

      items=htonl(items);
      write_fully(fd, (char*)&items, sizeof(items));

      for(list<leveldb::Slice>::iterator it = slices.begin(); it!=slices.end(); it++)
      {
        leveldb::Slice s=*it;
        if (write_slice(fd, s) < 0) { problems=true; break;}
        delete[] s.data();
      }

      delete[] prefix.data();
      delete I;

    }
    else
    {
      problems=true;
    }

  }
  //cout << "Closing socket with problems" << endl;
  close(fd);

}

int main(int argc, char* argv[])
{
  if (argc != 2)
  {
    cout << "Params: ./levelnet path_level_db" << endl;
    return -1;
  }

  cout << "LevelDB version " << leveldb::kMajorVersion << "." << leveldb::kMinorVersion << endl;

  leveldb::Options options;
  options.create_if_missing = true;
  leveldb::Status status = leveldb::DB::Open(options, argv[1], &db);

  //write_options.sync = true;

  if (!status.ok()) cerr << status.ToString() << endl;

  int sockfd = socket(AF_INET, SOCK_STREAM, 0);
  struct sockaddr_in serv_addr;
  int yes=1;

  setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int));
  setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &yes, sizeof(int));

  bzero((char *) &serv_addr, sizeof(serv_addr));
  serv_addr.sin_family = AF_INET;
  serv_addr.sin_addr.s_addr = INADDR_ANY;
  serv_addr.sin_port = htons(8844);
  if (bind(sockfd, (struct sockaddr *) &serv_addr,
    sizeof(serv_addr)) < 0)
    error("ERROR on binding");

  listen(sockfd,16);

  while(true)
  {
    socklen_t clilen;
    struct sockaddr_in cli_addr;
    clilen = sizeof(cli_addr);

    int newsockfd = accept(sockfd,
      (struct sockaddr *) &cli_addr,
      &clilen);

    pthread_t pt;
    connection_info info;
    info.fd = newsockfd;
    pthread_create(&pt, NULL, handle_connection, &info);

  }

}
<commit_msg>Set read timeout<commit_after>#include <leveldb/db.h>
#include <leveldb/slice.h>
#include <leveldb/env.h>
#include <leveldb/write_batch.h>

#include <unistd.h>
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <pthread.h>
#include <errno.h>
#include <time.h>
#include <netinet/tcp.h>
#include <list>

using namespace std;

static const int RESULT_GOOD = 1273252631;
static const int RESULT_BAD = 9999;
static const int RESULT_NOTFOUND = 133133;

leveldb::DB* db;
leveldb::WriteOptions write_options;

void error(const char *msg)
{
  perror(msg);
  exit(1);
}

struct connection_info
{
  int fd;
};

int read_fully(int fd, char* buffer, int len)
{
  int offset = 0;
  while(offset < len)
  {
    int r = read(fd, buffer + offset, len - offset);
    if (r <= 0) return r;
    offset += r;
  }

  return offset;
}

int write_fully(int fd, const char* buffer, int len)
{
  int offset = 0;
  while(offset < len)
  {
    int r = write(fd, buffer + offset, len - offset);
    if (r < 0) cout << "errno:" << errno << " " << strerror(errno) << endl;
    if (r <= 0) return r;
    offset += r;
  }

  return offset;
}

/*
 * The data in the slice will need to be freed
 */
int read_slice(int fd, leveldb::Slice &s)
{
  int sz;
  if(read_fully(fd, (char*)&sz, sizeof(sz)) <= 0) return -1;

  sz = ntohl(sz);

  char* data= NULL;

  if (sz > 0)
  {
    data = new char[sz];

    if(read_fully(fd, data, sz) <= 0)
    {
      return -1;
    }
  }

  s = leveldb::Slice(data,sz);

  //delete data;
  return 0;
}

int write_slice(int fd, leveldb::Slice &s)
{
  int sz = htonl(s.size());

  if (write_fully(fd, (char*)&sz, sizeof(sz)) < 0) return -1;
  if (write_fully(fd, s.data(), s.size()) < 0) return -1;
  return 0;
}

leveldb::Slice cloneSlice(leveldb::Slice a)
{
  char* b = new char[a.size()];
  memcpy(b, a.data(), a.size());

  return leveldb::Slice(b, a.size());
}

void* handle_connection(void* arg)
{
  connection_info* info=(connection_info*)arg;
  int fd = info->fd;

  //FILE* f = fdopen(fd, "w+");

  // [action][options]
  // actions
  //  1 - get (size = bytes of data) (data = key)
  //        [size][keydata]
  //  2 - put (size = number of keyvalues)
  //        [key_size][keydata][value_size][valuedata]
  //  3 - putall
  //        [items]
  //          [key_size][keydata][value_size][valuedata] (item times)
  //  4 - getprefix
  //        [size][keydata]
  // Returns for puts: int status code, 0 = no problems
  // Return for gets: int status code, 0 = no problems, [size][valuedata]
  // Returns for getprefix: int status code
  //   [items]
  //     [key_size][keydata][value_size][valuedata] (item times)

  bool problems=false;

  while(!problems)
  {
    char action[2];

    if (read_fully(fd, action, 2) <= 0) { problems=true; break;}

    if (action[0] == 1)
    {
      leveldb::Slice key;
      if (read_slice(fd, key) < 0) { problems=true; break;}
      string value;
      leveldb::Status db_stat = db->Get(leveldb::ReadOptions(),key, &value);

      delete []key.data();

      int status=RESULT_GOOD;

      if (db_stat.IsNotFound())
      {
        status=RESULT_NOTFOUND;
      }

      int net_status=htonl(status);
      write_fully(fd, (char*)&net_status, sizeof(net_status));

      if (status==RESULT_GOOD)
      {
        leveldb::Slice s = leveldb::Slice(value);
        if (write_slice(fd, s) < 0) { problems=true; break;}
      }

      fsync(fd);

    }
    else if (action[0] == 2)
    {
      leveldb::Slice key;
      leveldb::Slice value;

      if (read_slice(fd, key) < 0) { problems=true; break;}
      if (read_slice(fd, value) < 0) { problems=true; break;}

      leveldb::Status db_stat = db->Put(write_options,key, value);

      delete[] key.data();
      delete[] value.data();

      int status=RESULT_BAD;

      if (db_stat.ok())
      {
        status=RESULT_GOOD;
      }
      else
      {
        cout << db_stat.ToString() << endl;
        if (db_stat.IsCorruption() || db_stat.IsIOError()) exit(10);
      }
      status=htonl(status);
      write_fully(fd, (char*)&status, sizeof(status));
      fsync(fd);

    }
    else if (action[0] == 3)
    {
      int items;
      if(read_fully(fd, (char*)&items, sizeof(items)) <= 0) { problems=true; break;}
      items = ntohl(items);

      leveldb::WriteBatch write_batch;

      list<leveldb::Slice> slices;

      for(int i = 0; i<items; i++)
      {

        leveldb::Slice key;
        leveldb::Slice value;

        if (read_slice(fd, key) < 0) { problems=true; break;}
        if (read_slice(fd, value) < 0) { problems=true; break;}

        write_batch.Put(key, value);
        slices.push_back(key);
        slices.push_back(value);
      }

      if (problems) break;
      leveldb::Status db_stat = db->Write(write_options, &write_batch);

      int status=RESULT_BAD;
      if (db_stat.ok())
      {
        status=RESULT_GOOD;
      }
      else
      {
        cout << db_stat.ToString() << endl;
        if (db_stat.IsCorruption() || db_stat.IsIOError()) exit(10);
      }

      for(list<leveldb::Slice>::iterator I = slices.begin(); I!=slices.end(); I++)
      {
        delete[] I->data();
      }

      status=htonl(status);
      write_fully(fd, (char*)&status, sizeof(status));
      fsync(fd);

    }
    else if (action[0] == 4)
    {
      leveldb::Slice prefix;

      if (read_slice(fd, prefix) < 0) { problems=true; break;}

      list<leveldb::Slice> slices;
      slices.clear();

      leveldb::Iterator* I = db->NewIterator(leveldb::ReadOptions());

      int items=0;
      for(I->Seek(prefix); I->Valid() && I->key().starts_with(prefix) ;I->Next())
      {

        slices.push_back(cloneSlice(I->key()));
        slices.push_back(cloneSlice(I->value()));
        items++;
      }

      int status=RESULT_GOOD;
      status=htonl(status);
      write_fully(fd, (char*)&status, sizeof(status));

      items=htonl(items);
      write_fully(fd, (char*)&items, sizeof(items));

      for(list<leveldb::Slice>::iterator it = slices.begin(); it!=slices.end(); it++)
      {
        leveldb::Slice s=*it;
        if (write_slice(fd, s) < 0) { problems=true; break;}
        delete[] s.data();
      }

      delete[] prefix.data();
      delete I;

    }
    else
    {
      problems=true;
    }

  }
  //cout << "Closing socket with problems" << endl;
  close(fd);

}

int main(int argc, char* argv[])
{
  if (argc != 2)
  {
    cout << "Params: ./levelnet path_level_db" << endl;
    return -1;
  }

  cout << "LevelDB version " << leveldb::kMajorVersion << "." << leveldb::kMinorVersion << endl;

  leveldb::Options options;
  options.create_if_missing = true;
  leveldb::Status status = leveldb::DB::Open(options, argv[1], &db);

  //write_options.sync = true;

  if (!status.ok()) cerr << status.ToString() << endl;

  int sockfd = socket(AF_INET, SOCK_STREAM, 0);
  struct sockaddr_in serv_addr;
  int yes=1;

  setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int));
  setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &yes, sizeof(int));

  bzero((char *) &serv_addr, sizeof(serv_addr));
  serv_addr.sin_family = AF_INET;
  serv_addr.sin_addr.s_addr = INADDR_ANY;
  serv_addr.sin_port = htons(8844);
  if (bind(sockfd, (struct sockaddr *) &serv_addr,
    sizeof(serv_addr)) < 0)
    error("ERROR on binding");

  listen(sockfd,16);

  while(true)
  {
    socklen_t clilen;
    struct sockaddr_in cli_addr;
    clilen = sizeof(cli_addr);

    int newsockfd = accept(sockfd,
      (struct sockaddr *) &cli_addr,
      &clilen);

    struct timeval timeout;
      timeout.tv_sec = 3600;
      timeout.tv_usec = 0;

    setsockopt(newsockfd, SOL_SOCKET, SO_RCVTIMEO, (void *)&timeout,
                    sizeof(timeout));

    pthread_t pt;
    connection_info info;
    info.fd = newsockfd;
    pthread_create(&pt, NULL, handle_connection, &info);

  }

}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2015 Cryptonomex, Inc., and contributors.
 *
 * The MIT License
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
#include <graphene/app/application.hpp>

#include <graphene/delayed_node/delayed_node_plugin.hpp>
#include <graphene/account_history/account_history_plugin.hpp>
#include <graphene/market_history/market_history_plugin.hpp>

#include <fc/exception/exception.hpp>
#include <fc/thread/thread.hpp>
#include <fc/interprocess/signals.hpp>
#include <fc/log/console_appender.hpp>
#include <fc/log/file_appender.hpp>
#include <fc/log/logger.hpp>
#include <fc/log/logger_config.hpp>

#include <boost/filesystem.hpp>

#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/ini_parser.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/split.hpp>

#include <iostream>
#include <fstream>

#ifdef WIN32
# include <signal.h>
#else
# include <csignal>
#endif

using namespace graphene;
namespace bpo = boost::program_options;

void write_default_logging_config_to_stream(std::ostream& out);
fc::optional<fc::logging_config> load_logging_config_from_ini_file(const fc::path& config_ini_filename);

int main(int argc, char** argv) {
   try {
      app::application node;
      bpo::options_description app_options("Graphene Delayed Node");
      bpo::options_description cfg_options("Graphene Delayed Node");
      app_options.add_options()
              ("help,h", "Print this help message and exit.")
              ("data-dir,d", bpo::value<boost::filesystem::path>()->default_value("delayed_node_data_dir"), "Directory containing databases, configuration file, etc.")
              ("plugins", bpo::value<std::string>()->default_value("delayed_node account_history market_history"),
               "Space-separated list of plugins to activate");
              ;

      bpo::variables_map options;

      auto delayed_plug = node.register_plugin<delayed_node::delayed_node_plugin>();
      auto history_plug = node.register_plugin<account_history::account_history_plugin>();
      auto market_history_plug = node.register_plugin<market_history::market_history_plugin>();

      try
      {
         bpo::options_description cli, cfg;
         node.set_program_options(cli, cfg);
         app_options.add(cli);
         cfg_options.add(cfg);
         bpo::store(bpo::parse_command_line(argc, argv, app_options), options);
      }
      catch (const boost::program_options::error& e)
      {
         std::cerr << "Error parsing command line: " << e.what() << "\n";
         return 1;
      }

      if( options.count("help") )
      {
         std::cout << app_options << "\n";
         return 0;
      }

      fc::path data_dir;
      if( options.count("data-dir") )
      {
         data_dir = options["data-dir"].as<boost::filesystem::path>();
         if( data_dir.is_relative() )
            data_dir = fc::current_path() / data_dir;
      }

      fc::path config_ini_path = data_dir / "config.ini";
      // Create config file if not already present
      if( !fc::exists(config_ini_path) )
      {
         ilog("Writing new config file at ${path}", ("path", config_ini_path));
         if( !fc::exists(data_dir) )
            fc::create_directories(data_dir);

         std::ofstream out_cfg(config_ini_path.preferred_string());
         for( const boost::shared_ptr<bpo::option_description> od : cfg_options.options() )
         {
            if( !od->description().empty() )
               out_cfg << "# " << od->description() << "\n";
            boost::any store;
            if( !od->semantic()->apply_default(store) )
               out_cfg << "# " << od->long_name() << " = \n";
            else {
               auto example = od->format_parameter();
               if( example.empty() )
                  // This is a boolean switch
                  out_cfg << od->long_name() << " = " << "false\n";
               else {
                  // The string is formatted "arg (=<interesting part>)"
                  example.erase(0, 6);
                  example.erase(example.length()-1);
                  out_cfg << od->long_name() << " = " << example << "\n";
               }
            }
            out_cfg << "\n";
         }
         write_default_logging_config_to_stream(out_cfg);
         out_cfg.close();
         // read the default logging config we just wrote out to the file and start using it
         fc::optional<fc::logging_config> logging_config = load_logging_config_from_ini_file(config_ini_path);
         if (logging_config)
            fc::configure_logging(*logging_config);
      }

      // Parse configuration file
      try {
         bpo::store(bpo::parse_config_file<char>(config_ini_path.preferred_string().c_str(), cfg_options, true), options);
         // try to get logging options from the config file.
         try
         {
            fc::optional<fc::logging_config> logging_config = load_logging_config_from_ini_file(config_ini_path);
            if (logging_config)
               fc::configure_logging(*logging_config);
         }
         catch (const fc::exception&)
         {
            wlog("Error parsing logging config from config file ${config}, using default config", ("config", config_ini_path.preferred_string()));
         }

         bpo::notify(options);
      } catch( const boost::program_options::error& e ) {
         elog("Error parsing configuration file: ${e}", ("e", e.what()));
         return 1;
      }

      std::set<std::string> plugins;
      boost::split(plugins, options.at("plugins").as<std::string>(), [](char c){return c == ' ';});

      if(plugins.count("account_history") && plugins.count("elasticsearch")) {
         std::cerr << "Plugin conflict: Cannot load both account_history plugin and elasticsearch plugin\n";
         return 1;
      }

      std::for_each(plugins.begin(), plugins.end(), [&](const std::string& plug) mutable {
          if (!plug.empty()) {
             node.enable_plugin(plug);
          }
      });
      node.initialize(data_dir, options);
      node.initialize_plugins( options );

      node.startup();
      node.startup_plugins();

      fc::promise<int>::ptr exit_promise = new fc::promise<int>("UNIX Signal Handler");
      fc::set_signal_handler([&exit_promise](int signal) {
          exit_promise->set_value(signal);
      }, SIGINT);

      ilog("Started delayed node on a chain with ${h} blocks.", ("h", node.chain_database()->head_block_num()));
      ilog("Chain ID is ${id}", ("id", node.chain_database()->get_chain_id()) );

      int signal = exit_promise->wait();
      ilog("Exiting from signal ${n}", ("n", signal));
      node.shutdown_plugins();
      return 0;
   } catch( const fc::exception& e ) {
      elog("Exiting with error:\n${e}", ("e", e.to_detail_string()));
      return 1;
   }
}

// logging config is too complicated to be parsed by boost::program_options,
// so we do it by hand
//
// Currently, you can only specify the filenames and logging levels, which
// are all most users would want to change.  At a later time, options can
// be added to control rotation intervals, compression, and other seldom-
// used features
void write_default_logging_config_to_stream(std::ostream& out)
{
   out << "# declare an appender named \"stderr\" that writes messages to the console\n"
          "[log.console_appender.stderr]\n"
          "stream=std_error\n\n"
          "# declare an appender named \"p2p\" that writes messages to p2p.log\n"
          "[log.file_appender.p2p]\n"
          "filename=logs/p2p/p2p.log\n"
          "# filename can be absolute or relative to this config file\n\n"
          "# route any messages logged to the default logger to the \"stderr\" logger we\n"
          "# declared above, if they are info level are higher\n"
          "[logger.default]\n"
          "level=info\n"
          "appenders=stderr\n\n"
          "# route messages sent to the \"p2p\" logger to the p2p appender declared above\n"
          "[logger.p2p]\n"
          "level=info\n"
          "appenders=p2p\n\n";
}

fc::optional<fc::logging_config> load_logging_config_from_ini_file(const fc::path& config_ini_filename)
{
   try
   {
      fc::logging_config logging_config;
      bool found_logging_config = false;

      boost::property_tree::ptree config_ini_tree;
      boost::property_tree::ini_parser::read_ini(config_ini_filename.preferred_string().c_str(), config_ini_tree);
      for (const auto& section : config_ini_tree)
      {
         const std::string& section_name = section.first;
         const boost::property_tree::ptree& section_tree = section.second;

         const std::string console_appender_section_prefix = "log.console_appender.";
         const std::string file_appender_section_prefix = "log.file_appender.";
         const std::string logger_section_prefix = "logger.";

         if (boost::starts_with(section_name, console_appender_section_prefix))
         {
            std::string console_appender_name = section_name.substr(console_appender_section_prefix.length());
            std::string stream_name = section_tree.get<std::string>("stream");

            // construct a default console appender config here
            // stdout/stderr will be taken from ini file, everything else hard-coded here
            fc::console_appender::config console_appender_config;
            console_appender_config.level_colors.emplace_back(
                    fc::console_appender::level_color(fc::log_level::debug,
                                                      fc::console_appender::color::green));
            console_appender_config.level_colors.emplace_back(
                    fc::console_appender::level_color(fc::log_level::warn,
                                                      fc::console_appender::color::brown));
            console_appender_config.level_colors.emplace_back(
                    fc::console_appender::level_color(fc::log_level::error,
                                                      fc::console_appender::color::cyan));
            console_appender_config.stream = fc::variant(stream_name, 1).as<fc::console_appender::stream::type>(1);
            logging_config.appenders.push_back(fc::appender_config(console_appender_name, "console", fc::variant(console_appender_config, GRAPHENE_MAX_NESTED_OBJECTS)));
            found_logging_config = true;
         }
         else if (boost::starts_with(section_name, file_appender_section_prefix))
         {
            std::string file_appender_name = section_name.substr(file_appender_section_prefix.length());
            fc::path file_name = section_tree.get<std::string>("filename");
            if (file_name.is_relative())
               file_name = fc::absolute(config_ini_filename).parent_path() / file_name;

            // construct a default file appender config here
            // filename will be taken from ini file, everything else hard-coded here
            fc::file_appender::config file_appender_config;
            file_appender_config.filename = file_name;
            file_appender_config.flush = true;
            file_appender_config.rotate = true;
            file_appender_config.rotation_interval = fc::hours(1);
            file_appender_config.rotation_limit = fc::days(1);
            logging_config.appenders.push_back(fc::appender_config(file_appender_name, "file", fc::variant(file_appender_config, GRAPHENE_MAX_NESTED_OBJECTS)));
            found_logging_config = true;
         }
         else if (boost::starts_with(section_name, logger_section_prefix))
         {
            std::string logger_name = section_name.substr(logger_section_prefix.length());
            std::string level_string = section_tree.get<std::string>("level");
            std::string appenders_string = section_tree.get<std::string>("appenders");
            fc::logger_config logger_config(logger_name);
            logger_config.level = fc::variant(level_string, 1).as<fc::log_level>(1);
            boost::split(logger_config.appenders, appenders_string,
                         boost::is_any_of(" ,"),
                         boost::token_compress_on);
            logging_config.loggers.push_back(logger_config);
            found_logging_config = true;
         }
      }
      if (found_logging_config)
         return logging_config;
      else
         return fc::optional<fc::logging_config>();
   }
   FC_RETHROW_EXCEPTIONS(warn, "")
}
<commit_msg>remove useless check<commit_after>/*
 * Copyright (c) 2015 Cryptonomex, Inc., and contributors.
 *
 * The MIT License
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
#include <graphene/app/application.hpp>

#include <graphene/delayed_node/delayed_node_plugin.hpp>
#include <graphene/account_history/account_history_plugin.hpp>
#include <graphene/market_history/market_history_plugin.hpp>

#include <fc/exception/exception.hpp>
#include <fc/thread/thread.hpp>
#include <fc/interprocess/signals.hpp>
#include <fc/log/console_appender.hpp>
#include <fc/log/file_appender.hpp>
#include <fc/log/logger.hpp>
#include <fc/log/logger_config.hpp>

#include <boost/filesystem.hpp>

#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/ini_parser.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/split.hpp>

#include <iostream>
#include <fstream>

#ifdef WIN32
# include <signal.h>
#else
# include <csignal>
#endif

using namespace graphene;
namespace bpo = boost::program_options;

void write_default_logging_config_to_stream(std::ostream& out);
fc::optional<fc::logging_config> load_logging_config_from_ini_file(const fc::path& config_ini_filename);

int main(int argc, char** argv) {
   try {
      app::application node;
      bpo::options_description app_options("Graphene Delayed Node");
      bpo::options_description cfg_options("Graphene Delayed Node");
      app_options.add_options()
              ("help,h", "Print this help message and exit.")
              ("data-dir,d", bpo::value<boost::filesystem::path>()->default_value("delayed_node_data_dir"), "Directory containing databases, configuration file, etc.")
              ("plugins", bpo::value<std::string>()->default_value("delayed_node account_history market_history"),
               "Space-separated list of plugins to activate");
              ;

      bpo::variables_map options;

      auto delayed_plug = node.register_plugin<delayed_node::delayed_node_plugin>();
      auto history_plug = node.register_plugin<account_history::account_history_plugin>();
      auto market_history_plug = node.register_plugin<market_history::market_history_plugin>();

      try
      {
         bpo::options_description cli, cfg;
         node.set_program_options(cli, cfg);
         app_options.add(cli);
         cfg_options.add(cfg);
         bpo::store(bpo::parse_command_line(argc, argv, app_options), options);
      }
      catch (const boost::program_options::error& e)
      {
         std::cerr << "Error parsing command line: " << e.what() << "\n";
         return 1;
      }

      if( options.count("help") )
      {
         std::cout << app_options << "\n";
         return 0;
      }

      fc::path data_dir;
      if( options.count("data-dir") )
      {
         data_dir = options["data-dir"].as<boost::filesystem::path>();
         if( data_dir.is_relative() )
            data_dir = fc::current_path() / data_dir;
      }

      fc::path config_ini_path = data_dir / "config.ini";
      // Create config file if not already present
      if( !fc::exists(config_ini_path) )
      {
         ilog("Writing new config file at ${path}", ("path", config_ini_path));
         if( !fc::exists(data_dir) )
            fc::create_directories(data_dir);

         std::ofstream out_cfg(config_ini_path.preferred_string());
         for( const boost::shared_ptr<bpo::option_description> od : cfg_options.options() )
         {
            if( !od->description().empty() )
               out_cfg << "# " << od->description() << "\n";
            boost::any store;
            if( !od->semantic()->apply_default(store) )
               out_cfg << "# " << od->long_name() << " = \n";
            else {
               auto example = od->format_parameter();
               if( example.empty() )
                  // This is a boolean switch
                  out_cfg << od->long_name() << " = " << "false\n";
               else {
                  // The string is formatted "arg (=<interesting part>)"
                  example.erase(0, 6);
                  example.erase(example.length()-1);
                  out_cfg << od->long_name() << " = " << example << "\n";
               }
            }
            out_cfg << "\n";
         }
         write_default_logging_config_to_stream(out_cfg);
         out_cfg.close();
         // read the default logging config we just wrote out to the file and start using it
         fc::optional<fc::logging_config> logging_config = load_logging_config_from_ini_file(config_ini_path);
         if (logging_config)
            fc::configure_logging(*logging_config);
      }

      // Parse configuration file
      try {
         bpo::store(bpo::parse_config_file<char>(config_ini_path.preferred_string().c_str(), cfg_options, true), options);
         // try to get logging options from the config file.
         try
         {
            fc::optional<fc::logging_config> logging_config = load_logging_config_from_ini_file(config_ini_path);
            if (logging_config)
               fc::configure_logging(*logging_config);
         }
         catch (const fc::exception&)
         {
            wlog("Error parsing logging config from config file ${config}, using default config", ("config", config_ini_path.preferred_string()));
         }

         bpo::notify(options);
      } catch( const boost::program_options::error& e ) {
         elog("Error parsing configuration file: ${e}", ("e", e.what()));
         return 1;
      }

      std::set<std::string> plugins;
      boost::split(plugins, options.at("plugins").as<std::string>(), [](char c){return c == ' ';});

      std::for_each(plugins.begin(), plugins.end(), [&](const std::string& plug) mutable {
          if (!plug.empty()) {
             node.enable_plugin(plug);
          }
      });
      node.initialize(data_dir, options);
      node.initialize_plugins( options );

      node.startup();
      node.startup_plugins();

      fc::promise<int>::ptr exit_promise = new fc::promise<int>("UNIX Signal Handler");
      fc::set_signal_handler([&exit_promise](int signal) {
          exit_promise->set_value(signal);
      }, SIGINT);

      ilog("Started delayed node on a chain with ${h} blocks.", ("h", node.chain_database()->head_block_num()));
      ilog("Chain ID is ${id}", ("id", node.chain_database()->get_chain_id()) );

      int signal = exit_promise->wait();
      ilog("Exiting from signal ${n}", ("n", signal));
      node.shutdown_plugins();
      return 0;
   } catch( const fc::exception& e ) {
      elog("Exiting with error:\n${e}", ("e", e.to_detail_string()));
      return 1;
   }
}

// logging config is too complicated to be parsed by boost::program_options,
// so we do it by hand
//
// Currently, you can only specify the filenames and logging levels, which
// are all most users would want to change.  At a later time, options can
// be added to control rotation intervals, compression, and other seldom-
// used features
void write_default_logging_config_to_stream(std::ostream& out)
{
   out << "# declare an appender named \"stderr\" that writes messages to the console\n"
          "[log.console_appender.stderr]\n"
          "stream=std_error\n\n"
          "# declare an appender named \"p2p\" that writes messages to p2p.log\n"
          "[log.file_appender.p2p]\n"
          "filename=logs/p2p/p2p.log\n"
          "# filename can be absolute or relative to this config file\n\n"
          "# route any messages logged to the default logger to the \"stderr\" logger we\n"
          "# declared above, if they are info level are higher\n"
          "[logger.default]\n"
          "level=info\n"
          "appenders=stderr\n\n"
          "# route messages sent to the \"p2p\" logger to the p2p appender declared above\n"
          "[logger.p2p]\n"
          "level=info\n"
          "appenders=p2p\n\n";
}

fc::optional<fc::logging_config> load_logging_config_from_ini_file(const fc::path& config_ini_filename)
{
   try
   {
      fc::logging_config logging_config;
      bool found_logging_config = false;

      boost::property_tree::ptree config_ini_tree;
      boost::property_tree::ini_parser::read_ini(config_ini_filename.preferred_string().c_str(), config_ini_tree);
      for (const auto& section : config_ini_tree)
      {
         const std::string& section_name = section.first;
         const boost::property_tree::ptree& section_tree = section.second;

         const std::string console_appender_section_prefix = "log.console_appender.";
         const std::string file_appender_section_prefix = "log.file_appender.";
         const std::string logger_section_prefix = "logger.";

         if (boost::starts_with(section_name, console_appender_section_prefix))
         {
            std::string console_appender_name = section_name.substr(console_appender_section_prefix.length());
            std::string stream_name = section_tree.get<std::string>("stream");

            // construct a default console appender config here
            // stdout/stderr will be taken from ini file, everything else hard-coded here
            fc::console_appender::config console_appender_config;
            console_appender_config.level_colors.emplace_back(
                    fc::console_appender::level_color(fc::log_level::debug,
                                                      fc::console_appender::color::green));
            console_appender_config.level_colors.emplace_back(
                    fc::console_appender::level_color(fc::log_level::warn,
                                                      fc::console_appender::color::brown));
            console_appender_config.level_colors.emplace_back(
                    fc::console_appender::level_color(fc::log_level::error,
                                                      fc::console_appender::color::cyan));
            console_appender_config.stream = fc::variant(stream_name, 1).as<fc::console_appender::stream::type>(1);
            logging_config.appenders.push_back(fc::appender_config(console_appender_name, "console", fc::variant(console_appender_config, GRAPHENE_MAX_NESTED_OBJECTS)));
            found_logging_config = true;
         }
         else if (boost::starts_with(section_name, file_appender_section_prefix))
         {
            std::string file_appender_name = section_name.substr(file_appender_section_prefix.length());
            fc::path file_name = section_tree.get<std::string>("filename");
            if (file_name.is_relative())
               file_name = fc::absolute(config_ini_filename).parent_path() / file_name;

            // construct a default file appender config here
            // filename will be taken from ini file, everything else hard-coded here
            fc::file_appender::config file_appender_config;
            file_appender_config.filename = file_name;
            file_appender_config.flush = true;
            file_appender_config.rotate = true;
            file_appender_config.rotation_interval = fc::hours(1);
            file_appender_config.rotation_limit = fc::days(1);
            logging_config.appenders.push_back(fc::appender_config(file_appender_name, "file", fc::variant(file_appender_config, GRAPHENE_MAX_NESTED_OBJECTS)));
            found_logging_config = true;
         }
         else if (boost::starts_with(section_name, logger_section_prefix))
         {
            std::string logger_name = section_name.substr(logger_section_prefix.length());
            std::string level_string = section_tree.get<std::string>("level");
            std::string appenders_string = section_tree.get<std::string>("appenders");
            fc::logger_config logger_config(logger_name);
            logger_config.level = fc::variant(level_string, 1).as<fc::log_level>(1);
            boost::split(logger_config.appenders, appenders_string,
                         boost::is_any_of(" ,"),
                         boost::token_compress_on);
            logging_config.loggers.push_back(logger_config);
            found_logging_config = true;
         }
      }
      if (found_logging_config)
         return logging_config;
      else
         return fc::optional<fc::logging_config>();
   }
   FC_RETHROW_EXCEPTIONS(warn, "")
}
<|endoftext|>


<commit_before>#include <stdint.h>
#include <assert.h>

/////////////////////////////////////////////////////////////////////////////////////////
class BitArray
{
public:
    uint32_t *v;
    const uint32_t size;

    BitArray(uint32_t size =1)
        : size(size)
    {
        v = new uint32_t [size];
    }

    ~BitArray()
    {
        delete v;
    }

    uint32_t * operator[](int n)
    {
        return getDWord(n);
    }

public:

    uint32_t * getDWord(uint32_t n)
    {
        assert(n < size);
        return v+n;
    }

public:
    /////////////////////////////////////
    // Bit Operations
    //number |= 1 << n; //set bit
    //number &= ~(1 << n); //clear a bit
    //number ^= 1 << n; //toggle a bit
    //bit = (number >> n) & 1; //check a bit
    //number ^= (-value ^ number) & (1 << n); //setting the nth bit to either 1 or 0

    void setBit(uint32_t n)
    {
        uint32_t *pByte = getDWord(n/32);
        *pByte |= 1 << n%32;
    }

    void clearBit(uint32_t n)
    {
        uint32_t *pByte = getDWord(n/32);
        *pByte &= ~(1 << n%32);;
    }

    void toggleBit(uint32_t n)
    {
        uint32_t *pByte = getDWord(n/32);
        *pByte ^= 1 << n%32;
    }

    uint32_t checkBit(uint32_t n)
    {
        uint32_t *pByte = getDWord(n/32);
        return (*pByte >> n) & 1;
    }

    void setBit(uint32_t n, uint32_t val)
    {
        uint32_t *pByte = getDWord(n/32);
        *pByte ^= (-val ^ *pByte) & (1 << n%32);
    }

    /////////////////////////////////////////////////
    // DWord operations

    void andDWord(uint32_t n, uint32_t val)
    {
        uint32_t *pByte = getDWord(n);
        *pByte &= val;
    }

    void orDWord(uint32_t n, uint32_t val)
    {
        uint32_t *pByte = getDWord(n);
        *pByte |= val;
    }

    uint32_t numberOfSetBits(uint32_t n)
    {
        uint32_t byte = * getDWord(n);
        byte = byte - ((byte >> 1) & 0x55555555);
        byte = (byte & 0x33333333) + ((byte >> 2) & 0x33333333);
        return (((byte + (byte >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24;
    }

    /////////////////////////////////////////////////
    // Array operations

    void and(const BitArray &rhs)
    {
        assert(size == rhs.size);

        for(uint32_t i=0; i<size; ++i)
            andDWord(i, rhs.v[i]);
    }

    void or(const BitArray &rhs)
    {
        assert(size == rhs.size);

        for(uint32_t i=0; i<size; ++i)
            orDWord(i, rhs.v[i]);
    }

    uint32_t numberOfSetBits()
    {
        uint32_t ret = 0;
        for(uint32_t i=0; i<size; ++i)
            ret += numberOfSetBits(i);
        return ret;
    }
};

template <int L>
class BitArrayT : public BitArray
{
public:
    BitArrayT()
        : BitArray(L)
    {}
};

//int main()
//{
//    BitArray ba(2); ba.v[0] = ba.v[1] = 0;
//
//    ba.setBit(2); assert(ba.v[0] == 4);
//    ba.setBit(32); assert(ba.v[1] == 1);
//    ba.clearBit(2); assert(ba.v[0] == 0);
//    ba.clearBit(32); assert(ba.v[1] == 0);
//    ba.toggleBit(3); assert(ba.v[0] == 8); assert(ba.checkBit(3) == 1);
//    ba.toggleBit(63); /*assert(ba.v[0] == 2147483648L);*/ assert(ba.checkBit(63) == 1);
//    ba.setBit(3,0); assert(ba.v[0] == 0); assert(ba.checkBit(3) == 0);
//    ba.setBit(63,0); assert(ba.v[0] == 0); assert(ba.checkBit(63) == 0);
//
//    ba.v[0] = 0x1AB; ba.andDWord(0, 0x100); assert(ba.v[0] == 0x100);
//    ba.v[1] = 0x88; ba.andDWord(1, 8); assert(ba.v[1] == 8);
//    ba.v[0] = 0x100; ba.orDWord(0, 0x1AB); assert(ba.v[0] == 0x1AB);
//    ba.v[1] = 0x80; ba.orDWord(1, 8); assert(ba.v[1] == 0x88);
//
//    ba.v[0] = 0x514841; assert(ba.numberOfSetBits(0) == 7);
//    ba.v[1] = 0x854052AF; assert(ba.numberOfSetBits(1) == 13);
//    assert(ba.numberOfSetBits() == 20);
//
//    BitArrayT<2> bm; bm.v[0] = 0xFF00AA; bm.v[1] = 0x00BF00;
//    *ba[0] = 0x00FF00; *ba[1] = 0xAA00CC;
//    ba.and(bm);
//    assert(*ba[0] == 0 && *ba[1] == 0);
//
//    *ba[0] = 0x00CD00; *ba[1] = 0x880011;
//    ba.or(bm);
//    assert(*ba[0] == 0xFFCDAA && *ba[1] == 0x88BF11);
//}
<commit_msg>fix bitarray to uint32_t<commit_after>#include <stdint.h>
#include <assert.h>

/////////////////////////////////////////////////////////////////////////////////////////
class BitArray
{
public:
    uint32_t *v;
    const uint32_t size;

    BitArray(uint32_t size =1)
        : size(size)
    {
        v = new uint32_t [size];
    }

    ~BitArray()
    {
        delete v;
    }

    uint32_t * operator[](uint32_t n)
    {
        return getDWord(n);
    }

public:

    uint32_t * getDWord(uint32_t n)
    {
        assert(n < size);
        return v+n;
    }

public:
    /////////////////////////////////////
    // Bit Operations
    //number |= 1 << n; //set bit
    //number &= ~(1 << n); //clear a bit
    //number ^= 1 << n; //toggle a bit
    //bit = (number >> n) & 1; //check a bit
    //number ^= (-value ^ number) & (1 << n); //setting the nth bit to either 1 or 0

    void setBit(uint32_t n)
    {
        uint32_t *pByte = getDWord(n/32);
        *pByte |= 1 << n%32;
    }

    void clearBit(uint32_t n)
    {
        uint32_t *pByte = getDWord(n/32);
        *pByte &= ~(1 << n%32);;
    }

    void toggleBit(uint32_t n)
    {
        uint32_t *pByte = getDWord(n/32);
        *pByte ^= 1 << n%32;
    }

    uint32_t checkBit(uint32_t n)
    {
        uint32_t *pByte = getDWord(n/32);
        return (*pByte >> n) & 1;
    }

    void setBit(uint32_t n, uint32_t val)
    {
        uint32_t *pByte = getDWord(n/32);
        *pByte ^= (-val ^ *pByte) & (1 << n%32);
    }

    /////////////////////////////////////////////////
    // DWord operations

    void andDWord(uint32_t n, uint32_t val)
    {
        uint32_t *pByte = getDWord(n);
        *pByte &= val;
    }

    void orDWord(uint32_t n, uint32_t val)
    {
        uint32_t *pByte = getDWord(n);
        *pByte |= val;
    }

    uint32_t numberOfSetBits(uint32_t n)
    {
        uint32_t byte = * getDWord(n);
        byte = byte - ((byte >> 1) & 0x55555555);
        byte = (byte & 0x33333333) + ((byte >> 2) & 0x33333333);
        return (((byte + (byte >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24;
    }

    /////////////////////////////////////////////////
    // Array operations

    void and(const BitArray &rhs)
    {
        assert(size == rhs.size);

        for(uint32_t i=0; i<size; ++i)
            andDWord(i, rhs.v[i]);
    }

    void or(const BitArray &rhs)
    {
        assert(size == rhs.size);

        for(uint32_t i=0; i<size; ++i)
            orDWord(i, rhs.v[i]);
    }

    uint32_t numberOfSetBits()
    {
        uint32_t ret = 0;
        for(uint32_t i=0; i<size; ++i)
            ret += numberOfSetBits(i);
        return ret;
    }
};

template <uint32_t L>
class BitArrayT : public BitArray
{
public:
    BitArrayT()
        : BitArray(L)
    {}
};

//int main()
//{
//    BitArray ba(2); ba.v[0] = ba.v[1] = 0;
//
//    ba.setBit(2); assert(ba.v[0] == 4);
//    ba.setBit(32); assert(ba.v[1] == 1);
//    ba.clearBit(2); assert(ba.v[0] == 0);
//    ba.clearBit(32); assert(ba.v[1] == 0);
//    ba.toggleBit(3); assert(ba.v[0] == 8); assert(ba.checkBit(3) == 1);
//    ba.toggleBit(63); /*assert(ba.v[0] == 2147483648L);*/ assert(ba.checkBit(63) == 1);
//    ba.setBit(3,0); assert(ba.v[0] == 0); assert(ba.checkBit(3) == 0);
//    ba.setBit(63,0); assert(ba.v[0] == 0); assert(ba.checkBit(63) == 0);
//
//    ba.v[0] = 0x1AB; ba.andDWord(0, 0x100); assert(ba.v[0] == 0x100);
//    ba.v[1] = 0x88; ba.andDWord(1, 8); assert(ba.v[1] == 8);
//    ba.v[0] = 0x100; ba.orDWord(0, 0x1AB); assert(ba.v[0] == 0x1AB);
//    ba.v[1] = 0x80; ba.orDWord(1, 8); assert(ba.v[1] == 0x88);
//
//    ba.v[0] = 0x514841; assert(ba.numberOfSetBits(0) == 7);
//    ba.v[1] = 0x854052AF; assert(ba.numberOfSetBits(1) == 13);
//    assert(ba.numberOfSetBits() == 20);
//
//    BitArrayT<2> bm; bm.v[0] = 0xFF00AA; bm.v[1] = 0x00BF00;
//    *ba[0] = 0x00FF00; *ba[1] = 0xAA00CC;
//    ba.and(bm);
//    assert(*ba[0] == 0 && *ba[1] == 0);
//
//    *ba[0] = 0x00CD00; *ba[1] = 0x880011;
//    ba.or(bm);
//    assert(*ba[0] == 0xFFCDAA && *ba[1] == 0x88BF11);
//}
<|endoftext|>


<commit_before>/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * Copyright (C) 2015 ScyllaDB
 *
 * Modified by ScyllaDB
 */

/*
 * This file is part of Scylla.
 *
 * Scylla is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Scylla is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#pragma once

#include <cstddef>
#include <iosfwd>
#include "core/sstring.hh"
#include "seastarx.hh"

namespace cql3 {

class operator_type {
public:
    static const operator_type EQ;
    static const operator_type LT;
    static const operator_type LTE;
    static const operator_type GTE;
    static const operator_type GT;
    static const operator_type IN;
    static const operator_type CONTAINS;
    static const operator_type CONTAINS_KEY;
    static const operator_type NEQ;
    static const operator_type IS_NOT;
private:
    int32_t _b;
    const operator_type& _reverse;
    sstring _text;
private:
    operator_type(int32_t b, const operator_type& reverse, sstring text)
        : _b(b)
        , _reverse(reverse)
        , _text(std::move(text))
    {}
public:
    const operator_type& reverse() const { return _reverse; }
    bool is_slice() const {
        return (*this == LT) || (*this == LTE) || (*this == GT) || (*this == GTE);
    }
    sstring to_string() const { return _text; }
    bool operator==(const operator_type& other) const { return this == &other; }
    bool operator!=(const operator_type& other) const { return this != &other; }
#if 0

    /**
     * Write the serialized version of this Operator to the specified output.
     *
     * @param output the output to write to
     * @throws IOException if an I/O problem occurs while writing to the specified output
     */
    public void writeTo(DataOutput output) throws IOException
    {
        output.writeInt(b);
    }

    /**
     * Deserializes a Operator instance from the specified input.
     *
     * @param input the input to read from
     * @return the Operator instance deserialized
     * @throws IOException if a problem occurs while deserializing the Type instance.
     */
    public static Operator readFrom(DataInput input) throws IOException
    {
          int b = input.readInt();
          for (Operator operator : values())
              if (operator.b == b)
                  return operator;

          throw new IOException(String.format("Cannot resolve Relation.Type from binary representation: %s", b));
    }
#endif
};

static inline
std::ostream& operator<<(std::ostream& out, const operator_type& op) {
    return out << op.to_string();
}

}
<commit_msg>cql3: Make operator_type class non-copyable<commit_after>/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * Copyright (C) 2015 ScyllaDB
 *
 * Modified by ScyllaDB
 */

/*
 * This file is part of Scylla.
 *
 * Scylla is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Scylla is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#pragma once

#include <cstddef>
#include <iosfwd>
#include "core/sstring.hh"
#include "seastarx.hh"

namespace cql3 {

class operator_type {
public:
    static const operator_type EQ;
    static const operator_type LT;
    static const operator_type LTE;
    static const operator_type GTE;
    static const operator_type GT;
    static const operator_type IN;
    static const operator_type CONTAINS;
    static const operator_type CONTAINS_KEY;
    static const operator_type NEQ;
    static const operator_type IS_NOT;
private:
    int32_t _b;
    const operator_type& _reverse;
    sstring _text;
private:
    operator_type(int32_t b, const operator_type& reverse, sstring text)
        : _b(b)
        , _reverse(reverse)
        , _text(std::move(text))
    {}
public:
    operator_type(const operator_type&) = delete;
    operator_type& operator=(const operator_type&) = delete;
    const operator_type& reverse() const { return _reverse; }
    bool is_slice() const {
        return (*this == LT) || (*this == LTE) || (*this == GT) || (*this == GTE);
    }
    sstring to_string() const { return _text; }
    bool operator==(const operator_type& other) const { return this == &other; }
    bool operator!=(const operator_type& other) const { return this != &other; }
#if 0

    /**
     * Write the serialized version of this Operator to the specified output.
     *
     * @param output the output to write to
     * @throws IOException if an I/O problem occurs while writing to the specified output
     */
    public void writeTo(DataOutput output) throws IOException
    {
        output.writeInt(b);
    }

    /**
     * Deserializes a Operator instance from the specified input.
     *
     * @param input the input to read from
     * @return the Operator instance deserialized
     * @throws IOException if a problem occurs while deserializing the Type instance.
     */
    public static Operator readFrom(DataInput input) throws IOException
    {
          int b = input.readInt();
          for (Operator operator : values())
              if (operator.b == b)
                  return operator;

          throw new IOException(String.format("Cannot resolve Relation.Type from binary representation: %s", b));
    }
#endif
};

static inline
std::ostream& operator<<(std::ostream& out, const operator_type& op) {
    return out << op.to_string();
}

}
<|endoftext|>


<commit_before>/*
 *  Copyright 2012 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "webrtc/api/jsepsessiondescription.h"

#include <memory>

#include "webrtc/base/arraysize.h"
#include "webrtc/base/stringencode.h"
#include "webrtc/pc/mediasession.h"
#include "webrtc/pc/webrtcsdp.h"

using cricket::SessionDescription;

namespace webrtc {

static const char* kSupportedTypes[] = {
    JsepSessionDescription::kOffer,
    JsepSessionDescription::kPrAnswer,
    JsepSessionDescription::kAnswer
};

static bool IsTypeSupported(const std::string& type) {
  bool type_supported = false;
  for (size_t i = 0; i < arraysize(kSupportedTypes); ++i) {
    if (kSupportedTypes[i] == type) {
      type_supported = true;
      break;
    }
  }
  return type_supported;
}

// RFC 5245
// It is RECOMMENDED that default candidates be chosen based on the
// likelihood of those candidates to work with the peer that is being
// contacted.  It is RECOMMENDED that relayed > reflexive > host.
static const int kPreferenceUnknown = 0;
static const int kPreferenceHost = 1;
static const int kPreferenceReflexive = 2;
static const int kPreferenceRelayed = 3;

static const char kDummyAddress[] = "0.0.0.0";
static const int kDummyPort = 9;

static int GetCandidatePreferenceFromType(const std::string& type) {
  int preference = kPreferenceUnknown;
  if (type == cricket::LOCAL_PORT_TYPE) {
    preference = kPreferenceHost;
  } else if (type == cricket::STUN_PORT_TYPE) {
    preference = kPreferenceReflexive;
  } else if (type == cricket::RELAY_PORT_TYPE) {
    preference = kPreferenceRelayed;
  } else {
    RTC_NOTREACHED();
  }
  return preference;
}

// Update the connection address for the MediaContentDescription based on the
// candidates.
static void UpdateConnectionAddress(
    const JsepCandidateCollection& candidate_collection,
    cricket::ContentDescription* content_description) {
  int port = kDummyPort;
  std::string ip = kDummyAddress;
  int current_preference = kPreferenceUnknown;
  int current_family = AF_UNSPEC;
  for (size_t i = 0; i < candidate_collection.count(); ++i) {
    const IceCandidateInterface* jsep_candidate = candidate_collection.at(i);
    if (jsep_candidate->candidate().component() !=
        cricket::ICE_CANDIDATE_COMPONENT_RTP) {
      continue;
    }
    // Default destination should be UDP only.
    if (jsep_candidate->candidate().protocol() != cricket::UDP_PROTOCOL_NAME) {
      continue;
    }
    const int preference =
        GetCandidatePreferenceFromType(jsep_candidate->candidate().type());
    const int family = jsep_candidate->candidate().address().ipaddr().family();
    // See if this candidate is more preferable then the current one if it's the
    // same family. Or if the current family is IPv4 already so we could safely
    // ignore all IPv6 ones. WebRTC bug 4269.
    // http://code.google.com/p/webrtc/issues/detail?id=4269
    if ((preference <= current_preference && current_family == family) ||
        (current_family == AF_INET && family == AF_INET6)) {
      continue;
    }
    current_preference = preference;
    current_family = family;
    port = jsep_candidate->candidate().address().port();
    ip = jsep_candidate->candidate().address().ipaddr().ToString();
  }
  rtc::SocketAddress connection_addr;
  connection_addr.SetIP(ip);
  connection_addr.SetPort(port);
  static_cast<cricket::MediaContentDescription*>(content_description)
      ->set_connection_address(connection_addr);
}

const char SessionDescriptionInterface::kOffer[] = "offer";
const char SessionDescriptionInterface::kPrAnswer[] = "pranswer";
const char SessionDescriptionInterface::kAnswer[] = "answer";

const int JsepSessionDescription::kDefaultVideoCodecId = 100;
const char JsepSessionDescription::kDefaultVideoCodecName[] = "VP8";

SessionDescriptionInterface* CreateSessionDescription(const std::string& type,
                                                      const std::string& sdp,
                                                      SdpParseError* error) {
  if (!IsTypeSupported(type)) {
    return NULL;
  }

  JsepSessionDescription* jsep_desc = new JsepSessionDescription(type);
  if (!jsep_desc->Initialize(sdp, error)) {
    delete jsep_desc;
    return NULL;
  }
  return jsep_desc;
}

JsepSessionDescription::JsepSessionDescription(const std::string& type)
    : type_(type) {
}

JsepSessionDescription::~JsepSessionDescription() {}

bool JsepSessionDescription::Initialize(
    cricket::SessionDescription* description,
    const std::string& session_id,
    const std::string& session_version) {
  if (!description)
    return false;

  session_id_ = session_id;
  session_version_ = session_version;
  description_.reset(description);
  candidate_collection_.resize(number_of_mediasections());
  return true;
}

bool JsepSessionDescription::Initialize(const std::string& sdp,
                                        SdpParseError* error) {
  return SdpDeserialize(sdp, this, error);
}

bool JsepSessionDescription::AddCandidate(
    const IceCandidateInterface* candidate) {
  if (!candidate || candidate->sdp_mline_index() < 0)
    return false;
  size_t mediasection_index = 0;
  if (!GetMediasectionIndex(candidate, &mediasection_index)) {
    return false;
  }
  if (mediasection_index >= number_of_mediasections())
    return false;
  const std::string& content_name =
      description_->contents()[mediasection_index].name;
  const cricket::TransportInfo* transport_info =
      description_->GetTransportInfoByName(content_name);
  if (!transport_info) {
    return false;
  }

  cricket::Candidate updated_candidate = candidate->candidate();
  if (updated_candidate.username().empty()) {
    updated_candidate.set_username(transport_info->description.ice_ufrag);
  }
  if (updated_candidate.password().empty()) {
    updated_candidate.set_password(transport_info->description.ice_pwd);
  }

  std::unique_ptr<JsepIceCandidate> updated_candidate_wrapper(
      new JsepIceCandidate(candidate->sdp_mid(),
                           static_cast<int>(mediasection_index),
                           updated_candidate));
  if (!candidate_collection_[mediasection_index].HasCandidate(
          updated_candidate_wrapper.get())) {
    candidate_collection_[mediasection_index].add(
        updated_candidate_wrapper.release());
    UpdateConnectionAddress(
        candidate_collection_[mediasection_index],
        description_->contents()[mediasection_index].description);
  }

  return true;
}

size_t JsepSessionDescription::RemoveCandidates(
    const std::vector<cricket::Candidate>& candidates) {
  size_t num_removed = 0;
  for (auto& candidate : candidates) {
    int mediasection_index = GetMediasectionIndex(candidate);
    if (mediasection_index < 0) {
      // Not found.
      continue;
    }
    num_removed += candidate_collection_[mediasection_index].remove(candidate);
    UpdateConnectionAddress(
        candidate_collection_[mediasection_index],
        description_->contents()[mediasection_index].description);
  }
  return num_removed;
}

size_t JsepSessionDescription::number_of_mediasections() const {
  if (!description_)
    return 0;
  return description_->contents().size();
}

const IceCandidateCollection* JsepSessionDescription::candidates(
    size_t mediasection_index) const {
  if (mediasection_index >= candidate_collection_.size())
    return NULL;
  return &candidate_collection_[mediasection_index];
}

bool JsepSessionDescription::ToString(std::string* out) const {
  if (!description_ || !out) {
    return false;
  }
  *out = SdpSerialize(*this, false);
  return !out->empty();
}

bool JsepSessionDescription::GetMediasectionIndex(
    const IceCandidateInterface* candidate,
    size_t* index) {
  if (!candidate || !index) {
    return false;
  }
  *index = static_cast<size_t>(candidate->sdp_mline_index());
  if (description_ && !candidate->sdp_mid().empty()) {
    bool found = false;
    // Try to match the sdp_mid with content name.
    for (size_t i = 0; i < description_->contents().size(); ++i) {
      if (candidate->sdp_mid() == description_->contents().at(i).name) {
        *index = i;
        found = true;
        break;
      }
    }
    if (!found) {
      // If the sdp_mid is presented but we can't find a match, we consider
      // this as an error.
      return false;
    }
  }
  return true;
}

int JsepSessionDescription::GetMediasectionIndex(
    const cricket::Candidate& candidate) {
  // Find the description with a matching transport name of the candidate.
  const std::string& transport_name = candidate.transport_name();
  for (size_t i = 0; i < description_->contents().size(); ++i) {
    if (transport_name == description_->contents().at(i).name) {
      return static_cast<int>(i);
    }
  }
  return -1;
}

}  // namespace webrtc
<commit_msg>Fix the fuzz test.<commit_after>/*
 *  Copyright 2012 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "webrtc/api/jsepsessiondescription.h"

#include <memory>

#include "webrtc/base/arraysize.h"
#include "webrtc/base/stringencode.h"
#include "webrtc/pc/mediasession.h"
#include "webrtc/pc/webrtcsdp.h"

using cricket::SessionDescription;

namespace webrtc {

static const char* kSupportedTypes[] = {
    JsepSessionDescription::kOffer,
    JsepSessionDescription::kPrAnswer,
    JsepSessionDescription::kAnswer
};

static bool IsTypeSupported(const std::string& type) {
  bool type_supported = false;
  for (size_t i = 0; i < arraysize(kSupportedTypes); ++i) {
    if (kSupportedTypes[i] == type) {
      type_supported = true;
      break;
    }
  }
  return type_supported;
}

// RFC 5245
// It is RECOMMENDED that default candidates be chosen based on the
// likelihood of those candidates to work with the peer that is being
// contacted.  It is RECOMMENDED that relayed > reflexive > host.
static const int kPreferenceUnknown = 0;
static const int kPreferenceHost = 1;
static const int kPreferenceReflexive = 2;
static const int kPreferenceRelayed = 3;

static const char kDummyAddress[] = "0.0.0.0";
static const int kDummyPort = 9;

static int GetCandidatePreferenceFromType(const std::string& type) {
  int preference = kPreferenceUnknown;
  if (type == cricket::LOCAL_PORT_TYPE) {
    preference = kPreferenceHost;
  } else if (type == cricket::STUN_PORT_TYPE) {
    preference = kPreferenceReflexive;
  } else if (type == cricket::RELAY_PORT_TYPE) {
    preference = kPreferenceRelayed;
  } else {
    preference = kPreferenceUnknown;
  }
  return preference;
}

// Update the connection address for the MediaContentDescription based on the
// candidates.
static void UpdateConnectionAddress(
    const JsepCandidateCollection& candidate_collection,
    cricket::ContentDescription* content_description) {
  int port = kDummyPort;
  std::string ip = kDummyAddress;
  int current_preference = kPreferenceUnknown;
  int current_family = AF_UNSPEC;
  for (size_t i = 0; i < candidate_collection.count(); ++i) {
    const IceCandidateInterface* jsep_candidate = candidate_collection.at(i);
    if (jsep_candidate->candidate().component() !=
        cricket::ICE_CANDIDATE_COMPONENT_RTP) {
      continue;
    }
    // Default destination should be UDP only.
    if (jsep_candidate->candidate().protocol() != cricket::UDP_PROTOCOL_NAME) {
      continue;
    }
    const int preference =
        GetCandidatePreferenceFromType(jsep_candidate->candidate().type());
    const int family = jsep_candidate->candidate().address().ipaddr().family();
    // See if this candidate is more preferable then the current one if it's the
    // same family. Or if the current family is IPv4 already so we could safely
    // ignore all IPv6 ones. WebRTC bug 4269.
    // http://code.google.com/p/webrtc/issues/detail?id=4269
    if ((preference <= current_preference && current_family == family) ||
        (current_family == AF_INET && family == AF_INET6)) {
      continue;
    }
    current_preference = preference;
    current_family = family;
    port = jsep_candidate->candidate().address().port();
    ip = jsep_candidate->candidate().address().ipaddr().ToString();
  }
  rtc::SocketAddress connection_addr;
  connection_addr.SetIP(ip);
  connection_addr.SetPort(port);
  static_cast<cricket::MediaContentDescription*>(content_description)
      ->set_connection_address(connection_addr);
}

const char SessionDescriptionInterface::kOffer[] = "offer";
const char SessionDescriptionInterface::kPrAnswer[] = "pranswer";
const char SessionDescriptionInterface::kAnswer[] = "answer";

const int JsepSessionDescription::kDefaultVideoCodecId = 100;
const char JsepSessionDescription::kDefaultVideoCodecName[] = "VP8";

SessionDescriptionInterface* CreateSessionDescription(const std::string& type,
                                                      const std::string& sdp,
                                                      SdpParseError* error) {
  if (!IsTypeSupported(type)) {
    return NULL;
  }

  JsepSessionDescription* jsep_desc = new JsepSessionDescription(type);
  if (!jsep_desc->Initialize(sdp, error)) {
    delete jsep_desc;
    return NULL;
  }
  return jsep_desc;
}

JsepSessionDescription::JsepSessionDescription(const std::string& type)
    : type_(type) {
}

JsepSessionDescription::~JsepSessionDescription() {}

bool JsepSessionDescription::Initialize(
    cricket::SessionDescription* description,
    const std::string& session_id,
    const std::string& session_version) {
  if (!description)
    return false;

  session_id_ = session_id;
  session_version_ = session_version;
  description_.reset(description);
  candidate_collection_.resize(number_of_mediasections());
  return true;
}

bool JsepSessionDescription::Initialize(const std::string& sdp,
                                        SdpParseError* error) {
  return SdpDeserialize(sdp, this, error);
}

bool JsepSessionDescription::AddCandidate(
    const IceCandidateInterface* candidate) {
  if (!candidate || candidate->sdp_mline_index() < 0)
    return false;
  size_t mediasection_index = 0;
  if (!GetMediasectionIndex(candidate, &mediasection_index)) {
    return false;
  }
  if (mediasection_index >= number_of_mediasections())
    return false;
  const std::string& content_name =
      description_->contents()[mediasection_index].name;
  const cricket::TransportInfo* transport_info =
      description_->GetTransportInfoByName(content_name);
  if (!transport_info) {
    return false;
  }

  cricket::Candidate updated_candidate = candidate->candidate();
  if (updated_candidate.username().empty()) {
    updated_candidate.set_username(transport_info->description.ice_ufrag);
  }
  if (updated_candidate.password().empty()) {
    updated_candidate.set_password(transport_info->description.ice_pwd);
  }

  std::unique_ptr<JsepIceCandidate> updated_candidate_wrapper(
      new JsepIceCandidate(candidate->sdp_mid(),
                           static_cast<int>(mediasection_index),
                           updated_candidate));
  if (!candidate_collection_[mediasection_index].HasCandidate(
          updated_candidate_wrapper.get())) {
    candidate_collection_[mediasection_index].add(
        updated_candidate_wrapper.release());
    UpdateConnectionAddress(
        candidate_collection_[mediasection_index],
        description_->contents()[mediasection_index].description);
  }

  return true;
}

size_t JsepSessionDescription::RemoveCandidates(
    const std::vector<cricket::Candidate>& candidates) {
  size_t num_removed = 0;
  for (auto& candidate : candidates) {
    int mediasection_index = GetMediasectionIndex(candidate);
    if (mediasection_index < 0) {
      // Not found.
      continue;
    }
    num_removed += candidate_collection_[mediasection_index].remove(candidate);
    UpdateConnectionAddress(
        candidate_collection_[mediasection_index],
        description_->contents()[mediasection_index].description);
  }
  return num_removed;
}

size_t JsepSessionDescription::number_of_mediasections() const {
  if (!description_)
    return 0;
  return description_->contents().size();
}

const IceCandidateCollection* JsepSessionDescription::candidates(
    size_t mediasection_index) const {
  if (mediasection_index >= candidate_collection_.size())
    return NULL;
  return &candidate_collection_[mediasection_index];
}

bool JsepSessionDescription::ToString(std::string* out) const {
  if (!description_ || !out) {
    return false;
  }
  *out = SdpSerialize(*this, false);
  return !out->empty();
}

bool JsepSessionDescription::GetMediasectionIndex(
    const IceCandidateInterface* candidate,
    size_t* index) {
  if (!candidate || !index) {
    return false;
  }
  *index = static_cast<size_t>(candidate->sdp_mline_index());
  if (description_ && !candidate->sdp_mid().empty()) {
    bool found = false;
    // Try to match the sdp_mid with content name.
    for (size_t i = 0; i < description_->contents().size(); ++i) {
      if (candidate->sdp_mid() == description_->contents().at(i).name) {
        *index = i;
        found = true;
        break;
      }
    }
    if (!found) {
      // If the sdp_mid is presented but we can't find a match, we consider
      // this as an error.
      return false;
    }
  }
  return true;
}

int JsepSessionDescription::GetMediasectionIndex(
    const cricket::Candidate& candidate) {
  // Find the description with a matching transport name of the candidate.
  const std::string& transport_name = candidate.transport_name();
  for (size_t i = 0; i < description_->contents().size(); ++i) {
    if (transport_name == description_->contents().at(i).name) {
      return static_cast<int>(i);
    }
  }
  return -1;
}

}  // namespace webrtc
<|endoftext|>


<commit_before>// ECE556 - Copyright 2014 University of Wisconsin-Madison.  All Rights Reserved.

#include "ece556.h"

int main(int argc, char **argv)
{
    signal(SIGSEGV, handler);
 	if(argc!=3){
 		printf("Usage : ./ROUTE.exe <input_benchmark_name> <output_file_name> \n");
 		return 1;
 	}

 	int status;
	char *inputFileName = argv[1];
 	char *outputFileName = argv[2];

 	/// create a new routing instance
 	routingInst *rst = new routingInst;

 	/// read benchmark
    printf("about to enter read Benchmark\n");
    status = readBenchmark(inputFileName, rst);
    for(int i = 0; i < rst->numEdges; i++)
        cout << "edge weight of e" << i << " = " << rst->edgeCaps[i] << "\t";
    cout << endl;
 	if(status==0){
 		printf("ERROR: reading input file \n");
 		return 1;
 	}

 	/// run actual routing
 	status = solveRouting(rst);
 	if(status==0){
 		printf("ERROR: running routing \n");
 		release(rst);
 		return 1;
 	}

 	/// write the result
 	status = writeOutput(outputFileName, rst);
 	if(status==0){
 		printf("ERROR: writing the result \n");
 		release(rst);
 		return 1;
 	}

 	release(rst);
 	printf("\nDONE!\n\n");
 	return 0;
}
<commit_msg>got rid of print statements in main<commit_after>// ECE556 - Copyright 2014 University of Wisconsin-Madison.  All Rights Reserved.

#include "ece556.h"

int main(int argc, char **argv)
{
    signal(SIGSEGV, handler);
 	if(argc!=3){
 		printf("Usage : ./ROUTE.exe <input_benchmark_name> <output_file_name> \n");
 		return 1;
 	}

 	int status;
	char *inputFileName = argv[1];
 	char *outputFileName = argv[2];

 	/// create a new routing instance
 	routingInst *rst = new routingInst;

 	/// read benchmark
    status = readBenchmark(inputFileName, rst);
 	if(status==0){
 		printf("ERROR: reading input file \n");
 		return 1;
 	}

 	/// run actual routing
 	status = solveRouting(rst);
 	if(status==0){
 		printf("ERROR: running routing \n");
 		release(rst);
 		return 1;
 	}

 	/// write the result
 	status = writeOutput(outputFileName, rst);
 	if(status==0){
 		printf("ERROR: writing the result \n");
 		release(rst);
 		return 1;
 	}

 	release(rst);
 	printf("\nDONE!\n\n");
 	return 0;
}
<|endoftext|>


<commit_before><commit_msg>linux: abort unless we have the proper version of NSS<commit_after><|endoftext|>


<commit_before><commit_msg>Fixing scoped_ptr misusage in base/win_util.cc BUG=24266<commit_after><|endoftext|>


<commit_before>//@author A0097630B
#include "stdafx.h"
#include "exceptions/parse_error_exception.h"
#include "query_parser.h"

namespace You {
namespace NLP {

namespace spirit = boost::spirit;
namespace qi = spirit::qi;
namespace phoenix = boost::phoenix;

QUERY QueryParser::parse(const StringType& string) {
	QUERY result;

	if (parse(string, result)) {
		return result;
	} else {
		throw ParserException();
	}
}

bool QueryParser::parse(const StringType& string, QUERY& result) {
	return qi::parse(
		begin(string),
		end(string),
		QueryParser(),
		result);
}

QueryParser::QueryParser() : QueryParser::base_type(start) {
	start %= (
		(qi::lit(L'/') > explicitCommand) |
		addCommand
	) >> qi::eoi;
	BOOST_SPIRIT_DEBUG_NODE(start);

	explicitCommand %= (
		(qi::lit(L"add") >> space >> addCommand) |
		(qi::lit(L"show") >> space >> showCommand) |
		(qi::lit(L"edit") >> space >> editCommand) |
		(qi::lit(L"delete") >> space >> deleteCommand) |
		(qi::lit(L"undo") >> undoCommand)
	);
	BOOST_SPIRIT_DEBUG_NODE(explicitCommand);

	#pragma region Adding tasks
	addCommand %= (
		addCommandDescription
	);
	BOOST_SPIRIT_DEBUG_NODE(addCommand);

	addCommandDescription = (
		ParserCharTraits::char_ >> addCommandDescriptionTail
	)[qi::_val = phoenix::bind(&constructAddQuery, qi::_1, qi::_2)];
	BOOST_SPIRIT_DEBUG_NODE(addCommandDescription);

	addCommandDescriptionTail %= (
		addCommandPriority |
		addCommandDescription
	);
	BOOST_SPIRIT_DEBUG_NODE(addCommandDescriptionTail);

	addCommandPriority %= (
		(-space >> qi::lit('!') >> addCommandDeadlineOptional)
			[qi::_val = phoenix::bind(&constructAddQueryWithPriority, qi::_1)] |
		addCommandDeadlineOptional
	);
	BOOST_SPIRIT_DEBUG_NODE(addCommandPriority);

	addCommandDeadline = (
		space >> (qi::lit("by") | qi::lit("before")) >>
		utilityTime
	)[qi::_val = phoenix::bind(&constructAddQueryWithDeadline, qi::_1)];
	BOOST_SPIRIT_DEBUG_NODE(addCommandDeadline);

	addCommandDeadlineOptional = (
		addCommandDeadline || qi::eoi
	)[qi::_val = phoenix::bind(&constructAddQueryWithOptionalDeadline, qi::_1)];
	BOOST_SPIRIT_DEBUG_NODE(addCommandDeadlineOptional);
	#pragma endregion

	#pragma region Showing tasks
	showCommand = (
		-showCommandFiltering >>
		-(-space >> (qi::lit(L"sorted by") | qi::lit(L"order by")) >> space >>
		showCommandSorting)
	)[qi::_val = phoenix::bind(&constructShowQuery, qi::_1, qi::_2)];
	BOOST_SPIRIT_DEBUG_NODE(showCommand);

	showCommandFiltering %=
		showCommandFilteringColumn % (
			(-space >> qi::lit(L",") >> -space) |
			(space >> qi::lit(L"and") >> space));
	BOOST_SPIRIT_DEBUG_NODE(showCommandFiltering);

	showCommandFilteringColumn = (
		showCommandFields >>
		-space >> showCommandFilteringPredicate >> -space >>
		utilityValue
	)[qi::_val = phoenix::bind(&constructShowQueryFilteringColumn,
		qi::_1,
		qi::_2,
		qi::_3)];
	BOOST_SPIRIT_DEBUG_NODE(showCommandFiltering);

	showCommandFilteringPredicate.add
		(L"=", SHOW_QUERY::Predicate::EQ)
		(L"!=", SHOW_QUERY::Predicate::NOT_EQ)
		(L"<", SHOW_QUERY::Predicate::LESS_THAN)
		(L"<=", SHOW_QUERY::Predicate::LESS_THAN_EQ)
		(L">", SHOW_QUERY::Predicate::GREATER_THAN)
		(L">=", SHOW_QUERY::Predicate::GREATER_THAN_EQ);

	showCommandSorting %= (
		showCommandSortingColumn % (
			(-space >> qi::lit(L",") >> -space) |
			(space >> qi::lit(L"then") >> space)));
	BOOST_SPIRIT_DEBUG_NODE(showCommandSorting);

	showCommandSortingColumn = (
		showCommandFields >> -(space >> showCommandSortingOrders)
	)[qi::_val = phoenix::bind(&constructShowQuerySortColumn, qi::_1, qi::_2)];
	BOOST_SPIRIT_DEBUG_NODE(showCommandSortingColumn);

	showCommandSortingOrders.add
		(L"asc", SHOW_QUERY::Order::ASCENDING)
		(L"ascending", SHOW_QUERY::Order::ASCENDING)
		(L"desc", SHOW_QUERY::Order::DESCENDING)
		(L"descending", SHOW_QUERY::Order::DESCENDING);

	showCommandFields.add
		(L"description", TaskField::DESCRIPTION)
		(L"deadline", TaskField::DEADLINE)
		(L"priority", TaskField::PRIORITY)
		(L"done", TaskField::COMPLETE)
		(L"complete", TaskField::COMPLETE);
	#pragma endregion

	#pragma region Editing tasks
	editCommand = (
		qi::uint_ >> space >> qi::lit(L"set") >> space >> editCommandRule
	)[qi::_val = phoenix::bind(&constructEditQuery,
		qi::_1, qi::_2)];
	BOOST_SPIRIT_DEBUG_NODE(editCommand);

	editCommandRule %= (
		editCommandRuleNullary |
		editCommandRuleUnary |
		editCommandRulePriorities
	);
	BOOST_SPIRIT_DEBUG_NODE(editCommandRule);

	editCommandRuleNullary = (
		editCommandFieldsNullary
	)[qi::_val = phoenix::bind(&constructEditQueryNullary, qi::_1)];
	BOOST_SPIRIT_DEBUG_NODE(editCommandRuleNullary);

	editCommandRuleUnary = (
		editCommandFieldsUnary >>
		-space >> qi::lit('=') >> -space >>
		utilityValue)
	[qi::_val = phoenix::bind(&constructEditQueryUnary, qi::_1, qi::_2)];
	BOOST_SPIRIT_DEBUG_NODE(editCommandRuleUnary);

	editCommandRulePriorities = (
		qi::lit(L"priority") >>
		-space >> qi::lit('=') >> -space >>
		utilityTaskPriority
	)[qi::_val = phoenix::bind(&constructEditQueryPriority, qi::_1)];
	BOOST_SPIRIT_DEBUG_NODE(editCommandRulePriorities);

	editCommandFieldsUnary.add
		(L"description", TaskField::DESCRIPTION)
		(L"deadline", TaskField::DEADLINE);

	editCommandFieldsNullary.add
		(L"done", TaskField::COMPLETE)
		(L"complete", TaskField::COMPLETE);
	#pragma endregion

	#pragma region Deleting tasks
	deleteCommand = (
		qi::uint_
	)[qi::_val = phoenix::bind(&constructDeleteQuery, qi::_1)];
	BOOST_SPIRIT_DEBUG_NODE(deleteCommand);
	#pragma endregion

	#pragma region Undoing tasks
	undoCommand = (
		qi::eps
	)[qi::_val = phoenix::construct<UNDO_QUERY>()];
	BOOST_SPIRIT_DEBUG_NODE(undoCommand);
	#pragma endregion

	space = qi::omit[+ParserCharTraits::blank];

	utilityValue = (
		(qi::int_) |
		(qi::bool_) |
		utilityTaskPriority |
		utilityLexeme
	)[qi::_val = phoenix::bind(&constructValue, qi::_1)];

	utilityTaskPriority.add
		(L"normal", TaskPriority::NORMAL)
		(L"high", TaskPriority::HIGH);

	utilityTime = (
		qi::as_wstring[+ParserCharTraits::char_]
	)[qi::_val = phoenix::bind(&constructDateTime, qi::_1)];
	BOOST_SPIRIT_DEBUG_NODE(utilityTime);

	utilityLexeme %= qi::as_wstring[(
		qi::lit('\'') > *utilityLexemeContents > qi::lit('\'')
	)];
	BOOST_SPIRIT_DEBUG_NODE(utilityLexeme);

	utilityLexemeContents %= (
		qi::lit("\\'")[qi::_val = L'\''] |
		qi::lit("\\\\")[qi::_val = L'\\'] |
		(ParserCharTraits::char_ - qi::lit('\''))
	);
	BOOST_SPIRIT_DEBUG_NODE(utilityLexemeContents);

	qi::on_error<qi::fail>(start,
		phoenix::bind(&onFailure, qi::_1, qi::_2, qi::_3, qi::_4));
}

void QueryParser::onFailure(
	ParserIteratorType /*begin*/,
	ParserIteratorType end,
	ParserIteratorType errorPos,
	const spirit::info& message) {
	StringType lexeme(errorPos, end);
	throw ParseErrorException(message, lexeme);
}

}  // namespace NLP
}  // namespace You
<commit_msg>Time is the date time parser itself.<commit_after>//@author A0097630B
#include "stdafx.h"
#include "exceptions/parse_error_exception.h"
#include "query_parser.h"

namespace You {
namespace NLP {

namespace spirit = boost::spirit;
namespace qi = spirit::qi;
namespace phoenix = boost::phoenix;

QUERY QueryParser::parse(const StringType& string) {
	QUERY result;

	if (parse(string, result)) {
		return result;
	} else {
		throw ParserException();
	}
}

bool QueryParser::parse(const StringType& string, QUERY& result) {
	return qi::parse(
		begin(string),
		end(string),
		QueryParser(),
		result);
}

QueryParser::QueryParser() : QueryParser::base_type(start) {
	start %= (
		(qi::lit(L'/') > explicitCommand) |
		addCommand
	) >> qi::eoi;
	BOOST_SPIRIT_DEBUG_NODE(start);

	explicitCommand %= (
		(qi::lit(L"add") >> space >> addCommand) |
		(qi::lit(L"show") >> space >> showCommand) |
		(qi::lit(L"edit") >> space >> editCommand) |
		(qi::lit(L"delete") >> space >> deleteCommand) |
		(qi::lit(L"undo") >> undoCommand)
	);
	BOOST_SPIRIT_DEBUG_NODE(explicitCommand);

	#pragma region Adding tasks
	addCommand %= (
		addCommandDescription
	);
	BOOST_SPIRIT_DEBUG_NODE(addCommand);

	addCommandDescription = (
		ParserCharTraits::char_ >> addCommandDescriptionTail
	)[qi::_val = phoenix::bind(&constructAddQuery, qi::_1, qi::_2)];
	BOOST_SPIRIT_DEBUG_NODE(addCommandDescription);

	addCommandDescriptionTail %= (
		addCommandPriority |
		addCommandDescription
	);
	BOOST_SPIRIT_DEBUG_NODE(addCommandDescriptionTail);

	addCommandPriority %= (
		(-space >> qi::lit('!') >> addCommandDeadlineOptional)
			[qi::_val = phoenix::bind(&constructAddQueryWithPriority, qi::_1)] |
		addCommandDeadlineOptional
	);
	BOOST_SPIRIT_DEBUG_NODE(addCommandPriority);

	addCommandDeadline = (
		space >> (qi::lit("by") | qi::lit("before")) >>
		utilityTime
	)[qi::_val = phoenix::bind(&constructAddQueryWithDeadline, qi::_1)];
	BOOST_SPIRIT_DEBUG_NODE(addCommandDeadline);

	addCommandDeadlineOptional = (
		addCommandDeadline || qi::eoi
	)[qi::_val = phoenix::bind(&constructAddQueryWithOptionalDeadline, qi::_1)];
	BOOST_SPIRIT_DEBUG_NODE(addCommandDeadlineOptional);
	#pragma endregion

	#pragma region Showing tasks
	showCommand = (
		-showCommandFiltering >>
		-(-space >> (qi::lit(L"sorted by") | qi::lit(L"order by")) >> space >>
		showCommandSorting)
	)[qi::_val = phoenix::bind(&constructShowQuery, qi::_1, qi::_2)];
	BOOST_SPIRIT_DEBUG_NODE(showCommand);

	showCommandFiltering %=
		showCommandFilteringColumn % (
			(-space >> qi::lit(L",") >> -space) |
			(space >> qi::lit(L"and") >> space));
	BOOST_SPIRIT_DEBUG_NODE(showCommandFiltering);

	showCommandFilteringColumn = (
		showCommandFields >>
		-space >> showCommandFilteringPredicate >> -space >>
		utilityValue
	)[qi::_val = phoenix::bind(&constructShowQueryFilteringColumn,
		qi::_1,
		qi::_2,
		qi::_3)];
	BOOST_SPIRIT_DEBUG_NODE(showCommandFiltering);

	showCommandFilteringPredicate.add
		(L"=", SHOW_QUERY::Predicate::EQ)
		(L"!=", SHOW_QUERY::Predicate::NOT_EQ)
		(L"<", SHOW_QUERY::Predicate::LESS_THAN)
		(L"<=", SHOW_QUERY::Predicate::LESS_THAN_EQ)
		(L">", SHOW_QUERY::Predicate::GREATER_THAN)
		(L">=", SHOW_QUERY::Predicate::GREATER_THAN_EQ);

	showCommandSorting %= (
		showCommandSortingColumn % (
			(-space >> qi::lit(L",") >> -space) |
			(space >> qi::lit(L"then") >> space)));
	BOOST_SPIRIT_DEBUG_NODE(showCommandSorting);

	showCommandSortingColumn = (
		showCommandFields >> -(space >> showCommandSortingOrders)
	)[qi::_val = phoenix::bind(&constructShowQuerySortColumn, qi::_1, qi::_2)];
	BOOST_SPIRIT_DEBUG_NODE(showCommandSortingColumn);

	showCommandSortingOrders.add
		(L"asc", SHOW_QUERY::Order::ASCENDING)
		(L"ascending", SHOW_QUERY::Order::ASCENDING)
		(L"desc", SHOW_QUERY::Order::DESCENDING)
		(L"descending", SHOW_QUERY::Order::DESCENDING);

	showCommandFields.add
		(L"description", TaskField::DESCRIPTION)
		(L"deadline", TaskField::DEADLINE)
		(L"priority", TaskField::PRIORITY)
		(L"done", TaskField::COMPLETE)
		(L"complete", TaskField::COMPLETE);
	#pragma endregion

	#pragma region Editing tasks
	editCommand = (
		qi::uint_ >> space >> qi::lit(L"set") >> space >> editCommandRule
	)[qi::_val = phoenix::bind(&constructEditQuery,
		qi::_1, qi::_2)];
	BOOST_SPIRIT_DEBUG_NODE(editCommand);

	editCommandRule %= (
		editCommandRuleNullary |
		editCommandRuleUnary |
		editCommandRulePriorities
	);
	BOOST_SPIRIT_DEBUG_NODE(editCommandRule);

	editCommandRuleNullary = (
		editCommandFieldsNullary
	)[qi::_val = phoenix::bind(&constructEditQueryNullary, qi::_1)];
	BOOST_SPIRIT_DEBUG_NODE(editCommandRuleNullary);

	editCommandRuleUnary = (
		editCommandFieldsUnary >>
		-space >> qi::lit('=') >> -space >>
		utilityValue)
	[qi::_val = phoenix::bind(&constructEditQueryUnary, qi::_1, qi::_2)];
	BOOST_SPIRIT_DEBUG_NODE(editCommandRuleUnary);

	editCommandRulePriorities = (
		qi::lit(L"priority") >>
		-space >> qi::lit('=') >> -space >>
		utilityTaskPriority
	)[qi::_val = phoenix::bind(&constructEditQueryPriority, qi::_1)];
	BOOST_SPIRIT_DEBUG_NODE(editCommandRulePriorities);

	editCommandFieldsUnary.add
		(L"description", TaskField::DESCRIPTION)
		(L"deadline", TaskField::DEADLINE);

	editCommandFieldsNullary.add
		(L"done", TaskField::COMPLETE)
		(L"complete", TaskField::COMPLETE);
	#pragma endregion

	#pragma region Deleting tasks
	deleteCommand = (
		qi::uint_
	)[qi::_val = phoenix::bind(&constructDeleteQuery, qi::_1)];
	BOOST_SPIRIT_DEBUG_NODE(deleteCommand);
	#pragma endregion

	#pragma region Undoing tasks
	undoCommand = (
		qi::eps
	)[qi::_val = phoenix::construct<UNDO_QUERY>()];
	BOOST_SPIRIT_DEBUG_NODE(undoCommand);
	#pragma endregion

	space = qi::omit[+ParserCharTraits::blank];

	utilityValue = (
		(qi::int_) |
		(qi::bool_) |
		utilityTaskPriority |
		utilityLexeme
	)[qi::_val = phoenix::bind(&constructValue, qi::_1)];

	utilityTaskPriority.add
		(L"normal", TaskPriority::NORMAL)
		(L"high", TaskPriority::HIGH);

	utilityLexeme %= qi::as_wstring[(
		qi::lit('\'') > *utilityLexemeContents > qi::lit('\'')
	)];
	BOOST_SPIRIT_DEBUG_NODE(utilityLexeme);

	utilityLexemeContents %= (
		qi::lit("\\'")[qi::_val = L'\''] |
		qi::lit("\\\\")[qi::_val = L'\\'] |
		(ParserCharTraits::char_ - qi::lit('\''))
	);
	BOOST_SPIRIT_DEBUG_NODE(utilityLexemeContents);

	qi::on_error<qi::fail>(start,
		phoenix::bind(&onFailure, qi::_1, qi::_2, qi::_3, qi::_4));
}

void QueryParser::onFailure(
	ParserIteratorType /*begin*/,
	ParserIteratorType end,
	ParserIteratorType errorPos,
	const spirit::info& message) {
	StringType lexeme(errorPos, end);
	throw ParseErrorException(message, lexeme);
}

}  // namespace NLP
}  // namespace You
<|endoftext|>