<commit_before>#include "vlc_video_source.h"
#ifdef BUILD_PYTHON
#include "gil.h"
#endif
#include <cstdio>
#include <cstdlib>
#include <chrono>
#include <thread>

namespace gg
{

//!
//! \brief This is to be used by the
//! \c prepareRender and/or \c handleStream
//! functions as appropriate
//!
VideoFrame buffer_frame(I420, false);

VideoSourceVLC::VideoSourceVLC(const std::string path)
    : IVideoSource(gg::I420)
    , _vlc_inst(nullptr)
    , _vlc_mp(nullptr)
    , _running(false)
    , _video_buffer(nullptr)
    , _data_length(0)
    , _cols(0)
    , _rows(0)
    , _sub(nullptr)
    , _path(path)
    , _frame_rate(0)
{
    init_vlc();
    run_vlc();
    determine_full();
}

VideoSourceVLC::VideoSourceVLC(const std::string path,
                               const unsigned int frame_rate)
    : IVideoSource(gg::I420)
    , _vlc_inst(nullptr)
    , _vlc_mp(nullptr)
    , _running(false)
    , _video_buffer(nullptr)
    , _data_length(0)
    , _cols(0)
    , _rows(0)
    , _sub(nullptr)
    , _path(path)
    , _frame_rate(frame_rate)
{
    init_vlc();
    run_vlc();
    determine_full();
}

VideoSourceVLC::~VideoSourceVLC()
{
    stop_vlc();
    release_vlc();
    clear();
}

bool VideoSourceVLC::get_frame_dimensions(int & width, int & height)
{
    std::lock_guard<std::mutex> data_lock_guard(_data_lock);
    if(_cols == 0 || _rows == 0)
        return false;

    width = _cols;
    height = _rows;
    return true;
}

bool VideoSourceVLC::get_frame(VideoFrame & frame)
{
    if (frame.colour() != _colour)
        return false;

    std::lock_guard<std::mutex> data_lock_guard(_data_lock);
    if (_data_length > 0)
    {
        frame.init_from_specs(_video_buffer, _data_length, _cols, _rows);
        return true;
    }
    else
        return false;

    // TODO #86
}

double VideoSourceVLC::get_frame_rate()
{
    return libvlc_media_player_get_fps(_vlc_mp);
}

void VideoSourceVLC::set_sub_frame(int x, int y, int width, int height)
{
    if (x >= _full.x and x + width <= _full.x + _full.width and
        y >= _full.y and y + height <= _full.y + _full.height)
    {
        stop_vlc();
        set_crop(x, y, width, height);
        run_vlc();
    }
}

void VideoSourceVLC::get_full_frame()
{
    stop_vlc();
    reset_crop();
    run_vlc();
}

void VideoSourceVLC::init_vlc()
{
    // VLC global options (valid for the lifetime of the program)
    // see `vlc --help` for the difference between `--option` and `:option`
    const char * const vlc_args[] = {
        "-I", "dummy", // Don't use any interface
        "--ignore-config", // Don't use VLC's config
        "--file-logging",
        //"--verbose=2", // Be much more verbose then normal for debugging purpose
        "--no-audio",
        "--no-video-title-show"
    };

    // We launch VLC
    _vlc_inst = libvlc_new(sizeof(vlc_args) / sizeof(vlc_args[0]), vlc_args);
    if (_vlc_inst == nullptr)
        throw VideoSourceError("Could not create VLC engine");

    // create VLC media player
    _vlc_mp = libvlc_media_player_new(_vlc_inst);
    if (_vlc_mp == nullptr)
        throw VideoSourceError("Could not create VLC media player");
}

void VideoSourceVLC::run_vlc()
{
    libvlc_media_t * vlc_media = nullptr;

    // If path contains a colon (:), it will be treated as a
    // URL. Else, it will be considered as a local path.
    if (_path.find(":") == std::string::npos)
        vlc_media = libvlc_media_new_path(_vlc_inst, _path.c_str());
    else
        vlc_media = libvlc_media_new_location(_vlc_inst, _path.c_str());
    if (vlc_media == nullptr)
        throw VideoSourceError(std::string("Could not open ").append(_path));

    // compose the processing pipeline description
    char pipeline[512];
    // open transcode step
    sprintf(pipeline, "#transcode{");
    // cropping sub-frame
    unsigned int croptop = 0, cropbottom = 0, cropleft = 0, cropright = 0;
    if (_sub != nullptr) // cropping video?
    {
        croptop = std::max(_sub->y, croptop),
        cropbottom = std::max(_full.height - (_sub->y + _sub->height), cropbottom),
        cropleft = std::max(_sub->x, cropleft),
        cropright = std::max(_full.width - (_sub->x + _sub->width), cropright);
    }
    sprintf(pipeline, "%svfilter=croppadd{", pipeline);
    sprintf(pipeline, "%scroptop=%u,", pipeline, croptop);
    sprintf(pipeline, "%scropbottom=%u,", pipeline, cropbottom);
    sprintf(pipeline, "%scropleft=%u,", pipeline, cropleft);
    sprintf(pipeline, "%scropright=%u", pipeline, cropright);
    sprintf(pipeline, "%s}", pipeline);
    // colour space specification
    sprintf(pipeline, "%s,vcodec=I420", pipeline);
    // frame rate specification
    if (_frame_rate > 0)
        sprintf(pipeline, "%s,fps=%u", pipeline, _frame_rate);
    // close transcode step
    sprintf(pipeline, "%s}:", pipeline);
    // callbacks
    sprintf(pipeline,
            "%ssmem{video-data=%lld,video-prerender-callback=%lld,video-postrender-callback=%lld}",
            pipeline,
            (long long int)(intptr_t)(void*) this,
            (long long int)(intptr_t)(void*) &VideoSourceVLC::prepareRender,
            (long long int)(intptr_t)(void*) &VideoSourceVLC::handleStream );
    // activate pipeline in VLC media
    char sout_options[1024];
    sprintf(sout_options, ":sout=%s", pipeline);
    libvlc_media_add_option(vlc_media, sout_options);
    // set VLC media player's media
    libvlc_media_player_set_media(_vlc_mp, vlc_media);
    // release VLC media
    libvlc_media_release(vlc_media);

#ifdef BUILD_PYTHON
    ScopedPythonGILRelease gil_release;
#endif

    { // artificial scope for the mutex guard below
        std::lock_guard<std::mutex> data_lock_guard(_data_lock);
        // play the media_player
        if (libvlc_media_player_play(_vlc_mp) != 0)
            throw VideoSourceError("Could not start VLC media player");
        _running = true;
    }

    // empirically determined value that allows for initialisation
    // to succeed before any API functions are called on this object
    std::this_thread::sleep_for(std::chrono::milliseconds(350));

    // ensure no error!
    if (libvlc_media_player_get_state(_vlc_mp) == libvlc_Error)
        throw gg::VideoSourceError(std::string("Could not open ").append(_path));
}

void VideoSourceVLC::stop_vlc()
{
    // stop playing
    libvlc_media_player_stop(_vlc_mp);

    { // artificial scope for mutex guard below
        std::lock_guard<std::mutex> data_lock_guard(_data_lock);
        _running = false;
    }
}

void VideoSourceVLC::release_vlc()
{
    // free media player
    libvlc_media_player_release(_vlc_mp);

    // free engine
    libvlc_release(_vlc_inst);
}

void VideoSourceVLC::clear()
{
    // free buffer
    std::lock_guard<std::mutex> data_lock_guard(_data_lock);
    if (_video_buffer != nullptr)
    {
        delete[] _video_buffer;
        _video_buffer = nullptr;
    }
    _data_length = 0;
    _cols = 0;
    _rows = 0;

    reset_crop();
}

void VideoSourceVLC::determine_full()
{
    get_frame_dimensions((int&)_full.width, (int&)_full.height);
    _full.x = 0;
    _full.y = 0;
}

void VideoSourceVLC::set_crop(unsigned int x, unsigned int y,
                              unsigned int width, unsigned int height)
{
    if (_sub == nullptr) _sub = new FrameBox;
    _sub->x = x;
    _sub->y = y;
    _sub->width = width;
    _sub->height = height;
}

void VideoSourceVLC::reset_crop()
{
    // free sub-frame
    if (_sub != nullptr)
    {
        delete _sub;
        _sub = nullptr;
    }
}

void VideoSourceVLC::prepareRender(VideoSourceVLC * p_video_data,
                                   uint8_t ** pp_pixel_buffer,
                                   size_t size)
{
    std::lock_guard<std::mutex> data_lock_guard(p_video_data->_data_lock);
    if (p_video_data->_running)
    {
        if (size > p_video_data->_data_length)
            p_video_data->_video_buffer = reinterpret_cast<uint8_t *>(
                        realloc(p_video_data->_video_buffer, size * sizeof(uint8_t))
                        );
        p_video_data->_data_length = p_video_data->_video_buffer != nullptr ? size : 0;

        *pp_pixel_buffer = p_video_data->_video_buffer;
    }
}

void VideoSourceVLC::handleStream(VideoSourceVLC * p_video_data,
                                  uint8_t * p_pixel_buffer,
                                  size_t cols,
                                  size_t rows,
                                  size_t colour_depth,
                                  size_t size)
{
    std::lock_guard<std::mutex> data_lock_guard(p_video_data->_data_lock);
    // TODO: explain how data should be handled (see #86)
    if (p_video_data->_running)
    {
        p_video_data->_cols = cols;
        p_video_data->_rows = rows;
        buffer_frame.init_from_specs(p_pixel_buffer, size, cols, rows);
        p_video_data->notify(buffer_frame);
    }
}

}
<commit_msg>Issue #117: revised get_frame_rate of VLC video source to reflect the addition of frame rate member<commit_after>#include "vlc_video_source.h"
#ifdef BUILD_PYTHON
#include "gil.h"
#endif
#include <cstdio>
#include <cstdlib>
#include <chrono>
#include <thread>

