<commit_before>/***************************************************************************
* Copyright (c) 2016, Johan Mabille, Sylvain Corlay and Wolf Vollprecht    *
*                                                                          *
* Distributed under the terms of the BSD 3-Clause License.                 *
*                                                                          *
* The full license is in the file LICENSE, distributed with this software. *
****************************************************************************/

#ifndef XTENSOR_SORT_HPP
#define XTENSOR_SORT_HPP

#include <algorithm>

#include "xarray.hpp"
#include "xeval.hpp"
#include "xslice.hpp"  // for xnone
#include "xstrided_view.hpp"
#include "xtensor.hpp"

namespace xt
{
    template <class E>
    auto sort(const xexpression<E>& e, placeholders::xtuph /*t*/)
    {
        const auto de = e.derived_cast();
        E ev;
        ev.resize({de.size()});

        std::copy(de.cbegin(), de.cend(), ev.begin());
        std::sort(ev.begin(), ev.end());

        return ev;
    }

    namespace detail
    {
        template <class E, class F>
        void call_over_leading_axis(E& ev, F&& fct)
        {
            std::size_t n_iters = 1;
            std::ptrdiff_t secondary_stride;
            if (ev.layout() == layout_type::row_major)
            {
                n_iters = std::accumulate(ev.shape().begin(), ev.shape().end() - 1,
                                          std::size_t(1), std::multiplies<>());
                secondary_stride = static_cast<std::ptrdiff_t>(ev.strides()[ev.dimension() - 2]);
            }
            else
            {
                n_iters = std::accumulate(ev.shape().begin() + 1, ev.shape().end(),
                                          std::size_t(1), std::multiplies<>());
                secondary_stride = static_cast<std::ptrdiff_t>(ev.strides()[1]);
            }

            std::ptrdiff_t offset = 0;

            for (std::size_t i = 0; i < n_iters; ++i, offset += secondary_stride)
            {
                fct(ev.data() + offset, ev.data() + offset + secondary_stride);
            }
        }

        template <class E>
        inline std::size_t leading_axis(const E& e)
        {
            if (e.layout() == layout_type::row_major)
            {
                return e.dimension() - 1;
            }
            else if (e.layout() == layout_type::column_major)
            {
                return 0;
            }
            throw std::runtime_error("Layout not supported.");
        }
    }

    /**
     * Sort xexpression (optionally along axis)
     * The sort is performed using the ``std::sort`` functions.
     * A copy of the xexpression is created and returned.
     *
     * @param e xexpression to sort
     * @param axis axis along which sort is performed
     *
     * @return sorted array (copy)
     */
    template <class E>
    auto sort(const xexpression<E>& e, std::size_t axis)
    {
        using eval_type = typename E::temporary_type;

        const auto& de = e.derived_cast();

        if (de.dimension() == 1)
        {
            return sort(de, xnone());
        }

        eval_type ev;

        if (axis != detail::leading_axis(ev))
        {
            auto axis_numbers = arange<std::size_t>(de.shape().size());
            std::vector<std::size_t> permutation(axis_numbers.begin(), axis_numbers.end());
            permutation.erase(permutation.begin() + std::ptrdiff_t(axis));
            if (de.layout() == layout_type::row_major)
            {
                permutation.push_back(axis);
            }
            else
            {
                permutation.insert(permutation.begin(), axis);
            }

            // TODO find a more clever way to get reverse permutation?
            std::vector<std::size_t> reverse_permutation;
            for (auto el : axis_numbers)
            {
                auto it = std::find(permutation.begin(), permutation.end(), el);
                reverse_permutation.push_back(std::size_t(std::distance(permutation.begin(), it)));
            }

            ev = transpose(de, permutation);
            detail::call_over_leading_axis(ev, [](auto begin, auto end) { std::sort(begin, end); });
            ev = transpose(ev, reverse_permutation);
            return ev;
        }
        else
        {
            ev = de;
            detail::call_over_leading_axis(ev, [](auto begin, auto end) { std::sort(begin, end); });
            return ev;
        }
    }

    template <class E>
    auto sort(const xexpression<E>& e)
    {
        const auto& de = e.derived_cast();
        return sort(de, de.dimension() - 1);
    }

    namespace detail {
        template <class T>
        struct argsort_result_type
        {
            using type = xarray<std::size_t, xt::layout_type::dynamic>;
        };

        template <class T, std::size_t N>
        struct argsort_result_type<xtensor<T, N>>
        {
            using type = xtensor<std::size_t, N>;
        };

        template <class Ed, class Ei>
        void argsort_over_leading_axis(Ed& data, Ei& inds)
        {
            using value_type = typename Ed::value_type;
            std::size_t n_iters = 1;
            std::ptrdiff_t data_secondary_stride;
            std::ptrdiff_t inds_secondary_stride;
            if (data.layout() == layout_type::row_major)
            {
                n_iters = std::accumulate(data.shape().begin(), data.shape().end() - 1,
                                          std::size_t(1), std::multiplies<>());
                data_secondary_stride = static_cast<std::ptrdiff_t>(data.strides()[data.dimension() - 2]);
                inds_secondary_stride = static_cast<std::ptrdiff_t>(inds.strides()[inds.dimension() - 2]);
            }
            else
            {
                n_iters = std::accumulate(data.shape().begin() + 1, data.shape().end(),
                                          std::size_t(1), std::multiplies<>());
                data_secondary_stride = static_cast<std::ptrdiff_t>(data.strides()[1]);
                inds_secondary_stride = static_cast<std::ptrdiff_t>(inds.strides()[1]);
            }

            std::ptrdiff_t data_offset = 0;
            std::ptrdiff_t inds_offset = 0;

            for (std::size_t i = 0; i < n_iters; ++i, data_offset += data_secondary_stride,
                    inds_offset += inds_secondary_stride)
            {
                auto comp = [&data, &data_offset](std::size_t x, std::size_t y) {
                    return (*(data.data() + data_offset + x) <
                            *(data.data() + data_offset + y));
                };
                std::iota(inds.data() + inds_offset, inds.data() + inds_offset + inds_secondary_stride, 0);
                std::sort(inds.data() + inds_offset, inds.data() + inds_offset + inds_secondary_stride, comp);
            }
        }
    }

    template <class E>
    auto argsort(const xexpression<E>& e, placeholders::xtuph /*t*/)
    {
        using value_type = typename E::value_type;
        using result_type = typename detail::argsort_result_type<E>::type;

        const auto de = e.derived_cast();

        result_type result;
        result.resize({de.size()});
        auto comp = [&de](std::size_t x, std::size_t y) {
            return de[x] < de[y];
        };
        std::iota(result.begin(), result.end(), 0);
        std::sort(result.begin(), result.end(), comp);

        return result;
    }

    /**
     * Argsort xexpression (optionally along axis)
     * Performs an indirect sort along the given axis. Returns an xarray
     * of indices of the same shape as e that index data along the given axis in
     * sorted order.
     *
     * @param e xexpression to argsort
     * @param axis axis along which argsort is performed
     *
     * @return argsorted index array
     */
    template <class E>
    auto argsort(const xexpression<E>& e, std::size_t axis)
    {
        using eval_type = typename E::temporary_type;
        using value_type = typename E::value_type;
        using result_type = typename detail::argsort_result_type<E>::type;

        const auto& de = e.derived_cast();

        if (de.dimension() == 1)
        {
            return argsort(de, xnone());
        }

        eval_type ev;

        if (axis != detail::leading_axis(ev))
        {
            auto axis_numbers = arange<std::size_t>(de.shape().size());
            std::vector<std::size_t> permutation(axis_numbers.begin(), axis_numbers.end());
            permutation.erase(permutation.begin() + std::ptrdiff_t(axis));
            if (de.layout() == layout_type::row_major)
            {
                permutation.push_back(axis);
            }
            else
            {
                permutation.insert(permutation.begin(), axis);
            }

            // TODO find a more clever way to get reverse permutation?
            std::vector<std::size_t> reverse_permutation;
            for (auto el : axis_numbers)
            {
                auto it = std::find(permutation.begin(), permutation.end(), el);
                reverse_permutation.push_back(std::size_t(std::distance(permutation.begin(), it)));
            }

            ev = transpose(de, permutation);
            result_type res(ev.shape(), ev.layout());
            detail::argsort_over_leading_axis(ev, res);
            ev = transpose(ev, reverse_permutation);
            res = transpose(res, reverse_permutation);
            return res;
        }
        else
        {
            ev = de;
            result_type res(de.shape(), de.layout());
            detail::argsort_over_leading_axis(ev, res);
            return res;
        }
    }

    template <class E>
    auto argsort(const xexpression<E>& e)
    {
        const auto& de = e.derived_cast();
        return argsort(de, de.dimension() - 1);
    }

    namespace detail
    {
        template <class T>
        struct argfunc_result_type
        {
            using type = xarray<std::size_t>;
        };

        template <class T, std::size_t N>
        struct argfunc_result_type<xtensor<T, N>>
        {
            using type = xtensor<std::size_t, N - 1>;
        };

