<commit_before>#ifndef V_SMC_SAMPLER_HPP
#define V_SMC_SAMPLER_HPP

#include <vSMC/config.hpp>

#include <map>
#include <stdexcept>
#include <string>
#include <vector>
#include <mkl_cblas.h>
#include <boost/function.hpp>
#include <vDist/rng/gsl.hpp>
#include <vDist/tool/buffer.hpp>
#include <vSMC/history.hpp>
#include <vSMC/monitor.hpp>
#include <vSMC/particle.hpp>

namespace vSMC {

template <typename T>
class Sampler
{
    public :

    /// The type of particle values
    typedef T value_type;
    /// The type of partiles
    typedef Particle<T> particle_type;
    /// The type of initialize callable objects
    typedef boost::function<std::size_t
        (Particle<T> &, void *)> init_type;
    /// The type of move callable objects
    typedef boost::function<std::size_t
        (std::size_t, Particle<T> &)> move_type;
    /// The type of importance sampling integral
    typedef boost::function<void
        (std::size_t, const Particle<T> &, double *, void *)> integral_type;
    /// The type of path sampling integration
    typedef boost::function<double
        (std::size_t, const Particle<T> &, double *)> path_type;

    /// \brief Sampler does not have a default constructor
    ///
    /// \param N The number of particles
    /// \param init The functor used to initialize the particles
    /// \param move The functor used to move the particles and weights
    /// \param copy The functor used to copy particles within the sample
    /// \param mcmc The functor used to perform MCMC move
    /// \param mode The history storage mode. See HistoryMode
    /// \param scheme The resampling scheme. See ResampleScheme
    /// \param threshold The threshold for performing resampling
    /// \param seed The seed for the reampling RNG. See documentation of vDist
    /// \param brng The basic RNG for resampling RNG. See documentation of GSL
    Sampler (
            std::size_t N,
            const init_type &init,
            const move_type &move,
            const typename Particle<T>::copy_type &copy,
            const move_type &mcmc = NULL,
            HistoryMode mode = HISTORY_NONE,
            ResampleScheme scheme = RESIDUAL,
            double threshold = 0.5,
            const int seed = V_DIST_SEED,
            const gsl_rng_type *brng = V_DIST_GSL_BRNG) :
        initialized_(false), init_(init), move_(move), mcmc_(mcmc),
        rng_(seed, brng), scheme_(scheme), threshold_(threshold * N),
        particle_(N, copy), iter_num_(0), history_(mode),
        buffer_(N), path_integral_(NULL), show_progress_(false) {}

    /// \brief Get ESS
    ///
    /// \return The ESS value of the latest iteration
    double get_ESS () const
    {
        return ess_.back();
    }

    /// \brief Get all ESS
    ///
    /// \return History of ESS for all iterations
    const std::vector<double> &get_ESS_history () const
    {
        return ess_;
    }

    /// \brief Get indicator of resampling
    ///
    /// \return A bool value, \b true if the latest iteration was resampled
    bool get_resample () const
    {
        return resample_.back();
    }

    /// \brief Get history of resampling
    ///
    /// \return History of resampling for all iterations
    const std::vector<bool> &get_resample_history () const
    {
        return resample_;
    }

    /// \brief Get accept count
    ///
    /// \return The accept count of the latest iteration
    std::size_t get_accept () const
    {
        return accept_.back();
    }

    /// \brief Get history of accept count
    ///
    /// \return History of accept count for all iterations
    const std::vector<std::size_t> &get_accept_history () const
    {
        return accept_;
    }

    /// \brief Read only access to the particle set
    ///
    /// \return A const reference to the latest particle set.
    /// \note Any operations that change the state of the sampler (e.g., an
    /// iteration) may invalidate the reference.
    const Particle<T> &particle () const
    {
        return particle_;
    }

    /// \brief (Re)initialize the particle set
    ///
    /// \param param Additional parameters passed to initialization functor,
    /// the default is NULL
    void initialize (void *param = NULL)
    {
        history_.clear();
        ess_.clear();
        resample_.clear();
        accept_.clear();

        for (typename std::map<std::string, Monitor<T> >::iterator
                imap = monitor_.begin(); imap != monitor_.end(); ++imap)
            imap->second.clear();

        path_sample_.clear();
        path_width_.clear();
        path_grid_.clear();

        iter_num_ = 0;
        accept_.push_back(init_(particle_, param));
        post_move();

        initialized_ = true;
    }

    /// \brief Perform iteration
    void iterate ()
    {
        if (!initialized_)
            throw std::runtime_error(
                    "ERROR: vSMC::Sampler::iterate: "
                    "Sampler has not been initialized yet");

        ++iter_num_;
        accept_.push_back(move_(iter_num_, particle_));
        if (mcmc_)
            accept_.back() = mcmc_(iter_num_, particle_);
        post_move();
    }

    /// \brief Perform iteration
    ///
    /// \param n The number of iterations to be performed
    void iterate (std::size_t n)
    {
        for (std::size_t i = 0; i != n; ++i)
            iterate();
    }

    /// \brief Perform importance sampling integration
    ///
    /// \param intgral The functor used to compute the integrands
    double integrate (typename Monitor<T>::integral_type integral) const
    {
        std::size_t n = particle_.size();
        integral(iter_num_, particle_, buffer_);

        return cblas_ddot(n, particle_.get_weight_ptr(), 1, buffer_, 1);
    }

    /// \brief Perform importance sampling integration
    ///
    /// \param intgral The functor used to compute the integrands
    /// \param param Additional parameters to be passed to integral
    double integrate (integral_type integral, void *param) const
    {
        std::size_t n = particle_.size();
        integral(iter_num_, particle_, buffer_, param);

        return cblas_ddot(n, particle_.get_weight_ptr(), 1, buffer_, 1);
    }

    /// \brief Add a monitor, similar to \b monitor in \b BUGS
    ///
    /// \param name The name of the monitor
    /// \param integral The functor used to compute the integrands
    void add_monitor (const std::string &name,
            const typename Monitor<T>::integral_type &integral)
    {
        monitor_.insert(
                typename std::map<std::string, Monitor<T> >::value_type(
                    name, Monitor<T>(particle_.size(), integral)));
    }

    /// \brief Get the iteration index of a monitor
    ///
    /// \param The name of the monitor
    /// \return A vector of the monitor index
    typename Monitor<T>::index_type get_monitor_index (
            const std::string &name) const
    {
        return monitor_.find(name)->second.get_index();
    }

    /// \brief Get the record of Monite Carlo integration of a monitor
    ///
    /// \param name The name of the monitor
    /// \return A vector of the monitor record
    typename Monitor<T>::record_type get_monitor_record (
            const std::string &name) const
    {
        return monitor_.find(name)->second.get_record();
    }

    /// \brief Get both the iteration index and record of a monitor
    typename Monitor<T>::value_type get_monitor_value (
            const std::string &name) const
    {
        return monitor_.find(name)->second.get();
    }

    /// \brief Erase a monitor by name
    ///
    /// \param name The name of the monitor
    void erase_monitor (const std::string &name)
    {
        monitor_.erase(name);
    }

    /// \brief Clear all monitors
    void clear_monitor ()
    {
        monitor_.clear();
    }

    /// \brief Set the path sampling integral
    ///
    /// \param integral The functor used to compute the integrands
    void set_path_sampling (path_type integral)
    {
        path_integral_ = integral;
    }

    /// \brief Stop path sampling
    void clear_path_sampling ()
    {
        path_integral_ = NULL;
    }

    /// \brief Get the results of path sampling
    double get_path_sampling () const
    {
	std::size_t num = path_sample_.size();
	double sum = 0;
	for (std::size_t i = 1; i != num; ++i)
            sum += (path_sample_[i-1] + path_sample_[i])
                * path_width_[i] * 0.5;
        return sum;
    }

    const std::vector<double> &get_path_sample_history () const
    {
        return path_sample_;
    }

    const std::vector<double> &get_path_width_history () const
    {
        return path_width_;
    }

    const std::vector<double> &get_path_grid_history () const
    {
        return path_grid_;
    }

    void toggle_show_progress ()
    {
        show_progress_ = !show_progress_;
    }

    private :

    /// Initialization indicator
    bool initialized_;

    /// Initialization and movement
    init_type init_;
    move_type move_;
    move_type mcmc_;

    /// Resampling
    vDist::RngGSL rng_;
    ResampleScheme scheme_;
    double threshold_;

    /// Particle sets
    Particle<T> particle_;
    std::size_t iter_num_;
    std::vector<double> ess_;
    std::vector<bool> resample_;
    std::vector<std::size_t> accept_;

    /// History
    History<T> history_;

    /// Monte Carlo estimation by integration
    mutable vDist::tool::Buffer<double> buffer_;
    std::map<std::string, Monitor<T> > monitor_;

    /// Path sampling
    path_type path_integral_;
    std::vector<double> path_sample_;
    std::vector<double> path_width_;
    std::vector<double> path_grid_;

    /// Whether to show prograss while iterating
    bool show_progress_;

    void post_move ()
    {
        ess_.push_back(particle_.ESS());

        bool res_indicator = false;
        if (ess_.back() < threshold_) {
            res_indicator = true;
            particle_.resample(scheme_, rng_.get_rng());
        }
        resample_.push_back(res_indicator);

        if (history_.mode() != HISTORY_NONE)
            history_.push_back(particle_);

        for (typename std::map<std::string, Monitor<T> >::iterator
                imap = monitor_.begin(); imap != monitor_.end(); ++imap) {
            if (!imap->second.empty())
                imap->second.eval(iter_num_, particle_);
        }

        if (!path_integral_.empty()) {
            double width;
            path_sample_.push_back(eval_path(width));
            path_width_.push_back(width);
            path_grid_.push_back(path_grid_.size() ?
                    path_grid_.back() + width : width);
        }

        if (show_progress_) {
            std::cerr << '.';
            std::cerr.flush();
        }
    }

    double eval_path (double &width)
    {
        width = path_integral_(iter_num_, particle_, buffer_);

        return cblas_ddot(particle_.size(),
                particle_.get_weight_ptr(), 1, buffer_, 1);
    }
}; // class Sampler

} // namespace vSMC

#endif // V_SMC_SAMPLER_HPP
<commit_msg>documentation update<commit_after>#ifndef V_SMC_SAMPLER_HPP
#define V_SMC_SAMPLER_HPP

#include <vSMC/config.hpp>

#include <map>
#include <stdexcept>
#include <string>
#include <vector>
#include <mkl_cblas.h>
#include <boost/function.hpp>
#include <vDist/rng/gsl.hpp>
#include <vDist/tool/buffer.hpp>
#include <vSMC/history.hpp>
#include <vSMC/monitor.hpp>
#include <vSMC/particle.hpp>

namespace vSMC {

template <typename T>
class Sampler
{
    public :

    /// The type of particle values
    typedef T value_type;
    /// The type of partiles
    typedef Particle<T> particle_type;
    /// The type of initialize callable objects
    typedef boost::function<std::size_t
        (Particle<T> &, void *)> init_type;
    /// The type of move callable objects
    typedef boost::function<std::size_t
        (std::size_t, Particle<T> &)> move_type;
    /// The type of importance sampling integral
    typedef boost::function<void
        (std::size_t, const Particle<T> &, double *, void *)> integral_type;
    /// The type of path sampling integration
    typedef boost::function<double
        (std::size_t, const Particle<T> &, double *)> path_type;