namespace gg
{

//!
//! \brief This is to be used by the
//! \c prepareRender and/or \c handleStream
//! functions as appropriate
//!
VideoFrame buffer_frame(I420, false);

VideoSourceVLC::VideoSourceVLC(const std::string path)
    : IVideoSource(gg::I420)
    , _vlc_inst(nullptr)
    , _vlc_mp(nullptr)
    , _running(false)
    , _video_buffer(nullptr)
    , _data_length(0)
    , _cols(0)
    , _rows(0)
    , _sub(nullptr)
    , _path(path)
    , _frame_rate(0)
{
    init_vlc();
    run_vlc();
    determine_full();
}

VideoSourceVLC::VideoSourceVLC(const std::string path,
                               const unsigned int frame_rate)
    : IVideoSource(gg::I420)
    , _vlc_inst(nullptr)
    , _vlc_mp(nullptr)
    , _running(false)
    , _video_buffer(nullptr)
    , _data_length(0)
    , _cols(0)
    , _rows(0)
    , _sub(nullptr)
    , _path(path)
    , _frame_rate(frame_rate)
{
    init_vlc();
    run_vlc();
    determine_full();
}

VideoSourceVLC::~VideoSourceVLC()
{
    stop_vlc();
    release_vlc();
    clear();
}

bool VideoSourceVLC::get_frame_dimensions(int & width, int & height)
{
    std::lock_guard<std::mutex> data_lock_guard(_data_lock);
    if(_cols == 0 || _rows == 0)
        return false;

    width = _cols;
    height = _rows;
    return true;
}

bool VideoSourceVLC::get_frame(VideoFrame & frame)
{
    if (frame.colour() != _colour)
        return false;

    std::lock_guard<std::mutex> data_lock_guard(_data_lock);
    if (_data_length > 0)
    {
        frame.init_from_specs(_video_buffer, _data_length, _cols, _rows);
        return true;
    }
    else
        return false;

    // TODO #86
}

double VideoSourceVLC::get_frame_rate()
{
    if (_frame_rate > 0)
        return _frame_rate;
    else
        return libvlc_media_player_get_fps(_vlc_mp);
}

void VideoSourceVLC::set_sub_frame(int x, int y, int width, int height)
{
    if (x >= _full.x and x + width <= _full.x + _full.width and
        y >= _full.y and y + height <= _full.y + _full.height)
    {
        stop_vlc();
        set_crop(x, y, width, height);
        run_vlc();
    }
}

void VideoSourceVLC::get_full_frame()
{
    stop_vlc();
    reset_crop();
    run_vlc();
}

void VideoSourceVLC::init_vlc()
{
    // VLC global options (valid for the lifetime of the program)
    // see `vlc --help` for the difference between `--option` and `:option`
    const char * const vlc_args[] = {
        "-I", "dummy", // Don't use any interface
        "--ignore-config", // Don't use VLC's config
        "--file-logging",
        //"--verbose=2", // Be much more verbose then normal for debugging purpose
        "--no-audio",
        "--no-video-title-show"
    };

    // We launch VLC
    _vlc_inst = libvlc_new(sizeof(vlc_args) / sizeof(vlc_args[0]), vlc_args);
    if (_vlc_inst == nullptr)
        throw VideoSourceError("Could not create VLC engine");

    // create VLC media player
    _vlc_mp = libvlc_media_player_new(_vlc_inst);
    if (_vlc_mp == nullptr)
        throw VideoSourceError("Could not create VLC media player");
}

void VideoSourceVLC::run_vlc()
{
    libvlc_media_t * vlc_media = nullptr;

    // If path contains a colon (:), it will be treated as a
    // URL. Else, it will be considered as a local path.
    if (_path.find(":") == std::string::npos)
        vlc_media = libvlc_media_new_path(_vlc_inst, _path.c_str());
    else
        vlc_media = libvlc_media_new_location(_vlc_inst, _path.c_str());
    if (vlc_media == nullptr)
        throw VideoSourceError(std::string("Could not open ").append(_path));

    // compose the processing pipeline description
    char pipeline[512];
    // open transcode step
    sprintf(pipeline, "#transcode{");
    // cropping sub-frame
    unsigned int croptop = 0, cropbottom = 0, cropleft = 0, cropright = 0;
    if (_sub != nullptr) // cropping video?
    {
        croptop = std::max(_sub->y, croptop),
        cropbottom = std::max(_full.height - (_sub->y + _sub->height), cropbottom),
        cropleft = std::max(_sub->x, cropleft),
        cropright = std::max(_full.width - (_sub->x + _sub->width), cropright);
    }
    sprintf(pipeline, "%svfilter=croppadd{", pipeline);
    sprintf(pipeline, "%scroptop=%u,", pipeline, croptop);
    sprintf(pipeline, "%scropbottom=%u,", pipeline, cropbottom);
    sprintf(pipeline, "%scropleft=%u,", pipeline, cropleft);
    sprintf(pipeline, "%scropright=%u", pipeline, cropright);
    sprintf(pipeline, "%s}", pipeline);
    // colour space specification
    sprintf(pipeline, "%s,vcodec=I420", pipeline);
    // frame rate specification
    if (_frame_rate > 0)
        sprintf(pipeline, "%s,fps=%u", pipeline, _frame_rate);
    // close transcode step
    sprintf(pipeline, "%s}:", pipeline);
    // callbacks
    sprintf(pipeline,
            "%ssmem{video-data=%lld,video-prerender-callback=%lld,video-postrender-callback=%lld}",
            pipeline,
            (long long int)(intptr_t)(void*) this,
            (long long int)(intptr_t)(void*) &VideoSourceVLC::prepareRender,
            (long long int)(intptr_t)(void*) &VideoSourceVLC::handleStream );
    // activate pipeline in VLC media
    char sout_options[1024];
    sprintf(sout_options, ":sout=%s", pipeline);
    libvlc_media_add_option(vlc_media, sout_options);
    // set VLC media player's media
    libvlc_media_player_set_media(_vlc_mp, vlc_media);
    // release VLC media
    libvlc_media_release(vlc_media);

#ifdef BUILD_PYTHON
    ScopedPythonGILRelease gil_release;
#endif

    { // artificial scope for the mutex guard below
        std::lock_guard<std::mutex> data_lock_guard(_data_lock);
        // play the media_player
        if (libvlc_media_player_play(_vlc_mp) != 0)
            throw VideoSourceError("Could not start VLC media player");
        _running = true;
    }

    // empirically determined value that allows for initialisation
    // to succeed before any API functions are called on this object
    std::this_thread::sleep_for(std::chrono::milliseconds(350));

    // ensure no error!
    if (libvlc_media_player_get_state(_vlc_mp) == libvlc_Error)
        throw gg::VideoSourceError(std::string("Could not open ").append(_path));
}

void VideoSourceVLC::stop_vlc()
{
    // stop playing
    libvlc_media_player_stop(_vlc_mp);

    { // artificial scope for mutex guard below
        std::lock_guard<std::mutex> data_lock_guard(_data_lock);
        _running = false;
    }
}

void VideoSourceVLC::release_vlc()
{
    // free media player
    libvlc_media_player_release(_vlc_mp);

    // free engine
    libvlc_release(_vlc_inst);
}

void VideoSourceVLC::clear()
{
    // free buffer
    std::lock_guard<std::mutex> data_lock_guard(_data_lock);
    if (_video_buffer != nullptr)
    {
        delete[] _video_buffer;
        _video_buffer = nullptr;
    }
    _data_length = 0;
    _cols = 0;
    _rows = 0;

    reset_crop();
}

void VideoSourceVLC::determine_full()
{
    get_frame_dimensions((int&)_full.width, (int&)_full.height);
    _full.x = 0;
    _full.y = 0;
}

void VideoSourceVLC::set_crop(unsigned int x, unsigned int y,
                              unsigned int width, unsigned int height)
{
    if (_sub == nullptr) _sub = new FrameBox;
    _sub->x = x;
    _sub->y = y;
    _sub->width = width;
    _sub->height = height;
}

void VideoSourceVLC::reset_crop()
{
    // free sub-frame
    if (_sub != nullptr)
    {
        delete _sub;
        _sub = nullptr;
    }
}

void VideoSourceVLC::prepareRender(VideoSourceVLC * p_video_data,
                                   uint8_t ** pp_pixel_buffer,
                                   size_t size)
{
    std::lock_guard<std::mutex> data_lock_guard(p_video_data->_data_lock);
    if (p_video_data->_running)
    {
        if (size > p_video_data->_data_length)
            p_video_data->_video_buffer = reinterpret_cast<uint8_t *>(
                        realloc(p_video_data->_video_buffer, size * sizeof(uint8_t))
                        );
        p_video_data->_data_length = p_video_data->_video_buffer != nullptr ? size : 0;

        *pp_pixel_buffer = p_video_data->_video_buffer;
    }
}

void VideoSourceVLC::handleStream(VideoSourceVLC * p_video_data,
                                  uint8_t * p_pixel_buffer,
                                  size_t cols,
                                  size_t rows,
                                  size_t colour_depth,
                                  size_t size)
{
    std::lock_guard<std::mutex> data_lock_guard(p_video_data->_data_lock);
    // TODO: explain how data should be handled (see #86)
    if (p_video_data->_running)
    {
        p_video_data->_cols = cols;
        p_video_data->_rows = rows;
        buffer_frame.init_from_specs(p_pixel_buffer, size, cols, rows);
        p_video_data->notify(buffer_frame);
    }
}

}
<|endoftext|>


<commit_before>#include "openmc/source.h"

#include <algorithm> // for move
#include <sstream> // for stringstream
#include <dlfcn.h> // for dlopen

#include <fmt/core.h>
#include "xtensor/xadapt.hpp"

#include "openmc/bank.h"
#include "openmc/cell.h"
#include "openmc/error.h"
#include "openmc/file_utils.h"
#include "openmc/hdf5_interface.h"
#include "openmc/material.h"
#include "openmc/message_passing.h"
#include "openmc/mgxs_interface.h"
#include "openmc/nuclide.h"
#include "openmc/capi.h"
#include "openmc/random_lcg.h"
#include "openmc/search.h"
#include "openmc/settings.h"
#include "openmc/simulation.h"
#include "openmc/state_point.h"
#include "openmc/xml_interface.h"