        template <class IT, class F>
        inline std::size_t cmp_idx(IT iter, IT end, std::ptrdiff_t inc, F&& cmp)
        {
            std::size_t idx = 0;
            double min = *iter;
            iter += inc;
            for (std::size_t i = 1; iter < end; iter += inc, ++i)
            {
                if (cmp(*iter, min))
                {
                    min = *iter;
                    idx = i;
                }
            }
            return idx;
        }

        template <class E, class F>
        xtensor<std::size_t, 0> arg_func_impl(const E& e, F&& f)
        {
            return cmp_idx(e.template begin<XTENSOR_DEFAULT_LAYOUT>(),
                           e.template end<XTENSOR_DEFAULT_LAYOUT>(), 1,
                           std::forward<F>(f));
        }

        template <class E, class F>
        typename argfunc_result_type<E>::type
        arg_func_impl(const E& e, std::size_t axis, F&& cmp)
        {
            using value_type = typename E::value_type;
            using result_type = typename argfunc_result_type<E>::type;

            if (e.dimension() == 1)
            {
                return arg_func_impl(e, std::forward<F>(cmp));
            }

            xt::dynamic_shape<std::size_t> new_shape = e.shape();
            new_shape.erase(new_shape.begin() + std::ptrdiff_t(axis));

            result_type result(new_shape);
            auto result_iter = result.begin();

            auto arg_func_lambda = [&result_iter, &cmp](auto begin, auto end) {
                std::size_t idx = 0;
                value_type val = *begin;
                ++begin;
                for (std::size_t i = 1; begin != end; ++begin, ++i)
                {
                    if (cmp(*begin, val))
                    {
                        val = *begin;
                        idx = i;
                    }
                }
                *result_iter = idx;
                ++result_iter;
            };

            if (axis != detail::leading_axis(e))
            {
                E input;
                auto axis_numbers = arange<std::size_t>(e.shape().size());
                std::vector<std::size_t> permutation(axis_numbers.cbegin(), axis_numbers.cend());
                permutation.erase(permutation.begin() + std::ptrdiff_t(axis));
                if (input.layout() == layout_type::row_major)
                {
                    permutation.push_back(axis);
                }
                else
                {
                    permutation.insert(permutation.begin(), axis);
                }
                // Note we create a copy
                input = transpose(e, permutation);

                detail::call_over_leading_axis(input, arg_func_lambda);
                return result;
            }
            else
            {
                auto&& input = eval(e);
                detail::call_over_leading_axis(input, arg_func_lambda);
                return result;
            }
        }
    }

    template <class E>
    auto argmin(const xexpression<E>& e)
    {
        using value_type = typename E::value_type;
        auto&& ed = eval(e.derived_cast());
        return detail::arg_func_impl(ed, std::less<value_type>());
    }

    /**
     * Find position of minimal value in xexpression
     *
     * @param e input xexpression
     * @param axis select axis (or none)
     *
     * @return returns xarray with positions of minimal value
     */
    template <class E>
    auto argmin(const xexpression<E>& e, std::size_t axis)
    {
        using value_type = typename E::value_type;
        auto&& ed = eval(e.derived_cast());
        return detail::arg_func_impl(ed, axis, std::less<value_type>());
    }

    template <class E>
    auto argmax(const xexpression<E>& e)
    {
        using value_type = typename E::value_type;
        auto&& ed = eval(e.derived_cast());
        return detail::arg_func_impl(ed, std::greater<value_type>());
    }

    /**
     * Find position of maximal value in xexpression
     *
     * @param e input xexpression
     * @param axis select axis (or none)
     *
     * @return returns xarray with positions of maximal value
     */
    template <class E>
    auto argmax(const xexpression<E>& e, std::size_t axis)
    {
        using value_type = typename E::value_type;
        auto&& ed = eval(e.derived_cast());
        return detail::arg_func_impl(ed, axis, std::greater<value_type>());
    }

    /**
     * Find unique elements of a xexpression. This returns a flattened xtensor with
     * sorted, unique elements from the original expression.
     *
     * @param e input xexpression (will be flattened)
     */
    template <class E>
    auto unique(const xexpression<E>& e)
    {
        auto sorted = sort(e, xnone());
        auto end = std::unique(sorted.begin(), sorted.end());
        std::size_t sz = static_cast<std::size_t>(std::distance(sorted.begin(), end));
        // TODO check if we can shrink the vector without reallocation
        using value_type = typename E::value_type;
        auto result = xtensor<value_type, 1>::from_shape({sz});
        std::copy(sorted.begin(), end, result.begin());
        return result;
    }
}

#endif
<commit_msg>Fix easy subset of argsort PR review requests<commit_after>/***************************************************************************
* Copyright (c) 2016, Johan Mabille, Sylvain Corlay and Wolf Vollprecht    *
*                                                                          *
* Distributed under the terms of the BSD 3-Clause License.                 *
*                                                                          *
* The full license is in the file LICENSE, distributed with this software. *
****************************************************************************/

#ifndef XTENSOR_SORT_HPP
#define XTENSOR_SORT_HPP

#include <algorithm>

#include "xarray.hpp"
#include "xeval.hpp"
#include "xslice.hpp"  // for xnone
#include "xstrided_view.hpp"
#include "xtensor.hpp"

namespace xt
{
    template <class E>
    auto sort(const xexpression<E>& e, placeholders::xtuph /*t*/)
    {
        const auto de = e.derived_cast();
        E ev;
        ev.resize({de.size()});

        std::copy(de.cbegin(), de.cend(), ev.begin());
        std::sort(ev.begin(), ev.end());

        return ev;
    }

    namespace detail
    {
        template <class E, class F>
        void call_over_leading_axis(E& ev, F&& fct)
        {
            std::size_t n_iters = 1;
            std::ptrdiff_t secondary_stride;
            if (ev.layout() == layout_type::row_major)
            {
                n_iters = std::accumulate(ev.shape().begin(), ev.shape().end() - 1,
                                          std::size_t(1), std::multiplies<>());
                secondary_stride = static_cast<std::ptrdiff_t>(ev.strides()[ev.dimension() - 2]);
            }
            else
            {
                n_iters = std::accumulate(ev.shape().begin() + 1, ev.shape().end(),
                                          std::size_t(1), std::multiplies<>());
                secondary_stride = static_cast<std::ptrdiff_t>(ev.strides()[1]);
            }

            std::ptrdiff_t offset = 0;

            for (std::size_t i = 0; i < n_iters; ++i, offset += secondary_stride)
            {
                fct(ev.data() + offset, ev.data() + offset + secondary_stride);
            }
        }

        template <class E>
        inline std::size_t leading_axis(const E& e)
        {
            if (e.layout() == layout_type::row_major)
            {
                return e.dimension() - 1;
            }
            else if (e.layout() == layout_type::column_major)
            {
                return 0;
            }
            throw std::runtime_error("Layout not supported.");
        }
    }

    /**
     * Sort xexpression (optionally along axis)
     * The sort is performed using the ``std::sort`` functions.
     * A copy of the xexpression is created and returned.
     *
     * @param e xexpression to sort
     * @param axis axis along which sort is performed
     *
     * @return sorted array (copy)
     */
    template <class E>
    auto sort(const xexpression<E>& e, std::size_t axis)
    {
        using eval_type = typename E::temporary_type;

        const auto& de = e.derived_cast();

        if (de.dimension() == 1)
        {
            return sort(de, xnone());
        }

        eval_type ev;

        if (axis != detail::leading_axis(ev))
        {
            auto axis_numbers = arange<std::size_t>(de.shape().size());
            std::vector<std::size_t> permutation(axis_numbers.begin(), axis_numbers.end());
            permutation.erase(permutation.begin() + std::ptrdiff_t(axis));
            if (de.layout() == layout_type::row_major)
            {
                permutation.push_back(axis);
            }
            else
            {
                permutation.insert(permutation.begin(), axis);
            }

            // TODO find a more clever way to get reverse permutation?
            std::vector<std::size_t> reverse_permutation;
            for (auto el : axis_numbers)
            {
                auto it = std::find(permutation.begin(), permutation.end(), el);
                reverse_permutation.push_back(std::size_t(std::distance(permutation.begin(), it)));
            }

            ev = transpose(de, permutation);
            detail::call_over_leading_axis(ev, [](auto begin, auto end) { std::sort(begin, end); });
            ev = transpose(ev, reverse_permutation);
            return ev;
        }
        else
        {
            ev = de;
            detail::call_over_leading_axis(ev, [](auto begin, auto end) { std::sort(begin, end); });
            return ev;
        }
    }

    template <class E>
    auto sort(const xexpression<E>& e)
    {
        const auto& de = e.derived_cast();
        return sort(de, de.dimension() - 1);
    }

    namespace detail {
        template <class T>
        struct argsort_result_type
        {
            using type = xarray<std::size_t, xt::layout_type::dynamic>;
        };

        template <class T, std::size_t N>
        struct argsort_result_type<xtensor<T, N>>
        {
            using type = xtensor<std::size_t, N>;
        };

