<commit_before>#ifndef COFFEE_MILL_COMMON_TRAJECTORY_HPP
#define COFFEE_MILL_COMMON_TRAJECTORY_HPP
#include <mill/common/Snapshot.hpp>

namespace mill
{

class Trajectory
{
  public:
    using real_type      = double;
    using vector_type    = Vector<real_type, 3>;
    using attribute_type = Attribute;
    using attribute_container_type = std::map<std::string, attribute_type>;
    using snapshot_type  = Snapshot;
    using value_type     = snapshot_type;
    using container_type = std::vector<value_type>;
    using iterator       = typename container_type::iterator;
    using const_iterator = typename container_type::const_iterator;

  public:

    Trajectory() = default;
    ~Trajectory() = default;
    Trajectory(Trajectory const&) = default;
    Trajectory(Trajectory &&)     = default;
    Trajectory& operator=(Trajectory const&) = default;
    Trajectory& operator=(Trajectory &&)     = default;

    Trajectory(std::size_t N): snapshots_(N) {}
    Trajectory(attribute_container_type attr): attributes_(std::move(attr)) {}
    Trajectory(container_type ps)  : snapshots_(std::move(ps))    {}
    Trajectory(const std::vector<snapshot_type>& ss): snapshots_(ss.size())
    {
        std::copy(ss.begin(), ss.end(), snapshots_.begin());
    }

    void clear() {attributes_.clear(); snapshots_.clear(); return;}
    bool empty() const noexcept
    {
        return attributes_.empty() && snapshots_.empty();
    }
    std::size_t size() const noexcept
    {
        return snapshots_.size();
    }

    snapshot_type&       operator[](std::size_t i)       noexcept {return snapshots_[i];}
    snapshot_type const& operator[](std::size_t i) const noexcept {return snapshots_[i];}
    snapshot_type&       at(std::size_t i)       {return snapshots_.at(i);}
    snapshot_type const& at(std::size_t i) const {return snapshots_.at(i);}

    std::optional<snapshot_type> try_at(const std::size_t i) const noexcept
    {
        if(this->snapshots_.size() <= i)
        {
            return std::nullopt;
        }
        return this->snapshots_.at(i);
    }

    std::optional<attribute_type::boolean_type >
    try_boolean (const std::string& name) const noexcept
    {
        if(auto attr = this->try_at(name))
        {
            return attr->try_boolean();
        }
        return std::nullopt;
    }
    std::optional<attribute_type::integer_type >
    try_integer (const std::string& name) const noexcept
    {
        if(auto attr = this->try_at(name))
        {
            return attr->try_integer();
        }
        return std::nullopt;
    }
    std::optional<attribute_type::floating_type>
    try_floating(const std::string& name) const noexcept
    {
        if(auto attr = this->try_at(name))
        {
            return attr->try_floating();
        }
        return std::nullopt;
    }
    std::optional<attribute_type::string_type>
    try_string(const std::string& name) const noexcept
    {
        if(auto attr = this->try_at(name))
        {
            return attr->try_string();
        }
        return std::nullopt;
    }
    std::optional<attribute_type::vector_type>
    try_vector(const std::string& name) const noexcept
    {
        if(auto attr = this->try_at(name))
        {
            return attr->try_vector();
        }
        return std::nullopt;
    }
    std::optional<attribute_type::array_type>
    try_array(const std::string& name) const noexcept
    {
        if(auto attr = this->try_at(name))
        {
            return attr->try_array();
        }
        return std::nullopt;
    }

    attribute_type& operator[](const std::string& name) {return attributes_[name];}

    attribute_type&       at(const std::string& name)       {return attributes_.at(name);}
    attribute_type const& at(const std::string& name) const {return attributes_.at(name);}

    std::optional<attribute_type> try_at(const std::string& name) const noexcept
    {
        if(this->attributes_.count(name) != 0)
        {
            return this->attributes_.at(name);
        }
        return std::nullopt;
    }

    iterator        begin()       noexcept {return snapshots_.begin();}
    iterator        end()         noexcept {return snapshots_.end();}
    const_iterator  begin() const noexcept {return snapshots_.begin();}
    const_iterator  end()   const noexcept {return snapshots_.end();}
    const_iterator cbegin() const noexcept {return snapshots_.begin();}
    const_iterator cend()   const noexcept {return snapshots_.end();}

    attribute_container_type &      attributes()       noexcept {return attributes_;}
    attribute_container_type const& attributes() const noexcept {return attributes_;}
    container_type &      snapshots()       noexcept {return snapshots_;}
    container_type const& snapshots() const noexcept {return snapshots_;}

    void merge_attributes(Trajectory& other)
    {
        attributes_.merge(other.attributes_);
        if(this->size() == other.size())
        {
            for(std::size_t i=0; i<this->size(); ++i)
            {
                this->at(i).merge_attributes(other.at(i));
            }
        }
        return;
    }

  private:
    attribute_container_type attributes_;
    container_type           snapshots_;
};

} // mill
#endif// COFFEE_MILL_COMMON_TRAJECTORY_HPP
<commit_msg>:sparkles: add front/back to Traj<commit_after>#ifndef COFFEE_MILL_COMMON_TRAJECTORY_HPP
#define COFFEE_MILL_COMMON_TRAJECTORY_HPP
#include <mill/common/Snapshot.hpp>

namespace mill
{

class Trajectory
{
  public:
    using real_type      = double;
    using vector_type    = Vector<real_type, 3>;
    using attribute_type = Attribute;
    using attribute_container_type = std::map<std::string, attribute_type>;
    using snapshot_type  = Snapshot;
    using value_type     = snapshot_type;
    using container_type = std::vector<value_type>;
    using iterator       = typename container_type::iterator;
    using const_iterator = typename container_type::const_iterator;

  public:

    Trajectory() = default;
    ~Trajectory() = default;
    Trajectory(Trajectory const&) = default;
    Trajectory(Trajectory &&)     = default;
    Trajectory& operator=(Trajectory const&) = default;
    Trajectory& operator=(Trajectory &&)     = default;

    Trajectory(std::size_t N): snapshots_(N) {}
    Trajectory(attribute_container_type attr): attributes_(std::move(attr)) {}
    Trajectory(container_type ps)  : snapshots_(std::move(ps))    {}
    Trajectory(const std::vector<snapshot_type>& ss): snapshots_(ss.size())
    {
        std::copy(ss.begin(), ss.end(), snapshots_.begin());
    }

    void clear() {attributes_.clear(); snapshots_.clear(); return;}
    bool empty() const noexcept
    {
        return attributes_.empty() && snapshots_.empty();
    }
    std::size_t size() const noexcept
    {
        return snapshots_.size();
    }

    snapshot_type&       operator[](std::size_t i)       noexcept {return snapshots_[i];}
    snapshot_type const& operator[](std::size_t i) const noexcept {return snapshots_[i];}
    snapshot_type&       at(std::size_t i)       {return snapshots_.at(i);}
    snapshot_type const& at(std::size_t i) const {return snapshots_.at(i);}

    snapshot_type&       front()       noexcept {return snapshots_.front();}
    snapshot_type const& front() const noexcept {return snapshots_.front();}
    snapshot_type&       back()        noexcept {return snapshots_.back();}
    snapshot_type const& back()  const noexcept {return snapshots_.back();}

    std::optional<snapshot_type> try_at(const std::size_t i) const noexcept
    {
        if(this->snapshots_.size() <= i)
        {
            return std::nullopt;
        }
        return this->snapshots_.at(i);
    }

    std::optional<attribute_type::boolean_type >
    try_boolean (const std::string& name) const noexcept
    {
        if(auto attr = this->try_at(name))
        {
            return attr->try_boolean();
        }
        return std::nullopt;
    }
    std::optional<attribute_type::integer_type >
    try_integer (const std::string& name) const noexcept
    {
        if(auto attr = this->try_at(name))
        {
            return attr->try_integer();
        }
        return std::nullopt;
    }
    std::optional<attribute_type::floating_type>
    try_floating(const std::string& name) const noexcept
    {
        if(auto attr = this->try_at(name))
        {
            return attr->try_floating();
        }
        return std::nullopt;
    }
    std::optional<attribute_type::string_type>
    try_string(const std::string& name) const noexcept
    {
        if(auto attr = this->try_at(name))
        {
            return attr->try_string();
        }
        return std::nullopt;
    }
    std::optional<attribute_type::vector_type>
    try_vector(const std::string& name) const noexcept
    {
        if(auto attr = this->try_at(name))
        {
            return attr->try_vector();
        }
        return std::nullopt;
    }
    std::optional<attribute_type::array_type>
    try_array(const std::string& name) const noexcept
    {
        if(auto attr = this->try_at(name))
        {
            return attr->try_array();
        }
        return std::nullopt;
    }

    attribute_type& operator[](const std::string& name) {return attributes_[name];}

    attribute_type&       at(const std::string& name)       {return attributes_.at(name);}
    attribute_type const& at(const std::string& name) const {return attributes_.at(name);}

    std::optional<attribute_type> try_at(const std::string& name) const noexcept
    {
        if(this->attributes_.count(name) != 0)
        {
            return this->attributes_.at(name);
        }
        return std::nullopt;
    }

    iterator        begin()       noexcept {return snapshots_.begin();}
    iterator        end()         noexcept {return snapshots_.end();}
    const_iterator  begin() const noexcept {return snapshots_.begin();}
    const_iterator  end()   const noexcept {return snapshots_.end();}
    const_iterator cbegin() const noexcept {return snapshots_.begin();}
    const_iterator cend()   const noexcept {return snapshots_.end();}

    attribute_container_type &      attributes()       noexcept {return attributes_;}
    attribute_container_type const& attributes() const noexcept {return attributes_;}
    container_type &      snapshots()       noexcept {return snapshots_;}
    container_type const& snapshots() const noexcept {return snapshots_;}