namespace openmc {

//==============================================================================
// Global variables
//==============================================================================

namespace model {

std::vector<SourceDistribution> external_sources;

}

//==============================================================================
// SourceDistribution implementation
//==============================================================================

SourceDistribution::SourceDistribution(UPtrSpace space, UPtrAngle angle, UPtrDist energy)
  : space_{std::move(space)}, angle_{std::move(angle)}, energy_{std::move(energy)} { }

SourceDistribution::SourceDistribution(pugi::xml_node node)
{
  // Check for particle type
  if (check_for_node(node, "particle")) {
    auto temp_str = get_node_value(node, "particle", true, true);
    if (temp_str == "neutron") {
      particle_ = Particle::Type::neutron;
    } else if (temp_str == "photon") {
      particle_ = Particle::Type::photon;
      settings::photon_transport = true;
    } else {
      fatal_error(std::string("Unknown source particle type: ") + temp_str);
    }
  }

  // Check for source strength
  if (check_for_node(node, "strength")) {
    strength_ = std::stod(get_node_value(node, "strength"));
  }

  // Check for external source file
  if (check_for_node(node, "file")) {
    // Copy path of source file
    settings::path_source = get_node_value(node, "file", false, true);

    // Check if source file exists
    if (!file_exists(settings::path_source)) {
      fatal_error(fmt::format("Source file '{}' does not exist.",
        settings::path_source));
    }
  } else if (check_for_node(node, "library")) {
     settings::path_source_library = get_node_value(node, "library", false, true);
     // check if it exists
     if (!file_exists(settings::path_source_library)) {
	std::stringstream msg;
	msg << "Library file " << settings::path_source_library << "' does not exist.";
	fatal_error(msg);
     }
  } else {

    // Spatial distribution for external source
    if (check_for_node(node, "space")) {
      // Get pointer to spatial distribution
      pugi::xml_node node_space = node.child("space");

      // Check for type of spatial distribution and read
      std::string type;
      if (check_for_node(node_space, "type"))
        type = get_node_value(node_space, "type", true, true);
      if (type == "cartesian") {
        space_ = UPtrSpace{new CartesianIndependent(node_space)};
      } else if (type == "cylindrical") {
        space_ = UPtrSpace{new CylindricalIndependent(node_space)};
      } else if (type == "spherical") {
        space_ = UPtrSpace{new SphericalIndependent(node_space)};
      } else if (type == "box") {
        space_ = UPtrSpace{new SpatialBox(node_space)};
      } else if (type == "fission") {
        space_ = UPtrSpace{new SpatialBox(node_space, true)};
      } else if (type == "point") {
        space_ = UPtrSpace{new SpatialPoint(node_space)};
      } else {
        fatal_error(fmt::format(
          "Invalid spatial distribution for external source: {}", type));
      }

    } else {
      // If no spatial distribution specified, make it a point source
      space_ = UPtrSpace{new SpatialPoint()};
    }

    // Determine external source angular distribution
    if (check_for_node(node, "angle")) {
      // Get pointer to angular distribution
      pugi::xml_node node_angle = node.child("angle");

      // Check for type of angular distribution
      std::string type;
      if (check_for_node(node_angle, "type"))
        type = get_node_value(node_angle, "type", true, true);
      if (type == "isotropic") {
        angle_ = UPtrAngle{new Isotropic()};
      } else if (type == "monodirectional") {
        angle_ = UPtrAngle{new Monodirectional(node_angle)};
      } else if (type == "mu-phi") {
        angle_ = UPtrAngle{new PolarAzimuthal(node_angle)};
      } else {
        fatal_error(fmt::format(
          "Invalid angular distribution for external source: {}", type));
      }

    } else {
      angle_ = UPtrAngle{new Isotropic()};
    }

    // Determine external source energy distribution
    if (check_for_node(node, "energy")) {
      pugi::xml_node node_dist = node.child("energy");
      energy_ = distribution_from_xml(node_dist);
    } else {
      // Default to a Watt spectrum with parameters 0.988 MeV and 2.249 MeV^-1
      energy_ = UPtrDist{new Watt(0.988e6, 2.249e-6)};
    }
  }
}

Particle::Bank SourceDistribution::sample(uint64_t* seed) const
{
  Particle::Bank site;

  // Set weight to one by default
  site.wgt = 1.0;

  // Repeat sampling source location until a good site has been found
  bool found = false;
  int n_reject = 0;
  static int n_accept = 0;
  while (!found) {
    // Set particle type
    site.particle = particle_;

    // Sample spatial distribution
    site.r = space_->sample(seed);
    double xyz[] {site.r.x, site.r.y, site.r.z};

    // Now search to see if location exists in geometry
    int32_t cell_index, instance;
    int err = openmc_find_cell(xyz, &cell_index, &instance);
    found = (err != OPENMC_E_GEOMETRY);

    // Check if spatial site is in fissionable material
    if (found) {
      auto space_box = dynamic_cast<SpatialBox*>(space_.get());
      if (space_box) {
        if (space_box->only_fissionable()) {
          // Determine material
          const auto& c = model::cells[cell_index];
          auto mat_index = c->material_.size() == 1
            ? c->material_[0] : c->material_[instance];

          if (mat_index == MATERIAL_VOID) {
            found = false;
          } else {
            if (!model::materials[mat_index]->fissionable_) found = false;
          }
        }
      }
    }

    // Check for rejection
    if (!found) {
      ++n_reject;
      if (n_reject >= EXTSRC_REJECT_THRESHOLD &&
          static_cast<double>(n_accept)/n_reject <= EXTSRC_REJECT_FRACTION) {
        fatal_error("More than 95% of external source sites sampled were "
                    "rejected. Please check your external source definition.");
      }
    }
  }

  // Increment number of accepted samples
  ++n_accept;

  // Sample angle
  site.u = angle_->sample(seed);

  // Check for monoenergetic source above maximum particle energy
  auto p = static_cast<int>(particle_);
  auto energy_ptr = dynamic_cast<Discrete*>(energy_.get());
  if (energy_ptr) {
    auto energies = xt::adapt(energy_ptr->x());
    if (xt::any(energies > data::energy_max[p])) {
      fatal_error("Source energy above range of energies of at least "
                  "one cross section table");
    } else if (xt::any(energies < data::energy_min[p])) {
      fatal_error("Source energy below range of energies of at least "
                  "one cross section table");
    }
  }

  while (true) {
    // Sample energy spectrum
    site.E = energy_->sample(seed);

    // Resample if energy falls outside minimum or maximum particle energy
    if (site.E < data::energy_max[p] && site.E > data::energy_min[p]) break;
  }

  // Set delayed group
  site.delayed_group = 0;

  return site;
}

//==============================================================================
// Non-member functions
//==============================================================================

void initialize_source()
{
  write_message("Initializing source particles...", 5);

  if (settings::path_source != "") {
    // Read the source from a binary file instead of sampling from some
    // assumed source distribution

    write_message(fmt::format("Reading source file from {}...",
      settings::path_source), 6);

    // Open the binary file
    hid_t file_id = file_open(settings::path_source, 'r', true);

    // Read the file type
    std::string filetype;
    read_attribute(file_id, "filetype", filetype);

    // Check to make sure this is a source file
    if (filetype != "source" && filetype != "statepoint") {
      fatal_error("Specified starting source file not a source file type.");
    }

    // Read in the source bank
    read_source_bank(file_id);

    // Close file
    file_close(file_id);
  } else if ( settings::path_source_library != "" ) {
    // Get the source from a library object

    std::stringstream msg;
    msg << "Sampling from library source " << settings::path_source << "...";
    write_message(msg, 6);

    // Open the library
    void* source_library = dlopen(settings::path_source_library.c_str(),RTLD_LAZY);
    if(!source_library) {
      std::stringstream msg("Couldnt open source library " + settings::path_source_library);
      fatal_error(msg);
    }

    // load the symbol
    typedef Particle::Bank (*sample_t)();

    // reset errors
    dlerror();

    // get the function from the library
    sample_t sample_source = (sample_t) dlsym(source_library, "sample_source");
    const char *dlsym_error = dlerror();

    if (dlsym_error) {
      dlclose(source_library);
      fatal_error(dlsym_error);
    }

    // Generation source sites from specified distribution in the
    // library source
    for (int64_t i = 0; i < simulation::work_per_rank; ++i) {
      // initialize random number seed
      int64_t id = simulation::total_gen*settings::n_particles +
        simulation::work_index[mpi::rank] + i + 1;
      set_particle_seed(id);

      // sample external source distribution
      simulation::source_bank[i] = sample_source();
    }

    // release the library
    dlclose(source_library);

  } else {
    // Generation source sites from specified distribution in user input
    for (int64_t i = 0; i < simulation::work_per_rank; ++i) {
      // initialize random number seed
      int64_t id = simulation::total_gen*settings::n_particles +
        simulation::work_index[mpi::rank] + i + 1;
      uint64_t seed = init_seed(id, STREAM_SOURCE);

      // sample external source distribution
      simulation::source_bank[i] = sample_external_source(&seed);
    }
  }

  // Write out initial source
  if (settings::write_initial_source) {
    write_message("Writing out initial source...", 5);
    std::string filename = settings::path_output + "initial_source.h5";
    hid_t file_id = file_open(filename, 'w', true);
    write_source_bank(file_id);
    file_close(file_id);
  }
}

Particle::Bank sample_external_source(uint64_t* seed)
{
  // Determine total source strength
  double total_strength = 0.0;
  for (auto& s : model::external_sources)
    total_strength += s.strength();

  // Sample from among multiple source distributions
  int i = 0;
  if (model::external_sources.size() > 1) {
    double xi = prn(seed)*total_strength;
    double c = 0.0;
    for (; i < model::external_sources.size(); ++i) {
      c += model::external_sources[i].strength();
      if (xi < c) break;
    }
  }

  // Sample source site from i-th source distribution
  Particle::Bank site {model::external_sources[i].sample(seed)};

  // If running in MG, convert site.E to group
  if (!settings::run_CE) {
    site.E = lower_bound_index(data::mg.rev_energy_bins_.begin(),
      data::mg.rev_energy_bins_.end(), site.E);
    site.E = data::mg.num_energy_groups_ - site.E - 1.;
  }

  return site;
}

void free_memory_source()
{
  model::external_sources.clear();
}

void fill_source_bank_fixedsource()
{
  if (settings::path_source.empty()) {
    #pragma omp parallel for
    for (int64_t i = 0; i < simulation::work_per_rank; ++i) {
      // initialize random number seed
      int64_t id = (simulation::total_gen + overall_generation()) *
        settings::n_particles + simulation::work_index[mpi::rank] + i + 1;
      uint64_t seed = init_seed(id, STREAM_SOURCE);

      // sample external source distribution
      simulation::source_bank[i] = sample_external_source(&seed);
    }
  }
}

} // namespace openmc
<commit_msg>Added missing fixed source subroutine<commit_after>#include "openmc/source.h"

#include <algorithm> // for move
#include <sstream> // for stringstream
#include <dlfcn.h> // for dlopen

#include <fmt/core.h>
#include "xtensor/xadapt.hpp"

#include "openmc/bank.h"
#include "openmc/cell.h"
#include "openmc/error.h"
#include "openmc/file_utils.h"
#include "openmc/hdf5_interface.h"
#include "openmc/material.h"
#include "openmc/message_passing.h"
#include "openmc/mgxs_interface.h"
#include "openmc/nuclide.h"
#include "openmc/capi.h"
#include "openmc/random_lcg.h"
#include "openmc/search.h"
#include "openmc/settings.h"
#include "openmc/simulation.h"
#include "openmc/state_point.h"
#include "openmc/xml_interface.h"

