text:
/*
 * Copyright (c) 2009-2013 Charlie Wiseman, Jyoti Parwatikar, John DeHart
 * and Washington University in St. Louis
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 *    limitations under the License.
 *
 */

#include <iostream>
#include <sstream>
#include <cstdio>
#include <cstdlib>
#include <string>
#include <list>
#include <vector>
#include <map>
#include <set>
#include <exception>
#include <stdexcept>

#include <boost/shared_ptr.hpp>

#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
#include <stdint.h>
#include <memory.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <netinet/in.h>

#include "shared.h"
#include "onl_database.h"

#include "onlcrd_reservation.h"
#include "onlcrd_session.h"
#include "onlcrd_component.h"
#include "onlcrd_session_manager.h"
#include "onlcrd_globals.h"
#include "onlcrd_requests.h"
#include "onlcrd_responses.h"
#include "onlcrd_session_sharing.h"

using namespace onlcrd;
switch_vlan test_vlan = 0; //used when testing and don't want to connect to NMD

session_manager::session_manager() throw()
{
  pthread_mutex_init(&vlan_lock, NULL);

  pthread_mutex_init(&port_lock, NULL);

  pthread_mutex_init(&comp_lock, NULL);

  pthread_mutex_init(&session_lock, NULL);
  next_session_id = 1;

  pthread_mutex_init(&reservation_lock, NULL);
  next_reservation_id = 1;

  pthread_mutex_init(&db_lock, NULL);
  database = new onl::onldb();

  //JP added 11/13/12 to force users to wait until we know about all testbed nodes
  initializing = true;
}

session_manager::~session_manager()
{
  pthread_mutex_destroy(&vlan_lock);

  pthread_mutex_destroy(&db_lock);

  pthread_mutex_destroy(&comp_lock);

  pthread_mutex_destroy(&session_lock);

  while(!active_reservations.empty())
  {
    delete active_reservations.front();
    active_reservations.pop_front();
  }
  pthread_mutex_destroy(&reservation_lock);
}

void
session_manager::initialize()
{
  if (testing) return;
  int ret;
  if(!testing)
  {
    std::string cmd = "/usr/testbed/scripts/send_crd_email.pl";
    ret = system(cmd.c_str());
    if(ret < 0 || WEXITSTATUS(ret) != 1) write_log("session_manager::initialize(): Warning: starting email was not sent");
    database->clear_all_experiments();
  }

  if(!testing)
  {
    onld::initialize* init = new onld::initialize();

    onl::switch_info_list switch_list;
    database->get_switch_list(switch_list);
    while(!switch_list.empty())
    {
      onl::switch_info sw = switch_list.front();
      switch_list.pop_front();

      onld::switch_info nextsw(sw.get_switch(), sw.get_num_ports());
      nextsw.set_management_port(sw.get_mgmt_port());
      init->add_switch(nextsw);
    }

    init->set_connection(the_gige_conn);
    if(!init->send_and_wait())
    {
      write_log("session_manager::initialize(): NMD initialization failed! exiting.");
      exit(1);
    }
    switch_response *swresp = (switch_response*)init->get_response();
    if(swresp->getStatus() != NCCP_Status_Fine)
    {
      write_log("session_manager::initialize(): warning!! NMD initialization returned failure!");
    }
    delete swresp;
    delete init;
  }

  onl::node_info_list node_list;
  database->get_base_node_list(node_list);

  autoLockDebug clock(comp_lock, "session_manager::initialize(): comp_lock");

  std::list<crd_component_ptr> new_nodes;
  while(!node_list.empty())
  {
    onl::node_info node = node_list.front();
    node_list.pop_front();

    if(node.state() == "free")
    {
      std::string cp = "";
      unsigned short cp_port = 0;
      if(node.has_cp())
      {
        cp = node.cp();
        cp_port = node.cp_port();
      }

      crd_component_ptr new_comp(new crd_component(node.node(), cp, cp_port, node.do_keeboot(), node.is_dependent()));
      new_comp->setCluster(node.cluster());
      new_nodes.push_back(new_comp);

    }
  }
  //set dependent info
  std::list<crd_component_ptr>::iterator cit;
  std::list<crd_component_ptr>::reverse_iterator cit2;
  for(cit = new_nodes.begin(); cit != new_nodes.end(); ++cit)
    {
      if (!(*cit)->getCluster().empty())
	{
	  write_log("session_manager::initialize set dependent comp:" + (*cit)->getName() + " cluster:" + (*cit)->getCluster());
	  for(cit2 = new_nodes.rbegin(); cit2 != new_nodes.rend(); ++cit2)
	    {
	      if ((*cit)==(*cit2)) break;
	      if ((*cit2)->getCluster() == (*cit)->getCluster())
		{
		  (*cit)->setDependentComp((*cit2)->getName());
		  (*cit2)->setDependentComp((*cit)->getName());
		  break;
		}
	    }
	}
    }
  for(cit = new_nodes.begin(); cit != new_nodes.end(); ++cit)
  {
    if(!(*cit)->ignore())
    {
      refreshing_components.push_back((*cit));
      (*cit)->refresh();
    }
  }
  new_nodes.clear();
  clock.unlock();
}

bool
session_manager::authenticate(std::string username, std::string password)
{
  write_log("session_manager::authenticate(): user " + username + " with password hash " + password);
  autoLockDebug dlock(db_lock, "session_manager::authenticate(): db_lock");

  onl::onldb_resp res = database->authenticate_user(username,password);
  if(res.result() < 1)
  {
    write_log("session_manager::authenticate(): failed error:" + res.msg());
    return false;
  }
  return true;
}

bool
session_manager::has_session(std::string username)
{
  write_log("session_manager::has_session(): user " + username);
  autoLockDebug slock(session_lock, "session_manager::has_session(): session_lock");

  std::list<session_ptr>::iterator it;
  for(it = active_sessions.begin(); it != active_sessions.end(); ++it)
  {
    if(((*it)->getUser() == username) && (!((*it)->is_cleared()))) { return true; }
  }
  return false;
}

int
session_manager::reservation_time_left(std::string username)
{
  autoLockDebug dlock(db_lock, "session_manager::reservation_time_left(): db_lock");

  onl::onldb_resp res = database->has_reservation(username);
  if(res.result() < 1)
  {
    return 0;
  }
  return res.result();
}

bool
session_manager::is_admin(std::string username)
{
  autoLockDebug dlock(db_lock, "session_manager::is_admin(): db_lock");

  onl::onldb_resp res = database->is_admin(username);
  if(res.result() < 1)
  {
    return false;
  }
  return true;
}

bool
session_manager::extend_reservation(std::string username, uint32_t minutes)
{
  write_log("session_manager::extend_reservation(): user " + username + " for " + int2str(minutes));
  autoLockDebug dlock(db_lock, "session_manager::extend_reservation(): db_lock");

  onl::onldb_resp res = database->extend_current_reservation(username, minutes);
  if(res.result() < 1)
  {
    write_log("session_manager::extend_reservation(): failed: " + res.msg());
    return false;
  }
  return true;
}

bool
session_manager::cancel_reservation(std::string username)
{
  write_log("session_manager::cancel_reservation(): user " + username);
  autoLockDebug dlock(db_lock, "session_manager::cancel_reservation(): db_lock");

  onl::onldb_resp res = database->cancel_current_reservation(username);
  if(res.result() < 1)
  {
    return false;
  }
  return true;
}

int
session_manager::get_capacity(std::string type, int port)
{
  //write_log("session_manager::get_capacity(): type=" + type + " port=" + int2str(port));
  autoLockDebug dlock(db_lock, "session_manager::get_capacity(): db_lock");

  onl::onldb_resp res = database->get_capacity(type, port);

  return res.result();
}

bool
session_manager::has_virtual_port(std::string type)
{
  //write_log("session_manager::get_capacity(): type=" + type + " port=" + int2str(port));
  autoLockDebug dlock(db_lock, "session_manager::is_vport(): db_lock");

  onl::onldb_resp res = database->has_virtual_port(type);

  if (res.result())
    return true;
  else
    return false;
}

void
session_manager::get_switch_ports(unsigned int cid, switch_port& p1, switch_port& p2)
{
  //write_log("session_manager::get_switch_ports(): cid=" + int2str(cid));
  autoLockDebug dlock(db_lock, "session_manager::get_switch_ports(): db_lock");

  onl::switch_port_info spi1, spi2;

  database->get_switch_ports(cid, spi1, spi2);

  p1 = switch_port(spi1.get_switch(),spi1.get_port(),spi1.is_interswitch_port(),spi1.get_pass_tag());
  p2 = switch_port(spi2.get_switch(),spi2.get_port(),spi2.is_interswitch_port(),spi2.get_pass_tag());
}

void
session_manager::fix_component(onl::topology* top, uint32_t id, std::string cp)
{
  write_log("session_manager::fix_component(): id=" + int2str(id) + " cp=" + cp);
  autoLockDebug dlock(db_lock, "session_manager::fix_component(): db_lock");

  database->fix_component(top, id, cp);
}

bool
session_manager::make_reservation(reservation* res, std::string username, std::string early_start, std::string late_start, uint32_t duration, onl::topology* top)
{
  write_log("session_manager::make_reservation(): user " + username);
  autoLockDebug dlock(db_lock, "session_manager::make_reservation(): db_lock");

  onl::onldb_resp resp = database->make_reservation(username, early_start, late_start, duration, top);
  res->setErrorMsg(resp.msg());
  if(resp.result() < 1)
  {
    return false;
  }
  return true;
}

bool
session_manager::assign_resources(session_ptr sess, std::string username, onl::topology* top)
{
  write_log("session_manager::assign_resources(): user " + username);
  //write_usage_log("USAGE_LOG: COMMIT user " + username);
  autoLockDebug dlock(db_lock, "session_manager::assign_resources(): db_lock");

  onl::onldb_resp res = database->assign_resources(username, top);
  if(res.result() < 1)
  {
    sess->setErrorMsg(res.msg());
    return false;
  }
  return true;
}

void
session_manager::return_resources(std::string username, onl::topology* top)
{
  write_log("session_manager::return_resources(): user " + username);
  //write_usage_log("USAGE_LOG: CLOSE user " + username);
  autoLockDebug dlock(db_lock, "session_manager::return_resources(): db_lock");

  database->return_resources(username, top);
}

void
session_manager::check_for_expired_sessions()
{
  std::list<std::string> users;

  autoLockDebug dlock(db_lock, "session_manager::check_for_expired_sessions(): db_lock");
  onl::onldb_resp res = database->get_expired_sessions(users);
  dlock.unlock();

  if(res.result() < 1)
  {
    write_log("session_manager::check_for_expired_sessions(): warning: db call failed: " + res.msg());
    return;
  }

  while(!users.empty())
  {
    std::string user = users.front();
    users.pop_front();

    session_ptr sess = get_session(user);
    if (sess)
      {
	sess->expired();
	sess->clear();
      }
  }
}

void
session_manager::received_up_msg(std::string hostname)
{
  //TODO make sure all of the relevant components are updated particularly for vms
  write_log("session_manager::received_up_msg(): host " + hostname);

  autoLockDebug clock(comp_lock, "session_manager::received_up_msg(): comp_lock");

  crd_component_ptr comp;
  std::list<crd_component_ptr>::iterator i;
  for(i=refreshing_components.begin(); i!=refreshing_components.end(); ++i)
  {
    if((*i)->getCP() == hostname)
    {
      comp = *i;
      break;
    }
  }

  if(!comp)
  {
    for(i=active_components.begin(); i!=active_components.end(); ++i)
    {
      if((*i)->getCP() == hostname)
      {
        comp = *i;
        break;
      }
    }
  }
  clock.unlock();

  // if comp was in the list, then let the refresher finish
  if(comp)
  {
    comp->got_up_msg();
    return;
  }

  // if comp wasn't in the list, then it must have been in an unknown state
  // but is now back up
  autoLockDebug dlock(db_lock, "session_manager::received_up_msg(): db_lock");
  onl::onldb_resp r = database->get_node_from_cp(hostname);
  if(r.result() <= 0)
  {
    write_log("session_manager::received_up_msg(): get node failed: " + r.msg());
    return;
  }

  // if we got the node, r.msg() has the node name
  std::string node = r.msg();

  // get the base node info
  onl::node_info info;
  r = database->get_node_info(node, false, info);
  if(r.result() < 0)
  {
    write_log("session_manager::received_up_msg(): get node info failed: " + r.msg());
    return;
  }

  // since the node is back up now, free it
  r = database->set_state(node, "free");
  if(r.result() <= 0)
  {
    write_log("session_manager::received_up_msg(): set state to free failed: " + r.msg());
    return;
  }
  dlock.unlock();

  // if the node uses keeboot, then we need to complete the keeboot. the
  // simplest way to ensure a clean state is to refresh the node completely
  if(info.do_keeboot())
  {
    std::string cp = "";
    unsigned short cp_port = 0;
    if(info.has_cp())
    {
      cp = info.cp();
      cp_port = info.cp_port();
    }

    crd_component_ptr new_comp(new crd_component(node, cp, cp_port, info.do_keeboot(), info.is_dependent()));
    if(!new_comp->ignore())
    {
      refreshing_components.push_back(new_comp);
      new_comp->refresh();
    }
  }
}

void
session_manager::set_keeboot_param(std::string name, std::string param)
{
  autoLockDebug clock(comp_lock, "session_manager::set_keeboot_param(): comp_lock");
  keeboot_params[name] = param;
}

bool
session_manager::check_keeboot_param(std::string name)
{
  autoLockDebug clock(comp_lock, "session_manager::check_keeboot_param(): comp_lock");
  std::map<std::string, std::string>::iterator it;
  it = keeboot_params.find(name);
  if(it == keeboot_params.end())
  {
    return false;
  }
  return true;
}

