<commit_before>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2014 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

#ifndef MAPNIK_MARKER_HELPERS_HPP
#define MAPNIK_MARKER_HELPERS_HPP

#include <mapnik/color.hpp>
#include <mapnik/feature.hpp>
#include <mapnik/geometry_impl.hpp>
#include <mapnik/geometry_type.hpp>
#include <mapnik/geometry_centroid.hpp>
#include <mapnik/geom_util.hpp>
#include <mapnik/symbolizer.hpp>
#include <mapnik/expression_node.hpp>
#include <mapnik/expression_evaluator.hpp>
#include <mapnik/svg/svg_path_attributes.hpp>
#include <mapnik/svg/svg_converter.hpp>
#include <mapnik/marker.hpp> // for svg_storage_type
#include <mapnik/markers_placement.hpp>
#include <mapnik/attribute.hpp>
#include <mapnik/box2d.hpp>
#include <mapnik/vertex_converters.hpp>
#include <mapnik/vertex_processor.hpp>
#include <mapnik/label_collision_detector.hpp>
#include <mapnik/renderer_common/apply_vertex_converter.hpp>

// agg
#include "agg_trans_affine.h"

// boost
#include <boost/optional.hpp>
#include <boost/geometry/algorithms/centroid.hpp>
// stl
#include <memory>
#include <type_traits> // remove_reference
#include <cmath>

namespace mapnik {

struct clip_poly_tag;

using svg_attribute_type = agg::pod_bvector<svg::path_attributes>;

template <typename Detector>
struct vector_markers_dispatch : util::noncopyable
{
    vector_markers_dispatch(svg_path_ptr const& src,
                            agg::trans_affine const& marker_trans,
                            symbolizer_base const& sym,
                            Detector & detector,
                            double scale_factor,
                            feature_impl & feature,
                            attributes const& vars)
    : src_(src),
        marker_trans_(marker_trans),
        sym_(sym),
        detector_(detector),
        feature_(feature),
        vars_(vars),
        scale_factor_(scale_factor)
    {}

    virtual ~vector_markers_dispatch() {}

    template <typename T>
    void add_path(T & path)
    {
        marker_placement_enum placement_method = get<marker_placement_enum, keys::markers_placement_type>(sym_, feature_, vars_);
        value_bool ignore_placement = get<value_bool, keys::ignore_placement>(sym_, feature_, vars_);
        value_bool allow_overlap = get<value_bool, keys::allow_overlap>(sym_, feature_, vars_);
        value_bool avoid_edges = get<value_bool, keys::avoid_edges>(sym_, feature_, vars_);
        value_double opacity = get<value_double,keys::opacity>(sym_, feature_, vars_);
        value_double spacing = get<value_double, keys::spacing>(sym_, feature_, vars_);
        value_double max_error = get<value_double, keys::max_error>(sym_, feature_, vars_);
        coord2d center = src_->bounding_box().center();
        agg::trans_affine_translation recenter(-center.x, -center.y);
        agg::trans_affine tr = recenter * marker_trans_;
        markers_placement_params params { src_->bounding_box(), tr, spacing * scale_factor_, max_error, allow_overlap, avoid_edges };
        markers_placement_finder<T, Detector> placement_finder(
            placement_method, path, detector_, params);
        double x, y, angle = .0;
        while (placement_finder.get_point(x, y, angle, ignore_placement))
        {
            agg::trans_affine matrix = tr;
            matrix.rotate(angle);
            matrix.translate(x, y);
            render_marker(matrix, opacity);
        }
    }

    virtual void render_marker(agg::trans_affine const& marker_tr, double opacity) = 0;

protected:
    svg_path_ptr const& src_;
    agg::trans_affine const& marker_trans_;
    symbolizer_base const& sym_;
    Detector & detector_;
    feature_impl & feature_;
    attributes const& vars_;
    double scale_factor_;
};

template <typename Detector>
struct raster_markers_dispatch : util::noncopyable
{
    raster_markers_dispatch(image_rgba8 const& src,
                            agg::trans_affine const& marker_trans,
                            symbolizer_base const& sym,
                            Detector & detector,
                            double scale_factor,
                            feature_impl & feature,
                            attributes const& vars)
    : src_(src),
        marker_trans_(marker_trans),
        sym_(sym),
        detector_(detector),
        feature_(feature),
        vars_(vars),
        scale_factor_(scale_factor)
    {}

    virtual ~raster_markers_dispatch() {}

    template <typename T>
    void add_path(T & path)
    {
        marker_placement_enum placement_method = get<marker_placement_enum, keys::markers_placement_type>(sym_, feature_, vars_);
        value_bool allow_overlap = get<value_bool, keys::allow_overlap>(sym_, feature_, vars_);
        value_bool avoid_edges = get<value_bool, keys::avoid_edges>(sym_, feature_, vars_);
        value_double opacity = get<value_double, keys::opacity>(sym_, feature_, vars_);
        value_bool ignore_placement = get<value_bool, keys::ignore_placement>(sym_, feature_, vars_);
        value_double spacing = get<value_double, keys::spacing>(sym_, feature_, vars_);
        value_double max_error = get<value_double, keys::max_error>(sym_, feature_, vars_);
        box2d<double> bbox(0,0, src_.width(),src_.height());
        markers_placement_params params { bbox, marker_trans_, spacing * scale_factor_, max_error, allow_overlap, avoid_edges };
        markers_placement_finder<T, label_collision_detector4> placement_finder(
            placement_method, path, detector_, params);
        double x, y, angle = .0;
        while (placement_finder.get_point(x, y, angle, ignore_placement))
        {
            agg::trans_affine matrix = marker_trans_;
            matrix.rotate(angle);
            matrix.translate(x, y);
            render_marker(matrix, opacity);
        }
    }

    virtual void render_marker(agg::trans_affine const& marker_tr, double opacity) = 0;

protected:
    image_rgba8 const& src_;
    agg::trans_affine const& marker_trans_;
    symbolizer_base const& sym_;
    Detector & detector_;
    feature_impl & feature_;
    attributes const& vars_;
    double scale_factor_;
};

void build_ellipse(symbolizer_base const& sym, mapnik::feature_impl & feature, attributes const& vars, svg_storage_type & marker_ellipse, svg::svg_path_adapter & svg_path);

bool push_explicit_style(svg_attribute_type const& src,
                         svg_attribute_type & dst,
                         symbolizer_base const& sym,
                         feature_impl & feature,
                         attributes const& vars);

void setup_transform_scaling(agg::trans_affine & tr,
                             double svg_width,
                             double svg_height,
                             mapnik::feature_impl & feature,
                             attributes const& vars,
                             symbolizer_base const& sym);

// Apply markers to a feature with multiple geometries
template <typename Converter>
void apply_markers_multi(feature_impl const& feature, attributes const& vars, Converter & converter, symbolizer_base const& sym)
{
    using vertex_converter_type = Converter;
    using apply_vertex_converter_type = detail::apply_vertex_converter<vertex_converter_type>;
    using vertex_processor_type = new_geometry::vertex_processor<apply_vertex_converter_type>;

    auto const& geom = feature.get_geometry();
    new_geometry::geometry_types type = new_geometry::geometry_type(geom);

    if (type == new_geometry::geometry_types::Point
        || new_geometry::geometry_types::LineString
        || new_geometry::geometry_types::Polygon)
    {
        apply_vertex_converter_type apply(converter);
        mapnik::util::apply_visitor(vertex_processor_type(apply), geom);
    }
    else if (type != new_geometry::geometry_types::GeometryCollection) // multi geometries
    {

        marker_multi_policy_enum multi_policy = get<marker_multi_policy_enum, keys::markers_multipolicy>(sym, feature, vars);
        marker_placement_enum placement = get<marker_placement_enum, keys::markers_placement_type>(sym, feature, vars);

        if (placement == MARKER_POINT_PLACEMENT &&
            multi_policy == MARKER_WHOLE_MULTI)
        {
            new_geometry::point pt;
            if (new_geometry::centroid(geom, pt))
            {
                // unset any clipping since we're now dealing with a point
                converter.template unset<clip_poly_tag>();
                new_geometry::point_vertex_adapter va(pt);
                converter.apply(va);
            }
        }
        else if ((placement == MARKER_POINT_PLACEMENT || placement == MARKER_INTERIOR_PLACEMENT) &&
                 multi_policy == MARKER_LARGEST_MULTI)
        {
            // Only apply to path with largest envelope area
            // TODO: consider using true area for polygon types
            if (type == new_geometry::geometry_types::MultiPolygon)
            {
                new_geometry::multi_polygon multi_poly = mapnik::util::get<new_geometry::multi_polygon>(geom);
                double maxarea = 0;
                new_geometry::polygon const* largest = 0;
                for (new_geometry::polygon const& poly : multi_poly)
                {
                    box2d<double> bbox = new_geometry::envelope(poly);
                    new_geometry::polygon_vertex_adapter va(poly);
                    double area = bbox.width() * bbox.height();
                    if (area > maxarea)
                    {
                        maxarea = area;
                        largest = &poly;
                    }
                }
                if (largest)
                {
                    new_geometry::polygon_vertex_adapter va(*largest);
                    converter.apply(va);
                }
            }
        }
        else if (type == new_geometry::geometry_types::MultiPolygon)
        {
            if (multi_policy != MARKER_EACH_MULTI && placement != MARKER_POINT_PLACEMENT)
            {
                MAPNIK_LOG_WARN(marker_symbolizer) << "marker_multi_policy != 'each' has no effect with marker_placement != 'point'";
            }
            new_geometry::multi_polygon multi_poly = mapnik::util::get<new_geometry::multi_polygon>(geom);
            for (auto const& poly : multi_poly)
            {
                new_geometry::polygon_vertex_adapter va(poly);
                converter.apply(va);
            }
        }
    }
}

}