        template <class Ed, class Ei>
        void argsort_over_leading_axis(const Ed& data, Ei& inds)
        {
            using value_type = typename Ed::value_type;
            std::size_t n_iters = 1;
            std::ptrdiff_t data_secondary_stride;
            std::ptrdiff_t inds_secondary_stride;
            if (data.layout() == layout_type::row_major)
            {
                n_iters = std::accumulate(data.shape().begin(), data.shape().end() - 1,
                                          std::size_t(1), std::multiplies<>());
                data_secondary_stride = static_cast<std::ptrdiff_t>(data.strides()[data.dimension() - 2]);
                inds_secondary_stride = static_cast<std::ptrdiff_t>(inds.strides()[inds.dimension() - 2]);
            }
            else
            {
                n_iters = std::accumulate(data.shape().begin() + 1, data.shape().end(),
                                          std::size_t(1), std::multiplies<>());
                data_secondary_stride = static_cast<std::ptrdiff_t>(data.strides()[1]);
                inds_secondary_stride = static_cast<std::ptrdiff_t>(inds.strides()[1]);
            }

            std::ptrdiff_t data_offset = 0;
            std::ptrdiff_t inds_offset = 0;

            for (std::size_t i = 0; i < n_iters; ++i, data_offset += data_secondary_stride,
                    inds_offset += inds_secondary_stride)
            {
                auto comp = [&data, &data_offset](std::size_t x, std::size_t y) {
                    return (*(data.data() + data_offset + x) <
                            *(data.data() + data_offset + y));
                };
                std::iota(inds.data() + inds_offset, inds.data() + inds_offset + inds_secondary_stride, 0);
                std::sort(inds.data() + inds_offset, inds.data() + inds_offset + inds_secondary_stride, comp);
            }
        }
    }

    template <class E>
    auto argsort(const xexpression<E>& e, placeholders::xtuph /*t*/)
    {
        using value_type = typename E::value_type;
        using result_type = typename detail::argsort_result_type<E>::type;

        const auto& de = e.derived_cast();

        result_type result;
        result.resize({de.size()});
        auto comp = [&de](std::size_t x, std::size_t y) {
            return de[x] < de[y];
        };
        std::iota(result.begin(), result.end(), 0);
        std::sort(result.begin(), result.end(), comp);

        return result;
    }

    /**
     * Argsort xexpression (optionally along axis)
     * Performs an indirect sort along the given axis. Returns an xarray
     * of indices of the same shape as e that index data along the given axis in
     * sorted order.
     *
     * @param e xexpression to argsort
     * @param axis axis along which argsort is performed
     *
     * @return argsorted index array
     */
    template <class E>
    auto argsort(const xexpression<E>& e, std::size_t axis)
    {
        using eval_type = typename E::temporary_type;
        using value_type = typename E::value_type;
        using result_type = typename detail::argsort_result_type<E>::type;

        const auto& de = e.derived_cast();

        if (de.dimension() == 1)
        {
            return argsort(de, xnone());
        }

        if (axis != detail::leading_axis(de))
        {
            auto axis_numbers = arange<std::size_t>(de.shape().size());
            std::vector<std::size_t> permutation(axis_numbers.begin(), axis_numbers.end());
            permutation.erase(permutation.begin() + std::ptrdiff_t(axis));
            if (de.layout() == layout_type::row_major)
            {
                permutation.push_back(axis);
            }
            else
            {
                permutation.insert(permutation.begin(), axis);
            }

            // TODO find a more clever way to get reverse permutation?
            std::vector<std::size_t> reverse_permutation;
            for (auto el : axis_numbers)
            {
                auto it = std::find(permutation.begin(), permutation.end(), el);
                reverse_permutation.push_back(std::size_t(std::distance(permutation.begin(), it)));
            }

            eval_type ev = transpose(de, permutation);
            result_type res(ev.shape(), ev.layout());
            detail::argsort_over_leading_axis(ev, res);
            res = transpose(res, reverse_permutation);
            return res;
        }
        else
        {
            result_type res(de.shape(), de.layout());
            detail::argsort_over_leading_axis(de, res);
            return res;
        }
    }

    template <class E>
    auto argsort(const xexpression<E>& e)
    {
        const auto& de = e.derived_cast();
        return argsort(de, de.dimension() - 1);
    }

    namespace detail
    {
        template <class T>
        struct argfunc_result_type
        {
            using type = xarray<std::size_t>;
        };

        template <class T, std::size_t N>
        struct argfunc_result_type<xtensor<T, N>>
        {
            using type = xtensor<std::size_t, N - 1>;
        };

        template <class IT, class F>
        inline std::size_t cmp_idx(IT iter, IT end, std::ptrdiff_t inc, F&& cmp)
        {
            std::size_t idx = 0;
            double min = *iter;
            iter += inc;
            for (std::size_t i = 1; iter < end; iter += inc, ++i)
            {
                if (cmp(*iter, min))
                {
                    min = *iter;
                    idx = i;
                }
            }
            return idx;
        }

        template <class E, class F>
        xtensor<std::size_t, 0> arg_func_impl(const E& e, F&& f)
        {
            return cmp_idx(e.template begin<XTENSOR_DEFAULT_LAYOUT>(),
                           e.template end<XTENSOR_DEFAULT_LAYOUT>(), 1,
                           std::forward<F>(f));
        }

        template <class E, class F>
        typename argfunc_result_type<E>::type
        arg_func_impl(const E& e, std::size_t axis, F&& cmp)
        {
            using value_type = typename E::value_type;
            using result_type = typename argfunc_result_type<E>::type;

            if (e.dimension() == 1)
            {
                return arg_func_impl(e, std::forward<F>(cmp));
            }

            xt::dynamic_shape<std::size_t> new_shape = e.shape();
            new_shape.erase(new_shape.begin() + std::ptrdiff_t(axis));

            result_type result(new_shape);
            auto result_iter = result.begin();

            auto arg_func_lambda = [&result_iter, &cmp](auto begin, auto end) {
                std::size_t idx = 0;
                value_type val = *begin;
                ++begin;
                for (std::size_t i = 1; begin != end; ++begin, ++i)
                {
                    if (cmp(*begin, val))
                    {
                        val = *begin;
                        idx = i;
                    }
                }
                *result_iter = idx;
                ++result_iter;
            };

            if (axis != detail::leading_axis(e))
            {
                E input;
                auto axis_numbers = arange<std::size_t>(e.shape().size());
                std::vector<std::size_t> permutation(axis_numbers.cbegin(), axis_numbers.cend());
                permutation.erase(permutation.begin() + std::ptrdiff_t(axis));
                if (input.layout() == layout_type::row_major)
                {
                    permutation.push_back(axis);
                }
                else
                {
                    permutation.insert(permutation.begin(), axis);
                }
                // Note we create a copy
                input = transpose(e, permutation);

                detail::call_over_leading_axis(input, arg_func_lambda);
                return result;
            }
            else
            {
                auto&& input = eval(e);
                detail::call_over_leading_axis(input, arg_func_lambda);
                return result;
            }
        }
    }

    template <class E>
    auto argmin(const xexpression<E>& e)
    {
        using value_type = typename E::value_type;
        auto&& ed = eval(e.derived_cast());
        return detail::arg_func_impl(ed, std::less<value_type>());
    }

    /**
     * Find position of minimal value in xexpression
     *
     * @param e input xexpression
     * @param axis select axis (or none)
     *
     * @return returns xarray with positions of minimal value
     */
    template <class E>
    auto argmin(const xexpression<E>& e, std::size_t axis)
    {
        using value_type = typename E::value_type;
        auto&& ed = eval(e.derived_cast());
        return detail::arg_func_impl(ed, axis, std::less<value_type>());
    }

    template <class E>
    auto argmax(const xexpression<E>& e)
    {
        using value_type = typename E::value_type;
        auto&& ed = eval(e.derived_cast());
        return detail::arg_func_impl(ed, std::greater<value_type>());
    }

    /**
     * Find position of maximal value in xexpression
     *
     * @param e input xexpression
     * @param axis select axis (or none)
     *
     * @return returns xarray with positions of maximal value
     */
    template <class E>
    auto argmax(const xexpression<E>& e, std::size_t axis)
    {
        using value_type = typename E::value_type;
        auto&& ed = eval(e.derived_cast());
        return detail::arg_func_impl(ed, axis, std::greater<value_type>());
    }

    /**
     * Find unique elements of a xexpression. This returns a flattened xtensor with
     * sorted, unique elements from the original expression.
     *
     * @param e input xexpression (will be flattened)
     */
    template <class E>
    auto unique(const xexpression<E>& e)
    {
        auto sorted = sort(e, xnone());
        auto end = std::unique(sorted.begin(), sorted.end());
        std::size_t sz = static_cast<std::size_t>(std::distance(sorted.begin(), end));
        // TODO check if we can shrink the vector without reallocation
        using value_type = typename E::value_type;
        auto result = xtensor<value_type, 1>::from_shape({sz});
        std::copy(sorted.begin(), end, result.begin());
        return result;
    }
}

#endif
<|endoftext|>


<commit_before>// Basic GLnexus command-line interface for use on one compute node