std::string
session_manager::get_keeboot_param(std::string name)
{
  std::map<std::string, std::string>::iterator it;
  it = keeboot_params.find(name);
  if(it == keeboot_params.end())
  {
    // if the user hasn't set an fs to boot, check for a file in the
    // install directory with this nodes name.
    struct stat fb;
    std::string install_file = "/export/keeboot_kernels/install/" + name + ".fsa";
    if(lstat(install_file.c_str(), &fb) == 0)
    {
      if((fb.st_mode & S_IFMT) == S_IFLNK)
      {
        std::string install_fs = "install/" + name;
        return install_fs;
      }
    }
    return "";
    //std::string default_fs = type + "/default";
    //return default_fs;
  }
  std::string fs = it->second;
  keeboot_params.erase(it);
  return fs;
}

bool
session_manager::start_session_vlans(std::string sid)
{
  if (!testing)
    {
      onld::start_session* startsession = new onld::start_session(sid);
      startsession->set_connection(the_gige_conn);
      if (!startsession->send_and_wait())
	{
	  delete startsession;
	  return false;
	}

      switch_response *swresp = (switch_response*)startsession->get_response();
      if(swresp->getStatus() != NCCP_Status_Fine)
	{
	  delete swresp;
	  delete startsession;
	  return false;
	}

      delete swresp;
      delete startsession;
    }
  return true;
}

bool
session_manager::clear_session_vlans(std::string sid)
{
  if (!testing)
    {
      onld::end_session* endsession = new onld::end_session(sid);
      endsession->set_connection(the_gige_conn);
      if (!endsession->send_and_wait())
	{
	  delete endsession;
	  return false;
	}

      switch_response *swresp = (switch_response*)endsession->get_response();
      if(swresp->getStatus() != NCCP_Status_Fine)
	{
	  delete swresp;
	  delete endsession;
	  return false;
	}

      delete swresp;
      delete endsession;
    }
  return true;
}

vlan_ptr
session_manager::add_vlan(std::string sid)
{
  switch_vlan vlan = 0;
  vlan_ptr null_ptr(new crd_vlan());
  null_ptr->vlanid = 0;;
  null_ptr->is_deleted = true;
  if (!testing)
    {
      onld::add_vlan* addvlan = new onld::add_vlan(sid);
      addvlan->set_connection(the_gige_conn);

      if(!addvlan->send_and_wait())
	{
	  delete addvlan;
	  return null_ptr;
	}

      add_vlan_response *addresp = (add_vlan_response*)addvlan->get_response();
      if(addresp->getStatus() != NCCP_Status_Fine)
	{
	  delete addresp;
	  delete addvlan;
	  return null_ptr;
	}

      vlan = addresp->getVlan();
      write_log("session_manager::add_vlan() vlan " + int2str(vlan));

      delete addresp;
      delete addvlan;
    }
  else
    {
      vlan = ++test_vlan;
    }
  autoLockDebug vlock(vlan_lock, "session_manager::add_vlan(): vlan_lock");
  num_ports_on_vlan[vlan] = 0;
  vlock.unlock();
  vlan_ptr new_vlan(new crd_vlan());
  new_vlan->vlanid = vlan;
  new_vlan->is_deleted = false;

  return new_vlan;
}

bool
session_manager::add_port_to_vlan(vlan_ptr vlan, switch_port port, std::string sid)
{
  if (!testing)
    {
      add_to_vlan* addtovlan = new add_to_vlan(vlan->vlanid, port, sid);
      addtovlan->set_connection(the_gige_conn);

      if(!addtovlan->send_and_wait())
	{
	  delete addtovlan;
	  return false;
	}

      switch_response *swresp = (switch_response*)addtovlan->get_response();
      if(swresp->getStatus() != NCCP_Status_Fine)
	{
	  delete swresp;
	  delete addtovlan;
	  return false;
	}

      delete swresp;
      delete addtovlan;
    }

  autoLockDebug vlock(vlan_lock, "session_manager::add_port_to_vlan(): vlan_lock");
  num_ports_on_vlan[vlan->vlanid] = num_ports_on_vlan[vlan->vlanid] + 1;
  vlock.unlock();

  return true;
}

bool
session_manager::remove_port_from_vlan(vlan_ptr vlan, switch_port port, std::string sid)
{
  bool last_port = false;

  autoLockDebug vlock(vlan_lock, "session_manager::remove_port_from_vlan(): vlan_lock");
  num_ports_on_vlan[vlan->vlanid] = num_ports_on_vlan[vlan->vlanid] - 1;
  if(num_ports_on_vlan[vlan->vlanid] == 0) { last_port = true; }
  vlock.unlock();

  if (!testing)
    {
      delete_from_vlan* delfromvlan = new delete_from_vlan(vlan->vlanid, port, sid);
      delfromvlan->set_connection(the_gige_conn);
      /*
      if(!add_port_to_outstanding_list(port))
	{
	  write_log("session_manager::remove_port_from_vlan(" + int2str(vlan->vlanid) + "): giving up after port was always in outstanding list: " + port.getSwitchId() + " port " + int2str(port.getPortNum()));
	  delete delfromvlan;
	  return false;
	  }*/

      if(!delfromvlan->send_and_wait())
	{
	  //remove_port_from_outstanding_list(port);
	  delete delfromvlan;
	  if(last_port)
	    {
	      if (delete_vlan(vlan, sid))
		write_log("session_manager::remove_port_from_vlan(): delete vlan " + int2str(vlan->vlanid));
	      else
		write_log("session_manager::remove_port_from_vlan(): warning: delete vlan failed for vlan " + int2str(vlan->vlanid));
	    }
	  return false;
	}

      //remove_port_from_outstanding_list(port);

      switch_response *swresp = (switch_response*)delfromvlan->get_response();
      if(swresp->getStatus() != NCCP_Status_Fine)
	{
	  delete swresp;
	  delete delfromvlan;
	  if(last_port)
	    {
	      if (delete_vlan(vlan, sid))
		write_log("session_manager::remove_port_from_vlan(): b delete vlan " + int2str(vlan->vlanid));
	      else
		write_log("session_manager::remove_port_from_vlan(): warning: delete vlan failed for vlan " + int2str(vlan->vlanid));
	    }
	  return false;
	}

      delete swresp;
      delete delfromvlan;
    }
  //else //testing
  //remove_port_from_outstanding_list(port);

  if(last_port)
  {
    if (delete_vlan(vlan, sid))
      write_log("session_manager::remove_port_from_vlan(): c delete vlan " + int2str(vlan->vlanid));
    else
      write_log("session_manager::remove_port_from_vlan(): warning: delete vlan failed for vlan " + int2str(vlan->vlanid));
  }
  return true;
}

bool
session_manager::delete_vlan(vlan_ptr vlan, std::string sid)
{
  autoLockDebug vlock(vlan_lock, "session_manager::delete_vlan(): vlan_lock");
  num_ports_on_vlan.erase(vlan->vlanid);
  if (vlan->is_deleted)
    {
      write_log("session_manager::delete_vlan() vlan " + int2str(vlan->vlanid) + " already deleted");
      return true;
    }
  vlan->is_deleted = true;
  vlock.unlock();

  if (!testing)
    {
      onld::delete_vlan* delvlan = new onld::delete_vlan(vlan->vlanid, sid);
      delvlan->set_connection(the_gige_conn);

      write_log("session_manager::delete_vlan() vlan " + int2str(vlan->vlanid));
      if(!delvlan->send_and_wait())
	{
	  vlock.lock();
	  vlan->is_deleted = false;
	  vlock.unlock();
	  delete delvlan;
	  return false;
	}

      switch_response *delresp = (switch_response*)delvlan->get_response();
      if(delresp->getStatus() != NCCP_Status_Fine)
	{
	  delete delresp;
	  delete delvlan;
	  return false;
	}

      delete delresp;
      delete delvlan;
    }
  return true;
}

bool
session_manager::add_port_to_outstanding_list(switch_port port)
{
  unsigned int num_attempts = 0;
  std::set<switch_port>::iterator pit;
  autoLockDebug plock(port_lock, "session_manager::add_port_to_outstanding_list(): port lock");
  pit = outstanding_ports.find(port);
  while(pit != outstanding_ports.end())
  {
    plock.unlock();

    num_attempts++;
    if(num_attempts == 100)
    {
      return false;
    }

    sleep(3);
    plock.lock();
    pit = outstanding_ports.find(port);
  }
  outstanding_ports.insert(port);
  plock.unlock();
  return true;
}

void
session_manager::remove_port_from_outstanding_list(switch_port port)
{
  autoLockDebug plock(port_lock, "session_manager::remove_port_from_outstanding_list(): port lock");
  outstanding_ports.erase(port);
  plock.unlock();
}

crd_component_ptr
session_manager::get_component(std::string name, unsigned int vmid)
{
  crd_component_ptr comp;

  if(name.substr(0,5) == "vgige")
  {
    crd_component_ptr tmp(new crd_virtual_switch(name));
    return tmp;
  }

  autoLockDebug dlock(db_lock, "session_manager::get_component(): db_lock");
  onl::node_info info;
  onl::onldb_resp r = database->get_node_info(name, false, info);
  if(r.result() < 0)
  {
    write_log("session_manager::get_component(): failed: " + r.msg());
    return comp;
  }
  dlock.unlock();

  std::string cp = "";
  unsigned short cp_port = 0;
  if(info.has_cp())
  {
    cp = info.cp();
    cp_port = info.cp_port();
  }

  if(info.do_keeboot())
  {
    autoLockDebug clock(comp_lock, "session_manager::get_component(): comp_lock");
    keeboot_params.erase(name);
    clock.unlock();
  }

  if (vmid == 0)
    {
      crd_component_ptr new_comp(new crd_component(info.node(), cp, cp_port, info.do_keeboot(), info.is_dependent()));
      new_comp->setCluster(info.cluster());
      return new_comp;
    }
  else
    {
      crd_component_ptr new_comp(new crd_virtual_machine(vmid, info.node(), cp, cp_port, info.do_keeboot(), info.is_dependent()));
      return new_comp;
    }
}

void
session_manager::add_component(crd_component_ptr comp, session_ptr sess)
{
  comp->set_session(sess);
  if(comp->get_type() == "vgige" || comp->get_type() == "vm")
  {
    return;
  }

  autoLockDebug clock(comp_lock, "session_manager::add_component(): comp_lock");
  std::list<crd_component_ptr>::iterator i;
  for(i=active_components.begin(); i!=active_components.end(); ++i)
  {
    //TODO VM there may be more than one active session with a valid active VM using
    //the same node
    //remove if user is same and session is different
    if((*i)->getName() == comp->getName())
    {
      clock.unlock();
      session_ptr old_sess = (*i)->get_session();
      old_sess->expired();
      old_sess->clear();
      clock.lock();
      break;
    }
  }

  active_components.push_back(comp);
}

void
session_manager::remove_component(crd_component_ptr comp)
{
  if(comp->get_type() == "vgige" || comp->get_type() == "vm")
  {
    return;
  }

  autoLockDebug clock(comp_lock, "session_manager::remove_component(): comp_lock");
  std::list<crd_component_ptr>::iterator i;
  for(i=active_components.begin(); i!=active_components.end();)
  {
    if((*i) == comp)
    {
      i = active_components.erase(i);
      refreshing_components.push_back(comp);
    }
    else
    {
      ++i;
    }
  }
}

void
session_manager::clear_component(crd_component* comp)
{
  if(comp->get_type() == "vgige" || comp->get_type() == "vm")
  {
    comp->clear_session();
    return;
  }

  write_log("session_manager::clear_component: comp(" + int2str((unsigned long) comp) + ") " + comp->getName());
  autoLockDebug clock(comp_lock, "session_manager::clear_component(): comp_lock");
  std::list<crd_component_ptr>::iterator i;
  for(i=refreshing_components.begin(); i!=refreshing_components.end(); ++i)
  {
    if((*i).get() == comp)
    {
      comp->clear_session();
      refreshing_components.erase(i);
      if (initializing && refreshing_components.empty())//JP added 11/13/12
	{
	  initializing = false;
	  write_log("session_manager::clear_component: all components processed. initializing phase of crd is over.");
	}
      return;
    }
  }

  // really should never get here..
  write_log("session_manager::clear_component: warning: calling clear on node " + comp->getName() + " which is not in the refreshing list");
  comp->clear_session();
}

session_ptr
session_manager::add_session(std::string username, nccp_connection* conn,begin_session_req* begin_req)
{
  autoLockDebug slock(session_lock, "session_manager::add_session(): session_lock");
  session_ptr sess(new session(next_session_id, username, conn));
  if (begin_req != NULL) sess->set_begin_request(begin_req);
  else write_log("session_manager::add_session user:" + username + " begin_req is NULL");
  next_session_id++;
  active_sessions.push_back(sess);
  return sess;
}

session_ptr
session_manager::get_session(nccp_connection* conn)
{
  autoLockDebug slock(session_lock, "session_manager::get_session(nccp_conn): session_lock");
  std::list<session_ptr>::iterator it;
  for(it = active_sessions.begin(); it != active_sessions.end(); ++it)
  {
    if(((*it)->getConnection() == conn) && !((*it)->is_cleared())) { return *it; }
  }
  return session_ptr();
}

session_ptr
session_manager::get_session(nccp_connection* conn, std::string sid)
{
  autoLockDebug slock(session_lock, "session_manager::get_session(nccp_conn): session_lock");
  std::list<session_ptr>::iterator it;
  for(it = active_sessions.begin(); it != active_sessions.end(); ++it)
  {
    if(((*it)->getConnection() == conn) && ((*it)->getID() == sid) && !((*it)->is_cleared())) { return *it; }
  }
  return session_ptr();
}