namespace openmc {

//==============================================================================
// Global variables
//==============================================================================

namespace model {

std::vector<SourceDistribution> external_sources;

}

//==============================================================================
// SourceDistribution implementation
//==============================================================================

SourceDistribution::SourceDistribution(UPtrSpace space, UPtrAngle angle, UPtrDist energy)
  : space_{std::move(space)}, angle_{std::move(angle)}, energy_{std::move(energy)} { }

SourceDistribution::SourceDistribution(pugi::xml_node node)
{
  // Check for particle type
  if (check_for_node(node, "particle")) {
    auto temp_str = get_node_value(node, "particle", true, true);
    if (temp_str == "neutron") {
      particle_ = Particle::Type::neutron;
    } else if (temp_str == "photon") {
      particle_ = Particle::Type::photon;
      settings::photon_transport = true;
    } else {
      fatal_error(std::string("Unknown source particle type: ") + temp_str);
    }
  }

  // Check for source strength
  if (check_for_node(node, "strength")) {
    strength_ = std::stod(get_node_value(node, "strength"));
  }

  // Check for external source file
  if (check_for_node(node, "file")) {
    // Copy path of source file
    settings::path_source = get_node_value(node, "file", false, true);

    // Check if source file exists
    if (!file_exists(settings::path_source)) {
      fatal_error(fmt::format("Source file '{}' does not exist.",
        settings::path_source));
    }
  } else if (check_for_node(node, "library")) {
     settings::path_source_library = get_node_value(node, "library", false, true);
     // check if it exists
     if (!file_exists(settings::path_source_library)) {
	std::stringstream msg;
	msg << "Library file " << settings::path_source_library << "' does not exist.";
	fatal_error(msg);
     }
  } else {

    // Spatial distribution for external source
    if (check_for_node(node, "space")) {
      // Get pointer to spatial distribution
      pugi::xml_node node_space = node.child("space");

      // Check for type of spatial distribution and read
      std::string type;
      if (check_for_node(node_space, "type"))
        type = get_node_value(node_space, "type", true, true);
      if (type == "cartesian") {
        space_ = UPtrSpace{new CartesianIndependent(node_space)};
      } else if (type == "cylindrical") {
        space_ = UPtrSpace{new CylindricalIndependent(node_space)};
      } else if (type == "spherical") {
        space_ = UPtrSpace{new SphericalIndependent(node_space)};
      } else if (type == "box") {
        space_ = UPtrSpace{new SpatialBox(node_space)};
      } else if (type == "fission") {
        space_ = UPtrSpace{new SpatialBox(node_space, true)};
      } else if (type == "point") {
        space_ = UPtrSpace{new SpatialPoint(node_space)};
      } else {
        fatal_error(fmt::format(
          "Invalid spatial distribution for external source: {}", type));
      }

    } else {
      // If no spatial distribution specified, make it a point source
      space_ = UPtrSpace{new SpatialPoint()};
    }

    // Determine external source angular distribution
    if (check_for_node(node, "angle")) {
      // Get pointer to angular distribution
      pugi::xml_node node_angle = node.child("angle");

      // Check for type of angular distribution
      std::string type;
      if (check_for_node(node_angle, "type"))
        type = get_node_value(node_angle, "type", true, true);
      if (type == "isotropic") {
        angle_ = UPtrAngle{new Isotropic()};
      } else if (type == "monodirectional") {
        angle_ = UPtrAngle{new Monodirectional(node_angle)};
      } else if (type == "mu-phi") {
        angle_ = UPtrAngle{new PolarAzimuthal(node_angle)};
      } else {
        fatal_error(fmt::format(
          "Invalid angular distribution for external source: {}", type));
      }

    } else {
      angle_ = UPtrAngle{new Isotropic()};
    }

    // Determine external source energy distribution
    if (check_for_node(node, "energy")) {
      pugi::xml_node node_dist = node.child("energy");
      energy_ = distribution_from_xml(node_dist);
    } else {
      // Default to a Watt spectrum with parameters 0.988 MeV and 2.249 MeV^-1
      energy_ = UPtrDist{new Watt(0.988e6, 2.249e-6)};
    }
  }
}

Particle::Bank SourceDistribution::sample(uint64_t* seed) const
{
  Particle::Bank site;

  // Set weight to one by default
  site.wgt = 1.0;

  // Repeat sampling source location until a good site has been found
  bool found = false;
  int n_reject = 0;
  static int n_accept = 0;
  while (!found) {
    // Set particle type
    site.particle = particle_;

    // Sample spatial distribution
    site.r = space_->sample(seed);
    double xyz[] {site.r.x, site.r.y, site.r.z};

    // Now search to see if location exists in geometry
    int32_t cell_index, instance;
    int err = openmc_find_cell(xyz, &cell_index, &instance);
    found = (err != OPENMC_E_GEOMETRY);

    // Check if spatial site is in fissionable material
    if (found) {
      auto space_box = dynamic_cast<SpatialBox*>(space_.get());
      if (space_box) {
        if (space_box->only_fissionable()) {
          // Determine material
          const auto& c = model::cells[cell_index];
          auto mat_index = c->material_.size() == 1
            ? c->material_[0] : c->material_[instance];

          if (mat_index == MATERIAL_VOID) {
            found = false;
          } else {
            if (!model::materials[mat_index]->fissionable_) found = false;
          }
        }
      }
    }

    // Check for rejection
    if (!found) {
      ++n_reject;
      if (n_reject >= EXTSRC_REJECT_THRESHOLD &&
          static_cast<double>(n_accept)/n_reject <= EXTSRC_REJECT_FRACTION) {
        fatal_error("More than 95% of external source sites sampled were "
                    "rejected. Please check your external source definition.");
      }
    }
  }

  // Increment number of accepted samples
  ++n_accept;

  // Sample angle
  site.u = angle_->sample(seed);

  // Check for monoenergetic source above maximum particle energy
  auto p = static_cast<int>(particle_);
  auto energy_ptr = dynamic_cast<Discrete*>(energy_.get());
  if (energy_ptr) {
    auto energies = xt::adapt(energy_ptr->x());
    if (xt::any(energies > data::energy_max[p])) {
      fatal_error("Source energy above range of energies of at least "
                  "one cross section table");
    } else if (xt::any(energies < data::energy_min[p])) {
      fatal_error("Source energy below range of energies of at least "
                  "one cross section table");
    }
  }

  while (true) {
    // Sample energy spectrum
    site.E = energy_->sample(seed);

    // Resample if energy falls outside minimum or maximum particle energy
    if (site.E < data::energy_max[p] && site.E > data::energy_min[p]) break;
  }

  // Set delayed group
  site.delayed_group = 0;

  return site;
}

//==============================================================================
// Non-member functions
//==============================================================================

void initialize_source()
{
  write_message("Initializing source particles...", 5);

  if (settings::path_source != "") {
    // Read the source from a binary file instead of sampling from some
    // assumed source distribution

    write_message(fmt::format("Reading source file from {}...",
      settings::path_source), 6);

    // Open the binary file
    hid_t file_id = file_open(settings::path_source, 'r', true);

    // Read the file type
    std::string filetype;
    read_attribute(file_id, "filetype", filetype);

    // Check to make sure this is a source file
    if (filetype != "source" && filetype != "statepoint") {
      fatal_error("Specified starting source file not a source file type.");
    }

    // Read in the source bank
    read_source_bank(file_id);

    // Close file
    file_close(file_id);
  } else if ( settings::path_source_library != "" ) {
    // Get the source from a library object

    std::stringstream msg;
    msg << "Sampling from library source " << settings::path_source << "...";
    write_message(msg, 6);

    // Open the library
    void* source_library = dlopen(settings::path_source_library.c_str(),RTLD_LAZY);
    if(!source_library) {
      std::stringstream msg("Couldnt open source library " + settings::path_source_library);
      fatal_error(msg);
    }

    // load the symbol
    typedef Particle::Bank (*sample_t)();

    // reset errors
    dlerror();

    // get the function from the library
    sample_t sample_source = (sample_t) dlsym(source_library, "sample_source");
    const char *dlsym_error = dlerror();

    // check for any dlsym errors
    if (dlsym_error) {
      std::cout << dlsym_error << std::endl;
      dlclose(source_library);
      fatal_error("Couldnt open the sample_source symbol");
    }

    // Generation source sites from specified distribution in the
    // library source
    for (int64_t i = 0; i < simulation::work_per_rank; ++i) {
      // initialize random number seed
      int64_t id = simulation::total_gen*settings::n_particles +
        simulation::work_index[mpi::rank] + i + 1;
      set_particle_seed(id);

      // sample external source distribution
      simulation::source_bank[i] = sample_source();
    }

    // release the library
    dlclose(source_library);

  } else {
    // Generation source sites from specified distribution in user input
    for (int64_t i = 0; i < simulation::work_per_rank; ++i) {
      // initialize random number seed
      int64_t id = simulation::total_gen*settings::n_particles +
        simulation::work_index[mpi::rank] + i + 1;
      uint64_t seed = init_seed(id, STREAM_SOURCE);

      // sample external source distribution
      simulation::source_bank[i] = sample_external_source(&seed);
    }
  }

  // Write out initial source
  if (settings::write_initial_source) {
    write_message("Writing out initial source...", 5);
    std::string filename = settings::path_output + "initial_source.h5";
    hid_t file_id = file_open(filename, 'w', true);
    write_source_bank(file_id);
    file_close(file_id);
  }
}

Particle::Bank sample_external_source(uint64_t* seed)
{
  // Determine total source strength
  double total_strength = 0.0;
  for (auto& s : model::external_sources)
    total_strength += s.strength();

  // Sample from among multiple source distributions
  int i = 0;
  if (model::external_sources.size() > 1) {
    double xi = prn(seed)*total_strength;
    double c = 0.0;
    for (; i < model::external_sources.size(); ++i) {
      c += model::external_sources[i].strength();
      if (xi < c) break;
    }
  }

  // Sample source site from i-th source distribution
  Particle::Bank site {model::external_sources[i].sample(seed)};

  // If running in MG, convert site.E to group
  if (!settings::run_CE) {
    site.E = lower_bound_index(data::mg.rev_energy_bins_.begin(),
      data::mg.rev_energy_bins_.end(), site.E);
    site.E = data::mg.num_energy_groups_ - site.E - 1.;
  }

  return site;
}

void free_memory_source()
{
  model::external_sources.clear();
}

void fill_source_bank_fixedsource()
{
  if (settings::path_source.empty() && settings::path_source_library.empty()) {
    for (int64_t i = 0; i < simulation::work_per_rank; ++i) {
      // initialize random number seed
      int64_t id = (simulation::total_gen + overall_generation()) *
        settings::n_particles + simulation::work_index[mpi::rank] + i + 1;
      uint64_t seed = init_seed(id, STREAM_SOURCE);

      // sample external source distribution
      simulation::source_bank[i] = sample_external_source(&seed);
    }
  } else if (settings::path_source.empty() && !settings::path_source.empty()) {
     std::stringstream msg;

    // Open the library
    void* source_library = dlopen(settings::path_source_library.c_str(),RTLD_LAZY);
    if(!source_library) {
      std::stringstream msg("Couldnt open source library " + settings::path_source_library);
      fatal_error(msg);
    }

    // load the symbol
    typedef Particle::Bank (*sample_t)();

    // reset errors
    dlerror();

    // get the function from the library
    sample_t sample_source = (sample_t) dlsym(source_library, "sample_source");
    const char *dlsym_error = dlerror();

    // check for any dlsym errors
    if (dlsym_error) {
      std::cout << dlsym_error << std::endl;
      dlclose(source_library);
      fatal_error("Couldnt open the sample_source symbol");
    }

    // Generation source sites from specified distribution in the
    // library source
    for (int64_t i = 0; i < simulation::work_per_rank; ++i) {
      // initialize random number seed
      int64_t id = simulation::total_gen*settings::n_particles +
        simulation::work_index[mpi::rank] + i + 1;
      set_particle_seed(id);

      // sample external source distribution
      simulation::source_bank[i] = sample_source();
    }

    // release the library
    dlclose(source_library);
  }
}

} // namespace openmc
<|endoftext|>