    void merge_attributes(Trajectory& other)
    {
        attributes_.merge(other.attributes_);
        if(this->size() == other.size())
        {
            for(std::size_t i=0; i<this->size(); ++i)
            {
                this->at(i).merge_attributes(other.at(i));
            }
        }
        return;
    }

  private:
    attribute_container_type attributes_;
    container_type           snapshots_;
};

} // mill
#endif// COFFEE_MILL_COMMON_TRAJECTORY_HPP
<|endoftext|>


<commit_before>#pragma once
#include "dedisp.h"
#include <cstdlib>
#include <vector>
#include <string>
#include <sstream>
#include <stdexcept>
#include <data_types/timeseries.hpp>
#include <data_types/filterbank.hpp>
#include <utils/exceptions.hpp>

class Dedisperser {
private:
  dedisp_plan plan;
  Filterbank& filterbank;
  unsigned int num_gpus;
  std::vector<float> dm_list;
  std::vector<dedisp_bool> killmask;

public:
  Dedisperser(Filterbank& filterbank, unsigned int num_gpus=1)
    :filterbank(filterbank), num_gpus(num_gpus)
  {
    killmask.resize(filterbank.get_nchans(),1);
    dedisp_error error = dedisp_create_plan_multi(&plan,
						  filterbank.get_nchans(),
						  filterbank.get_tsamp(),
						  filterbank.get_fch1(),
						  filterbank.get_foff(),
						  num_gpus);
    ErrorChecker::check_dedisp_error(error,"create_plan_multi");
  }

  virtual ~Dedisperser()
  {
    dedisp_destroy_plan(plan);
  }

  void set_dm_list(float* dm_list_ptr, unsigned int ndms)
  {
    dm_list.resize(ndms);
    std::copy(dm_list_ptr, dm_list_ptr+ndms, dm_list.begin());
    dedisp_error error = dedisp_set_dm_list(plan,&dm_list[0],dm_list.size());
    ErrorChecker::check_dedisp_error(error,"set_dm_list");
  }

  void set_dm_list(std::vector<float> dm_list_vec)
  {
    dm_list.resize(dm_list_vec.size());
    std::copy(dm_list_vec.begin(), dm_list_vec.end(), dm_list.begin());
    dedisp_error error = dedisp_set_dm_list(plan,&dm_list[0],dm_list.size());
    ErrorChecker::check_dedisp_error(error,"set_dm_list");
  }

  std::vector<float> get_dm_list(void){
    return dm_list;
  }

  void generate_dm_list(float dm_start, float dm_end,
			float width, float tolerance)
  {
    dedisp_error error = dedisp_generate_dm_list(plan, dm_start, dm_end, width, tolerance);
    ErrorChecker::check_dedisp_error(error,"generate_dm_list");
    dm_list.resize(dedisp_get_dm_count(plan));
    const float* plan_dm_list = dedisp_get_dm_list(plan);
    std::copy(plan_dm_list,plan_dm_list+dm_list.size(),dm_list.begin());
  }

  void set_killmask(std::vector<int> killmask_in)
  {
    killmask.swap(killmask_in);
    dedisp_error error = dedisp_set_killmask(plan,&killmask[0]);
    ErrorChecker::check_dedisp_error(error,"set_killmask");
  }

  void set_killmask(std::string filename)
  {
    std::ifstream infile;
    std::string str;
    killmask.clear();
    infile.open(filename.c_str(),std::ifstream::in | std::ifstream::binary);
    ErrorChecker::check_file_error(infile,filename);

    int ii=0;
    while(!infile.eof()&&ii<filterbank.get_nchans()){
      std::getline(infile, str);
      killmask.push_back(std::atoi(str.c_str()));
      ii++;
    }

    if (killmask.size() != filterbank.get_nchans()){
      std::cerr << "WARNING: killmask is not the same size as nchans" << std::endl;
      std::cerr << killmask.size() <<" != " <<  filterbank.get_nchans() <<  std::endl;
      killmask.resize(filterbank.get_nchans(),1);
    } else {
      dedisp_error error = dedisp_set_killmask(plan,&killmask[0]);
      ErrorChecker::check_dedisp_error(error,"set_killmask");
    }

  }

  //DispersionTrials<unsigned char> dedisperse(void);
/*  DispersionTrials<unsigned char> dedisperse(void)
  {
    size_t max_delay = dedisp_get_max_delay(plan);
    unsigned int out_nsamps = filterbank.get_nsamps()-max_delay;
    size_t output_size = out_nsamps * dm_list.size();
    unsigned char* data_ptr = new unsigned char [output_size];
    dedisp_error error = dedisp_execute(plan,
					filterbank.get_nsamps(),
					filterbank.get_data(),
					filterbank.get_nbits(),
					data_ptr,8,(unsigned)0);

    ErrorChecker::check_dedisp_error(error,"execute");
    DispersionTrials<unsigned char> ddata(data_ptr,out_nsamps,filterbank.get_tsamp(),dm_list);
    return ddata;
  }
*/
  //DispersionTrials<unsigned char> dedisperse(void);
  /**

  Take in a reference for Dedispersion trials, dedisperse and store the data inside its member vector.

  */
  void dedisperse(DispersionTrials<unsigned int>& trials)
  {

    size_t max_delay = dedisp_get_max_delay(plan);
    unsigned int out_nsamps = filterbank.get_nsamps()-max_delay;

    trials.resize(out_nsamps, dm_list);

    dedisp_error error = dedisp_execute(plan,
					filterbank.get_nsamps(),
					filterbank.get_data(),
					filterbank.get_nbits(),
					(unsigned char*)trials.get_data_ptr(),32,(unsigned)0);

    ErrorChecker::check_dedisp_error(error,"execute");

  }
};
<commit_msg>made destructor robust<commit_after>#pragma once
#include "dedisp.h"
#include <cstdlib>
#include <vector>
#include <string>
#include <sstream>
#include <stdexcept>
#include <data_types/timeseries.hpp>
#include <data_types/filterbank.hpp>
#include <utils/exceptions.hpp>

class Dedisperser {
private:
  dedisp_plan plan;
  Filterbank& filterbank;
  unsigned int num_gpus;
  std::vector<float> dm_list;
  std::vector<dedisp_bool> killmask;

public:
  Dedisperser(Filterbank& filterbank, unsigned int num_gpus=1)
    :filterbank(filterbank), num_gpus(num_gpus)
  {
    killmask.resize(filterbank.get_nchans(),1);
    dedisp_error error = dedisp_create_plan_multi(&plan,
						  filterbank.get_nchans(),
						  filterbank.get_tsamp(),
						  filterbank.get_fch1(),
						  filterbank.get_foff(),
						  num_gpus);
    ErrorChecker::check_dedisp_error(error,"create_plan_multi");
  }

  virtual ~Dedisperser()
  {
    if( plan ) {
      dedisp_destroy_plan(plan);
    }
  }

  void set_dm_list(float* dm_list_ptr, unsigned int ndms)
  {
    dm_list.resize(ndms);
    std::copy(dm_list_ptr, dm_list_ptr+ndms, dm_list.begin());
    dedisp_error error = dedisp_set_dm_list(plan,&dm_list[0],dm_list.size());
    ErrorChecker::check_dedisp_error(error,"set_dm_list");
  }

  void set_dm_list(std::vector<float> dm_list_vec)
  {
    dm_list.resize(dm_list_vec.size());
    std::copy(dm_list_vec.begin(), dm_list_vec.end(), dm_list.begin());
    dedisp_error error = dedisp_set_dm_list(plan,&dm_list[0],dm_list.size());
    ErrorChecker::check_dedisp_error(error,"set_dm_list");
  }

  std::vector<float> get_dm_list(void){
    return dm_list;
  }

  void generate_dm_list(float dm_start, float dm_end,
			float width, float tolerance)
  {
    dedisp_error error = dedisp_generate_dm_list(plan, dm_start, dm_end, width, tolerance);
    ErrorChecker::check_dedisp_error(error,"generate_dm_list");
    dm_list.resize(dedisp_get_dm_count(plan));
    const float* plan_dm_list = dedisp_get_dm_list(plan);
    std::copy(plan_dm_list,plan_dm_list+dm_list.size(),dm_list.begin());
  }

  void set_killmask(std::vector<int> killmask_in)
  {
    killmask.swap(killmask_in);
    dedisp_error error = dedisp_set_killmask(plan,&killmask[0]);
    ErrorChecker::check_dedisp_error(error,"set_killmask");
  }

  void set_killmask(std::string filename)
  {
    std::ifstream infile;
    std::string str;
    killmask.clear();
    infile.open(filename.c_str(),std::ifstream::in | std::ifstream::binary);
    ErrorChecker::check_file_error(infile,filename);

    int ii=0;
    while(!infile.eof()&&ii<filterbank.get_nchans()){
      std::getline(infile, str);
      killmask.push_back(std::atoi(str.c_str()));
      ii++;
    }

    if (killmask.size() != filterbank.get_nchans()){
      std::cerr << "WARNING: killmask is not the same size as nchans" << std::endl;
      std::cerr << killmask.size() <<" != " <<  filterbank.get_nchans() <<  std::endl;
      killmask.resize(filterbank.get_nchans(),1);
    } else {
      dedisp_error error = dedisp_set_killmask(plan,&killmask[0]);
      ErrorChecker::check_dedisp_error(error,"set_killmask");
    }

  }

