<commit_before>#include "Tiles.h"

namespace sfc {

    Tile::Tile(const Image& image, sfc::Mode mode, unsigned bpp, bool no_flip) {
        if (image.indexed_data().empty()) throw std::runtime_error("Can't create tile without indexed data");

        _mode = mode;
        _bpp = bpp;
        _width = image.width();
        _height = image.height();
        _palette = image.palette();

        index_t mask = sfc::bitmask_at_bpp(_bpp);
        for (index_t ip : image.indexed_data()) _data.push_back(ip & mask);

        if (!no_flip) {
            _mirrors.push_back(sfc::mirror(_data, _width, true,  false));
            _mirrors.push_back(sfc::mirror(_data, _width, false, true));
            _mirrors.push_back(sfc::mirror(_data, _width, true,  true));
        }
    }

    Tile::Tile(const std::vector<uint8_t>& native_data, sfc::Mode mode, unsigned bpp, bool no_flip, unsigned width, unsigned height) {
        _mode = mode;
        _bpp = bpp;
        _width = width;
        _height = height;
        _data = sfc::unpack_native_tile(native_data, mode, bpp, width, height);

        _palette.resize(sfc::palette_size_at_bpp(bpp));
        channel_t add = 0x100 / _palette.size();
        for (unsigned i = 0; i < _palette.size(); ++i) {
            channel_t value = add * i;
            _palette[i] = (rgba_t)(0xff000000 + value + (value << 8) + (value << 16));
        }

        if (!no_flip) {
            _mirrors.push_back(sfc::mirror(_data, _width, true,  false));
            _mirrors.push_back(sfc::mirror(_data, _width, false, true));
            _mirrors.push_back(sfc::mirror(_data, _width, true,  true));
        }
    }

    Tile::Tile(const std::vector<Tile>& metatile, bool no_flip, unsigned width, unsigned height) {
        if (metatile.empty()) return;

        _mode = metatile[0]._mode;
        _bpp = metatile[0]._bpp;
        _palette = metatile[0]._palette;
        _width = width;
        _height = height;
        _data.resize(width * height);

        const unsigned metatile_dim = metatile[0]._width;
        const unsigned metatiles_h = width / metatile_dim;
        const unsigned metatiles_v = height / metatile_dim;

        int metatile_index = 0;
        for (int my = 0; my < metatiles_v; ++my) {
            for (int mx = 0; mx < metatiles_h; ++mx) {
                for (int blit_y = 0; blit_y < metatile_dim; ++blit_y) {
                    std::memcpy(&_data[((blit_y + (my * metatile_dim)) * width) + (mx * metatile_dim)], &metatile[metatile_index]._data[blit_y * metatile_dim], metatile_dim);
                }
                ++metatile_index;
            }
        }

        if (!no_flip) {
            _mirrors.push_back(sfc::mirror(_data, _width, true,  false));
            _mirrors.push_back(sfc::mirror(_data, _width, false, true));
            _mirrors.push_back(sfc::mirror(_data, _width, true,  true));
        }
    }

    bool Tile::is_h_flipped(const Tile& other) const {
        if (other._data == _data) return false;
        if (_mirrors.empty()) throw std::runtime_error("Programmer error");
        if (other._data == _mirrors[0] || other._data == _mirrors[2]) return true;
        return false;
    }

    bool Tile::is_v_flipped(const Tile& other) const {
        if (other._data == _data) return false;
        if (_mirrors.empty()) throw std::runtime_error("Programmer error");
        if (other._data == _mirrors[1] || other._data == _mirrors[2]) return true;
        return false;
    }

    bool Tile::operator==(const Tile& other) const {
        if (other._data == _data) return true;
        if (!_mirrors.empty()) {
            for (auto& m : _mirrors) if (other._data == m) return true;
        }
        return false;
    }

    Tile Tile::crop(unsigned x, unsigned y, unsigned crop_width, unsigned crop_height) const {
        Tile t;
        t._mode = _mode;
        t._bpp = _bpp;
        t._width = crop_width;
        t._height = crop_height;
        t._palette = _palette;
        t._data.resize(crop_width * crop_height);

        if (x > _width || y > _height) {
            // no blit
        } else {
            unsigned blit_width = (x + crop_width > _width) ? _width - x : crop_width;
            unsigned blit_height = (y + crop_height > _height) ? _height - y : crop_height;
            for (int iy = 0; iy < blit_height; ++iy) std::memcpy(&t._data[iy * t._width], &_data[(x) + ((iy + y) * _width)], blit_width);
        }

        if (_mirrors.size()) {
            t._mirrors.push_back(sfc::mirror(t._data, t._width, true,  false));
            t._mirrors.push_back(sfc::mirror(t._data, t._width, false, true));
            t._mirrors.push_back(sfc::mirror(t._data, t._width, true,  true));
        }

        return t;
    }

    std::vector<Tile> Tile::crops(unsigned tile_width, unsigned tile_height) const {
        std::vector<Tile> tv;
        unsigned x = 0; unsigned y = 0;
        while (y < _height) {
            while (x < _width) {
                tv.push_back(crop(x, y, tile_width, tile_height));
                x += tile_width;
            }
            x = 0;
            y += tile_height;
        }
        return tv;
    }

    std::vector<uint8_t> Tile::native_data() const {
        return sfc::pack_native_tile(_data, _mode, _bpp, _width, _height);
    }

    std::vector<rgba_t> Tile::rgba_data() const {
        std::vector<rgba_t> v(_data.size());
        for (unsigned i = 0; i < _data.size(); ++i) v[i] = (_data[i] == 0) ? transparent_color : _palette[_data[i]];
        return v;
    }

    Tileset::Tileset(const std::vector<uint8_t> native_data, sfc::Mode mode, unsigned bpp, unsigned tile_width, unsigned tile_height, bool no_flip) {
        _mode = mode;
        _bpp = bpp;
        _tile_width = tile_width;
        _tile_height = tile_height;
        _no_flip = no_flip;

        if (_mode == Mode::snes || _mode == Mode::snes_mode7) {
            unsigned bytes_per_tile = bpp << 3;
            if (native_data.size() % bytes_per_tile != 0) throw std::runtime_error("Tile data can't be deserialized (size doesn't match bpp setting)");
            unsigned tiles = (unsigned)native_data.size() / bytes_per_tile;

            for (unsigned i = 0; i < tiles; ++i) {
                _tiles.push_back(Tile(std::vector<uint8_t>(&native_data[i * bytes_per_tile], &native_data[(i + 1) * bytes_per_tile]), mode, bpp, no_flip, 8, 8));
            }
        }

        if (_tile_width != 8 || _tile_height != 8) _tiles = remap_tiles_for_input(_tiles, _mode);
    }

    void Tileset::add(const sfc::Image& image, const Palette* palette) {
        Tile tile;

        if (_no_remap) {
            if (is_full()) throw std::runtime_error("Tileset reached maximum size");
            tile = Tile(image, _mode, _bpp, _no_flip);
        } else {
            if (palette == nullptr) throw std::runtime_error("Can't remap tile without palette");
            Image remapped_image = Image(image, palette->subpalette_matching(image));
            tile = Tile(remapped_image, _mode, _bpp, _no_flip);
       }

        if (_no_discard) {
            _tiles.push_back(tile);
        } else {
            if (std::find(_tiles.begin(), _tiles.end(), tile) == _tiles.end()) {
                _tiles.push_back(tile);
            } else {
                ++discarded_tiles;
            }
        }
    }

    int Tileset::index_of(const sfc::Tile& tile) const {
        auto index = std::find(_tiles.begin(), _tiles.end(), tile);
        if (index != _tiles.end()) {
            return (int)std::distance(_tiles.begin(), index);
        } else {
            return -1;
        }
    }

    // save native data
    void Tileset::save(const std::string& path) const {
        sfc::write_file(path, native_data());
    }

    std::vector<uint8_t> Tileset::native_data() const {
        std::vector<Tile> tv;
        if (_tile_width != 8 || _tile_height != 8) {
            tv = remap_tiles_for_output(_tiles, _mode);
        } else {
            tv = _tiles;
        }

        std::vector<uint8_t> data;
        for (const auto& t : tv) {
            auto nt = t.native_data();
            data.insert(data.end(), nt.begin(), nt.end());
        }
        return data;
    }

    std::vector<Tile> Tileset::remap_tiles_for_output(const std::vector<Tile>& tiles, Mode mode) const {
        std::vector<Tile> tv;

        if (mode == Mode::snes) {
            if (!(_tile_width == 8 || _tile_width == 16 || _tile_height == 8 || _tile_height == 16))
                throw std::runtime_error("Programmer error (remap_tiles_for_output Mode::snes with not 16x16, 16x8 or 8x16)");

            const unsigned cells_per_tile_h = _tile_width / 8;
            const unsigned cells_per_tile_v = _tile_height / 8;
            const unsigned cells_per_row = 16;
            const unsigned tiles_per_row = cells_per_row / cells_per_tile_h;
            const unsigned cell_rows = div_ceil((int)_tiles.size(), tiles_per_row) * cells_per_tile_v;

            tv.resize(cells_per_row * cell_rows);

            for (int i = 0; i < _tiles.size(); ++i) {
                unsigned base_pos = (((i / tiles_per_row) * cells_per_tile_v) * cells_per_row) + ((i % tiles_per_row) << (cells_per_tile_h - 1));
                auto ct = _tiles[i].crops(8, 8);
                for (int cy = 0; cy < cells_per_tile_v; ++cy) {
                    for (int cx = 0; cx < cells_per_tile_h; ++cx) {
                        tv[base_pos + (cy * cells_per_row) + cx] = ct[(cy * cells_per_tile_v) + cx];
                    }
                }
            }

        } else if (mode == Mode::snes_mode7) {
            // We shouldn't arrive here
            throw std::runtime_error("Programmer error");
        }

        return tv;
    }

    std::vector<Tile> Tileset::remap_tiles_for_input(const std::vector<Tile>& tiles, Mode mode) const {
        std::vector<Tile> tv;

        if (mode == Mode::snes) {
            if (!(_tile_width == 8 || _tile_width == 16 || _tile_height == 8 || _tile_height == 16))
                throw std::runtime_error("Programmer error (remap_tiles_for_input Mode::snes with not 16x16, 16x8 or 8x16)");

            const unsigned cells_per_tile_h = _tile_width / 8;
            const unsigned cells_per_tile_v = _tile_height / 8;

            for (int i = 0; i < _tiles.size(); ++i) {
                std::vector<Tile> metatile;
                for (int yo = 0; yo < cells_per_tile_v; ++yo) {
                    for (int xo = 0; xo < cells_per_tile_h; ++xo) {
                        if ((i + (yo * 16 ) + xo) < tiles.size()) metatile.push_back(tiles[i + (yo * 16 ) + xo]);
                    }
                }
                if (metatile.size() == cells_per_tile_h * cells_per_tile_v) tv.push_back(Tile(metatile, _no_flip, _tile_width, _tile_height));
            }

        } else if (mode == Mode::snes_mode7) {
            // We shouldn't arrive here
            throw std::runtime_error("Programmer error");
        }

        return tv;
    }

}
<commit_msg>sfc_tiles: max tile option is honored in remap mode<commit_after>#include "Tiles.h"