    /// \brief Sampler does not have a default constructor
    ///
    /// \param N The number of particles
    /// \param init The functor used to initialize the particles
    /// \param move The functor used to move the particles and weights
    /// \param copy The functor used to copy particles within the sample
    /// \param mcmc The functor used to perform MCMC move
    /// \param mode The history storage mode. See HistoryMode
    /// \param scheme The resampling scheme. See ResampleScheme
    /// \param threshold The threshold for performing resampling
    /// \param seed The seed for the reampling RNG. See documentation of vDist
    /// \param brng The basic RNG for resampling RNG. See documentation of GSL
    Sampler (
            std::size_t N,
            const init_type &init,
            const move_type &move,
            const typename Particle<T>::copy_type &copy,
            const move_type &mcmc = NULL,
            HistoryMode mode = HISTORY_NONE,
            ResampleScheme scheme = RESIDUAL,
            double threshold = 0.5,
            const int seed = V_DIST_SEED,
            const gsl_rng_type *brng = V_DIST_GSL_BRNG) :
        initialized_(false), init_(init), move_(move), mcmc_(mcmc),
        rng_(seed, brng), scheme_(scheme), threshold_(threshold * N),
        particle_(N, copy), iter_num_(0), history_(mode),
        buffer_(N), path_integral_(NULL), show_progress_(false) {}

    /// \brief Get ESS
    ///
    /// \return The ESS value of the latest iteration
    double get_ESS () const
    {
        return ess_.back();
    }

    /// \brief Get all ESS
    ///
    /// \return History of ESS for all iterations
    const std::vector<double> &get_ESS_history () const
    {
        return ess_;
    }

    /// \brief Get indicator of resampling
    ///
    /// \return A bool value, \b true if the latest iteration was resampled
    bool get_resample () const
    {
        return resample_.back();
    }

    /// \brief Get history of resampling
    ///
    /// \return History of resampling for all iterations
    const std::vector<bool> &get_resample_history () const
    {
        return resample_;
    }

    /// \brief Get accept count
    ///
    /// \return The accept count of the latest iteration
    std::size_t get_accept () const
    {
        return accept_.back();
    }

    /// \brief Get history of accept count
    ///
    /// \return History of accept count for all iterations
    const std::vector<std::size_t> &get_accept_history () const
    {
        return accept_;
    }

    /// \brief Read only access to the particle set
    ///
    /// \return A const reference to the latest particle set.
    /// \note Any operations that change the state of the sampler (e.g., an
    /// iteration) may invalidate the reference.
    const Particle<T> &particle () const
    {
        return particle_;
    }

    /// \brief (Re)initialize the particle set
    ///
    /// \param param Additional parameters passed to initialization functor,
    /// the default is NULL
    void initialize (void *param = NULL)
    {
        history_.clear();
        ess_.clear();
        resample_.clear();
        accept_.clear();

        for (typename std::map<std::string, Monitor<T> >::iterator
                imap = monitor_.begin(); imap != monitor_.end(); ++imap)
            imap->second.clear();

        path_sample_.clear();
        path_width_.clear();
        path_grid_.clear();

        iter_num_ = 0;
        accept_.push_back(init_(particle_, param));
        post_move();

        initialized_ = true;
    }

    /// \brief Perform iteration
    void iterate ()
    {
        if (!initialized_)
            throw std::runtime_error(
                    "ERROR: vSMC::Sampler::iterate: "
                    "Sampler has not been initialized yet");

        ++iter_num_;
        accept_.push_back(move_(iter_num_, particle_));
        if (mcmc_)
            accept_.back() = mcmc_(iter_num_, particle_);
        post_move();
    }

    /// \brief Perform iteration
    ///
    /// \param n The number of iterations to be performed
    void iterate (std::size_t n)
    {
        for (std::size_t i = 0; i != n; ++i)
            iterate();
    }

    /// \brief Perform importance sampling integration
    ///
    /// \param intgral The functor used to compute the integrands
    double integrate (typename Monitor<T>::integral_type integral) const
    {
        std::size_t n = particle_.size();
        integral(iter_num_, particle_, buffer_);

        return cblas_ddot(n, particle_.get_weight_ptr(), 1, buffer_, 1);
    }

    /// \brief Perform importance sampling integration
    ///
    /// \param intgral The functor used to compute the integrands
    /// \param param Additional parameters to be passed to integral
    double integrate (integral_type integral, void *param) const
    {
        std::size_t n = particle_.size();
        integral(iter_num_, particle_, buffer_, param);

        return cblas_ddot(n, particle_.get_weight_ptr(), 1, buffer_, 1);
    }

    /// \brief Add a monitor, similar to \b monitor in \b BUGS
    ///
    /// \param name The name of the monitor
    /// \param integral The functor used to compute the integrands
    void add_monitor (const std::string &name,
            const typename Monitor<T>::integral_type &integral)
    {
        monitor_.insert(
                typename std::map<std::string, Monitor<T> >::value_type(
                    name, Monitor<T>(particle_.size(), integral)));
    }

    /// \brief Get the iteration index of a monitor
    ///
    /// \param The name of the monitor
    /// \return A vector of the monitor index
    typename Monitor<T>::index_type get_monitor_index (
            const std::string &name) const
    {
        return monitor_.find(name)->second.get_index();
    }

    /// \brief Get the record of Monite Carlo integration of a monitor
    ///
    /// \param name The name of the monitor
    /// \return A vector of the monitor record
    typename Monitor<T>::record_type get_monitor_record (
            const std::string &name) const
    {
        return monitor_.find(name)->second.get_record();
    }

    /// \brief Get both the iteration index and record of a monitor
    ///
    /// \param name The name of the monitor
    /// \return A pair of vectors of the monitor record and index
    typename Monitor<T>::value_type get_monitor_value (
            const std::string &name) const
    {
        return monitor_.find(name)->second.get();
    }

    /// \brief Erase a monitor by name
    ///
    /// \param name The name of the monitor
    void erase_monitor (const std::string &name)
    {
        monitor_.erase(name);
    }

    /// \brief Clear all monitors
    void clear_monitor ()
    {
        monitor_.clear();
    }

    /// \brief Set the path sampling integral
    ///
    /// \param integral The functor used to compute the integrands
    void set_path_sampling (path_type integral)
    {
        path_integral_ = integral;
    }

    /// \brief Stop path sampling
    void clear_path_sampling ()
    {
        path_integral_ = NULL;
    }

    /// \brief Get the results of path sampling
    ///
    /// \return The path sampling integration result
    double get_path_sampling () const
    {
	std::size_t num = path_sample_.size();
	double sum = 0;
	for (std::size_t i = 1; i != num; ++i)
            sum += (path_sample_[i-1] + path_sample_[i])
                * path_width_[i] * 0.5;
        return sum;
    }

    /// \brief Get the history of path sampling integrand
    ///
    /// \return A vector of the path sampling integrand history
    const std::vector<double> &get_path_sample_history () const
    {
        return path_sample_;
    }

    /// \brief Get the history of path sampling width
    ///
    /// \return A vector of the path sampling width history
    const std::vector<double> &get_path_width_history () const
    {
        return path_width_;
    }

    /// \brief Get the history of path sampling grid
    ///
    /// \return A vector of the path sampling accumulative width history
    const std::vector<double> &get_path_grid_history () const
    {
        return path_grid_;
    }

    /// \brief Toggle whether or not show progress information while iterating
    void toggle_show_progress ()
    {
        show_progress_ = !show_progress_;
    }

    private :

    /// Initialization indicator
    bool initialized_;

    /// Initialization and movement
    init_type init_;
    move_type move_;
    move_type mcmc_;

    /// Resampling
    vDist::RngGSL rng_;
    ResampleScheme scheme_;
    double threshold_;

    /// Particle sets
    Particle<T> particle_;
    std::size_t iter_num_;
    std::vector<double> ess_;
    std::vector<bool> resample_;
    std::vector<std::size_t> accept_;

    /// History
    History<T> history_;

    /// Monte Carlo estimation by integration
    mutable vDist::tool::Buffer<double> buffer_;
    std::map<std::string, Monitor<T> > monitor_;

    /// Path sampling
    path_type path_integral_;
    std::vector<double> path_sample_;
    std::vector<double> path_width_;
    std::vector<double> path_grid_;

    /// Whether to show prograss while iterating
    bool show_progress_;

    void post_move ()
    {
        ess_.push_back(particle_.ESS());

        bool res_indicator = false;
        if (ess_.back() < threshold_) {
            res_indicator = true;
            particle_.resample(scheme_, rng_.get_rng());
        }
        resample_.push_back(res_indicator);

        if (history_.mode() != HISTORY_NONE)
            history_.push_back(particle_);

        for (typename std::map<std::string, Monitor<T> >::iterator
                imap = monitor_.begin(); imap != monitor_.end(); ++imap) {
            if (!imap->second.empty())
                imap->second.eval(iter_num_, particle_);
        }

        if (!path_integral_.empty()) {
            double width;
            path_sample_.push_back(eval_path(width));
            path_width_.push_back(width);
            path_grid_.push_back(path_grid_.size() ?
                    path_grid_.back() + width : width);
        }

        if (show_progress_) {
            std::cerr << '.';
            std::cerr.flush();
        }
    }

    double eval_path (double &width)
    {
        width = path_integral_(iter_num_, particle_, buffer_);

        return cblas_ddot(particle_.size(),
                particle_.get_weight_ptr(), 1, buffer_, 1);
    }
}; // class Sampler

} // namespace vSMC

#endif // V_SMC_SAMPLER_HPP
<|endoftext|>


<commit_before>
#include <vector>
#include <string>
#include <unordered_map>
#include <memory>
#include <iostream>
#include <cctype>
#include <SDL.h>
#include <SDL_opengl.h>
#include <SDL_net.h>
#include <SOIL.h>
#include <res_path.h>
#include <scheme-defs.h>
#include <scheme-private.h>
#include <scheme.h>

#include "hashstring.h"
#include "locator.h"
#include "servicecounter.h"
#include "service.h"
#include "servicecheckout.h"
#include "scripting.h"
#include "tinyscm_if.h"
#include "image.h"

extern SDL_sem* global_lock;

extern "C" {
	void register_image_functions(scheme* sc);
}