  //DispersionTrials<unsigned char> dedisperse(void);
/*  DispersionTrials<unsigned char> dedisperse(void)
  {
    size_t max_delay = dedisp_get_max_delay(plan);
    unsigned int out_nsamps = filterbank.get_nsamps()-max_delay;
    size_t output_size = out_nsamps * dm_list.size();
    unsigned char* data_ptr = new unsigned char [output_size];
    dedisp_error error = dedisp_execute(plan,
					filterbank.get_nsamps(),
					filterbank.get_data(),
					filterbank.get_nbits(),
					data_ptr,8,(unsigned)0);

    ErrorChecker::check_dedisp_error(error,"execute");
    DispersionTrials<unsigned char> ddata(data_ptr,out_nsamps,filterbank.get_tsamp(),dm_list);
    return ddata;
  }
*/
  //DispersionTrials<unsigned char> dedisperse(void);
  /**

  Take in a reference for Dedispersion trials, dedisperse and store the data inside its member vector.

  */
  void dedisperse(DispersionTrials<unsigned int>& trials)
  {

    size_t max_delay = dedisp_get_max_delay(plan);
    unsigned int out_nsamps = filterbank.get_nsamps()-max_delay;

    trials.resize(out_nsamps, dm_list);

    dedisp_error error = dedisp_execute(plan,
					filterbank.get_nsamps(),
					filterbank.get_data(),
					filterbank.get_nbits(),
					(unsigned char*)trials.get_data_ptr(),32,(unsigned)0);

    ErrorChecker::check_dedisp_error(error,"execute");

  }
};
<|endoftext|>


<commit_before>/* $Id$
Author: Constantin Loizides <mailto: loizides@ikf.physik.uni-frankfurt.de
*/

#include <stream.h>
#include <libgen.h>
#include "AliL3RootTypes.h"
#include "AliL3Logger.h"
#include "AliL3MemHandler.h"
#include "AliL3AltroMemHandler.h"
#include "AliL3DigitData.h"
#include "AliL3Transform.h"

/**
Example program how to open and read a raw datafile.
In addition it shows, how to store results in an Altro like
data format.
*/

int main(int argc,char **argv)
{
  Int_t slice=0;
  Int_t patch=0;
  Bool_t altroout=kFALSE;
  FILE *afile=0;

  /*
    AliL3Logger l;
    l.Set(AliL3Logger::kAll);
    //l.UseStdout();
    l.UseStream();
  */

  if(argc<2)
    {
      cout<<"Usage: read datafile [slice] [patch] [altrodatfile]"<<endl;
      return -1;
    }
  if (argc>2) {
    slice=atoi(argv[2]);
  }
  if (argc>3) {
    patch=atoi(argv[3]);
  }
  if (argc>4) {
    altroout=kTRUE;
    afile=fopen(argv[4],"w");
  }

  //Loading all specific aliroot version quantities, needed.
  Char_t fname[1024];
  strcpy(fname,argv[1]);
  AliL3Transform::Init(dirname(fname));
  strcpy(fname,argv[1]);

  //Filehandler object:
  AliL3MemHandler file;

  //Give slice and patch information (see filename convention)
  if((patch>=0)&&(patch<6)) file.Init(slice,patch);
  else {
    Int_t srows[2]={0,175};
    file.Init(slice,0,srows);
  }

  //Open the data file:
  if(!file.SetBinaryInput(argv[1]))
    {
      cerr<<"Error opening file "<<argv[1]<<endl;
      return -1;
    }

  //Create an RowData object to access the data
  AliL3DigitRowData *digits=0;
  UInt_t nrows=0;

  //Read the file, and store the data in memory. Return value is a pointer to the data.
  digits = file.CompBinary2Memory(nrows);

  //Create an ALtroMemHandler object
  AliL3AltroMemHandler altromem;
  if(altroout) altroout=altromem.SetASCIIOutput(afile);

  UShort_t time,charge;
  UChar_t pad;
  Int_t row=file.GetRowMin()-1,crows=0,lrow=row;

  for(UInt_t r=0; r<nrows; r++) //Loop over padrows
    {
      //Get the data on this padrow:
      AliL3DigitData *dataPt = (AliL3DigitData*)digits->fDigitData;
      row++;
      if(lrow+1==row) crows++;

      //Loop over all digits on this padrow:
      for(UInt_t ndig=0; ndig<digits->fNDigit; ndig++)
      //for(UInt_t ndig=digits->fNDigit;ndig>0;ndig--)
	{
	  lrow=row;
	  pad = dataPt[ndig].fPad;
	  time = dataPt[ndig].fTime;
	  charge = dataPt[ndig].fCharge;
	  cout << "Padrow " << row << " pad " << (int)pad << " time " <<(int) time << " charge " << (int)charge << endl;
	  if(altroout) altromem.Write(row,pad,charge,time);
	}

      //Move the pointer to the next padrow:
      file.UpdateRowPointer(digits);
    }

  if(afile) {
    altromem.WriteFinal();
    fclose(afile);
  }

  //cerr << "Rows: " << (file.GetRowMax()-file.GetRowMin()+1) << " Consecutive: " << crows << endl;
  return 0;
}

<commit_msg>Changes to read also Altro like data.<commit_after>/* $Id$
Author: Constantin Loizides <mailto: loizides@ikf.physik.uni-frankfurt.de
*/

#include <stream.h>
#include <libgen.h>
#include "AliL3RootTypes.h"
#include "AliL3Logger.h"
#include "AliL3MemHandler.h"
#include "AliL3AltroMemHandler.h"
#include "AliL3DigitData.h"
#include "AliL3Transform.h"

/**
Example program how to open and read a raw datafile.
In addition it shows, how to store (and read) the
digits in an Altro like data format.
*/

int main(int argc,char **argv)
{
  Int_t slice=0;
  Int_t patch=0;
  Bool_t altroout=kFALSE;
  FILE *afile=0;

  //AliL3Logger l;
  //l.Set(AliL3Logger::kAll);
  //l.UseStdout();
  //l.UseStream();

  if(argc<2)
    {
      cout<<"Usage: read datafile [slice] [patch] [altrodatfile]"<<endl;
      return -1;
    }
  if (argc>2) {
    slice=atoi(argv[2]);
  }
  if (argc>3) {
    patch=atoi(argv[3]);
  }
  if (argc>4) {
    altroout=kTRUE;
    afile=fopen(argv[4],"w");
  }

  //Loading all specific aliroot version quantities, needed.
  Char_t fname[1024];
  strcpy(fname,argv[1]);
  AliL3Transform::Init(dirname(fname));
  strcpy(fname,argv[1]);

  //Filehandler object:
  AliL3MemHandler file;

  //Give slice and patch information (see filename convention)
  if((patch>=0)&&(patch<6)) file.Init(slice,patch);
  else {
    Int_t srows[2]={0,175};
    patch=0;
    file.Init(slice,patch,srows);
  }

  //Open the data file:
  if(!file.SetBinaryInput(argv[1]))
    {
      cerr<<"Error opening file "<<argv[1]<<endl;
      return -1;
    }

  //Create an RowData object to access the data
  AliL3DigitRowData *digits=0;
  UInt_t nrows=0;

  //Read the file, and store the data in memory. Return value is a pointer to the data.
  digits = file.CompBinary2Memory(nrows);

  //Create an ALtroMemHandler object
  AliL3AltroMemHandler altromem;
  if(altroout) altroout=altromem.SetASCIIOutput(afile);

  UShort_t time,charge;
  UChar_t pad;
  Int_t row=file.GetRowMin()-1,crows=0,lrow=row;

  for(UInt_t r=0; r<nrows; r++) //Loop over padrows
    {
      //Get the data on this padrow:
      AliL3DigitData *dataPt = (AliL3DigitData*)digits->fDigitData;
      row++;
      if(lrow+1==row) crows++;

      //Loop over all digits on this padrow:
      for(UInt_t ndig=0; ndig<digits->fNDigit; ndig++)
	{
	  lrow=row;
	  pad = dataPt[ndig].fPad;
	  time = dataPt[ndig].fTime;
	  charge = dataPt[ndig].fCharge;
	  cout << "Padrow " << row << " pad " << (int)pad << " time " <<(int) time << " charge " << (int)charge << endl;
	  if(altroout) altromem.Write(row,pad,time,charge);
	}

      //Move the pointer to the next padrow:
      file.UpdateRowPointer(digits);
    }

  if(afile) {
    altromem.WriteFinal();
    fclose(afile);

#if 0
    //test Altro read
    UShort_t rrow=0,rtime=0,rcharge=0;
    UChar_t rpad=0;
    afile=fopen(argv[4],"r");
    altromem.SetASCIIInput(afile);
    while(altromem.Read(rrow,rpad,rtime,rcharge)){
      cout << "Padrow " << (int)rrow << " pad " << (int)rpad << " time " <<(int)rtime << " charge " << (int)rcharge << endl;
    }
    fclose(afile);
#endif
#if 0
    //test Altro read sequence
    UShort_t rrow=0,rtime=0;
    UChar_t rpad=0,n=100,i=100;
    UShort_t *charges=new UShort_t[100];
    afile=fopen(argv[4],"r");
    altromem.SetASCIIInput(afile);
    while(altromem.ReadSequence(rrow,rpad,rtime,i,&charges)){
      cout << "Padrow " << (int)rrow << " pad " << (int)rpad << " time " <<(int)rtime << " charges ";
      for(UChar_t ii=0;ii<i;ii++) cout << (int)charges[ii] << " ";
      cout << endl;
      i=n;
    }
    fclose(afile);
#endif
  }

  //cerr << "Rows: " << (file.GetRowMax()-file.GetRowMin()+1) << " Consecutive: " << crows << endl;
  return 0;
}

<|endoftext|>


<commit_before>/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

/*
 $Log$
 Revision 1.5  2001/05/31 06:58:38  fca
 Patch problem with destructor

 Revision 1.4  2001/05/01 14:47:45  nilsen
 Fixed destructor so that it destroyes the pointers fSegmentation, fResponse,
 fSimulation, and fReconst if they have been allocated. The two TStrings
 fDigClassName and fClustClassName shoud be destroyed automaticaly. This should
 fix a small memory leak associated with digitization and reconstruction.

*/

#include "AliITSDetType.h"
#include "AliITSClusterFinder.h"
#include "AliITSsimulation.h"

ClassImp(AliITSDetType)