#include <iostream>
#include <exception>
#include <fstream>
#include <getopt.h>
#include <sstream>
#include <cstdlib>
#include "vcf.h"
#include "hfile.h"
#include "service.h"
#include "unifier.h"
#include "BCFKeyValueData.h"
#include "RocksKeyValue.h"
#include "ctpl_stl.h"
#include "spdlog/spdlog.h"
#include "spdlog/sinks/stdout_sinks.h"
#include "cli_utils.h"

using namespace std;

auto console = spdlog::stderr_logger_mt("GLnexus");
GLnexus::Status s;
#define H(desc,expr) \
    s = expr; \
    if (s.bad()) { \
        console->error("Failed to {}: {}", desc, s.str()); \
        if (getenv("DX_JOB_ID")) { \
            ofstream joberrorjson("/home/dnanexus/job_error.json"); \
            joberrorjson << "{\"error\": {\"type\": \"AppError\", \"message\": \""; \
            joberrorjson << "Failed to " << desc << ": " << s.str(); \
            joberrorjson << "\"}}"; \
            joberrorjson.close(); \
        } \
        return 1; \
    }

// Perform all the separate GLnexus operations in one go.
// return 0 on success, 1 on failure.
static int all_steps(const vector<string> &vcf_files,
                     const string &bedfilename,
                     const string &config_name, bool squeeze,
                     size_t mem_budget, size_t nr_threads,
                     bool debug,
                     bool iter_compare,
                     size_t bucket_size) {
    GLnexus::Status s;
    GLnexus::unifier_config unifier_cfg;
    GLnexus::genotyper_config genotyper_cfg;
    string cfg_crc32c;

    if (vcf_files.empty()) {
        console->error("No source GVCF files specified");
        return 1;
    }

    H("load unifier/genotyper configuration",
        GLnexus::cli::utils::load_config(console, config_name, unifier_cfg, genotyper_cfg, cfg_crc32c, squeeze));

    // initilize empty database
    string dbpath("GLnexus.DB");
    vector<pair<string,size_t> > contigs;
    H("initializing database", GLnexus::cli::utils::db_init(console, dbpath, vcf_files[0], contigs,
                                                            bucket_size));

    {
        // sanity check, see that we can get the contigs back
        vector<pair<string,size_t> > contigs_dbg;
        H("Reading the contigs back from DB",
          GLnexus::cli::utils::db_get_contigs(console, dbpath, contigs_dbg));
        if (contigs_dbg != contigs)
            return GLnexus::Status::Invalid("error, contigs read from DB do not match originals");
    }

    // Load the GVCFs into the database
    {
        // use an empty range filter
        vector<GLnexus::range> ranges;
        H("bulk load into DB",
          GLnexus::cli::utils::db_bulk_load(console, mem_budget, nr_threads, vcf_files, dbpath, ranges, contigs, false));
    }

    if (iter_compare) {
        H("compare database iteration methods",
          GLnexus::cli::utils::compare_db_itertion_algorithms(console, dbpath, 50));
    }

    // discover alleles
    // TODO: if bedfilename is empty, fill ranges with all contigs
    // TODO: overlap allele discovery with final compactions. have db_bulk_load output a RocksKeyValue pointer which we can reuse
    vector<GLnexus::range> ranges;
    H("parsing the bed file", GLnexus::cli::utils::parse_bed_file(console, bedfilename, contigs, ranges));
    GLnexus::discovered_alleles dsals;
    unsigned sample_count = 0;
    H("discover alleles",
      GLnexus::cli::utils::discover_alleles(console, mem_budget, nr_threads, dbpath, ranges, contigs, dsals, sample_count));
    if (debug) {
        string filename("/tmp/dsals.yml");
        console->info("Writing discovered alleles as YAML to {}", filename);
        H("serialize discovered alleles to a file",
          GLnexus::cli::utils::yaml_write_discovered_alleles_to_file(dsals, contigs, sample_count, filename));
    }

    // partition dsals by contig to reduce peak memory usage in the unifier
    std::vector<GLnexus::discovered_alleles> dsals_by_contig(contigs.size());
    for (auto p = dsals.begin(); p != dsals.end(); dsals.erase(p++)) {
        UNPAIR(*p, al, dai);
        assert(al.pos.rid >= 0 && al.pos.rid < contigs.size());
        dsals_by_contig[al.pos.rid][al] = dai;
    }

    // unify sites
    // we could parallelize over dsals_by_contig although this might increase memory usage.
    vector<GLnexus::unified_site> sites;
    GLnexus::unifier_stats stats;
    for (auto& dsals_i : dsals_by_contig) {
        GLnexus::unifier_stats stats1;
        H("unify sites",
          GLnexus::cli::utils::unify_sites(console, unifier_cfg, contigs, dsals_i, sample_count, sites, stats1));
        stats += stats1;
    }
    console->info("unified to {} sites cleanly with {} ALT alleles. {} ALT alleles were {} and {} were filtered out on quality thresholds.",
                  sites.size(), stats.unified_alleles, stats.lost_alleles,
                  (unifier_cfg.monoallelic_sites_for_lost_alleles ? "additionally included in monoallelic sites" : "lost due to failure to unify"),
                  stats.filtered_alleles);
    if (debug) {
        string filename("/tmp/sites.yml");
        console->info("Writing unified sites as YAML to {}", filename);
        H("write unified sites to file",
          GLnexus::cli::utils::write_unified_sites_to_file(sites, contigs, filename));
    }

    // genotype
    genotyper_cfg.output_residuals = debug;
    vector<string> hdr_lines = { ("##GLnexusConfig="+config_name), ("##GLnexusConfigCRC32C="+cfg_crc32c) };
    auto DX_JOB_ID = std::getenv("DX_JOB_ID");
    if (DX_JOB_ID) {
        // if running in DNAnexus, record job ID in header
        hdr_lines.push_back(string("##DX_JOB_ID=")+DX_JOB_ID);
    }
    string outfile("-");
    H("Genotyping",
      GLnexus::cli::utils::genotype(console, mem_budget, nr_threads, dbpath, genotyper_cfg, sites, hdr_lines, outfile));

    return 0;
}

void help(const char* prog) {
    cout << "Usage: " << prog << " [options] /vcf/file/1 .. /vcf/file/N" << endl
         << "Merge and joint-call input gVCF files, emitting multi-sample BCF on standard output." << endl << endl
         << "Options:" << endl
         << "  --bed FILE, -b FILE   three-column BED file of ranges to analyze (required)" << endl
         << "  --config X, -c X      configuration preset name or .yml filename (default: gatk)" << endl
         << "  --squeeze, -S         reduce pVCF size by suppressing detail in cells derived from reference bands" << endl
         << "  --list, -l            given files contain lists of gVCF filenames, one per line" << endl
         << "  --mem-gbytes X, -m X  memory budget, in gbytes (default: most of system memory)" << endl
         << "  --threads X, -t X     thread budget (default: all hardware threads)" << endl
         << "  --help, -h            print this help message" << endl
         << endl << "Configuration presets:" << endl;
    cout << GLnexus::cli::utils::describe_config_presets() << endl;
}

// Expected usage:
//    glnexus [vcf files]
//
int main(int argc, char *argv[]) {
    GLnexus::Status s;
    spdlog::set_level(spdlog::level::info);
    spdlog::set_pattern("[%t] %+");
    #ifdef NDEBUG
    #define BUILD_CONFIG "release"
    #else
    #define BUILD_CONFIG "debug"
    #endif
    console->info("glnexus_cli {} {} {}", BUILD_CONFIG, GIT_REVISION, __TIMESTAMP__);
    GLnexus::cli::utils::detect_jemalloc(console);

    if (argc < 2) {
        help(argv[0]);
        return 1;
    }

    static struct option long_options[] = {
        {"help", no_argument, 0, 'h'},
        {"bed", required_argument, 0, 'b'},
        {"config", required_argument, 0, 'c'},
        {"squeeze", no_argument, 0, 'S'},
        {"list", no_argument, 0, 'l'},
        {"mem-gbytes", required_argument, 0, 'm'},
        {"threads", required_argument, 0, 't'},
        {"bucket_size", required_argument, 0, 'x'},
        {"debug", no_argument, 0, 'd'},
        {"iter_compare", no_argument, 0, 'i'},
        {0, 0, 0, 0}
    };

    int c;
    string config_name = "gatk";
    bool squeeze = false;
    bool list_of_files = false;
    bool debug = false;
    bool iter_compare = false;
    string bedfilename;
    size_t mem_budget = 0, nr_threads = 0;
    size_t bucket_size = GLnexus::BCFKeyValueData::default_bucket_size;

    while (-1 != (c = getopt_long(argc, argv, "hb:dIx:m:t:c:",
                                  long_options, nullptr))) {
        switch (c) {
            case 'b':
                bedfilename = string(optarg);
                if (bedfilename.size() == 0) {
                    cerr <<  "invalid BED filename" << endl;
                    return 1;
                }
                break;

            case 'l':
                list_of_files = true;
                break;

            case 'c':
                config_name = string(optarg);
                break;

            case 'S':
                squeeze = true;
                break;

            case 'd':
                debug = true;
                break;

            case 'h':
            case '?':
                help(argv[0]);
                exit(0);
                break;

            case 'i':
                iter_compare = true;
                break;

            case 'x':
                bucket_size = strtoul(optarg, nullptr, 10);
                if (bucket_size == 0 || bucket_size > 1000000000) {
                    cerr << "bucket size should be in (1,1e9]" << endl;
                    return 1;
                }
                break;

            case 'm':
                mem_budget = strtoull(optarg, nullptr, 10);
                if (mem_budget == 0 || mem_budget > 16*1024) {
                    cerr << "invalid --mem-gbytes" << endl;
                    return 1;
                }
                mem_budget <<= 30;
                break;

            case 't':
                nr_threads = strtoull(optarg, nullptr, 10);
                if (nr_threads == 0 || nr_threads > 1024) {
                    cerr << "invalid --threads" << endl;
                    return 1;
                }
                break;

            default:
                abort ();
        }
    }

    if (optind > argc-1) {
        help(argv[0]);
        return 1;
    }

    vector<string> vcf_files, vcf_files_precursor;
    for (int i=optind; i < argc; i++) {
        vcf_files_precursor.push_back(string(argv[i]));
    }

    if (list_of_files) {
        for (const string& fn : vcf_files_precursor) {
            string gvcf;
            ifstream infile(fn);
            while (getline(infile, gvcf)) {
                vcf_files.push_back(gvcf);
            }
            if (infile.bad() || !infile.eof()) {
                H("read input file list", GLnexus::Status::IOError("reading", fn));
            }
        }
    } else {
        vcf_files = vcf_files_precursor;
    }

    return all_steps(vcf_files, bedfilename, config_name, squeeze, mem_budget, nr_threads, debug, iter_compare, bucket_size);
}
<commit_msg>CLI: process full length of all contigs if --bed is omitted closes #150<commit_after>// Basic GLnexus command-line interface for use on one compute node