namespace sfc {

    Tile::Tile(const Image& image, sfc::Mode mode, unsigned bpp, bool no_flip) {
        if (image.indexed_data().empty()) throw std::runtime_error("Can't create tile without indexed data");

        _mode = mode;
        _bpp = bpp;
        _width = image.width();
        _height = image.height();
        _palette = image.palette();

        index_t mask = sfc::bitmask_at_bpp(_bpp);
        for (index_t ip : image.indexed_data()) _data.push_back(ip & mask);

        if (!no_flip) {
            _mirrors.push_back(sfc::mirror(_data, _width, true,  false));
            _mirrors.push_back(sfc::mirror(_data, _width, false, true));
            _mirrors.push_back(sfc::mirror(_data, _width, true,  true));
        }
    }

    Tile::Tile(const std::vector<uint8_t>& native_data, sfc::Mode mode, unsigned bpp, bool no_flip, unsigned width, unsigned height) {
        _mode = mode;
        _bpp = bpp;
        _width = width;
        _height = height;
        _data = sfc::unpack_native_tile(native_data, mode, bpp, width, height);

        _palette.resize(sfc::palette_size_at_bpp(bpp));
        channel_t add = 0x100 / _palette.size();
        for (unsigned i = 0; i < _palette.size(); ++i) {
            channel_t value = add * i;
            _palette[i] = (rgba_t)(0xff000000 + value + (value << 8) + (value << 16));
        }

        if (!no_flip) {
            _mirrors.push_back(sfc::mirror(_data, _width, true,  false));
            _mirrors.push_back(sfc::mirror(_data, _width, false, true));
            _mirrors.push_back(sfc::mirror(_data, _width, true,  true));
        }
    }

    Tile::Tile(const std::vector<Tile>& metatile, bool no_flip, unsigned width, unsigned height) {
        if (metatile.empty()) return;

        _mode = metatile[0]._mode;
        _bpp = metatile[0]._bpp;
        _palette = metatile[0]._palette;
        _width = width;
        _height = height;
        _data.resize(width * height);

        const unsigned metatile_dim = metatile[0]._width;
        const unsigned metatiles_h = width / metatile_dim;
        const unsigned metatiles_v = height / metatile_dim;

        int metatile_index = 0;
        for (int my = 0; my < metatiles_v; ++my) {
            for (int mx = 0; mx < metatiles_h; ++mx) {
                for (int blit_y = 0; blit_y < metatile_dim; ++blit_y) {
                    std::memcpy(&_data[((blit_y + (my * metatile_dim)) * width) + (mx * metatile_dim)], &metatile[metatile_index]._data[blit_y * metatile_dim], metatile_dim);
                }
                ++metatile_index;
            }
        }

        if (!no_flip) {
            _mirrors.push_back(sfc::mirror(_data, _width, true,  false));
            _mirrors.push_back(sfc::mirror(_data, _width, false, true));
            _mirrors.push_back(sfc::mirror(_data, _width, true,  true));
        }
    }

    bool Tile::is_h_flipped(const Tile& other) const {
        if (other._data == _data) return false;
        if (_mirrors.empty()) throw std::runtime_error("Programmer error");
        if (other._data == _mirrors[0] || other._data == _mirrors[2]) return true;
        return false;
    }

    bool Tile::is_v_flipped(const Tile& other) const {
        if (other._data == _data) return false;
        if (_mirrors.empty()) throw std::runtime_error("Programmer error");
        if (other._data == _mirrors[1] || other._data == _mirrors[2]) return true;
        return false;
    }

    bool Tile::operator==(const Tile& other) const {
        if (other._data == _data) return true;
        if (!_mirrors.empty()) {
            for (auto& m : _mirrors) if (other._data == m) return true;
        }
        return false;
    }

    Tile Tile::crop(unsigned x, unsigned y, unsigned crop_width, unsigned crop_height) const {
        Tile t;
        t._mode = _mode;
        t._bpp = _bpp;
        t._width = crop_width;
        t._height = crop_height;
        t._palette = _palette;
        t._data.resize(crop_width * crop_height);

        if (x > _width || y > _height) {
            // no blit
        } else {
            unsigned blit_width = (x + crop_width > _width) ? _width - x : crop_width;
            unsigned blit_height = (y + crop_height > _height) ? _height - y : crop_height;
            for (int iy = 0; iy < blit_height; ++iy) std::memcpy(&t._data[iy * t._width], &_data[(x) + ((iy + y) * _width)], blit_width);
        }

        if (_mirrors.size()) {
            t._mirrors.push_back(sfc::mirror(t._data, t._width, true,  false));
            t._mirrors.push_back(sfc::mirror(t._data, t._width, false, true));
            t._mirrors.push_back(sfc::mirror(t._data, t._width, true,  true));
        }

        return t;
    }

    std::vector<Tile> Tile::crops(unsigned tile_width, unsigned tile_height) const {
        std::vector<Tile> tv;
        unsigned x = 0; unsigned y = 0;
        while (y < _height) {
            while (x < _width) {
                tv.push_back(crop(x, y, tile_width, tile_height));
                x += tile_width;
            }
            x = 0;
            y += tile_height;
        }
        return tv;
    }

    std::vector<uint8_t> Tile::native_data() const {
        return sfc::pack_native_tile(_data, _mode, _bpp, _width, _height);
    }

    std::vector<rgba_t> Tile::rgba_data() const {
        std::vector<rgba_t> v(_data.size());
        for (unsigned i = 0; i < _data.size(); ++i) v[i] = (_data[i] == 0) ? transparent_color : _palette[_data[i]];
        return v;
    }

    Tileset::Tileset(const std::vector<uint8_t> native_data, sfc::Mode mode, unsigned bpp, unsigned tile_width, unsigned tile_height, bool no_flip) {
        _mode = mode;
        _bpp = bpp;
        _tile_width = tile_width;
        _tile_height = tile_height;
        _no_flip = no_flip;

        if (_mode == Mode::snes || _mode == Mode::snes_mode7) {
            unsigned bytes_per_tile = bpp << 3;
            if (native_data.size() % bytes_per_tile != 0) throw std::runtime_error("Tile data can't be deserialized (size doesn't match bpp setting)");
            unsigned tiles = (unsigned)native_data.size() / bytes_per_tile;

            for (unsigned i = 0; i < tiles; ++i) {
                _tiles.push_back(Tile(std::vector<uint8_t>(&native_data[i * bytes_per_tile], &native_data[(i + 1) * bytes_per_tile]), mode, bpp, no_flip, 8, 8));
            }
        }

        if (_tile_width != 8 || _tile_height != 8) _tiles = remap_tiles_for_input(_tiles, _mode);
    }

    void Tileset::add(const sfc::Image& image, const Palette* palette) {
        Tile tile;

        if (_no_remap) {
            tile = Tile(image, _mode, _bpp, _no_flip);
        } else {
            if (palette == nullptr) throw std::runtime_error("Can't remap tile without palette");
            Image remapped_image = Image(image, palette->subpalette_matching(image));
            tile = Tile(remapped_image, _mode, _bpp, _no_flip);
       }

        if (_no_discard) {
            if (is_full()) throw std::runtime_error("Tileset reached maximum size");
            _tiles.push_back(tile);
        } else {
            if (std::find(_tiles.begin(), _tiles.end(), tile) == _tiles.end()) {
                if (is_full()) throw std::runtime_error("Tileset reached maximum size");
                _tiles.push_back(tile);
            } else {
                ++discarded_tiles;
            }
        }
    }

    int Tileset::index_of(const sfc::Tile& tile) const {
        auto index = std::find(_tiles.begin(), _tiles.end(), tile);
        if (index != _tiles.end()) {
            return (int)std::distance(_tiles.begin(), index);
        } else {
            return -1;
        }
    }

    // save native data
    void Tileset::save(const std::string& path) const {
        sfc::write_file(path, native_data());
    }

    std::vector<uint8_t> Tileset::native_data() const {
        std::vector<Tile> tv;
        if (_tile_width != 8 || _tile_height != 8) {
            tv = remap_tiles_for_output(_tiles, _mode);
        } else {
            tv = _tiles;
        }

        std::vector<uint8_t> data;
        for (const auto& t : tv) {
            auto nt = t.native_data();
            data.insert(data.end(), nt.begin(), nt.end());
        }
        return data;
    }

    std::vector<Tile> Tileset::remap_tiles_for_output(const std::vector<Tile>& tiles, Mode mode) const {
        std::vector<Tile> tv;

        if (mode == Mode::snes) {
            if (!(_tile_width == 8 || _tile_width == 16 || _tile_height == 8 || _tile_height == 16))
                throw std::runtime_error("Programmer error (remap_tiles_for_output Mode::snes with not 16x16, 16x8 or 8x16)");

            const unsigned cells_per_tile_h = _tile_width / 8;
            const unsigned cells_per_tile_v = _tile_height / 8;
            const unsigned cells_per_row = 16;
            const unsigned tiles_per_row = cells_per_row / cells_per_tile_h;
            const unsigned cell_rows = div_ceil((int)_tiles.size(), tiles_per_row) * cells_per_tile_v;

            tv.resize(cells_per_row * cell_rows);

            for (int i = 0; i < _tiles.size(); ++i) {
                unsigned base_pos = (((i / tiles_per_row) * cells_per_tile_v) * cells_per_row) + ((i % tiles_per_row) << (cells_per_tile_h - 1));
                auto ct = _tiles[i].crops(8, 8);
                for (int cy = 0; cy < cells_per_tile_v; ++cy) {
                    for (int cx = 0; cx < cells_per_tile_h; ++cx) {
                        tv[base_pos + (cy * cells_per_row) + cx] = ct[(cy * cells_per_tile_v) + cx];
                    }
                }
            }

        } else if (mode == Mode::snes_mode7) {
            // We shouldn't arrive here
            throw std::runtime_error("Programmer error");
        }

        return tv;
    }