AliITSDetType::AliITSDetType(){
    // constructor

    fSegmentation = 0;
    fResponse     = 0;
    fSimulation   = 0;
    fReconst      = 0;
}
//----------------------------------------------------------------------
AliITSDetType::~AliITSDetType(){
    // destructor
  /* PH Commented because AliITSDetType is not the owner
    if(fSegmentation!=0) delete fSegmentation; fSegmentation = 0;
    //    if(fResponse!=0)     delete fResponse;     fResponse     = 0;
    if(fSimulation!=0)   delete fSimulation;   fSimulation   = 0;
    if(fReconst!=0)      delete fReconst;      fReconst      = 0;
  */
}
//______________________________________________________________________
AliITSDetType::AliITSDetType(const AliITSDetType &source){
  //     Copy Constructor

  if(&source == this) return;
  this->fReconst        = source.fReconst;
  this->fSimulation     = source.fSimulation;
  this->fResponse       = source.fResponse;
  this->fSegmentation   = source.fSegmentation;
  this->fDigClassName   = source.fDigClassName;
  this->fClustClassName = source.fClustClassName;
  return;
}
//______________________________________________________________________
AliITSDetType& AliITSDetType::operator=(const AliITSDetType &source){
  //    Assignment operator

  if(&source == this) return *this;
  this->fReconst        = source.fReconst;
  this->fSimulation     = source.fSimulation;
  this->fResponse       = source.fResponse;
  this->fSegmentation   = source.fSegmentation;
  this->fDigClassName   = source.fDigClassName;
  this->fClustClassName = source.fClustClassName;
  return *this;
}
<commit_msg>Destructor reverted after a temporary fix<commit_after>/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

/*
 $Log$
 Revision 1.6  2001/09/07 08:44:43  hristov
 Deletion commented out because AliITSDetType was not the owner

 Revision 1.5  2001/05/31 06:58:38  fca
 Patch problem with destructor

 Revision 1.4  2001/05/01 14:47:45  nilsen
 Fixed destructor so that it destroyes the pointers fSegmentation, fResponse,
 fSimulation, and fReconst if they have been allocated. The two TStrings
 fDigClassName and fClustClassName shoud be destroyed automaticaly. This should
 fix a small memory leak associated with digitization and reconstruction.

*/

#include "AliITSDetType.h"
#include "AliITSClusterFinder.h"
#include "AliITSsimulation.h"

ClassImp(AliITSDetType)

AliITSDetType::AliITSDetType(){
    // constructor

    fSegmentation = 0;
    fResponse     = 0;
    fSimulation   = 0;
    fReconst      = 0;
}
//----------------------------------------------------------------------
AliITSDetType::~AliITSDetType(){
    // destructor
    if(fSegmentation!=0) delete fSegmentation; fSegmentation = 0;
    //    if(fResponse!=0)     delete fResponse;     fResponse     = 0;
    if(fSimulation!=0)   delete fSimulation;   fSimulation   = 0;
    if(fReconst!=0)      delete fReconst;      fReconst      = 0;
}
//______________________________________________________________________
AliITSDetType::AliITSDetType(const AliITSDetType &source){
  //     Copy Constructor

  if(&source == this) return;
  this->fReconst        = source.fReconst;
  this->fSimulation     = source.fSimulation;
  this->fResponse       = source.fResponse;
  this->fSegmentation   = source.fSegmentation;
  this->fDigClassName   = source.fDigClassName;
  this->fClustClassName = source.fClustClassName;
  return;
}
//______________________________________________________________________
AliITSDetType& AliITSDetType::operator=(const AliITSDetType &source){
  //    Assignment operator

  if(&source == this) return *this;
  this->fReconst        = source.fReconst;
  this->fSimulation     = source.fSimulation;
  this->fResponse       = source.fResponse;
  this->fSegmentation   = source.fSegmentation;
  this->fDigClassName   = source.fDigClassName;
  this->fClustClassName = source.fClustClassName;
  return *this;
}
<|endoftext|>


<commit_before><commit_msg>Compiler warning.<commit_after><|endoftext|>


<commit_before>#ifndef GENERIC_COROUTINE_HPP
# define GENERIC_COROUTINE_HPP
# pragma once

#include <cassert>

#include <csetjmp>

#include <functional>

#include <memory>

#include "savestate.hpp"

namespace generic
{

class coroutine
{
  statebuf env_in_;
  statebuf env_out_;

  ::std::function<void()> f_;

  bool running_;
  bool terminated_;

  ::std::unique_ptr<char[]> stack_;

  char* const stack_top_;

public:
  explicit coroutine(::std::size_t const N = 1024 * 1024) :
    running_{false},
    terminated_{true},
    stack_(new char[N]),
    stack_top_(stack_.get() + N)
  {
  }

  template <typename F>
  explicit coroutine(::std::size_t const N, F&& f) :
    coroutine(N)
  {
    assign(::std::forward<F>(f));
  }

  auto terminated() const noexcept
  {
    return terminated_;
  }

  template <typename F>
  void assign(F&& f)
  {
    running_ = terminated_ = false;

    f_ = [this, f = ::std::forward<F>(f)]()
      {
        f(*this);

        running_ = false;

        terminated_ = true;

        yield();
      };
  }

  void yield() noexcept __attribute__ ((noinline))
  {
#if defined(i386) || defined(__i386) || defined(__i386__)
    asm volatile ("":::"eax", "ebx", "ecx", "edx", "esi", "edi");
#elif defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64)
    asm volatile ("":::"rax", "rbx", "rcx", "rdx", "rsi", "rdi", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15");
#endif

    if (!savestate(env_out_))
    {
      restorestate(env_in_);
    }
    // else do nothing
  }

  void resume() noexcept __attribute__ ((noinline))
  {
#if defined(i386) || defined(__i386) || defined(__i386__)
    asm volatile ("":::"eax", "ebx", "ecx", "edx", "esi", "edi");
#elif defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64)
    asm volatile ("":::"rax", "rbx", "rcx", "rdx", "rsi", "rdi", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15");
#endif

    if (savestate(env_in_))
    {
      return;
    }
    else if (running_)
    {
      restorestate(env_out_);
    }
    else
    {
      running_ = true;

      // stack switch
#if defined(i386) || defined(__i386) || defined(__i386__)
      asm volatile(
        "movl %0, %%esp"
        :
        : "m" (stack_top_)
      );
#elif defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64)
      asm volatile(
        "movq %0, %%rsp"
        :
        : "m" (stack_top_)
      );
#else
#error "can't switch stack frame"
#endif

      f_();
    }
  }
};

}

#endif // GENERIC_COROUTINE_HPP
<commit_msg>some fixes<commit_after>#ifndef GENERIC_COROUTINE_HPP
# define GENERIC_COROUTINE_HPP
# pragma once

#include <cassert>

#include <csetjmp>

#include <functional>

#include <memory>

#include "savestate.hpp"

namespace generic
{

class coroutine
{
  statebuf env_in_;
  statebuf env_out_;

  ::std::function<void()> f_;

  bool running_;
  bool terminated_;

  ::std::unique_ptr<char[]> stack_;

  char* const stack_top_;

public:
  explicit coroutine(::std::size_t const N = 512 * 1024) :
    running_{false},
    terminated_{true},
    stack_(new char[N]),
    stack_top_(stack_.get() + N)
  {
  }

  template <typename F>
  explicit coroutine(::std::size_t const N, F&& f) :
    coroutine(N)
  {
    assign(::std::forward<F>(f));
  }

  auto terminated() const noexcept
  {
    return terminated_;
  }

  template <typename F>
  void assign(F&& f)
  {
    running_ = terminated_ = false;

    f_ = [this, f = ::std::forward<F>(f)]()
      {
        f(*this);

        running_ = false;

        terminated_ = true;

        yield();
      };
  }