<commit_before>// Copyright 2014 Reece Heineke<reece.heineke@gmail.com>
#include "iem/session.hpp"

#include <numeric>
#include <string>
#include <vector>
#include <utility>

#include "boost/property_tree/xml_parser.hpp"

namespace iem {

using ptree = boost::property_tree::ptree;
using StringPair = std::pair<std::string, std::string>;
using StringPairVector = std::vector<StringPair>;

constexpr auto _VAH = "viewAssetHoldings";

Session::Session(const std::string& username, const std::string& password):
    username_(username), password_(password), cookie_(""), client_() {
}

const std::string url_encode(const std::vector<StringPair>& nvs) {
  using boost::network::uri::encoded;
  auto op = [](const std::string& a, const StringPair& p) {
    return a.empty() ?
           encoded(p.first) + '=' + encoded(p.second) :
           a + '&' + encoded(p.first) + '=' + encoded(p.second);
  };
  return std::accumulate(nvs.begin(), nvs.end(), std::string{}, op);
}

ClientRequest buildRequest(const std::string &path,
                           const StringPairVector& name_value_pairs = {}) {
  // URI
  boost::network::uri::uri url;
  url << boost::network::uri::scheme("https")
      << boost::network::uri::host("iem.uiowa.edu")
      << boost::network::uri::path(path);
  ClientRequest request(url);
  // Add default headers
  using boost::network::header;
  // Python requests default headers
  request << header("User-Agent", "python-requests/2.10.0")
          << header("Accept-Encoding", "gzip, deflate")
          << header("Accept", "*/*");
          // << header("Connection", "keep-alive");
  // Optional body
  if (name_value_pairs.size()) {
    const auto body = url_encode(name_value_pairs);
    request << boost::network::body(body);
    request << header("Content-Length", std::to_string(body.length()))
            << header("Content-Type", "application/x-www-form-urlencoded");
  }
  return request;
}

const ClientResponse Session::authenticate(const bool force_login) {
  // Login request
  auto login_request = buildRequest(
      "/iem/trader/TraderLogin.action",
      {
          {"forceLogin", force_login ? "true" : "false"},  // Required
          {"username", this->username()},
          {"password", this->password()},
          {"loginSubmit", "Sign in"},  // Required
          {"_sourcePage", ""},  // Required
      });
  // POST request
  const auto login_response = client_.post(login_request);
  // Extract important headers - IEM requests a redirect
  std::string location;
  for (auto h : login_response.headers()) {
    if (h.first == "Set-Cookie") {
      cookie_ = h.second;
    } else if (h.first == "Location") {
      location = h.second;
    }
  }

  // Market select request
  auto market_select_request = buildRequest(location);
  // Set cookie
  market_select_request << boost::network::header("Set-Cookie", cookie());
  // GET request
  return client_.get(market_select_request);
}

const ClientResponse Session::logout() {
  // Construct request
  auto logout_request = buildRequest("/iem/trader/TraderLogin.action?logout=");
  // Set cookie
  logout_request << boost::network::header("Cookie", this->cookie());
  // GET request
  return client_.get(logout_request);
}

Price _parse_price(const std::string &px_str) {
  if (px_str.size()) {
    std::istringstream iss(px_str);
    Price p;
    iss >> p;
    return p;
  }
  return nanPrice();
}

position_t _parse_quantity(const std::string &qty_str) {
  if (qty_str.size()) {
    return std::stoi(qty_str);
  }
  return 0;
}

const ptree& empty_ptree() {
  static ptree t;
  return t;
}

unsigned int num_open_orders(ptree::const_assoc_iterator it) {
  auto obo_form = it->second.get_child("form", empty_ptree());
  std::string value;
  if (obo_form == empty_ptree()) {
    value = it->second.data();
  } else {
    // viewAssetHoldings input
    auto input_its = obo_form.equal_range("input");
    for (auto it = input_its.first; it != input_its.second; it++) {
      if (it->second.get<std::string>("<xmlattr>.name") == _VAH) {
        value = it->second.get<std::string>("<xmlattr>.value");
      }
    }
  }
  boost::trim(value);
  return std::stoi(value);
}

const OrderBook _read_html(ptree::const_assoc_iterator tr_it) {
  // Orderbook values
  std::string contract_name;
  Price bb;
  bool bbp;
  Price ba;
  bool bap;
  Price lp;
  position_t pos;
  unsigned int noo;
  unsigned int nao;

  auto td_its = tr_it->second.equal_range("td");
  const std::string& c = "contract";
  for (auto it = td_its.first; it != td_its.second; it++) {
    // XML attribute called class
    const auto& klass = it->second.get<std::string>("<xmlattr>.class", c);
    if (klass == c) {  // Contract name
      contract_name = it->second.data();
      boost::trim(contract_name);
    } else if (klass == "change-cell bestBidPrice") {  // Best bid price
      auto data = it->second.get_child("p").data();
      boost::trim(data);
      bb = _parse_price(data);
      bbp = data.find("*") != std::string::npos;
    } else if (klass == "change-cell bestAskPrice") {  // Best ask price
      auto data = it->second.get_child("p").data();
      boost::trim(data);
      ba = _parse_price(data);
      bap = data.find("*") != std::string::npos;
    } else if (klass == "change-cell lastPrice") {  // Last trade price
      auto data = it->second.get_child("p").data();
      boost::trim(data);
      lp = _parse_price(data);
    } else if (klass == "change-cell quantity") {  // Position
      auto data = it->second.get<std::string>("<xmlattr>.value");
      pos = _parse_quantity(data);
    } else if (klass == "yourBidsCell") {  // Number of open bid orders
      noo = num_open_orders(it);
    } else if (klass == "yourAsksCell") {  // Number of open ask orders
      nao = num_open_orders(it);
    }
  }

  return OrderBook(contract_name, bb, bbp, ba, bap, lp, noo, nao, pos);
}

const std::vector<OrderBook> read_html(const std::string& body) {
  // In order to increase likelihood of parsing valid XML, find substring that
  // covers all html tables. Might assume one table.
  size_t pos = body.find("<table");
  size_t len = body.rfind("table") - pos + 6;
  auto tables_str = body.substr(pos, len);
  // Boost ptree works on streams only
  std::istringstream is(tables_str);
  // ptree
  ptree pt;
  read_xml(is, pt);
  // XML nodes(terminology?) of interest
  const auto table = pt.get_child("table");
  const auto tbody = table.get_child("tbody");
  // As a test, let's get the first contract(terminology?) name
  const auto tr = tbody.get_child("tr");
  const auto tr_its = tbody.equal_range("tr");

  std::vector<OrderBook> obs;
  for (auto it = tr_its.first; it != tr_its.second; it++) {
    obs.push_back(_read_html(it));
  }
  return obs;
}

const std::vector<OrderBook> Session::market_orderbook(int market) {
  // Construct request
  auto market_orderbook_request = buildRequest(
      "/iem/trader/MarketTrader.action",
      {{"market", std::to_string(market)}}
  );
  // Set cookie
  market_orderbook_request << boost::network::header("Cookie", cookie());
  // POST request
  const auto& response = client_.post(market_orderbook_request);
  return read_html(body(response));
}

const ClientResponse Session::asset_holdings(const Contract& contract) {
  // Construct request
  auto asset_holdings_request = buildRequest(
      "/iem/trader/TraderActivity.action",
      {
          {"market", "contract.market"},
          {"asset", std::to_string(contract.asset_id())},
          {"activityType", "holdings"},
          {_VAH, std::to_string(25)}  // Number of transactions? Required?
      });
  // Set cookie
  asset_holdings_request << boost::network::header("Cookie", cookie());
  // POST request
  const auto& response = client_.post(asset_holdings_request);
  return response;
}

const ClientResponse Session::place_order(const Order& order) {
  // Construct request
  auto order_request = buildRequest("order/LimitOrder.action");
  // TODO(rheineke): Differentiate order types
  // Set cookie
  order_request << boost::network::header("Cookie", cookie());
  // POST request
  const auto& response = client_.post(order_request);
  return response;
}

const std::string _limit_order_type(Side side) {
  return (side == Side::buy) ? "bid" : "ask";
}

const std::string _expiration_date(const Single& order) {
  return to_iso_extended_string(order.price_time_limit().expiration().date());
}

const ClientRequest limit_order_request(const Single& order) {
  using boost::gregorian::to_iso_extended_string;
  // Construct request
  const auto& c = order.contract();
  auto order_request = buildRequest(
      "order/LimitOrder.action",
      {
          {"limitOrderAssetToMarket", std::to_string(c.asset_to_market_id())},
          {"orderType", _limit_order_type(order.side())},
          {"expirationDate", _expiration_date(order)},
          {"price", ""},
          {"limitOrderQuantity", std::to_string(order.quantity())},
          {"placeLimitOder", "Place Limit Order"},
          {"market", std::to_string(c.market().value())}
      });
  return order_request;
}

const ClientResponse Session::cancel_order(const Order& order) {
  // Construct request
  auto cancel_order_request = buildRequest("TraderActivity.action");
  // TODO(rheineke): Differentiate order types
  // Set cookie
  cancel_order_request << boost::network::header("Cookie", cookie());
  // POST request
  const auto& response = client_.post(cancel_order_request);
  return response;
}

int snprintf_session(char* const str, const Session& s) {
  static const auto fmt("{\"name\":\"session\", \"username\":\"%s\", "
                        "\"password\":\"%s\", \"cookie\":\"%s\"}");

  return snprintf(str, 160, fmt, s.username().c_str(), s.password().c_str(),
                  s.cookie().c_str());
}

}  // namespace iem
<commit_msg>#3 Use unit tested to_string<commit_after>// Copyright 2014 Reece Heineke<reece.heineke@gmail.com>
#include "iem/session.hpp"