#include <iostream>
#include <exception>
#include <fstream>
#include <getopt.h>
#include <sstream>
#include <cstdlib>
#include "vcf.h"
#include "hfile.h"
#include "service.h"
#include "unifier.h"
#include "BCFKeyValueData.h"
#include "RocksKeyValue.h"
#include "ctpl_stl.h"
#include "spdlog/spdlog.h"
#include "spdlog/sinks/stdout_sinks.h"
#include "cli_utils.h"

using namespace std;

auto console = spdlog::stderr_logger_mt("GLnexus");
GLnexus::Status s;
#define H(desc,expr) \
    s = expr; \
    if (s.bad()) { \
        console->error("Failed to {}: {}", desc, s.str()); \
        if (getenv("DX_JOB_ID")) { \
            ofstream joberrorjson("/home/dnanexus/job_error.json"); \
            joberrorjson << "{\"error\": {\"type\": \"AppError\", \"message\": \""; \
            joberrorjson << "Failed to " << desc << ": " << s.str(); \
            joberrorjson << "\"}}"; \
            joberrorjson.close(); \
        } \
        return 1; \
    }

// Perform all the separate GLnexus operations in one go.
// return 0 on success, 1 on failure.
static int all_steps(const vector<string> &vcf_files,
                     const string &bedfilename,
                     const string &config_name, bool squeeze,
                     size_t mem_budget, size_t nr_threads,
                     bool debug,
                     bool iter_compare,
                     size_t bucket_size) {
    GLnexus::Status s;
    GLnexus::unifier_config unifier_cfg;
    GLnexus::genotyper_config genotyper_cfg;
    string cfg_crc32c;

    if (vcf_files.empty()) {
        console->error("No source GVCF files specified");
        return 1;
    }

    H("load unifier/genotyper configuration",
        GLnexus::cli::utils::load_config(console, config_name, unifier_cfg, genotyper_cfg, cfg_crc32c, squeeze));

    // initilize empty database
    string dbpath("GLnexus.DB");
    vector<pair<string,size_t> > contigs;
    H("initialize database", GLnexus::cli::utils::db_init(console, dbpath, vcf_files[0], contigs,
                                                          bucket_size));

    {
        // sanity check, see that we can get the contigs back
        vector<pair<string,size_t> > contigs_dbg;
        H("read the contigs back from DB",
          GLnexus::cli::utils::db_get_contigs(console, dbpath, contigs_dbg));
        if (contigs_dbg != contigs)
            return GLnexus::Status::Invalid("error, contigs read from DB do not match originals");
    }

    // Load the GVCFs into the database
    {
        // use an empty range filter
        vector<GLnexus::range> ranges;
        H("bulk load into DB",
          GLnexus::cli::utils::db_bulk_load(console, mem_budget, nr_threads, vcf_files, dbpath, ranges, contigs, false));
    }

    if (iter_compare) {
        H("compare database iteration methods",
          GLnexus::cli::utils::compare_db_itertion_algorithms(console, dbpath, 50));
    }

    // discover alleles
    // TODO: overlap allele discovery with final compactions. have db_bulk_load output a RocksKeyValue pointer which we can reuse
    vector<GLnexus::range> ranges;
    if (bedfilename.empty()) {
        console->info("processing full length of {} contigs, as no --bed file was specified", std::to_string(contigs.size()));
        for (int rid = 0; rid < contigs.size(); ++rid) {
            ranges.push_back(GLnexus::range(rid, 0, contigs[rid].second));
        }
    } else {
        H("parse the bed file", GLnexus::cli::utils::parse_bed_file(console, bedfilename, contigs, ranges));
    }
    GLnexus::discovered_alleles dsals;
    unsigned sample_count = 0;
    H("discover alleles",
      GLnexus::cli::utils::discover_alleles(console, mem_budget, nr_threads, dbpath, ranges, contigs, dsals, sample_count));
    if (debug) {
        string filename("/tmp/dsals.yml");
        console->info("Writing discovered alleles as YAML to {}", filename);
        H("serialize discovered alleles to a file",
          GLnexus::cli::utils::yaml_write_discovered_alleles_to_file(dsals, contigs, sample_count, filename));
    }

    // partition dsals by contig to reduce peak memory usage in the unifier
    std::vector<GLnexus::discovered_alleles> dsals_by_contig(contigs.size());
    for (auto p = dsals.begin(); p != dsals.end(); dsals.erase(p++)) {
        UNPAIR(*p, al, dai);
        assert(al.pos.rid >= 0 && al.pos.rid < contigs.size());
        dsals_by_contig[al.pos.rid][al] = dai;
    }

    // unify sites
    // we could parallelize over dsals_by_contig although this might increase memory usage.
    vector<GLnexus::unified_site> sites;
    GLnexus::unifier_stats stats;
    for (auto& dsals_i : dsals_by_contig) {
        GLnexus::unifier_stats stats1;
        H("unify sites",
          GLnexus::cli::utils::unify_sites(console, unifier_cfg, contigs, dsals_i, sample_count, sites, stats1));
        stats += stats1;
    }
    console->info("unified to {} sites cleanly with {} ALT alleles. {} ALT alleles were {} and {} were filtered out on quality thresholds.",
                  sites.size(), stats.unified_alleles, stats.lost_alleles,
                  (unifier_cfg.monoallelic_sites_for_lost_alleles ? "additionally included in monoallelic sites" : "lost due to failure to unify"),
                  stats.filtered_alleles);
    if (debug) {
        string filename("/tmp/sites.yml");
        console->info("Writing unified sites as YAML to {}", filename);
        H("write unified sites to file",
          GLnexus::cli::utils::write_unified_sites_to_file(sites, contigs, filename));
    }

    // genotype
    genotyper_cfg.output_residuals = debug;
    vector<string> hdr_lines = { ("##GLnexusConfig="+config_name), ("##GLnexusConfigCRC32C="+cfg_crc32c) };
    auto DX_JOB_ID = std::getenv("DX_JOB_ID");
    if (DX_JOB_ID) {
        // if running in DNAnexus, record job ID in header
        hdr_lines.push_back(string("##DX_JOB_ID=")+DX_JOB_ID);
    }
    string outfile("-");
    H("genotype",
      GLnexus::cli::utils::genotype(console, mem_budget, nr_threads, dbpath, genotyper_cfg, sites, hdr_lines, outfile));

    return 0;
}

void help(const char* prog) {
    cout << "Usage: " << prog << " [options] /vcf/file/1 .. /vcf/file/N" << endl
         << "Merge and joint-call input gVCF files, emitting multi-sample BCF on standard output." << endl << endl
         << "Options:" << endl
         << "  --bed FILE, -b FILE   three-column BED file of ranges to analyze (if omitted, use full length of all contigs)" << endl
         << "  --config X, -c X      configuration preset name or .yml filename (default: gatk)" << endl
         << "  --squeeze, -S         reduce pVCF size by suppressing detail in cells derived from reference bands" << endl
         << "  --list, -l            given files contain lists of gVCF filenames, one per line" << endl
         << "  --mem-gbytes X, -m X  memory budget, in gbytes (default: most of system memory)" << endl
         << "  --threads X, -t X     thread budget (default: all hardware threads)" << endl
         << "  --help, -h            print this help message" << endl
         << endl << "Configuration presets:" << endl;
    cout << GLnexus::cli::utils::describe_config_presets() << endl;
}