    std::vector<Tile> Tileset::remap_tiles_for_input(const std::vector<Tile>& tiles, Mode mode) const {
        std::vector<Tile> tv;

        if (mode == Mode::snes) {
            if (!(_tile_width == 8 || _tile_width == 16 || _tile_height == 8 || _tile_height == 16))
                throw std::runtime_error("Programmer error (remap_tiles_for_input Mode::snes with not 16x16, 16x8 or 8x16)");

            const unsigned cells_per_tile_h = _tile_width / 8;
            const unsigned cells_per_tile_v = _tile_height / 8;

            for (int i = 0; i < _tiles.size(); ++i) {
                std::vector<Tile> metatile;
                for (int yo = 0; yo < cells_per_tile_v; ++yo) {
                    for (int xo = 0; xo < cells_per_tile_h; ++xo) {
                        if ((i + (yo * 16 ) + xo) < tiles.size()) metatile.push_back(tiles[i + (yo * 16 ) + xo]);
                    }
                }
                if (metatile.size() == cells_per_tile_h * cells_per_tile_v) tv.push_back(Tile(metatile, _no_flip, _tile_width, _tile_height));
            }

        } else if (mode == Mode::snes_mode7) {
            // We shouldn't arrive here
            throw std::runtime_error("Programmer error");
        }

        return tv;
    }

}
<|endoftext|>


<commit_before>#include <boost/type_traits/make_signed.hpp>
#include <boost/mpl/eval_if.hpp>

#include <limits>
#include <cmath>

namespace utils { namespace verbose_output {
    namespace {
        // identity map for signed types
        template<typename T>
        struct signed_type_identity
        {
            typedef T type;
        };

        // map from unsigned type to signed analog
        template<typename T>
        struct unsigned_type_map
        {
            typename typedef boost::make_signed<T>::type type;
        };
    }

    _tmpl_head_T_
    typename _cls_name_::result_type _cls_name_::operator()(typename _cls_name_::args<0>::type x)
    {
        using boost::make_signed;
        using boost::mpl::eval_if_c;

        typedef eval_if_c<std::numeric_limits<T>::is_signed, signed_type_identity<T>,
            unsigned_type_map<T> >::type type;
        type const value = *boost::any_cast<T>(&x);

        type const state = this->state();
        type const stride = this->stride();
        if (std::abs(state + stride) <= std::abs(value)) {
            this->state(static_cast<T>(state + stride));

            return true;
        }

        return false;
    }
}}
<commit_msg>numerals_rule.inl: refactoring<commit_after>#include <boost/type_traits/make_signed.hpp>
#include <boost/mpl/eval_if.hpp>

#include <limits>
#include <cmath>

namespace utils { namespace verbose_output {
    namespace {
        // identity map for signed types
        template<typename T>
        struct signed_type_identity
        {
            typedef T type;
        };

        // map from unsigned type to signed analog
        template<typename T>
        struct unsigned_type_map
        {
            typename typedef boost::make_signed<T>::type type;
        };
    }

    _tmpl_head_T_
    typename _cls_name_::result_type _cls_name_::operator()(typename _cls_name_::args<0>::type x)
    {
        using boost::make_signed;
        using boost::mpl::eval_if_c;

        typedef eval_if_c<std::numeric_limits<T>::is_signed, signed_type_identity<T>,
            unsigned_type_map<T> >::type type;
        type const value = *boost::any_cast<T>(&x);

        type const pt = this->state() + this->stride();
        if (std::abs(pt) <= std::abs(value)) {
            this->state(static_cast<T>(pt));

            return true;
        }

        return false;
    }
}}
<|endoftext|>


<commit_before>// Copyright (c) 2019 ASMlover. 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 ofconditions 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 materialsprovided with the
//    distribution.
//
// 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.
#pragma once

#include "helper.hh"

namespace wrencc {

template <typename T>
class DoubleList final : private UnCopyable {
  template <typename _Tp> struct ListNode {
    ListNode<_Tp>* prev;
    ListNode<_Tp>* next;
    _Tp value;
  };
  using NodeType = ListNode<T>;

  sz_t size_{};
  NodeType* head_{};

  inline void initialize_head_aux() noexcept {
    head_ = SimpleAlloc<NodeType>::allocate(1);
    head_->prev = head_;
    head_->next = head_;
  }

  inline void destroy_head_aux() noexcept {
    SimpleAlloc<NodeType>::deallocate(head_);
  }
public:
  DoubleList() noexcept { initialize_head_aux(); }
  ~DoubleList() noexcept {
    // clear
    destroy_head_aux();
  }

  inline bool empty() const noexcept { return size_ == 0; }
  inline sz_t size() const noexcept { return size_; }
  inline T& get_head() noexcept { return head_->next->value; }
  inline const T& get_head() const noexcept { return head_->next->value; }
  inline T& get_tail() noexcept { return head_->prev->value; }
  inline const T& get_tail() const noexcept { return head_->prev->value; }

  void clear() {
  }

  void append(const T& x);
  void append(T&& x);
  template <typename... Args> void append(Args&&... args);

  T pop_head();
  T pop_tail();

  template <typename Function> inline void for_each(Function&& fn) noexcept;
};

}
<commit_msg>:construction: chore(list): updated the double linked-list<commit_after>// Copyright (c) 2019 ASMlover. 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 ofconditions 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 materialsprovided with the
//    distribution.
//
// 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.
#pragma once

#include "helper.hh"

namespace wrencc {

template <typename T>
class DoubleList final : private UnCopyable {
  template <typename _Tp> struct ListNode {
    ListNode<_Tp>* prev;
    ListNode<_Tp>* next;
    _Tp value;
  };
  using NodeType = ListNode<T>;

  sz_t size_{};
  NodeType* head_{};

  inline void initialize_head() noexcept {
    head_ = SimpleAlloc<NodeType>::allocate();
    head_->prev = head_;
    head_->next = head_;
  }

  inline void destroy_head() noexcept {
    SimpleAlloc<NodeType>::deallocate(head_);
  }

  NodeType* create_aux(const T& value) {
    NodeType* node = SimpleAlloc<NodeType>::allocate();
    try {
      construct(&node->value, value);
      node->prev = node->prev = nullptr;
    }
    catch (...) {
    }
    return node;
  }

  NodeType* create_aux(T&& value) {
    NodeType* node = SimpleAlloc<NodeType>::allocate();
    try {
      construct(&node->value, std::move(value));
      node->prev = node->prev = nullptr;
    }
    catch (...) {
    }
    return node;
  }

  template <typename... Args> NodeType* create_aux(Args&&... args) {
    NodeType* node = SimpleAlloc<NodeType>::allocate();
    try {
      construct(&node->value, std::forward<Args>(args)...);
      node->prev = node->prev = nullptr;
    }
    catch (...) {
    }
    return node;
  }

  void destroy_aux(NodeType* node) {
    destroy(&node->value);
    SimpleAlloc<NodeType>::deallocate(node);
  }

  inline void insert_aux(NodeType* pos, NodeType* new_node) noexcept {
    new_node->next = pos;
    new_node->prev = pos->prev;
    pos->prev->next = new_node;
    pos->prev = new_node;
    ++size_;
  }
public:
  DoubleList() noexcept { initialize_head(); }
  ~DoubleList() noexcept {
    clear();
    destroy_head();
  }

  inline bool empty() const noexcept { return head_->next == head_; }
  inline sz_t size() const noexcept { return size_; }
  inline T& get_head() noexcept { return head_->next->value; }
  inline const T& get_head() const noexcept { return head_->next->value; }
  inline T& get_tail() noexcept { return head_->prev->value; }
  inline const T& get_tail() const noexcept { return head_->prev->value; }

  void clear() {
    NodeType* cur = head_->next;
    while (cur != head_) {
      NodeType* node = cur;
      cur = cur->next;
      destroy(&node->value);
      SimpleAlloc<NodeType>::deallocate(node);
    }
    head_->prev = head_->next = head_;
    size_ = 0;
  }

  void append(const T& x) { insert_aux(head_, create_aux(x)); }
  void append(T&& x) { insert_aux(head_, create_aux(std::move(x))); }

  template <typename... Args> void append(Args&&... args) {
    insert_aux(head_, create_aux(std::forward<Args>(args)...));
  }

  T pop_head();
  T pop_tail();

  template <typename Function> inline void for_each(Function&& fn) noexcept {
    for (auto* n = head_->next; n != head_; n = n->next)
      fn(n->value);
  }
};

}
<|endoftext|>


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

#ifndef SD_FRAMEWORK_SLIDE_SORTER_MODULE_HXX
#define SD_FRAMEWORK_SLIDE_SORTER_MODULE_HXX

#include "ResourceManager.hxx"

#include <com/sun/star/drawing/framework/XControllerManager.hpp>
#include <com/sun/star/drawing/framework/XTabBar.hpp>

namespace css = ::com::sun::star;

namespace sd { namespace framework {

/** This module is responsible for showing the slide sorter bar and the the
    slide sorter view in the center pane.
*/
class SlideSorterModule
    : public ResourceManager
{
public:
    SlideSorterModule (
        const css::uno::Reference<css::frame::XController>& rxController,
        const ::rtl::OUString& rsLeftPaneURL);
    virtual ~SlideSorterModule (void);

    // XConfigurationChangeListener

    virtual void SAL_CALL notifyConfigurationChange (
        const css::drawing::framework::ConfigurationChangeEvent& rEvent)
        throw (css::uno::RuntimeException);

private:
    css::uno::Reference<css::drawing::framework::XResourceId> mxViewTabBarId;
    css::uno::Reference<css::drawing::framework::XControllerManager> mxControllerManager;

    void UpdateViewTabBar (
        const css::uno::Reference<css::drawing::framework::XTabBar>& rxViewTabBar);
};

} } // end of namespace sd::framework

#endif
<commit_msg>INTEGRATION: CWS changefileheader (1.2.234); FILE MERGED 2008/04/01 12:38:49 thb 1.2.234.2: #i85898# Stripping all external header guards 2008/03/31 13:58:02 rt 1.2.234.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: SlideSorterModule.hxx,v $
 * $Revision: 1.4 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef SD_FRAMEWORK_SLIDE_SORTER_MODULE_HXX
#define SD_FRAMEWORK_SLIDE_SORTER_MODULE_HXX

#include "ResourceManager.hxx"

#include <com/sun/star/drawing/framework/XControllerManager.hpp>
#include <com/sun/star/drawing/framework/XTabBar.hpp>

namespace css = ::com::sun::star;

namespace sd { namespace framework {

/** This module is responsible for showing the slide sorter bar and the the
    slide sorter view in the center pane.
*/
class SlideSorterModule
    : public ResourceManager
{
public:
    SlideSorterModule (
        const css::uno::Reference<css::frame::XController>& rxController,
        const ::rtl::OUString& rsLeftPaneURL);
    virtual ~SlideSorterModule (void);

    // XConfigurationChangeListener

    virtual void SAL_CALL notifyConfigurationChange (
        const css::drawing::framework::ConfigurationChangeEvent& rEvent)
        throw (css::uno::RuntimeException);

private:
    css::uno::Reference<css::drawing::framework::XResourceId> mxViewTabBarId;
    css::uno::Reference<css::drawing::framework::XControllerManager> mxControllerManager;

    void UpdateViewTabBar (
        const css::uno::Reference<css::drawing::framework::XTabBar>& rxViewTabBar);
};

} } // end of namespace sd::framework