#endif //MAPNIK_MARKER_HELPERS_HPP
<commit_msg>remove unused headers<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2014 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

#ifndef MAPNIK_MARKER_HELPERS_HPP
#define MAPNIK_MARKER_HELPERS_HPP

#include <mapnik/color.hpp>
#include <mapnik/feature.hpp>
#include <mapnik/geometry_impl.hpp>
#include <mapnik/geometry_type.hpp>
#include <mapnik/geometry_centroid.hpp>
#include <mapnik/symbolizer.hpp>
#include <mapnik/expression_node.hpp>
#include <mapnik/expression_evaluator.hpp>
#include <mapnik/svg/svg_path_attributes.hpp>
#include <mapnik/svg/svg_converter.hpp>
#include <mapnik/marker.hpp> // for svg_storage_type
#include <mapnik/markers_placement.hpp>
#include <mapnik/attribute.hpp>
#include <mapnik/box2d.hpp>
#include <mapnik/vertex_converters.hpp>
#include <mapnik/vertex_processor.hpp>
#include <mapnik/label_collision_detector.hpp>
#include <mapnik/renderer_common/apply_vertex_converter.hpp>

// agg
#include "agg_trans_affine.h"

// boost
#include <boost/optional.hpp>
// stl
#include <memory>
#include <type_traits> // remove_reference
#include <cmath>

namespace mapnik {

struct clip_poly_tag;

using svg_attribute_type = agg::pod_bvector<svg::path_attributes>;

template <typename Detector>
struct vector_markers_dispatch : util::noncopyable
{
    vector_markers_dispatch(svg_path_ptr const& src,
                            agg::trans_affine const& marker_trans,
                            symbolizer_base const& sym,
                            Detector & detector,
                            double scale_factor,
                            feature_impl & feature,
                            attributes const& vars)
    : src_(src),
        marker_trans_(marker_trans),
        sym_(sym),
        detector_(detector),
        feature_(feature),
        vars_(vars),
        scale_factor_(scale_factor)
    {}

    virtual ~vector_markers_dispatch() {}

    template <typename T>
    void add_path(T & path)
    {
        marker_placement_enum placement_method = get<marker_placement_enum, keys::markers_placement_type>(sym_, feature_, vars_);
        value_bool ignore_placement = get<value_bool, keys::ignore_placement>(sym_, feature_, vars_);
        value_bool allow_overlap = get<value_bool, keys::allow_overlap>(sym_, feature_, vars_);
        value_bool avoid_edges = get<value_bool, keys::avoid_edges>(sym_, feature_, vars_);
        value_double opacity = get<value_double,keys::opacity>(sym_, feature_, vars_);
        value_double spacing = get<value_double, keys::spacing>(sym_, feature_, vars_);
        value_double max_error = get<value_double, keys::max_error>(sym_, feature_, vars_);
        coord2d center = src_->bounding_box().center();
        agg::trans_affine_translation recenter(-center.x, -center.y);
        agg::trans_affine tr = recenter * marker_trans_;
        markers_placement_params params { src_->bounding_box(), tr, spacing * scale_factor_, max_error, allow_overlap, avoid_edges };
        markers_placement_finder<T, Detector> placement_finder(
            placement_method, path, detector_, params);
        double x, y, angle = .0;
        while (placement_finder.get_point(x, y, angle, ignore_placement))
        {
            agg::trans_affine matrix = tr;
            matrix.rotate(angle);
            matrix.translate(x, y);
            render_marker(matrix, opacity);
        }
    }

    virtual void render_marker(agg::trans_affine const& marker_tr, double opacity) = 0;

protected:
    svg_path_ptr const& src_;
    agg::trans_affine const& marker_trans_;
    symbolizer_base const& sym_;
    Detector & detector_;
    feature_impl & feature_;
    attributes const& vars_;
    double scale_factor_;
};

template <typename Detector>
struct raster_markers_dispatch : util::noncopyable
{
    raster_markers_dispatch(image_rgba8 const& src,
                            agg::trans_affine const& marker_trans,
                            symbolizer_base const& sym,
                            Detector & detector,
                            double scale_factor,
                            feature_impl & feature,
                            attributes const& vars)
    : src_(src),
        marker_trans_(marker_trans),
        sym_(sym),
        detector_(detector),
        feature_(feature),
        vars_(vars),
        scale_factor_(scale_factor)
    {}

    virtual ~raster_markers_dispatch() {}

    template <typename T>
    void add_path(T & path)
    {
        marker_placement_enum placement_method = get<marker_placement_enum, keys::markers_placement_type>(sym_, feature_, vars_);
        value_bool allow_overlap = get<value_bool, keys::allow_overlap>(sym_, feature_, vars_);
        value_bool avoid_edges = get<value_bool, keys::avoid_edges>(sym_, feature_, vars_);
        value_double opacity = get<value_double, keys::opacity>(sym_, feature_, vars_);
        value_bool ignore_placement = get<value_bool, keys::ignore_placement>(sym_, feature_, vars_);
        value_double spacing = get<value_double, keys::spacing>(sym_, feature_, vars_);
        value_double max_error = get<value_double, keys::max_error>(sym_, feature_, vars_);
        box2d<double> bbox(0,0, src_.width(),src_.height());
        markers_placement_params params { bbox, marker_trans_, spacing * scale_factor_, max_error, allow_overlap, avoid_edges };
        markers_placement_finder<T, label_collision_detector4> placement_finder(
            placement_method, path, detector_, params);
        double x, y, angle = .0;
        while (placement_finder.get_point(x, y, angle, ignore_placement))
        {
            agg::trans_affine matrix = marker_trans_;
            matrix.rotate(angle);
            matrix.translate(x, y);
            render_marker(matrix, opacity);
        }
    }

    virtual void render_marker(agg::trans_affine const& marker_tr, double opacity) = 0;

protected:
    image_rgba8 const& src_;
    agg::trans_affine const& marker_trans_;
    symbolizer_base const& sym_;
    Detector & detector_;
    feature_impl & feature_;
    attributes const& vars_;
    double scale_factor_;
};

void build_ellipse(symbolizer_base const& sym, mapnik::feature_impl & feature, attributes const& vars, svg_storage_type & marker_ellipse, svg::svg_path_adapter & svg_path);

bool push_explicit_style(svg_attribute_type const& src,
                         svg_attribute_type & dst,
                         symbolizer_base const& sym,
                         feature_impl & feature,
                         attributes const& vars);

void setup_transform_scaling(agg::trans_affine & tr,
                             double svg_width,
                             double svg_height,
                             mapnik::feature_impl & feature,
                             attributes const& vars,
                             symbolizer_base const& sym);

// Apply markers to a feature with multiple geometries
template <typename Converter>
void apply_markers_multi(feature_impl const& feature, attributes const& vars, Converter & converter, symbolizer_base const& sym)
{
    using vertex_converter_type = Converter;
    using apply_vertex_converter_type = detail::apply_vertex_converter<vertex_converter_type>;
    using vertex_processor_type = new_geometry::vertex_processor<apply_vertex_converter_type>;

    auto const& geom = feature.get_geometry();
    new_geometry::geometry_types type = new_geometry::geometry_type(geom);

    if (type == new_geometry::geometry_types::Point
        || new_geometry::geometry_types::LineString
        || new_geometry::geometry_types::Polygon)
    {
        apply_vertex_converter_type apply(converter);
        mapnik::util::apply_visitor(vertex_processor_type(apply), geom);
    }
    else if (type != new_geometry::geometry_types::GeometryCollection) // multi geometries
    {

        marker_multi_policy_enum multi_policy = get<marker_multi_policy_enum, keys::markers_multipolicy>(sym, feature, vars);
        marker_placement_enum placement = get<marker_placement_enum, keys::markers_placement_type>(sym, feature, vars);

        if (placement == MARKER_POINT_PLACEMENT &&
            multi_policy == MARKER_WHOLE_MULTI)
        {
            new_geometry::point pt;
            if (new_geometry::centroid(geom, pt))
            {
                // unset any clipping since we're now dealing with a point
                converter.template unset<clip_poly_tag>();
                new_geometry::point_vertex_adapter va(pt);
                converter.apply(va);
            }
        }
        else if ((placement == MARKER_POINT_PLACEMENT || placement == MARKER_INTERIOR_PLACEMENT) &&
                 multi_policy == MARKER_LARGEST_MULTI)
        {
            // Only apply to path with largest envelope area
            // TODO: consider using true area for polygon types
            if (type == new_geometry::geometry_types::MultiPolygon)
            {
                new_geometry::multi_polygon multi_poly = mapnik::util::get<new_geometry::multi_polygon>(geom);
                double maxarea = 0;
                new_geometry::polygon const* largest = 0;
                for (new_geometry::polygon const& poly : multi_poly)
                {
                    box2d<double> bbox = new_geometry::envelope(poly);
                    new_geometry::polygon_vertex_adapter va(poly);
                    double area = bbox.width() * bbox.height();
                    if (area > maxarea)
                    {
                        maxarea = area;
                        largest = &poly;
                    }
                }
                if (largest)
                {
                    new_geometry::polygon_vertex_adapter va(*largest);
                    converter.apply(va);
                }
            }
        }
        else if (type == new_geometry::geometry_types::MultiPolygon)
        {
            if (multi_policy != MARKER_EACH_MULTI && placement != MARKER_POINT_PLACEMENT)
            {
                MAPNIK_LOG_WARN(marker_symbolizer) << "marker_multi_policy != 'each' has no effect with marker_placement != 'point'";
            }
            new_geometry::multi_polygon multi_poly = mapnik::util::get<new_geometry::multi_polygon>(geom);
            for (auto const& poly : multi_poly)
            {
                new_geometry::polygon_vertex_adapter va(poly);
                converter.apply(va);
            }
        }
    }
}

}