// Expected usage:
//    glnexus [vcf files]
//
int main(int argc, char *argv[]) {
    GLnexus::Status s;
    spdlog::set_level(spdlog::level::info);
    spdlog::set_pattern("[%t] %+");
    #ifdef NDEBUG
    #define BUILD_CONFIG "release"
    #else
    #define BUILD_CONFIG "debug"
    #endif
    console->info("glnexus_cli {} {} {}", BUILD_CONFIG, GIT_REVISION, __TIMESTAMP__);
    GLnexus::cli::utils::detect_jemalloc(console);

    if (argc < 2) {
        help(argv[0]);
        return 1;
    }

    static struct option long_options[] = {
        {"help", no_argument, 0, 'h'},
        {"bed", required_argument, 0, 'b'},
        {"config", required_argument, 0, 'c'},
        {"squeeze", no_argument, 0, 'S'},
        {"list", no_argument, 0, 'l'},
        {"mem-gbytes", required_argument, 0, 'm'},
        {"threads", required_argument, 0, 't'},
        {"bucket_size", required_argument, 0, 'x'},
        {"debug", no_argument, 0, 'd'},
        {"iter_compare", no_argument, 0, 'i'},
        {0, 0, 0, 0}
    };

    int c;
    string config_name = "gatk";
    bool squeeze = false;
    bool list_of_files = false;
    bool debug = false;
    bool iter_compare = false;
    string bedfilename;
    size_t mem_budget = 0, nr_threads = 0;
    size_t bucket_size = GLnexus::BCFKeyValueData::default_bucket_size;

    while (-1 != (c = getopt_long(argc, argv, "hb:dIx:m:t:c:",
                                  long_options, nullptr))) {
        switch (c) {
            case 'b':
                bedfilename = string(optarg);
                if (bedfilename.size() == 0) {
                    cerr <<  "invalid BED filename" << endl;
                    return 1;
                }
                break;

            case 'l':
                list_of_files = true;
                break;

            case 'c':
                config_name = string(optarg);
                break;

            case 'S':
                squeeze = true;
                break;

            case 'd':
                debug = true;
                break;

            case 'h':
            case '?':
                help(argv[0]);
                exit(0);
                break;

            case 'i':
                iter_compare = true;
                break;

            case 'x':
                bucket_size = strtoul(optarg, nullptr, 10);
                if (bucket_size == 0 || bucket_size > 1000000000) {
                    cerr << "bucket size should be in (1,1e9]" << endl;
                    return 1;
                }
                break;

            case 'm':
                mem_budget = strtoull(optarg, nullptr, 10);
                if (mem_budget == 0 || mem_budget > 16*1024) {
                    cerr << "invalid --mem-gbytes" << endl;
                    return 1;
                }
                mem_budget <<= 30;
                break;

            case 't':
                nr_threads = strtoull(optarg, nullptr, 10);
                if (nr_threads == 0 || nr_threads > 1024) {
                    cerr << "invalid --threads" << endl;
                    return 1;
                }
                break;

            default:
                abort ();
        }
    }

    if (optind > argc-1) {
        help(argv[0]);
        return 1;
    }

    vector<string> vcf_files, vcf_files_precursor;
    for (int i=optind; i < argc; i++) {
        vcf_files_precursor.push_back(string(argv[i]));
    }

    if (list_of_files) {
        for (const string& fn : vcf_files_precursor) {
            string gvcf;
            ifstream infile(fn);
            while (getline(infile, gvcf)) {
                vcf_files.push_back(gvcf);
            }
            if (infile.bad() || !infile.eof()) {
                H("read input file list", GLnexus::Status::IOError("reading", fn));
            }
        }
    } else {
        vcf_files = vcf_files_precursor;
    }

    return all_steps(vcf_files, bedfilename, config_name, squeeze, mem_budget, nr_threads, debug, iter_compare, bucket_size);
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: resourceprovider.cxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: obo $ $Date: 2005-04-27 08:53:18 $
 *
 *  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): _______________________________________
 *
 *
 ************************************************************************/

//------------------------------------------------------------------------
// includes
//------------------------------------------------------------------------

#ifndef _OSL_DIAGNOSE_H_
#include <osl/diagnose.h>
#endif

#ifndef _RTL_USTRBUF_HXX_
#include <rtl/ustrbuf.hxx>
#endif

#ifndef _RESOURCEPROVIDER_HXX_
#include "resourceprovider.hxx"
#endif

#ifndef _VOS_MUTEX_HXX_
#include <vos/mutex.hxx>
#endif

#ifndef _SV_SVAPP_HXX
#include <vcl/svapp.hxx>
#endif

#ifndef _TOOLS_RESMGR_HXX
#include <tools/resmgr.hxx>
#endif

#ifndef _COM_SUN_STAR_UI_DIALOGS_COMMONFILEPICKERELEMENTIDS_HPP_
#include <com/sun/star/ui/dialogs/CommonFilePickerElementIds.hpp>
#endif

#ifndef _COM_SUN_STAR_UI_DIALOGS_EXTENDEDFILEPICKERELEMENTIDS_HPP_
#include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
#endif

#include <svtools/svtools.hrc>

//------------------------------------------------------------
// namespace directives
//------------------------------------------------------------

using rtl::OUString;
using namespace ::com::sun::star::ui::dialogs::ExtendedFilePickerElementIds;
using namespace ::com::sun::star::ui::dialogs::CommonFilePickerElementIds;

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

#define RES_NAME fps_office

#define FOLDERPICKER_TITLE            500
#define FOLDER_PICKER_DEF_DESCRIPTION 501

//------------------------------------------------------------
// we have to translate control ids to resource ids
//------------------------------------------------------------

struct _Entry
{
    sal_Int32 ctrlId;
    sal_Int16 resId;
};

_Entry CtrlIdToResIdTable[] = {
    { CHECKBOX_AUTOEXTENSION,                   STR_SVT_FILEPICKER_AUTO_EXTENSION },
    { CHECKBOX_PASSWORD,                        STR_SVT_FILEPICKER_PASSWORD },
    { CHECKBOX_FILTEROPTIONS,                   STR_SVT_FILEPICKER_FILTER_OPTIONS },
    { CHECKBOX_READONLY,                        STR_SVT_FILEPICKER_READONLY },
    { CHECKBOX_LINK,                            STR_SVT_FILEPICKER_INSERT_AS_LINK },
    { CHECKBOX_PREVIEW,                         STR_SVT_FILEPICKER_SHOW_PREVIEW },
    { PUSHBUTTON_PLAY,                          STR_SVT_FILEPICKER_PLAY },
    { LISTBOX_VERSION_LABEL,                    STR_SVT_FILEPICKER_VERSION },
    { LISTBOX_TEMPLATE_LABEL,                   STR_SVT_FILEPICKER_TEMPLATES },
    { LISTBOX_IMAGE_TEMPLATE_LABEL,             STR_SVT_FILEPICKER_IMAGE_TEMPLATE },
    { CHECKBOX_SELECTION,                       STR_SVT_FILEPICKER_SELECTION },
    { FOLDERPICKER_TITLE,                       STR_SVT_FOLDERPICKER_DEFAULT_TITLE },
    { FOLDER_PICKER_DEF_DESCRIPTION,            STR_SVT_FOLDERPICKER_DEFAULT_DESCRIPTION }
};

const sal_Int32 SIZE_TABLE = sizeof( CtrlIdToResIdTable ) / sizeof( _Entry );

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

sal_Int16 CtrlIdToResId( sal_Int32 aControlId )
{
    sal_Int16 aResId = -1;

    for ( sal_Int32 i = 0; i < SIZE_TABLE; i++ )
    {
        if ( CtrlIdToResIdTable[i].ctrlId == aControlId )
        {
            aResId = CtrlIdToResIdTable[i].resId;
            break;
        }
    }

    return aResId;
}

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

class CResourceProvider_Impl
{
public:

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

    CResourceProvider_Impl( )
    {
        m_ResMgr = CREATEVERSIONRESMGR( RES_NAME );
    }

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

    ~CResourceProvider_Impl( )
    {
        delete m_ResMgr;
    }

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

    OUString getResString( sal_Int16 aId )
    {
        String   aResString;
        OUString aResOUString;

        const ::vos::OGuard aGuard( Application::GetSolarMutex() );

        try
        {
            OSL_ASSERT( m_ResMgr );

            // translate the control id to a resource id
            sal_Int16 aResId = CtrlIdToResId( aId );

            if ( aResId > -1 )
            {
                aResString = String( ResId( aResId, m_ResMgr ) );
                aResOUString = OUString( aResString );
            }
        }
        catch(...)
        {
        }

        return aResOUString;
    }

public:
    ResMgr* m_ResMgr;
};

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

CResourceProvider::CResourceProvider( ) :
    m_pImpl( new CResourceProvider_Impl() )
{
}

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

CResourceProvider::~CResourceProvider( )
{
    delete m_pImpl;
}

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