  void yield() noexcept __attribute__ ((noinline))
  {
#if defined(i386) || defined(__i386) || defined(__i386__)
    asm volatile ("":::"eax", "ebx", "ecx", "edx", "esi", "edi");
#elif defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64)
    asm volatile ("":::"rax", "rbx", "rcx", "rdx", "rsi", "rdi", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15");
#endif

    if (!savestate(env_out_))
    {
      restorestate(env_in_);
    }
    // else do nothing
  }

  void resume() noexcept __attribute__ ((noinline))
  {
#if defined(i386) || defined(__i386) || defined(__i386__)
    asm volatile ("":::"eax", "ebx", "ecx", "edx", "esi", "edi");
#elif defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64)
    asm volatile ("":::"rax", "rbx", "rcx", "rdx", "rsi", "rdi", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15");
#endif

    if (savestate(env_in_))
    {
      return;
    }
    else if (running_)
    {
      restorestate(env_out_);
    }
    else
    {
      running_ = true;

      // stack switch
#if defined(i386) || defined(__i386) || defined(__i386__)
      asm volatile(
        "movl %0, %%esp"
        :
        : "m" (stack_top_)
      );
#elif defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64)
      asm volatile(
        "movq %0, %%rsp"
        :
        : "m" (stack_top_)
      );
#else
#error "can't switch stack frame"
#endif

      f_();
    }
  }
};

}

#endif // GENERIC_COROUTINE_HPP
<|endoftext|>


<commit_before>// Copyright (c) 2009-2021 The Regents of the University of Michigan
// This file is part of the HOOMD-blue project, released under the BSD 3-Clause License.

// Maintainer: jglaser

/*! \file SnapshotSystemData.cc
    \brief Implements SnapshotSystemData related functions
 */

#include "SnapshotSystemData.h"
#include <pybind11/pybind11.h>
namespace py = pybind11;

template<class Real>
void SnapshotSystemData<Real>::replicate(unsigned int nx, unsigned int ny, unsigned int nz)
    {
    assert(nx > 0);
    assert(ny > 0);
    assert(nz > 0);

    // Update global box
    BoxDim old_box = global_box;
    Scalar3 L = global_box.getL();
    L.x *= (Scalar)nx;
    L.y *= (Scalar)ny;
    L.z *= (Scalar)nz;
    global_box.setL(L);

    unsigned int old_n = particle_data.size;
    unsigned int n = nx * ny * nz;

    // replicate snapshots
    particle_data.replicate(nx, ny, nz, old_box, global_box);
    bond_data.replicate(n, old_n);
    angle_data.replicate(n, old_n);
    dihedral_data.replicate(n, old_n);
    improper_data.replicate(n, old_n);
    constraint_data.replicate(n, old_n);
    pair_data.replicate(n, old_n);
    }

template<class Real> void SnapshotSystemData<Real>::wrap()
    {
    for (unsigned int i = 0; i < particle_data.size; i++)
        {
		global_box.wrap(particle_data.pos[i], particle_data.image[i]);
        }
    }

template<class Real>
void SnapshotSystemData<Real>::broadcast_box(std::shared_ptr<MPIConfiguration> mpi_conf)
    {
#ifdef ENABLE_MPI
    if (mpi_conf->getNRanks() > 1)
        {
        bcast(global_box, 0, mpi_conf->getCommunicator());
        bcast(dimensions, 0, mpi_conf->getCommunicator());
        }
#endif
    }

template<class Real>
void SnapshotSystemData<Real>::broadcast(unsigned int root,
                                         std::shared_ptr<ExecutionConfiguration> exec_conf)
    {
#ifdef ENABLE_MPI
    if (exec_conf->getNRanks() > 1)
        {
        bcast(global_box, root, exec_conf->getMPICommunicator());
        bcast(dimensions, root, exec_conf->getMPICommunicator());

        particle_data.bcast(root, exec_conf->getMPICommunicator());
        bcast(map, root, exec_conf->getMPICommunicator());
        bond_data.bcast(root, exec_conf->getMPICommunicator());
        angle_data.bcast(root, exec_conf->getMPICommunicator());
        dihedral_data.bcast(root, exec_conf->getMPICommunicator());
        improper_data.bcast(root, exec_conf->getMPICommunicator());
        constraint_data.bcast(root, exec_conf->getMPICommunicator());
        pair_data.bcast(root, exec_conf->getMPICommunicator());
        }
#endif
    }

template<class Real>
void SnapshotSystemData<Real>::broadcast_all(unsigned int root,
                                             std::shared_ptr<ExecutionConfiguration> exec_conf)
    {
#ifdef ENABLE_MPI
    MPI_Comm hoomd_world = exec_conf->getHOOMDWorldMPICommunicator();
    int n_ranks;
    MPI_Comm_size(hoomd_world, &n_ranks);
    if (n_ranks > 0)
        {
        bcast(global_box, root, hoomd_world);
        bcast(dimensions, root, hoomd_world);

        particle_data.bcast(root, hoomd_world);
        bcast(map, root, hoomd_world);

        bond_data.bcast(root, hoomd_world);
        angle_data.bcast(root, hoomd_world);
        dihedral_data.bcast(root, hoomd_world);
        improper_data.bcast(root, hoomd_world);
        constraint_data.bcast(root, hoomd_world);
        pair_data.bcast(root, hoomd_world);
        }
#endif
    }

// instantiate both float and double snapshots
template struct PYBIND11_EXPORT SnapshotSystemData<float>;
template struct PYBIND11_EXPORT SnapshotSystemData<double>;

void export_SnapshotSystemData(py::module& m)
    {
    py::class_<SnapshotSystemData<float>, std::shared_ptr<SnapshotSystemData<float>>>(
        m,
        "SnapshotSystemData_float")
        .def(py::init<>())
        .def_readwrite("_dimensions", &SnapshotSystemData<float>::dimensions)
        .def_readwrite("_global_box", &SnapshotSystemData<float>::global_box)
        .def_readonly("particles", &SnapshotSystemData<float>::particle_data)
        .def_readonly("bonds", &SnapshotSystemData<float>::bond_data)
        .def_readonly("angles", &SnapshotSystemData<float>::angle_data)
        .def_readonly("dihedrals", &SnapshotSystemData<float>::dihedral_data)
        .def_readonly("impropers", &SnapshotSystemData<float>::improper_data)
        .def_readonly("constraints", &SnapshotSystemData<float>::constraint_data)
        .def_readonly("pairs", &SnapshotSystemData<float>::pair_data)
        .def("replicate", &SnapshotSystemData<float>::replicate)
        .def("_broadcast_box", &SnapshotSystemData<float>::broadcast_box)
        .def("_broadcast", &SnapshotSystemData<float>::broadcast)
        .def("_broadcast_all", &SnapshotSystemData<float>::broadcast_all);

    py::class_<SnapshotSystemData<double>, std::shared_ptr<SnapshotSystemData<double>>>(
        m,
        "SnapshotSystemData_double")
        .def(py::init<>())
        .def_readwrite("_dimensions", &SnapshotSystemData<double>::dimensions)
        .def_readwrite("_global_box", &SnapshotSystemData<double>::global_box)
        .def_readonly("particles", &SnapshotSystemData<double>::particle_data)
        .def_readonly("bonds", &SnapshotSystemData<double>::bond_data)
        .def_readonly("angles", &SnapshotSystemData<double>::angle_data)
        .def_readonly("dihedrals", &SnapshotSystemData<double>::dihedral_data)
        .def_readonly("impropers", &SnapshotSystemData<double>::improper_data)
        .def_readonly("constraints", &SnapshotSystemData<double>::constraint_data)
        .def_readonly("pairs", &SnapshotSystemData<double>::pair_data)
        .def("replicate", &SnapshotSystemData<double>::replicate)
        .def("_broadcast_box", &SnapshotSystemData<double>::broadcast_box)
        .def("_broadcast", &SnapshotSystemData<double>::broadcast)
        .def("_broadcast_all", &SnapshotSystemData<double>::broadcast_all);
    }
<commit_msg>fix compile errors<commit_after>// Copyright (c) 2009-2021 The Regents of the University of Michigan
// This file is part of the HOOMD-blue project, released under the BSD 3-Clause License.

// Maintainer: jglaser

/*! \file SnapshotSystemData.cc
    \brief Implements SnapshotSystemData related functions
 */

#include "SnapshotSystemData.h"
#include <pybind11/pybind11.h>
namespace py = pybind11;

template<class Real>
void SnapshotSystemData<Real>::replicate(unsigned int nx, unsigned int ny, unsigned int nz)
    {
    assert(nx > 0);
    assert(ny > 0);
    assert(nz > 0);

    // Update global box
    BoxDim old_box = global_box;
    Scalar3 L = global_box.getL();
    L.x *= (Scalar)nx;
    L.y *= (Scalar)ny;
    L.z *= (Scalar)nz;
    global_box.setL(L);

    unsigned int old_n = particle_data.size;
    unsigned int n = nx * ny * nz;

    // replicate snapshots
    particle_data.replicate(nx, ny, nz, old_box, global_box);
    bond_data.replicate(n, old_n);
    angle_data.replicate(n, old_n);
    dihedral_data.replicate(n, old_n);
    improper_data.replicate(n, old_n);
    constraint_data.replicate(n, old_n);
    pair_data.replicate(n, old_n);
    }

template<class Real>
void SnapshotSystemData<Real>::wrap()
    {
    for (unsigned int i = 0; i < particle_data.size; i++)
        {
		vec3<double> p = particle_data.pos[i];
		global_box.wrap(p, particle_data.image[i]);
		particle_data.pos[i] = p;
        }
    }

template<class Real>
void SnapshotSystemData<Real>::broadcast_box(std::shared_ptr<MPIConfiguration> mpi_conf)
    {
#ifdef ENABLE_MPI
    if (mpi_conf->getNRanks() > 1)
        {
        bcast(global_box, 0, mpi_conf->getCommunicator());
        bcast(dimensions, 0, mpi_conf->getCommunicator());
        }
#endif
    }

template<class Real>
void SnapshotSystemData<Real>::broadcast(unsigned int root,
                                         std::shared_ptr<ExecutionConfiguration> exec_conf)
    {
#ifdef ENABLE_MPI
    if (exec_conf->getNRanks() > 1)
        {
        bcast(global_box, root, exec_conf->getMPICommunicator());
        bcast(dimensions, root, exec_conf->getMPICommunicator());

        particle_data.bcast(root, exec_conf->getMPICommunicator());
        bcast(map, root, exec_conf->getMPICommunicator());
        bond_data.bcast(root, exec_conf->getMPICommunicator());
        angle_data.bcast(root, exec_conf->getMPICommunicator());
        dihedral_data.bcast(root, exec_conf->getMPICommunicator());
        improper_data.bcast(root, exec_conf->getMPICommunicator());
        constraint_data.bcast(root, exec_conf->getMPICommunicator());
        pair_data.bcast(root, exec_conf->getMPICommunicator());
        }
#endif
    }

template<class Real>
void SnapshotSystemData<Real>::broadcast_all(unsigned int root,
                                             std::shared_ptr<ExecutionConfiguration> exec_conf)
    {
#ifdef ENABLE_MPI
    MPI_Comm hoomd_world = exec_conf->getHOOMDWorldMPICommunicator();
    int n_ranks;
    MPI_Comm_size(hoomd_world, &n_ranks);
    if (n_ranks > 0)
        {
        bcast(global_box, root, hoomd_world);
        bcast(dimensions, root, hoomd_world);

        particle_data.bcast(root, hoomd_world);
        bcast(map, root, hoomd_world);

        bond_data.bcast(root, hoomd_world);
        angle_data.bcast(root, hoomd_world);
        dihedral_data.bcast(root, hoomd_world);
        improper_data.bcast(root, hoomd_world);
        constraint_data.bcast(root, hoomd_world);
        pair_data.bcast(root, hoomd_world);
        }
#endif
    }

// instantiate both float and double snapshots
template struct PYBIND11_EXPORT SnapshotSystemData<float>;
template struct PYBIND11_EXPORT SnapshotSystemData<double>;

void export_SnapshotSystemData(py::module& m)
    {
    py::class_<SnapshotSystemData<float>, std::shared_ptr<SnapshotSystemData<float>>>(
        m,
        "SnapshotSystemData_float")
        .def(py::init<>())
        .def_readwrite("_dimensions", &SnapshotSystemData<float>::dimensions)
        .def_readwrite("_global_box", &SnapshotSystemData<float>::global_box)
        .def_readonly("particles", &SnapshotSystemData<float>::particle_data)
        .def_readonly("bonds", &SnapshotSystemData<float>::bond_data)
        .def_readonly("angles", &SnapshotSystemData<float>::angle_data)
        .def_readonly("dihedrals", &SnapshotSystemData<float>::dihedral_data)
        .def_readonly("impropers", &SnapshotSystemData<float>::improper_data)
        .def_readonly("constraints", &SnapshotSystemData<float>::constraint_data)
        .def_readonly("pairs", &SnapshotSystemData<float>::pair_data)
        .def("replicate", &SnapshotSystemData<float>::replicate)
        .def("_broadcast_box", &SnapshotSystemData<float>::broadcast_box)
        .def("_broadcast", &SnapshotSystemData<float>::broadcast)
        .def("_broadcast_all", &SnapshotSystemData<float>::broadcast_all);

    py::class_<SnapshotSystemData<double>, std::shared_ptr<SnapshotSystemData<double>>>(
        m,
        "SnapshotSystemData_double")
        .def(py::init<>())
        .def_readwrite("_dimensions", &SnapshotSystemData<double>::dimensions)
        .def_readwrite("_global_box", &SnapshotSystemData<double>::global_box)
        .def_readonly("particles", &SnapshotSystemData<double>::particle_data)
        .def_readonly("bonds", &SnapshotSystemData<double>::bond_data)
        .def_readonly("angles", &SnapshotSystemData<double>::angle_data)
        .def_readonly("dihedrals", &SnapshotSystemData<double>::dihedral_data)
        .def_readonly("impropers", &SnapshotSystemData<double>::improper_data)
        .def_readonly("constraints", &SnapshotSystemData<double>::constraint_data)
        .def_readonly("pairs", &SnapshotSystemData<double>::pair_data)
        .def("replicate", &SnapshotSystemData<double>::replicate)
        .def("_broadcast_box", &SnapshotSystemData<double>::broadcast_box)
        .def("_broadcast", &SnapshotSystemData<double>::broadcast)
        .def("_broadcast_all", &SnapshotSystemData<double>::broadcast_all);
    }
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: soundplayer.cxx,v $
 *
 *  $Revision: 1.11 $
 *
 *  last change: $Author: kz $ $Date: 2008-03-07 17:02:53 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_slideshow.hxx"

#include <canvas/debug.hxx>
#include <canvas/verbosetrace.hxx>

#include <comphelper/anytostring.hxx>
#include <cppuhelper/exc_hlp.hxx>

#include <com/sun/star/lang/XMultiComponentFactory.hpp>
#include <com/sun/star/lang/NoSupportException.hpp>
#include <com/sun/star/lang/XComponent.hdl>

#include <tools/urlobj.hxx>

#include <avmedia/mediawindow.hxx>

#include "soundplayer.hxx"

#include <algorithm>

using namespace ::com::sun::star;

namespace slideshow
{
    namespace internal
    {
        // TODO(Q3): Move the whole SoundPlayer class to avmedia.