session_ptr
session_manager::get_session(std::string username)
{
  autoLockDebug slock(session_lock, "session_manager::get_session(string): session_lock");
  std::list<session_ptr>::iterator it;
  for(it = active_sessions.begin(); it != active_sessions.end(); ++it)
  {
    if(((*it)->getUser() == username) && !((*it)->is_cleared())) { return *it; }
  }
  return session_ptr();
}

void
session_manager::remove_session(session* sess)
{
  autoLockDebug slock(session_lock, "session_manager::remove_session(): session_lock");
  std::list<session_ptr>::iterator it;
  for(it = active_sessions.begin(); it != active_sessions.end(); ++it)
  {
    if((*it)->getID() == sess->getID())
    {
      write_log("session_manager::remove_session: removing session " + (*it)->getID() + " with ref count " + int2str((*it).use_count()));
      active_sessions.erase(it);
      break;
    }
  }
}

reservation*
session_manager::add_reservation(std::string username, nccp_connection* conn, begin_reservation_req* begin_req)
{
  autoLockDebug rlock(reservation_lock, "session_manager::add_reservation(): reservation_lock");
  reservation* res = new reservation(next_reservation_id, username, conn);
  if (begin_req != NULL) res->set_begin_request(begin_req);
  else write_log("session_manager::add_reservation user:" + username + " begin_req is NULL");
  next_reservation_id++;
  active_reservations.push_back(res);
  return res;
}

reservation*
session_manager::get_reservation(nccp_connection* conn)
{
  autoLockDebug rlock(reservation_lock, "session_manager::get_reservation(): reservation_lock");
  std::list<reservation *>::iterator it;
  for(it = active_reservations.begin(); it != active_reservations.end(); ++it)
  {
    if((*it)->getConnection() == conn) { return *it; }
  }
  return NULL;
}

reservation*
session_manager::get_reservation(nccp_connection* conn, std::string rid)
{
  autoLockDebug rlock(reservation_lock, "session_manager::get_reservation(): reservation_lock");
  std::list<reservation *>::iterator it;
  for(it = active_reservations.begin(); it != active_reservations.end(); ++it)
  {
    if((*it)->getConnection() == conn && (*it)->getID() == rid) { return *it; }
  }
  return NULL;
}

void
session_manager::remove_reservation(reservation* res)
{
  res->clear();

  autoLockDebug rlock(reservation_lock, "session_manager::remove_reservation(): reservation_lock");
  std::list<reservation *>::iterator it;
  for(it = active_reservations.begin(); it != active_reservations.end(); ++it)
  {
    if((*it)->getConnection() == res->getConnection())
    {
      active_reservations.erase(it);
      break;
    }
  }
  rlock.unlock();

  delete res;
}

void
session_manager::get_observable_sessions(std::string username, std::list<session_ptr>& list)
{
  autoLockDebug slock(session_lock, "session_manager::get_observable_sessions(): session_lock");
  std::list<session_ptr>::iterator it;
  for(it = active_sessions.begin(); it != active_sessions.end(); ++it)
  {
    if((*it)->observable_by(username)) { list.push_back(*it); }
  }
}

ext: cc

max_stars_repo_name: WU-ARL/ONLdaemons

max_issues_repo_name: WU-ARL/ONLdaemons

max_forks_repo_name: WU-ARL/ONLdaemons


text:
#include <boost/fusion/tuple.hpp>
#include <boost/fusion/view.hpp>
#include <boost/fusion/algorithm.hpp>
#include <boost/type_traits.hpp>
#include <boost/mpl/arg.hpp>
#include <string>
#include <iostream>

using namespace boost::fusion;

struct print
{
  template <typename T>
  void operator()(const T &t) const
  {
    std::cout << std::boolalpha << t << '\n';
  }
};

int main()
{
  typedef tuple<int, std::string, bool, double> tuple_type;
  tuple_type t{10, "Boost", true, 3.14};
  filter_view<tuple_type, boost::is_integral<boost::mpl::arg<1>>> v{t};
  for_each(v, print{});
}

ext: cpp

max_stars_repo_name: KwangjoJeong/Boost

max_issues_repo_name: KwangjoJeong/Boost

max_forks_repo_name: KwangjoJeong/Boost


text:
//---------------------------------------------------------------------------//
//!
//! \file   MonteCarlo_ParticleEventDispatcher.hpp
//! \author Alex Robinson
//! \brief  Particle event dispatcher database base class declaration.
//!
//---------------------------------------------------------------------------//

#ifndef MONTE_CARLO_PARTICLE_EVENT_DISPATCHER_HPP
#define MONTE_CARLO_PARTICLE_EVENT_DISPATCHER_HPP

// Std Lib Includes
#include <memory>

// Boost Includes
#include <boost/serialization/split_member.hpp>
#include <boost/serialization/version.hpp>
#include <boost/serialization/assume_abstract.hpp>
#include <boost/serialization/export.hpp>
#include <boost/serialization/shared_ptr.hpp>

// FRENSIE Includes
#include "Utility_ExplicitSerializationTemplateInstantiationMacros.hpp"
#include "Utility_SerializationHelpers.hpp"
#include "Utility_Map.hpp"

namespace MonteCarlo{

//! The particle event dispatcher database base class
template<typename Dispatcher>
class ParticleEventDispatcher
{

public:

  // Constructor
  ParticleEventDispatcher();

  // Destructor
  virtual ~ParticleEventDispatcher()
  { /* ... */ }

  //! Get the appropriate local dispatcher for the given entity id
  Dispatcher& getLocalDispatcher( const uint64_t entity_id );

  //! Attach an observer to the appropriate dispatcher
  void attachObserver(
          const uint64_t entity_id,
          const std::set<ParticleType>& particle_types,
	  const std::shared_ptr<typename Dispatcher::ObserverType>& observer );

  //! Attach an observer to the appropriate dispatcher
  void attachObserver(
          const uint64_t entity_id,
	  const std::shared_ptr<typename Dispatcher::ObserverType>& observer );

  //! Detach an observer from the appropriate local dispatcher
  void detachObserver( const uint64_t entity_id,
                       const std::shared_ptr<typename Dispatcher::ObserverType>& observer );

  //! Detach the observer from all local dispatchers
  void detachObserver( const std::shared_ptr<typename Dispatcher::ObserverType>& observer );

  //! Detach all observers
  void detachAllObservers();

protected:

  // Typedef for the dispatcher map
  typedef typename std::unordered_map<uint64_t,std::unique_ptr<Dispatcher> >
  DispatcherMap;

  //! Get the dispatcher map
  DispatcherMap& getDispatcherMap();

private:

  // Serialize the observer
  template<typename Archive>
  void serialize( Archive& ar, const unsigned version );

  // Declare the boost serialization access object as a friend
  friend class boost::serialization::access;

  DispatcherMap d_dispatcher_map;
};

} // end MonteCarlo namespace

BOOST_SERIALIZATION_CLASS1_VERSION( ParticleEventDispatcher, MonteCarlo, 0 );

//---------------------------------------------------------------------------//
// Template Includes.
//---------------------------------------------------------------------------//

#include "MonteCarlo_ParticleEventDispatcher_def.hpp"

//---------------------------------------------------------------------------//

#endif // end MONTE_CARLO_PARTICLE_EVENT_DISPATCHER_HPP

//---------------------------------------------------------------------------//
// end MonteCarlo_ParticleEventDispatcher.hpp
//---------------------------------------------------------------------------//

ext: hpp


text:
#include "MessageHandler.h"
#include "../CompilationUnit.h"
#include "../parser/LPGParser.h"
#include "../parser/LPGParser_top_level_ast.h"
#include "../ASTUtils.h"
#include <stack>
#include <boost/asio/basic_signal_set.hpp>

namespace
{

	#define GetRValue(rgb)      (LOBYTE(rgb))
	#define GetGValue(rgb)      (LOBYTE(((WORD)(rgb)) >> 8))
	#define GetBValue(rgb)      (LOBYTE((rgb)>>16))
	struct SWT
	{
		/**
	 * Default color white (value is 1).
	 */
		const static  int COLOR_WHITE = 1;

		/**
		 * Default color black (value is 2).
		 */
		const static  int COLOR_BLACK = 2;

		/**
		 * Default color red (value is 3).
		 */
		const static  int COLOR_RED = 3;

		/**
		 * Default color dark red (value is 4).
		 */
		const static  int COLOR_DARK_RED = 4;

		/**
		 * Default color green (value is 5).
		 */
		const static  int COLOR_GREEN = 5;

		/**
		 * Default color dark green (value is 6).
		 */
		const static  int COLOR_DARK_GREEN = 6;

		/**
		 * Default color yellow (value is 7).
		 */
		const static  int COLOR_YELLOW = 7;

		/**
		 * Default color dark yellow (value is 8).
		 */
		const static  int COLOR_DARK_YELLOW = 8;

		/**
		 * Default color blue (value is 9).
		 */
		const static  int COLOR_BLUE = 9;

		/**
		 * Default color dark blue (value is 10).
		 */
		const static  int COLOR_DARK_BLUE = 10;

		/**
		 * Default color magenta (value is 11).
		 */
		const static  int COLOR_MAGENTA = 11;

		/**
		 * Default color dark magenta (value is 12).
		 */
		const static  int COLOR_DARK_MAGENTA = 12;

		/**
		 * Default color cyan (value is 13).
		 */
		const static  int COLOR_CYAN = 13;

		/**
		 * Default color dark cyan (value is 14).
		 */
		const static  int COLOR_DARK_CYAN = 14;

		/**
		 * Default color gray (value is 15).
		 */
		const static  int COLOR_GRAY = 15;

		/**
		 * Default color dark gray (value is 16).
		 */
		const static  int COLOR_DARK_GRAY = 16;

		/*
		 * System Colors
		 *
		 * Dealing with system colors is an area where there are
		 * many platform differences.  On some platforms, system
		 * colors can change dynamically while the program is
		 * running.  On other platforms, system colors can be
		 * changed for all instances of a particular widget.
		 * Therefore, the only truly portable method to obtain
		 * a widget color query is to query the color from an
		 * instance of the widget.
		 *
		 *	It is expected that the list of supported colors
		 * will grow over time.
		 */

		 /**
		  * System color used to paint dark shadow areas (value is 17).
		  */
		const static  int COLOR_WIDGET_DARK_SHADOW = 17;

		/**
		 * System color used to paint normal shadow areas (value is 18).
		 */
		const static  int COLOR_WIDGET_NORMAL_SHADOW = 18;

		/**
		 * System color used to paint light shadow areas (value is 19).
		 */
		const static  int COLOR_WIDGET_LIGHT_SHADOW = 19;

		/**
		 * System color used to paint highlight shadow areas (value is 20).
		 */
		const static  int COLOR_WIDGET_HIGHLIGHT_SHADOW = 20;

		/**
		 * System color used to paint foreground areas (value is 21).
		 */
		const static  int COLOR_WIDGET_FOREGROUND = 21;

		/**
		 * System color used to paint background areas (value is 22).
		 */
		const static  int COLOR_WIDGET_BACKGROUND = 22;

		/**
		 * System color used to paint border areas (value is 23).
		 */
		const static  int COLOR_WIDGET_BORDER = 23;

		/**
		 * System color used to paint list foreground areas (value is 24).
		 */
		const static  int COLOR_LIST_FOREGROUND = 24;

		/**
		 * System color used to paint list background areas (value is 25).
		 */
		const static  int COLOR_LIST_BACKGROUND = 25;

		/**
		 * System color used to paint list selection background areas (value is 26).
		 */
		const static  int COLOR_LIST_SELECTION = 26;

		/**
		 * System color used to paint list selected text (value is 27).
		 */
		const static  int COLOR_LIST_SELECTION_TEXT = 27;

		/**
		 * System color used to paint tooltip text (value is 28).
		 */
		const static  int COLOR_INFO_FOREGROUND = 28;

		/**
		 * System color used to paint tooltip background areas (value is 29).
		 */
		const static  int COLOR_INFO_BACKGROUND = 29;

		/**
		 * System color used to paint title text (value is 30).
		 */
		const static  int COLOR_TITLE_FOREGROUND = 30;

		/**
		 * System color used to paint title background areas (value is 31).
		 */
		const static  int COLOR_TITLE_BACKGROUND = 31;

		/**
		 * System color used to paint title background gradient (value is 32).
		 */
		const static  int COLOR_TITLE_BACKGROUND_GRADIENT = 32;

		/**
		 * System color used to paint inactive title text (value is 33).
		 */
		const static  int COLOR_TITLE_INACTIVE_FOREGROUND = 33;

		/**
		 * System color used to paint inactive title background areas (value is 34).
		 */
		const static  int COLOR_TITLE_INACTIVE_BACKGROUND = 34;

		/**
		 * System color used to paint inactive title background gradient (value is 35).
		 */
		const static  int COLOR_TITLE_INACTIVE_BACKGROUND_GRADIENT = 35;

		/**
		 * System color used to paint link text (value is 36).
		 *
		 * @since 3.102
		 */
		const static  int COLOR_LINK_FOREGROUND = 36;

		/**
		 * System color used to paint with alpha 0 (value is 37).
		 *

		 * This pseudo-color can be used to set a transparent background on SWT
		 * controls.

		 * Note that this is a HINT and may be overridden by the platform.
		 * For example:
		 *

		 *
{@link org.eclipse.swt.widgets.Combo Combo},
		 * {@link org.eclipse.swt.widgets.List List} and
		 * {@link org.eclipse.swt.widgets.Tree Tree} support transparent background
		 * on GTK3 and Windows only.

		 *
{@link org.eclipse.swt.widgets.Text Text} supports transparent
		 * background on Windows only whereas {@link org.eclipse.swt.widgets.Table
		 * Table} supports transparent background on GTK3 only.

		 *

		 *
		 * @since 3.104
		 */
		const static  int COLOR_TRANSPARENT = 37;