#include <numeric>
#include <string>
#include <vector>
#include <utility>

#include "boost/property_tree/xml_parser.hpp"

namespace iem {

using ptree = boost::property_tree::ptree;
using StringPair = std::pair<std::string, std::string>;
using StringPairVector = std::vector<StringPair>;

constexpr auto _VAH = "viewAssetHoldings";

Session::Session(const std::string& username, const std::string& password):
    username_(username), password_(password), cookie_(""), client_() {
}

const std::string url_encode(const std::vector<StringPair>& nvs) {
  using boost::network::uri::encoded;
  auto op = [](const std::string& a, const StringPair& p) {
    return a.empty() ?
           encoded(p.first) + '=' + encoded(p.second) :
           a + '&' + encoded(p.first) + '=' + encoded(p.second);
  };
  return std::accumulate(nvs.begin(), nvs.end(), std::string{}, op);
}

ClientRequest buildRequest(const std::string &path,
                           const StringPairVector& name_value_pairs = {}) {
  // URI
  boost::network::uri::uri url;
  url << boost::network::uri::scheme("https")
      << boost::network::uri::host("iem.uiowa.edu")
      << boost::network::uri::path(path);
  ClientRequest request(url);
  // Add default headers
  using boost::network::header;
  // Python requests default headers
  request << header("User-Agent", "python-requests/2.10.0")
          << header("Accept-Encoding", "gzip, deflate")
          << header("Accept", "*/*");
          // << header("Connection", "keep-alive");
  // Optional body
  if (name_value_pairs.size()) {
    const auto body = url_encode(name_value_pairs);
    request << boost::network::body(body);
    request << header("Content-Length", std::to_string(body.length()))
            << header("Content-Type", "application/x-www-form-urlencoded");
  }
  return request;
}

const ClientResponse Session::authenticate(const bool force_login) {
  // Login request
  auto login_request = buildRequest(
      "/iem/trader/TraderLogin.action",
      {
          {"forceLogin", force_login ? "true" : "false"},  // Required
          {"username", this->username()},
          {"password", this->password()},
          {"loginSubmit", "Sign in"},  // Required
          {"_sourcePage", ""},  // Required
      });
  // POST request
  const auto login_response = client_.post(login_request);
  // Extract important headers - IEM requests a redirect
  std::string location;
  for (auto h : login_response.headers()) {
    if (h.first == "Set-Cookie") {
      cookie_ = h.second;
    } else if (h.first == "Location") {
      location = h.second;
    }
  }

  // Market select request
  auto market_select_request = buildRequest(location);
  // Set cookie
  market_select_request << boost::network::header("Set-Cookie", cookie());
  // GET request
  return client_.get(market_select_request);
}

const ClientResponse Session::logout() {
  // Construct request
  auto logout_request = buildRequest("/iem/trader/TraderLogin.action?logout=");
  // Set cookie
  logout_request << boost::network::header("Cookie", this->cookie());
  // GET request
  return client_.get(logout_request);
}

Price _parse_price(const std::string &px_str) {
  if (px_str.size()) {
    std::istringstream iss(px_str);
    Price p;
    iss >> p;
    return p;
  }
  return nanPrice();
}

position_t _parse_quantity(const std::string &qty_str) {
  if (qty_str.size()) {
    return std::stoi(qty_str);
  }
  return 0;
}

const ptree& empty_ptree() {
  static ptree t;
  return t;
}

unsigned int num_open_orders(ptree::const_assoc_iterator it) {
  auto obo_form = it->second.get_child("form", empty_ptree());
  std::string value;
  if (obo_form == empty_ptree()) {
    value = it->second.data();
  } else {
    // viewAssetHoldings input
    auto input_its = obo_form.equal_range("input");
    for (auto it = input_its.first; it != input_its.second; it++) {
      if (it->second.get<std::string>("<xmlattr>.name") == _VAH) {
        value = it->second.get<std::string>("<xmlattr>.value");
      }
    }
  }
  boost::trim(value);
  return std::stoi(value);
}

const OrderBook _read_html(ptree::const_assoc_iterator tr_it) {
  // Orderbook values
  std::string contract_name;
  Price bb;
  bool bbp;
  Price ba;
  bool bap;
  Price lp;
  position_t pos;
  unsigned int noo;
  unsigned int nao;

  auto td_its = tr_it->second.equal_range("td");
  const std::string& c = "contract";
  for (auto it = td_its.first; it != td_its.second; it++) {
    // XML attribute called class
    const auto& klass = it->second.get<std::string>("<xmlattr>.class", c);
    if (klass == c) {  // Contract name
      contract_name = it->second.data();
      boost::trim(contract_name);
    } else if (klass == "change-cell bestBidPrice") {  // Best bid price
      auto data = it->second.get_child("p").data();
      boost::trim(data);
      bb = _parse_price(data);
      bbp = data.find("*") != std::string::npos;
    } else if (klass == "change-cell bestAskPrice") {  // Best ask price
      auto data = it->second.get_child("p").data();
      boost::trim(data);
      ba = _parse_price(data);
      bap = data.find("*") != std::string::npos;
    } else if (klass == "change-cell lastPrice") {  // Last trade price
      auto data = it->second.get_child("p").data();
      boost::trim(data);
      lp = _parse_price(data);
    } else if (klass == "change-cell quantity") {  // Position
      auto data = it->second.get<std::string>("<xmlattr>.value");
      pos = _parse_quantity(data);
    } else if (klass == "yourBidsCell") {  // Number of open bid orders
      noo = num_open_orders(it);
    } else if (klass == "yourAsksCell") {  // Number of open ask orders
      nao = num_open_orders(it);
    }
  }

  return OrderBook(contract_name, bb, bbp, ba, bap, lp, noo, nao, pos);
}

const std::vector<OrderBook> read_html(const std::string& body) {
  // In order to increase likelihood of parsing valid XML, find substring that
  // covers all html tables. Might assume one table.
  size_t pos = body.find("<table");
  size_t len = body.rfind("table") - pos + 6;
  auto tables_str = body.substr(pos, len);
  // Boost ptree works on streams only
  std::istringstream is(tables_str);
  // ptree
  ptree pt;
  read_xml(is, pt);
  // XML nodes(terminology?) of interest
  const auto table = pt.get_child("table");
  const auto tbody = table.get_child("tbody");
  // As a test, let's get the first contract(terminology?) name
  const auto tr = tbody.get_child("tr");
  const auto tr_its = tbody.equal_range("tr");

  std::vector<OrderBook> obs;
  for (auto it = tr_its.first; it != tr_its.second; it++) {
    obs.push_back(_read_html(it));
  }
  return obs;
}

const std::vector<OrderBook> Session::market_orderbook(int market) {
  // Construct request
  auto market_orderbook_request = buildRequest(
      "/iem/trader/MarketTrader.action",
      {{"market", std::to_string(market)}}
  );
  // Set cookie
  market_orderbook_request << boost::network::header("Cookie", cookie());
  // POST request
  const auto& response = client_.post(market_orderbook_request);
  return read_html(body(response));
}

const ClientResponse Session::asset_holdings(const Contract& contract) {
  // Construct request
  auto asset_holdings_request = buildRequest(
      "/iem/trader/TraderActivity.action",
      {
          {"market", "contract.market"},
          {"asset", std::to_string(contract.asset_id())},
          {"activityType", "holdings"},
          {_VAH, std::to_string(25)}  // Number of transactions? Required?
      });
  // Set cookie
  asset_holdings_request << boost::network::header("Cookie", cookie());
  // POST request
  const auto& response = client_.post(asset_holdings_request);
  return response;
}

const ClientResponse Session::place_order(const Order& order) {
  // Construct request
  auto order_request = buildRequest("order/LimitOrder.action");
  // TODO(rheineke): Differentiate order types
  // Set cookie
  order_request << boost::network::header("Cookie", cookie());
  // POST request
  const auto& response = client_.post(order_request);
  return response;
}

const std::string _limit_order_type(Side side) {
  return (side == Side::buy) ? "bid" : "ask";
}

const std::string _expiration_date(const Single& order) {
  return to_iso_extended_string(order.price_time_limit().expiration().date());
}

const ClientRequest limit_order_request(const Single& order) {
  using boost::gregorian::to_iso_extended_string;
  // Construct request
  const auto& c = order.contract();
  auto order_request = buildRequest(
      "order/LimitOrder.action",
      {
          {"limitOrderAssetToMarket", std::to_string(c.asset_to_market_id())},
          {"orderType", _limit_order_type(order.side())},
          {"expirationDate", _expiration_date(order)},
          {"price", to_string(order.price_time_limit().price())},
          {"limitOrderQuantity", std::to_string(order.quantity())},
          {"placeLimitOder", "Place Limit Order"},
          {"market", std::to_string(c.market().value())}
      });
  return order_request;
}

const std::string _market_order_type(Side side) {
  return (side == Side::buy) ? "buy" : "sell";
}

const ClientRequest market_order_request(const Single& order) {
  // Construct request
  const auto& c = order.contract();
  auto order_request = buildRequest(
      "order/MarketOrder.action",
      {
          {"limitOrderAssetToMarket", std::to_string(c.asset_to_market_id())},
          {"orderType", _market_order_type(order.side())},
          {"marketOrderQuantity", std::to_string(order.quantity())},
          {"placeMarketOder", "Place Market Order"},
          {"market", std::to_string(c.market().value())}
      });
  return order_request;
}

const ClientRequest bundle_order_request(const Bundle& order) {
  // Construct request
  const auto& cb = order.contract_bundle();
  auto order_request = buildRequest(
      "order/MarketOrder.action",
      {
          {"limitOrderAssetToMarket", std::to_string(cb.bundle_id())},
          {"orderType", _market_order_type(order.side())},
          {"bundleOrderQuantity", std::to_string(order.quantity())},
          {"placeBundleOder", "Place Bundle Order"},
          {"market", std::to_string(cb.market().value())}
      });
  return order_request;
}

const ClientResponse Session::cancel_order(const Order& order) {
  // Construct request
  auto cancel_order_request = buildRequest("TraderActivity.action");
  // TODO(rheineke): Differentiate order types
  // Set cookie
  cancel_order_request << boost::network::header("Cookie", cookie());
  // POST request
  const auto& response = client_.post(cancel_order_request);
  return response;
}

int snprintf_session(char* const str, const Session& s) {
  static const auto fmt("{\"name\":\"session\", \"username\":\"%s\", "
                        "\"password\":\"%s\", \"cookie\":\"%s\"}");

  return snprintf(str, 160, fmt, s.username().c_str(), s.password().c_str(),
                  s.cookie().c_str());
}

}  // namespace iem
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: dstribut.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 21:03:25 $
 *
 *  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
 *
 ************************************************************************/