        boost::shared_ptr<SoundPlayer> SoundPlayer::create(
            EventMultiplexer & rEventMultiplexer,
            const ::rtl::OUString& rSoundURL,
            const uno::Reference< uno::XComponentContext>&  rComponentContext )
        {
            boost::shared_ptr<SoundPlayer> pPlayer(
                new SoundPlayer( rEventMultiplexer,
                                 rSoundURL,
                                 rComponentContext ) );
            rEventMultiplexer.addPauseHandler( pPlayer );
            pPlayer->mThis = pPlayer;
            return pPlayer;
        }

        bool SoundPlayer::handlePause( bool bPauseShow )
        {
            return bPauseShow ? stopPlayback() : startPlayback();
        }

        void SoundPlayer::dispose()
        {
            if( mThis )
            {
                mrEventMultiplexer.removePauseHandler( mThis );
                mThis.reset();
            }

            if( mxPlayer.is() )
            {
                mxPlayer->stop();
                uno::Reference<lang::XComponent> xComponent(
                    mxPlayer, uno::UNO_QUERY );
                if( xComponent.is() )
                    xComponent->dispose();
                mxPlayer.clear();
            }
        }

        SoundPlayer::SoundPlayer(
            EventMultiplexer & rEventMultiplexer,
            const ::rtl::OUString& rSoundURL,
            const uno::Reference< uno::XComponentContext>&  rComponentContext )
            : mrEventMultiplexer(rEventMultiplexer),
              mThis(),
              mxPlayer()
        {
            ENSURE_AND_THROW( rComponentContext.is(),
                              "SoundPlayer::SoundPlayer(): Invalid component context" );

            try
            {
                const INetURLObject aURL( rSoundURL );
                mxPlayer.set( avmedia::MediaWindow::createPlayer(
                                aURL.GetMainURL( INetURLObject::DECODE_UNAMBIGUOUS ) ),
                                uno::UNO_QUERY);
            }
            catch( uno::RuntimeException& )
            {
                throw;
            }
            catch( uno::Exception& )
            {
            }

            if( !mxPlayer.is() )
                throw lang::NoSupportException(
                    rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
                                       "No sound support for ") ) + rSoundURL,
                    uno::Reference<uno::XInterface>() );
        }

        SoundPlayer::~SoundPlayer()
        {
            try
            {
                dispose();
            }
            catch (uno::Exception &) {
                OSL_ENSURE( false, rtl::OUStringToOString(
                                comphelper::anyToString(
                                    cppu::getCaughtException() ),
                                RTL_TEXTENCODING_UTF8 ).getStr() );
            }
        }

        double SoundPlayer::getDuration() const
        {
            if( !mxPlayer.is() )
                return 0.0;

            const double nDuration( mxPlayer->getDuration() );
            if( mxPlayer->isPlaying() )
                return ::std::max( 0.0,
                                   nDuration - mxPlayer->getMediaTime() );
            else
                return nDuration;
        }

        bool SoundPlayer::startPlayback()
        {
            if( !mxPlayer.is() )
                return false;

            if( mxPlayer->isPlaying() )
                mxPlayer->stop();

            mxPlayer->start();
            return true;
        }

        bool SoundPlayer::stopPlayback()
        {
            if( mxPlayer.is() )
                mxPlayer->stop();

            return true;
        }

        void SoundPlayer::setPlaybackLoop( bool bLoop )
        {
            if( mxPlayer.is() )
                mxPlayer->setPlaybackLoop( bLoop );
        }
    }
}
<commit_msg>INTEGRATION: CWS changefileheader (1.11.6); FILE MERGED 2008/03/31 14:00:15 rt 1.11.6.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: soundplayer.cxx,v $
 * $Revision: 1.12 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_slideshow.hxx"

#include <canvas/debug.hxx>
#include <canvas/verbosetrace.hxx>

#include <comphelper/anytostring.hxx>
#include <cppuhelper/exc_hlp.hxx>

#include <com/sun/star/lang/XMultiComponentFactory.hpp>
#include <com/sun/star/lang/NoSupportException.hpp>
#include <com/sun/star/lang/XComponent.hdl>

#include <tools/urlobj.hxx>

#include <avmedia/mediawindow.hxx>

#include "soundplayer.hxx"

#include <algorithm>

using namespace ::com::sun::star;

namespace slideshow
{
    namespace internal
    {
        // TODO(Q3): Move the whole SoundPlayer class to avmedia.

        boost::shared_ptr<SoundPlayer> SoundPlayer::create(
            EventMultiplexer & rEventMultiplexer,
            const ::rtl::OUString& rSoundURL,
            const uno::Reference< uno::XComponentContext>&  rComponentContext )
        {
            boost::shared_ptr<SoundPlayer> pPlayer(
                new SoundPlayer( rEventMultiplexer,
                                 rSoundURL,
                                 rComponentContext ) );
            rEventMultiplexer.addPauseHandler( pPlayer );
            pPlayer->mThis = pPlayer;
            return pPlayer;
        }

        bool SoundPlayer::handlePause( bool bPauseShow )
        {
            return bPauseShow ? stopPlayback() : startPlayback();
        }

        void SoundPlayer::dispose()
        {
            if( mThis )
            {
                mrEventMultiplexer.removePauseHandler( mThis );
                mThis.reset();
            }

            if( mxPlayer.is() )
            {
                mxPlayer->stop();
                uno::Reference<lang::XComponent> xComponent(
                    mxPlayer, uno::UNO_QUERY );
                if( xComponent.is() )
                    xComponent->dispose();
                mxPlayer.clear();
            }
        }

        SoundPlayer::SoundPlayer(
            EventMultiplexer & rEventMultiplexer,
            const ::rtl::OUString& rSoundURL,
            const uno::Reference< uno::XComponentContext>&  rComponentContext )
            : mrEventMultiplexer(rEventMultiplexer),
              mThis(),
              mxPlayer()
        {
            ENSURE_AND_THROW( rComponentContext.is(),
                              "SoundPlayer::SoundPlayer(): Invalid component context" );

            try
            {
                const INetURLObject aURL( rSoundURL );
                mxPlayer.set( avmedia::MediaWindow::createPlayer(
                                aURL.GetMainURL( INetURLObject::DECODE_UNAMBIGUOUS ) ),
                                uno::UNO_QUERY);
            }
            catch( uno::RuntimeException& )
            {
                throw;
            }
            catch( uno::Exception& )
            {
            }

            if( !mxPlayer.is() )
                throw lang::NoSupportException(
                    rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
                                       "No sound support for ") ) + rSoundURL,
                    uno::Reference<uno::XInterface>() );
        }