namespace venk
{

const char *ImageService::computeName(const char *name)
{
    static char imageName[Image::maxImageNameLength];

    extern size_t strnlen(const char *string, size_t maxlen);

    // skip '.tga'
    int end = 0;
    while (isalnum(name[end]))
        end++;
    strncpy(imageName, name, end);
    imageName[end] = '\0';
    return imageName;
}

bool ImageService::initialise(ImageService* self)
{
	(void) self;
	ServiceCheckout<ScriptingService> scripting;
	scheme* sc = scripting->get_scheme();
	register_image_functions(sc);
    return true;
}

bool ImageService::shutdown(ImageService* self)
{
	self->imageTable.clear();
    return true;
}

std::shared_ptr<Image> ImageService::loadImage(const char *filename)
{
	SDL_assert((filename != nullptr) && (strlen(filename) < Image::maxImageNameLength));
    std::shared_ptr<Image> image = std::make_shared<Image>(filename);
    const char *imagename = computeName(filename);
    std::cerr << "Loaded image " << imagename << std::endl;
    imageTable.insert(ImageLookupTable_t::value_type(imagename, image));
    return image;
}

std::shared_ptr<Image> ImageService::makeImage(const char* name, const Uint8* mem, int width, int height, int channels)
{
    std::shared_ptr<Image> image = std::make_shared<Image>(mem, height, width, channels);
    imageTable.insert(ImageLookupTable_t::value_type(name, image));
    return image;
}

std::shared_ptr<Image> ImageService::getImage(const char *name)
{
    const char *imagename = computeName(name);
    return std::shared_ptr<Image>(imageTable.find(imagename)->second);
}

std::function<const char*()> ImageService::enumerateImages()
{
	ImageLookupTable_t::iterator  image_it = imageTable.begin();
	auto result = [=]() mutable -> const char*
	{
		if (image_it != imageTable.end()) {
			const char* name = (image_it->first).c_str();
			++image_it;
			return name;
		}
		return nullptr;
	};
	return result;
}
// -------------------- Image methods --------------------

Image::Image(const Uint8* mem, int width, int height, int channels) : mWidth(width), mHeight(height), mChannels(channels)
{
	Sint64 size = width*height;
	mPixels = SOIL_load_image_from_memory((const unsigned char *)mem, size, &mWidth, &mHeight, &mChannels, SOIL_LOAD_AUTO);
	return;
}

Image::Image(const std::string& fileName) : mPixels(nullptr)
{
    std::string fullFileName = getResourcePath();
    fullFileName = fullFileName + "images/" + fileName;
    SDL_RWops *rwops = SDL_RWFromFile(fullFileName.c_str(), "rb");
    if (rwops != nullptr)
    {
        Sint64 size = SDL_RWsize(rwops);
        if (size != -1L)
        {
            void *buf = SDL_malloc(size);
            size_t read = SDL_RWread(rwops, buf, 1, size);
            if (read == size)
            {
                mPixels = SOIL_load_image_from_memory((const unsigned char *)buf, size, &mWidth, &mHeight, &mChannels, SOIL_LOAD_AUTO);
                if (mPixels != nullptr)
                {
                    SDL_RWclose(rwops);
                    return;
                }
                else
                {
                    std::cerr << "Creating " << fileName << " failed" << std::endl;
                }
            }
            else
            {
                std::cerr << "Reading " << fileName << " failed" << std::endl;
            }
            SDL_free(buf);
        }
        else
        {
            std::cerr << "Probing " << fileName << " failed" << std::endl;
        }
    }
    else
    {
        std::cerr << "Opening " << fileName << " failed" << std::endl;
    }
    SDL_RWclose(rwops);
    return;
}

std::shared_ptr<SDL_Surface> Image::surface() const
{
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
    Uint32 rmask = 0xff000000;
    Uint32 gmask = 0x00ff0000;
    Uint32 bmask = 0x0000ff00;
    Uint32 amask = 0x000000ff;
#else
    Uint32 rmask = 0x000000ff;
    Uint32 gmask = 0x0000ff00;
    Uint32 bmask = 0x00ff0000;
    Uint32 amask = 0xff000000;
#endif

    auto surface_deleter = [](SDL_Surface * s)
    {
        if (s) SDL_FreeSurface(s);
    };
    std::shared_ptr<SDL_Surface> result(
		SDL_CreateRGBSurfaceFrom(mPixels, mWidth, mHeight, mChannels * 8, mWidth * mChannels,
								 rmask, gmask, bmask, amask ),
		surface_deleter);
    return result;
}

Image::~Image()
{
    if (mPixels != nullptr)
        SOIL_free_image_data(mPixels);
}

// Scheme bindings

extern "C"
{
	static const char* imageTag = "IMAGE";

	/* to manage the lifetime of images in scheme */
	typedef std::unordered_map< std::string, std::shared_ptr<Image> > SchemeImageTable_t;
	SchemeImageTable_t scheme_images;

	/* this will get called when the scheme garbage collector wants it gone */
	void scheme_image_delete(void* ptr)
	{
		const char *ref = (const char*) ptr;
		scheme_images.erase(ref);
		SDL_free(ptr);
	}

	/* add an image in scheme vector form to the image management */
	pointer add_image_from_scheme(scheme *sc, pointer args)
	{
		hold_global_lock();
		pointer name_arg;
		if( is_string( name_arg = pair_car(args)) )
		{
			char *name;
			name = string_value( name_arg );
			std::cout << "Creating image named " << name << std::endl;
			if (scheme_images.find(name) != scheme_images.end() )
			{
				std::cout << "Image named " << name << " already exists " << std::endl;
				goto bad_args;
			}
			// to do - need height & width
			args = pair_cdr(args);
			long width = 0;
			if ((args != nullptr) && (is_integer(pair_car(args))))
			{
				width = ivalue(pair_car(args));
			} else {
				goto bad_args;
			}
			// to do - need height & width
			args = pair_cdr(args);
			long height = 0;
			if ((args != nullptr) && (is_integer(pair_car(args))))
			{
				height = ivalue(pair_car(args));
			} else {
				goto bad_args;
			}
			args = pair_cdr(args);
			if (!is_pair(args))
				goto bad_args;
			pointer image_arg = pair_car(args);
			if ( is_pair(image_arg) ) {
				int    channel_size = height * width;
				int    nchannels = list_length(sc, image_arg);
				int    channeli  = nchannels - 1;
				Uint8 *buf = (Uint8*) SDL_malloc(nchannels * channel_size);
				while ((image_arg != nullptr) && (image_arg != sc->NIL))
				{
					if (!is_pair(image_arg))
						goto bad_args;

					if (!is_pair(pair_car(image_arg)))
						goto bad_args;

					pointer channel_name = pair_car(pair_car(image_arg));
					if (is_symbol(channel_name)) {
						std::cout << "Channel : " << symname(channel_name) << std::endl;
					} else {
						goto bad_args;
					}
					pointer channel_data = pair_car(pair_cdr(image_arg));
					if (is_vector(channel_data)) {
						channel_size = ivalue(channel_data);
						std::cout << "Size : " << ivalue(channel_data) << " bytes." << std::endl;
						for(Sint32 i = 0; i < ivalue(channel_data); i++) {
							pointer element = vector_elem(channel_data,i);
							if (!is_number(element))
								goto bad_args;
							buf[i*nchannels+channeli] = (Uint8)(rvalue(element) * 255.0);
						}
					} else {
						goto bad_args;
					}
					channeli--;
					image_arg = pair_cdr(image_arg);
				}
				ServiceCheckout<ImageService> images;
				// to do -- table of scheme managed images / table or opaque type?
				std::shared_ptr<Image> scheme_image = images->makeImage(name, buf, width, height, nchannels);
				SDL_free(buf);
				auto result = scheme_images.emplace(make_pair(name, scheme_image));
				if (!result.second) {
					std::cout << "image : " << name << " insertion failed" << std::endl;
					goto bad_args;
				}
				const char* ref = SDL_strdup(name);
				release_global_lock();
				return mk_opaque(sc, imageTag, (void*) ref, scheme_image_delete);
			}
		}
  bad_args:
		release_global_lock();
		std::cout << "Bad arguments " << std::endl;
		return sc->F;
	}

	pointer image_names(scheme* sc, pointer args)
	{
		hold_global_lock();
		if(args != sc->NIL)
		{
			return sc->F;
		}
		ServiceCheckout<ImageService> images;
		auto enumerator = images->enumerateImages();
		const char* name = nullptr;
		pointer result = sc->NIL;
		while( (name = enumerator()) != nullptr )
		{
			result = cons(sc, mk_string(sc, name), result);
		}
		release_global_lock();
		return result;
	}

	void register_image_functions(scheme* sc)
	{
		/* inline lustration how to define a "foreign" function
		   implemented in C */
		scheme_define(sc,sc->global_env,mk_symbol(sc,"image-names"),mk_foreign_func(sc, image_names));
		scheme_define(sc,sc->global_env,mk_symbol(sc,"add-image"),mk_foreign_func(sc, add_image_from_scheme));

	}
}

}

<commit_msg>Added image loading from scheme.<commit_after>
#include <vector>
#include <string>
#include <unordered_map>
#include <memory>
#include <iostream>
#include <cctype>
#include <SDL.h>
#include <SDL_opengl.h>
#include <SDL_net.h>
#include <SOIL.h>
#include <physfs.h>
#include <res_path.h>
#include <scheme-defs.h>
#include <scheme-private.h>
#include <scheme.h>

#include "hashstring.h"
#include "locator.h"
#include "servicecounter.h"
#include "service.h"
#include "servicecheckout.h"
#include "scripting.h"
#include "tinyscm_if.h"
#include "image.h"

extern SDL_sem* global_lock;

extern "C" {
	void register_image_functions(scheme* sc);
}