		/**
		 * System color used to paint disabled text background areas (value is 38).
		 *
		 * @since 3.112
		 */
		const static  int COLOR_TEXT_DISABLED_BACKGROUND = 38;

		/**
		 * System color used to paint disabled foreground areas (value is 39).
		 *
		 * @since 3.112
		 */
		const static  int COLOR_WIDGET_DISABLED_FOREGROUND = 39;
	};

	struct Color
	{
		int handle = 0;
		int alpha = 255;

		TextDocument::Color Convert() const
		{
			TextDocument::Color _color;
			_color.alpha = alpha / 255.0;
			_color.red =  GetRValue(handle)/255.0;
			_color.green = GetGValue(handle) / 255.0;
			_color.blue = GetBValue(handle) / 255.0;
			return  _color;
		}
		static Color win32_new(int handle, int alpha) {
			Color color;
			color.handle = handle;
			color.alpha = alpha;
			return color;
		}
		static Color win32_new(int handle)
		{
			return  win32_new(handle, 255);
		}

		static Color getSystemColor(int id) {

			int pixel = 0x00000000;
			switch (id) {
			case SWT::COLOR_WIDGET_DARK_SHADOW:		pixel = ::GetSysColor(COLOR_3DDKSHADOW);	break;
			case SWT::COLOR_WIDGET_DISABLED_FOREGROUND: pixel = ::GetSysColor(COLOR_GRAYTEXT); break;
			case SWT::COLOR_WIDGET_NORMAL_SHADOW:	pixel = ::GetSysColor(COLOR_3DSHADOW); 	break;
			case SWT::COLOR_WIDGET_LIGHT_SHADOW: 	pixel = ::GetSysColor(COLOR_3DLIGHT);  	break;
			case SWT::COLOR_WIDGET_HIGHLIGHT_SHADOW:	pixel = ::GetSysColor(COLOR_3DHIGHLIGHT);  break;
			case SWT::COLOR_TEXT_DISABLED_BACKGROUND:
			case SWT::COLOR_WIDGET_BACKGROUND: 		pixel = ::GetSysColor(COLOR_3DFACE);  	break;
			case SWT::COLOR_WIDGET_BORDER: 		pixel = ::GetSysColor(COLOR_WINDOWFRAME);  break;
			case SWT::COLOR_WIDGET_FOREGROUND:
			case SWT::COLOR_LIST_FOREGROUND: 		pixel = ::GetSysColor(COLOR_WINDOWTEXT);	break;
			case SWT::COLOR_LIST_BACKGROUND: 		pixel = ::GetSysColor(COLOR_WINDOW);  	break;
			case SWT::COLOR_LIST_SELECTION: 		pixel = ::GetSysColor(COLOR_HIGHLIGHT);	break;
			case SWT::COLOR_LIST_SELECTION_TEXT: 	pixel = ::GetSysColor(COLOR_HIGHLIGHTTEXT); break;
			case SWT::COLOR_LINK_FOREGROUND: 	pixel = ::GetSysColor(COLOR_HOTLIGHT); break;
			case SWT::COLOR_INFO_FOREGROUND:		pixel = ::GetSysColor(COLOR_INFOTEXT);	break;
			case SWT::COLOR_INFO_BACKGROUND:		pixel = ::GetSysColor(COLOR_INFOBK);		break;
			case SWT::COLOR_TITLE_FOREGROUND: 		pixel = ::GetSysColor(COLOR_CAPTIONTEXT);	break;
			case SWT::COLOR_TITLE_BACKGROUND:		pixel = ::GetSysColor(COLOR_ACTIVECAPTION);		break;
			case SWT::COLOR_TITLE_BACKGROUND_GRADIENT:
				pixel = ::GetSysColor(COLOR_GRADIENTACTIVECAPTION);
				if (pixel == 0) pixel = ::GetSysColor(COLOR_ACTIVECAPTION);
				break;
			case SWT::COLOR_TITLE_INACTIVE_FOREGROUND: 		pixel = ::GetSysColor(COLOR_INACTIVECAPTIONTEXT);	break;
			case SWT::COLOR_TITLE_INACTIVE_BACKGROUND:			pixel = ::GetSysColor(COLOR_INACTIVECAPTION);		break;
			case SWT::COLOR_TITLE_INACTIVE_BACKGROUND_GRADIENT:
				pixel = ::GetSysColor(COLOR_GRADIENTINACTIVECAPTION);
				if (pixel == 0) pixel = ::GetSysColor(COLOR_INACTIVECAPTION);
				break;
			default:
				return getSystemColorInternal(id);
			}
			return win32_new( pixel);
		}
	private:
		static Color getSystemColorInternal(int id) {

			int pixel = 0x00000000;
			int alpha = 255;
			switch (id) {
			case SWT::COLOR_TRANSPARENT:			alpha = 0;  break;
			case SWT::COLOR_WHITE:				pixel = 0x00FFFFFF;  break;
			case SWT::COLOR_BLACK:				pixel = 0x00000000;  break;
			case SWT::COLOR_RED:					pixel = 0x000000FF;  break;
			case SWT::COLOR_DARK_RED:			pixel = 0x00000080;  break;
			case SWT::COLOR_GREEN:				pixel = 0x0000FF00;  break;
			case SWT::COLOR_DARK_GREEN:			pixel = 0x00008000;  break;
			case SWT::COLOR_YELLOW:				pixel = 0x0000FFFF;  break;
			case SWT::COLOR_DARK_YELLOW:		pixel = 0x00008080;  break;
			case SWT::COLOR_BLUE:				pixel = 0x00FF0000;  break;
			case SWT::COLOR_DARK_BLUE:			pixel = 0x00800000;  break;
			case SWT::COLOR_MAGENTA:			pixel = 0x00FF00FF;  break;
			case SWT::COLOR_DARK_MAGENTA:		pixel = 0x00800080;  break;
			case SWT::COLOR_CYAN:				pixel = 0x00FFFF00;  break;
			case SWT::COLOR_DARK_CYAN:			pixel = 0x00808000;  break;
			case SWT::COLOR_GRAY:				pixel = 0x00C0C0C0;  break;
			case SWT::COLOR_DARK_GRAY:			pixel = 0x00808080;  break;
			default: ;
			}
			return win32_new(pixel, alpha);
		}

	};

	TextDocument::Color COMMENT = Color::getSystemColor(SWT::COLOR_DARK_CYAN).Convert();

	TextDocument::Color SYMBOL = Color::getSystemColor(SWT::COLOR_DARK_RED).Convert();

	TextDocument::Color KEYWORD = Color::getSystemColor(SWT::COLOR_BLUE).Convert();

	TextDocument::Color LITERAL = Color::getSystemColor(SWT::COLOR_DARK_GRAY).Convert();

	TextDocument::Color EMPTY = Color::getSystemColor(SWT::COLOR_DARK_GRAY).Convert();

	TextDocument::Color ANNOTATION = Color::getSystemColor(SWT::COLOR_MAGENTA).Convert();

	TextDocument::Color Other = Color::getSystemColor(SWT::COLOR_BLACK).Convert();

}
struct DocumentColorHandlerData
{
	std::shared_ptr<CompilationUnit>& unit;

	shared_ptr_wstring buffer;
	DocumentColorHandlerData(std::shared_ptr<CompilationUnit>& u, std::vector<ColorInformation>& o) :unit(u)
	{
		if (!unit)
		{
			return;
		}
		Init();
		auto lex = unit->runtime_unit->_lexer.getILexStream();
		auto process_token = [&](IToken* token)
		{
			ColorInformation information;
			information.color = getColoring(token);

			auto pos = ASTUtils::toPosition(lex, token->getStartOffset());
			if (pos)
			{
				information.range.start = pos.value();
			}
			pos = ASTUtils::toPosition(lex, token->getEndOffset());
			if (pos)
			{
				information.range.end = pos.value();
			}
			o.emplace_back(information);
		};
		{
			Tuple<IToken*>& tokens = u->runtime_unit->_parser.prsStream->tokens;
			for (int i = 0; i < tokens.size(); ++i)
			{
				IToken* token = tokens[i];
				process_token(token);
			}
		}
		{
			Tuple<IToken*>& tokens = u->runtime_unit->_parser.prsStream->adjuncts;
			for (int i = 0; i < tokens.size(); ++i)
			{
				IToken* token = tokens[i];
				process_token(token);
			}
		}
	}
	void Init()
	{
		auto& parser = unit->runtime_unit->_parser;
		auto  tokenKindNames = parser.orderedTerminalSymbols();
		fIsKeyword.resize(tokenKindNames.size());

		auto keywordKinds = unit->runtime_unit->_lexer.kwLexer->keywordKind;
		auto length = unit->runtime_unit->_lexer.kwLexer->keywordKindLenth;
		for (int i = 1; i < length; i++) {
			int index = parser.getIPrsStream()->mapKind(keywordKinds[i]);
			fIsKeyword[index] = true;

		}
		buffer = unit->runtime_unit->_parser.getIPrsStream()->getInputChars();
	}
	std::vector<bool>fIsKeyword;
	bool isKeyword(int kind) {
		return kind < LPGParsersym::numTokenKinds&& fIsKeyword[kind];
	}
	TextDocument::Color getColoring(IToken* token) {

		auto kind = token->getKind();
		if (kind == LPGParsersym::TK_EMPTY_KEY)
			return EMPTY;
		if (isKeyword(token->getKind()))
			return KEYWORD;
		if (kind == LPGParsersym::TK_SYMBOL)
		{
			int tokStartOffset = token->getStartOffset();
			wchar_t ch = buffer[tokStartOffset];
			if (ch == '\'' || ch == '"')
				return LITERAL;
			return SYMBOL;
		}
		if (kind == LPGParsersym::TK_SINGLE_LINE_COMMENT)
			return COMMENT;
		if (kind == LPGParsersym::TK_MACRO_NAME)
			return ANNOTATION;

		return Other;
	}

};
DocumentColorHandler::DocumentColorHandler(std::shared_ptr<CompilationUnit>&u, std::vector<ColorInformation>&o) :d_ptr(new DocumentColorHandlerData(u,o))
{

}

DocumentColorHandler::~DocumentColorHandler()
{
	delete d_ptr;
}

max_stars_repo_name: kuafuwang/LPG-language-server

max_issues_repo_name: kuafuwang/LPG-language-server

max_forks_repo_name: kuafuwang/LPG-language-server


text:
/* test_thread_safe_arrays.cpp - Tests that Adept arrays are thread-safe

  Copyright (C) 2017 ECMWF

  Copying and distribution of this file, with or without modification,
  are permitted in any medium without royalty provided the copyright
  notice and this notice are preserved.  This file is offered as-is,
  without any warranty.

*/

#ifdef _OPENMP
#include <omp.h>
#endif

//#define ADEPT_STORAGE_THREAD_SAFE 1

#include <adept_arrays.h>

int main(int argc, const char** argv)
{
  using namespace adept;

  int N = 2;
  Matrix A(N,N);
  SymmMatrix S(N);

  Matrix B;
  SymmMatrix T;
#ifdef ADEPT_STORAGE_THREAD_SAFE
  std::cout << "Storage should be thread safe\n";
  // B shares the data and increases the reference counter of the
  // shared Storage object. If A goes out of scope, B will "steal" the
  // data.
  B >>= A;
  T >>= S;
#else
  std::cout << "Storage is not thread safe: using soft_link()\n";
  // B points to the data but does not have access to the Storage
  // object. If A goes out of scope, B will most likely point to an
  // inaccessible memory location.
  B >>= A.soft_link();
  T >>= S.soft_link();
#endif

  A = 1.0; // Also seen by B
  S = 2.0; // Also seen by S

  int nthreads = 1;

#ifdef _OPENMP
  nthreads = omp_get_max_threads();
  std::cout << omp_get_num_procs() << " processors available running maximum of "
	    << nthreads << " threads\n";
#else
  std::cout << "Compiled without OpenMP support: 1 thread\n";
#endif

  // The following almost always causes a crash if the code is not
  // properly thread safe
#pragma omp parallel for
  for (int i = 0; i < N*1000; ++i) {

    for (int j = 0; j < N*1000; ++j) {
      B[j % N] = noalias(B(__,j)) + T.diag_vector();
    }

  }

  if (nthreads > 1) {
    std::cout << "Parallel subsetting of array zillions of times was successful\n";
  }
  else {
    std::cout << "Serial subsetting of array zillions of times was successful (unsurprisingly)\n";
  }

  return 0;

}


text:
#include "convert.hpp"

#include <boost/smart_ptr/intrusive_ptr.hpp>
#include <boost/smart_ptr/intrusive_ref_counter.hpp>

#include "nlohmann/json.hpp"

#include <pybind11/stl.h>
#include <pybind11/stl_bind.h>

#include "components/document/core/dict.hpp"

// The bug related to the use of RTTI by the pybind11 library has been fixed: a
// declaration should be in each translation unit.
PYBIND11_DECLARE_HOLDER_TYPE(T, boost::intrusive_ptr<T>)

using components::document::document_t;
using components::document::document_view_t;
using json = nlohmann::json;