#endif
<|endoftext|>


<commit_before>/* * This file is part of meego-keyboard *
 *
 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
 * All rights reserved.
 * Contact: Nokia Corporation (directui@nokia.com)
 *
 * If you have questions regarding the use of this file, please contact
 * Nokia at directui@nokia.com.
 *
 * 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
 * and appearing in the file LICENSE.LGPL included in the packaging
 * of this file.
 */

#include "mvirtualkeyboardstyle.h"
#include "notification.h"

#include <QDebug>
#include <QFontMetrics>
#include <QPainter>

#include <MSceneManager>
#include <float.h>

namespace
{
    const int Margin = 10;           // Margin of the box surrounding text
    const int FrameCount = 15;       // How many frames to use in fading
    const int FadeTime = 300;        // Duration of fading in/out animation
    const int HoldTime = 700;        // Time to hold the widget in visible state
};

Notification::Notification(const MVirtualKeyboardStyleContainer *style, QGraphicsWidget *parent)
    : MWidget(parent),
      styleContainer(style)
{
    // Notification sets its own absolute opacity
    setFlag(ItemIgnoresParentOpacity, true);
    setZValue(FLT_MAX);

    visibilityTimer.setInterval(HoldTime);
    visibilityTimer.setSingleShot(true);

    fadeTimeLine.setFrameRange(0, FrameCount);
    fadeTimeLine.setDuration(FadeTime);

    connect(&fadeTimeLine, SIGNAL(frameChanged(int)),
            this, SLOT(updateOpacity(int)));
    connect(&fadeTimeLine, SIGNAL(finished()),
            this, SLOT(fadingFinished()));

    connect(&visibilityTimer, SIGNAL(timeout()),
            this, SLOT(fadeOut()));

    getStyleValues();
    hide();
}

Notification::~Notification()
{
}

void
Notification::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
{
    painter->setFont(font);
    painter->setPen(border);
    painter->setBrush(background);
    painter->setRenderHint(QPainter::Antialiasing);
    painter->drawRoundedRect(rect(), 10, 10);
    painter->setPen(textColor);
    painter->drawText(rect(), Qt::AlignCenter, message);
}

void
Notification::displayText(const QString &message, const QRectF &area)
{
    if (this->message != message) {
        this->message = message;
        resetGeometry(area);
    }

    fadeIn();
}

void
Notification::updateOpacity(int op)
{
    setOpacity(qreal(op) / qreal(FrameCount) * opacity);
    update();
}

void
Notification::fadingFinished()
{
    if (fadeTimeLine.direction() == QTimeLine::Forward) {
        // Notification is now shown an will be visible
        // as long as visibility timer runs.
        visibilityTimer.start();
    } else {
        // We have faded out
        hide();
    }
}

void Notification::fadeOut()
{
    fadeTimeLine.setDirection(QTimeLine::Backward);
    fadeTimeLine.start();
}

void Notification::getStyleValues()
{
    font = style()->notificationFont();
    border = style()->notificationBorderColor();
    background = style()->notificationBackgroundColor();
    textColor = style()->notificationTextColor();
    opacity = style()->notificationOpacity();
}

void Notification::fadeIn()
{
    // Handle fadeIn request in four different states:
    // not visible, fading in, visible, fading out

    if (fadeTimeLine.state() == QTimeLine::NotRunning) {
        if (isVisible()) {
            // Already visible so just prolong the visibility time
            // by restarting timer.
            visibilityTimer.start();
        } else {
            // The common case, begin fading in from hidden state.
            setOpacity(0.0);
            show();

            // Begin fading in
            fadeTimeLine.setDirection(QTimeLine::Forward);
            fadeTimeLine.start();
        }
    } else {
        // Fading in progress

        if (fadeTimeLine.direction() == QTimeLine::Forward) {
            // New fade in requested while fading in.
            // Do nothing, i.e. continue ongoing fading.
        } else {
            fadeTimeLine.toggleDirection();
        }
    }
}

void Notification::resetGeometry(const QRectF &area)
{
    const QFontMetrics fm(font);
    const int width = fm.width(message) + Margin * 2;
    const int height = fm.height() + Margin * 2;

    setGeometry(area.width() / 2 - width / 2,
                (area.height() - height) / 2,
                width, height);
}

const MVirtualKeyboardStyleContainer &Notification::style() const
{
    return *styleContainer;
}
<commit_msg>Changes: notification widget updates geometry on every request<commit_after>/* * This file is part of meego-keyboard *
 *
 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
 * All rights reserved.
 * Contact: Nokia Corporation (directui@nokia.com)
 *
 * If you have questions regarding the use of this file, please contact
 * Nokia at directui@nokia.com.
 *
 * 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
 * and appearing in the file LICENSE.LGPL included in the packaging
 * of this file.
 */

#include "mvirtualkeyboardstyle.h"
#include "notification.h"

#include <QDebug>
#include <QFontMetrics>
#include <QPainter>

#include <MSceneManager>
#include <float.h>

namespace
{
    const int Margin = 10;           // Margin of the box surrounding text
    const int FrameCount = 15;       // How many frames to use in fading
    const int FadeTime = 300;        // Duration of fading in/out animation
    const int HoldTime = 700;        // Time to hold the widget in visible state
};

Notification::Notification(const MVirtualKeyboardStyleContainer *style, QGraphicsWidget *parent)
    : MWidget(parent),
      styleContainer(style)
{
    // Notification sets its own absolute opacity
    setFlag(ItemIgnoresParentOpacity, true);
    setZValue(FLT_MAX);

    visibilityTimer.setInterval(HoldTime);
    visibilityTimer.setSingleShot(true);

    fadeTimeLine.setFrameRange(0, FrameCount);
    fadeTimeLine.setDuration(FadeTime);

    connect(&fadeTimeLine, SIGNAL(frameChanged(int)),
            this, SLOT(updateOpacity(int)));
    connect(&fadeTimeLine, SIGNAL(finished()),
            this, SLOT(fadingFinished()));

    connect(&visibilityTimer, SIGNAL(timeout()),
            this, SLOT(fadeOut()));

    getStyleValues();
    hide();
}

Notification::~Notification()
{
}

void
Notification::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
{
    painter->setFont(font);
    painter->setPen(border);
    painter->setBrush(background);
    painter->setRenderHint(QPainter::Antialiasing);
    painter->drawRoundedRect(rect(), 10, 10);
    painter->setPen(textColor);
    painter->drawText(rect(), Qt::AlignCenter, message);
}

void
Notification::displayText(const QString &message, const QRectF &area)
{
    if (this->message != message) {
        this->message = message;
    }
    resetGeometry(area);

    fadeIn();
}

void
Notification::updateOpacity(int op)
{
    setOpacity(qreal(op) / qreal(FrameCount) * opacity);
    update();
}

void
Notification::fadingFinished()
{
    if (fadeTimeLine.direction() == QTimeLine::Forward) {
        // Notification is now shown an will be visible
        // as long as visibility timer runs.
        visibilityTimer.start();
    } else {
        // We have faded out
        hide();
    }
}

void Notification::fadeOut()
{
    fadeTimeLine.setDirection(QTimeLine::Backward);
    fadeTimeLine.start();
}

void Notification::getStyleValues()
{
    font = style()->notificationFont();
    border = style()->notificationBorderColor();
    background = style()->notificationBackgroundColor();
    textColor = style()->notificationTextColor();
    opacity = style()->notificationOpacity();
}

void Notification::fadeIn()
{
    // Handle fadeIn request in four different states:
    // not visible, fading in, visible, fading out

    if (fadeTimeLine.state() == QTimeLine::NotRunning) {
        if (isVisible()) {
            // Already visible so just prolong the visibility time
            // by restarting timer.
            visibilityTimer.start();
        } else {
            // The common case, begin fading in from hidden state.
            setOpacity(0.0);
            show();

            // Begin fading in
            fadeTimeLine.setDirection(QTimeLine::Forward);
            fadeTimeLine.start();
        }
    } else {
        // Fading in progress

        if (fadeTimeLine.direction() == QTimeLine::Forward) {
            // New fade in requested while fading in.
            // Do nothing, i.e. continue ongoing fading.
        } else {
            fadeTimeLine.toggleDirection();
        }
    }
}

void Notification::resetGeometry(const QRectF &area)
{
    const QFontMetrics fm(font);
    const int width = fm.width(message) + Margin * 2;
    const int height = fm.height() + Margin * 2;

    setGeometry(area.width() / 2 - width / 2,
                (area.height() - height) / 2,
                width, height);
}

const MVirtualKeyboardStyleContainer &Notification::style() const
{
    return *styleContainer;
}
<|endoftext|>


<commit_before>#include "net/url_fetcher.h"

#include <event2/buffer.h>
#include <event2/keyvalq_struct.h>
#include <glog/logging.h>

#include "net/connection_pool.h"

using cert_trans::internal::ConnectionPool;
using cert_trans::internal::evhttp_connection_unique_ptr;
using std::bind;
using std::endl;
using std::make_pair;
using std::move;
using std::ostream;
using std::string;
using util::Status;
using util::Task;
using util::TaskHold;

namespace cert_trans {

struct UrlFetcher::Impl {
  Impl(libevent::Base* base) : base_(CHECK_NOTNULL(base)), pool_(base_) {
  }

  libevent::Base* const base_;
  internal::ConnectionPool pool_;
};

namespace {

struct State {
  State(ConnectionPool* pool, evhttp_cmd_type verb,
        const UrlFetcher::Request& request, UrlFetcher::Response* response,
        Task* task);

  ~State() {
    CHECK(!conn_) << "request state object still had a connection at cleanup?";
  }

  // The following methods must only be called on the libevent
  // dispatch thread.
  void MakeRequest();
  void RequestDone(evhttp_request* req);

  ConnectionPool* const pool_;
  const evhttp_cmd_type verb_;
  const UrlFetcher::Request request_;
  UrlFetcher::Response* const response_;
  Task* const task_;