OUString CResourceProvider::getResString( sal_Int32 aId )
{
   return m_pImpl->getResString( aId );
}
<commit_msg>INTEGRATION: CWS ooo19126 (1.6.40); FILE MERGED 2005/09/05 17:13:49 rt 1.6.40.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: resourceprovider.cxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 23:53:06 $
 *
 *  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
 *
 ************************************************************************/

//------------------------------------------------------------------------
// includes
//------------------------------------------------------------------------

#ifndef _OSL_DIAGNOSE_H_
#include <osl/diagnose.h>
#endif

#ifndef _RTL_USTRBUF_HXX_
#include <rtl/ustrbuf.hxx>
#endif

#ifndef _RESOURCEPROVIDER_HXX_
#include "resourceprovider.hxx"
#endif

#ifndef _VOS_MUTEX_HXX_
#include <vos/mutex.hxx>
#endif

#ifndef _SV_SVAPP_HXX
#include <vcl/svapp.hxx>
#endif

#ifndef _TOOLS_RESMGR_HXX
#include <tools/resmgr.hxx>
#endif

#ifndef _COM_SUN_STAR_UI_DIALOGS_COMMONFILEPICKERELEMENTIDS_HPP_
#include <com/sun/star/ui/dialogs/CommonFilePickerElementIds.hpp>
#endif

#ifndef _COM_SUN_STAR_UI_DIALOGS_EXTENDEDFILEPICKERELEMENTIDS_HPP_
#include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
#endif

#include <svtools/svtools.hrc>

//------------------------------------------------------------
// namespace directives
//------------------------------------------------------------

using rtl::OUString;
using namespace ::com::sun::star::ui::dialogs::ExtendedFilePickerElementIds;
using namespace ::com::sun::star::ui::dialogs::CommonFilePickerElementIds;

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

#define RES_NAME fps_office

#define FOLDERPICKER_TITLE            500
#define FOLDER_PICKER_DEF_DESCRIPTION 501

//------------------------------------------------------------
// we have to translate control ids to resource ids
//------------------------------------------------------------

struct _Entry
{
    sal_Int32 ctrlId;
    sal_Int16 resId;
};

_Entry CtrlIdToResIdTable[] = {
    { CHECKBOX_AUTOEXTENSION,                   STR_SVT_FILEPICKER_AUTO_EXTENSION },
    { CHECKBOX_PASSWORD,                        STR_SVT_FILEPICKER_PASSWORD },
    { CHECKBOX_FILTEROPTIONS,                   STR_SVT_FILEPICKER_FILTER_OPTIONS },
    { CHECKBOX_READONLY,                        STR_SVT_FILEPICKER_READONLY },
    { CHECKBOX_LINK,                            STR_SVT_FILEPICKER_INSERT_AS_LINK },
    { CHECKBOX_PREVIEW,                         STR_SVT_FILEPICKER_SHOW_PREVIEW },
    { PUSHBUTTON_PLAY,                          STR_SVT_FILEPICKER_PLAY },
    { LISTBOX_VERSION_LABEL,                    STR_SVT_FILEPICKER_VERSION },
    { LISTBOX_TEMPLATE_LABEL,                   STR_SVT_FILEPICKER_TEMPLATES },
    { LISTBOX_IMAGE_TEMPLATE_LABEL,             STR_SVT_FILEPICKER_IMAGE_TEMPLATE },
    { CHECKBOX_SELECTION,                       STR_SVT_FILEPICKER_SELECTION },
    { FOLDERPICKER_TITLE,                       STR_SVT_FOLDERPICKER_DEFAULT_TITLE },
    { FOLDER_PICKER_DEF_DESCRIPTION,            STR_SVT_FOLDERPICKER_DEFAULT_DESCRIPTION }
};

const sal_Int32 SIZE_TABLE = sizeof( CtrlIdToResIdTable ) / sizeof( _Entry );

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

sal_Int16 CtrlIdToResId( sal_Int32 aControlId )
{
    sal_Int16 aResId = -1;

    for ( sal_Int32 i = 0; i < SIZE_TABLE; i++ )
    {
        if ( CtrlIdToResIdTable[i].ctrlId == aControlId )
        {
            aResId = CtrlIdToResIdTable[i].resId;
            break;
        }
    }

    return aResId;
}

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

class CResourceProvider_Impl
{
public:

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

    CResourceProvider_Impl( )
    {
        m_ResMgr = CREATEVERSIONRESMGR( RES_NAME );
    }

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

    ~CResourceProvider_Impl( )
    {
        delete m_ResMgr;
    }

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

    OUString getResString( sal_Int16 aId )
    {
        String   aResString;
        OUString aResOUString;

        const ::vos::OGuard aGuard( Application::GetSolarMutex() );

        try
        {
            OSL_ASSERT( m_ResMgr );

            // translate the control id to a resource id
            sal_Int16 aResId = CtrlIdToResId( aId );

            if ( aResId > -1 )
            {
                aResString = String( ResId( aResId, m_ResMgr ) );
                aResOUString = OUString( aResString );
            }
        }
        catch(...)
        {
        }

        return aResOUString;
    }

public:
    ResMgr* m_ResMgr;
};

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

CResourceProvider::CResourceProvider( ) :
    m_pImpl( new CResourceProvider_Impl() )
{
}

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

CResourceProvider::~CResourceProvider( )
{
    delete m_pImpl;
}

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

OUString CResourceProvider::getResString( sal_Int32 aId )
{
   return m_pImpl->getResString( aId );
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: registerservices.cxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: as $ $Date: 2001-01-26 08:39:47 $
 *
 *  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): _______________________________________
 *
 *
 ************************************************************************/
//_________________________________________________________________________________________________________________
//  includes of my own project
//_________________________________________________________________________________________________________________

#ifndef __FRAMEWORK_MACROS_REGISTRATION_HXX_
#include <macros/registration.hxx>
#endif

/*=================================================================================================================
    Add new include and new register info to for new services.

    Example:

        #ifndef __YOUR_SERVICE_1_HXX_
        #include <service1.hxx>
        #endif

        #ifndef __YOUR_SERVICE_2_HXX_
        #include <service2.hxx>
        #endif

        COMPONENTGETIMPLEMENTATIONENVIRONMENT

        COMPONENTWRITEINFO  (   COMPONENTINFO( Service1 )
                                 COMPONENTINFO( Service2 )
                            )

        COMPONENTGETFACTORY (   IFFACTORIE( Service1 )
                                 else
                                IFFACTORIE( Service2 )
                             )
=================================================================================================================*/

#ifndef __FRAMEWORK_SERVICES_URLTRANSFORMER_HXX_
#include <services/urltransformer.hxx>
#endif

#ifndef __FRAMEWORK_SERVICES_PLUGINFRAME_HXX_
#include <services/pluginframe.hxx>
#endif

#ifndef __FRAMEWORK_SERVICES_DESKTOP_HXX_
#include <services/desktop.hxx>
#endif

#ifndef __FRAMEWORK_SERVICES_DOCUMENTPROPERTIES_HXX_
#include <services/documentproperties.hxx>
#endif

#ifndef __FRAMEWORK_SERVICES_TASK_HXX_
#include <services/task.hxx>
#endif

#ifndef __FRAMEWORK_SERVICES_FRAME_HXX_
#include <services/frame.hxx>
#endif

#ifdef TF_FILTER//MUSTFILTER
    #ifndef __FRAMEWORK_SERVICES_FILTERFACTORY_HXX_
    #include <services/filterfactory.hxx>
    #endif

    #ifndef __FRAMEWORK_SERVICES_TYPEDETECTION_HXX_
    #include <services/typedetection.hxx>
    #endif
#endif//MUSTFILTER

COMPONENTGETIMPLEMENTATIONENVIRONMENT

#ifdef TF_FILTER//MUSTFILTER
COMPONENTWRITEINFO  (   COMPONENTINFO( ::framework::URLTransformer              )
                        COMPONENTINFO( ::framework::PlugInFrame                 )
                        COMPONENTINFO( ::framework::Desktop                     )
                        COMPONENTINFO( ::framework::Task                        )
                        COMPONENTINFO( ::framework::Frame                       )
                        COMPONENTINFO( ::framework::FilterFactory               )
                        COMPONENTINFO( ::framework::TypeDetection               )
                        COMPONENTINFO( ::framework::DocumentProperties          )
                    )

COMPONENTGETFACTORY (   IFFACTORY( ::framework::URLTransformer                  )   else
                        IFFACTORY( ::framework::PlugInFrame                     )   else
                        IFFACTORY( ::framework::Desktop                         )   else
                        IFFACTORY( ::framework::Task                            )   else
                        IFFACTORY( ::framework::Frame                           )   else
                        IFFACTORY( ::framework::FilterFactory                   )   else
                        IFFACTORY( ::framework::TypeDetection                   )   else
                        IFFACTORY( ::framework::DocumentProperties              )
                    )
#else//MUSTFILTER
COMPONENTWRITEINFO  (   COMPONENTINFO( ::framework::URLTransformer              )
                        COMPONENTINFO( ::framework::PlugInFrame                 )
                        COMPONENTINFO( ::framework::Desktop                     )
                        COMPONENTINFO( ::framework::Task                        )
                        COMPONENTINFO( ::framework::Frame                       )
                        COMPONENTINFO( ::framework::DocumentProperties          )
                    )