inline json to_json(const py::handle& obj) {
    if (obj.ptr() == nullptr || obj.is_none()) {
        return nullptr;
    }
    if (py::isinstance<py::bool_>(obj)) {
        return obj.cast<bool>();
    }
    if (py::isinstance<py::int_>(obj)) {
        return obj.cast<long>();
    }
    if (py::isinstance<py::float_>(obj)) {
        return obj.cast<double>();
    }
    if (py::isinstance<py::bytes>(obj)) {
        py::module base64 = py::module::import("base64");
        return base64.attr("b64encode")(obj).attr("decode")("utf-8").cast<std::string>();
    }
    if (py::isinstance<py::str>(obj)) {
        return obj.cast<std::string>();
    }
    if (py::isinstance<py::tuple>(obj) || py::isinstance<py::list>(obj)) {
        auto out = json::array();
        for (const py::handle value : obj) {
            out.push_back(to_json(value));
        }
        return out;
    }
    if (py::isinstance<py::dict>(obj)) {
        auto out = json::object();
        for (const py::handle key : obj) {
            out[py::str(key).cast<std::string>()] = to_json(obj[key]);
        }
        return out;
    }
    throw std::runtime_error("to_json not implemented for this type of object: " + py::repr(obj).cast<std::string>());
}

inline ::document::retained_const_t<::document::impl::value_t> to__(const py::handle& obj) {
    if (py::isinstance<py::bool_>(obj)) {
        return ::document::impl::new_value(obj.cast<bool>());
    }
    if (py::isinstance<py::int_>(obj)) {
        return ::document::impl::new_value(obj.cast<long>());
    }
    if (py::isinstance<py::float_>(obj)) {
        return ::document::impl::new_value(obj.cast<double>());
    }
    if (py::isinstance<py::bytes>(obj)) {
        py::module base64 = py::module::import("base64");
        return ::document::impl::new_value(base64.attr("b64encode")(obj).attr("decode")("utf-8").cast<std::string>());
    }
    if (py::isinstance<py::str>(obj)) {
        return ::document::impl::new_value(obj.cast<std::string>());
    }

    if (py::isinstance<py::tuple>(obj) || py::isinstance<py::list>(obj)) {
        auto out = document_t::create_array();
        for (const py::handle value : obj) {
            out->append(to__(value));
        }
        return out->as_array();
    }
    if (py::isinstance<py::dict>(obj)) {
        document_t out;
        to_document(obj, out);
        return out.value();
    }

    throw std::runtime_error("to_json not implemented for this type of object: " + py::repr(obj).cast<std::string>());
}

void to_document_inner(std::string&& key, const py::handle& source, document_t& target) {
    if (source.ptr() == nullptr || source.is_none()) {
        target.add_null(std::move(key));
        return;
    }
    if (py::isinstance<py::bool_>(source)) {
        target.add_bool(std::move(key), source.cast<bool>());
        return;
    }
    if (py::isinstance<py::int_>(source)) {
        target.add_long(std::move(key), source.cast<long>());
        return;
    }
    if (py::isinstance<py::float_>(source)) {
        target.add_double(std::move(key), source.cast<double>());
        return;
    }
    if (py::isinstance<py::bytes>(source)) {
        py::module base64 = py::module::import("base64");
        target.add_string(std::move(key), base64.attr("b64encode")(source).attr("decode")("utf-8").cast<std::string>());
        return;
    }
    if (py::isinstance<py::str>(source)) {
        target.add_string(std::move(key), source.cast<std::string>());
        return;
    }

    if (py::isinstance<py::tuple>(source) || py::isinstance<py::list>(source)) {
        auto inner_doc = document_t::create_array();
        for (const py::handle value : source) {
            inner_doc->append(to__(value));
        }
        target.add_array(std::move(key), inner_doc);
        return;
    }
    if (py::isinstance<py::dict>(source)) {
        document_t inner_doc;
        to_document(source, inner_doc);
        target.add_dict(std::move(key), std::move(inner_doc));
        return;
    }

    throw std::runtime_error("to_document not implemented for this type of object: " + py::repr(source).cast<std::string>());
}

void to_document(const py::handle& source, document_t& target) {
    for (const py::handle key : source) {
        to_document_inner(py::str(key).cast<std::string>(), source[key], target);
    }
}

void update_document_inner(std::string&& key, const py::handle& obj, document_t& target) {
    if (obj.ptr() == nullptr || obj.is_none()) {
        target.add_null(key);
        return;
    }
    if (py::isinstance<py::bool_>(obj)) {
        target.add_bool(key, obj.cast<bool>());
        return;
    }
    if (py::isinstance<py::int_>(obj)) {
        target.add_long(key, obj.cast<long>());
        return;
    }
    if (py::isinstance<py::float_>(obj)) {
        target.add_double(key, obj.cast<double>());
        return;
    }
    if (py::isinstance<py::bytes>(obj)) {
        py::module base64 = py::module::import("base64");
        target.add_string(key, base64.attr("b64encode")(obj).attr("decode")("utf-8").cast<std::string>());
    }
    if (py::isinstance<py::str>(obj)) {
        target.add_string(key, obj.cast<std::string>());
        return;
    }
    /*
    if (py::isinstance<py::tuple>(obj) || py::isinstance<py::list>(obj)) {
        auto out = nl::json::array();
        for (const py::handle value : obj) {
            out.push_back(to_json(value));
        }
        return out;
    }
    if (py::isinstance<py::dict>(obj)) {
        auto out = nl::json::object();
        for (const py::handle key : obj) {
            out[py::str(key).cast<std::string>()] = to_json(obj[key]);
        }
        return out;
    }
     */
    throw std::runtime_error("update_document_inner not implemented for this type of object: " + py::repr(obj).cast<std::string>());
}

auto from_document(const document_view_t &document) -> py::object {
    if (document.is_dict()) {
        py::dict dict;
        for (auto it = document.begin(); it; ++it) {
            auto key = static_cast<std::string>(it.key()->as_string());
            dict[py::str(key)] = from_object(document, key);
        }
        return std::move(dict);
    } else {
        py::list list;
        for (uint32_t i = 0; i < document.count(); ++i) {
            list.append(from_object(document, i));
        }
        return std::move(list);
    }
    return py::none();
}

template <class TKey>
auto from_object_(const document_view_t &document, const TKey &key) -> py::object {
    if (document.is_null(key)) {
        return py::none();
    } else if (document.is_bool(key)) {
        return py::bool_(document.get_as<bool>(key));
    } else if (document.is_ulong(key)) {
        return py::int_(document.get_as<ulong>(key));
    } else if (document.is_long(key)) {
        return py::int_(document.get_as<long>(key));
    } else if (document.is_float(key)) {
        return py::float_(document.get_as<float>(key));
    } else if (document.is_double(key)) {
        return py::float_(document.get_as<double>(key));
    } else if (document.is_string(key)) {
        return py::str(document.get_as<std::string>(key));
    } else if (document.is_array(key)) {
        py::list list;
        auto array = document.get_array(key);
        for (uint32_t i = 0; i < array.count(); ++i) {
            list.append(from_object_<uint32_t>(array, i));
        }
        return std::move(list);
    } else if (document.is_dict(key)) {
        py::dict dict;
        auto sub_doc = document.get_dict(key);
        for (auto it = sub_doc.begin(); it; ++it) {
            auto key = static_cast<std::string>(it.key()->as_string());
            dict[py::str(key)] = from_object_<std::string>(sub_doc, key);
        }
        return std::move(dict);
    }
    return py::none();
}

auto from_object(const document_view_t &document, const std::string &key) -> py::object {
    return from_object_<std::string>(document, std::string(key));
}

auto from_object(const document_view_t &document, uint32_t index) -> py::object {
    return from_object_<uint32_t>(document, index);
}

void update_document(const py::handle& source, document_t& target) {
    for (const py::handle key : source) {
        //std::cerr << py::str(key).cast<std::string>()  << std::endl;
        update_document_inner(py::str(key).cast<std::string>(), source[key], target);
    }

    ///throw std::runtime_error("update_document not implemented for this type of object: " + py::repr(source).cast<std::string>());
}

max_stars_repo_name: cyberduckninja/RocketJoe

max_issues_repo_name: cyberduckninja/RocketJoe

max_forks_repo_name: cyberduckninja/RocketJoe


text:
// Copyright 2018 The SAF Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <gtest/gtest.h>
#include <boost/algorithm/string/replace.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <caffe/caffe.hpp>
#include <opencv2/opencv.hpp>

#include <assert.h>
#include <iostream>
#include <string>
#include <vector>

#include "camera/camera.h"
#include "common/serialization.h"
#include "common/types.h"
#include "model/model.h"
#include "model/model_manager.h"
#include "operator/neural_net_evaluator.h"
#include "stream/frame.h"
#include "stream/stream.h"

constexpr auto ALPHA = 0.001f;

constexpr auto CHANNELS = 3;
constexpr auto WIDTH = 224;
constexpr auto HEIGHT = 224;
const auto SHAPE = cv::Size(WIDTH, HEIGHT);

constexpr auto INPUT_IMAGE_FILEPATH = "data/input.jpg";
constexpr auto NETWORK_FILEPATH = "data/mobilenet/mobilenet_deploy.prototxt";
constexpr auto WEIGHTS_FILEPATH = "/tmp/mobilenet.caffemodel";

const std::vector<std::string> OUTPUTS = {
    "conv1",       "conv2_1/dw",  "conv2_1/sep", "conv2_2/dw",  "conv2_2/sep",
    "conv3_1/dw",  "conv3_1/sep", "conv3_2/dw",  "conv3_2/sep", "conv4_1/dw",
    "conv4_1/sep", "conv4_2/dw",  "conv4_2/sep", "conv5_1/dw",  "conv5_1/sep",
    "conv5_2/dw",  "conv5_2/sep", "conv5_3/dw",  "conv5_3/sep", "conv5_4/dw",
    "conv5_4/sep", "conv5_5/dw",  "conv5_5/sep", "conv5_6/dw",  "conv5_6/sep",
    "conv6/dw",    "conv6/sep",   "pool6",       "fc7",         "prob"};

bool FloatEqual(float lhs, float rhs) {
  if (lhs < 0) {
    lhs *= -1;
    rhs *= -1;
  }
  return lhs - lhs * ALPHA <= rhs && lhs + lhs * ALPHA >= rhs;
}

void CvMatEqual(cv::Mat lhs, cv::Mat rhs) {
  std::vector<int> cur_idx;
  if (lhs.dims != rhs.dims) {
    return;
  }
  CHECK_EQ(lhs.dims, rhs.dims);
  CHECK_GT(lhs.dims, 0);
  auto lhs_it = lhs.begin<float>();
  auto lhs_end = lhs.end<float>();
  auto rhs_it = rhs.begin<float>();
  auto rhs_end = rhs.end<float>();
  while (lhs_it != lhs_end && rhs_it != rhs_end) {
    CHECK(FloatEqual(*lhs_it, *rhs_it))
        << "Expects: " << *lhs_it << " Found: " << *rhs_it;
    ++lhs_it;
    ++rhs_it;
  }
}

cv::Mat Preprocess(const cv::Mat& img) {
  cv::Size input_geometry_ = cv::Size(WIDTH, HEIGHT);
  // Convert the input image to the input image format of the network.
  cv::Mat sample = img;

  cv::Mat sample_resized;
  if (sample.size() != input_geometry_)
    cv::resize(sample, sample_resized, input_geometry_);
  else
    sample_resized = sample;
  return sample_resized;
}

TEST(TestNneCaffe, TestExtractIntermediateActivationsCaffe) {
  std::ifstream f(WEIGHTS_FILEPATH);
  ASSERT_TRUE(f.good()) << "The Caffe model file \"" << WEIGHTS_FILEPATH
                        << "\" was not found. Download it by executing: "
                        << "curl -o " << WEIGHTS_FILEPATH
                        << " https://raw.githubusercontent.com/cdwat/"
                           "MobileNet-Caffe/master/mobilenet.caffemodel";
  f.close();

  // Construct model
  Shape input_shape(CHANNELS, WIDTH, HEIGHT);
  ModelDesc desc("TestExtractIntermediateActivationsCaffe", MODEL_TYPE_CAFFE,
                 NETWORK_FILEPATH, WEIGHTS_FILEPATH, WIDTH, HEIGHT, "", "prob");
  NeuralNetEvaluator nne(desc, input_shape, 1, OUTPUTS);

  // Configure the mean image
  ModelManager::GetInstance().SetMeanColors(cv::Scalar(104.0, 117.0, 123.0));

  // Read the input
  cv::Mat original_image = cv::imread(INPUT_IMAGE_FILEPATH);
  ASSERT_FALSE(original_image.empty()) << "Image empty. Is a library (i.e. "
                                          "libtensorflow) clobbering libjpeg "
                                          "symbols?";
  cv::Mat preprocessed_image = Preprocess(original_image);

  // Construct frame with input image in it
  auto input_frame = std::make_unique<Frame>();
  input_frame->SetValue(Camera::kCaptureTimeMicrosKey,
                        boost::posix_time::microsec_clock::local_time());
  input_frame->SetValue("frame_id", (unsigned long)0);
  input_frame->SetValue("original_image", original_image);
  input_frame->SetValue("image", preprocessed_image);

  // Prepare stream
  StreamPtr stream = std::make_shared<Stream>();
  nne.SetSource("input", stream, "");

  // We need to set up the StreamReaders before calling Start().
  StreamReader* reader = nne.GetSink()->Subscribe();

  nne.Start();
  stream->PushFrame(std::move(input_frame));
  auto output_frame = reader->PopFrame();
  ASSERT_FALSE(output_frame == nullptr) << "Unable to get frame";
  for (decltype(OUTPUTS.size()) i = 0; i < OUTPUTS.size(); ++i) {
    std::string filename = OUTPUTS.at(i);
    boost::replace_all(filename, "/", ".");
    filename = "data/mobilenet/caffe_ground_truth/" + filename + ".bin";
    // contains the activations of the output layer
    std::ifstream gt_file;
    gt_file.open(filename);
    cv::Mat expected_output;
    boost::archive::binary_iarchive expected_output_archive(gt_file);

    try {
      expected_output_archive >> expected_output;
    } catch (std::exception& e) {
      LOG(INFO) << "Ignoring empty layer\n";
      continue;
    }

    gt_file.close();

    cv::Mat actual_output = output_frame->GetValue<cv::Mat>(OUTPUTS.at(i));
    int num_channel = actual_output.channels();
    int height = actual_output.rows;
    int width = actual_output.cols;
    float* gt_data_ptr = (float*)expected_output.ptr();
    int per_channel_floats = height * width;
    std::vector<cv::Mat> gt_channels;
    for (int i = 0; i < num_channel; ++i) {
      cv::Mat cur_channel(HEIGHT, WIDTH, CV_32F);
      memcpy(cur_channel.data, gt_data_ptr + per_channel_floats * i,
             per_channel_floats * sizeof(float));
      gt_channels.push_back(cur_channel);
    }
    cv::Mat expected_output_transposed;
    cv::merge(gt_channels, expected_output_transposed);
    CvMatEqual(expected_output_transposed, actual_output);
  }
  nne.Stop();
}