#endif //MAPNIK_MARKER_HELPERS_HPP
<|endoftext|>


<commit_before>/*
 * This file is part of otf2xx (https://github.com/tud-zih-energy/otf2xx)
 * otf2xx - A wrapper for the Open Trace Format 2 library
 *
 * Copyright (c) 2013-2016, Technische Universität Dresden, Germany
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * * Redistributions of source code must retain the above copyright notice, this
 *   list of conditions and the following disclaimer.
 *
 * * Redistributions in binary form must reproduce the above copyright notice,
 *   this list of conditions and the following disclaimer in the documentation
 *   and/or other materials provided with the distribution.
 *
 * * Neither the name of the copyright holder nor the names of its
 *   contributors may be used to endorse or promote products derived from
 *   this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

#ifndef INCLUDE_OTF2XX_CHRONO_CONVERT_HPP
#define INCLUDE_OTF2XX_CHRONO_CONVERT_HPP

#include <otf2xx/chrono/clock.hpp>
#include <otf2xx/chrono/ticks.hpp>
#include <otf2xx/chrono/time_point.hpp>

#include <otf2xx/definition/clock_properties.hpp>

#include <cassert>
#include <cmath>
#include <limits>

namespace otf2
{
namespace chrono
{

    /**
     * \brief class to convert between ticks and time points
     *
     * This class can convert between ticks and time points.
     * For this, it needs the number of ticks per second.
     *
     * \note The time epoch is assumed to be equal between the time point and
     *       time point represented with the number ticks given.
     */
    class convert
    {
        static_assert(clock::period::num == 1, "Don't mess around with chrono!");

    public:
        explicit convert(otf2::chrono::ticks ticks_per_second =
                             otf2::chrono::ticks(otf2::chrono::clock::period::den),
                         otf2::chrono::ticks offset = otf2::chrono::ticks(0))
        : offset_(offset.count()),
          factor_(static_cast<double>(clock::period::den) / ticks_per_second.count()),
          inverse_factor_(ticks_per_second.count() / static_cast<double>(clock::period::den))
        {
            // WARNING: Be careful, when changing clock::period::den.
            // You will have to think about every calculations twice, as there
            // might be narrowing and rounding anywhere.
            // We also assumed here, that we have nanoseconds or picoseconds resolution and the
            // input resolution is about nanoseconds or a few hundred
            // picoseconds.
            // These assumptions have to be double checked!

            assert(ticks_per_second.count() <= clock::period::den);
        }

        explicit convert(const otf2::definition::clock_properties& cp)
        : convert(cp.ticks_per_second(), cp.start_time())
        {
        }

        convert(const convert&) = default;
        convert& operator=(const convert&) = default;

        convert(convert&&) = default;
        convert& operator=(convert&&) = default;

        /**
         * \brief converts from ticks to time point
         *
         * \param[in] ticks since epoch
         * \return time_point with a duration equal to the passed time
         *         since the epoch.
         */
        otf2::chrono::time_point operator()(otf2::chrono::ticks ticks) const
        {
            // VTTI please remember that those two inputs are uint64_t and then look at the next
            // line
            assert(ticks.count() >= offset_);

            auto tp = ticks.count() - offset_;

            assert(tp < static_cast<uint64_t>(std::numeric_limits<int64_t>::max()) / factor_);

            return time_point(otf2::chrono::duration(static_cast<int64_t>(tp * factor_)));
        }

        /**
         * \brief converts from time points to ticks
         *
         * \param[in] t a time point
         * \return number ticks equal to passed time of the duration of the time
         *         point
         */
        otf2::chrono::ticks operator()(time_point t) const
        {
            auto tp = t.time_since_epoch().count();

            assert(tp <
                   static_cast<uint64_t>(std::numeric_limits<int64_t>::max()) / inverse_factor_);

            // Note 1: Using ceil here has its origins in the observation that casting from double
            // to int in the other conversion above leads to an implicit round down. Thus, we
            // counter that here with an explicit round up.
            // Note 2: Using an multiplication with the inverse yields a better performance. Though,
            // there might be cases, where a different sequence of multiplication or division
            // operations would result in lower rounding errors.
            auto tpi = static_cast<uint64_t>(std::ceil(tp * inverse_factor_));

            assert(tpi >= -offset_);

            return ticks(tpi + offset_);
        }

    private:
        uint64_t offset_;

        double factor_;
        double inverse_factor_;
    };

    /**
     * \brief converts from std::chrono::timepoint to otf2::chrono::time_point
     *
     * \param[in] tp the std::chrono time point
     * \return the same time point as otf2::chrono::time_point
     */
    template <typename Clock, typename Duration>
    otf2::chrono::time_point convert_time_point(std::chrono::time_point<Clock, Duration> tp)
    {
        return otf2::chrono::time_point(
            std::chrono::duration_cast<otf2::chrono::clock::duration>(tp.time_since_epoch()));
    }
} // namespace chrono
} // namespace otf2