  evhttp_connection_unique_ptr conn_;
};

void RequestCallback(evhttp_request* req, void* userdata) {
  static_cast<State*>(CHECK_NOTNULL(userdata))->RequestDone(req);
}

UrlFetcher::Request NormaliseRequest(UrlFetcher::Request req) {
  if (req.url.Path().empty()) {
    req.url.SetPath("/");
  }

  return req;
}

State::State(ConnectionPool* pool, evhttp_cmd_type verb,
             const UrlFetcher::Request& request,
             UrlFetcher::Response* response, Task* task)
    : pool_(CHECK_NOTNULL(pool)),
      verb_(verb),
      request_(NormaliseRequest(request)),
      response_(CHECK_NOTNULL(response)),
      task_(CHECK_NOTNULL(task)) {
  if (request_.url.Protocol() != "http") {
    VLOG(1) << "unsupported protocol: " << request_.url.Protocol();
    task_->Return(Status(util::error::INVALID_ARGUMENT,
                         "UrlFetcher: unsupported protocol: " +
                             request_.url.Protocol()));
    return;
  }
}

void State::MakeRequest() {
  CHECK(libevent::Base::OnEventThread());
  evhttp_request* const http_req(
      CHECK_NOTNULL(evhttp_request_new(&RequestCallback, this)));
  evhttp_add_header(evhttp_request_get_output_headers(http_req), "Host",
                    request_.url.Host().c_str());

  if (!request_.body.empty()) {
    if (evbuffer_add_reference(evhttp_request_get_output_buffer(http_req),
                               request_.body.data(), request_.body.size(),
                               nullptr, nullptr) != 0) {
      VLOG(1) << "error when adding the request body";
      task_->Return(
          Status(util::error::INTERNAL, "could not set the request body"));
      return;
    }
  }

  conn_ = pool_->Get(request_.url);

  VLOG(1) << "evhttp_make_request(" << conn_.get() << ", " << http_req << ", "
          << verb_ << ", \"" << request_.url.PathQuery() << "\")";
  if (evhttp_make_request(conn_.get(), http_req, verb_,
                          request_.url.PathQuery().c_str()) != 0) {
    VLOG(1) << "evhttp_make_request error";
    // Put back the connection, RequestDone is not going to get
    // called.
    pool_->Put(move(conn_));
    task_->Return(Status(util::error::INTERNAL, "evhttp_make_request error"));
    return;
  }
}

void State::RequestDone(evhttp_request* req) {
  CHECK(libevent::Base::OnEventThread());
  CHECK(conn_);
  pool_->Put(move(conn_));

  if (!req) {
    // TODO(pphaneuf): The dreaded null request... These are fairly
    // fatal things, like protocol parse errors, but could also be a
    // connection timeout. I think we should do retries in this case,
    // with a deadline of our own? At least, then, it would be easier
    // to distinguish between an obscure error, or a more common
    // timeout.
    VLOG(1) << "RequestCallback received a null request";
    task_->Return(Status::UNKNOWN);
    return;
  }

  response_->status_code = evhttp_request_get_response_code(req);
  if (response_->status_code < 100) {
    // TODO(pphaneuf): According to my reading of libevent, this is
    // most likely to be a connection refused?
    VLOG(1) << "request has a status code lower than 100: "
            << response_->status_code;
    task_->Return(
        Status(util::error::FAILED_PRECONDITION, "connection refused"));
    return;
  }

  for (evkeyval* ptr = evhttp_request_get_input_headers(req)->tqh_first; ptr;
       ptr = ptr->next.tqe_next) {
    response_->headers.insert(make_pair(ptr->key, ptr->value));
  }

  const size_t body_length(
      evbuffer_get_length(evhttp_request_get_input_buffer(req)));
  string body(reinterpret_cast<const char*>(evbuffer_pullup(
                  evhttp_request_get_input_buffer(req), body_length)),
              body_length);
  response_->body.swap(body);

  task_->Return();
}

}  // namespace

// Needs to be defined where Impl is also defined.
UrlFetcher::UrlFetcher() {
}

UrlFetcher::UrlFetcher(libevent::Base* base)
    : impl_(new Impl(CHECK_NOTNULL(base))) {
}

// Needs to be defined where Impl is also defined.
UrlFetcher::~UrlFetcher() {
}

void UrlFetcher::Get(const Request& req, Response* resp, Task* task) {
  TaskHold hold(task);

  State* const state(
      new State(&impl_->pool_, EVHTTP_REQ_GET, req, resp, task));
  task->DeleteWhenDone(state);

  impl_->base_->Add(bind(&State::MakeRequest, state));
}

void UrlFetcher::Post(const Request& req, Response* resp, Task* task) {
  TaskHold hold(task);

  State* const state(
      new State(&impl_->pool_, EVHTTP_REQ_POST, req, resp, task));
  task->DeleteWhenDone(state);

  impl_->base_->Add(bind(&State::MakeRequest, state));
}

ostream& operator<<(ostream& output, const UrlFetcher::Response& resp) {
  output << "status_code: " << resp.status_code << endl
         << "headers {" << endl;
  for (const auto& header : resp.headers) {
    output << "  " << header.first << ": " << header.second << endl;
  }
  output << "}" << endl
         << "body: <<EOF" << endl
         << resp.body << "EOF" << endl;

  return output;
}

}  // namespace cert_trans
<commit_msg>Clear the HTTP headers in a response before filling them in.<commit_after>#include "net/url_fetcher.h"

#include <event2/buffer.h>
#include <event2/keyvalq_struct.h>
#include <glog/logging.h>

#include "net/connection_pool.h"

using cert_trans::internal::ConnectionPool;
using cert_trans::internal::evhttp_connection_unique_ptr;
using std::bind;
using std::endl;
using std::make_pair;
using std::move;
using std::ostream;
using std::string;
using util::Status;
using util::Task;
using util::TaskHold;

namespace cert_trans {

struct UrlFetcher::Impl {
  Impl(libevent::Base* base) : base_(CHECK_NOTNULL(base)), pool_(base_) {
  }

  libevent::Base* const base_;
  internal::ConnectionPool pool_;
};

namespace {

struct State {
  State(ConnectionPool* pool, evhttp_cmd_type verb,
        const UrlFetcher::Request& request, UrlFetcher::Response* response,
        Task* task);

  ~State() {
    CHECK(!conn_) << "request state object still had a connection at cleanup?";
  }

  // The following methods must only be called on the libevent
  // dispatch thread.
  void MakeRequest();
  void RequestDone(evhttp_request* req);

  ConnectionPool* const pool_;
  const evhttp_cmd_type verb_;
  const UrlFetcher::Request request_;
  UrlFetcher::Response* const response_;
  Task* const task_;

  evhttp_connection_unique_ptr conn_;
};

void RequestCallback(evhttp_request* req, void* userdata) {
  static_cast<State*>(CHECK_NOTNULL(userdata))->RequestDone(req);
}

UrlFetcher::Request NormaliseRequest(UrlFetcher::Request req) {
  if (req.url.Path().empty()) {
    req.url.SetPath("/");
  }

  return req;
}

State::State(ConnectionPool* pool, evhttp_cmd_type verb,
             const UrlFetcher::Request& request,
             UrlFetcher::Response* response, Task* task)
    : pool_(CHECK_NOTNULL(pool)),
      verb_(verb),
      request_(NormaliseRequest(request)),
      response_(CHECK_NOTNULL(response)),
      task_(CHECK_NOTNULL(task)) {
  if (request_.url.Protocol() != "http") {
    VLOG(1) << "unsupported protocol: " << request_.url.Protocol();
    task_->Return(Status(util::error::INVALID_ARGUMENT,
                         "UrlFetcher: unsupported protocol: " +
                             request_.url.Protocol()));
    return;
  }
}

void State::MakeRequest() {
  CHECK(libevent::Base::OnEventThread());
  evhttp_request* const http_req(
      CHECK_NOTNULL(evhttp_request_new(&RequestCallback, this)));
  evhttp_add_header(evhttp_request_get_output_headers(http_req), "Host",
                    request_.url.Host().c_str());

  if (!request_.body.empty()) {
    if (evbuffer_add_reference(evhttp_request_get_output_buffer(http_req),
                               request_.body.data(), request_.body.size(),
                               nullptr, nullptr) != 0) {
      VLOG(1) << "error when adding the request body";
      task_->Return(
          Status(util::error::INTERNAL, "could not set the request body"));
      return;
    }
  }

  conn_ = pool_->Get(request_.url);

  VLOG(1) << "evhttp_make_request(" << conn_.get() << ", " << http_req << ", "
          << verb_ << ", \"" << request_.url.PathQuery() << "\")";
  if (evhttp_make_request(conn_.get(), http_req, verb_,
                          request_.url.PathQuery().c_str()) != 0) {
    VLOG(1) << "evhttp_make_request error";
    // Put back the connection, RequestDone is not going to get
    // called.
    pool_->Put(move(conn_));
    task_->Return(Status(util::error::INTERNAL, "evhttp_make_request error"));
    return;
  }
}

void State::RequestDone(evhttp_request* req) {
  CHECK(libevent::Base::OnEventThread());
  CHECK(conn_);
  pool_->Put(move(conn_));

  if (!req) {
    // TODO(pphaneuf): The dreaded null request... These are fairly
    // fatal things, like protocol parse errors, but could also be a
    // connection timeout. I think we should do retries in this case,
    // with a deadline of our own? At least, then, it would be easier
    // to distinguish between an obscure error, or a more common
    // timeout.
    VLOG(1) << "RequestCallback received a null request";
    task_->Return(Status::UNKNOWN);
    return;
  }

  response_->status_code = evhttp_request_get_response_code(req);
  if (response_->status_code < 100) {
    // TODO(pphaneuf): According to my reading of libevent, this is
    // most likely to be a connection refused?
    VLOG(1) << "request has a status code lower than 100: "
            << response_->status_code;
    task_->Return(
        Status(util::error::FAILED_PRECONDITION, "connection refused"));
    return;
  }

  response_->headers.clear();
  for (evkeyval* ptr = evhttp_request_get_input_headers(req)->tqh_first; ptr;
       ptr = ptr->next.tqe_next) {
    response_->headers.insert(make_pair(ptr->key, ptr->value));
  }

  const size_t body_length(
      evbuffer_get_length(evhttp_request_get_input_buffer(req)));
  string body(reinterpret_cast<const char*>(evbuffer_pullup(
                  evhttp_request_get_input_buffer(req), body_length)),
              body_length);
  response_->body.swap(body);

  task_->Return();
}

}  // namespace

// Needs to be defined where Impl is also defined.
UrlFetcher::UrlFetcher() {
}

UrlFetcher::UrlFetcher(libevent::Base* base)
    : impl_(new Impl(CHECK_NOTNULL(base))) {
}

// Needs to be defined where Impl is also defined.
UrlFetcher::~UrlFetcher() {
}

void UrlFetcher::Get(const Request& req, Response* resp, Task* task) {
  TaskHold hold(task);

  State* const state(
      new State(&impl_->pool_, EVHTTP_REQ_GET, req, resp, task));
  task->DeleteWhenDone(state);

  impl_->base_->Add(bind(&State::MakeRequest, state));
}

void UrlFetcher::Post(const Request& req, Response* resp, Task* task) {
  TaskHold hold(task);

  State* const state(
      new State(&impl_->pool_, EVHTTP_REQ_POST, req, resp, task));
  task->DeleteWhenDone(state);

  impl_->base_->Add(bind(&State::MakeRequest, state));
}

ostream& operator<<(ostream& output, const UrlFetcher::Response& resp) {
  output << "status_code: " << resp.status_code << endl
         << "headers {" << endl;
  for (const auto& header : resp.headers) {
    output << "  " << header.first << ": " << header.second << endl;
  }
  output << "}" << endl
         << "body: <<EOF" << endl
         << resp.body << "EOF" << endl;

  return output;
}

}  // namespace cert_trans
<|endoftext|>


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