namespace venk
{

const char *ImageService::computeName(const char *name)
{
    static char imageName[Image::maxImageNameLength];

    extern size_t strnlen(const char *string, size_t maxlen);

    // skip '.tga'
    int end = 0;
    while (isalnum(name[end]))
        end++;
    strncpy(imageName, name, end);
    imageName[end] = '\0';
    return imageName;
}

bool ImageService::initialise(ImageService* self)
{
	(void) self;
	ServiceCheckout<ScriptingService> scripting;
	scheme* sc = scripting->get_scheme();
	register_image_functions(sc);
    return true;
}

bool ImageService::shutdown(ImageService* self)
{
	self->imageTable.clear();
    return true;
}

std::shared_ptr<Image> ImageService::loadImage(const char *filename)
{
	SDL_assert((filename != nullptr) && (strlen(filename) < Image::maxImageNameLength));
    std::shared_ptr<Image> image = std::make_shared<Image>(filename);
	if (image) {
		const char *imagename = computeName(filename);
		std::cerr << "Loaded image " << imagename << std::endl;
		imageTable.insert(ImageLookupTable_t::value_type(imagename, image));
	}
    return image;
}

std::shared_ptr<Image> ImageService::makeImage(const char* name, const Uint8* mem, int width, int height, int channels)
{
    std::shared_ptr<Image> image = std::make_shared<Image>(mem, height, width, channels);
    imageTable.insert(ImageLookupTable_t::value_type(name, image));
    return image;
}

std::shared_ptr<Image> ImageService::getImage(const char *name)
{
    const char *imagename = computeName(name);
    return std::shared_ptr<Image>(imageTable.find(imagename)->second);
}

std::function<const char*()> ImageService::enumerateImages()
{
	ImageLookupTable_t::iterator  image_it = imageTable.begin();
	auto result = [=]() mutable -> const char*
	{
		if (image_it != imageTable.end()) {
			const char* name = (image_it->first).c_str();
			++image_it;
			return name;
		}
		return nullptr;
	};
	return result;
}
// -------------------- Image methods --------------------

Image::Image(const Uint8* mem, int width, int height, int channels) : mWidth(width), mHeight(height), mChannels(channels)
{
	Sint64 size = width*height;
	mPixels = SOIL_load_image_from_memory((const unsigned char *)mem, size, &mWidth, &mHeight, &mChannels, SOIL_LOAD_AUTO);
	return;
}

Image::Image(const std::string& fileName) : mPixels(nullptr)
{
    std::string fullFileName = getResourcePath();
    fullFileName = fullFileName + "images/" + fileName;
    SDL_RWops *rwops = SDL_RWFromFile(fullFileName.c_str(), "rb");
    if (rwops != nullptr)
    {
        Sint64 size = SDL_RWsize(rwops);
        if (size != -1L)
        {
            void *buf = SDL_malloc(size);
            size_t read = SDL_RWread(rwops, buf, 1, size);
            if (read == size)
            {
                mPixels = SOIL_load_image_from_memory((const unsigned char *)buf, size, &mWidth, &mHeight, &mChannels, SOIL_LOAD_AUTO);
                if (mPixels != nullptr)
                {
                    SDL_RWclose(rwops);
                    return;
                }
                else
                {
                    std::cerr << "Creating " << fileName << " failed" << std::endl;
                }
            }
            else
            {
                std::cerr << "Reading " << fileName << " failed" << std::endl;
            }
            SDL_free(buf);
        }
        else
        {
            std::cerr << "Probing " << fileName << " failed" << std::endl;
        }
		SDL_RWclose(rwops);
    }
    else
    {
        std::cerr << "Opening " << fileName << " failed" << std::endl;
    }
    return;
}

std::shared_ptr<SDL_Surface> Image::surface() const
{
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
    Uint32 rmask = 0xff000000;
    Uint32 gmask = 0x00ff0000;
    Uint32 bmask = 0x0000ff00;
    Uint32 amask = 0x000000ff;
#else
    Uint32 rmask = 0x000000ff;
    Uint32 gmask = 0x0000ff00;
    Uint32 bmask = 0x00ff0000;
    Uint32 amask = 0xff000000;
#endif

    auto surface_deleter = [](SDL_Surface * s)
    {
        if (s) SDL_FreeSurface(s);
    };
    std::shared_ptr<SDL_Surface> result(
		SDL_CreateRGBSurfaceFrom(mPixels, mWidth, mHeight, mChannels * 8, mWidth * mChannels,
								 rmask, gmask, bmask, amask ),
		surface_deleter);
    return result;
}

Image::~Image()
{
    if (mPixels != nullptr)
        SOIL_free_image_data(mPixels);
}

// Scheme bindings

extern "C"
{
	static const char* imageTag = "IMAGE";

	/* to manage the lifetime of images in scheme */
	typedef std::unordered_map< std::string, std::shared_ptr<Image> > SchemeImageTable_t;
	SchemeImageTable_t scheme_images;

	/* this will get called when the scheme garbage collector wants it gone */
	void scheme_image_delete(void* ptr)
	{
		const char *ref = (const char*) ptr;
		scheme_images.erase(ref);
		SDL_free(ptr);
	}

	/* add an image in scheme vector form to the image management */
	pointer add_image_from_scheme(scheme *sc, pointer args)
	{
		hold_global_lock();
		pointer name_arg;
		if( is_string( name_arg = pair_car(args)) )
		{
			char *name;
			name = string_value( name_arg );
			std::cout << "Creating image named " << name << std::endl;
			if (scheme_images.find(name) != scheme_images.end() )
			{
				std::cout << "Image named " << name << " already exists " << std::endl;
				goto bad_args;
			}
			// to do - need height & width
			args = pair_cdr(args);
			long width = 0;
			if ((args != nullptr) && (is_integer(pair_car(args))))
			{
				width = ivalue(pair_car(args));
			} else {
				goto bad_args;
			}
			// to do - need height & width
			args = pair_cdr(args);
			long height = 0;
			if ((args != nullptr) && (is_integer(pair_car(args))))
			{
				height = ivalue(pair_car(args));
			} else {
				goto bad_args;
			}
			args = pair_cdr(args);
			if (!is_pair(args))
				goto bad_args;
			pointer image_arg = pair_car(args);
			if ( is_pair(image_arg) ) {
				int    channel_size = height * width;
				int    nchannels = list_length(sc, image_arg);
				int    channeli  = nchannels - 1;
				Uint8 *buf = (Uint8*) SDL_malloc(nchannels * channel_size);
				while ((image_arg != nullptr) && (image_arg != sc->NIL))
				{
					if (!is_pair(image_arg))
						goto bad_args;

					if (!is_pair(pair_car(image_arg)))
						goto bad_args;

					pointer channel_name = pair_car(pair_car(image_arg));
					if (is_symbol(channel_name)) {
						std::cout << "Channel : " << symname(channel_name) << std::endl;
					} else {
						goto bad_args;
					}
					pointer channel_data = pair_car(pair_cdr(image_arg));
					if (is_vector(channel_data)) {
						channel_size = ivalue(channel_data);
						std::cout << "Size : " << ivalue(channel_data) << " bytes." << std::endl;
						for(Sint32 i = 0; i < ivalue(channel_data); i++) {
							pointer element = vector_elem(channel_data,i);
							if (!is_number(element))
								goto bad_args;
							buf[i*nchannels+channeli] = (Uint8)(rvalue(element) * 255.0);
						}
					} else {
						goto bad_args;
					}
					channeli--;
					image_arg = pair_cdr(image_arg);
				}
				ServiceCheckout<ImageService> images;
				// to do -- table of scheme managed images / table or opaque type?
				std::shared_ptr<Image> scheme_image = images->makeImage(name, buf, width, height, nchannels);
				SDL_free(buf);
				auto result = scheme_images.emplace(make_pair(name, scheme_image));
				if (!result.second) {
					std::cout << "image : " << name << " insertion failed" << std::endl;
					goto bad_args;
				}
				const char* ref = SDL_strdup(name);
				release_global_lock();
				return mk_opaque(sc, imageTag, (void*) ref, scheme_image_delete);
			}
		}
  bad_args:
		release_global_lock();
		std::cout << "Bad arguments " << std::endl;
		return sc->F;
	}

	pointer image_names(scheme* sc, pointer args)
	{
		hold_global_lock();
		if(args != sc->NIL)
		{
			release_global_lock();
			return sc->F;
		}
		ServiceCheckout<ImageService> images;
		auto enumerator = images->enumerateImages();
		const char* name = nullptr;
		pointer result = sc->NIL;
		while( (name = enumerator()) != nullptr )
		{
			result = cons(sc, mk_string(sc, name), result);
		}
		release_global_lock();
		return result;
	}

	pointer image_file_names(scheme* sc, pointer args)
	{
		hold_global_lock();
		if(args != sc->NIL)
		{
			release_global_lock();
			return sc->F;
		}
		pointer result = sc->NIL;
		char** flist = PHYSFS_enumerateFiles("images");
		for(char** i = flist; *i != nullptr; i++) {
			result = cons(sc, mk_string(sc, *i), result);
		}
		PHYSFS_freeList(flist);
		release_global_lock();
		return result;
	}

	pointer load_image(scheme* sc, pointer args)
	{
		hold_global_lock();
		if (is_string(pair_car(args))) {
			ServiceCheckout<ImageService> images;
			char *name = string_value(pair_car(args));
			std::shared_ptr<Image> image = images->loadImage(name);
			auto result = scheme_images.insert(make_pair(name, image));
			if (!result.second) {
				std::cout << "image : " << name << " loading failed" << std::endl;
				goto bad_args;
			}
			const char* ref = SDL_strdup(name);
			release_global_lock();
			return mk_opaque(sc, imageTag, (void*) ref, scheme_image_delete);
		}
  bad_args:
		release_global_lock();
		return sc->F;
	}

	void register_image_functions(scheme* sc)
	{
		/* inline lustration how to define a "foreign" function
		   implemented in C */
		scheme_define(sc,sc->global_env,mk_symbol(sc,"image-names"),mk_foreign_func(sc, image_names));
		scheme_define(sc,sc->global_env,mk_symbol(sc,"image-file-names"),mk_foreign_func(sc, image_file_names));
		scheme_define(sc,sc->global_env,mk_symbol(sc,"load-image"),mk_foreign_func(sc, load_image));
		scheme_define(sc,sc->global_env,mk_symbol(sc,"add-image"),mk_foreign_func(sc, add_image_from_scheme));

	}
}

}

<|endoftext|>


<commit_before>#include "indexer/feature_meta.hpp"

namespace feature
{
string Metadata::GetWikiURL() const
{
  string value = this->Get(FMD_WIKIPEDIA);
  string::size_type i = value.find(':');
  if (i == string::npos)
    return string();
  return "https://" + value.substr(0, i) + ".wikipedia.org/wiki/" + value.substr(i + 1);
}

char hex_to_dec(char ch)
{
  if (ch >= '0' && ch <= '9')
    return ch - '0';
  if (ch >= 'a')
    ch -= 32;
  if (ch >= 'A' && ch <= 'F')
    return ch - 'A' + 10;
  return -1;
}

string UriDecode(string const & sSrc)
{
  // This code was slightly modified from
  // http://www.codeguru.com/cpp/cpp/string/conversions/article.php/c12759
  //
  // Note from RFC1630: "Sequences which start with a percent
  // sign but are not followed by two hexadecimal characters
  // (0-9, A-F) are reserved for future extension"

  const unsigned char * pSrc = (const unsigned char *)sSrc.c_str();
  const string::size_type SRC_LEN = sSrc.length();
  const unsigned char * const SRC_END = pSrc + SRC_LEN;
  // last decodable '%'
  const unsigned char * const SRC_LAST_DEC = SRC_END - 2;

  char * const pStart = new char[SRC_LEN];
  char * pEnd = pStart;

  while (pSrc < SRC_LAST_DEC)
  {
    if (*pSrc == '%')
    {
      char dec1 = hex_to_dec(*(pSrc + 1));
      char dec2 = hex_to_dec(*(pSrc + 2));
      if (-1 != dec1 && -1 != dec2)
      {
        *pEnd++ = (dec1 << 4) + dec2;
        pSrc += 2;
      }
    }
    else if (*pSrc == '_')
      *pEnd++ = ' ';
    else
      *pEnd++ = *pSrc;
    pSrc++;
  }

  // the last 2- chars
  while (pSrc < SRC_END)
    *pEnd++ = *pSrc++;

  string sResult(pStart, pEnd);
  delete [] pStart;
  return sResult;
}

string Metadata::GetWikiTitle() const
{
  string value = this->Get(FMD_WIKIPEDIA);
  return UriDecode(value);
}
}  // namespace feature
<commit_msg>[metadata] Review fixes<commit_after>#include "indexer/feature_meta.hpp"

namespace feature
{
string Metadata::GetWikiURL() const
{
  string value = this->Get(FMD_WIKIPEDIA);
  string::size_type i = value.find(':');
  if (i == string::npos)
    return string();
  return "https://" + value.substr(0, i) + ".wikipedia.org/wiki/" + value.substr(i + 1);
}

namespace
{
char HexToDec(char ch)
{
  if (ch >= '0' && ch <= '9')
    return ch - '0';
  if (ch >= 'a')
    ch -= 'a' - 'A';
  if (ch >= 'A' && ch <= 'F')
    return ch - 'A' + 10;
  return -1;
}

string UriDecode(string const & sSrc)
{
  // This code was slightly modified from
  // http://www.codeguru.com/cpp/cpp/string/conversions/article.php/c12759
  //
  // Note from RFC1630: "Sequences which start with a percent
  // sign but are not followed by two hexadecimal characters
  // (0-9, A-F) are reserved for future extension"

  unsigned char const * pSrc = (unsigned char const *)sSrc.c_str();
  string::size_type const srcLen = sSrc.length();
  unsigned char const * const srcEnd = pSrc + srcLen;
  // last decodable '%'
  unsigned char const * const srcLastDec = srcEnd - 2;

  char * const pStart = new char[srcLen];
  char * pEnd = pStart;

  while (pSrc < srcEnd)
  {
    if (*pSrc == '%')
    {
      if (pSrc < srcLastDec)
      {
        char dec1 = HexToDec(*(pSrc + 1));
        char dec2 = HexToDec(*(pSrc + 2));
        if (-1 != dec1 && -1 != dec2)
        {
          *pEnd++ = (dec1 << 4) + dec2;
          pSrc += 3;
          continue;
        }
      }
    }

    if (*pSrc == '_')
      *pEnd++ = ' ';
    else
      *pEnd++ = *pSrc;
    pSrc++;
  }

  string sResult(pStart, pEnd);
  delete [] pStart;
  return sResult;
}
}

string Metadata::GetWikiTitle() const
{
  string value = this->Get(FMD_WIKIPEDIA);
  return UriDecode(value);
}
}  // namespace feature
<|endoftext|>


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

#include <wx/xrc/xmlres.h>
#include <wx/config.h>
#include <wx/listbox.h>
#include <wx/stattext.h>
#include <wx/intl.h>