#endif // INCLUDE_OTF2XX_CHRONO_CONVERT_HPP
<commit_msg>Fixes assertion in convert<commit_after>/*
 * This file is part of otf2xx (https://github.com/tud-zih-energy/otf2xx)
 * otf2xx - A wrapper for the Open Trace Format 2 library
 *
 * Copyright (c) 2013-2016, Technische Universität Dresden, Germany
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * * Redistributions of source code must retain the above copyright notice, this
 *   list of conditions and the following disclaimer.
 *
 * * Redistributions in binary form must reproduce the above copyright notice,
 *   this list of conditions and the following disclaimer in the documentation
 *   and/or other materials provided with the distribution.
 *
 * * Neither the name of the copyright holder nor the names of its
 *   contributors may be used to endorse or promote products derived from
 *   this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

#ifndef INCLUDE_OTF2XX_CHRONO_CONVERT_HPP
#define INCLUDE_OTF2XX_CHRONO_CONVERT_HPP

#include <otf2xx/chrono/clock.hpp>
#include <otf2xx/chrono/ticks.hpp>
#include <otf2xx/chrono/time_point.hpp>

#include <otf2xx/definition/clock_properties.hpp>

#include <cassert>
#include <cmath>
#include <limits>

namespace otf2
{
namespace chrono
{

    /**
     * \brief class to convert between ticks and time points
     *
     * This class can convert between ticks and time points.
     * For this, it needs the number of ticks per second.
     *
     * \note The time epoch is assumed to be equal between the time point and
     *       time point represented with the number ticks given.
     */
    class convert
    {
        static_assert(clock::period::num == 1, "Don't mess around with chrono!");

    public:
        explicit convert(otf2::chrono::ticks ticks_per_second =
                             otf2::chrono::ticks(otf2::chrono::clock::period::den),
                         otf2::chrono::ticks offset = otf2::chrono::ticks(0))
        : offset_(offset.count()),
          factor_(static_cast<double>(clock::period::den) / ticks_per_second.count()),
          inverse_factor_(ticks_per_second.count() / static_cast<double>(clock::period::den))
        {
            // WARNING: Be careful, when changing clock::period::den.
            // You will have to think about every calculations twice, as there
            // might be narrowing and rounding anywhere.
            // We also assumed here, that we have nanoseconds or picoseconds resolution and the
            // input resolution is about nanoseconds or a few hundred
            // picoseconds.
            // These assumptions have to be double checked!

            assert(ticks_per_second.count() <= clock::period::den);
        }

        explicit convert(const otf2::definition::clock_properties& cp)
        : convert(cp.ticks_per_second(), cp.start_time())
        {
        }

        convert(const convert&) = default;
        convert& operator=(const convert&) = default;

        convert(convert&&) = default;
        convert& operator=(convert&&) = default;

        /**
         * \brief converts from ticks to time point
         *
         * \param[in] ticks since epoch
         * \return time_point with a duration equal to the passed time
         *         since the epoch.
         */
        otf2::chrono::time_point operator()(otf2::chrono::ticks ticks) const
        {
            // VTTI please remember that those two inputs are uint64_t and then look at the next
            // line
            assert(ticks.count() >= offset_);

            auto tp = ticks.count() - offset_;

            assert(tp < static_cast<uint64_t>(std::numeric_limits<int64_t>::max()) / factor_);

            return time_point(otf2::chrono::duration(static_cast<int64_t>(tp * factor_)));
        }

        /**
         * \brief converts from time points to ticks
         *
         * \param[in] t a time point
         * \return number ticks equal to passed time of the duration of the time
         *         point
         */
        otf2::chrono::ticks operator()(time_point t) const
        {
            auto tp = t.time_since_epoch().count();

            assert(tp <
                   static_cast<uint64_t>(std::numeric_limits<int64_t>::max()) / inverse_factor_);

            // Note 1: Using ceil here has its origins in the observation that casting from double
            // to int in the other conversion above leads to an implicit round down. Thus, we
            // counter that here with an explicit round up.
            // Note 2: Using an multiplication with the inverse yields a better performance. Though,
            // there might be cases, where a different sequence of multiplication or division
            // operations would result in lower rounding errors.
            auto tpi = static_cast<uint64_t>(std::ceil(tp * inverse_factor_));

            assert(tpi <= std::numeric_limits<std::uint64_t>::max() - offset_);

            return ticks(tpi + offset_);
        }

    private:
        uint64_t offset_;

        double factor_;
        double inverse_factor_;
    };

    /**
     * \brief converts from std::chrono::timepoint to otf2::chrono::time_point
     *
     * \param[in] tp the std::chrono time point
     * \return the same time point as otf2::chrono::time_point
     */
    template <typename Clock, typename Duration>
    otf2::chrono::time_point convert_time_point(std::chrono::time_point<Clock, Duration> tp)
    {
        return otf2::chrono::time_point(
            std::chrono::duration_cast<otf2::chrono::clock::duration>(tp.time_since_epoch()));
    }
} // namespace chrono
} // namespace otf2

#endif // INCLUDE_OTF2XX_CHRONO_CONVERT_HPP
<|endoftext|>


<commit_before>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
**
** GNU Lesser General Public License Usage
**
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this file.
** Please review the following information to ensure the GNU Lesser General
** Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**************************************************************************/

#include "simulatorqtversion.h"
#include "qt4projectmanagerconstants.h"

#include <qtsupport/qtsupportconstants.h>
#include <proparser/profileevaluator.h>

#include <QCoreApplication>
#include <QDir>
#include <QFileInfoList>

using namespace Qt4ProjectManager;
using namespace Qt4ProjectManager::Internal;

SimulatorQtVersion::SimulatorQtVersion()
    : QtSupport::BaseQtVersion()
{

}

SimulatorQtVersion::SimulatorQtVersion(const Utils::FileName &path, bool isAutodetected, const QString &autodetectionSource)
    : QtSupport::BaseQtVersion(path, isAutodetected, autodetectionSource)
{

}

SimulatorQtVersion::~SimulatorQtVersion()
{

}

SimulatorQtVersion *SimulatorQtVersion::clone() const
{
    return new SimulatorQtVersion(*this);
}

QString SimulatorQtVersion::type() const
{
    return QLatin1String(QtSupport::Constants::SIMULATORQT);
}

QString SimulatorQtVersion::warningReason() const
{
    if (qtAbis().count() == 1 && qtAbis().first().isNull())
        return QCoreApplication::translate("QtVersion", "ABI detection failed: Make sure to use a matching tool chain when building.");
    if (qtVersion() >= QtSupport::QtVersionNumber(4, 7, 0) && qmlviewerCommand().isEmpty())
        return QCoreApplication::translate("QtVersion", "No qmlviewer installed.");
    return QString();
}

QList<ProjectExplorer::Abi> SimulatorQtVersion::detectQtAbis() const
{
    ensureMkSpecParsed();
    return qtAbisFromLibrary(qtCorePath(versionInfo(), qtVersionString()));
}

bool SimulatorQtVersion::supportsTargetId(const QString &id) const
{
    return id == QLatin1String(Constants::QT_SIMULATOR_TARGET_ID);
}

QSet<QString> SimulatorQtVersion::supportedTargetIds() const
{
    return QSet<QString>() << QLatin1String(Constants::QT_SIMULATOR_TARGET_ID);
}

QString SimulatorQtVersion::description() const
{
    return QCoreApplication::translate("QtVersion", "Qt Simulator", "Qt Version is meant for Qt Simulator");
}

Core::FeatureSet SimulatorQtVersion::availableFeatures() const
{
    Core::FeatureSet features = QtSupport::BaseQtVersion::availableFeatures();
    if (qtVersion() >= QtSupport::QtVersionNumber(4, 7, 4)) //no reliable test for components, yet.
           features |= Core::FeatureSet(QtSupport::Constants::FEATURE_QTQUICK_COMPONENTS_MEEGO)
                   | Core::FeatureSet(QtSupport::Constants::FEATURE_QTQUICK_COMPONENTS_SYMBIAN);

    return features;
}

bool SimulatorQtVersion::supportsPlatform(const QString &platformName) const
{
    return (platformName == QtSupport::Constants::SYMBIAN_PLATFORM
            || platformName == QtSupport::Constants::MEEGO_HARMATTAN_PLATFORM
            || platformName.isEmpty());
}
<commit_msg>Wizards: The simulator is for mobile development<commit_after>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
**
** GNU Lesser General Public License Usage
**
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this file.
** Please review the following information to ensure the GNU Lesser General
** Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**************************************************************************/

#include "simulatorqtversion.h"
#include "qt4projectmanagerconstants.h"

#include <qtsupport/qtsupportconstants.h>
#include <proparser/profileevaluator.h>

#include <QCoreApplication>
#include <QDir>
#include <QFileInfoList>

using namespace Qt4ProjectManager;
using namespace Qt4ProjectManager::Internal;

SimulatorQtVersion::SimulatorQtVersion()
    : QtSupport::BaseQtVersion()
{

}

SimulatorQtVersion::SimulatorQtVersion(const Utils::FileName &path, bool isAutodetected, const QString &autodetectionSource)
    : QtSupport::BaseQtVersion(path, isAutodetected, autodetectionSource)
{

}

SimulatorQtVersion::~SimulatorQtVersion()
{

}

SimulatorQtVersion *SimulatorQtVersion::clone() const
{
    return new SimulatorQtVersion(*this);
}

QString SimulatorQtVersion::type() const
{
    return QLatin1String(QtSupport::Constants::SIMULATORQT);
}

QString SimulatorQtVersion::warningReason() const
{
    if (qtAbis().count() == 1 && qtAbis().first().isNull())
        return QCoreApplication::translate("QtVersion", "ABI detection failed: Make sure to use a matching tool chain when building.");
    if (qtVersion() >= QtSupport::QtVersionNumber(4, 7, 0) && qmlviewerCommand().isEmpty())
        return QCoreApplication::translate("QtVersion", "No qmlviewer installed.");
    return QString();
}

QList<ProjectExplorer::Abi> SimulatorQtVersion::detectQtAbis() const
{
    ensureMkSpecParsed();
    return qtAbisFromLibrary(qtCorePath(versionInfo(), qtVersionString()));
}

bool SimulatorQtVersion::supportsTargetId(const QString &id) const
{
    return id == QLatin1String(Constants::QT_SIMULATOR_TARGET_ID);
}

QSet<QString> SimulatorQtVersion::supportedTargetIds() const
{
    return QSet<QString>() << QLatin1String(Constants::QT_SIMULATOR_TARGET_ID);
}

QString SimulatorQtVersion::description() const
{
    return QCoreApplication::translate("QtVersion", "Qt Simulator", "Qt Version is meant for Qt Simulator");
}

Core::FeatureSet SimulatorQtVersion::availableFeatures() const
{
    Core::FeatureSet features = QtSupport::BaseQtVersion::availableFeatures();
    if (qtVersion() >= QtSupport::QtVersionNumber(4, 7, 4)) //no reliable test for components, yet.
           features |= Core::FeatureSet(QtSupport::Constants::FEATURE_QTQUICK_COMPONENTS_MEEGO)
                   | Core::FeatureSet(QtSupport::Constants::FEATURE_QTQUICK_COMPONENTS_SYMBIAN);
    features |= Core::FeatureSet(QtSupport::Constants::FEATURE_MOBILE);

    return features;
}