#ifndef _SVX_DSTRIBUT_HXX
#define _SVX_DSTRIBUT_HXX

#ifndef _SVX_DLG_CTRL_HXX
#include <dlgctrl.hxx>
#endif

#ifndef _SV_GROUP_HXX
#include <vcl/group.hxx>
#endif

#ifndef _SV_FIXED_HXX
#include <vcl/fixed.hxx>
#endif

#ifndef _SVX_DSTRIBUT_ENUM_HXX
#include "dstribut_enum.hxx" //CHINA001
#endif
/*************************************************************************
|*
\************************************************************************/

/*
enum SvxDistributeHorizontal
{
    SvxDistributeHorizontalNone = 0,
    SvxDistributeHorizontalLeft,
    SvxDistributeHorizontalCenter,
    SvxDistributeHorizontalDistance,
    SvxDistributeHorizontalRight
};

enum SvxDistributeVertical
{
    SvxDistributeVerticalNone = 0,
    SvxDistributeVerticalTop,
    SvxDistributeVerticalCenter,
    SvxDistributeVerticalDistance,
    SvxDistributeVerticalBottom
};
*/

/*************************************************************************
|*
\************************************************************************/

class SvxDistributePage : public SvxTabPage
{
    SvxDistributeHorizontal     meDistributeHor;
    SvxDistributeVertical       meDistributeVer;

    FixedLine                   maFlHorizontal      ;
    RadioButton                 maBtnHorNone        ;
    RadioButton                 maBtnHorLeft        ;
    RadioButton                 maBtnHorCenter      ;
    RadioButton                 maBtnHorDistance    ;
    RadioButton                 maBtnHorRight       ;
    FixedImage                  maHorLow            ;
    FixedImage                  maHorCenter         ;
    FixedImage                  maHorDistance       ;
    FixedImage                  maHorHigh           ;
    FixedLine                   maFlVertical        ;
    RadioButton                 maBtnVerNone        ;
    RadioButton                 maBtnVerTop         ;
    RadioButton                 maBtnVerCenter      ;
    RadioButton                 maBtnVerDistance    ;
    RadioButton                 maBtnVerBottom      ;
    FixedImage                  maVerLow            ;
    FixedImage                  maVerCenter         ;
    FixedImage                  maVerDistance       ;
    FixedImage                  maVerHigh           ;

public:
    SvxDistributePage(Window* pWindow, const SfxItemSet& rInAttrs,
        SvxDistributeHorizontal eHor = SvxDistributeHorizontalNone,
        SvxDistributeVertical eVer = SvxDistributeVerticalNone);
    ~SvxDistributePage();

    static SfxTabPage* Create(Window*, const SfxItemSet&,
        SvxDistributeHorizontal eHor, SvxDistributeVertical eVer);
    static UINT16* GetRanges();
    virtual BOOL FillItemSet(SfxItemSet&);
    virtual void Reset(const SfxItemSet&);
    virtual void PointChanged(Window* pWindow, RECT_POINT eRP);

    SvxDistributeHorizontal GetDistributeHor() const { return meDistributeHor; }
    SvxDistributeVertical GetDistributeVer() const { return meDistributeVer; }
};

/*************************************************************************
|*
\************************************************************************/

class SvxDistributeDialog : public SfxSingleTabDialog
{
    SvxDistributePage*          mpPage;

public:
    SvxDistributeDialog(Window* pParent, const SfxItemSet& rAttr,
        SvxDistributeHorizontal eHor = SvxDistributeHorizontalNone,
        SvxDistributeVertical eVer = SvxDistributeVerticalNone);
    ~SvxDistributeDialog();

    SvxDistributeHorizontal GetDistributeHor() const { return mpPage->GetDistributeHor(); }
    SvxDistributeVertical GetDistributeVer() const { return mpPage->GetDistributeVer(); }
};

#endif // _SVX_DSTRIBUT_HXX

<commit_msg>INTEGRATION: CWS vgbugs07 (1.4.878); FILE MERGED 2007/06/04 13:26:16 vg 1.4.878.1: #i76605# Remove -I .../inc/module hack introduced by hedaburemove01<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: dstribut.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: hr $ $Date: 2007-06-27 17:04:09 $
 *
 *  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
 *
 ************************************************************************/
#ifndef _SVX_DSTRIBUT_HXX
#define _SVX_DSTRIBUT_HXX

#ifndef _SVX_DLG_CTRL_HXX
#include <svx/dlgctrl.hxx>
#endif

#ifndef _SV_GROUP_HXX
#include <vcl/group.hxx>
#endif

#ifndef _SV_FIXED_HXX
#include <vcl/fixed.hxx>
#endif

#ifndef _SVX_DSTRIBUT_ENUM_HXX
#include <svx/dstribut_enum.hxx> //CHINA001
#endif
/*************************************************************************
|*
\************************************************************************/

/*
enum SvxDistributeHorizontal
{
    SvxDistributeHorizontalNone = 0,
    SvxDistributeHorizontalLeft,
    SvxDistributeHorizontalCenter,
    SvxDistributeHorizontalDistance,
    SvxDistributeHorizontalRight
};

enum SvxDistributeVertical
{
    SvxDistributeVerticalNone = 0,
    SvxDistributeVerticalTop,
    SvxDistributeVerticalCenter,
    SvxDistributeVerticalDistance,
    SvxDistributeVerticalBottom
};
*/

/*************************************************************************
|*
\************************************************************************/

class SvxDistributePage : public SvxTabPage
{
    SvxDistributeHorizontal     meDistributeHor;
    SvxDistributeVertical       meDistributeVer;

    FixedLine                   maFlHorizontal      ;
    RadioButton                 maBtnHorNone        ;
    RadioButton                 maBtnHorLeft        ;
    RadioButton                 maBtnHorCenter      ;
    RadioButton                 maBtnHorDistance    ;
    RadioButton                 maBtnHorRight       ;
    FixedImage                  maHorLow            ;
    FixedImage                  maHorCenter         ;
    FixedImage                  maHorDistance       ;
    FixedImage                  maHorHigh           ;
    FixedLine                   maFlVertical        ;
    RadioButton                 maBtnVerNone        ;
    RadioButton                 maBtnVerTop         ;
    RadioButton                 maBtnVerCenter      ;
    RadioButton                 maBtnVerDistance    ;
    RadioButton                 maBtnVerBottom      ;
    FixedImage                  maVerLow            ;
    FixedImage                  maVerCenter         ;
    FixedImage                  maVerDistance       ;
    FixedImage                  maVerHigh           ;

public:
    SvxDistributePage(Window* pWindow, const SfxItemSet& rInAttrs,
        SvxDistributeHorizontal eHor = SvxDistributeHorizontalNone,
        SvxDistributeVertical eVer = SvxDistributeVerticalNone);
    ~SvxDistributePage();

    static SfxTabPage* Create(Window*, const SfxItemSet&,
        SvxDistributeHorizontal eHor, SvxDistributeVertical eVer);
    static UINT16* GetRanges();
    virtual BOOL FillItemSet(SfxItemSet&);
    virtual void Reset(const SfxItemSet&);
    virtual void PointChanged(Window* pWindow, RECT_POINT eRP);

    SvxDistributeHorizontal GetDistributeHor() const { return meDistributeHor; }
    SvxDistributeVertical GetDistributeVer() const { return meDistributeVer; }
};

/*************************************************************************
|*
\************************************************************************/

class SvxDistributeDialog : public SfxSingleTabDialog
{
    SvxDistributePage*          mpPage;

public:
    SvxDistributeDialog(Window* pParent, const SfxItemSet& rAttr,
        SvxDistributeHorizontal eHor = SvxDistributeHorizontalNone,
        SvxDistributeVertical eVer = SvxDistributeVerticalNone);
    ~SvxDistributeDialog();

    SvxDistributeHorizontal GetDistributeHor() const { return mpPage->GetDistributeHor(); }
    SvxDistributeVertical GetDistributeVer() const { return mpPage->GetDistributeVer(); }
};

#endif // _SVX_DSTRIBUT_HXX

<|endoftext|>


<commit_before>#include "Servidor.h"

using namespace std;

int main(void) {

    Servidor server;

    return 0;

}
<commit_msg>Algo que me falto actualizar<commit_after>#include "Servidor.h"

using namespace std;

int main(void) {

    Servidor server;
    server.iniciarServidor();

    return 0;

}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: multifil.cxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: obo $ $Date: 2006-07-13 11:59:59 $
 *
 *  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
 *
 ************************************************************************/

#ifdef SVX_DLLIMPLEMENTATION
#undef SVX_DLLIMPLEMENTATION
#endif

// include ---------------------------------------------------------------

#ifndef _SHL_HXX //autogen
#include <tools/shl.hxx>
#endif
#ifndef _SV_MSGBOX_HXX //autogen
#include <vcl/msgbox.hxx>
#endif

#ifndef _FILEDLGHELPER_HXX
#include <sfx2/filedlghelper.hxx>
#endif

#include <tools/urlobj.hxx>

#include "multipat.hxx"
#include "multifil.hxx"
#include "dialmgr.hxx"

#include "multipat.hrc"
#include "dialogs.hrc"

// #97807# -------------
#ifndef _COM_SUN_STAR_UCB_XCONTENTPROVIDER_HPP_
#include <com/sun/star/ucb/XContentProvider.hpp>
#endif
#ifndef _UCBHELPER_CONTENTBROKER_HXX
#include <ucbhelper/contentbroker.hxx>
#endif

using namespace com::sun::star::ucb;
using namespace com::sun::star::uno;

// class SvxMultiFileDialog ----------------------------------------------