        SoundPlayer::~SoundPlayer()
        {
            try
            {
                dispose();
            }
            catch (uno::Exception &) {
                OSL_ENSURE( false, rtl::OUStringToOString(
                                comphelper::anyToString(
                                    cppu::getCaughtException() ),
                                RTL_TEXTENCODING_UTF8 ).getStr() );
            }
        }

        double SoundPlayer::getDuration() const
        {
            if( !mxPlayer.is() )
                return 0.0;

            const double nDuration( mxPlayer->getDuration() );
            if( mxPlayer->isPlaying() )
                return ::std::max( 0.0,
                                   nDuration - mxPlayer->getMediaTime() );
            else
                return nDuration;
        }

        bool SoundPlayer::startPlayback()
        {
            if( !mxPlayer.is() )
                return false;

            if( mxPlayer->isPlaying() )
                mxPlayer->stop();

            mxPlayer->start();
            return true;
        }

        bool SoundPlayer::stopPlayback()
        {
            if( mxPlayer.is() )
                mxPlayer->stop();

            return true;
        }

        void SoundPlayer::setPlaybackLoop( bool bLoop )
        {
            if( mxPlayer.is() )
                mxPlayer->setPlaybackLoop( bLoop );
        }
    }
}
<|endoftext|>


<commit_before>//===-- ValueObjectDynamicValue.cpp ---------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "lldb/Core/ValueObjectDynamicValue.h"

// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ValueObjectList.h"
#include "lldb/Core/Value.h"
#include "lldb/Core/ValueObject.h"

#include "lldb/Symbol/ClangASTType.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Symbol/Type.h"
#include "lldb/Symbol/Variable.h"

#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/LanguageRuntime.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"

using namespace lldb_private;

ValueObjectDynamicValue::ValueObjectDynamicValue (ValueObject &parent, lldb::DynamicValueType use_dynamic) :
    ValueObject(parent),
    m_address (),
    m_type_sp(),
    m_use_dynamic (use_dynamic)
{
    m_last_format_mgr_dynamic = use_dynamic;
    SetName (parent.GetName());
}

ValueObjectDynamicValue::~ValueObjectDynamicValue()
{
    m_owning_valobj_sp.reset();
}

lldb::clang_type_t
ValueObjectDynamicValue::GetClangTypeImpl ()
{
    if (m_type_sp)
        return m_value.GetClangType();
    else
        return m_parent->GetClangType();
}

ConstString
ValueObjectDynamicValue::GetTypeName()
{
    const bool success = UpdateValueIfNeeded(false);
    if (success && m_type_sp)
        return ClangASTType::GetConstTypeName (GetClangAST(), GetClangType());
    else
        return m_parent->GetTypeName();
}

uint32_t
ValueObjectDynamicValue::CalculateNumChildren()
{
    const bool success = UpdateValueIfNeeded(false);
    if (success && m_type_sp)
        return ClangASTContext::GetNumChildren (GetClangAST (), GetClangType(), true);
    else
        return m_parent->GetNumChildren();
}

clang::ASTContext *
ValueObjectDynamicValue::GetClangASTImpl ()
{
    const bool success = UpdateValueIfNeeded(false);
    if (success && m_type_sp)
        return m_type_sp->GetClangAST();
    else
        return m_parent->GetClangAST ();
}

size_t
ValueObjectDynamicValue::GetByteSize()
{
    const bool success = UpdateValueIfNeeded(false);
    if (success && m_type_sp)
        return m_value.GetValueByteSize(GetClangAST(), NULL);
    else
        return m_parent->GetByteSize();
}

lldb::ValueType
ValueObjectDynamicValue::GetValueType() const
{
    return m_parent->GetValueType();
}

bool
ValueObjectDynamicValue::UpdateValue ()
{
    SetValueIsValid (false);
    m_error.Clear();

    if (!m_parent->UpdateValueIfNeeded(false))
    {
        // The dynamic value failed to get an error, pass the error along
        if (m_error.Success() && m_parent->GetError().Fail())
            m_error = m_parent->GetError();
        return false;
    }

    // Setting our type_sp to NULL will route everything back through our
    // parent which is equivalent to not using dynamic values.
    if (m_use_dynamic == lldb::eNoDynamicValues)
    {
        m_type_sp.reset();
        return true;
    }

    ExecutionContext exe_ctx (GetExecutionContextRef());
    Target *target = exe_ctx.GetTargetPtr();
    if (target)
    {
        m_data.SetByteOrder(target->GetArchitecture().GetByteOrder());
        m_data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
    }

    // First make sure our Type and/or Address haven't changed:
    Process *process = exe_ctx.GetProcessPtr();
    if (!process)
        return false;

    TypeAndOrName class_type_or_name;
    Address dynamic_address;
    bool found_dynamic_type = false;

    lldb::LanguageType known_type = m_parent->GetObjectRuntimeLanguage();
    if (known_type != lldb::eLanguageTypeUnknown && known_type != lldb::eLanguageTypeC)
    {
        LanguageRuntime *runtime = process->GetLanguageRuntime (known_type);
        if (runtime)
            found_dynamic_type = runtime->GetDynamicTypeAndAddress (*m_parent, m_use_dynamic, class_type_or_name, dynamic_address);
    }
    else
    {
        LanguageRuntime *cpp_runtime = process->GetLanguageRuntime (lldb::eLanguageTypeC_plus_plus);
        if (cpp_runtime)
            found_dynamic_type = cpp_runtime->GetDynamicTypeAndAddress (*m_parent, m_use_dynamic, class_type_or_name, dynamic_address);

        if (!found_dynamic_type)
        {
            LanguageRuntime *objc_runtime = process->GetLanguageRuntime (lldb::eLanguageTypeObjC);
            if (objc_runtime)
                found_dynamic_type = objc_runtime->GetDynamicTypeAndAddress (*m_parent, m_use_dynamic, class_type_or_name, dynamic_address);
        }
    }

    lldb::TypeSP dynamic_type_sp = class_type_or_name.GetTypeSP();

    // Getting the dynamic value may have run the program a bit, and so marked us as needing updating, but we really
    // don't...

    m_update_point.SetUpdated();

    // If we don't have a dynamic type, then make ourselves just a echo of our parent.
    // Or we could return false, and make ourselves an echo of our parent?
    if (!found_dynamic_type)
    {
        ClearDynamicTypeInformation();
        m_type_sp.reset();
        SetValueDidChange(true);
        m_value = m_parent->GetValue();
        m_error = m_value.GetValueAsData (&exe_ctx, GetClangAST(), m_data, 0, GetModule().get());
        return m_error.Success();
    }

    Value old_value(m_value);

    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));

    bool has_changed_type = false;

    if (!m_type_sp)
    {
        m_type_sp = dynamic_type_sp;
        has_changed_type = true;
    }
    else if (dynamic_type_sp != m_type_sp)
    {
        // We are another type, we need to tear down our children...
        m_type_sp = dynamic_type_sp;
        SetValueDidChange (true);
        has_changed_type = true;
    }

    if (has_changed_type)
        ClearDynamicTypeInformation ();

    if (!m_address.IsValid() || m_address != dynamic_address)
    {
        if (m_address.IsValid())
            SetValueDidChange (true);

        // We've moved, so we should be fine...
        m_address = dynamic_address;
        lldb::TargetSP target_sp (GetTargetSP());
        lldb::addr_t load_address = m_address.GetLoadAddress(target_sp.get());
        m_value.GetScalar() = load_address;
    }

    // The type will always be the type of the dynamic object.  If our parent's type was a pointer,
    // then our type should be a pointer to the type of the dynamic object.  If a reference, then the original type
    // should be okay...
    lldb::clang_type_t orig_type = m_type_sp->GetClangForwardType();
    lldb::clang_type_t corrected_type = orig_type;
    if (m_parent->IsPointerType())
        corrected_type = ClangASTContext::CreatePointerType (m_type_sp->GetClangAST(), orig_type);
    else if (m_parent->IsPointerOrReferenceType())
        corrected_type = ClangASTContext::CreateLValueReferenceType (m_type_sp->GetClangAST(), orig_type);

    m_value.SetContext (Value::eContextTypeClangType, corrected_type);

    // Our address is the location of the dynamic type stored in memory.  It isn't a load address,
    // because we aren't pointing to the LOCATION that stores the pointer to us, we're pointing to us...
    m_value.SetValueType(Value::eValueTypeScalar);

    if (has_changed_type && log)
        log->Printf("[%s %p] has a new dynamic type %s",
                    GetName().GetCString(),
                    this,
                    GetTypeName().GetCString());

    if (m_address.IsValid() && m_type_sp)
    {
        // The variable value is in the Scalar value inside the m_value.
        // We can point our m_data right to it.
        m_error = m_value.GetValueAsData (&exe_ctx, GetClangAST(), m_data, 0, GetModule().get());
        if (m_error.Success())
        {
            if (ClangASTContext::IsAggregateType (GetClangType()))
            {
                // this value object represents an aggregate type whose
                // children have values, but this object does not. So we
                // say we are changed if our location has changed.
                SetValueDidChange (m_value.GetValueType() != old_value.GetValueType() || m_value.GetScalar() != old_value.GetScalar());
            }

            SetValueIsValid (true);
            return true;
        }
    }

    // We get here if we've failed above...
    SetValueIsValid (false);
    return false;
}

bool
ValueObjectDynamicValue::IsInScope ()
{
    return m_parent->IsInScope();
}