#include "summarydlg.h"
#include "utility.h"

MergeSummaryDialog::MergeSummaryDialog(wxWindow *parent)
{
    wxXmlResource::Get()->LoadDialog(this, parent, "summary");

    RestoreWindowState(this, wxDefaultSize, WinState_Size);
    CentreOnParent();
}

MergeSummaryDialog::~MergeSummaryDialog()
{
    SaveWindowState(this, WinState_Size);
}

void MergeSummaryDialog::TransferTo(const wxArrayString& snew, const wxArrayString& sobsolete)
{
    wxString sum;
    sum.Printf(_("(%i new, %i obsolete)"),
               snew.GetCount(), sobsolete.GetCount());
    XRCCTRL(*this, "items_count", wxStaticText)->SetLabel(sum);

    wxListBox *listbox;
    size_t i;

    listbox = XRCCTRL(*this, "new_strings", wxListBox);
    for (i = 0; i < snew.GetCount(); i++)
    {
        listbox->Append(snew[i]);
    }

    listbox = XRCCTRL(*this, "obsolete_strings", wxListBox);
    for (i = 0; i < sobsolete.GetCount(); i++)
    {
        listbox->Append(sobsolete[i]);
    }
}
<commit_msg>Fix incorrect printf() specifiers.<commit_after>/*
 *  This file is part of Poedit (http://www.poedit.net)
 *
 *  Copyright (C) 2000-2013 Vaclav Slavik
 *
 *  Permission is hereby granted, free of charge, to any person obtaining a
 *  copy of this software and associated documentation files (the "Software"),
 *  to deal in the Software without restriction, including without limitation
 *  the rights to use, copy, modify, merge, publish, distribute, sublicense,
 *  and/or sell copies of the Software, and to permit persons to whom the
 *  Software is furnished to do so, subject to the following conditions:
 *
 *  The above copyright notice and this permission notice shall be included in
 *  all copies or substantial portions of the Software.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 *  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 *  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 *  DEALINGS IN THE SOFTWARE.
 *
 */

#include <wx/xrc/xmlres.h>
#include <wx/config.h>
#include <wx/listbox.h>
#include <wx/stattext.h>
#include <wx/intl.h>

#include "summarydlg.h"
#include "utility.h"

MergeSummaryDialog::MergeSummaryDialog(wxWindow *parent)
{
    wxXmlResource::Get()->LoadDialog(this, parent, "summary");

    RestoreWindowState(this, wxDefaultSize, WinState_Size);
    CentreOnParent();
}

MergeSummaryDialog::~MergeSummaryDialog()
{
    SaveWindowState(this, WinState_Size);
}