IMPL_LINK( SvxMultiFileDialog, AddHdl_Impl, PushButton *, pBtn )
{
    sfx2::FileDialogHelper aDlg( ::sfx2::FILEOPEN_SIMPLE, 0 );

    if ( IsClassPathMode() )
    {
        aDlg.SetTitle( SVX_RES( RID_SVXSTR_ARCHIVE_TITLE ) );
        aDlg.AddFilter( SVX_RES( RID_SVXSTR_ARCHIVE_HEADLINE ), String::CreateFromAscii("*.jar;*.zip") );
    }

    if ( aDlg.Execute() == ERRCODE_NONE )
    {
        // #97807# URL content comparison of entries -----------
        INetURLObject aFile( aDlg.GetPath() );
        String sInsFile = aFile.getFSysPath( INetURLObject::FSYS_DETECT );
        ::ucb::Content aContent( aFile.GetMainURL( INetURLObject::NO_DECODE ), Reference< XCommandEnvironment >() );
        Reference< XContent > xContent = aContent.get();
        OSL_ENSURE( xContent.is(), "AddHdl_Impl: invalid content interface!" );
        Reference< XContentIdentifier > xID = xContent->getIdentifier();
        OSL_ENSURE( xID.is(), "AddHdl_Impl: invalid ID interface!" );
        // ensure the content of files are valid

        USHORT nCount = aPathLB.GetEntryCount();
        BOOL bDuplicated = FALSE;
        try
        {
            if( nCount > 0 ) // start comparison
            {
                USHORT i;
                ::ucb::Content & VContent = aContent; // temporary Content reference
                Reference< XContent > xVContent;
                Reference< XContentIdentifier > xVID;
                for( i = 0; i < nCount; i++ )
                {
                    String sVFile = aPathLB.GetEntry( i );
                    std::map< String, ::ucb::Content >::iterator aCur = aFileContentMap.find( sVFile );
                    if( aCur == aFileContentMap.end() ) // look for File Content in aFileContentMap, but not find it.
                    {
                        INetURLObject aVFile( sVFile, INetURLObject::FSYS_DETECT );
                        aFileContentMap[sVFile] = ::ucb::Content( aVFile.GetMainURL( INetURLObject::NO_DECODE ), Reference< XCommandEnvironment >() );
                        VContent = aFileContentMap.find( sVFile )->second;
                    }
                    else
                        VContent = aCur->second;
                    xVContent = VContent.get();
                    OSL_ENSURE( xVContent.is(), "AddHdl_Impl: invalid content interface!" );
                    xVID = xVContent->getIdentifier();
                    OSL_ENSURE( xVID.is(), "AddHdl_Impl: invalid ID interface!" );
                    if ( xID.is() && xVID.is() )
                    {
                        // get a generic content provider
                        ::ucb::ContentBroker* pBroker = ::ucb::ContentBroker::get();
                        Reference< XContentProvider > xProvider;
                        if ( pBroker )
                            xProvider = pBroker->getContentProviderInterface();
                        if ( xProvider.is() )
                        {
                            if ( 0 == xProvider->compareContentIds( xID, xVID ) )
                            {
                                bDuplicated = TRUE;
                                break;
                            }
                        }
                    }
                }
            } // end of if the entries are more than zero.
        } // end of try(}
        catch( const Exception& ) // catch every exception of comparison
           {
            OSL_ENSURE( sal_False, "AddHdl_Impl: caught an unexpected exception!" );
           }

        if ( bDuplicated ) // #97807# --------------------
        {
            String sMsg( SVX_RES( RID_SVXSTR_MULTIFILE_DBL_ERR ) );
            sMsg.SearchAndReplaceAscii( "%1", sInsFile );
            InfoBox( pBtn, sMsg ).Execute();
        }
        else
        {
            USHORT nPos = aPathLB.InsertEntry( sInsFile, LISTBOX_APPEND );
            aPathLB.SetEntryData( nPos, (void*) new String( sInsFile ) );
        }

    } // end of if ( aDlg.Execute() == ERRCODE_NONE )
    return 0;
}

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

IMPL_LINK( SvxMultiFileDialog, DelHdl_Impl, PushButton *, EMPTYARG )
{
    USHORT nPos = aPathLB.GetSelectEntryPos();
    aPathLB.RemoveEntry( nPos );
    USHORT nCnt = aPathLB.GetEntryCount();

    if ( nCnt )
    {
        nCnt--;

        if ( nPos > nCnt )
            nPos = nCnt;
        aPathLB.SelectEntryPos( nPos );
    }
    return 0;
}

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

SvxMultiFileDialog::SvxMultiFileDialog( Window* pParent, BOOL bEmptyAllowed ) :

    SvxMultiPathDialog( pParent, bEmptyAllowed )

{
    aAddBtn.SetClickHdl( LINK( this, SvxMultiFileDialog, AddHdl_Impl ) );
    aDelBtn.SetClickHdl( LINK( this, SvxMultiFileDialog, DelHdl_Impl ) );
    SetText( SVX_RES( RID_SVXSTR_FILE_TITLE ) );
    aPathFL.SetText( SVX_RES( RID_SVXSTR_FILE_HEADLINE ) );
    aDelBtn.Enable();
}

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

SvxMultiFileDialog::~SvxMultiFileDialog()
{
}

<commit_msg>INTEGRATION: CWS pchfix02 (1.6.74); FILE MERGED 2006/09/01 17:46:16 kaib 1.6.74.1: #i68856# Added header markers and pch files<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: multifil.cxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: obo $ $Date: 2006-09-17 04:27:55 $
 *
 *  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_svx.hxx"

#ifdef SVX_DLLIMPLEMENTATION
#undef SVX_DLLIMPLEMENTATION
#endif

// include ---------------------------------------------------------------

#ifndef _SHL_HXX //autogen
#include <tools/shl.hxx>
#endif
#ifndef _SV_MSGBOX_HXX //autogen
#include <vcl/msgbox.hxx>
#endif

#ifndef _FILEDLGHELPER_HXX
#include <sfx2/filedlghelper.hxx>
#endif

#include <tools/urlobj.hxx>

#include "multipat.hxx"
#include "multifil.hxx"
#include "dialmgr.hxx"

#include "multipat.hrc"
#include "dialogs.hrc"

// #97807# -------------
#ifndef _COM_SUN_STAR_UCB_XCONTENTPROVIDER_HPP_
#include <com/sun/star/ucb/XContentProvider.hpp>
#endif
#ifndef _UCBHELPER_CONTENTBROKER_HXX
#include <ucbhelper/contentbroker.hxx>
#endif

using namespace com::sun::star::ucb;
using namespace com::sun::star::uno;

// class SvxMultiFileDialog ----------------------------------------------

IMPL_LINK( SvxMultiFileDialog, AddHdl_Impl, PushButton *, pBtn )
{
    sfx2::FileDialogHelper aDlg( ::sfx2::FILEOPEN_SIMPLE, 0 );

    if ( IsClassPathMode() )
    {
        aDlg.SetTitle( SVX_RES( RID_SVXSTR_ARCHIVE_TITLE ) );
        aDlg.AddFilter( SVX_RES( RID_SVXSTR_ARCHIVE_HEADLINE ), String::CreateFromAscii("*.jar;*.zip") );
    }

    if ( aDlg.Execute() == ERRCODE_NONE )
    {
        // #97807# URL content comparison of entries -----------
        INetURLObject aFile( aDlg.GetPath() );
        String sInsFile = aFile.getFSysPath( INetURLObject::FSYS_DETECT );
        ::ucb::Content aContent( aFile.GetMainURL( INetURLObject::NO_DECODE ), Reference< XCommandEnvironment >() );
        Reference< XContent > xContent = aContent.get();
        OSL_ENSURE( xContent.is(), "AddHdl_Impl: invalid content interface!" );
        Reference< XContentIdentifier > xID = xContent->getIdentifier();
        OSL_ENSURE( xID.is(), "AddHdl_Impl: invalid ID interface!" );
        // ensure the content of files are valid

        USHORT nCount = aPathLB.GetEntryCount();
        BOOL bDuplicated = FALSE;
        try
        {
            if( nCount > 0 ) // start comparison
            {
                USHORT i;
                ::ucb::Content & VContent = aContent; // temporary Content reference
                Reference< XContent > xVContent;
                Reference< XContentIdentifier > xVID;
                for( i = 0; i < nCount; i++ )
                {
                    String sVFile = aPathLB.GetEntry( i );
                    std::map< String, ::ucb::Content >::iterator aCur = aFileContentMap.find( sVFile );
                    if( aCur == aFileContentMap.end() ) // look for File Content in aFileContentMap, but not find it.
                    {
                        INetURLObject aVFile( sVFile, INetURLObject::FSYS_DETECT );
                        aFileContentMap[sVFile] = ::ucb::Content( aVFile.GetMainURL( INetURLObject::NO_DECODE ), Reference< XCommandEnvironment >() );
                        VContent = aFileContentMap.find( sVFile )->second;
                    }
                    else
                        VContent = aCur->second;
                    xVContent = VContent.get();
                    OSL_ENSURE( xVContent.is(), "AddHdl_Impl: invalid content interface!" );
                    xVID = xVContent->getIdentifier();
                    OSL_ENSURE( xVID.is(), "AddHdl_Impl: invalid ID interface!" );
                    if ( xID.is() && xVID.is() )
                    {
                        // get a generic content provider
                        ::ucb::ContentBroker* pBroker = ::ucb::ContentBroker::get();
                        Reference< XContentProvider > xProvider;
                        if ( pBroker )
                            xProvider = pBroker->getContentProviderInterface();
                        if ( xProvider.is() )
                        {
                            if ( 0 == xProvider->compareContentIds( xID, xVID ) )
                            {
                                bDuplicated = TRUE;
                                break;
                            }
                        }
                    }
                }
            } // end of if the entries are more than zero.
        } // end of try(}
        catch( const Exception& ) // catch every exception of comparison
           {
            OSL_ENSURE( sal_False, "AddHdl_Impl: caught an unexpected exception!" );
           }

        if ( bDuplicated ) // #97807# --------------------
        {
            String sMsg( SVX_RES( RID_SVXSTR_MULTIFILE_DBL_ERR ) );
            sMsg.SearchAndReplaceAscii( "%1", sInsFile );
            InfoBox( pBtn, sMsg ).Execute();
        }
        else
        {
            USHORT nPos = aPathLB.InsertEntry( sInsFile, LISTBOX_APPEND );
            aPathLB.SetEntryData( nPos, (void*) new String( sInsFile ) );
        }

    } // end of if ( aDlg.Execute() == ERRCODE_NONE )
    return 0;
}

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

IMPL_LINK( SvxMultiFileDialog, DelHdl_Impl, PushButton *, EMPTYARG )
{
    USHORT nPos = aPathLB.GetSelectEntryPos();
    aPathLB.RemoveEntry( nPos );
    USHORT nCnt = aPathLB.GetEntryCount();

    if ( nCnt )
    {
        nCnt--;

        if ( nPos > nCnt )
            nPos = nCnt;
        aPathLB.SelectEntryPos( nPos );
    }
    return 0;
}

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

SvxMultiFileDialog::SvxMultiFileDialog( Window* pParent, BOOL bEmptyAllowed ) :

    SvxMultiPathDialog( pParent, bEmptyAllowed )

{
    aAddBtn.SetClickHdl( LINK( this, SvxMultiFileDialog, AddHdl_Impl ) );
    aDelBtn.SetClickHdl( LINK( this, SvxMultiFileDialog, DelHdl_Impl ) );
    SetText( SVX_RES( RID_SVXSTR_FILE_TITLE ) );
    aPathFL.SetText( SVX_RES( RID_SVXSTR_FILE_HEADLINE ) );
    aDelBtn.Enable();
}

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

SvxMultiFileDialog::~SvxMultiFileDialog()
{
}

<|endoftext|>