max_stars_repo_name: ccanel/saf

max_issues_repo_name: ccanel/saf

max_forks_repo_name: ccanel/saf


text:
/**
 * Copyright (C) 2019 Xilinx, Inc
 *
 * Licensed under the Apache License, Version 2.0 (the "License"). You may
 * not use this file except in compliance with the License. A copy of the
 * License is located 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.
 */

// ------ I N C L U D E   F I L E S -------------------------------------------
// Local - Include Files
#include "SubCmd.h"
#include <iostream>
#include <boost/format.hpp>

#include "XBUtilities.h"
namespace XBU = XBUtilities;

static SubCmdTable cmdTable;

unsigned int
register_subcommand(const std::string &_subCmdName,
                    const std::string & _description,
                    t_subcommand _pSubCommand,
                    bool _isHidden)
{
  if (cmdTable.find(_subCmdName) != cmdTable.end()) {
    XBU::fatal(boost::str(boost::format("Sub-command '%s' already registered.") % _subCmdName));
    exit(1);
  }

  cmdTable[_subCmdName] = SubCmdEntry{_subCmdName, _description, _pSubCommand, _isHidden};
  return 0;
}

const SubCmdEntry *
getSubCmdEntry(const std::string &_sSubCmdName)
{
  if (cmdTable.find(_sSubCmdName) == cmdTable.end()) {
    return nullptr;
  }

  return &cmdTable[_sSubCmdName];
}

const std::map<const std::string, SubCmdEntry> &
getSubCmdsTable()
{
  return cmdTable;
}

max_stars_repo_name: xuhz/XRT

max_issues_repo_name: xuhz/XRT

max_forks_repo_name: xuhz/XRT


text:
#include <StdInc.h>
#include <Hooking.h>

#include <CoreConsole.h>
#include <RageParser.h>

#include <nutsnbolts.h>

#include <CrossBuildRuntime.h>

#include <boost/algorithm/string.hpp>

#include <atArray.h>

static void** g_profileSettings;

#define PS_NAME(s) { HashRageString(s), s }

static std::map<uint32_t, std::string> _profileSettingNames = {
	PS_NAME("PREF_SFX_VOLUME"),
	PS_NAME("PREF_MUSIC_VOLUME_IN_MP"),
	PS_NAME("PREF_MUSIC_VOLUME"),
	PS_NAME("PREF_DIAG_BOOST"),
	PS_NAME("PREF_RADIO_STATION"),
	PS_NAME("PREF_UR_PLAYMODE"),
	PS_NAME("PREF_UR_AUTOSCAN"),
	PS_NAME("PREF_VOICE_OUTPUT"),
	PS_NAME("PREF_VOICE_SPEAKERS"),
	PS_NAME("PREF_SPEAKER_OUTPUT"),
	PS_NAME("PREF_CTRL_SPEAKER"),
	PS_NAME("PREF_CTRL_SPEAKER_HEADPHONE"),
	PS_NAME("PREF_CTRL_SPEAKER_VOL"),
	PS_NAME("PREF_PULSE_HEADSET"),
	PS_NAME("PREF_SS_FRONT"),
	PS_NAME("PREF_SS_REAR"),
	PS_NAME("PREF_AUDIO_MUTE_ON_FOCUS_LOSS"),
	PS_NAME("PREF_RADAR_MODE"),
	PS_NAME("PREF_DISPLAY_HUD"),
	PS_NAME("PREF_RETICULE"),
	PS_NAME("PREF_RETICULE_SIZE"),
	PS_NAME("PREF_DISPLAY_GPS"),
	PS_NAME("PREF_BIG_RADAR"),
	PS_NAME("PREF_BIG_RADAR_NAMES"),
	PS_NAME("PREF_GAMMA"),
	PS_NAME("PREF_SAFEZONE_SIZE"),
	PS_NAME("PREF_DOF"),
	PS_NAME("PREF_SKFX"),
	PS_NAME("PREF_SUBTITLES"),
	PS_NAME("PREF_MEASUREMENT_SYSTEM"),
	PS_NAME("PREF_CURRENT_LANGUAGE"),
	PS_NAME("PREF_GFX_VID_OVERRIDE"),
	PS_NAME("PREF_GFX_DXVERSION"),
	PS_NAME("PREF_VID_SCREEN_TYPE"),
	PS_NAME("PREF_VID_RESOLUTION"),
	PS_NAME("PREF_VID_ASPECT"),
	PS_NAME("PREF_VID_REFRESH"),
	PS_NAME("PREF_VID_ADAPTER"),
	PS_NAME("PREF_VID_MONITOR"),
	PS_NAME("PREF_GFX_FXAA"),
	PS_NAME("PREF_GFX_MSAA"),
	PS_NAME("PREF_GFX_TXAA"),
	PS_NAME("PREF_VID_VSYNC"),
	PS_NAME("PREF_VID_STEREO"),
	PS_NAME("PREF_VID_STEREO_CONVERGENCE"),
	PS_NAME("PREF_VID_STEREO_SEPARATION"),
	PS_NAME("PREF_VID_PAUSE_ON_FOCUS_LOSS"),
	PS_NAME("PREF_GFX_CITY_DENSITY"),
	PS_NAME("PREF_GFX_POP_VARIETY"),
	PS_NAME("PREF_GFX_DIST_SCALE"),
	PS_NAME("PREF_GFX_TEXTURE_QUALITY"),
	PS_NAME("PREF_GFX_SHADER_QUALITY"),
	PS_NAME("PREF_GFX_SHADOW_QUALITY"),
	PS_NAME("PREF_GFX_REFLECTION_QUALITY"),
	PS_NAME("PREF_GFX_REFLECTION_MSAA"),
	PS_NAME("PREF_GFX_WATER_QUALITY"),
	PS_NAME("PREF_GFX_PARTICLES_QUALITY"),
	PS_NAME("PREF_GFX_GRASS_QUALITY"),
	PS_NAME("PREF_GFX_NIGHT_LIGHTS"),
	PS_NAME("PREF_GFX_SHADOW_SOFTNESS"),
	PS_NAME("PREF_GFX_POST_FX"),
	PS_NAME("PREF_GFX_MB_STRENGTH"),
	PS_NAME("PREF_GFX_DOF"),
	PS_NAME("PREF_GFX_ANISOTROPIC_FILTERING"),
	PS_NAME("PREF_GFX_AMBIENT_OCCLUSION"),
	PS_NAME("PREF_GFX_TESSELLATION"),
	PS_NAME("PREF_ADV_GFX_LONG_SHADOWS"),
	PS_NAME("PREF_ADV_GFX_ULTRA_SHADOWS"),
	PS_NAME("PREF_ADV_GFX_HD_FLIGHT"),
	PS_NAME("PREF_ADV_GFX_MAX_LOD"),
	PS_NAME("PREF_ADV_GFX_SHADOWS_DIST_MULT"),
	PS_NAME("PREF_GFX_SCALING"),
	PS_NAME("PREF_REPLAY_MODE"),
	PS_NAME("PREF_REPLAY_MEM_LIMIT"),
	PS_NAME("PREF_REPLAY_AUTO_RESUME_RECORDING"),
	PS_NAME("PREF_REPLAY_AUTO_SAVE_RECORDING"),
	PS_NAME("PREF_VIDEO_UPLOAD_PRIVACY"),
	PS_NAME("PREF_ROCKSTAR_EDITOR_TOOLTIP"),
	PS_NAME("PREF_ROCKSTAR_EDITOR_EXPORT_GRAPHICS_UPGRADE"),
	PS_NAME("PREF_VOICE_ENABLE"),
	PS_NAME("PREF_VOICE_OUTPUT_DEVICE"),
	PS_NAME("PREF_VOICE_OUTPUT_VOLUME"),
	PS_NAME("PREF_VOICE_SOUND_VOLUME"),
	PS_NAME("PREF_VOICE_MUSIC_VOLUME"),
	PS_NAME("PREF_VOICE_TALK_ENABLED"),
	PS_NAME("PREF_VOICE_FEEDBACK"),
	PS_NAME("PREF_VOICE_INPUT_DEVICE"),
	PS_NAME("PREF_VOICE_CHAT_MODE"),
	PS_NAME("PREF_VOICE_MIC_VOLUME"),
	PS_NAME("PREF_VOICE_MIC_SENSITIVITY"),
	PS_NAME("PREF_CONTROLS_CONTEXT"),
	PS_NAME("PREF_TARGET_CONFIG"),
	PS_NAME("PREF_TARGET_CONFIG"),
	PS_NAME("PREF_VIBRATION"),
	PS_NAME("PREF_INVERT_LOOK"),
	PS_NAME("PREF_CONTROL_CONFIG"),
	PS_NAME("PREF_CONTROL_CONFIG_FPS"),
	PS_NAME("PREF_CONTROLLER_SENSITIVITY"),
	PS_NAME("PREF_FPS_LOOK_SENSITIVITY"),
	PS_NAME("PREF_FPS_AIM_SENSITIVITY"),
	PS_NAME("PREF_LOOK_AROUND_SENSITIVITY"),
	PS_NAME("PREF_AIM_DEADZONE"),
	PS_NAME("PREF_FPS_AIM_DEADZONE"),
	PS_NAME("PREF_AIM_ACCELERATION"),
	PS_NAME("PREF_FPS_AIM_ACCELERATION"),
	PS_NAME("PREF_SNIPER_ZOOM"),
	PS_NAME("PREF_CINEMATIC_SHOOTING"),
	PS_NAME("PREF_ALTERNATE_HANDBRAKE"),
	PS_NAME("PREF_ALTERNATE_DRIVEBY"),
	PS_NAME("PREF_CONTROLLER_LIGHT_EFFECT"),
	PS_NAME("PREF_MOUSE_TYPE"),
	PS_NAME("PREF_MOUSE_ON_FOOT_SCALE"),
	PS_NAME("PREF_MOUSE_WEIGHT_SCALE"),
	PS_NAME("PREF_MOUSE_ACCELERATION"),
	PS_NAME("PREF_INVERT_MOUSE"),
	PS_NAME("PREF_KBM_TOGGLE_AIM"),
	PS_NAME("PREF_FPS_DEFAULT_AIM_TYPE"),
	PS_NAME("PREF_MOUSE_DRIVE"),
	PS_NAME("PREF_MOUSE_FLY"),
	PS_NAME("PREF_MOUSE_SUB"),
	PS_NAME("PREF_MOUSE_DRIVING_SCALE"),
	PS_NAME("PREF_MOUSE_PLANE_SCALE"),
	PS_NAME("PREF_MOUSE_HELI_SCALE"),
	PS_NAME("PREF_MOUSE_SUB_SCALE"),
	PS_NAME("PREF_INVERT_MOUSE_FLYING"),
	PS_NAME("PREF_INVERT_MOUSE_SUB"),
	PS_NAME("PREF_SWAP_ROLL_YAW_MOUSE_FLYING"),
	PS_NAME("PREF_MOUSE_AUTOCENTER_BIKE"),
	PS_NAME("PREF_MOUSE_AUTOCENTER_CAR"),
	PS_NAME("PREF_MOUSE_AUTOCENTER_PLANE"),
	PS_NAME("PREF_CONTROLLER_LIGHT_EFFECT"),
	PS_NAME("PREF_FPS_PERSISTANT_VIEW"),
	PS_NAME("PREF_CAMERA_HEIGHT"),
	PS_NAME("PREF_FPS_AUTO_LEVEL"),
	PS_NAME("PREF_FPS_FIELD_OF_VIEW"),
	PS_NAME("PREF_FPS_RAGDOLL"),
	PS_NAME("PREF_FPS_COMBATROLL"),
	PS_NAME("PREF_FPS_HEADBOB"),
	PS_NAME("PREF_FPS_THIRD_PERSON_COVER"),
	PS_NAME("PREF_FPS_VEH_AUTO_CENTER"),
	PS_NAME("PREF_HOOD_CAMERA"),
	PS_NAME("PREF_FPS_RELATIVE_VEHICLE_CAMERA_DRIVEBY_AIMING"),
	PS_NAME("PREF_LANDING_PAGE"),
	PS_NAME("PREF_STARTUP_FLOW"),
	PS_NAME("PREF_AUTOSAVE"),
	PS_NAME("PREF_FACEBOOK_UPDATES"),
	PS_NAME("PREF_FEED_PHONE"),
	PS_NAME("PREF_FEED_STATS"),
	PS_NAME("PREF_FEED_CREW"),
	PS_NAME("PREF_FEED_FRIENDS"),
	PS_NAME("PREF_FEED_SOCIAL"),
	PS_NAME("PREF_FEED_STORE"),
	PS_NAME("PREF_FEED_TOOLTIP"),
	PS_NAME("PREF_FEED_DELAY"),
	PS_NAME("PREF_SIXAXIS_HELI"),
	PS_NAME("PREF_SIXAXIS_BIKE"),
	PS_NAME("PREF_SIXAXIS_BOAT"),
	PS_NAME("PREF_SIXAXIS_RELOAD"),
};