void MergeSummaryDialog::TransferTo(const wxArrayString& snew, const wxArrayString& sobsolete)
{
    wxString sum;
    sum.Printf(_("(%i new, %i obsolete)"),
               (int)snew.GetCount(), (int)sobsolete.GetCount());
    XRCCTRL(*this, "items_count", wxStaticText)->SetLabel(sum);

    wxListBox *listbox;
    size_t i;

    listbox = XRCCTRL(*this, "new_strings", wxListBox);
    for (i = 0; i < snew.GetCount(); i++)
    {
        listbox->Append(snew[i]);
    }

    listbox = XRCCTRL(*this, "obsolete_strings", wxListBox);
    for (i = 0; i < sobsolete.GetCount(); i++)
    {
        listbox->Append(sobsolete[i]);
    }
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: accmap.hxx,v $
 *
 *  $Revision: 1.10 $
 *
 *  last change: $Author: mib $ $Date: 2002-04-11 13:53:13 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#ifndef _ACCMAP_HXX
#define _ACCMAP_HXX

#ifndef _DRAFTS_COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLE_HPP_
#include <drafts/com/sun/star/accessibility/XAccessible.hpp>
#endif

#ifndef _SAL_TYPES_H_
#include <sal/types.h>
#endif
#ifndef _VOS_REF_HXX_
#include <vos/ref.hxx>
#endif
#ifndef _VOS_MUTEX_HXX_ //autogen
#include <vos/mutex.hxx>
#endif
#ifndef _VIEWSH_HXX
#include "viewsh.hxx"
#endif

class Rectangle;
class SwFrm;
class SwRootFrm;
class SwAccessibleContext;
class SwAccessibleContextMap_Impl;
class SwAccessibleEventList_Impl;
class SwAccessibleEventMap_Impl;
struct SwAccessibleEvent_Impl;
class SwRect;
class ViewShell;

#define ACC_STATE_EDITABLE 0x01
#define ACC_STATE_OPAQUE 0x02
#define ACC_STATE_CARET 0x80

#define ACC_STATE_MASK 0x7F

class SwAccessibleMap
{
    ::vos::OMutex aMutex;
    ::vos::OMutex aEventMutex;
    SwAccessibleContextMap_Impl *pMap;
    SwAccessibleEventList_Impl *pEvents;
    SwAccessibleEventMap_Impl *pEventMap;
    ViewShell *pVSh;
    sal_Int32 nPara;
    sal_Int32 nFootnote;
    sal_Int32 nEndnote;

    static void FireEvent( const SwAccessibleEvent_Impl& rEvent );
    void AppendEvent( const SwAccessibleEvent_Impl& rEvent );

    void InvalidateCursorPosition(
        const ::com::sun::star::uno::Reference<
            ::drafts::com::sun::star::accessibility::XAccessible>& rAcc );

public:

    SwAccessibleMap( ViewShell *pSh );
    ~SwAccessibleMap();

    ::com::sun::star::uno::Reference<
        ::drafts::com::sun::star::accessibility::XAccessible> GetDocumentView();

    ::vos::ORef < SwAccessibleContext > GetContextImpl(
                                                 const SwFrm *pFrm,
                                                sal_Bool bCreate = sal_True );
    ::com::sun::star::uno::Reference<
        ::drafts::com::sun::star::accessibility::XAccessible> GetContext(
                                                 const SwFrm *pFrm,
                                                sal_Bool bCreate = sal_True );

    ViewShell *GetShell() const { return pVSh; }
    const SwRect& GetVisArea() const { return pVSh->VisArea(); }

    void RemoveContext( const SwFrm *pFrm );

    // Dispose frame and its children if bRecursive is set
    void Dispose( const SwFrm *pFrm, sal_Bool bRecursive=sal_False );

    void InvalidatePosOrSize( const SwFrm *pFrm, const SwRect& rOldFrm );

    void InvalidateContent( const SwFrm *pFrm );

    void InvalidateCursorPosition( const SwFrm *pFrm );

    void SetCursorContext(
        const ::vos::ORef < SwAccessibleContext >& rCursorContext );

    // Invalidate state of whole tree. If an action is open, this call
    // is processed when the last action ends.
    void InvalidateStates( sal_uInt8 nStates );

    void FireEvents();
};

#endif
<commit_msg>#95586#: XAccessibleTable<commit_after>/*************************************************************************
 *
 *  $RCSfile: accmap.hxx,v $
 *
 *  $Revision: 1.11 $
 *
 *  last change: $Author: mib $ $Date: 2002-04-17 14:26:24 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#ifndef _ACCMAP_HXX
#define _ACCMAP_HXX

#ifndef _DRAFTS_COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLE_HPP_
#include <drafts/com/sun/star/accessibility/XAccessible.hpp>
#endif

#ifndef _SAL_TYPES_H_
#include <sal/types.h>
#endif
#ifndef _VOS_REF_HXX_
#include <vos/ref.hxx>
#endif
#ifndef _VOS_MUTEX_HXX_ //autogen
#include <vos/mutex.hxx>
#endif
#ifndef _VIEWSH_HXX
#include "viewsh.hxx"
#endif

class Rectangle;
class SwFrm;
class SwRootFrm;
class SwAccessibleContext;
class SwAccessibleContextMap_Impl;
class SwAccessibleEventList_Impl;
class SwAccessibleEventMap_Impl;
struct SwAccessibleEvent_Impl;
class SwRect;
class ViewShell;

// real states for events
#define ACC_STATE_EDITABLE 0x01
#define ACC_STATE_OPAQUE 0x02

// pseudo states for events
#define ACC_STATE_CARET 0x80

#define ACC_STATE_MASK 0x7F

class SwAccessibleMap
{
    ::vos::OMutex maMutex;
    ::vos::OMutex maEventMutex;
    SwAccessibleContextMap_Impl *mpMap;
    SwAccessibleEventList_Impl *mpEvents;
    SwAccessibleEventMap_Impl *mpEventMap;
    ViewShell *mpVSh;
    sal_Int32 mnPara;
    sal_Int32 mnFootnote;
    sal_Int32 mnEndnote;

    static void FireEvent( const SwAccessibleEvent_Impl& rEvent );
    void AppendEvent( const SwAccessibleEvent_Impl& rEvent );

    void InvalidateCursorPosition(
        const ::com::sun::star::uno::Reference<
            ::drafts::com::sun::star::accessibility::XAccessible>& rAcc );

public:

    SwAccessibleMap( ViewShell *pSh );
    ~SwAccessibleMap();

    ::com::sun::star::uno::Reference<
        ::drafts::com::sun::star::accessibility::XAccessible> GetDocumentView();

    ::vos::ORef < SwAccessibleContext > GetContextImpl(
                                                 const SwFrm *pFrm,
                                                sal_Bool bCreate = sal_True );
    ::com::sun::star::uno::Reference<
        ::drafts::com::sun::star::accessibility::XAccessible> GetContext(
                                                 const SwFrm *pFrm,
                                                sal_Bool bCreate = sal_True );

    ViewShell *GetShell() const { return mpVSh; }
    const SwRect& GetVisArea() const { return mpVSh->VisArea(); }

    void RemoveContext( const SwFrm *pFrm );

    // Dispose frame and its children if bRecursive is set
    void Dispose( const SwFrm *pFrm, sal_Bool bRecursive=sal_False );

    void InvalidatePosOrSize( const SwFrm *pFrm, const SwRect& rOldFrm );

    void InvalidateContent( const SwFrm *pFrm );

    void InvalidateCursorPosition( const SwFrm *pFrm );

    void SetCursorContext(
        const ::vos::ORef < SwAccessibleContext >& rCursorContext );

    // Invalidate state of whole tree. If an action is open, this call
    // is processed when the last action ends.
    void InvalidateStates( sal_uInt8 nStates );

    void FireEvents();
};

#endif
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: calbck.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: rt $ $Date: 2006-02-09 14:53:27 $
 *
 *  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
 *
 ************************************************************************/

/*************************************************************
#* Service-Klassen
 *************************************************************/

/*
#* Aendert sich ein Attribut in einem Format, so muss diese
#* Aenderung an alle abhaengigen Formate und ueber sie an
#* alle betroffenen Nodes propagiert werden. Dabei muss
#* festgestellt werden, ob die Aenderung einen Effekt haben
#* kann, oder ob das geaenderte Attribut von dem abhaengigen
#* Format ueberdefiniert wird (so dass ohnehin der
#* Attributwert des abhaengigen Formates den geaenderten
#* Wert verdeckt). Weiterhin kann der betroffene Node
#* feststellen, ob er von dem geaenderten Attribut Gebrauch
#* macht (Beispiel: Linienabstand fuer Unterstreichung wurde
#* geaendert, das Attribut Unterstreichung wurde aber nicht
#* verwendet). So wird bei Aenderungen der minimale Aufwand
#* zum Reformatieren erkannt.
 */
#ifndef _CALBCK_HXX
#define _CALBCK_HXX

#ifndef _SOLAR_H
#include <tools/solar.h>
#endif

#ifndef _RTTI_HXX
#include <tools/rtti.hxx>
#endif

#ifndef INCLUDED_SWDLLAPI_H
#include "swdllapi.h"
#endif

class SwModify;
class SwClientIter;
class SfxPoolItem;
class SvStream;

// ----------
// SwClient
// ----------

class SW_DLLPUBLIC SwClient
{
    friend class SwModify;
    friend class SwClientIter;

    SwClient *pLeft, *pRight;           // fuer die AVL-Sortierung
    BOOL bModifyLocked : 1;             // wird in SwModify::Modify benutzt,
                                        // eigentlich ein Member des SwModify
                                        // aber aus Platzgruenden hier.
    BOOL bInModify  : 1;                // ist in einem Modify. (Debug!!!)
    BOOL bInDocDTOR : 1;                // Doc wird zerstoert, nicht "abmelden"
    BOOL bInCache   : 1;                // Ist im BorderAttrCache des Layout,
                                        // Traegt sich dann im Modify aus!
    BOOL bInSwFntCache : 1;             // Ist im SwFont-Cache der Formatierung

protected:
    SwModify *pRegisteredIn;

    // single argument ctors shall be explicit.
    explicit SwClient(SwModify *pToRegisterIn);

public:
    inline SwClient();
    virtual ~SwClient();

    virtual void Modify( SfxPoolItem *pOld, SfxPoolItem *pNew);
    const SwModify* GetRegisteredIn() const { return pRegisteredIn; }

    //rtti, abgeleitete moegens gleichtun oder nicht. Wenn sie es gleichtun
    //kann ueber die Abhaengigkeitsliste eines Modify typsicher gecastet
    //werden.
    TYPEINFO();

    void LockModify()                   { bModifyLocked = TRUE;  }
    void UnlockModify()                 { bModifyLocked = FALSE; }
    void SetInCache( BOOL bNew )        { bInCache = bNew;       }
    void SetInSwFntCache( BOOL bNew )   { bInSwFntCache = bNew;  }
    int  IsModifyLocked() const         { return bModifyLocked;  }
    int  IsInDocDTOR()    const         { return bInDocDTOR;     }
    int  IsInCache()      const         { return bInCache;       }
    int  IsInSwFntCache()  const        { return bInSwFntCache;  }

        // erfrage vom Client Informationen
    virtual BOOL GetInfo( SfxPoolItem& ) const;

private:
    SwClient( const SwClient& );
    SwClient &operator=( const SwClient& );
};

inline SwClient::SwClient() :
    pLeft(0), pRight(0), pRegisteredIn(0)
{ bModifyLocked = bInModify = bInDocDTOR = bInCache = bInSwFntCache = FALSE; }

// ----------
// SwModify
// ----------

// Klasse hat eine doppelt Verkette Liste fuer die Abhaengigen.

class SW_DLLPUBLIC SwModify: public SwClient
{
    friend SvStream& operator<<( SvStream& aS, SwModify & );

    friend class SwClientIter;
    SwClient* pRoot;

    SW_DLLPRIVATE SwClient *_Remove(SwClient *pDepend);

public:
    SwModify() : pRoot(0) {}

    // single argument ctors shall be explicit.
    explicit SwModify(SwModify *pToRegisterIn );
    virtual ~SwModify();

    virtual void Modify( SfxPoolItem *pOldValue, SfxPoolItem *pNewValue );
    void Add(SwClient *pDepend);
    SwClient *Remove(SwClient *pDepend)
        {   return bInDocDTOR ?  0 : _Remove( pDepend ); }

    const SwClient* GetDepends() const  { return pRoot; }

        // erfrage vom Client Informationen
    virtual BOOL GetInfo( SfxPoolItem& ) const;

    void SetInDocDTOR() { bInDocDTOR = TRUE; }

    void CheckCaching( const USHORT nWhich );

    BOOL IsLastDepend() const
        { return pRoot && !pRoot->pLeft && !pRoot->pRight; }

private:
    // forbidden and not implemented (see @ SwClient).
    SwModify & operator= (const SwModify &);

protected:
    // forbidden and not implemented (see @ SwClient),
    //   but GCC >= 3.4 needs an accessible "T (const T&)"
    //   to pass a "T" as a "const T&" argument
    SwModify (const SwModify &);
};

// ----------
// SwDepend
// ----------

/*
 * Sehr sinnvolle Klasse, wenn ein Objekt von mehreren Objekten
 * abhaengig ist. Diese sollte fuer jede Abhaengigkeit ein Objekt
 * der Klasse SwDepend als Member haben.
 */
class SwDepend: public SwClient
{
    SwClient *pToTell;

public:
    SwDepend() : pToTell(0) {}
    SwDepend(SwClient *pTellHim, SwModify *pDepend);

    SwClient* GetToTell() { return pToTell; }
    virtual void Modify( SfxPoolItem *pOldValue, SfxPoolItem *pNewValue );

        // erfrage vom Client Informationen
    virtual BOOL GetInfo( SfxPoolItem & ) const;

private:
    // forbidden and not implemented (see @ SwClient).
    SwDepend (const SwDepend &);
    SwDepend & operator= (const SwDepend &);
};

class SW_DLLPUBLIC SwClientIter
{
    friend SwClient* SwModify::_Remove(SwClient *); // fuer Ptr-Korrektur
    friend void SwModify::Add(SwClient *);          // nur fuer ASSERT !

    SwModify& rRoot;
    SwClient *pAkt, *pDelNext;
    // fuers Updaten der aller Iteratoren beim Einfuegen/Loeschen von
    // Clients, wenn der Iterator gerade draufsteht.
    SwClientIter *pNxtIter;

    SwClient* mpWatchClient;    // if set, SwModify::_Remove checks if this client is removed

    TypeId aSrchId;             // fuer First/Next - suche diesen Type

public:
    SwClientIter( SwModify& );
    ~SwClientIter();

    const SwModify& GetModify() const       { return rRoot; }
          SwModify& GetModify()             { return rRoot; }

#ifndef CFRONT
    SwClient* operator++(int);  // zum Naechsten
    SwClient* operator--(int);  // zum Vorherigen
#endif
    SwClient* operator++();     // zum Naechsten
    SwClient* operator--();     // zum Vorherigen

    SwClient* GoStart();        // zum Anfang
    SwClient* GoEnd();          // zum Ende

    inline SwClient* GoRoot();      // wieder ab Root (==Start) anfangen

    SwClient* operator()() const
        { return pDelNext == pAkt ? pAkt : pDelNext; }

    int IsChanged() const { return pDelNext != pAkt; }

    SwClient* First( TypeId nType );
    SwClient* Next();

    const SwClient* GetWatchClient() const { return mpWatchClient; }
    void SetWatchClient( SwClient* pWatch ) { mpWatchClient = pWatch; }
};

inline SwClient* SwClientIter::GoRoot()     // wieder ab Root anfangen
{
    pAkt = rRoot.pRoot;
    return (pDelNext = pAkt);
}

#endif
<commit_msg>INTEGRATION: CWS writercorehandoff (1.2.462); FILE MERGED 2006/03/17 07:51:15 tra 1.2.462.4: RESYNC: (1.3-1.4); FILE MERGED 2005/09/13 11:15:44 tra 1.2.462.3: RESYNC: (1.2-1.3); FILE MERGED 2005/06/07 14:09:40 fme 1.2.462.2: #i50348# General cleanup - removed unused header files, functions, members, declarations etc. 2005/06/06 07:07:21 tra 1.2.462.1: Unnecessary includes removed #i50348#<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: calbck.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: hr $ $Date: 2006-08-14 15:17:18 $
 *
 *  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
 *
 ************************************************************************/

/*************************************************************
#* Service-Klassen
 *************************************************************/

/*
#* Aendert sich ein Attribut in einem Format, so muss diese
#* Aenderung an alle abhaengigen Formate und ueber sie an
#* alle betroffenen Nodes propagiert werden. Dabei muss
#* festgestellt werden, ob die Aenderung einen Effekt haben
#* kann, oder ob das geaenderte Attribut von dem abhaengigen
#* Format ueberdefiniert wird (so dass ohnehin der
#* Attributwert des abhaengigen Formates den geaenderten
#* Wert verdeckt). Weiterhin kann der betroffene Node
#* feststellen, ob er von dem geaenderten Attribut Gebrauch
#* macht (Beispiel: Linienabstand fuer Unterstreichung wurde
#* geaendert, das Attribut Unterstreichung wurde aber nicht
#* verwendet). So wird bei Aenderungen der minimale Aufwand
#* zum Reformatieren erkannt.
 */
#ifndef _CALBCK_HXX
#define _CALBCK_HXX

#ifndef _RTTI_HXX
#include <tools/rtti.hxx>
#endif

#ifndef INCLUDED_SWDLLAPI_H
#include "swdllapi.h"
#endif

class SwModify;
class SwClientIter;
class SfxPoolItem;
class SvStream;

// ----------
// SwClient
// ----------

class SW_DLLPUBLIC SwClient
{
    friend class SwModify;
    friend class SwClientIter;

    SwClient *pLeft, *pRight;           // fuer die AVL-Sortierung
    BOOL bModifyLocked : 1;             // wird in SwModify::Modify benutzt,
                                        // eigentlich ein Member des SwModify
                                        // aber aus Platzgruenden hier.
    BOOL bInModify  : 1;                // ist in einem Modify. (Debug!!!)
    BOOL bInDocDTOR : 1;                // Doc wird zerstoert, nicht "abmelden"
    BOOL bInCache   : 1;                // Ist im BorderAttrCache des Layout,
                                        // Traegt sich dann im Modify aus!
    BOOL bInSwFntCache : 1;             // Ist im SwFont-Cache der Formatierung

protected:
    SwModify *pRegisteredIn;

    // single argument ctors shall be explicit.
    explicit SwClient(SwModify *pToRegisterIn);

public:
    inline SwClient();
    virtual ~SwClient();

    virtual void Modify( SfxPoolItem *pOld, SfxPoolItem *pNew);
    const SwModify* GetRegisteredIn() const { return pRegisteredIn; }

    //rtti, abgeleitete moegens gleichtun oder nicht. Wenn sie es gleichtun
    //kann ueber die Abhaengigkeitsliste eines Modify typsicher gecastet
    //werden.
    TYPEINFO();

    void LockModify()                   { bModifyLocked = TRUE;  }
    void UnlockModify()                 { bModifyLocked = FALSE; }
    void SetInCache( BOOL bNew )        { bInCache = bNew;       }
    void SetInSwFntCache( BOOL bNew )   { bInSwFntCache = bNew;  }
    int  IsModifyLocked() const         { return bModifyLocked;  }
    int  IsInDocDTOR()    const         { return bInDocDTOR;     }
    int  IsInCache()      const         { return bInCache;       }
    int  IsInSwFntCache()  const        { return bInSwFntCache;  }

        // erfrage vom Client Informationen
    virtual BOOL GetInfo( SfxPoolItem& ) const;

private:
    SwClient( const SwClient& );
    SwClient &operator=( const SwClient& );
};

inline SwClient::SwClient() :
    pLeft(0), pRight(0), pRegisteredIn(0)
{ bModifyLocked = bInModify = bInDocDTOR = bInCache = bInSwFntCache = FALSE; }

// ----------
// SwModify
// ----------

// Klasse hat eine doppelt Verkette Liste fuer die Abhaengigen.

class SW_DLLPUBLIC SwModify: public SwClient
{
    friend SvStream& operator<<( SvStream& aS, SwModify & );

    friend class SwClientIter;
    SwClient* pRoot;

    SW_DLLPRIVATE SwClient *_Remove(SwClient *pDepend);

public:
    SwModify() : pRoot(0) {}

    // single argument ctors shall be explicit.
    explicit SwModify(SwModify *pToRegisterIn );
    virtual ~SwModify();

    virtual void Modify( SfxPoolItem *pOldValue, SfxPoolItem *pNewValue );
    void Add(SwClient *pDepend);
    SwClient *Remove(SwClient *pDepend)
        {   return bInDocDTOR ?  0 : _Remove( pDepend ); }

    const SwClient* GetDepends() const  { return pRoot; }

        // erfrage vom Client Informationen
    virtual BOOL GetInfo( SfxPoolItem& ) const;

    void SetInDocDTOR() { bInDocDTOR = TRUE; }

    void CheckCaching( const USHORT nWhich );

    BOOL IsLastDepend() const
        { return pRoot && !pRoot->pLeft && !pRoot->pRight; }

private:
    // forbidden and not implemented (see @ SwClient).
    SwModify & operator= (const SwModify &);

protected:
    // forbidden and not implemented (see @ SwClient),
    //   but GCC >= 3.4 needs an accessible "T (const T&)"
    //   to pass a "T" as a "const T&" argument
    SwModify (const SwModify &);
};

// ----------
// SwDepend
// ----------

/*
 * Sehr sinnvolle Klasse, wenn ein Objekt von mehreren Objekten
 * abhaengig ist. Diese sollte fuer jede Abhaengigkeit ein Objekt
 * der Klasse SwDepend als Member haben.
 */
class SwDepend: public SwClient
{
    SwClient *pToTell;

public:
    SwDepend() : pToTell(0) {}
    SwDepend(SwClient *pTellHim, SwModify *pDepend);

    SwClient* GetToTell() { return pToTell; }
    virtual void Modify( SfxPoolItem *pOldValue, SfxPoolItem *pNewValue );

        // erfrage vom Client Informationen
    virtual BOOL GetInfo( SfxPoolItem & ) const;

private:
    // forbidden and not implemented (see @ SwClient).
    SwDepend (const SwDepend &);
    SwDepend & operator= (const SwDepend &);
};

class SW_DLLPUBLIC SwClientIter
{
    friend SwClient* SwModify::_Remove(SwClient *); // fuer Ptr-Korrektur
    friend void SwModify::Add(SwClient *);          // nur fuer ASSERT !

    SwModify& rRoot;
    SwClient *pAkt, *pDelNext;
    // fuers Updaten der aller Iteratoren beim Einfuegen/Loeschen von
    // Clients, wenn der Iterator gerade draufsteht.
    SwClientIter *pNxtIter;

    SwClient* mpWatchClient;    // if set, SwModify::_Remove checks if this client is removed

    TypeId aSrchId;             // fuer First/Next - suche diesen Type

public:
    SwClientIter( SwModify& );
    ~SwClientIter();

    const SwModify& GetModify() const       { return rRoot; }
          SwModify& GetModify()             { return rRoot; }

#ifndef CFRONT
    SwClient* operator++(int);  // zum Naechsten
    SwClient* operator--(int);  // zum Vorherigen
#endif
    SwClient* operator++();     // zum Naechsten
    SwClient* operator--();     // zum Vorherigen

    SwClient* GoStart();        // zum Anfang
    SwClient* GoEnd();          // zum Ende

    inline SwClient* GoRoot();      // wieder ab Root (==Start) anfangen

    SwClient* operator()() const
        { return pDelNext == pAkt ? pAkt : pDelNext; }

    int IsChanged() const { return pDelNext != pAkt; }

    SwClient* First( TypeId nType );
    SwClient* Next();

    const SwClient* GetWatchClient() const { return mpWatchClient; }
    void SetWatchClient( SwClient* pWatch ) { mpWatchClient = pWatch; }
};

inline SwClient* SwClientIter::GoRoot()     // wieder ab Root anfangen
{
    pAkt = rRoot.pRoot;
    return (pDelNext = pAkt);
}

#endif
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: flypos.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 01:47:08 $
 *
 *  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 _FLYPOS_HXX
#define _FLYPOS_HXX

#ifndef _SVARRAY_HXX //autogen
#include <svtools/svarray.hxx>
#endif

class SwCntntNode;
class ViewShell;
class SwFrmFmt;
class SwNodeIndex;

// Struktur zum Erfragen der akt. freifliegenden Rahmen am Dokument.
class SwPosFlyFrm
{
    const SwFrmFmt* pFrmFmt;    // das FlyFrmFmt
//  SwPosition* pPos;           // Position in den ContentNode
    SwNodeIndex* pNdIdx;        // es reicht ein Index auf den Node
    UINT32 nOrdNum;
public:
    SwPosFlyFrm( const SwNodeIndex& , const SwFrmFmt*, USHORT nArrPos );
    virtual ~SwPosFlyFrm(); // virtual fuer die Writer (DLL !!)

    // operatoren fuer das Sort-Array
    BOOL operator==( const SwPosFlyFrm& );
    BOOL operator<( const SwPosFlyFrm& );

    const SwFrmFmt& GetFmt() const { return *pFrmFmt; }
    const SwNodeIndex& GetNdIndex() const { return *pNdIdx; }
    UINT32 GetOrdNum() const { return nOrdNum; }
};

typedef SwPosFlyFrm* SwPosFlyFrmPtr;
SV_DECL_PTRARR_SORT( SwPosFlyFrms, SwPosFlyFrmPtr, 0, 40 )

#endif // _FLYPOS_HXX
<commit_msg>INTEGRATION: CWS writercorehandoff (1.2.802); FILE MERGED 2005/09/13 11:27:13 tra 1.2.802.2: RESYNC: (1.2-1.3); FILE MERGED 2005/06/07 14:09:53 fme 1.2.802.1: #i50348# General cleanup - removed unused header files, functions, members, declarations etc.<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: flypos.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: hr $ $Date: 2006-08-14 15:22:49 $
 *
 *  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 _FLYPOS_HXX
#define _FLYPOS_HXX

#ifndef _SVARRAY_HXX //autogen
#include <svtools/svarray.hxx>
#endif

class SwFrmFmt;
class SwNodeIndex;

// Struktur zum Erfragen der akt. freifliegenden Rahmen am Dokument.
class SwPosFlyFrm
{
    const SwFrmFmt* pFrmFmt;    // das FlyFrmFmt
//  SwPosition* pPos;           // Position in den ContentNode
    SwNodeIndex* pNdIdx;        // es reicht ein Index auf den Node
    UINT32 nOrdNum;
public:
    SwPosFlyFrm( const SwNodeIndex& , const SwFrmFmt*, USHORT nArrPos );
    virtual ~SwPosFlyFrm(); // virtual fuer die Writer (DLL !!)

    // operatoren fuer das Sort-Array
    BOOL operator==( const SwPosFlyFrm& );
    BOOL operator<( const SwPosFlyFrm& );

    const SwFrmFmt& GetFmt() const { return *pFrmFmt; }
    const SwNodeIndex& GetNdIndex() const { return *pNdIdx; }
    UINT32 GetOrdNum() const { return nOrdNum; }
};

typedef SwPosFlyFrm* SwPosFlyFrmPtr;
SV_DECL_PTRARR_SORT( SwPosFlyFrms, SwPosFlyFrmPtr, 0, 40 )

#endif // _FLYPOS_HXX
<|endoftext|>


<commit_before>#include "taskqueuer.h"

WARNINGS_DISABLE
#include <QCoreApplication>
#include <QEventLoop>
#include <QVariant>
WARNINGS_ENABLE

#include "cmdlinetask.h"

TaskQueuer::TaskQueuer() : _threadPool(QThreadPool::globalInstance())
{
#ifdef QT_TESTLIB_LIB
    _fakeNextTask = false;
#endif
}

TaskQueuer::~TaskQueuer()
{
    // Wait up to 1 second to finish any background tasks
    _threadPool->waitForDone(1000);
    // Wait up to 1 second to delete objects scheduled with ->deleteLater()
    QCoreApplication::processEvents(QEventLoop::AllEvents, 1000);
}

void TaskQueuer::stopTasks(bool interrupt, bool running, bool queued)
{
    // Clear the queue first, to avoid starting a queued task
    // after already clearing the running task(s).
    if(queued)
    {
        while(!_taskQueue.isEmpty())
        {
            CmdlineTask *task = _taskQueue.dequeue();
            if(task)
            {
                task->emitCanceled();
                task->deleteLater();
            }
        }
        emit message("Cleared queued tasks.");
    }

    // Deal with a running backup.
    if(interrupt)
    {
        // Sending a SIGQUIT will cause the tarsnap binary to
        // create a checkpoint.  Non-tarsnap binaries should be
        // receive a CmdlineTask::stop() instead of a SIGQUIT.
        if(!_runningTasks.isEmpty())
            _runningTasks.first()->sigquit();
        emit message("Interrupting current backup.");
    }

    // Stop running tasks.
    if(running)
    {
        for(CmdlineTask *task : _runningTasks)
        {
            if(task)
                task->stop();
        }
        emit message("Stopped running tasks.");
    }
}

void TaskQueuer::queueTask(CmdlineTask *task, bool exclusive, bool isBackup)
{
    // Sanity check.
    Q_ASSERT(task != nullptr);

    // Add to list of backup tasks (if applicable).
    if(isBackup)
        _backupUuidList.append(task->uuid());

    // Add to the queue and trigger starting a new task.
    if(exclusive && !_runningTasks.isEmpty())
        _taskQueue.enqueue(task);
    else
        startTask(task);
}

void TaskQueuer::startTask(CmdlineTask *task)
{
    // Ensure that we have a task, or bail.
    if(task == nullptr)
    {
        if(!_taskQueue.isEmpty())
            task = _taskQueue.dequeue();
        else
            return;
    }

    // Set up the task ending.
    connect(task, &CmdlineTask::dequeue, this, &TaskQueuer::dequeueTask);
    task->setAutoDelete(false);

    // Record this thread as "running", even though it hasn't actually
    // started yet.  QThreadPool::start() is non-blocking, and in fact
    // explicitly states that a QRunnable can be added to an internal
    // run queue if it's exceeded QThreadPoll::maxThreadCount().
    //
    // However, for the purpose of this TaskQueuer, the task should not
    // be recorded in our _taskQueue (because we've just dequeued()'d it).
    // The "strictly correct" solution would be to add a
    // _waitingForStart queue, and move items out of that queue when the
    // relevant CmdlineTask::started signal was emitted.  At the moment,
    // I don't think that step is necessary, but I might need to revisit
    // that decision later.
    _runningTasks.append(task);

    // Start the task.
#ifdef QT_TESTLIB_LIB
    if(_fakeNextTask)
        task->fake();
#endif
    _threadPool->start(task);

    // Update the task numbers.
    bool backupTaskRunning = isBackupTaskRunning();
    emit numTasks(backupTaskRunning, _runningTasks.count(), _taskQueue.count());
}

void TaskQueuer::dequeueTask()
{
    // Get the task.
    CmdlineTask *task = qobject_cast<CmdlineTask *>(sender());

    // Sanity check.
    if(task == nullptr)
        return;

    // Clean up task.
    _runningTasks.removeOne(task);
    _backupUuidList.removeAll(task->uuid());
    task->deleteLater();

    // Start another task.
    if(_runningTasks.isEmpty())
        startTask(nullptr);

    // Update the task numbers.
    bool backupTaskRunning = isBackupTaskRunning();
    emit numTasks(backupTaskRunning, _runningTasks.count(), _taskQueue.count());
}

bool TaskQueuer::isBackupTaskRunning()
{
    if(!_runningTasks.isEmpty() && !_backupUuidList.isEmpty())
    {
        for(CmdlineTask *task : _runningTasks)
        {
            if(task && _backupUuidList.contains(task->uuid()))
            {
                return true;
            }
        }
    }
    return false;
}

void TaskQueuer::getTaskInfo()
{
    bool backupTaskRunning = isBackupTaskRunning();
    emit taskInfo(backupTaskRunning, _runningTasks.count(), _taskQueue.count());
}

#ifdef QT_TESTLIB_LIB
void TaskQueuer::fakeNextTask()
{
    _fakeNextTask = true;
}

void TaskQueuer::waitUntilIdle()
{
    while(!(_taskQueue.isEmpty() && _runningTasks.isEmpty()))
        QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
}
#endif
<commit_msg>TaskQueuer: expand removing a finished task<commit_after>#include "taskqueuer.h"

WARNINGS_DISABLE
#include <QCoreApplication>
#include <QEventLoop>
#include <QVariant>
WARNINGS_ENABLE

#include "cmdlinetask.h"

TaskQueuer::TaskQueuer() : _threadPool(QThreadPool::globalInstance())
{
#ifdef QT_TESTLIB_LIB
    _fakeNextTask = false;
#endif
}

TaskQueuer::~TaskQueuer()
{
    // Wait up to 1 second to finish any background tasks
    _threadPool->waitForDone(1000);
    // Wait up to 1 second to delete objects scheduled with ->deleteLater()
    QCoreApplication::processEvents(QEventLoop::AllEvents, 1000);
}

void TaskQueuer::stopTasks(bool interrupt, bool running, bool queued)
{
    // Clear the queue first, to avoid starting a queued task
    // after already clearing the running task(s).
    if(queued)
    {
        while(!_taskQueue.isEmpty())
        {
            CmdlineTask *task = _taskQueue.dequeue();
            if(task)
            {
                task->emitCanceled();
                task->deleteLater();
            }
        }
        emit message("Cleared queued tasks.");
    }

    // Deal with a running backup.
    if(interrupt)
    {
        // Sending a SIGQUIT will cause the tarsnap binary to
        // create a checkpoint.  Non-tarsnap binaries should be
        // receive a CmdlineTask::stop() instead of a SIGQUIT.
        if(!_runningTasks.isEmpty())
            _runningTasks.first()->sigquit();
        emit message("Interrupting current backup.");
    }

    // Stop running tasks.
    if(running)
    {
        for(CmdlineTask *task : _runningTasks)
        {
            if(task)
                task->stop();
        }
        emit message("Stopped running tasks.");
    }
}

void TaskQueuer::queueTask(CmdlineTask *task, bool exclusive, bool isBackup)
{
    // Sanity check.
    Q_ASSERT(task != nullptr);

    // Add to list of backup tasks (if applicable).
    if(isBackup)
        _backupUuidList.append(task->uuid());

    // Add to the queue and trigger starting a new task.
    if(exclusive && !_runningTasks.isEmpty())
        _taskQueue.enqueue(task);
    else
        startTask(task);
}

void TaskQueuer::startTask(CmdlineTask *task)
{
    // Ensure that we have a task, or bail.
    if(task == nullptr)
    {
        if(!_taskQueue.isEmpty())
            task = _taskQueue.dequeue();
        else
            return;
    }

    // Set up the task ending.
    connect(task, &CmdlineTask::dequeue, this, &TaskQueuer::dequeueTask);
    task->setAutoDelete(false);

    // Record this thread as "running", even though it hasn't actually
    // started yet.  QThreadPool::start() is non-blocking, and in fact
    // explicitly states that a QRunnable can be added to an internal
    // run queue if it's exceeded QThreadPoll::maxThreadCount().
    //
    // However, for the purpose of this TaskQueuer, the task should not
    // be recorded in our _taskQueue (because we've just dequeued()'d it).
    // The "strictly correct" solution would be to add a
    // _waitingForStart queue, and move items out of that queue when the
    // relevant CmdlineTask::started signal was emitted.  At the moment,
    // I don't think that step is necessary, but I might need to revisit
    // that decision later.
    _runningTasks.append(task);

    // Start the task.
#ifdef QT_TESTLIB_LIB
    if(_fakeNextTask)
        task->fake();
#endif
    _threadPool->start(task);

    // Update the task numbers.
    bool backupTaskRunning = isBackupTaskRunning();
    emit numTasks(backupTaskRunning, _runningTasks.count(), _taskQueue.count());
}

void TaskQueuer::dequeueTask()
{
    // Get the task.
    CmdlineTask *task = qobject_cast<CmdlineTask *>(sender());

    // Sanity check.
    if(task == nullptr)
        return;

    // Clean up task.
    for(CmdlineTask *t : _runningTasks)
    {
        if(t == task)
        {
            _runningTasks.removeOne(t);
            break;
        }
    }
    _backupUuidList.removeAll(task->uuid());
    task->deleteLater();

    // Start another task.
    if(_runningTasks.isEmpty())
        startTask(nullptr);

    // Update the task numbers.
    bool backupTaskRunning = isBackupTaskRunning();
    emit numTasks(backupTaskRunning, _runningTasks.count(), _taskQueue.count());
}

bool TaskQueuer::isBackupTaskRunning()
{
    if(!_runningTasks.isEmpty() && !_backupUuidList.isEmpty())
    {
        for(CmdlineTask *task : _runningTasks)
        {
            if(task && _backupUuidList.contains(task->uuid()))
            {
                return true;
            }
        }
    }
    return false;
}

void TaskQueuer::getTaskInfo()
{
    bool backupTaskRunning = isBackupTaskRunning();
    emit taskInfo(backupTaskRunning, _runningTasks.count(), _taskQueue.count());
}

#ifdef QT_TESTLIB_LIB
void TaskQueuer::fakeNextTask()
{
    _fakeNextTask = true;
}

void TaskQueuer::waitUntilIdle()
{
    while(!(_taskQueue.isEmpty() && _runningTasks.isEmpty()))
        QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
}
#endif
<|endoftext|>


<commit_before>// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab
/*
 * Ceph - scalable distributed file system
 *
 * Copyright (C) 2011 Dreamhost
 *
 * This 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.  See file COPYING.
 *
 */

#include "common/armor.h"
#include "config.h"
#include "include/buffer.h"
#include "include/encoding.h"

#include "gtest/gtest.h"

TEST(RoundTrip, SimpleRoundTrip) {
  static const int OUT_LEN = 4096;
  const char * const original = "abracadabra";
  const char * const correctly_encoded = "YWJyYWNhZGFicmE=";
  char out[OUT_LEN];
  memset(out, 0, sizeof(out));
  int alen = ceph_armor(out, out + OUT_LEN, original, original + strlen(original));
  ASSERT_STREQ(correctly_encoded, out);

  char out2[OUT_LEN];
  memset(out2, 0, sizeof(out2));
  ceph_unarmor(out2, out2 + OUT_LEN, out, out + alen);
  ASSERT_STREQ(original, out2);
}

TEST(RoundTrip, RandomRoundTrips) {
  static const int IN_MAX = 1024;
  static const int OUT_MAX = 4096;
  static const int ITERS = 1000;
  for (int i = 0; i < ITERS; ++i) {
    unsigned int seed = i;
    int in_len = rand_r(&seed) % IN_MAX;

    char in[IN_MAX];
    memset(in, 0, sizeof(in));
    for (int j = 0; i < in_len; ++j) {
      in[j] = rand_r(&seed) % 0xff;
    }
    char out[OUT_MAX];
    memset(out, 0, sizeof(out));
    int alen = ceph_armor(out, out + OUT_MAX, in, in + in_len);
    ASSERT_GE(alen, 0);

    char decoded[IN_MAX];
    memset(decoded, 0, sizeof(decoded));
    int blen = ceph_unarmor(decoded, decoded + OUT_MAX, out, out + alen);
    ASSERT_GE(blen, 0);

    ASSERT_EQ(memcmp(in, decoded, in_len), 0);
  }
}

TEST(FuzzEncoding, BadDecode1) {
  static const int OUT_LEN = 4096;
  const char * const bad_encoded = "FAKEBASE64 foo";
  char out[OUT_LEN];
  memset(out, 0, sizeof(out));
  int alen = ceph_unarmor(out, out + OUT_LEN, bad_encoded, bad_encoded + strlen(bad_encoded));
  ASSERT_LT(alen, 0);
}

TEST(FuzzEncoding, BadDecode2) {
  string str("FAKEBASE64 foo");
  bool failed = false;
  try {
    bufferlist bl;
    bl.append(str);

    bufferlist cl;
    cl.decode_base64(bl);
    cl.hexdump(std::cerr);
  }
  catch (const buffer::error &err) {
    failed = true;
  }
  ASSERT_EQ(failed, true);
}
<commit_msg>units: RandomRoundTrips: fix endptr for buffer<commit_after>// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab
/*
 * Ceph - scalable distributed file system
 *
 * Copyright (C) 2011 Dreamhost
 *
 * This 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.  See file COPYING.
 *
 */

#include "common/armor.h"
#include "config.h"
#include "include/buffer.h"
#include "include/encoding.h"

#include "gtest/gtest.h"

TEST(RoundTrip, SimpleRoundTrip) {
  static const int OUT_LEN = 4096;
  const char * const original = "abracadabra";
  const char * const correctly_encoded = "YWJyYWNhZGFicmE=";
  char out[OUT_LEN];
  memset(out, 0, sizeof(out));
  int alen = ceph_armor(out, out + OUT_LEN, original, original + strlen(original));
  ASSERT_STREQ(correctly_encoded, out);

  char out2[OUT_LEN];
  memset(out2, 0, sizeof(out2));
  ceph_unarmor(out2, out2 + OUT_LEN, out, out + alen);
  ASSERT_STREQ(original, out2);
}

TEST(RoundTrip, RandomRoundTrips) {
  static const int IN_MAX = 1024;
  static const int OUT_MAX = 4096;
  static const int ITERS = 1000;
  for (int i = 0; i < ITERS; ++i) {
    unsigned int seed = i;
    int in_len = rand_r(&seed) % IN_MAX;

    char in[IN_MAX];
    memset(in, 0, sizeof(in));
    for (int j = 0; i < in_len; ++j) {
      in[j] = rand_r(&seed) % 0xff;
    }
    char out[OUT_MAX];
    memset(out, 0, sizeof(out));
    int alen = ceph_armor(out, out + OUT_MAX, in, in + in_len);
    ASSERT_GE(alen, 0);

    char decoded[IN_MAX];
    memset(decoded, 0, sizeof(decoded));
    int blen = ceph_unarmor(decoded, decoded + IN_MAX, out, out + alen);
    ASSERT_GE(blen, 0);

    ASSERT_EQ(memcmp(in, decoded, in_len), 0);
  }
}

TEST(FuzzEncoding, BadDecode1) {
  static const int OUT_LEN = 4096;
  const char * const bad_encoded = "FAKEBASE64 foo";
  char out[OUT_LEN];
  memset(out, 0, sizeof(out));
  int alen = ceph_unarmor(out, out + OUT_LEN, bad_encoded, bad_encoded + strlen(bad_encoded));
  ASSERT_LT(alen, 0);
}

TEST(FuzzEncoding, BadDecode2) {
  string str("FAKEBASE64 foo");
  bool failed = false;
  try {
    bufferlist bl;
    bl.append(str);

    bufferlist cl;
    cl.decode_base64(bl);
    cl.hexdump(std::cerr);
  }
  catch (const buffer::error &err) {
    failed = true;
  }
  ASSERT_EQ(failed, true);
}
<|endoftext|>