#include <graphene/app/plugin.hpp>
#include <graphene/chain/database.hpp>

namespace graphene { namespace template_plugin {
   using namespace chain;

//
// Plugins should #define their SPACE_ID's so plugins with
// conflicting SPACE_ID assignments can be compiled into the
// same binary (by simply re-assigning some of the conflicting #defined
// SPACE_ID's in a build script).
//
// Assignment of SPACE_ID's cannot be done at run-time because
// various template automagic depends on them being known at compile
// time.
//
#ifndef template_SPACE_ID
#define template_SPACE_ID 6
#endif

namespace detail
{
    class template_plugin_impl;
}

class template_plugin : public graphene::app::plugin
{
   public:
      template_plugin();
      virtual ~template_plugin();

      std::string plugin_name()const override;
      std::string plugin_description()const override;
      virtual void plugin_set_program_options(
         boost::program_options::options_description& cli,
         boost::program_options::options_description& cfg) override;
      virtual void plugin_initialize(const boost::program_options::variables_map& options) override;
      virtual void plugin_startup() override;

      friend class detail::template_plugin_impl;
      std::unique_ptr<detail::template_plugin_impl> my;
};

} } //graphene::template
<commit_msg>remove space id section<commit_after>/*
 * Copyright (c) 2018 template_plugin and contributors.
 *
 * The MIT License
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
#pragma once

#include <graphene/app/plugin.hpp>
#include <graphene/chain/database.hpp>

namespace graphene { namespace template_plugin {
using namespace chain;

namespace detail
{
    class template_plugin_impl;
}

class template_plugin : public graphene::app::plugin
{
   public:
      template_plugin();
      virtual ~template_plugin();

      std::string plugin_name()const override;
      std::string plugin_description()const override;
      virtual void plugin_set_program_options(
         boost::program_options::options_description& cli,
         boost::program_options::options_description& cfg) override;
      virtual void plugin_initialize(const boost::program_options::variables_map& options) override;
      virtual void plugin_startup() override;

      friend class detail::template_plugin_impl;
      std::unique_ptr<detail::template_plugin_impl> my;
};

} } //graphene::template
<|endoftext|>


<commit_before>//===--- LoopInfo.cpp - SIL Loop Analysis ---------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

#include "swift/SIL/LoopInfo.h"
#include "swift/SIL/SILBasicBlock.h"
#include "swift/SIL/Dominance.h"
#include "swift/SIL/SILFunction.h"
#include "swift/SIL/CFG.h"
#include "llvm/Analysis/LoopInfoImpl.h"
#include "llvm/Support/Debug.h"

using namespace swift;

// Instantiate template members.
template class llvm::LoopBase<SILBasicBlock, SILLoop>;
template class llvm::LoopInfoBase<SILBasicBlock, SILLoop>;

void SILLoop::dump() const {
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
  print(llvm::dbgs());
#endif
}

SILLoopInfo::SILLoopInfo(SILFunction *F, DominanceInfo *DT) : Dominance(DT) {
  LI.analyze(*Dominance);
}

bool SILLoop::canDuplicate(SILInstruction *I) const {
  // The deallocation of a stack allocation must be in the loop, otherwise the
  // deallocation will be fed by a phi node of two allocations.
  if (I->isAllocatingStack()) {
    for (auto *UI : I->getUses()) {
      if (UI->getUser()->isDeallocatingStack()) {
        if (!contains(UI->getUser()->getParent()))
          return false;
      }
    }
    return true;
  }

  // CodeGen can't build ssa for objc methods.
  if (auto *Method = dyn_cast<MethodInst>(I)) {
    if (Method->getMember().isForeign) {
      for (auto *UI : Method->getUses()) {
        if (!contains(UI->getUser()))
          return false;
      }
    }
    return true;
  }

  // We can't have a phi of two openexistential instructions of different UUID.
  SILInstruction *OEI = dyn_cast<OpenExistentialAddrInst>(I);
  if (OEI || (OEI = dyn_cast<OpenExistentialRefInst>(I)) ||
      (OEI = dyn_cast<OpenExistentialMetatypeInst>(I))) {
    for (auto *UI : OEI->getUses())
      if (!contains(UI->getUser()))
        return false;
    return true;
  }

  if (auto *Dealloc = dyn_cast<DeallocStackInst>(I)) {
    // The matching alloc_stack must be in the loop.
    if (auto *Alloc = dyn_cast<AllocStackInst>(Dealloc->getOperand()))
        return contains(Alloc->getParent());
    return false;
  }

  if (isa<ThrowInst>(I))
    return false;

  assert(I->isTriviallyDuplicatable() &&
    "Code here must match isTriviallyDuplicatable in SILInstruction");
  return true;
}

void SILLoopInfo::verify() const {
  LI.verify(*Dominance);
}
<commit_msg>Fix SILLoop::canDuplicate to handle all kinds of open_existential instructions.<commit_after>//===--- LoopInfo.cpp - SIL Loop Analysis ---------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

#include "swift/SIL/LoopInfo.h"
#include "swift/SIL/SILBasicBlock.h"
#include "swift/SIL/Dominance.h"
#include "swift/SIL/SILFunction.h"
#include "swift/SIL/CFG.h"
#include "llvm/Analysis/LoopInfoImpl.h"
#include "llvm/Support/Debug.h"

using namespace swift;

// Instantiate template members.
template class llvm::LoopBase<SILBasicBlock, SILLoop>;
template class llvm::LoopInfoBase<SILBasicBlock, SILLoop>;

void SILLoop::dump() const {
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
  print(llvm::dbgs());
#endif
}

SILLoopInfo::SILLoopInfo(SILFunction *F, DominanceInfo *DT) : Dominance(DT) {
  LI.analyze(*Dominance);
}

bool SILLoop::canDuplicate(SILInstruction *I) const {
  // The deallocation of a stack allocation must be in the loop, otherwise the
  // deallocation will be fed by a phi node of two allocations.
  if (I->isAllocatingStack()) {
    for (auto *UI : I->getUses()) {
      if (UI->getUser()->isDeallocatingStack()) {
        if (!contains(UI->getUser()->getParent()))
          return false;
      }
    }
    return true;
  }

  // CodeGen can't build ssa for objc methods.
  if (auto *Method = dyn_cast<MethodInst>(I)) {
    if (Method->getMember().isForeign) {
      for (auto *UI : Method->getUses()) {
        if (!contains(UI->getUser()))
          return false;
      }
    }
    return true;
  }

  // We can't have a phi of two openexistential instructions of different UUID.
  if (isa<OpenExistentialAddrInst>(I) || isa<OpenExistentialRefInst>(I) ||
      isa<OpenExistentialMetatypeInst>(I) ||
      isa<OpenExistentialValueInst>(I) || isa<OpenExistentialBoxInst>(I) ||
      isa<OpenExistentialBoxValueInst>(I)) {
    for (auto *UI : I->getUses())
      if (!contains(UI->getUser()))
        return false;
    return true;
  }

  if (auto *Dealloc = dyn_cast<DeallocStackInst>(I)) {
    // The matching alloc_stack must be in the loop.
    if (auto *Alloc = dyn_cast<AllocStackInst>(Dealloc->getOperand()))
        return contains(Alloc->getParent());
    return false;
  }

  if (isa<ThrowInst>(I))
    return false;

  assert(I->isTriviallyDuplicatable() &&
    "Code here must match isTriviallyDuplicatable in SILInstruction");
  return true;
}

void SILLoopInfo::verify() const {
  LI.verify(*Dominance);
}
<|endoftext|>


<commit_before>#ifndef CRUNCH_BASE_MEMORY_HPP
#define CRUNCH_BASE_MEMORY_HPP

#include "crunch/base/platform.hpp"

#include <cstddef>
#include <malloc.h>

namespace Crunch {

#if defined (CRUNCH_PLATFORM_WIN32)

inline void* MallocAligned(std::size_t bytes, std::size_t alignment)
{
    return ::_malloc_aligned(bytes, alignment);
}

inline void FreeAligned(void* allocation)
{
    ::_free_aligned(allocation);
}

#elif defined (CRUNCH_PLATFORM_LINUX)

inline void* MallocAligned(std::size_t bytes, std::size_t alignment)
{
    return ::memalign(alignment, bytes);
}

inline void FreeAligned(void* allocation)
{
    ::free(allocation);
}

#else
#   error "Unsupported platform"
#endif

inline void* AlignPointerUp(void* pointer, std::size_t alignment)
{
    std::size_t const a = alignment - 1;
    return (void*)(((std::size_t)pointer + a) & ~a);
}

inline void* AlignPointerDown(void* pointer, std::size_t alignment)
{
    return (void*)((std::size_t)pointer & ~(alignment - 1));
}

inline bool IsPointerAligned(void* pointer, std::size_t alignment)
{
    return ((std::size_t)pointer & (alignment - 1)) == 0;
}

inline void* OffsetPointer(void* pointer, std::ptrdiff_t delta)
{
    return (void*)((std::size_t)pointer + delta);
}

}

#endif
<commit_msg>crunch_base - Fixed MallocAligned and FreeAligned windows compile errors<commit_after>#ifndef CRUNCH_BASE_MEMORY_HPP
#define CRUNCH_BASE_MEMORY_HPP

#include "crunch/base/platform.hpp"

#include <cstddef>
#include <malloc.h>

namespace Crunch {

#if defined (CRUNCH_PLATFORM_WIN32)

__declspec(noalias) __declspec(restrict) inline void* MallocAligned(std::size_t bytes, std::size_t alignment)
{
    return ::_aligned_malloc(bytes, alignment);
}

__declspec(noalias) inline void FreeAligned(void* allocation)
{
    ::_aligned_free(allocation);
}

#elif defined (CRUNCH_PLATFORM_LINUX)

inline void* MallocAligned(std::size_t bytes, std::size_t alignment)
{
    return ::memalign(alignment, bytes);
}

inline void FreeAligned(void* allocation)
{
    ::free(allocation);
}

#else
#   error "Unsupported platform"
#endif

inline void* AlignPointerUp(void* pointer, std::size_t alignment)
{
    std::size_t const a = alignment - 1;
    return (void*)(((std::size_t)pointer + a) & ~a);
}

inline void* AlignPointerDown(void* pointer, std::size_t alignment)
{
    return (void*)((std::size_t)pointer & ~(alignment - 1));
}

inline bool IsPointerAligned(void* pointer, std::size_t alignment)
{
    return ((std::size_t)pointer & (alignment - 1)) == 0;
}

inline void* OffsetPointer(void* pointer, std::ptrdiff_t delta)
{
    return (void*)((std::size_t)pointer + delta);
}

}

#endif
<|endoftext|>


<commit_before>/** \file    translator_ajax.cc
 *  \brief   Interface for updating translations by ajax requests
 *  \author  Johannes Riedl
 */