static int* g_prefs;

struct ProfileConVar
{
	ConVar<int> value;
	int lastValue;

	ProfileConVar(const std::string& name, int defaultValue)
		: value(name, ConVar_Archive, defaultValue)
	{
		lastValue = defaultValue;
	}
};

static std::map<int, std::shared_ptr<ProfileConVar>> _profileConVars;

static hook::cdecl_stub<void(int idx, int, int)> _updatePref([]()
{
	if (Is372())
	{
		return (void*)nullptr;
	}

	return hook::get_pattern("83 F9 62 0F 8F ? ? 00 00 83 F9 61 0F", (xbr::IsGameBuildOrGreater<2060>()) ? -0x29 : -0x23);
});

void ProfileSettingsInit()
{
	OnGameFrame.Connect([]()
	{
		if (Is372())
		{
			return;
		}

		if (!*g_profileSettings || !**(void***)g_profileSettings)
		{
			return;
		}

		if (_profileConVars.empty())
		{
			auto structureField = rage::GetStructureDefinition(0xA0063C79);
			auto enumeration = structureField->m_members[2]->m_definition->enumData;

			for (auto field = enumeration->fields; field->index != -1 || field->hash != 0; field++)
			{
				auto name = fmt::sprintf("0x%08x", field->hash);

				if (_profileSettingNames.find(field->hash) != _profileSettingNames.end())
				{
					name = _profileSettingNames[field->hash].substr(5);

					boost::algorithm::to_lower(name);

					while (name.find('_') != std::string::npos)
					{
						auto undPos = name.find('_');
						name = name.substr(0, undPos) + (char)toupper(name[undPos + 1]) + name.substr(undPos + 2);
					}
				}

				name = "profile_" + name;

				// profile_vidMonitor pointing to an invalid index will crash the game when opening settings, and
				// the game doesn't use the profile setting as authoritative anyway
				if (name == "profile_vidMonitor")
				{
					continue;
				}

				// profile_gfx* is also a pretty bad one
				if (name.find("profile_gfx") == 0)
				{
					continue;
				}

				auto setting = g_prefs[field->index];
				_profileConVars[field->index] = std::make_shared<ProfileConVar>(name, setting);
			}
		}

		for (auto& pair : _profileConVars)
		{
			int val = pair.second->value.GetValue();

			// if the pref changed, but the convar didn't, update convar with pref value
			if (g_prefs[pair.first] != val && pair.second->lastValue == val)
			{
				val = g_prefs[pair.first];
				pair.second->value.GetHelper()->SetRawValue(val);
			}

			// if the convar changed, update pref with convar value
			if (pair.second->lastValue != val)
			{
				if (val != -999)
				{
					g_prefs[pair.first] = val;
					_updatePref(pair.first, 2, -1);
				}

				pair.second->lastValue = val;
			}
		}
	});
}

static bool (*g_orig_parSettingsLoad)(void* parManager, const char* filename, const char* ext, void* outStruct, void* handle);

static bool parser_SettingsLoad(void* parManager, const char* filename, const char* ext, char* outStruct, void* handle)
{
	bool rv = g_orig_parSettingsLoad(parManager, filename, ext, outStruct, handle);

	if (rv)
	{
		int& shadowQuality = *(int*)(outStruct + 40);

		if (shadowQuality < 0 || shadowQuality > 3)
		{
			shadowQuality = 1;
		}
	}

	return rv;
}

static HookFunction hookFunction([]()
{
	g_prefs = hook::get_address<int*>(hook::get_pattern("8D 0C 9B 8B 14 AA 8D 3C 4A 83 F8 FF 0F 84", -4));
	g_profileSettings = hook::get_address<void**>(hook::get_pattern("44 38 7B 20 0F 84 ? ? 00 00 41 8D 7F 02", -4));

	// reset shadow quality to 'normal' if it has had -1 saved
	{
		auto location = hook::get_pattern("4C 8B C7 48 89 44 24 20 E8 ? ? ? ? 84 C0 75 14", 8);
		hook::set_call(&g_orig_parSettingsLoad, location);
		hook::call(location, parser_SettingsLoad);
	}

	// Patches enabling ShadowQuality=OFF in pausemenu
	//
    // 8D 4B 42      lea     ecx, [rbx+42h]
    // FF CA         dec     edx    <---------------
	hook::nop(hook::get_pattern<unsigned char>("8D 4B 42 FF CA", 3), 2);

	// 8B 45 88      mov     eax, [rbp+0D0h+var_148]
    // FF C8         dec     eax   <--------------
    // 3B C1         cmp     eax, ecx
	hook::nop(hook::get_pattern<unsigned char>("8B 45 ? FF C8 3B C1", 3), 2);

	// 8B 44 24 68   mov     eax, [rsp+300h+var_298]
    // FF C8         dec     eax   <----------------
    // 3B C1         cmp     eax, ecx
	hook::nop(hook::get_pattern<unsigned char>("8B 44 ? ? FF C8 3B C1", 4), 2);

	// *This is where the Game converts the value from profile/preferences in the pausemenu to the CGraphicsSettings in the CSettingsManager*
	// 89 43 5C             mov     [rbx+5Ch], eax
    // 8B 05 04 E3 ED 01    mov     eax, cs:pref_shadowQuality
    // FF C0                inc     eax  <---------------
	hook::nop(hook::get_pattern<unsigned char>("89 43 ? 8B 05 ? ? ? ? FF C0 89", 9), 2);

	// Most of the checks are done via the game's internal settings, but there is one here in the pausemenu for another option(#93)
	// 83 3D 92 A2 EC 01 02   cmp     cs:pref_shadowQuality, 2  <--------------- (this should be 3 now)
	// 41 0F 9D C4            setnl   r12b
	unsigned char *cmp2 = hook::get_pattern<unsigned char>("83 3D ? ? ? ? 02 41 0F 9D C4", 6);
	hook::put<uint8_t>(cmp2, 0x03);

	// Crash fix (connecticut-texas-carbon) for `_updatePref()` (settings->display->safezone-size)
	// The game doesn't check for nullptr here, but does in other places...

	// Conveniently, there is a function [1604]sub_14018014C() that checks null and sets=1 for us
	unsigned char* checkAndSetFuncAddr = hook::get_pattern<unsigned char>("48 8B 05 ? ? ? ? 48 85 C0 74 ? C6 80 AC 00 00 00 01 C3");

	if (!xbr::IsGameBuildOrGreater<2372>())
	{
		// 48 8B 05 EB 74 E7 01    mov     rax, cs:qword_14206E448
		// 40 88 B8 AC 00 00 00    mov     [rax+0ACh], dil(value=1)
		unsigned char* crashAddr = hook::get_pattern<unsigned char>("48 8B 05 ? ? ? ? 40 88 B8 AC 00 00 00");
		hook::nop(crashAddr, 14);
		hook::call(crashAddr, checkAndSetFuncAddr);
	}
	else
	{
		// this area was somewhat re-worked in 2372.
		// The pointer is now retrieved via a function ex: auto ptr = GetPointer();
		// And then ptr+172 is set with another Function ex: SetBool172(ptr);
		// however the functions are simple 1-liners, it still doesn't seem to check for null.

		// E8 E2 9A 2A 00                          call    GetPointer
		// 48 8B C8                                mov     rcx, rax
		// E8 C2 0A 2B 00                          call    SetBool172  <-------------------
		// E8 B5 DD 13 00                          call    sub_7FF712DE62B4
		// 48 8B 0D AA 11 E0 01                    mov     rcx, cs:qword_7FF714AA96

		unsigned char* setBool172 = hook::get_pattern<unsigned char>("E8 ? ? ? ? 48 8B C8 E8 ? ? ? ? E8 ? ? ? ? 48 8B 0D", 8);
		hook::call(setBool172, checkAndSetFuncAddr);
	}
});

max_stars_repo_name: thorium-cfx/fivem

max_issues_repo_name: thorium-cfx/fivem

max_forks_repo_name: thorium-cfx/fivem


text:
//---------------------------------------------------------------------------//
//!
//! \file   MonteCarlo_Electroatom.hpp
//! \author Luke Kersting
//! \brief  The electroatom base class declaration
//!
//---------------------------------------------------------------------------//

#ifndef MONTE_CARLO_ELECTROATOM_HPP
#define MONTE_CARLO_ELECTROATOM_HPP

// Std Lib Includes
#include <string>

// Boost Includes
#include <boost/unordered_map.hpp>
#include <boost/unordered_set.hpp>

// Trilinos Includes
#include <Teuchos_Array.hpp>
#include <Teuchos_ScalarTraits.hpp>

// FRENSIE Includes
#include "MonteCarlo_ElectroatomicReactionType.hpp"
#include "MonteCarlo_ElectroatomicReaction.hpp"
#include "MonteCarlo_AtomicRelaxationModel.hpp"
#include "MonteCarlo_ElectroatomCore.hpp"

namespace MonteCarlo{

//! The atom class for electroatomic reactions
class Electroatom
{

private:

  // Typedef for Teuchos ScalarTraits
  typedef Teuchos::ScalarTraits<double> ST;

public:

  //! Typedef for the reaction map
  typedef ElectroatomCore::ReactionMap ReactionMap;

  //! Typedef for the const reaction map
  typedef ElectroatomCore::ConstReactionMap ConstReactionMap;

  //! Return the reactions that are treated as scattering
  static const boost::unordered_set<ElectroatomicReactionType>&
  getScatteringReactionTypes();

  //! Constructor
  template<typename InterpPolicy>
  Electroatom(
	  const std::string& name,
	  const unsigned atomic_number,
	  const double atomic_weight,
	  const Teuchos::ArrayRCP<double>& energy_grid,
	  const ReactionMap& standard_scattering_reactions,
	  const ReactionMap& standard_absorption_reactions,
	  const Teuchos::RCP<AtomicRelaxationModel>& atomic_relaxation_model,
	  const bool processed_cross_sections,
	  const InterpPolicy policy );

  //! Constructor (from a core)
  Electroatom( const std::string& name,
	     const unsigned atomic_number,
	     const double atomic_weight,
	     const ElectroatomCore& core );

  //! Destructor
  virtual ~Electroatom()
  { /* ... */ }

  //! Return the atom name
  const std::string& getAtomName() const;

  //! Return the nuclide name
  virtual const std::string& getNuclideName() const;

  //! Return the atomic number
  unsigned getAtomicNumber() const;

  //! Return the atomic mass number
  virtual unsigned getAtomicMassNumber() const;

  //! Return the nuclear isomer number
  virtual unsigned getIsomerNumber() const;

  //! Return the atomic weight
  double getAtomicWeight() const;

  //! Return the temperature of the atom
  virtual double getTemperature() const;

  //! Return the total cross section at the desired energy
  double getTotalCrossSection( const double energy ) const;

  //! Return the total absorption cross section at the desired energy
  double getAbsorptionCrossSection( const double energy ) const;

  //! Return the survival probability at the desired energy
  double getSurvivalProbability( const double energy ) const;

  //! Return the cross section for a specific electroatomic reaction
  double getReactionCrossSection(
			        const double energy,
			        const ElectroatomicReactionType reaction ) const;

  //! Collide with a electron
  virtual void collideAnalogue( ElectronState& electron,
				                ParticleBank& bank ) const;

  //! Collide with a electron and survival bias
  virtual void collideSurvivalBias( ElectronState& electron,
				                    ParticleBank& bank ) const;

  //! Return the core
  const ElectroatomCore& getCore() const;

private:

  // Sample an absorption reaction
  void sampleAbsorptionReaction( const double scaled_random_number,
                                 ElectronState& electron,
                                 ParticleBank& bank ) const;

  // Sample a scattering reaction
  void sampleScatteringReaction( const double scaled_random_number,
                                 ElectronState& electron,
                                 ParticleBank& bank ) const;

  // The atom name
  std::string d_name;

  // The atomic number of the atom
  unsigned d_atomic_number;

  // The atomic weight of the atom
  double d_atomic_weight;

  // The electroatom core (storing all reactions, relaxation model)
  ElectroatomCore d_core;
};

// Return the nuclide name
inline const std::string& Electroatom::getNuclideName() const
{
  return this->getAtomName();
}

// Return the atomic mass number
inline unsigned Electroatom::getAtomicMassNumber() const
{
  return 0u;
}

// Return the nuclear isomer number
inline unsigned Electroatom::getIsomerNumber() const
{
  return 0u;
}

// Return the temperature of the atom
/*! \details This information is irrelevant for electroatomic reactions. However,
 * it my be important for photonuclear reactions where Doppler broadening of
 * cross sections may be necessary.
 */
inline double Electroatom::getTemperature() const
{
  return 0.0;
}

// Return the core
inline const ElectroatomCore& Electroatom::getCore() const
{
  return d_core;
}

} // end MonteCarlo namespace

//---------------------------------------------------------------------------//
// Template Includes
//---------------------------------------------------------------------------//

#include "MonteCarlo_Electroatom_def.hpp"

//---------------------------------------------------------------------------//

#endif // end MONTE_CARLO_ELECTROATOM_HPP

//---------------------------------------------------------------------------//
// end MonteCarlo_Electroatom.hpp
//---------------------------------------------------------------------------//


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

#include <boost/date_time/gregorian/gregorian.hpp>

#include "Tudat/Astrodynamics/BasicAstrodynamics/physicalConstants.h"

#include "Tudat/Astrodynamics/BasicAstrodynamics/timeConversions.h"