bool
ValueObjectDynamicValue::SetValueFromCString (const char *value_str, Error& error)
{
    if (!UpdateValueIfNeeded(false))
    {
        error.SetErrorString("unable to read value");
        return false;
    }

    uint64_t my_value = GetValueAsUnsigned(UINT64_MAX);
    uint64_t parent_value = m_parent->GetValueAsUnsigned(UINT64_MAX);

    if (my_value == UINT64_MAX || parent_value == UINT64_MAX)
    {
        error.SetErrorString("unable to read value");
        return false;
    }

    // if we are at an offset from our parent, in order to set ourselves correctly we would need
    // to change the new value so that it refers to the correct dynamic type. we choose not to deal
    // with that - if anything more than a value overwrite is required, you should be using the
    // expression parser instead of the value editing facility
    if (my_value != parent_value)
    {
        // but NULL'ing out a value should always be allowed
        if (strcmp(value_str,"0"))
        {
            error.SetErrorString("unable to modify dynamic value, use 'expression' command");
            return false;
        }
    }

    bool ret_val = m_parent->SetValueFromCString(value_str,error);
    SetNeedsUpdate();
    return ret_val;
}
<commit_msg>Fixing a silly typo in the previous patch<commit_after>//===-- ValueObjectDynamicValue.cpp ---------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "lldb/Core/ValueObjectDynamicValue.h"

// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ValueObjectList.h"
#include "lldb/Core/Value.h"
#include "lldb/Core/ValueObject.h"

#include "lldb/Symbol/ClangASTType.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Symbol/Type.h"
#include "lldb/Symbol/Variable.h"

#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/LanguageRuntime.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"

using namespace lldb_private;

ValueObjectDynamicValue::ValueObjectDynamicValue (ValueObject &parent, lldb::DynamicValueType use_dynamic) :
    ValueObject(parent),
    m_address (),
    m_type_sp(),
    m_use_dynamic (use_dynamic)
{
    m_last_format_mgr_dynamic = use_dynamic;
    SetName (parent.GetName());
}

ValueObjectDynamicValue::~ValueObjectDynamicValue()
{
    m_owning_valobj_sp.reset();
}

lldb::clang_type_t
ValueObjectDynamicValue::GetClangTypeImpl ()
{
    if (m_type_sp)
        return m_value.GetClangType();
    else
        return m_parent->GetClangType();
}

ConstString
ValueObjectDynamicValue::GetTypeName()
{
    const bool success = UpdateValueIfNeeded(false);
    if (success && m_type_sp)
        return ClangASTType::GetConstTypeName (GetClangAST(), GetClangType());
    else
        return m_parent->GetTypeName();
}

uint32_t
ValueObjectDynamicValue::CalculateNumChildren()
{
    const bool success = UpdateValueIfNeeded(false);
    if (success && m_type_sp)
        return ClangASTContext::GetNumChildren (GetClangAST (), GetClangType(), true);
    else
        return m_parent->GetNumChildren();
}

clang::ASTContext *
ValueObjectDynamicValue::GetClangASTImpl ()
{
    const bool success = UpdateValueIfNeeded(false);
    if (success && m_type_sp)
        return m_type_sp->GetClangAST();
    else
        return m_parent->GetClangAST ();
}

size_t
ValueObjectDynamicValue::GetByteSize()
{
    const bool success = UpdateValueIfNeeded(false);
    if (success && m_type_sp)
        return m_value.GetValueByteSize(GetClangAST(), NULL);
    else
        return m_parent->GetByteSize();
}

lldb::ValueType
ValueObjectDynamicValue::GetValueType() const
{
    return m_parent->GetValueType();
}

bool
ValueObjectDynamicValue::UpdateValue ()
{
    SetValueIsValid (false);
    m_error.Clear();

    if (!m_parent->UpdateValueIfNeeded(false))
    {
        // The dynamic value failed to get an error, pass the error along
        if (m_error.Success() && m_parent->GetError().Fail())
            m_error = m_parent->GetError();
        return false;
    }

    // Setting our type_sp to NULL will route everything back through our
    // parent which is equivalent to not using dynamic values.
    if (m_use_dynamic == lldb::eNoDynamicValues)
    {
        m_type_sp.reset();
        return true;
    }

    ExecutionContext exe_ctx (GetExecutionContextRef());
    Target *target = exe_ctx.GetTargetPtr();
    if (target)
    {
        m_data.SetByteOrder(target->GetArchitecture().GetByteOrder());
        m_data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
    }

    // First make sure our Type and/or Address haven't changed:
    Process *process = exe_ctx.GetProcessPtr();
    if (!process)
        return false;

    TypeAndOrName class_type_or_name;
    Address dynamic_address;
    bool found_dynamic_type = false;

    lldb::LanguageType known_type = m_parent->GetObjectRuntimeLanguage();
    if (known_type != lldb::eLanguageTypeUnknown && known_type != lldb::eLanguageTypeC)
    {
        LanguageRuntime *runtime = process->GetLanguageRuntime (known_type);
        if (runtime)
            found_dynamic_type = runtime->GetDynamicTypeAndAddress (*m_parent, m_use_dynamic, class_type_or_name, dynamic_address);
    }
    else
    {
        LanguageRuntime *cpp_runtime = process->GetLanguageRuntime (lldb::eLanguageTypeC_plus_plus);
        if (cpp_runtime)
            found_dynamic_type = cpp_runtime->GetDynamicTypeAndAddress (*m_parent, m_use_dynamic, class_type_or_name, dynamic_address);

        if (!found_dynamic_type)
        {
            LanguageRuntime *objc_runtime = process->GetLanguageRuntime (lldb::eLanguageTypeObjC);
            if (objc_runtime)
                found_dynamic_type = objc_runtime->GetDynamicTypeAndAddress (*m_parent, m_use_dynamic, class_type_or_name, dynamic_address);
        }
    }

    lldb::TypeSP dynamic_type_sp = class_type_or_name.GetTypeSP();

    // Getting the dynamic value may have run the program a bit, and so marked us as needing updating, but we really
    // don't...

    m_update_point.SetUpdated();

    // If we don't have a dynamic type, then make ourselves just a echo of our parent.
    // Or we could return false, and make ourselves an echo of our parent?
    if (!found_dynamic_type)
    {
        if (m_type_sp)
            SetValueDidChange(true);
        ClearDynamicTypeInformation();
        m_type_sp.reset();
        m_value = m_parent->GetValue();
        m_error = m_value.GetValueAsData (&exe_ctx, GetClangAST(), m_data, 0, GetModule().get());
        return m_error.Success();
    }

    Value old_value(m_value);

    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));

    bool has_changed_type = false;

    if (!m_type_sp)
    {
        m_type_sp = dynamic_type_sp;
        has_changed_type = true;
    }
    else if (dynamic_type_sp != m_type_sp)
    {
        // We are another type, we need to tear down our children...
        m_type_sp = dynamic_type_sp;
        SetValueDidChange (true);
        has_changed_type = true;
    }

    if (has_changed_type)
        ClearDynamicTypeInformation ();

    if (!m_address.IsValid() || m_address != dynamic_address)
    {
        if (m_address.IsValid())
            SetValueDidChange (true);

        // We've moved, so we should be fine...
        m_address = dynamic_address;
        lldb::TargetSP target_sp (GetTargetSP());
        lldb::addr_t load_address = m_address.GetLoadAddress(target_sp.get());
        m_value.GetScalar() = load_address;
    }

    // The type will always be the type of the dynamic object.  If our parent's type was a pointer,
    // then our type should be a pointer to the type of the dynamic object.  If a reference, then the original type
    // should be okay...
    lldb::clang_type_t orig_type = m_type_sp->GetClangForwardType();
    lldb::clang_type_t corrected_type = orig_type;
    if (m_parent->IsPointerType())
        corrected_type = ClangASTContext::CreatePointerType (m_type_sp->GetClangAST(), orig_type);
    else if (m_parent->IsPointerOrReferenceType())
        corrected_type = ClangASTContext::CreateLValueReferenceType (m_type_sp->GetClangAST(), orig_type);

    m_value.SetContext (Value::eContextTypeClangType, corrected_type);

    // Our address is the location of the dynamic type stored in memory.  It isn't a load address,
    // because we aren't pointing to the LOCATION that stores the pointer to us, we're pointing to us...
    m_value.SetValueType(Value::eValueTypeScalar);

    if (has_changed_type && log)
        log->Printf("[%s %p] has a new dynamic type %s",
                    GetName().GetCString(),
                    this,
                    GetTypeName().GetCString());

    if (m_address.IsValid() && m_type_sp)
    {
        // The variable value is in the Scalar value inside the m_value.
        // We can point our m_data right to it.
        m_error = m_value.GetValueAsData (&exe_ctx, GetClangAST(), m_data, 0, GetModule().get());
        if (m_error.Success())
        {
            if (ClangASTContext::IsAggregateType (GetClangType()))
            {
                // this value object represents an aggregate type whose
                // children have values, but this object does not. So we
                // say we are changed if our location has changed.
                SetValueDidChange (m_value.GetValueType() != old_value.GetValueType() || m_value.GetScalar() != old_value.GetScalar());
            }

            SetValueIsValid (true);
            return true;
        }
    }

    // We get here if we've failed above...
    SetValueIsValid (false);
    return false;
}

bool
ValueObjectDynamicValue::IsInScope ()
{
    return m_parent->IsInScope();
}

bool
ValueObjectDynamicValue::SetValueFromCString (const char *value_str, Error& error)
{
    if (!UpdateValueIfNeeded(false))
    {
        error.SetErrorString("unable to read value");
        return false;
    }

    uint64_t my_value = GetValueAsUnsigned(UINT64_MAX);
    uint64_t parent_value = m_parent->GetValueAsUnsigned(UINT64_MAX);

    if (my_value == UINT64_MAX || parent_value == UINT64_MAX)
    {
        error.SetErrorString("unable to read value");
        return false;
    }

    // if we are at an offset from our parent, in order to set ourselves correctly we would need
    // to change the new value so that it refers to the correct dynamic type. we choose not to deal
    // with that - if anything more than a value overwrite is required, you should be using the
    // expression parser instead of the value editing facility
    if (my_value != parent_value)
    {
        // but NULL'ing out a value should always be allowed
        if (strcmp(value_str,"0"))
        {
            error.SetErrorString("unable to modify dynamic value, use 'expression' command");
            return false;
        }
    }

    bool ret_val = m_parent->SetValueFromCString(value_str,error);
    SetNeedsUpdate();
    return ret_val;
}
<|endoftext|>