COMPONENTGETFACTORY (   IFFACTORY( ::framework::URLTransformer                  )   else
                        IFFACTORY( ::framework::PlugInFrame                     )   else
                        IFFACTORY( ::framework::Desktop                         )   else
                        IFFACTORY( ::framework::Task                            )   else
                        IFFACTORY( ::framework::Frame                           )   else
                        IFFACTORY( ::framework::DocumentProperties              )
                    )
#endif//MUSTFILTER
<commit_msg>#65293# include order: limits (from the stl) has to be included first, otherwise for solaris you get problems caused by a min/max macro defined somewhere<commit_after>/*************************************************************************
 *
 *  $RCSfile: registerservices.cxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: rt $ $Date: 2001-02-01 13:31:35 $
 *
 *  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): _______________________________________
 *
 *
 ************************************************************************/
//_________________________________________________________________________________________________________________
//  includes of my own project
//_________________________________________________________________________________________________________________

#include <limits>

#ifndef __FRAMEWORK_MACROS_REGISTRATION_HXX_
#include <macros/registration.hxx>
#endif

/*=================================================================================================================
    Add new include and new register info to for new services.

    Example:

        #ifndef __YOUR_SERVICE_1_HXX_
        #include <service1.hxx>
        #endif

        #ifndef __YOUR_SERVICE_2_HXX_
        #include <service2.hxx>
        #endif

        COMPONENTGETIMPLEMENTATIONENVIRONMENT

        COMPONENTWRITEINFO  (   COMPONENTINFO( Service1 )
                                 COMPONENTINFO( Service2 )
                            )

        COMPONENTGETFACTORY (   IFFACTORIE( Service1 )
                                 else
                                IFFACTORIE( Service2 )
                             )
=================================================================================================================*/

#ifndef __FRAMEWORK_SERVICES_URLTRANSFORMER_HXX_
#include <services/urltransformer.hxx>
#endif

#ifndef __FRAMEWORK_SERVICES_PLUGINFRAME_HXX_
#include <services/pluginframe.hxx>
#endif

#ifndef __FRAMEWORK_SERVICES_DESKTOP_HXX_
#include <services/desktop.hxx>
#endif

#ifndef __FRAMEWORK_SERVICES_DOCUMENTPROPERTIES_HXX_
#include <services/documentproperties.hxx>
#endif

#ifndef __FRAMEWORK_SERVICES_TASK_HXX_
#include <services/task.hxx>
#endif

#ifndef __FRAMEWORK_SERVICES_FRAME_HXX_
#include <services/frame.hxx>
#endif

#ifdef TF_FILTER//MUSTFILTER
    #ifndef __FRAMEWORK_SERVICES_FILTERFACTORY_HXX_
    #include <services/filterfactory.hxx>
    #endif

    #ifndef __FRAMEWORK_SERVICES_TYPEDETECTION_HXX_
    #include <services/typedetection.hxx>
    #endif
#endif//MUSTFILTER

COMPONENTGETIMPLEMENTATIONENVIRONMENT

#ifdef TF_FILTER//MUSTFILTER
COMPONENTWRITEINFO  (   COMPONENTINFO( ::framework::URLTransformer              )
                        COMPONENTINFO( ::framework::PlugInFrame                 )
                        COMPONENTINFO( ::framework::Desktop                     )
                        COMPONENTINFO( ::framework::Task                        )
                        COMPONENTINFO( ::framework::Frame                       )
                        COMPONENTINFO( ::framework::FilterFactory               )
                        COMPONENTINFO( ::framework::TypeDetection               )
                        COMPONENTINFO( ::framework::DocumentProperties          )
                    )

COMPONENTGETFACTORY (   IFFACTORY( ::framework::URLTransformer                  )   else
                        IFFACTORY( ::framework::PlugInFrame                     )   else
                        IFFACTORY( ::framework::Desktop                         )   else
                        IFFACTORY( ::framework::Task                            )   else
                        IFFACTORY( ::framework::Frame                           )   else
                        IFFACTORY( ::framework::FilterFactory                   )   else
                        IFFACTORY( ::framework::TypeDetection                   )   else
                        IFFACTORY( ::framework::DocumentProperties              )
                    )
#else//MUSTFILTER
COMPONENTWRITEINFO  (   COMPONENTINFO( ::framework::URLTransformer              )
                        COMPONENTINFO( ::framework::PlugInFrame                 )
                        COMPONENTINFO( ::framework::Desktop                     )
                        COMPONENTINFO( ::framework::Task                        )
                        COMPONENTINFO( ::framework::Frame                       )
                        COMPONENTINFO( ::framework::DocumentProperties          )
                    )

COMPONENTGETFACTORY (   IFFACTORY( ::framework::URLTransformer                  )   else
                        IFFACTORY( ::framework::PlugInFrame                     )   else
                        IFFACTORY( ::framework::Desktop                         )   else
                        IFFACTORY( ::framework::Task                            )   else
                        IFFACTORY( ::framework::Frame                           )   else
                        IFFACTORY( ::framework::DocumentProperties              )
                    )
#endif//MUSTFILTER
<|endoftext|>


<commit_before>/*
 * Copywrite 2014-2015 Krzysztof Stasik. All rights reserved.
 */
#include "base/network/url.h"

#include <string>
#include <stdlib.h>

namespace Base {

Url::Url() {
  m_hostname[0] = '\0';
  m_service[0] = '\0';
}

Url::Url(const AddressIPv4 &address, u16 port) {
  snprintf(m_service, kServiceMax, "%d", port);
  snprintf(m_hostname, kHostnameMax, "%d.%d.%d.%d", address.GetA(),
           address.GetB(), address.GetC(), address.GetD());
}

Url::Url(const char *string) {
  std::string address = string;

  std::size_t a_pos = 0;
  std::size_t b_pos = address.find('.', a_pos) + 1;
  std::size_t c_pos = address.find('.', b_pos) + 1;
  std::size_t d_pos = address.find('.', c_pos) + 1;
  std::size_t p_pos = address.find(':', d_pos) + 1;

  strncpy(m_hostname, string, p_pos > kHostnameMax ? kHostnameMax : p_pos);
  m_hostname[kHostnameMax - 1] = '\0';
  strncpy(m_service, address.substr(p_pos).c_str(), kServiceMax);
  m_service[kServiceMax - 1] = '\0';
}

Url::Url(const char *string, u16 port) {
  strncpy(m_hostname, string, kHostnameMax);
  m_hostname[kHostnameMax - 1] = '\0';
  snprintf(m_service, kServiceMax, "%d", port);
}

Url::Url(const char *hostname, const char *service) {
  strncpy(m_hostname, hostname, kHostnameMax);
  m_hostname[kHostnameMax - 1] = '\0';
}

Url::Url(const Socket::Address &addr) {
  addr.GetHostname(m_hostname, kHostnameMax);
  addr.GetService(m_service, kServiceMax);
}

u16 Url::GetPort() const { return atoi(m_service); }

} // namespace Base
<commit_msg>* url service fix<commit_after>/*
 * Copywrite 2014-2015 Krzysztof Stasik. All rights reserved.
 */
#include "base/network/url.h"

#include <string>
#include <stdlib.h>

namespace Base {

Url::Url() {
  m_hostname[0] = '\0';
  m_service[0] = '\0';
}

Url::Url(const AddressIPv4 &address, u16 port) {
  snprintf(m_service, kServiceMax, "%d", port);
  snprintf(m_hostname, kHostnameMax, "%d.%d.%d.%d", address.GetA(),
           address.GetB(), address.GetC(), address.GetD());
}

Url::Url(const char *string) {
  std::string address = string;

  std::size_t a_pos = 0;
  std::size_t b_pos = address.find('.', a_pos) + 1;
  std::size_t c_pos = address.find('.', b_pos) + 1;
  std::size_t d_pos = address.find('.', c_pos) + 1;
  std::size_t p_pos = address.find(':', d_pos) + 1;

  strncpy(m_hostname, string, p_pos > kHostnameMax ? kHostnameMax : p_pos);
  m_hostname[kHostnameMax - 1] = '\0';
  strncpy(m_service, address.substr(p_pos).c_str(), kServiceMax);
  m_service[kServiceMax - 1] = '\0';
}

Url::Url(const char *string, u16 port) {
  strncpy(m_hostname, string, kHostnameMax);
  m_hostname[kHostnameMax - 1] = '\0';
  snprintf(m_service, kServiceMax, "%d", port);
}

Url::Url(const char *hostname, const char *service) {
  strncpy(m_hostname, hostname, kHostnameMax);
  m_hostname[kHostnameMax - 1] = '\0';
  strncpy(m_service, service, kServiceMax);
  m_hostname[kServiceMax - 1] = '\0';
}

Url::Url(const Socket::Address &addr) {
  addr.GetHostname(m_hostname, kHostnameMax);
  addr.GetService(m_service, kServiceMax);
}

u16 Url::GetPort() const { return atoi(m_service); }

} // namespace Base
<|endoftext|>