namespace tudat
{
namespace basic_astrodynamics
{

//! Compute number of seconds since a reference Julian day.
double convertJulianDayToSecondsSinceEpoch( const double julianDay,
                                            const double epochSinceJulianDayZero )
{
    return ( julianDay - epochSinceJulianDayZero ) * physical_constants::JULIAN_DAY;
}

//! Compute Julian day from seconds since reference Julian day epoch.
double convertSecondsSinceEpochToJulianDay( const double secondsSinceEpoch,
                                            const double epochSinceJulianDayZero )
{
    return ( secondsSinceEpoch / physical_constants::JULIAN_DAY + epochSinceJulianDayZero );
}

//! Compute the Julian day from the calendar date and time.
double convertCalendarDateToJulianDay( const int calendarYear,
                                       const int calendarMonth,
                                       const int calendarDay,
                                       const int calendarHour,
                                       const int calendarMinutes,
                                       const double calendarSeconds )
{
    // Calculate julian day of calendar date.
    double julianDay = boost::gregorian::date( calendarYear, calendarMonth, calendarDay ).julian_day( );

    //Compute day fraction
    const double dayFraction = static_cast< double >( calendarHour ) / 24.0 +
                               static_cast< double >( calendarMinutes ) / ( 24.0 * 60.0 ) +
                               calendarSeconds / ( 24.0 * 3600.0 );

    // Compute Julian day by adding day fraction and subtracting 0.5 to reference to midnight
    // instead of noon..
    return julianDay + dayFraction - 0.5;
}

} // namespace basic_astrodynamics
} // namespace tudat

max_stars_repo_name: JPelamatti/ThesisTUDAT

max_issues_repo_name: JPelamatti/ThesisTUDAT

max_forks_repo_name: JPelamatti/ThesisTUDAT


text:
// Copyright (c) 2017 The Zcash developers
// Copyright (c) 2017-2020 The LitecoinZ Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or https://www.opensource.org/licenses/mit-license.php .

#include <core_io.h>
#include <key_io.h>
#include <rpc/protocol.h>
#include <rpc/server.h>
#include <rpc/util.h>
#include <script/script.h>
#include <script/standard.h>
#include <sync.h>
#include <util/system.h>
#include <util/time.h>
#include <validation.h>
#include <wallet/paymentdisclosure.h>
#include <wallet/paymentdisclosuredb.h>
#include <wallet/rpcwallet.h>
#include <wallet/wallet.h>
#include <zcash/JoinSplit.hpp>
#include <zcash/Note.hpp>
#include <zcash/NoteEncryption.hpp>

#include <fstream>
#include <stdint.h>

#include <boost/algorithm/string.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>

#include <univalue.h>

/**
 * RPC call to generate a payment disclosure
 */
UniValue z_getpaymentdisclosure(const JSONRPCRequest& request)
{
    std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
    CWallet* const pwallet = wallet.get();

    if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
        return NullUniValue;
    }

            RPCHelpMan{"z_getpaymentdisclosure",
                "\nGenerate a payment disclosure for a given joinsplit output.\n",
                {
                    {"txid", RPCArg::Type::STR, RPCArg::Optional::NO, ""},
                    {"js_index", RPCArg::Type::STR, RPCArg::Optional::NO, ""},
                    {"output_index", RPCArg::Type::STR, RPCArg::Optional::NO, ""},
                    {"message", RPCArg::Type::STR, RPCArg::Optional::NO, ""},
                },
                RPCResult{
            "\"paymentdisclosure\"  (string) Hex data string, with \"zpd:\" prefix.\n"
                },
                RPCExamples{
            HelpExampleCli("z_getpaymentdisclosure", "\"96f12882450429324d5f3b48630e3168220e49ab7b0f066e5c2935a6b88bb0f2\" 0 0 \"refund\"") +
            "\nAs a JSON-RPC call\n"
            + HelpExampleRpc("z_getpaymentdisclosure", "\"96f12882450429324d5f3b48630e3168220e49ab7b0f066e5c2935a6b88bb0f2\", 0, 0, \"refund\"")
                },
            }.Check(request);

    bool fEnablePaymentDisclosure = gArgs.GetBoolArg("-paymentdisclosure", false);

    if (!fEnablePaymentDisclosure) {
        throw JSONRPCError(RPC_WALLET_ERROR, "Error: payment disclosure is disabled.");
    }

    auto locked_chain = pwallet->chain().lock();
    LOCK(pwallet->cs_wallet);

    EnsureWalletIsUnlocked(pwallet);

    // Check wallet knows about txid
    std::string txid = request.params[0].get_str();
    uint256 hash;
    hash.SetHex(txid);

    CTransactionRef tx;
    uint256 hashBlock;

    // Check txid has been seen
    if (!GetTransaction(hash, tx, Params().GetConsensus(), hashBlock)) {
        throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available about transaction");
    }

    // Check tx has been confirmed
    if (hashBlock.IsNull()) {
        throw JSONRPCError(RPC_MISC_ERROR, "Transaction has not been confirmed yet");
    }

    // Check is mine
    if (!pwallet->mapWallet.count(hash)) {
        throw JSONRPCError(RPC_MISC_ERROR, "Transaction does not belong to the wallet");
    }
    const CWalletTx& wtx = pwallet->mapWallet.at(hash);

    // Check if shielded tx
    if (wtx.tx->vJoinSplit.empty()) {
        throw JSONRPCError(RPC_MISC_ERROR, "Transaction is not a shielded transaction");
    }

    // Check js_index
    size_t js_index = request.params[1].get_int();
    if ((int)js_index < 0 || js_index >= wtx.tx->vJoinSplit.size()) {
        throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid js_index");
    }

    // Check output_index
    int output_index = request.params[2].get_int();
    if (output_index < 0 || output_index >= ZC_NUM_JS_OUTPUTS) {
        throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid output_index");
    }

    // Get message if it exists
    std::string msg;
    if (!request.params[4].isNull()) {
        msg = request.params[3].get_str();
    }

    // Create PaymentDisclosureKey
    PaymentDisclosureKey key = {hash, js_index, (uint8_t)output_index};

    // TODO: In future, perhaps init the DB in init.cpp
    std::shared_ptr<PaymentDisclosureDB> db = PaymentDisclosureDB::sharedInstance();
    PaymentDisclosureInfo info;
    if (!db->Get(key, info)) {
        throw JSONRPCError(RPC_DATABASE_ERROR, "Could not find payment disclosure info for the given joinsplit output");
    }

    PaymentDisclosure pd(wtx.tx->joinSplitPubKey, key, info, msg);
    CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
    ss << pd;
    std::string strHex = HexStr(ss.begin(), ss.end());
    return PAYMENT_DISCLOSURE_BLOB_STRING_PREFIX + strHex;
}

/**
 * RPC call to validate a payment disclosure data blob.
 */
UniValue z_validatepaymentdisclosure(const JSONRPCRequest& request)
{
    std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
    CWallet* const pwallet = wallet.get();

    if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
        return NullUniValue;
    }

            RPCHelpMan{"z_validatepaymentdisclosure",
                "\nValidates a payment disclosure.\n",
                {
                    {"paymentdisclosure", RPCArg::Type::STR, RPCArg::Optional::NO, "Hex data string, with \"zpd:\" prefix."},
                },
                RPCResults{},
                RPCExamples{
            HelpExampleCli("z_validatepaymentdisclosure", "\"zpd:706462ff004c561a0447ba2ec51184e6c204...\"") +
            "\nAs a JSON-RPC call\n"
            + HelpExampleRpc("z_validatepaymentdisclosure", "\"zpd:706462ff004c561a0447ba2ec51184e6c204...\"")
                },
            }.Check(request);

    bool fEnablePaymentDisclosure = gArgs.GetBoolArg("-paymentdisclosure", false);

    if (!fEnablePaymentDisclosure) {
        throw JSONRPCError(RPC_WALLET_ERROR, "Error: payment disclosure is disabled.");
    }

    auto locked_chain = pwallet->chain().lock();
    LOCK(pwallet->cs_wallet);

    EnsureWalletIsUnlocked(pwallet);

    // Verify the payment disclosure input begins with "zpd:" prefix.
    std::string strInput = request.params[0].get_str();
    size_t pos = strInput.find(PAYMENT_DISCLOSURE_BLOB_STRING_PREFIX);
    if (pos != 0) {
        throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, payment disclosure prefix not found.");
    }
    std::string hexInput = strInput.substr(strlen(PAYMENT_DISCLOSURE_BLOB_STRING_PREFIX));
    if (!IsHex(hexInput))
    {
        throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected payment disclosure data in hexadecimal format.");
    }

    // Unserialize the payment disclosure data into an object
    PaymentDisclosure pd;
    CDataStream ss(ParseHex(hexInput), SER_NETWORK, PROTOCOL_VERSION);
    try {
        ss >> pd;
        // too much data is ignored, but if not enough data, exception of type ios_base::failure is thrown,
        // CBaseDataStream::read(): end of data: iostream error
    } catch (const std::exception &e) {
        throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, payment disclosure data is malformed.");
    }

    if (pd.payload.marker != PAYMENT_DISCLOSURE_PAYLOAD_MAGIC_BYTES) {
        throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, payment disclosure marker not found.");
    }

    if (pd.payload.version != PAYMENT_DISCLOSURE_VERSION_EXPERIMENTAL) {
        throw JSONRPCError(RPC_INVALID_PARAMETER, "Payment disclosure version is unsupported.");
    }

    uint256 hash = pd.payload.txid;
    CTransactionRef tx;
    uint256 hashBlock;
    // Check if we have seen the transaction
    if (!GetTransaction(hash, tx, Params().GetConsensus(), hashBlock)) {
        throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available about transaction");
    }

    // Check if the transaction has been confirmed
    if (hashBlock.IsNull()) {
        throw JSONRPCError(RPC_MISC_ERROR, "Transaction has not been confirmed yet");
    }

    // Check if shielded tx
    if (tx->vJoinSplit.empty()) {
        throw JSONRPCError(RPC_MISC_ERROR, "Transaction is not a shielded transaction");
    }

    UniValue errs(UniValue::VARR);
    UniValue o(UniValue::VOBJ);
    o.pushKV("txid", pd.payload.txid.ToString());

    // Check js_index
    if (pd.payload.js >= tx->vJoinSplit.size()) {
        errs.push_back("Payment disclosure refers to an invalid joinsplit index");
    }
    o.pushKV("jsIndex", pd.payload.js);

    if ((int8_t)pd.payload.n < 0 || pd.payload.n >= ZC_NUM_JS_OUTPUTS) {
        errs.push_back("Payment disclosure refers to an invalid output index");
    }
    o.pushKV("outputIndex", pd.payload.n);
    o.pushKV("version", pd.payload.version);
    o.pushKV("onetimePrivKey", pd.payload.esk.ToString());
    o.pushKV("message", pd.payload.message);
    o.pushKV("joinSplitPubKey", tx->joinSplitPubKey.ToString());

    // Verify the payment disclosure was signed using the same key as the transaction i.e. the joinSplitPrivKey.
    uint256 dataToBeSigned = SerializeHash(pd.payload, SER_GETHASH, 0);
    bool sigVerified = (crypto_sign_verify_detached(pd.payloadSig.data(),
        dataToBeSigned.begin(), 32,
        tx->joinSplitPubKey.begin()) == 0);
    o.pushKV("signatureVerified", sigVerified);
    if (!sigVerified) {
        errs.push_back("Payment disclosure signature does not match transaction signature");
    }

    // Check the payment address is valid
    libzcash::SproutPaymentAddress zaddr = pd.payload.zaddr;
    {
        o.pushKV("paymentAddress", EncodePaymentAddress(zaddr));

        try {
            // Decrypt the note to get value and memo field
            JSDescription jsdesc = tx->vJoinSplit[pd.payload.js];
            uint256 h_sig = ZCJoinSplit::h_sig(jsdesc.randomSeed, jsdesc.nullifiers, tx->joinSplitPubKey);

            ZCPaymentDisclosureNoteDecryption decrypter;

            ZCNoteEncryption::Ciphertext ciphertext = jsdesc.ciphertexts[pd.payload.n];

            uint256 pk_enc = zaddr.pk_enc;
            auto plaintext = decrypter.decryptWithEsk(ciphertext, pk_enc, pd.payload.esk, h_sig, pd.payload.n);

            CDataStream ssPlain(SER_NETWORK, PROTOCOL_VERSION);
            ssPlain << plaintext;
            libzcash::SproutNotePlaintext npt;
            ssPlain >> npt;

            std::string memoHexString = HexStr(npt.memo().data(), npt.memo().data() + npt.memo().size());
            o.pushKV("memo", memoHexString);
            o.pushKV("value", ValueFromAmount(npt.value()));

            // Check the blockchain commitment matches decrypted note commitment
            uint256 cm_blockchain =  jsdesc.commitments[pd.payload.n];
            libzcash::SproutNote note = npt.note(zaddr);
            uint256 cm_decrypted = note.cm();
            bool cm_match = (cm_decrypted == cm_blockchain);
            o.pushKV("commitmentMatch", cm_match);
            if (!cm_match) {
                errs.push_back("Commitment derived from payment disclosure does not match blockchain commitment");
            }
        } catch (const std::exception &e) {
            errs.push_back(std::string("Error while decrypting payment disclosure note: ") + std::string(e.what()) );
        }
    }

    bool isValid = errs.empty();
    o.pushKV("valid", isValid);
    if (!isValid) {
        o.pushKV("errors", errs);
    }

    return o;
}

max_stars_repo_name: litecoinz-core/bitcoin

max_issues_repo_name: litecoinz-core/bitcoin

max_forks_repo_name: litecoinz-core/bitcoin