bool SimulatorQtVersion::supportsPlatform(const QString &platformName) const
{
    return (platformName == QtSupport::Constants::SYMBIAN_PLATFORM
            || platformName == QtSupport::Constants::MEEGO_HARMATTAN_PLATFORM
            || platformName.isEmpty());
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: AccessibleViewForwarder.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: af $ $Date: 2002-06-03 15:06:58 $
 *
 *  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 _SVX_ACCESSIBILITY_ACCESSIBLE_VIEW_FORWARDER_HXX
#include "AccessibleViewForwarder.hxx"
#endif

#ifndef _SVDPNTV_HXX
#include <svx/svdpntv.hxx>
#endif
#ifndef _SV_OUTDEV_HXX
#include <vcl/outdev.hxx>
#endif

namespace accessibility {

/** For the time beeing, the implementation of this class will not use the
    member mrDevice.  Instead the device is retrieved from the view
    everytime it is used.  This is necessary because the device has to stay
    up-to-date with the current view and the class has to stay compatible.
    May change in the future.
*/

AccessibleViewForwarder::AccessibleViewForwarder (SdrPaintView* pView, USHORT nWindowId)
    : mpView (pView),
      mnWindowId (nWindowId),
      mrDevice (*pView->GetWin(nWindowId))
{
    OSL_ASSERT (mpView != NULL);
    // empty
}

AccessibleViewForwarder::AccessibleViewForwarder (SdrPaintView* pView, OutputDevice& rDevice)
    : mpView (pView),
      mnWindowId (0),
      mrDevice (rDevice)
{
    // Search the output device to determine its id.
    for (USHORT i=0; i<mpView->GetWinCount(); i++)
        if (mpView->GetWin(i) == &rDevice)
        {
            mnWindowId = i;
            break;
        }
}

AccessibleViewForwarder::~AccessibleViewForwarder (void)
{
    // empty
}

void AccessibleViewForwarder::SetView (SdrPaintView* pView)
{
    mpView = pView;
    OSL_ASSERT (mpView != NULL);
}

sal_Bool AccessibleViewForwarder::IsValid (void) const
{
    return sal_True;
}

Rectangle AccessibleViewForwarder::GetVisibleArea (void) const
{
    return mpView->GetVisibleArea (mnWindowId);
}

Point AccessibleViewForwarder::LogicToPixel (const Point& rPoint) const
{
    OSL_ASSERT (mpView != NULL);
    OutputDevice* pDevice = mpView->GetWin(mnWindowId);
    Rectangle aBBox (static_cast<Window*>(pDevice)->GetWindowExtentsRelative(NULL));
    return pDevice->LogicToPixel (rPoint) + aBBox.TopLeft();
}

Size AccessibleViewForwarder::LogicToPixel (const Size& rSize) const
{
    OSL_ASSERT (mpView != NULL);
    OutputDevice* pDevice = mpView->GetWin(mnWindowId);
    return pDevice->LogicToPixel (rSize);
}

Point AccessibleViewForwarder::PixelToLogic (const Point& rPoint) const
{
    OSL_ASSERT (mpView != NULL);
    OutputDevice* pDevice = mpView->GetWin(mnWindowId);
    return pDevice->PixelToLogic (rPoint);
}

Size AccessibleViewForwarder::PixelToLogic (const Size& rSize) const
{
    OSL_ASSERT (mpView != NULL);
    OutputDevice* pDevice = mpView->GetWin(mnWindowId);
    return pDevice->PixelToLogic (rSize);
}

} // end of namespace accessibility
<commit_msg>#100559# Transformation of point coordinates into internal coordinates now takes care of absolute pixel coordinates.<commit_after>/*************************************************************************
 *
 *  $RCSfile: AccessibleViewForwarder.cxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: af $ $Date: 2002-06-28 08:44:42 $
 *
 *  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 _SVX_ACCESSIBILITY_ACCESSIBLE_VIEW_FORWARDER_HXX
#include "AccessibleViewForwarder.hxx"
#endif

#ifndef _SVDPNTV_HXX
#include <svx/svdpntv.hxx>
#endif
#ifndef _SV_OUTDEV_HXX
#include <vcl/outdev.hxx>
#endif

namespace accessibility {

/** For the time beeing, the implementation of this class will not use the
    member mrDevice.  Instead the device is retrieved from the view
    everytime it is used.  This is necessary because the device has to stay
    up-to-date with the current view and the class has to stay compatible.
    May change in the future.
*/

AccessibleViewForwarder::AccessibleViewForwarder (SdrPaintView* pView, USHORT nWindowId)
    : mpView (pView),
      mnWindowId (nWindowId),
      mrDevice (*pView->GetWin(nWindowId))
{
    OSL_ASSERT (mpView != NULL);
    // empty
}

AccessibleViewForwarder::AccessibleViewForwarder (SdrPaintView* pView, OutputDevice& rDevice)
    : mpView (pView),
      mnWindowId (0),
      mrDevice (rDevice)
{
    // Search the output device to determine its id.
    for (USHORT i=0; i<mpView->GetWinCount(); i++)
        if (mpView->GetWin(i) == &rDevice)
        {
            mnWindowId = i;
            break;
        }
}

AccessibleViewForwarder::~AccessibleViewForwarder (void)
{
    // empty
}

void AccessibleViewForwarder::SetView (SdrPaintView* pView)
{
    mpView = pView;
    OSL_ASSERT (mpView != NULL);
}

sal_Bool AccessibleViewForwarder::IsValid (void) const
{
    return sal_True;
}

Rectangle AccessibleViewForwarder::GetVisibleArea (void) const
{
    return mpView->GetVisibleArea (mnWindowId);
}

/** Tansform the given point into pixel coordiantes.  After the the pixel
    coordiantes of the window origin are added to make the point coordinates
    absolute.
*/
Point AccessibleViewForwarder::LogicToPixel (const Point& rPoint) const
{
    OSL_ASSERT (mpView != NULL);
    OutputDevice* pDevice = mpView->GetWin(mnWindowId);
    Rectangle aBBox (static_cast<Window*>(pDevice)->GetWindowExtentsRelative(NULL));
    return pDevice->LogicToPixel (rPoint) + aBBox.TopLeft();
}

Size AccessibleViewForwarder::LogicToPixel (const Size& rSize) const
{
    OSL_ASSERT (mpView != NULL);
    OutputDevice* pDevice = mpView->GetWin(mnWindowId);
    return pDevice->LogicToPixel (rSize);
}

/** First subtract the window origin to make the point coordinates relative
    to the window and then transform them into internal coordinates.
*/
Point AccessibleViewForwarder::PixelToLogic (const Point& rPoint) const
{
    OSL_ASSERT (mpView != NULL);
    OutputDevice* pDevice = mpView->GetWin(mnWindowId);
    Rectangle aBBox (static_cast<Window*>(pDevice)->GetWindowExtentsRelative(NULL));
    return pDevice->PixelToLogic (rPoint - aBBox.TopLeft());
}

Size AccessibleViewForwarder::PixelToLogic (const Size& rSize) const
{
    OSL_ASSERT (mpView != NULL);
    OutputDevice* pDevice = mpView->GetWin(mnWindowId);
    return pDevice->PixelToLogic (rSize);
}

} // end of namespace accessibility
<|endoftext|>


<commit_before>/**
 * @file clitest.cpp
 * @brief  Brief description of file.
 *
 */

#include <pthread.h>
#include <string>
#include <map>
#include <queue>

#include "tcp.h"
#include "messages.h"
#include "data.h"
#include "time.h"

namespace diamondapparatus {

/// this is the database the client writes stuff to from its thread
static std::map<std::string,Topic *> topics;

/// primary mutex
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
/// condition used in get-wait
static pthread_cond_t getcond = PTHREAD_COND_INITIALIZER;

static bool running=false;

inline void lock(const char *n){
    dprintf("+++Attemping to lock: %s\n",n);
    pthread_mutex_lock(&mutex);
}
inline void unlock(const char *n){
    dprintf("---Unlocking: %s\n",n);
    pthread_mutex_unlock(&mutex);
}

// the states the client can be in
enum ClientState {
    ST_IDLE,
    ST_AWAITACK
};
class MyClient : public TCPClient {
    ClientState state;
public:
    MyClient(const char *host,int port) : TCPClient(host,port){
        state = ST_IDLE;
    }

    void setState(ClientState s){
        dprintf("====> state = %d\n",s);
        state = s;
    }

    // the topic I'm waiting for in get(), if any.
    const char *waittopic;

    void notify(const char *d){
        dprintf("notify at %p\n",d);
        const char *name = Topic::getNameFromMsg(d);
        if(topics.find(std::string(name)) == topics.end()){
            fprintf(stderr,"Topic %s not in client set, ignoring\n",name);
            return;
        }
        Topic *t = topics[name];
        t->fromMessage(d);
        t->state =Topic::Changed;
        t->timeLastSet = Time::now();

        // if we were waiting for this, signal.
        if(waittopic && !strcmp(name,waittopic)){
            pthread_cond_signal(&getcond);
        }
    }

    virtual void process(uint32_t packetsize,void *packet){
        lock("msgrecv");
        char *p = (char *)packet;
        SCAck *ack;
        uint32_t type = ntohl(*(uint32_t *)p);
        dprintf("Packet type %d at %p\n",type,packet);

        if(type == SC_KILLCLIENT){
            fprintf(stderr,"force exit\n");
            running=false;
        }

        switch(state){
        case ST_IDLE:
            if(type == SC_NOTIFY){
                notify(p);
            }
            break;
        case ST_AWAITACK:
            ack = (SCAck *)p;
            if(type != SC_ACK)
                throw "unexpected packet in awaiting ack";
            else if(ack->code){
                dprintf("Ack code %d: %s\n",ntohs(ack->code),ack->msg);
                throw "bad code from ack";
            } else
                dprintf("Acknowledged\n");
            setState(ST_IDLE);
            break;
        }
        unlock("msgrecv");
    }

    void subscribe(const char *name){
        lock("subscribe");
        StrMsg p;
        p.type = htonl(CS_SUBSCRIBE);
        strcpy(p.msg,name);
        request(&p,sizeof(StrMsg));
        //TODO - ADD TIMEOUT
        setState(ST_AWAITACK);
        unlock("subscribe");
    }

    void publish(const char *name,Topic& d){
        lock("publish");
        int size;
        const char *p = d.toMessage(&size,CS_PUBLISH,name);
        request(p,size);
        //TODO - ADD TIMEOUT
        setState(ST_AWAITACK);
        free((void *)p);
        unlock("publish");
    }

    void simpleMsg(int msg){
        lock("smlmsg");
        NoDataMsg p;
        p.type = htonl(msg);
        request(&p,sizeof(NoDataMsg));
        unlock("smlmsg");
    }

    bool isIdle(){
        lock("isidle");
        bool e = (state == ST_IDLE);
        dprintf("Is idle? state=%d, so %s\n",state,e?"true":"false");
        unlock("isidle");
        return e;
    }

};

/*
 *
 *
 * Threading stuff
 *
 *
 */

static pthread_t thread;

static MyClient *client;

static void *threadfunc(void *parameter){
    running = true;
    while(running){
        // deal with requests
        if(!client->update())break;
    }
    dprintf("LOOP EXITING\n");
    delete client;
    running = false;
};
static void waitForIdle(){
    while(running && !client->isIdle()){
        usleep(100000);
    }
    dprintf("Wait done, running=%s, isidle=%s\n",running?"T":"F",
           client->isIdle()?"T":"F");
}

/*
 *
 *
 * Interface code
 *
 *
 */

void init(){
    // get environment data or defaults
    const char *hn = getenv("DIAMOND_HOST");
    char *hostname = NULL;
    if(hn)hostname = strdup(hn);
    const char *pr = getenv("DIAMOND_PORT");
    int port = pr?atoi(pr):DEFAULTPORT;
    client = new MyClient(hostname?hostname:"localhost",port);
    pthread_create(&thread,NULL,threadfunc,NULL);
    if(hostname)free(hostname);
    while(!running){} // wait for thread
}

void destroy(){
    running=false;// assume atomic :)
    pthread_cond_destroy(&getcond);
    pthread_mutex_destroy(&mutex);
}

void subscribe(const char *n){
    if(!running)throw DiamondException("not connected");
    Topic *t = new Topic();
    topics[n]=t;
    client->subscribe(n);
    waitForIdle(); // wait for the ack
}

void publish(const char *name,Topic& t){
    if(!running)throw DiamondException("not connected");
    client->publish(name,t);
    waitForIdle(); // wait for the ack
}

void killServer(){
    if(!running)throw DiamondException("not connected");
    client->simpleMsg(CS_KILLSERVER);
}
void clearServer(){
    if(!running)throw DiamondException("not connected");
    client->simpleMsg(CS_CLEARSERVER);
}

bool isRunning(){
    return running;
}

Topic get(const char *n,int wait){
    Topic rv;
    if(!running){
        rv.state = Topic::NotConnected;
        return rv;
    }

    if(topics.find(n) == topics.end()){
        // topic not subscribed to
        rv.state = Topic::NotFound;
        return rv;
    }

    // we are connected and subscribed to this topic

    lock("gettopic");
    Topic *t = topics[n];
    if(t->state == Topic::NoData){
        // if WaitAny, wait for data
        if(wait == GetWaitAny){
            dprintf("No data present : entering wait\n");
            while(t->state == Topic::NoData){
                client->waittopic = n;
                // stalls until new data arrives, but unlocks mutex
                pthread_cond_wait(&getcond,&mutex);
                dprintf("Data apparently arrived!\n");
            }
            // should now have data and mutex locked again
        } else {
            rv.state = Topic::NotFound;
            return rv;
        }
    }
    if(wait == GetWaitNew){
        while(t->state != Topic::Changed){
            client->waittopic = n;
            // stalls until new data arrives, but unlocks mutex
            pthread_cond_wait(&getcond,&mutex);
        }
        // should now have data and mutex locked again
    }
    rv = *t;
    t->state = Topic::Unchanged;
    unlock("gettopic");
    return rv;
}

}
<commit_msg>waitcond cleared after data waited for received.<commit_after>/**
 * @file clitest.cpp
 * @brief  Brief description of file.
 *
 */

#include <pthread.h>
#include <string>
#include <map>
#include <queue>

#include "tcp.h"
#include "messages.h"
#include "data.h"
#include "time.h"

namespace diamondapparatus {

/// this is the database the client writes stuff to from its thread
static std::map<std::string,Topic *> topics;

/// primary mutex
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
/// condition used in get-wait
static pthread_cond_t getcond = PTHREAD_COND_INITIALIZER;

static bool running=false;

inline void lock(const char *n){
    dprintf("+++Attemping to lock: %s\n",n);
    pthread_mutex_lock(&mutex);
}
inline void unlock(const char *n){
    dprintf("---Unlocking: %s\n",n);
    pthread_mutex_unlock(&mutex);
}

// the states the client can be in
enum ClientState {
    ST_IDLE,
    ST_AWAITACK
};
class MyClient : public TCPClient {
    ClientState state;
public:
    MyClient(const char *host,int port) : TCPClient(host,port){
        state = ST_IDLE;
    }

    void setState(ClientState s){
        dprintf("====> state = %d\n",s);
        state = s;
    }

    // the topic I'm waiting for in get(), if any.
    const char *waittopic;

    void notify(const char *d){
        dprintf("notify at %p\n",d);
        const char *name = Topic::getNameFromMsg(d);
        if(topics.find(std::string(name)) == topics.end()){
            fprintf(stderr,"Topic %s not in client set, ignoring\n",name);
            return;
        }
        Topic *t = topics[name];
        t->fromMessage(d);
        t->state =Topic::Changed;
        t->timeLastSet = Time::now();

        // if we were waiting for this, signal.
        if(waittopic && !strcmp(name,waittopic)){
            pthread_cond_signal(&getcond);
            waittopic=NULL; // and zero the wait topic.
        }
    }

    virtual void process(uint32_t packetsize,void *packet){
        lock("msgrecv");
        char *p = (char *)packet;
        SCAck *ack;
        uint32_t type = ntohl(*(uint32_t *)p);
        dprintf("Packet type %d at %p\n",type,packet);

        if(type == SC_KILLCLIENT){
            fprintf(stderr,"force exit\n");
            running=false;
        }

        switch(state){
        case ST_IDLE:
            if(type == SC_NOTIFY){
                notify(p);
            }
            break;
        case ST_AWAITACK:
            ack = (SCAck *)p;
            if(type != SC_ACK)
                throw "unexpected packet in awaiting ack";
            else if(ack->code){
                dprintf("Ack code %d: %s\n",ntohs(ack->code),ack->msg);
                throw "bad code from ack";
            } else
                dprintf("Acknowledged\n");
            setState(ST_IDLE);
            break;
        }
        unlock("msgrecv");
    }

    void subscribe(const char *name){
        lock("subscribe");
        StrMsg p;
        p.type = htonl(CS_SUBSCRIBE);
        strcpy(p.msg,name);
        request(&p,sizeof(StrMsg));
        //TODO - ADD TIMEOUT
        setState(ST_AWAITACK);
        unlock("subscribe");
    }

    void publish(const char *name,Topic& d){
        lock("publish");
        int size;
        const char *p = d.toMessage(&size,CS_PUBLISH,name);
        request(p,size);
        //TODO - ADD TIMEOUT
        setState(ST_AWAITACK);
        free((void *)p);
        unlock("publish");
    }

    void simpleMsg(int msg){
        lock("smlmsg");
        NoDataMsg p;
        p.type = htonl(msg);
        request(&p,sizeof(NoDataMsg));
        unlock("smlmsg");
    }

    bool isIdle(){
        lock("isidle");
        bool e = (state == ST_IDLE);
        dprintf("Is idle? state=%d, so %s\n",state,e?"true":"false");
        unlock("isidle");
        return e;
    }

};

/*
 *
 *
 * Threading stuff
 *
 *
 */

static pthread_t thread;

static MyClient *client;

static void *threadfunc(void *parameter){
    running = true;
    while(running){
        // deal with requests
        if(!client->update())break;
    }
    dprintf("LOOP EXITING\n");
    delete client;
    running = false;
};
static void waitForIdle(){
    while(running && !client->isIdle()){
        usleep(100000);
    }
    dprintf("Wait done, running=%s, isidle=%s\n",running?"T":"F",
           client->isIdle()?"T":"F");
}

/*
 *
 *
 * Interface code
 *
 *
 */

void init(){
    // get environment data or defaults
    const char *hn = getenv("DIAMOND_HOST");
    char *hostname = NULL;
    if(hn)hostname = strdup(hn);
    const char *pr = getenv("DIAMOND_PORT");
    int port = pr?atoi(pr):DEFAULTPORT;
    client = new MyClient(hostname?hostname:"localhost",port);
    pthread_create(&thread,NULL,threadfunc,NULL);
    if(hostname)free(hostname);
    while(!running){} // wait for thread
}

void destroy(){
    running=false;// assume atomic :)
    pthread_cond_destroy(&getcond);
    pthread_mutex_destroy(&mutex);
}

void subscribe(const char *n){
    if(!running)throw DiamondException("not connected");
    Topic *t = new Topic();
    topics[n]=t;
    client->subscribe(n);
    waitForIdle(); // wait for the ack
}

void publish(const char *name,Topic& t){
    if(!running)throw DiamondException("not connected");
    client->publish(name,t);
    waitForIdle(); // wait for the ack
}

void killServer(){
    if(!running)throw DiamondException("not connected");
    client->simpleMsg(CS_KILLSERVER);
}
void clearServer(){
    if(!running)throw DiamondException("not connected");
    client->simpleMsg(CS_CLEARSERVER);
}

bool isRunning(){
    return running;
}

Topic get(const char *n,int wait){
    Topic rv;
    if(!running){
        rv.state = Topic::NotConnected;
        return rv;
    }

    if(topics.find(n) == topics.end()){
        // topic not subscribed to
        rv.state = Topic::NotFound;
        return rv;
    }

    // we are connected and subscribed to this topic

    lock("gettopic");
    Topic *t = topics[n];
    if(t->state == Topic::NoData){
        // if WaitAny, wait for data
        if(wait == GetWaitAny){
            dprintf("No data present : entering wait\n");
            while(t->state == Topic::NoData){
                client->waittopic = n;
                // stalls until new data arrives, but unlocks mutex
                pthread_cond_wait(&getcond,&mutex);
                dprintf("Data apparently arrived!\n");
            }
            // should now have data and mutex locked again
        } else {
            rv.state = Topic::NotFound;
            return rv;
        }
    }
    if(wait == GetWaitNew){
        while(t->state != Topic::Changed){
            client->waittopic = n;
            // stalls until new data arrives, but unlocks mutex
            pthread_cond_wait(&getcond,&mutex);
        }
        // should now have data and mutex locked again
    }
    rv = *t;
    t->state = Topic::Unchanged;
    unlock("gettopic");
    return rv;
}

}
<|endoftext|>


<commit_before>#include "Model/Classes/NMR_KeyStoreResourceData.h"
#include "Common/NMR_Exception.h"
#include <memory>

namespace NMR {
	CKeyStoreResourceData::CKeyStoreResourceData(std::string const & path) {
		m_sPath = path;
		m_EncryptionAlgorithm = eKeyStoreEncryptAlgorithm::Aes256Gcm;
	}

	CKeyStoreResourceData::CKeyStoreResourceData(std::string const & path, eKeyStoreEncryptAlgorithm const & ea, nfBool const & compression)
	{
		m_sPath = path;
		m_EncryptionAlgorithm = ea;
		m_bCompression = compression;
	}

	PKeyStoreDecryptRight CKeyStoreResourceData::addDecryptRight(PKeyStoreDecryptRight decryptRight)
	{
		if (!decryptRight->getConsumer().get())
			throw CNMRException(NMR_ERROR_INVALIDPARAM);
		if (m_ConsumerDecryptRight.find(decryptRight->getConsumer()->getConsumerID()) != m_ConsumerDecryptRight.end()) {
			throw CNMRException(NMR_ERROR_DUPLICATE_KEYSTORECONSUMER);
		}
		m_DecryptRights.push_back(decryptRight);
		m_ConsumerDecryptRight[decryptRight->getConsumer()->getConsumerID()] = decryptRight;
		return decryptRight;
	}

	PKeyStoreDecryptRight CKeyStoreResourceData::addDecryptRight(NMR::PKeyStoreConsumer const& consumer, eKeyStoreEncryptAlgorithm const& encryptAlgorithm) {
		NMR::CIPHERVALUE value = { 0, 0, 0 };
		return this->addDecryptRight(consumer, encryptAlgorithm, value);
	}

	PKeyStoreDecryptRight CKeyStoreResourceData::addDecryptRight(NMR::PKeyStoreConsumer const& consumer, eKeyStoreEncryptAlgorithm const& encryptAlgorithm, NMR::CIPHERVALUE const& cipherValue)
	{
		if (!consumer.get())
			throw CNMRException(NMR_ERROR_INVALIDPARAM);
		if (m_ConsumerDecryptRight.find(consumer->getConsumerID()) != m_ConsumerDecryptRight.end()) {
			throw CNMRException(NMR_ERROR_DUPLICATE_KEYSTORECONSUMER);
		}

		PKeyStoreDecryptRight decryptRight = std::make_shared<CKeyStoreDecryptRight>(consumer, encryptAlgorithm, cipherValue);
		m_DecryptRights.push_back(decryptRight);
		m_ConsumerDecryptRight[consumer->getConsumerID()] = decryptRight;
		return decryptRight;
	}

	nfUint32 CKeyStoreResourceData::getDecryptRightCount()
	{
		return (uint32_t)m_DecryptRights.size();
	}

	PKeyStoreDecryptRight CKeyStoreResourceData::getDecryptRight(nfUint32 index) const
	{
		return m_DecryptRights[index];
	}

	PKeyStoreDecryptRight CKeyStoreResourceData::findDecryptRightByConsumer(NMR::PKeyStoreConsumer const& consumer)
	{
		if (!consumer.get())
			throw CNMRException(NMR_ERROR_INVALIDPARAM);
		return m_ConsumerDecryptRight[consumer->getConsumerID()];
	}

	void CKeyStoreResourceData::removeDecryptRight(NMR::PKeyStoreConsumer const& consumer)
	{
		if (!consumer.get())
			throw CNMRException(NMR_ERROR_INVALIDPARAM);
		size_t n = m_ConsumerDecryptRight.erase(consumer->getConsumerID());
		if (n > 0) {
			for (auto it = m_DecryptRights.begin(); it != m_DecryptRights.end(); it++) {
				if ((*it)->getConsumer()->getConsumerID() == consumer->getConsumerID()) {
					m_DecryptRights.erase(it);
				}
			}
		}
	}

	eKeyStoreEncryptAlgorithm CKeyStoreResourceData::getEncryptionAlgorithm() const
	{
		return m_EncryptionAlgorithm;
	}

	nfBool CKeyStoreResourceData::getCompression() const
	{
		return m_bCompression;
	}
	NMR::PPackageModelPath CKeyStoreResourceData::getPath() const
	{
		NMR::CResourceHandler * pResourceHandler = new NMR::CResourceHandler();
		return pResourceHandler->makePackageModelPath(m_sPath);
	}

	nfBool CKeyStoreResourceData::empty() const {
		return m_DecryptRights.empty();

	CIPHERVALUE CKeyStoreResourceData::getCipherValue() const {
		return m_sCipherValue;
	}

	void CKeyStoreResourceData::setCipherValue(CIPHERVALUE const & cv) {
		m_sCipherValue = cv;
		m_bOpen = true;
	}

	bool CKeyStoreResourceData::isOpen() const {
		return m_bOpen;
	}

}
<commit_msg>SW3DRAM-975 adding missing token<commit_after>#include "Model/Classes/NMR_KeyStoreResourceData.h"
#include "Common/NMR_Exception.h"
#include <memory>

namespace NMR {
	CKeyStoreResourceData::CKeyStoreResourceData(std::string const & path) {
		m_sPath = path;
		m_EncryptionAlgorithm = eKeyStoreEncryptAlgorithm::Aes256Gcm;
	}

	CKeyStoreResourceData::CKeyStoreResourceData(std::string const & path, eKeyStoreEncryptAlgorithm const & ea, nfBool const & compression)
	{
		m_sPath = path;
		m_EncryptionAlgorithm = ea;
		m_bCompression = compression;
	}

	PKeyStoreDecryptRight CKeyStoreResourceData::addDecryptRight(PKeyStoreDecryptRight decryptRight)
	{
		if (!decryptRight->getConsumer().get())
			throw CNMRException(NMR_ERROR_INVALIDPARAM);
		if (m_ConsumerDecryptRight.find(decryptRight->getConsumer()->getConsumerID()) != m_ConsumerDecryptRight.end()) {
			throw CNMRException(NMR_ERROR_DUPLICATE_KEYSTORECONSUMER);
		}
		m_DecryptRights.push_back(decryptRight);
		m_ConsumerDecryptRight[decryptRight->getConsumer()->getConsumerID()] = decryptRight;
		return decryptRight;
	}

	PKeyStoreDecryptRight CKeyStoreResourceData::addDecryptRight(NMR::PKeyStoreConsumer const& consumer, eKeyStoreEncryptAlgorithm const& encryptAlgorithm) {
		NMR::CIPHERVALUE value = { 0, 0, 0 };
		return this->addDecryptRight(consumer, encryptAlgorithm, value);
	}

	PKeyStoreDecryptRight CKeyStoreResourceData::addDecryptRight(NMR::PKeyStoreConsumer const& consumer, eKeyStoreEncryptAlgorithm const& encryptAlgorithm, NMR::CIPHERVALUE const& cipherValue)
	{
		if (!consumer.get())
			throw CNMRException(NMR_ERROR_INVALIDPARAM);
		if (m_ConsumerDecryptRight.find(consumer->getConsumerID()) != m_ConsumerDecryptRight.end()) {
			throw CNMRException(NMR_ERROR_DUPLICATE_KEYSTORECONSUMER);
		}

		PKeyStoreDecryptRight decryptRight = std::make_shared<CKeyStoreDecryptRight>(consumer, encryptAlgorithm, cipherValue);
		m_DecryptRights.push_back(decryptRight);
		m_ConsumerDecryptRight[consumer->getConsumerID()] = decryptRight;
		return decryptRight;
	}

	nfUint32 CKeyStoreResourceData::getDecryptRightCount()
	{
		return (uint32_t)m_DecryptRights.size();
	}

	PKeyStoreDecryptRight CKeyStoreResourceData::getDecryptRight(nfUint32 index) const
	{
		return m_DecryptRights[index];
	}

	PKeyStoreDecryptRight CKeyStoreResourceData::findDecryptRightByConsumer(NMR::PKeyStoreConsumer const& consumer)
	{
		if (!consumer.get())
			throw CNMRException(NMR_ERROR_INVALIDPARAM);
		return m_ConsumerDecryptRight[consumer->getConsumerID()];
	}

	void CKeyStoreResourceData::removeDecryptRight(NMR::PKeyStoreConsumer const& consumer)
	{
		if (!consumer.get())
			throw CNMRException(NMR_ERROR_INVALIDPARAM);
		size_t n = m_ConsumerDecryptRight.erase(consumer->getConsumerID());
		if (n > 0) {
			for (auto it = m_DecryptRights.begin(); it != m_DecryptRights.end(); it++) {
				if ((*it)->getConsumer()->getConsumerID() == consumer->getConsumerID()) {
					m_DecryptRights.erase(it);
				}
			}
		}
	}

	eKeyStoreEncryptAlgorithm CKeyStoreResourceData::getEncryptionAlgorithm() const
	{
		return m_EncryptionAlgorithm;
	}

	nfBool CKeyStoreResourceData::getCompression() const
	{
		return m_bCompression;
	}
	NMR::PPackageModelPath CKeyStoreResourceData::getPath() const
	{
		NMR::CResourceHandler * pResourceHandler = new NMR::CResourceHandler();
		return pResourceHandler->makePackageModelPath(m_sPath);
	}

	nfBool CKeyStoreResourceData::empty() const {
		return m_DecryptRights.empty();
	}

	CIPHERVALUE CKeyStoreResourceData::getCipherValue() const {
		return m_sCipherValue;
	}

	void CKeyStoreResourceData::setCipherValue(CIPHERVALUE const & cv) {
		m_sCipherValue = cv;
		m_bOpen = true;
	}

	bool CKeyStoreResourceData::isOpen() const {
		return m_bOpen;
	}

}
<|endoftext|>


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

#include "paddle/fluid/memory/allocation/buffered_allocator.h"
#include <algorithm>
#include <limits>
#include <utility>

namespace paddle {
namespace memory {
namespace allocation {

BufferedAllocator::BufferedAllocator(std::unique_ptr<Allocator>&& allocator) {
  underlying_allocator_.reset(
      dynamic_cast<UnmanagedAllocator*>(allocator.release()));
  PADDLE_ENFORCE_NOT_NULL(
      underlying_allocator_,
      "Underlying allocator of BufferedAllocator must be unmanaged");
  if (underlying_allocator_->IsAllocThreadSafe()) {
    mtx_.reset(new std::mutex());
  }
}

BufferedAllocator::~BufferedAllocator() { FreeCache(-1UL); }

std::unique_ptr<Allocation> BufferedAllocator::Allocate(size_t size,
                                                        Allocator::Attr attr) {
  std::unique_ptr<Allocation> result;
  {
    platform::LockGuardPtr<std::mutex> guard(mtx_);
    auto it = allocations_.lower_bound(size);
    if (it != allocations_.end() && it->first < size * 2) {
      result = std::move(it->second);
      allocations_.erase(it);
    }
  }

  if (result) {
    return result;
  }

  try {
    return underlying_allocator_->Allocate(size, attr);
  } catch (BadAlloc&) {
    FreeCache(size);
    return underlying_allocator_->Allocate(size, attr);
  }
}

void BufferedAllocator::FreeCache(size_t size) {
  platform::LockGuardPtr<std::mutex> guard(mtx_);
  if (UNLIKELY(size == 0)) return;
  size_t cur = 0;
  while (!allocations_.empty()) {  // free the largest
    auto it = --allocations_.end();
    cur += it->second->size();
    underlying_allocator_->FreeUniquePtr(std::move(it->second));
    allocations_.erase(it);
    if (cur >= size) return;
  }
}

void BufferedAllocator::FreeUniquePtr(std::unique_ptr<Allocation> allocation) {
  platform::LockGuardPtr<std::mutex> guard(mtx_);
  allocations_.emplace(allocation->size(), std::move(allocation));
}

bool BufferedAllocator::IsAllocThreadSafe() const {
  return this->underlying_allocator_->IsAllocThreadSafe();
}

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

#include "paddle/fluid/memory/allocation/buffered_allocator.h"
#include <algorithm>
#include <limits>
#include <utility>

namespace paddle {
namespace memory {
namespace allocation {

BufferedAllocator::BufferedAllocator(std::unique_ptr<Allocator>&& allocator) {
  underlying_allocator_.reset(
      dynamic_cast<UnmanagedAllocator*>(allocator.release()));
  PADDLE_ENFORCE_NOT_NULL(
      underlying_allocator_,
      "Underlying allocator of BufferedAllocator must be unmanaged");
  if (underlying_allocator_->IsAllocThreadSafe()) {
    mtx_.reset(new std::mutex());
  }
}

BufferedAllocator::~BufferedAllocator() { FreeCache(-1UL); }

std::unique_ptr<Allocation> BufferedAllocator::Allocate(size_t size,
                                                        Allocator::Attr attr) {
  {
    platform::LockGuardPtr<std::mutex> guard(mtx_);
    auto it = allocations_.lower_bound(size);
    if (it != allocations_.end() && it->first < size * 2) {
      std::unique_ptr<Allocation> result(std::move(it->second));
      allocations_.erase(it);
      return result;
    }
  }

  try {
    return underlying_allocator_->Allocate(size, attr);
  } catch (BadAlloc&) {
    FreeCache(size);
    return underlying_allocator_->Allocate(size, attr);
  }
}

void BufferedAllocator::FreeCache(size_t size) {
  platform::LockGuardPtr<std::mutex> guard(mtx_);
  if (UNLIKELY(size == 0)) return;
  size_t cur = 0;
  while (!allocations_.empty()) {  // free the largest
    auto it = --allocations_.end();
    cur += it->second->size();
    underlying_allocator_->FreeUniquePtr(std::move(it->second));
    allocations_.erase(it);
    if (cur >= size) return;
  }
}

void BufferedAllocator::FreeUniquePtr(std::unique_ptr<Allocation> allocation) {
  platform::LockGuardPtr<std::mutex> guard(mtx_);
  allocations_.emplace(allocation->size(), std::move(allocation));
}

bool BufferedAllocator::IsAllocThreadSafe() const {
  return this->underlying_allocator_->IsAllocThreadSafe();
}

}  // namespace allocation
}  // namespace memory
}  // namespace paddle
<|endoftext|>