/*
    Copyright (C) 2017, Library of the University of Tübingen

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as
    published by the Free Software Foundation, either version 3 of the
    License, or (at your option) any later version.

    This program 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 Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <iostream>
#include <fstream>
#include <cerrno>
#include <cstdio>
#include <cstring>
#include "Compiler.h"
#include "ExecUtil.h"
#include "HtmlUtil.h"
#include "MiscUtil.h"
#include "StringUtil.h"
#include "UrlUtil.h"
#include "WebUtil.h"
#include "util.h"

const std::string getTranslatorOrEmptryString() {
    return (std::getenv("REMOTE_USER") != nullptr) ? std::getenv("REMOTE_USER") : "";
}

void DumpCgiArgs(const std::multimap<std::string, std::string> &cgi_args) {
    for (const auto &key_and_values : cgi_args)
        std::cout << key_and_values.first << " = " << key_and_values.second << '\n';
}

std::string GetCGIParameterOrDie(const std::multimap<std::string, std::string> &cgi_args,
                                 const std::string &parameter_name)
{
    const auto key_and_value(cgi_args.find(parameter_name));
    if (key_and_value == cgi_args.cend())
        Error("expected a(n) \"" + parameter_name + "\" parameter!");

    return key_and_value->second;
}

std::string GetCGIParameterOrEmptyString(const std::multimap<std::string, std::string> &cgi_args,
                                         const std::string &parameter_name)
{
    const auto key_and_value(cgi_args.find(parameter_name));
    if (key_and_value == cgi_args.cend())
        return "";

    return key_and_value->second;
}

std::string GetEnvParameterOrEmptyString(const std::multimap<std::string, std::string> &env_args,
                                         const std::string &parameter_name)
{
    const auto key_and_value(env_args.find(parameter_name));
    if (key_and_value == env_args.cend())
        return "";

    return key_and_value->second;
}

void Update(const std::multimap<std::string, std::string> &cgi_args, const std::multimap<std::string, std::string> &env_args) {
    const std::string language_code(GetCGIParameterOrDie(cgi_args, "language_code"));
    const std::string translation(GetCGIParameterOrDie(cgi_args, "translation"));
    const std::string index(GetCGIParameterOrDie(cgi_args, "index"));
    const std::string gnd_code(GetCGIParameterOrEmptyString(cgi_args, "gnd_code"));
    const std::string translator(GetEnvParameterOrEmptyString(env_args, "REMOTE_USER"));

    std::string update_command("/usr/local/bin/translation_db_tool update '" + index);
    if (not gnd_code.empty())
        update_command += "' '" + gnd_code;
    update_command += "' " + language_code + " '" + translation + "' '" + translator + "'";

    std::string output;
    if (not ExecUtil::ExecSubcommandAndCaptureStdout(update_command, &output))
        Error("failed to execute \"" + update_command + "\" or it returned a non-zero exit code!");
}

void Insert(const std::multimap<std::string, std::string> &cgi_args, const std::multimap<std::string, std::string> &env_args) {
    const std::string language_code(GetCGIParameterOrDie(cgi_args, "language_code"));
    const std::string translation(GetCGIParameterOrDie(cgi_args, "translation"));
    const std::string index(GetCGIParameterOrDie(cgi_args, "index"));
    const std::string gnd_code(GetCGIParameterOrEmptyString(cgi_args, "gnd_code"));
    const std::string translator(GetEnvParameterOrEmptyString(env_args, "REMOTE_USER"));

    if (translation.empty())
        return;

    std::string insert_command("/usr/local/bin/translation_db_tool insert '" + index);
    if (not gnd_code.empty())
        insert_command += "' '" + gnd_code;
    insert_command += "' " + language_code + " '" + translation + "' '" + translator + "'";

    std::string output;
    if (not ExecUtil::ExecSubcommandAndCaptureStdout(insert_command, &output))
        Error("failed to execute \"" + insert_command + "\" or it returned a non-zero exit code!");
}

int main(int argc, char *argv[]) {
    ::progname = argv[0];

    try {
        std::multimap<std::string, std::string> cgi_args;
        WebUtil::GetAllCgiArgs(&cgi_args, argc, argv);

        std::multimap<std::string, std::string> env_args;
        env_args.insert(std::make_pair("REMOTE_USER", getTranslatorOrEmptryString()));

        if (cgi_args.size() == 5 or cgi_args.size() == 6) {
            const std::string action(GetCGIParameterOrDie(cgi_args, "action"));
            std::string status = "Status: 501 Not Implemented";
            if (action == "insert") {
                Insert(cgi_args, env_args);
                status = "Status: 201 Created\r\n";
            }
            else if (action == "update") {
                Update(cgi_args, env_args);
                status = "Status: 200 OK\r\n";
            }
            else
                Error("Unknown action: " + action + "! Expecting 'insert' or 'update'.");

            std::cout << "Content-Type: text/html; charset=utf-8\r\n\r\n";
            const std::string language_code(GetCGIParameterOrDie(cgi_args, "language_code"));
            std::cout << status;
        } else
            Error("we should be called w/ either or 5 or 6 CGI arguments!");
    } catch (const std::exception &x) {
        Error("caught exception: " + std::string(x.what()));
    }
}

<commit_msg>Fixed apostrophe problem with translations<commit_after>/** \file    translator_ajax.cc
 *  \brief   Interface for updating translations by ajax requests
 *  \author  Johannes Riedl
 */

/*
    Copyright (C) 2017, Library of the University of Tübingen

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as
    published by the Free Software Foundation, either version 3 of the
    License, or (at your option) any later version.

    This program 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 Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <iostream>
#include <fstream>
#include <cerrno>
#include <cstdio>
#include <cstring>
#include "Compiler.h"
#include "ExecUtil.h"
#include "HtmlUtil.h"
#include "MiscUtil.h"
#include "StringUtil.h"
#include "UrlUtil.h"
#include "WebUtil.h"
#include "util.h"

const std::string getTranslatorOrEmptryString() {
    return (std::getenv("REMOTE_USER") != nullptr) ? std::getenv("REMOTE_USER") : "";
}

void DumpCgiArgs(const std::multimap<std::string, std::string> &cgi_args) {
    for (const auto &key_and_values : cgi_args)
        std::cout << key_and_values.first << " = " << key_and_values.second << '\n';
}

std::string GetCGIParameterOrDie(const std::multimap<std::string, std::string> &cgi_args,
                                 const std::string &parameter_name)
{
    const auto key_and_value(cgi_args.find(parameter_name));
    if (key_and_value == cgi_args.cend())
        Error("expected a(n) \"" + parameter_name + "\" parameter!");

    return key_and_value->second;
}

std::string GetCGIParameterOrEmptyString(const std::multimap<std::string, std::string> &cgi_args,
                                         const std::string &parameter_name)
{
    const auto key_and_value(cgi_args.find(parameter_name));
    if (key_and_value == cgi_args.cend())
        return "";

    return key_and_value->second;
}

std::string GetEnvParameterOrEmptyString(const std::multimap<std::string, std::string> &env_args,
                                         const std::string &parameter_name)
{
    const auto key_and_value(env_args.find(parameter_name));
    if (key_and_value == env_args.cend())
        return "";

    return key_and_value->second;
}

void Update(const std::multimap<std::string, std::string> &cgi_args, const std::multimap<std::string, std::string> &env_args) {
    const std::string language_code(GetCGIParameterOrDie(cgi_args, "language_code"));
    const std::string translation(GetCGIParameterOrDie(cgi_args, "translation"));
    const std::string index(GetCGIParameterOrDie(cgi_args, "index"));
    const std::string gnd_code(GetCGIParameterOrEmptyString(cgi_args, "gnd_code"));
    const std::string translator(GetEnvParameterOrEmptyString(env_args, "REMOTE_USER"));

    std::string update_command("/usr/local/bin/translation_db_tool update '" + index);
    if (not gnd_code.empty())
        update_command += "' '" + gnd_code;
    update_command += "' " + language_code + " \"" + translation + "\" '" + translator + "'";

    std::string output;
    if (not ExecUtil::ExecSubcommandAndCaptureStdout(update_command, &output))
        Error("failed to execute \"" + update_command + "\" or it returned a non-zero exit code!");
}

void Insert(const std::multimap<std::string, std::string> &cgi_args, const std::multimap<std::string, std::string> &env_args) {
    const std::string language_code(GetCGIParameterOrDie(cgi_args, "language_code"));
    const std::string translation(GetCGIParameterOrDie(cgi_args, "translation"));
    const std::string index(GetCGIParameterOrDie(cgi_args, "index"));
    const std::string gnd_code(GetCGIParameterOrEmptyString(cgi_args, "gnd_code"));
    const std::string translator(GetEnvParameterOrEmptyString(env_args, "REMOTE_USER"));

    if (translation.empty())
        return;

    std::string insert_command("/usr/local/bin/translation_db_tool insert '" + index);
    if (not gnd_code.empty())
        insert_command += "' '" + gnd_code;
    insert_command += "' " + language_code + " \"" + translation + "\" '" + translator + "'";

    std::string output;
    if (not ExecUtil::ExecSubcommandAndCaptureStdout(insert_command, &output))
        Error("failed to execute \"" + insert_command + "\" or it returned a non-zero exit code!");
}

int main(int argc, char *argv[]) {
    ::progname = argv[0];

    try {
        std::multimap<std::string, std::string> cgi_args;
        WebUtil::GetAllCgiArgs(&cgi_args, argc, argv);

        std::multimap<std::string, std::string> env_args;
        env_args.insert(std::make_pair("REMOTE_USER", getTranslatorOrEmptryString()));

        if (cgi_args.size() == 5 or cgi_args.size() == 6) {
            const std::string action(GetCGIParameterOrDie(cgi_args, "action"));
            std::string status = "Status: 501 Not Implemented";
            if (action == "insert") {
                Insert(cgi_args, env_args);
                status = "Status: 201 Created\r\n";
            }
            else if (action == "update") {
                Update(cgi_args, env_args);
                status = "Status: 200 OK\r\n";
            }
            else
                Error("Unknown action: " + action + "! Expecting 'insert' or 'update'.");

            std::cout << "Content-Type: text/html; charset=utf-8\r\n\r\n";
            const std::string language_code(GetCGIParameterOrDie(cgi_args, "language_code"));
            std::cout << status;
        } else
            Error("we should be called w/ either or 5 or 6 CGI arguments!");
    } catch (const std::exception &x) {
        Error("caught exception: " + std::string(x.what()));
    }
}

<|endoftext|>


<commit_before>/*
 * (C) Copyright 2015 ETH Zurich Systems Group (http://www.systems.ethz.ch/) and others.
 *
 * 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.
 *
 * Contributors:
 *     Markus Pilman <mpilman@inf.ethz.ch>
 *     Simon Loesing <sloesing@inf.ethz.ch>
 *     Thomas Etter <etterth@gmail.com>
 *     Kevin Bocksrocker <kevin.bocksrocker@gmail.com>
 *     Lucas Braun <braunl@inf.ethz.ch>
 */

#include <telldb/Tuple.hpp>
#include <tellstore/Table.hpp>

#include <crossbow/alignment.hpp>

#include <memory.h>

namespace tell {
namespace db {

namespace {

boost::any deserialize(tell::store::FieldType type, const char* const data) {
    using namespace tell::store;
    switch (type) {
    case FieldType::NULLTYPE:
        return nullptr;
    case FieldType::SMALLINT:
        LOG_ASSERT(reinterpret_cast<uintptr_t>(data) % alignof(int16_t) == 0u, "Pointer to field must be aligned");
        return int16_t(*reinterpret_cast<const int16_t*>(data));
    case FieldType::INT:
        LOG_ASSERT(reinterpret_cast<uintptr_t>(data) % alignof(int32_t) == 0u, "Pointer to field must be aligned");
        return int32_t(*reinterpret_cast<const int32_t*>(data));
    case FieldType::BIGINT:
        LOG_ASSERT(reinterpret_cast<uintptr_t>(data) % alignof(int64_t) == 0u, "Pointer to field must be aligned");
        return int64_t(*reinterpret_cast<const int64_t*>(data));
    case FieldType::FLOAT:
        LOG_ASSERT(reinterpret_cast<uintptr_t>(data) % alignof(float) == 0u, "Pointer to field must be aligned");
        return float(*reinterpret_cast<const float*>(data));
    case FieldType::DOUBLE:
        LOG_ASSERT(reinterpret_cast<uintptr_t>(data) % alignof(double) == 0u, "Pointer to field must be aligned");
        return double(*reinterpret_cast<const double*>(data));
    case FieldType::TEXT:
    case FieldType::BLOB:
        {
            LOG_ASSERT(reinterpret_cast<uintptr_t>(data) % alignof(uint32_t) == 0u, "Pointer to field must be aligned");
            auto sz = *reinterpret_cast<const uint32_t*>(data);
            return crossbow::string(data + sizeof(uint32_t), sz);
        }
    case FieldType::NOTYPE:
        LOG_ASSERT(false, "One should never use a field of type NOTYPE");
        return false;
    }
    LOG_ASSERT(false, "Unreachable code");
    return false;
}

} // namespace {}

Tuple::Tuple(
        const tell::store::Record& record,
        const tell::store::Tuple& tuple,
        crossbow::ChunkMemoryPool& pool)
    : mRecord(record)
    , mPool(pool)
    , mFields(&mPool)
{
    int numFields = record.fieldCount();
    for (int i = 0; i < numFields; ++i) {
        bool isNull = false;
        tell::store::FieldType type;
        auto data = record.data(tuple.data(), id_t(i), isNull, &type);
        if (isNull) {
            mFields.emplace_back(tell::store::FieldType::NULLTYPE, nullptr);
        } else {
            mFields.emplace_back(type, deserialize(type, data));
        }
    }
}

Tuple::Tuple(const store::Record& record, crossbow::ChunkMemoryPool& pool)
    : mRecord(record)
    , mPool(pool)
    , mFields(&mPool)
{
    int numFields = record.fieldCount();
    mFields.resize(numFields);
}

size_t Tuple::size() const {
    auto result = mRecord.fixedSize();
    const auto& schema = mRecord.schema();
    for (decltype(mFields.size()) i = schema.varSizeFields().size(); i < mFields.size(); ++i) {
        result = crossbow::align(result, 4u);
        result += sizeof(uint32_t);
        if (mFields[i].type() != store::FieldType::NULLTYPE) {
            const auto& v = boost::any_cast<const crossbow::string&>(mFields[i].value());
            result += v.size();
        }
    }
    return crossbow::align(result, 8u);
}

void Tuple::serialize(char* dest) const {
    const auto& schema = mRecord.schema();
    auto someNull = !mRecord.schema().allNotNull();
    auto pos = dest;
    if (!mRecord.schema().allNotNull()) {
        // set bitmap to null
        auto headerSize = mRecord.headerSize();
        ::memset(dest, 0, headerSize);
        pos += headerSize;
    }
    const auto& fixedSize = schema.fixedSizeFields();
    auto numFixedSize = fixedSize.size();
    auto numFields = mRecord.fieldCount();
    const auto& varSizedFields = schema.varSizeFields();
    for (decltype(numFields) i = 0; i < numFields; ++i) {
        auto isFixedSize = (i < numFixedSize);
        if (!isFixedSize) {
            pos = crossbow::align(pos, 4u);
        }
        if (someNull)
            mRecord.setFieldNull(dest, i, mFields[i].null());
        if (mFields[i].null()) {
            store::FieldType type;
            if (isFixedSize) {
                type = fixedSize[i].type();
            } else {
                type = varSizedFields[i - numFixedSize].type();
            }
            store::FieldBase f(type);
            auto defaultSize = f.defaultSize();
            memset(pos, 0, defaultSize);
            pos += defaultSize;
        } else {
            pos += mFields[i].serialize(pos);
        }
    }
}

} // namespace db
} // namespace tell

<commit_msg>Fix iteration begin<commit_after>/*
 * (C) Copyright 2015 ETH Zurich Systems Group (http://www.systems.ethz.ch/) and others.
 *
 * 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.
 *
 * Contributors:
 *     Markus Pilman <mpilman@inf.ethz.ch>
 *     Simon Loesing <sloesing@inf.ethz.ch>
 *     Thomas Etter <etterth@gmail.com>
 *     Kevin Bocksrocker <kevin.bocksrocker@gmail.com>
 *     Lucas Braun <braunl@inf.ethz.ch>
 */

#include <telldb/Tuple.hpp>
#include <tellstore/Table.hpp>

#include <crossbow/alignment.hpp>

#include <memory.h>

namespace tell {
namespace db {

namespace {

boost::any deserialize(tell::store::FieldType type, const char* const data) {
    using namespace tell::store;
    switch (type) {
    case FieldType::NULLTYPE:
        return nullptr;
    case FieldType::SMALLINT:
        LOG_ASSERT(reinterpret_cast<uintptr_t>(data) % alignof(int16_t) == 0u, "Pointer to field must be aligned");
        return int16_t(*reinterpret_cast<const int16_t*>(data));
    case FieldType::INT:
        LOG_ASSERT(reinterpret_cast<uintptr_t>(data) % alignof(int32_t) == 0u, "Pointer to field must be aligned");
        return int32_t(*reinterpret_cast<const int32_t*>(data));
    case FieldType::BIGINT:
        LOG_ASSERT(reinterpret_cast<uintptr_t>(data) % alignof(int64_t) == 0u, "Pointer to field must be aligned");
        return int64_t(*reinterpret_cast<const int64_t*>(data));
    case FieldType::FLOAT:
        LOG_ASSERT(reinterpret_cast<uintptr_t>(data) % alignof(float) == 0u, "Pointer to field must be aligned");
        return float(*reinterpret_cast<const float*>(data));
    case FieldType::DOUBLE:
        LOG_ASSERT(reinterpret_cast<uintptr_t>(data) % alignof(double) == 0u, "Pointer to field must be aligned");
        return double(*reinterpret_cast<const double*>(data));
    case FieldType::TEXT:
    case FieldType::BLOB:
        {
            LOG_ASSERT(reinterpret_cast<uintptr_t>(data) % alignof(uint32_t) == 0u, "Pointer to field must be aligned");
            auto sz = *reinterpret_cast<const uint32_t*>(data);
            return crossbow::string(data + sizeof(uint32_t), sz);
        }
    case FieldType::NOTYPE:
        LOG_ASSERT(false, "One should never use a field of type NOTYPE");
        return false;
    }
    LOG_ASSERT(false, "Unreachable code");
    return false;
}

} // namespace {}

Tuple::Tuple(
        const tell::store::Record& record,
        const tell::store::Tuple& tuple,
        crossbow::ChunkMemoryPool& pool)
    : mRecord(record)
    , mPool(pool)
    , mFields(&mPool)
{
    int numFields = record.fieldCount();
    for (int i = 0; i < numFields; ++i) {
        bool isNull = false;
        tell::store::FieldType type;
        auto data = record.data(tuple.data(), id_t(i), isNull, &type);
        if (isNull) {
            mFields.emplace_back(tell::store::FieldType::NULLTYPE, nullptr);
        } else {
            mFields.emplace_back(type, deserialize(type, data));
        }
    }
}

Tuple::Tuple(const store::Record& record, crossbow::ChunkMemoryPool& pool)
    : mRecord(record)
    , mPool(pool)
    , mFields(&mPool)
{
    int numFields = record.fieldCount();
    mFields.resize(numFields);
}

size_t Tuple::size() const {
    auto result = mRecord.fixedSize();
    const auto& schema = mRecord.schema();
    for (decltype(mFields.size()) i = schema.fixedSizeFields().size(); i < mFields.size(); ++i) {
        result = crossbow::align(result, 4u);
        result += sizeof(uint32_t);
        if (mFields[i].type() != store::FieldType::NULLTYPE) {
            const auto& v = boost::any_cast<const crossbow::string&>(mFields[i].value());
            result += v.size();
        }
    }
    return crossbow::align(result, 8u);
}

void Tuple::serialize(char* dest) const {
    const auto& schema = mRecord.schema();
    auto someNull = !mRecord.schema().allNotNull();
    auto pos = dest;
    if (!mRecord.schema().allNotNull()) {
        // set bitmap to null
        auto headerSize = mRecord.headerSize();
        ::memset(dest, 0, headerSize);
        pos += headerSize;
    }
    const auto& fixedSize = schema.fixedSizeFields();
    auto numFixedSize = fixedSize.size();
    auto numFields = mRecord.fieldCount();
    const auto& varSizedFields = schema.varSizeFields();
    for (decltype(numFields) i = 0; i < numFields; ++i) {
        auto isFixedSize = (i < numFixedSize);
        if (!isFixedSize) {
            pos = crossbow::align(pos, 4u);
        }
        if (someNull)
            mRecord.setFieldNull(dest, i, mFields[i].null());
        if (mFields[i].null()) {
            store::FieldType type;
            if (isFixedSize) {
                type = fixedSize[i].type();
            } else {
                type = varSizedFields[i - numFixedSize].type();
            }
            store::FieldBase f(type);
            auto defaultSize = f.defaultSize();
            memset(pos, 0, defaultSize);
            pos += defaultSize;
        } else {
            pos += mFields[i].serialize(pos);
        }
    }
}

} // namespace db
} // namespace tell

<|endoftext|>