<commit_before>/*ckwg +5
 * Copyright 2011 by Kitware, Inc. All Rights Reserved. Please refer to
 * KITWARE_LICENSE.TXT for licensing information, or contact General Counsel,
 * Kitware, Inc., 28 Corporate Drive, Clifton Park, NY 12065.
 */

#include <vistk/pipeline_util/load_pipe.h>
#include <vistk/pipeline_util/pipe_bakery.h>
#include <vistk/pipeline_util/pipe_declaration_types.h>

#include <vistk/pipeline/config.h>
#include <vistk/pipeline/modules.h>
#include <vistk/pipeline/schedule.h>
#include <vistk/pipeline/schedule_registry.h>
#include <vistk/pipeline/pipeline.h>

#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/split.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/foreach.hpp>
#include <boost/program_options.hpp>

#include <fstream>
#include <iostream>
#include <vector>

namespace po = boost::program_options;

static std::string const split_str = "=";
static vistk::config::key_t const schedule_block = vistk::config::key_t("_schedule");

static po::options_description make_options();
static void usage(po::options_description const& options);

int main(int argc, char* argv[])
{
  vistk::load_known_modules();

  po::options_description const desc = make_options();

  po::variables_map vm;
  po::store(po::parse_command_line(argc, argv, desc), vm);
  po::notify(vm);

  if (vm.count("help"))
  {
    usage(desc);
  }

  if (!vm.count("pipeline"))
  {
    std::cerr << "Error: pipeline not set" << std::endl;
    usage(desc);
  }

  vistk::pipeline_t pipe;

  vistk::config_t conf;

  {
    std::istream* pistr;
    std::ifstream fin;

    vistk::path_t const ipath = vm["pipeline"].as<vistk::path_t>();

    if (ipath.native() == vistk::path_t("-"))
    {
      pistr = &std::cin;
    }
    else
    {
      fin.open(ipath.native().c_str());

      if (!fin.good())
      {
        std::cerr << "Error: Unable to open input file" << std::endl;

        return 1;
      }

      pistr = &fin;
    }

    std::istream& istr = *pistr;

    /// \todo Include paths?

    vistk::pipe_blocks blocks = vistk::load_pipe_blocks(istr, boost::filesystem::current_path());

    // Load supplemental configuration files.
    if (vm.count("config"))
    {
      vistk::paths_t const configs = vm["config"].as<vistk::paths_t>();

      BOOST_FOREACH (vistk::path_t const& config, configs)
      {
        vistk::pipe_blocks const config_blocks = vistk::load_pipe_blocks_from_file(config);

        blocks.insert(blocks.end(), config_blocks.begin(), config_blocks.end());
      }
    }

    // Insert lone setting variables from the command line.
    if (vm.count("setting"))
    {
      std::vector<std::string> const settings = vm["setting"].as<std::vector<std::string> >();

      BOOST_FOREACH (std::string const& setting, settings)
      {
        vistk::config_pipe_block block;

        vistk::config_value_t value;

        size_t const split_pos = setting.find(split_str);

        if (split_pos == std::string::npos)
        {
          std::cerr << "Error: The setting on the command line "
                       "\'" << setting << "\' does not contain "
                       "the \'" << split_str << "\' string which "
                       "separates the key from the value" << std::endl;

          return 1;
        }

        vistk::config::key_t setting_key = setting.substr(0, split_pos);
        vistk::config::value_t setting_value = setting.substr(split_pos + split_str.size());

        vistk::config::keys_t keys;

        if (vistk::config::block_sep.size() != 1)
        {
          std::cerr << "Error: The block separator is not than "
                       "one character and does not work here" << std::endl;

          return 1;
        }

        /// \bug Does not work if (vistk::config::block_sep.size() != 1).
        boost::split(keys, setting_key, boost::is_any_of(vistk::config::block_sep));

        if (keys.size() < 2)
        {
          std::cerr << "Error: The key in the command line setting "
                       "\'" << setting << "\' does not contain "
                       "at least two keys in its keypath which is "
                       "invalid" << std::endl;

          return 1;
        }

        value.key.key_path.push_back(keys.back());
        value.value = setting_value;

        keys.pop_back();

        block.key = keys;
        block.values.push_back(value);

        blocks.push_back(block);
      }
    }

    pipe = vistk::bake_pipe_blocks(blocks);

    conf = vistk::extract_configuration(blocks);
  }

  if (!pipe)
  {
    std::cerr << "Error: Unable to bake pipeline" << std::endl;

    return 1;
  }

  pipe->setup_pipeline();

  vistk::schedule_registry::type_t const schedule_type = vm["schedule"].as<vistk::schedule_registry::type_t>();
  vistk::config_t const schedule_config = conf->subblock(schedule_block + vistk::config::block_sep + schedule_type);

  vistk::schedule_registry_t reg = vistk::schedule_registry::self();

  vistk::schedule_t schedule = reg->create_schedule(schedule_type, schedule_config, pipe);

  if (!schedule)
  {
    std::cerr << "Error: Unable to create schedule" << std::endl;

    return 1;
  }

  schedule->start();
  schedule->wait();

  return 0;
}

po::options_description
make_options()
{
  po::options_description desc;

  desc.add_options()
    ("help,h", "output help message and quit")
    ("pipeline,p", po::value<vistk::path_t>(), "pipeline")
    ("config,c", po::value<vistk::paths_t>(), "supplemental configuration file")
    ("setting,s", po::value<std::vector<std::string> >(), "additional configuration")
    ("include,I", po::value<vistk::paths_t>(), "configuration include path")
    ("schedule,S", po::value<vistk::schedule_registry::type_t>(), "schedule type")
  ;

  return desc;
}

void
usage(po::options_description const& options)
{
  std::cerr << options << std::endl;

  exit(1);
}
<commit_msg>Use the default schedule if none is given<commit_after>/*ckwg +5
 * Copyright 2011 by Kitware, Inc. All Rights Reserved. Please refer to
 * KITWARE_LICENSE.TXT for licensing information, or contact General Counsel,
 * Kitware, Inc., 28 Corporate Drive, Clifton Park, NY 12065.
 */

#include <vistk/pipeline_util/load_pipe.h>
#include <vistk/pipeline_util/pipe_bakery.h>
#include <vistk/pipeline_util/pipe_declaration_types.h>

#include <vistk/pipeline/config.h>
#include <vistk/pipeline/modules.h>
#include <vistk/pipeline/schedule.h>
#include <vistk/pipeline/schedule_registry.h>
#include <vistk/pipeline/pipeline.h>

#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/split.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/foreach.hpp>
#include <boost/program_options.hpp>

#include <fstream>
#include <iostream>
#include <vector>

namespace po = boost::program_options;

static std::string const split_str = "=";
static vistk::config::key_t const schedule_block = vistk::config::key_t("_schedule");

static po::options_description make_options();
static void usage(po::options_description const& options);

int main(int argc, char* argv[])
{
  vistk::load_known_modules();

  po::options_description const desc = make_options();

  po::variables_map vm;
  po::store(po::parse_command_line(argc, argv, desc), vm);
  po::notify(vm);

  if (vm.count("help"))
  {
    usage(desc);
  }

  if (!vm.count("pipeline"))
  {
    std::cerr << "Error: pipeline not set" << std::endl;
    usage(desc);
  }

  vistk::pipeline_t pipe;

  vistk::config_t conf;

  {
    std::istream* pistr;
    std::ifstream fin;

    vistk::path_t const ipath = vm["pipeline"].as<vistk::path_t>();

    if (ipath.native() == vistk::path_t("-"))
    {
      pistr = &std::cin;
    }
    else
    {
      fin.open(ipath.native().c_str());

      if (!fin.good())
      {
        std::cerr << "Error: Unable to open input file" << std::endl;

        return 1;
      }

      pistr = &fin;
    }

    std::istream& istr = *pistr;

    /// \todo Include paths?

    vistk::pipe_blocks blocks = vistk::load_pipe_blocks(istr, boost::filesystem::current_path());

    // Load supplemental configuration files.
    if (vm.count("config"))
    {
      vistk::paths_t const configs = vm["config"].as<vistk::paths_t>();

      BOOST_FOREACH (vistk::path_t const& config, configs)
      {
        vistk::pipe_blocks const config_blocks = vistk::load_pipe_blocks_from_file(config);

        blocks.insert(blocks.end(), config_blocks.begin(), config_blocks.end());
      }
    }

    // Insert lone setting variables from the command line.
    if (vm.count("setting"))
    {
      std::vector<std::string> const settings = vm["setting"].as<std::vector<std::string> >();

      BOOST_FOREACH (std::string const& setting, settings)
      {
        vistk::config_pipe_block block;

        vistk::config_value_t value;

        size_t const split_pos = setting.find(split_str);

        if (split_pos == std::string::npos)
        {
          std::cerr << "Error: The setting on the command line "
                       "\'" << setting << "\' does not contain "
                       "the \'" << split_str << "\' string which "
                       "separates the key from the value" << std::endl;

          return 1;
        }

        vistk::config::key_t setting_key = setting.substr(0, split_pos);
        vistk::config::value_t setting_value = setting.substr(split_pos + split_str.size());

        vistk::config::keys_t keys;

        if (vistk::config::block_sep.size() != 1)
        {
          std::cerr << "Error: The block separator is not than "
                       "one character and does not work here" << std::endl;

          return 1;
        }

        /// \bug Does not work if (vistk::config::block_sep.size() != 1).
        boost::split(keys, setting_key, boost::is_any_of(vistk::config::block_sep));

        if (keys.size() < 2)
        {
          std::cerr << "Error: The key in the command line setting "
                       "\'" << setting << "\' does not contain "
                       "at least two keys in its keypath which is "
                       "invalid" << std::endl;

          return 1;
        }

        value.key.key_path.push_back(keys.back());
        value.value = setting_value;

        keys.pop_back();

        block.key = keys;
        block.values.push_back(value);

        blocks.push_back(block);
      }
    }

    pipe = vistk::bake_pipe_blocks(blocks);

    conf = vistk::extract_configuration(blocks);
  }

  if (!pipe)
  {
    std::cerr << "Error: Unable to bake pipeline" << std::endl;

    return 1;
  }

  pipe->setup_pipeline();

  vistk::schedule_registry::type_t schedule_type = vistk::schedule_registry::default_type;

  if (vm.count("schedule"))
  {
    schedule_type = vm["schedule"].as<vistk::schedule_registry::type_t>();
  }

  vistk::config_t const schedule_config = conf->subblock(schedule_block + vistk::config::block_sep + schedule_type);

  vistk::schedule_registry_t reg = vistk::schedule_registry::self();

  vistk::schedule_t schedule = reg->create_schedule(schedule_type, schedule_config, pipe);

  if (!schedule)
  {
    std::cerr << "Error: Unable to create schedule" << std::endl;

    return 1;
  }

  schedule->start();
  schedule->wait();

  return 0;
}

po::options_description
make_options()
{
  po::options_description desc;

  desc.add_options()
    ("help,h", "output help message and quit")
    ("pipeline,p", po::value<vistk::path_t>(), "pipeline")
    ("config,c", po::value<vistk::paths_t>(), "supplemental configuration file")
    ("setting,s", po::value<std::vector<std::string> >(), "additional configuration")
    ("include,I", po::value<vistk::paths_t>(), "configuration include path")
    ("schedule,S", po::value<vistk::schedule_registry::type_t>(), "schedule type")
  ;

  return desc;
}

void
usage(po::options_description const& options)
{
  std::cerr << options << std::endl;

  exit(1);
}
<|endoftext|>


<commit_before>#include "UpdaterWindow.h"

#include "../3RVX/3RVX.h"
#include "../3RVX/Logger.h"
#include "../3RVX/CommCtl.h"
#include "../3RVX/NotifyIcon.h"
#include "resource.h"

UpdaterWindow::UpdaterWindow() :
Window(L"3RVX-UpdateWindow") {
    HRESULT hr = LoadIconMetric(
        Window::InstanceHandle(),
        MAKEINTRESOURCE(IDI_MAINICON),
        LIM_SMALL,
        &_icon);
}

LRESULT UpdaterWindow::WndProc(
    HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {

    if (message == _3RVX::WM_3RVX_SETTINGSCTRL) {
        switch (wParam) {
        case _3RVX::MSG_UPDATEICON:
            CLOG(L"Received request to activate window from external program");
            new NotifyIcon(Window::Handle(), L"Update Available", _icon);
            break;
        }

        return Window::WndProc(hWnd, message, wParam, lParam);
    }
}
<commit_msg>Make sure all code paths return a value<commit_after>#include "UpdaterWindow.h"

#include "../3RVX/3RVX.h"
#include "../3RVX/Logger.h"
#include "../3RVX/CommCtl.h"
#include "../3RVX/NotifyIcon.h"
#include "resource.h"

UpdaterWindow::UpdaterWindow() :
Window(L"3RVX-UpdateWindow") {
    HRESULT hr = LoadIconMetric(
        Window::InstanceHandle(),
        MAKEINTRESOURCE(IDI_MAINICON),
        LIM_SMALL,
        &_icon);
}

LRESULT UpdaterWindow::WndProc(
    HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {

    if (message == _3RVX::WM_3RVX_SETTINGSCTRL) {
        switch (wParam) {
        case _3RVX::MSG_UPDATEICON:
            CLOG(L"Received request to activate window from external program");
            new NotifyIcon(Window::Handle(), L"Update Available", _icon);
            break;
        }

    }

    return Window::WndProc(hWnd, message, wParam, lParam);
}
<|endoftext|>


<commit_before>#include "rastertext.hpp"
#include "font_pango.hpp"
#include <cairo/cairo.h>
#include <pango/pangocairo.h>
#include <assert.h>
#include <stdlib.h>

static unsigned int round_up_pow2(unsigned int x)
{
    x -= 1;
    x |= x >> 16;
    x |= x >> 8;
    x |= x >> 4;
    x |= x >> 2;
    x |= x >> 1;
    return x + 1;
}

static PangoContext *getSharedContext()
{
    static cairo_t *cr = NULL;
    static PangoContext *context = NULL;
    if (!cr) {
        cairo_surface_t *surf =
            cairo_image_surface_create(CAIRO_FORMAT_A8, 1, 1);
        assert(surf);
        cr = cairo_create(surf);
    }
    if (!context) {
        context = pango_cairo_create_context(cr);
        assert(context);
    } else {
        pango_cairo_update_context(cr, context);
    }
    return context;
}

void RasterText::loadImage(void **data, unsigned int *width,
                           unsigned int *height)
{
    PangoContext *context = getSharedContext();
    PangoLayout *layout = pango_layout_new(context);
    if (font_.info_) {
        PangoFontDescription *desc = font_.info_->desc;
        if (desc)
            pango_layout_set_font_description(layout, desc);
    }
    PangoAlignment alignment = PANGO_ALIGN_LEFT;
    switch (alignment_) {
    case Left: alignment = PANGO_ALIGN_LEFT; break;
    case Center: alignment = PANGO_ALIGN_CENTER; break;
    case Right: alignment = PANGO_ALIGN_RIGHT; break;
    }
    pango_layout_set_alignment(layout, alignment);
    pango_layout_set_text(layout, text_.data(), text_.size());
    int baseline = pango_layout_get_baseline(layout) / PANGO_SCALE;
    PangoRectangle bounds;
    pango_layout_get_pixel_extents(layout, &bounds, NULL);
    vx1_ = bounds.x;
    vx2_ = bounds.x + bounds.width;
    vy1_ = baseline - bounds.y - bounds.height;
    vy2_ = baseline - bounds.y;
    unsigned int twidth = round_up_pow2(bounds.width);
    unsigned int theight = round_up_pow2(bounds.height);
    float xscale = 1.0f / twidth, yscale = 1.0f / theight;
    int xoff = (twidth - bounds.width) / 2;
    int yoff = (theight - bounds.height) / 2;
    tx1_ = xoff * xscale;
    tx2_ = (xoff + bounds.width) * xscale;
    ty1_ = (yoff + bounds.height) * yscale;
    ty2_ = yoff * yscale;
    unsigned int stride =
        cairo_format_stride_for_width(CAIRO_FORMAT_A8, twidth);
    void *ptr = calloc(stride, theight);
    if (!ptr)
        return;
    cairo_surface_t *surf = cairo_image_surface_create_for_data(
        static_cast<unsigned char *>(ptr), CAIRO_FORMAT_A8,
        twidth, theight, stride);
    cairo_t *cr = cairo_create(surf);
    cairo_translate(cr, xoff - bounds.x, yoff - bounds.y);
    pango_cairo_update_context(cr, context);
    pango_layout_context_changed(layout);
    pango_cairo_show_layout(cr, layout);
    g_object_unref(layout);
    cairo_destroy(cr);
    cairo_surface_destroy(surf);
    *data = ptr;
    *width = twidth;
    *height = theight;
}
<commit_msg>Fixed horizontal text alignment in RasterText class.<commit_after>#include "rastertext.hpp"
#include "font_pango.hpp"
#include <cairo/cairo.h>
#include <pango/pangocairo.h>
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>

static unsigned int round_up_pow2(unsigned int x)
{
    x -= 1;
    x |= x >> 16;
    x |= x >> 8;
    x |= x >> 4;
    x |= x >> 2;
    x |= x >> 1;
    return x + 1;
}

static PangoContext *getSharedContext()
{
    static cairo_t *cr = NULL;
    static PangoContext *context = NULL;
    if (!cr) {
        cairo_surface_t *surf =
            cairo_image_surface_create(CAIRO_FORMAT_A8, 1, 1);
        assert(surf);
        cr = cairo_create(surf);
    }
    if (!context) {
        context = pango_cairo_create_context(cr);
        assert(context);
    } else {
        pango_cairo_update_context(cr, context);
    }
    return context;
}

void RasterText::loadImage(void **data, unsigned int *width,
                           unsigned int *height)
{
    PangoContext *context = getSharedContext();
    PangoLayout *layout = pango_layout_new(context);
    if (font_.info_) {
        PangoFontDescription *desc = font_.info_->desc;
        if (desc)
            pango_layout_set_font_description(layout, desc);
    }
    PangoAlignment alignment = PANGO_ALIGN_LEFT;
    pango_layout_set_alignment(layout, alignment);
    pango_layout_set_text(layout, text_.data(), text_.size());
    int baseline = pango_layout_get_baseline(layout) / PANGO_SCALE;
    PangoRectangle bounds, lbounds;
    pango_layout_get_pixel_extents(layout, &bounds, &lbounds);
    float lxoff;
    switch (alignment_) {
    default:
    case Left:
        lxoff = bounds.x - lbounds.x;
        break;
    case Center:
        lxoff = bounds.x - (lbounds.x + lbounds.width / 2);
        break;
    case Right:
        lxoff = bounds.x - (lbounds.x + lbounds.width);
        break;
    }
    vx1_ = bounds.x + lxoff;
    vx2_ = bounds.x + bounds.width + lxoff;
    vy1_ = baseline - bounds.y - bounds.height;
    vy2_ = baseline - bounds.y;
    unsigned int twidth = round_up_pow2(bounds.width);
    unsigned int theight = round_up_pow2(bounds.height);
    float xscale = 1.0f / twidth, yscale = 1.0f / theight;
    int xoff = (twidth - bounds.width) / 2;
    int yoff = (theight - bounds.height) / 2;
    tx1_ = xoff * xscale;
    tx2_ = (xoff + bounds.width) * xscale;
    ty1_ = (yoff + bounds.height) * yscale;
    ty2_ = yoff * yscale;
    unsigned int stride =
        cairo_format_stride_for_width(CAIRO_FORMAT_A8, twidth);
    void *ptr = calloc(stride, theight);
    if (!ptr)
        return;
    cairo_surface_t *surf = cairo_image_surface_create_for_data(
        static_cast<unsigned char *>(ptr), CAIRO_FORMAT_A8,
        twidth, theight, stride);
    cairo_t *cr = cairo_create(surf);
    cairo_translate(cr, xoff - bounds.x, yoff - bounds.y);
    pango_cairo_update_context(cr, context);
    pango_layout_context_changed(layout);
    pango_cairo_show_layout(cr, layout);
    g_object_unref(layout);
    cairo_destroy(cr);
    cairo_surface_destroy(surf);
    *data = ptr;
    *width = twidth;
    *height = theight;
}
<|endoftext|>


<commit_before>// Copyright © 2017-2018 Dmitriy Khaustov
//
// 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.
//
// Author: Dmitriy Khaustov aka xDimon
// Contacts: khaustov.dm@gmail.com
// File created on: 2017.05.30

// PercentEncoding.cpp

#include "PercentEncoding.hpp"

#include <stdexcept>
#include <sstream>
#include <iomanip>

// unreserved
static const std::string unreserved =
	"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
		"abcdefghijklmnopqrstuvwxyz"
		"0123456789"
		"-_.~";

// reserved
static const std::string reserved =
	"!*'();:@&=+$,/?%#[]";

inline static bool need_encode(char c)
{
	if (unreserved.find(c) != std::string::npos)
	{
		return false;
	}
	if (reserved.find(c) != std::string::npos)
	{
		return true;
	}
	return true;
}

static int decodePercentEscapedByte(std::istringstream& iss)
{
	auto c = iss.get();
	if (c != '%')
	{
		throw std::runtime_error("Wrong token for start percent-encoded sequence");
	}

	int result = 0;

	if (iss.eof())
	{
		throw std::runtime_error("Unxpected end of data during try parse percent-encoded symbol");
	}
	c = iss.get();
	if (c >= '0' && c <= '9')
	{
		result = c - '0';
	}
	else if (c >= 'a' && c <= 'f')
	{
		result = 10 + c - 'a';
	}
	else if (c >= 'A' && c <= 'F')
	{
		result = 10 + c - 'A';
	}
	else if (c == -1)
	{
		throw std::runtime_error("Unxpected end of data during try parse percent-encoded symbol");
	}
	else
	{
		throw std::runtime_error("Wrong percent-encoded symbol");
	}

	if (iss.eof())
	{
		throw std::runtime_error("Unxpected end of data during try parse percent-encoded symbol");
	}
	c = iss.get();
	if (c >= '0' && c <= '9')
	{
		result = (result << 4) | (c - '0');
	}
	else if (c >= 'a' && c <= 'f')
	{
		result = (result << 4) | (10 + c - 'a');
	}
	else if (c >= 'A' && c <= 'F')
	{
		result = (result << 4) | (10 + c - 'A');
	}
	else if (c == -1)
	{
		throw std::runtime_error("Unxpected end of data during try parse percent-encoded symbol");
	}
	else
	{
		throw std::runtime_error("Wrong percent-encoded symbol");
	}

	return result;
}

static uint32_t decodePercentEscaped(std::istringstream& iss, bool& isUtf8)
{
	auto c = decodePercentEscapedByte(iss);

	if (!isUtf8)
	{
		return static_cast<uint32_t>(c);
	}

	int bytes;
	uint32_t symbol = 0;
	if ((c & 0b11111100) == 0b11111100)
	{
		bytes = 6;
		symbol = static_cast<uint8_t>(c) & static_cast<uint8_t>(0b1);
	}
	else if ((c & 0b11111000) == 0b11111000)
	{
		bytes = 5;
		symbol = static_cast<uint8_t>(c) & static_cast<uint8_t>(0b11);
	}
	else if ((c & 0b11110000) == 0b11110000)
	{
		bytes = 4;
		symbol = static_cast<uint8_t>(c) & static_cast<uint8_t>(0b111);
	}
	else if ((c & 0b11100000) == 0b11100000)
	{
		bytes = 3;
		symbol = static_cast<uint8_t>(c) & static_cast<uint8_t>(0b1111);
	}
	else if ((c & 0b11000000) == 0b11000000)
	{
		bytes = 2;
		symbol = static_cast<uint8_t>(c) & static_cast<uint8_t>(0b11111);
	}
	else if ((c & 0b10000000) == 0b00000000)
	{
		return static_cast<uint8_t>(c) & static_cast<uint8_t>(0b1111111);
	}
	else
	{
		isUtf8 = false;
		return static_cast<uint32_t>(c);
	}

	auto fc = c;
	auto p = iss.tellg();

	while (--bytes > 0)
	{
		if (iss.eof())
		{
			isUtf8 = false;
			return static_cast<uint32_t>(fc);
		}
		try
		{
			c = decodePercentEscapedByte(iss);
		}
		catch(...)
		{
			iss.clear(iss.goodbit);
			iss.seekg(p);
			return static_cast<uint32_t>(fc);
		}
		if ((c & 0b11000000) != 0b10000000)
		{
			iss.clear(iss.goodbit);
			iss.seekg(p);
			return static_cast<uint32_t>(fc);
		}
		symbol = (symbol << 6) | (c & 0b0011'1111);
	}

	return symbol;
}

std::string PercentEncoding::decode(const std::string& input)
{
	std::istringstream iss(input);
	std::ostringstream oss;
	bool isUtf8 = true;

	while (!iss.eof())
	{
		int c = iss.peek();
		if (c == '%')
		{
			auto symbol = decodePercentEscaped(iss, isUtf8);

			if (symbol <= 0b0111'1111) // 7bit -> 1byte
			{
				oss.put(static_cast<uint8_t>(symbol));
			}
			else if (symbol <= 0b0111'1111'1111) // 11bit -> 2byte
			{
				oss.put(static_cast<uint8_t>(0b1100'0000 | (0b0001'1111 & (symbol >> 6))));
				oss.put(static_cast<uint8_t>(0b1000'0000 | (0b0011'1111 & (symbol >> 0))));
			}
			else if (symbol <= 0b1111'1111'1111'1111) // 16bit -> 3byte
			{
				oss.put(static_cast<uint8_t>(0b1110'0000 | (0b0000'1111 & (symbol >> 12))));
				oss.put(static_cast<uint8_t>(0b1000'0000 | (0b0011'1111 & (symbol >> 6))));
				oss.put(static_cast<uint8_t>(0b1000'0000 | (0b0011'1111 & (symbol >> 0))));
			}
			else if (symbol <= 0b0001'1111'1111'1111'1111'1111) // 21bit -> 4byte
			{
				oss.put(static_cast<uint8_t>(0b1111'0000 | (0b0000'0111 & (symbol >> 18))));
				oss.put(static_cast<uint8_t>(0b1000'0000 | (0b0011'1111 & (symbol >> 12))));
				oss.put(static_cast<uint8_t>(0b1000'0000 | (0b0011'1111 & (symbol >> 6))));
				oss.put(static_cast<uint8_t>(0b1000'0000 | (0b0011'1111 & (symbol >> 0))));
			}
			else if (symbol <= 0b0011'1111'1111'1111'1111'1111'1111) // 26bit -> 5byte
			{
				oss.put(static_cast<uint8_t>(0b1111'1000 | (0b0000'0011 & (symbol >> 24))));
				oss.put(static_cast<uint8_t>(0b1000'0000 | (0b0011'1111 & (symbol >> 18))));
				oss.put(static_cast<uint8_t>(0b1000'0000 | (0b0011'1111 & (symbol >> 12))));
				oss.put(static_cast<uint8_t>(0b1000'0000 | (0b0011'1111 & (symbol >> 6))));
				oss.put(static_cast<uint8_t>(0b1000'0000 | (0b0011'1111 & (symbol >> 0))));
			}
			else if (symbol <= 0b0111'1111'1111'1111'1111'1111'1111'1111) // 31bit -> 6byte
			{
				oss.put(static_cast<uint8_t>(0b1111'1100 | (0b0000'0001 & (symbol >> 30))));
				oss.put(static_cast<uint8_t>(0b1000'0000 | (0b0011'1111 & (symbol >> 24))));
				oss.put(static_cast<uint8_t>(0b1000'0000 | (0b0011'1111 & (symbol >> 18))));
				oss.put(static_cast<uint8_t>(0b1000'0000 | (0b0011'1111 & (symbol >> 12))));
				oss.put(static_cast<uint8_t>(0b1000'0000 | (0b0011'1111 & (symbol >> 6))));
				oss.put(static_cast<uint8_t>(0b1000'0000 | (0b0011'1111 & (symbol >> 0))));
			}
		}
		else if (c == -1)
		{
			break;
		}
		else
		{
			iss.ignore();
			oss.put(static_cast<uint8_t>(c));
		}
	}

	return std::move(oss.str());
}

std::string PercentEncoding::encode(const std::string& input)
{
	std::istringstream iss(input);
	std::ostringstream oss;

	while (!iss.eof())
	{
		auto c = iss.get();
		if (c == -1)
		{
			break;
		}
		if (need_encode(static_cast<uint8_t>(c)))
		{
			oss << "%"
				<< std::uppercase
				<< std::setfill('0')
				<< std::setw(2)
				<< std::hex
				<< c;
		}
		else
		{
			oss.put(static_cast<uint8_t>(c));
		}
	}

	return std::move(oss.str());
}
<commit_msg>Little fix in percent-encoding<commit_after>// Copyright © 2017-2018 Dmitriy Khaustov
//
// 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.
//
// Author: Dmitriy Khaustov aka xDimon
// Contacts: khaustov.dm@gmail.com
// File created on: 2017.05.30

// PercentEncoding.cpp

#include "PercentEncoding.hpp"

#include <stdexcept>
#include <sstream>
#include <iomanip>

// unreserved
static const std::string unreserved(
	"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
	"abcdefghijklmnopqrstuvwxyz"
	"0123456789"
	"-_.~"
);

// reserved
static const std::string reserved(
	"!*'();:@&=+$,/?#[]"
);

inline static bool need_encode(const char c)
{
	if (unreserved.find(c) != std::string::npos)
	{
		return false;
	}
	if (reserved.find(c) != std::string::npos)
	{
		return true;
	}
	if (c == '%')
	{
		return true;
	}
	return true;
}

static int decodePercentEscapedByte(std::istringstream& iss)
{
	auto c = iss.get();
	if (c != '%')
	{
		throw std::runtime_error("Wrong token for start percent-encoded sequence");
	}

	int result = 0;

	if (iss.eof())
	{
		throw std::runtime_error("Unxpected end of data during try parse percent-encoded symbol");
	}
	c = iss.get();
	if (c >= '0' && c <= '9')
	{
		result = c - '0';
	}
	else if (c >= 'a' && c <= 'f')
	{
		result = 10 + c - 'a';
	}
	else if (c >= 'A' && c <= 'F')
	{
		result = 10 + c - 'A';
	}
	else if (c == -1)
	{
		throw std::runtime_error("Unxpected end of data during try parse percent-encoded symbol");
	}
	else
	{
		throw std::runtime_error("Wrong percent-encoded symbol");
	}

	if (iss.eof())
	{
		throw std::runtime_error("Unxpected end of data during try parse percent-encoded symbol");
	}
	c = iss.get();
	if (c >= '0' && c <= '9')
	{
		result = (result << 4) | (c - '0');
	}
	else if (c >= 'a' && c <= 'f')
	{
		result = (result << 4) | (10 + c - 'a');
	}
	else if (c >= 'A' && c <= 'F')
	{
		result = (result << 4) | (10 + c - 'A');
	}
	else if (c == -1)
	{
		throw std::runtime_error("Unxpected end of data during try parse percent-encoded symbol");
	}
	else
	{
		throw std::runtime_error("Wrong percent-encoded symbol");
	}

	return result;
}

static uint32_t decodePercentEscaped(std::istringstream& iss, bool& isUtf8)
{
	auto c = decodePercentEscapedByte(iss);

	if (!isUtf8)
	{
		return static_cast<uint32_t>(c);
	}

	int bytes;
	uint32_t symbol = 0;
	if ((c & 0b11111100) == 0b11111100)
	{
		bytes = 6;
		symbol = static_cast<uint8_t>(c) & static_cast<uint8_t>(0b1);
	}
	else if ((c & 0b11111000) == 0b11111000)
	{
		bytes = 5;
		symbol = static_cast<uint8_t>(c) & static_cast<uint8_t>(0b11);
	}
	else if ((c & 0b11110000) == 0b11110000)
	{
		bytes = 4;
		symbol = static_cast<uint8_t>(c) & static_cast<uint8_t>(0b111);
	}
	else if ((c & 0b11100000) == 0b11100000)
	{
		bytes = 3;
		symbol = static_cast<uint8_t>(c) & static_cast<uint8_t>(0b1111);
	}
	else if ((c & 0b11000000) == 0b11000000)
	{
		bytes = 2;
		symbol = static_cast<uint8_t>(c) & static_cast<uint8_t>(0b11111);
	}
	else if ((c & 0b10000000) == 0b00000000)
	{
		return static_cast<uint8_t>(c) & static_cast<uint8_t>(0b1111111);
	}
	else
	{
		isUtf8 = false;
		return static_cast<uint32_t>(c);
	}

	auto fc = c;
	auto p = iss.tellg();

	while (--bytes > 0)
	{
		if (iss.eof())
		{
			isUtf8 = false;
			return static_cast<uint32_t>(fc);
		}
		try
		{
			c = decodePercentEscapedByte(iss);
		}
		catch(...)
		{
			iss.clear(iss.goodbit);
			iss.seekg(p);
			return static_cast<uint32_t>(fc);
		}
		if ((c & 0b11000000) != 0b10000000)
		{
			iss.clear(iss.goodbit);
			iss.seekg(p);
			return static_cast<uint32_t>(fc);
		}
		symbol = (symbol << 6) | (c & 0b0011'1111);
	}

	return symbol;
}

std::string PercentEncoding::decode(const std::string& input)
{
	std::istringstream iss(input);
	std::ostringstream oss;
	bool isUtf8 = true;

	while (!iss.eof())
	{
		int c = iss.peek();
		if (c == '%')
		{
			auto symbol = decodePercentEscaped(iss, isUtf8);

			if (symbol <= 0b0111'1111) // 7bit -> 1byte
			{
				oss.put(static_cast<uint8_t>(symbol));
			}
			else if (symbol <= 0b0111'1111'1111) // 11bit -> 2byte
			{
				oss.put(static_cast<uint8_t>(0b1100'0000 | (0b0001'1111 & (symbol >> 6))));
				oss.put(static_cast<uint8_t>(0b1000'0000 | (0b0011'1111 & (symbol >> 0))));
			}
			else if (symbol <= 0b1111'1111'1111'1111) // 16bit -> 3byte
			{
				oss.put(static_cast<uint8_t>(0b1110'0000 | (0b0000'1111 & (symbol >> 12))));
				oss.put(static_cast<uint8_t>(0b1000'0000 | (0b0011'1111 & (symbol >> 6))));
				oss.put(static_cast<uint8_t>(0b1000'0000 | (0b0011'1111 & (symbol >> 0))));
			}
			else if (symbol <= 0b0001'1111'1111'1111'1111'1111) // 21bit -> 4byte
			{
				oss.put(static_cast<uint8_t>(0b1111'0000 | (0b0000'0111 & (symbol >> 18))));
				oss.put(static_cast<uint8_t>(0b1000'0000 | (0b0011'1111 & (symbol >> 12))));
				oss.put(static_cast<uint8_t>(0b1000'0000 | (0b0011'1111 & (symbol >> 6))));
				oss.put(static_cast<uint8_t>(0b1000'0000 | (0b0011'1111 & (symbol >> 0))));
			}
			else if (symbol <= 0b0011'1111'1111'1111'1111'1111'1111) // 26bit -> 5byte
			{
				oss.put(static_cast<uint8_t>(0b1111'1000 | (0b0000'0011 & (symbol >> 24))));
				oss.put(static_cast<uint8_t>(0b1000'0000 | (0b0011'1111 & (symbol >> 18))));
				oss.put(static_cast<uint8_t>(0b1000'0000 | (0b0011'1111 & (symbol >> 12))));
				oss.put(static_cast<uint8_t>(0b1000'0000 | (0b0011'1111 & (symbol >> 6))));
				oss.put(static_cast<uint8_t>(0b1000'0000 | (0b0011'1111 & (symbol >> 0))));
			}
			else if (symbol <= 0b0111'1111'1111'1111'1111'1111'1111'1111) // 31bit -> 6byte
			{
				oss.put(static_cast<uint8_t>(0b1111'1100 | (0b0000'0001 & (symbol >> 30))));
				oss.put(static_cast<uint8_t>(0b1000'0000 | (0b0011'1111 & (symbol >> 24))));
				oss.put(static_cast<uint8_t>(0b1000'0000 | (0b0011'1111 & (symbol >> 18))));
				oss.put(static_cast<uint8_t>(0b1000'0000 | (0b0011'1111 & (symbol >> 12))));
				oss.put(static_cast<uint8_t>(0b1000'0000 | (0b0011'1111 & (symbol >> 6))));
				oss.put(static_cast<uint8_t>(0b1000'0000 | (0b0011'1111 & (symbol >> 0))));
			}
		}
		else if (c == -1)
		{
			break;
		}
		else
		{
			iss.ignore();
			oss.put(static_cast<uint8_t>(c));
		}
	}

	return oss.str();
}

std::string PercentEncoding::encode(const std::string& input)
{
	std::istringstream iss(input);
	std::ostringstream oss;

	while (!iss.eof())
	{
		auto c = iss.get();
		if (c == -1)
		{
			break;
		}
		if (need_encode(static_cast<uint8_t>(c)))
		{
			oss << "%"
				<< std::uppercase
				<< std::setfill('0')
				<< std::setw(2)
				<< std::hex
				<< c;
		}
		else
		{
			oss.put(static_cast<uint8_t>(c));
		}
	}

	return oss.str();
}
<|endoftext|>


<commit_before>#ifndef STAN_MATH_PRIM_SCAL_FUN_DISTANCE_HPP
#define STAN_MATH_PRIM_SCAL_FUN_DISTANCE_HPP

#include <stan/math/prim/scal/err/check_finite.hpp>
#include <stan/math/prim/scal/fun/abs.hpp>
#include <stan/math/prim/scal/meta/return_type.hpp>

namespace stan {
namespace math {

/**
 * Returns the distance between two scalars.
 *
 * @param x1 First scalar.
 * @param x2 Second scalar.
 * @return Distance between two scalars
 * @throw std::domain_error If the arguments are not finite.
 */
template <typename T1, typename T2>
inline typename return_type<T1, T2>::type distance(
    const T1& x1, const T2& x2) {
  check_finite("distance", "x1", x1);
  check_finite("distance", "x2", x2);
  return abs(x1 - x2);
}
}  // namespace math
}  // namespace stan
#endif
<commit_msg>[Jenkins] auto-formatting by clang-format version 5.0.2-svn328729-1~exp1~20180406212027.91 (branches/release_50)<commit_after>#ifndef STAN_MATH_PRIM_SCAL_FUN_DISTANCE_HPP
#define STAN_MATH_PRIM_SCAL_FUN_DISTANCE_HPP

#include <stan/math/prim/scal/err/check_finite.hpp>
#include <stan/math/prim/scal/fun/abs.hpp>
#include <stan/math/prim/scal/meta/return_type.hpp>

namespace stan {
namespace math {

/**
 * Returns the distance between two scalars.
 *
 * @param x1 First scalar.
 * @param x2 Second scalar.
 * @return Distance between two scalars
 * @throw std::domain_error If the arguments are not finite.
 */
template <typename T1, typename T2>
inline typename return_type<T1, T2>::type distance(const T1& x1, const T2& x2) {
  check_finite("distance", "x1", x1);
  check_finite("distance", "x2", x2);
  return abs(x1 - x2);
}
}  // namespace math
}  // namespace stan
#endif
<|endoftext|>


<commit_before>/* Copyright 2017 The TensorFlow Authors. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/

#include "tensorflow/core/grappler/costs/analytical_cost_estimator.h"

#include <limits>
#include <unordered_map>

#include "tensorflow/core/framework/tensor.pb.h"  // NOLINT
#include "tensorflow/core/framework/tensor_shape.pb.h"
#include "tensorflow/core/graph/types.h"
#include "tensorflow/core/grappler/costs/graph_properties.h"
#include "tensorflow/core/grappler/costs/op_performance_data.pb.h"
#include "tensorflow/core/grappler/costs/utils.h"
#include "tensorflow/core/grappler/costs/virtual_placer.h"
#include "tensorflow/core/grappler/costs/virtual_scheduler.h"
#include "tensorflow/core/grappler/grappler_item.h"
#include "tensorflow/core/grappler/op_types.h"
#include "tensorflow/core/grappler/utils.h"

namespace tensorflow {
namespace grappler {

namespace {

// Helper function in PredictCosts() to add cost node to cost_graph.
void AddCostNode(ReadyNodeManager* node_manager, const OpContext& op_context,
                 int node_id, const Costs& node_costs,
                 gtl::FlatMap<string, CostGraphDef::Node*>* name_to_cost_node,
                 gtl::FlatMap<string, int>* name_to_id,
                 CostGraphDef* cost_graph) {
  const string& op_name = op_context.name;
  auto it = name_to_cost_node->find(op_name);
  CostGraphDef::Node* node;
  if (it != name_to_cost_node->end()) {
    node = it->second;
    node->clear_input_info();
    node->clear_output_info();
  } else {
    node = cost_graph->add_node();
    (*name_to_cost_node)[op_name] = node;
    node->set_name(op_name);
    node->set_id(node_id);
    (*name_to_id)[node->name()] = node->id();
  }
  // For nodes we have seen before (e.g. Merge nodes are executed twice by
  // VirtualScheduler), the following fields will be overwritten/updated.
  node->set_device(op_context.device_name);
  node->set_compute_cost(node_costs.execution_time.asMicroSeconds().count());
  node->set_compute_time(node_costs.compute_time.asMicroSeconds().count());
  node->set_memory_time(node_costs.memory_time.asMicroSeconds().count());
  node->set_inaccurate(node_costs.inaccurate);

  for (const string& input : node_manager->GetCurrNode()->input()) {
    int input_port;
    string input_name = ParseNodeName(input, &input_port);

    // All inputs should have been seen already unless this is a Merge node.
    if (name_to_id->find(input_name) == name_to_id->end()) {
      if (!IsMerge(*node_manager->GetCurrNode()))
        VLOG(1) << "input: " << input
                << " not found for non-Merge node: " << op_name;

      // For Merge node, some of inputs may not be seen before
      // For example, for a typical while loop in tensorflow, Merge node
      // will be executed twice by VirtualScheduler (one for Enter, the
      // other for NextIteration), so eventually both inputs will be added.
      continue;
    }

    if (IsControlInput(input)) {
      node->add_control_input(name_to_id->at(input_name));
    } else {
      auto* input_info = node->add_input_info();
      input_info->set_preceding_node(name_to_id->at(input_name));
      input_info->set_preceding_port(input_port);
    }
  }

  for (const auto& output : op_context.op_info.outputs()) {
    auto output_info = node->add_output_info();
    output_info->set_alias_input_port(-1);
    output_info->set_dtype(output.dtype());
    *output_info->mutable_shape() = output.shape();

    int64 size = DataTypeSize(output.dtype());
    for (const auto& dim : output.shape().dim()) {
      size *= std::max<int64>(1, dim.size());
    }
    output_info->set_size(size);
  }
}

}  // namespace

AnalyticalCostEstimator::AnalyticalCostEstimator(
    Cluster* cluster, bool use_static_shapes,
    bool use_aggressive_shape_inference)
    : AnalyticalCostEstimator(
          cluster, absl::make_unique<OpLevelCostEstimator>(),
          ReadyNodeManagerFactory("FirstReady"), use_static_shapes,
          use_aggressive_shape_inference) {}

AnalyticalCostEstimator::AnalyticalCostEstimator(
    Cluster* cluster, std::unique_ptr<OpLevelCostEstimator> node_estimator,
    std::unique_ptr<ReadyNodeManager> node_manager, bool use_static_shapes,
    bool use_aggressive_shape_inference)
    : node_estimator_(std::move(node_estimator)),
      node_manager_(std::move(node_manager)),
      use_static_shapes_(use_static_shapes),
      use_aggressive_shape_inference_(use_aggressive_shape_inference) {
  scheduler_ = absl::make_unique<VirtualScheduler>(
      use_static_shapes_, use_aggressive_shape_inference_, cluster,
      node_manager_.get(),
      absl::make_unique<VirtualPlacer>(cluster->GetDevices()));
}

AnalyticalCostEstimator::AnalyticalCostEstimator(
    Cluster* cluster, std::unique_ptr<OpLevelCostEstimator> node_estimator,
    std::unique_ptr<ReadyNodeManager> node_manager,
    std::unique_ptr<VirtualPlacer> placer, bool use_static_shapes,
    bool use_aggressive_shape_inference)
    : node_estimator_(std::move(node_estimator)),
      node_manager_(std::move(node_manager)),
      use_static_shapes_(use_static_shapes),
      use_aggressive_shape_inference_(use_aggressive_shape_inference) {
  scheduler_ = absl::make_unique<VirtualScheduler>(
      use_static_shapes_, use_aggressive_shape_inference_, cluster,
      node_manager_.get(), std::move(placer));
}

Status AnalyticalCostEstimator::Initialize(const GrapplerItem& item) {
  item_ = &item;
  return Status::OK();
}

Status AnalyticalCostEstimator::PredictCosts(const GraphDef& optimized_graph,
                                             RunMetadata* run_metadata,
                                             Costs* costs) const {
  std::unique_ptr<GrapplerItem> item_storage;
  const GrapplerItem* item;
  // Many callers to PredictCosts() pass the same optimized_graph as was used
  // to initialize the estimator.
  if (&optimized_graph == &item_->graph) {
    item = item_;
  } else {
    GraphDef graph_copy = optimized_graph;
    item_storage = absl::make_unique<GrapplerItem>(
        item_->WithGraph(std::move(graph_copy)));
    item = item_storage.get();
  }

  auto status = scheduler_->Init(item);
  if (!status.ok()) {
    if (costs) {
      costs->execution_time = Costs::Duration::max();
    }
    return status;
  }

  gtl::FlatMap<string, CostGraphDef::Node*> name_to_cost_node;
  CostGraphDef* cost_graph = nullptr;
  if (run_metadata) {
    cost_graph = run_metadata->mutable_cost_graph();
    // TODO(pcma): Clear nodes in cost_graph after we make sure we always pass
    // in an empty cost_graph (a non-empty but incomplete cost_graph will cause
    // problems, e.g., no node_id in cost_graph).
    for (auto& node : *cost_graph->mutable_node()) {
      name_to_cost_node[node.name()] = &node;
    }
  }
  std::vector<string> inaccurate_nodes;
  int nodes_executed = 0;
  int node_id = 0;
  gtl::FlatMap<string, int> name_to_id;

  Costs node_costs;
  do {
    ++nodes_executed;
    OpContext op_context = scheduler_->GetCurrNode();
    node_costs = node_estimator_->PredictCosts(op_context);

    if (node_costs.inaccurate) {
      inaccurate_nodes.push_back(op_context.name);
      if (node_costs.num_ops_with_unknown_shapes > 0)
        VLOG(4) << op_context.name << " has "
                << node_costs.num_ops_with_unknown_shapes << " unknown shapes";
    }

    // TODO(pcma): Add unit tests for generating CostGraphDef.
    if (cost_graph) {
      AddCostNode(node_manager_.get(), op_context, node_id++, node_costs,
                  &name_to_cost_node, &name_to_id, cost_graph);
    }
  } while (scheduler_->MarkCurrNodeExecuted(node_costs));

  VLOG(1) << inaccurate_nodes.size() << " out of " << nodes_executed
          << " nodes have inaccurate time estimation";
  if (VLOG_IS_ON(3)) {
    for (const auto& node : inaccurate_nodes) {
      VLOG(4) << "Node with inaccurate time estimation: " << node;
    }
  }

  // run_metadata gets step_stats and partition_graphs from Summary.
  if (costs) {
    *costs = scheduler_->Summary(run_metadata);
  } else if (run_metadata) {
    scheduler_->GenerateRunMetadata(run_metadata);
  }

  if (VLOG_IS_ON(1)) {
    bool verbose = VLOG_IS_ON(2);
    if (run_metadata) {
      VLOG(1) << GetStatsStringFromRunMetadata(*run_metadata, verbose);
    } else {
      RunMetadata run_metadata;
      scheduler_->GenerateRunMetadata(&run_metadata);
      VLOG(1) << GetStatsStringFromRunMetadata(run_metadata, verbose);
    }
  }

  return Status::OK();
}

}  // end namespace grappler
}  // end namespace tensorflow
<commit_msg>Add memory usage details to the cost graph.<commit_after>/* Copyright 2017 The TensorFlow Authors. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/

#include "tensorflow/core/grappler/costs/analytical_cost_estimator.h"

#include <limits>
#include <unordered_map>

#include "tensorflow/core/framework/tensor.pb.h"  // NOLINT
#include "tensorflow/core/framework/tensor_shape.pb.h"
#include "tensorflow/core/graph/types.h"
#include "tensorflow/core/grappler/costs/graph_properties.h"
#include "tensorflow/core/grappler/costs/op_performance_data.pb.h"
#include "tensorflow/core/grappler/costs/utils.h"
#include "tensorflow/core/grappler/costs/virtual_placer.h"
#include "tensorflow/core/grappler/costs/virtual_scheduler.h"
#include "tensorflow/core/grappler/grappler_item.h"
#include "tensorflow/core/grappler/op_types.h"
#include "tensorflow/core/grappler/utils.h"

namespace tensorflow {
namespace grappler {

namespace {

// Helper function in PredictCosts() to add cost node to cost_graph.
void AddCostNode(ReadyNodeManager* node_manager, const OpContext& op_context,
                 int node_id, const Costs& node_costs,
                 gtl::FlatMap<string, CostGraphDef::Node*>* name_to_cost_node,
                 gtl::FlatMap<string, int>* name_to_id,
                 CostGraphDef* cost_graph) {
  const string& op_name = op_context.name;
  auto it = name_to_cost_node->find(op_name);
  CostGraphDef::Node* node;
  if (it != name_to_cost_node->end()) {
    node = it->second;
    node->clear_input_info();
    node->clear_output_info();
  } else {
    node = cost_graph->add_node();
    (*name_to_cost_node)[op_name] = node;
    node->set_name(op_name);
    node->set_id(node_id);
    (*name_to_id)[node->name()] = node->id();
  }
  // For nodes we have seen before (e.g. Merge nodes are executed twice by
  // VirtualScheduler), the following fields will be overwritten/updated.
  node->set_device(op_context.device_name);
  node->set_compute_cost(node_costs.execution_time.asMicroSeconds().count());
  node->set_compute_time(node_costs.compute_time.asMicroSeconds().count());
  node->set_memory_time(node_costs.memory_time.asMicroSeconds().count());
  node->set_temporary_memory_size(node_costs.temporary_memory);
  node->set_persistent_memory_size(node_costs.persistent_memory);
  node->set_inaccurate(node_costs.inaccurate);

  for (const string& input : node_manager->GetCurrNode()->input()) {
    int input_port;
    string input_name = ParseNodeName(input, &input_port);

    // All inputs should have been seen already unless this is a Merge node.
    if (name_to_id->find(input_name) == name_to_id->end()) {
      if (!IsMerge(*node_manager->GetCurrNode()))
        VLOG(1) << "input: " << input
                << " not found for non-Merge node: " << op_name;

      // For Merge node, some of inputs may not be seen before
      // For example, for a typical while loop in tensorflow, Merge node
      // will be executed twice by VirtualScheduler (one for Enter, the
      // other for NextIteration), so eventually both inputs will be added.
      continue;
    }

    if (IsControlInput(input)) {
      node->add_control_input(name_to_id->at(input_name));
    } else {
      auto* input_info = node->add_input_info();
      input_info->set_preceding_node(name_to_id->at(input_name));
      input_info->set_preceding_port(input_port);
    }
  }

  for (const auto& output : op_context.op_info.outputs()) {
    auto output_info = node->add_output_info();
    output_info->set_alias_input_port(-1);
    output_info->set_dtype(output.dtype());
    *output_info->mutable_shape() = output.shape();

    int64 size = DataTypeSize(output.dtype());
    for (const auto& dim : output.shape().dim()) {
      size *= std::max<int64>(1, dim.size());
    }
    output_info->set_size(size);
  }
}

}  // namespace

AnalyticalCostEstimator::AnalyticalCostEstimator(
    Cluster* cluster, bool use_static_shapes,
    bool use_aggressive_shape_inference)
    : AnalyticalCostEstimator(
          cluster, absl::make_unique<OpLevelCostEstimator>(),
          ReadyNodeManagerFactory("FirstReady"), use_static_shapes,
          use_aggressive_shape_inference) {}

AnalyticalCostEstimator::AnalyticalCostEstimator(
    Cluster* cluster, std::unique_ptr<OpLevelCostEstimator> node_estimator,
    std::unique_ptr<ReadyNodeManager> node_manager, bool use_static_shapes,
    bool use_aggressive_shape_inference)
    : node_estimator_(std::move(node_estimator)),
      node_manager_(std::move(node_manager)),
      use_static_shapes_(use_static_shapes),
      use_aggressive_shape_inference_(use_aggressive_shape_inference) {
  scheduler_ = absl::make_unique<VirtualScheduler>(
      use_static_shapes_, use_aggressive_shape_inference_, cluster,
      node_manager_.get(),
      absl::make_unique<VirtualPlacer>(cluster->GetDevices()));
}

AnalyticalCostEstimator::AnalyticalCostEstimator(
    Cluster* cluster, std::unique_ptr<OpLevelCostEstimator> node_estimator,
    std::unique_ptr<ReadyNodeManager> node_manager,
    std::unique_ptr<VirtualPlacer> placer, bool use_static_shapes,
    bool use_aggressive_shape_inference)
    : node_estimator_(std::move(node_estimator)),
      node_manager_(std::move(node_manager)),
      use_static_shapes_(use_static_shapes),
      use_aggressive_shape_inference_(use_aggressive_shape_inference) {
  scheduler_ = absl::make_unique<VirtualScheduler>(
      use_static_shapes_, use_aggressive_shape_inference_, cluster,
      node_manager_.get(), std::move(placer));
}

Status AnalyticalCostEstimator::Initialize(const GrapplerItem& item) {
  item_ = &item;
  return Status::OK();
}

Status AnalyticalCostEstimator::PredictCosts(const GraphDef& optimized_graph,
                                             RunMetadata* run_metadata,
                                             Costs* costs) const {
  std::unique_ptr<GrapplerItem> item_storage;
  const GrapplerItem* item;
  // Many callers to PredictCosts() pass the same optimized_graph as was used
  // to initialize the estimator.
  if (&optimized_graph == &item_->graph) {
    item = item_;
  } else {
    GraphDef graph_copy = optimized_graph;
    item_storage = absl::make_unique<GrapplerItem>(
        item_->WithGraph(std::move(graph_copy)));
    item = item_storage.get();
  }

  auto status = scheduler_->Init(item);
  if (!status.ok()) {
    if (costs) {
      costs->execution_time = Costs::Duration::max();
    }
    return status;
  }

  gtl::FlatMap<string, CostGraphDef::Node*> name_to_cost_node;
  CostGraphDef* cost_graph = nullptr;
  if (run_metadata) {
    cost_graph = run_metadata->mutable_cost_graph();
    // TODO(pcma): Clear nodes in cost_graph after we make sure we always pass
    // in an empty cost_graph (a non-empty but incomplete cost_graph will cause
    // problems, e.g., no node_id in cost_graph).
    for (auto& node : *cost_graph->mutable_node()) {
      name_to_cost_node[node.name()] = &node;
    }
  }
  std::vector<string> inaccurate_nodes;
  int nodes_executed = 0;
  int node_id = 0;
  gtl::FlatMap<string, int> name_to_id;

  Costs node_costs;
  do {
    ++nodes_executed;
    OpContext op_context = scheduler_->GetCurrNode();
    node_costs = node_estimator_->PredictCosts(op_context);

    if (node_costs.inaccurate) {
      inaccurate_nodes.push_back(op_context.name);
      if (node_costs.num_ops_with_unknown_shapes > 0)
        VLOG(4) << op_context.name << " has "
                << node_costs.num_ops_with_unknown_shapes << " unknown shapes";
    }

    // TODO(pcma): Add unit tests for generating CostGraphDef.
    if (cost_graph) {
      AddCostNode(node_manager_.get(), op_context, node_id++, node_costs,
                  &name_to_cost_node, &name_to_id, cost_graph);
    }
  } while (scheduler_->MarkCurrNodeExecuted(node_costs));

  VLOG(1) << inaccurate_nodes.size() << " out of " << nodes_executed
          << " nodes have inaccurate time estimation";
  if (VLOG_IS_ON(3)) {
    for (const auto& node : inaccurate_nodes) {
      VLOG(4) << "Node with inaccurate time estimation: " << node;
    }
  }

  // run_metadata gets step_stats and partition_graphs from Summary.
  if (costs) {
    *costs = scheduler_->Summary(run_metadata);
  } else if (run_metadata) {
    scheduler_->GenerateRunMetadata(run_metadata);
  }

  if (VLOG_IS_ON(1)) {
    bool verbose = VLOG_IS_ON(2);
    if (run_metadata) {
      VLOG(1) << GetStatsStringFromRunMetadata(*run_metadata, verbose);
    } else {
      RunMetadata run_metadata;
      scheduler_->GenerateRunMetadata(&run_metadata);
      VLOG(1) << GetStatsStringFromRunMetadata(run_metadata, verbose);
    }
  }

  return Status::OK();
}

}  // end namespace grappler
}  // end namespace tensorflow
<|endoftext|>


<commit_before>#include "ride/finddlg.h"

#include "ride/wx.h"
#include "ride/generated/ui.h"
#include "ride/wxutils.h"

#include "wx/stc/stc.h"
#include "ride/settings.h"
#include <wx/dir.h>
#include "ride/mainwindow.h"
#include "ride/fileedit.h"

class FindDlg : public ui::Find {
public:
  FindDlg(wxWindow* parent, const wxString& find, const ride::FindDlg& data, bool findd);

  const wxString GetText() const {
    return uiFindText->GetValue();
  }

  const int GetFlags();

  void ToData(ride::FindDlg& data) const;

  wxStyledTextCtrl* GetStc() {
    return m_scintilla1;
  }

  bool LookInCurrentFile() const {
    return uiLookIn->GetSelection() == 0;
  }

  bool IsRecursive() const {
    return uiIncludeSubFolders->GetValue();
  }

  const wxString getReplaceText() const {
    return uiReplaceText->GetValue();
  }

  bool KeepFilesOpen() const {
    return uiKeepFilesOpen->GetValue();
  }

protected:
  void OnCancel(wxCommandEvent& event);
  void OnOk(wxCommandEvent& event);
  void OnEnter(wxCommandEvent& event) {
    OnOk(event);
  }
};

FindDlg::FindDlg(wxWindow* parent, const wxString& find, const ride::FindDlg& data, bool findd)
  : ui::Find(parent, wxID_ANY)
{
  uiFindText->SetValue(find);
  uiFindText->SelectAll();
  uiFindText->SetFocus();

  uiLookIn->Append("Current file");
  uiLookIn->Append("This project");
  uiLookIn->SetSelection(0);

  uiFindTarget->Append("Normal text");
  uiFindTarget->Append("Regex");
  uiFindTarget->Append("Posix");

  uiIncludeSubFolders->SetValue(data.sub_folders());
  uiMatchCase->SetValue(data.match_case());
  uiMatchWholeWord->SetValue(data.match_whole_word());
  uiFindWordStart->SetValue(data.match_start());
  uiFileTypes->SetValue(data.file_types().c_str());
  uiFindTarget->SetSelection(data.target());

  uiReplaceStatic->Enable(findd==false);
  uiReplaceText->Enable(findd == false);
}

void FindDlg::ToData(ride::FindDlg& data) const {
  data.set_sub_folders(uiIncludeSubFolders->GetValue());
  data.set_match_case(uiMatchCase->GetValue());
  data.set_match_whole_word(uiMatchWholeWord->GetValue());
  data.set_match_start(uiFindWordStart->GetValue());
  data.set_file_types(uiFileTypes->GetValue());
  data.set_target(static_cast<::ride::FindDlgTarget>(uiFindTarget->GetSelection()));
}

void FindDlg::OnCancel(wxCommandEvent& event) {
  EndModal(wxID_CANCEL);
}

void FindDlg::OnOk(wxCommandEvent& event) {
  if (uiFindText->GetValue().length() <= 0) {
    ShowInfo(this, "Need to enter search text", "Missing Search Text");
    return;
  }
  EndModal(wxID_OK);
}

const int FindDlg::GetFlags() {
  int ret = 0;

  if (uiMatchCase->GetValue()) {
    ret |= wxSTC_FIND_MATCHCASE;
  }

  if (uiMatchWholeWord->GetValue()) {
    ret |= wxSTC_FIND_WHOLEWORD;
  }

  if (uiFindWordStart->GetValue()) {
    ret |= wxSTC_FIND_WORDSTART;
  }

  switch (uiFindTarget->GetSelection()) {
  case 0:
    break;
  case 1:
    ret |= wxSTC_FIND_REGEXP;
    break;
  case 2:
    ret |= wxSTC_FIND_POSIX;
    break;
  default:
    assert(false && "invalid selection");
    break;
  }

  return ret;
}

struct FindResult {
  FindResult(const wxString& f, const wxString& co, const int sl, const int sc, const int el, const int ec)
    : file(f)
    , content(co)
    , start_line(sl)
    , start_col(sc)
    , end_line(el)
    , end_col(ec)
  {
  }

  wxString file;
  wxString content;
  int start_line;
  int start_col;
  int end_line;
  int end_col;
};

int FindInStc(wxStyledTextCtrl* stc, const wxString& file, const wxString& text, int flags, std::vector<FindResult>* res, bool doReplace, const wxString& replaceText) {
  assert(res);
  assert(stc);
  int start_index = 0;
  int count = 0;
  while (true) {
    int end_index = 0;
    start_index = stc->FindText(start_index, stc->GetLength(), text, &end_index, flags);
    if (start_index == -1) return count;
    assert(start_index != end_index);
    const int start_line = stc->LineFromPosition(start_index);
    const int start_col = start_index - stc->PositionFromLine(start_line);
    const int end_line = stc->LineFromPosition(end_index);
    const int end_col = end_index - stc->PositionFromLine(end_line);
    res->push_back(FindResult(file, stc->GetLine(start_line).Trim(true).Trim(false), start_line+1, start_col+1, end_line+1, end_col+1));
    ++count;

    if (doReplace) {
      const bool useRegex = flags & wxSTC_FIND_REGEXP || flags & wxSTC_FIND_POSIX;
      const int change = useRegex
        ? stc->ReplaceTargetRE(replaceText)
       : stc->ReplaceTarget(replaceText);
      assert(change > 0);
      start_index = start_index + change;
    }
    else {
      start_index = end_index;
    }
  }

  return count;
}

void FindInFiles(MainWindow* parent, wxStyledTextCtrl* fallback, const wxString& file, const wxString& text, int flags, std::vector<FindResult>* res, bool doReplace, const wxString& replaceText, bool keepFilesOpen) {
  FileEdit* edit = parent->GetFile(file);
  wxStyledTextCtrl* stc = NULL;
  if (edit) {
    stc = edit->GetStc();
  }
  else {
    fallback->LoadFile(file);

    if (doReplace && keepFilesOpen) {
      int found = fallback->FindText(0, stc->GetLength(), text, NULL, flags);
      if (found > 0) {
        FileEdit* opened_edit = parent->OpenFile(file);
        stc = opened_edit->GetStc();
      }
    }
    if( stc == NULL ) {
      stc = fallback;
    }
  }
  assert(stc);
  int count = FindInStc(stc, file, text, flags, res, doReplace, replaceText);

  if (doReplace && count > 0 && stc == fallback) {
    if (false == stc->SaveFile(file)) {
      ShowError(parent, "Failed to save after replace!", "Error saving!");
    }
  }
}

bool ShowFindDlg(MainWindow* parent, const wxString& current_selection, const wxString& current_file, const wxString root_folder, wxStyledTextCtrl* output, bool find) {
  static ride::FindDlg find_dlg_data;
  FindDlg dlg(parent, current_selection, find_dlg_data, find);

  if (wxID_OK != dlg.ShowModal()) return false;
  dlg.ToData(find_dlg_data);

  std::vector<FindResult> results;
  wxString file_info = current_file;

  // we can't create a styled ctrl so we cheat by having a 0x0 widget on the find dlg
  // and use that for searching/replacing...
  wxStyledTextCtrl* fallback = dlg.GetStc();

  if (dlg.LookInCurrentFile()) {
    FindInFiles(parent, fallback, current_file, dlg.GetText(), dlg.GetFlags(), &results, find==false, dlg.getReplaceText(), dlg.KeepFilesOpen());
  }
  else {
    wxArrayString files;
    const wxString pattern = find_dlg_data.file_types();
    const size_t count = wxDir::GetAllFiles(root_folder, &files, pattern,
      dlg.IsRecursive() ? wxDIR_FILES | wxDIR_DIRS : wxDIR_FILES);
    file_info = wxString::Format("%d files in %s", count, root_folder);
    for (const auto file : files) {
      FindInFiles(parent, fallback, file, dlg.GetText(), dlg.GetFlags(), &results, find == false, dlg.getReplaceText(), dlg.KeepFilesOpen());
    }
  }

  const auto count = results.size();

  ClearOutput(output);
  WriteLine(output, wxString::Format("Searching for %s in %s", dlg.GetText(), file_info));
  WriteLine(output, wxString::Format("Found %d matches", count));
  WriteLine(output, "");
  for (auto res : results) {
    // try to format the same way rust related error looks like so we can reuse the parser code for both and get some synergy effects
    const wxString mess = wxString::Format("%s:%d : %d : %d : %d found: %s", res.file, res.start_line, res.start_col, res.end_line, res.end_col, res.content);
    WriteLine(output, mess);
  }

  return true;
}
<commit_msg>refacoring<commit_after>#include "ride/finddlg.h"

#include "ride/wx.h"
#include "ride/generated/ui.h"
#include "ride/wxutils.h"

#include "wx/stc/stc.h"
#include "ride/settings.h"
#include <wx/dir.h>
#include "ride/mainwindow.h"
#include "ride/fileedit.h"

class FindDlg : public ui::Find {
public:
  FindDlg(wxWindow* parent, const wxString& find, const ride::FindDlg& data, bool findd);

  const wxString GetText() const {
    return uiFindText->GetValue();
  }

  const int GetFlags();

  void ToData(ride::FindDlg& data) const;

  wxStyledTextCtrl* GetStc() {
    return m_scintilla1;
  }

  bool LookInCurrentFile() const {
    return uiLookIn->GetSelection() == 0;
  }

  bool IsRecursive() const {
    return uiIncludeSubFolders->GetValue();
  }

  const wxString getReplaceText() const {
    return uiReplaceText->GetValue();
  }

  bool KeepFilesOpen() const {
    return uiKeepFilesOpen->GetValue();
  }

protected:
  void OnCancel(wxCommandEvent& event);
  void OnOk(wxCommandEvent& event);
  void OnEnter(wxCommandEvent& event) {
    OnOk(event);
  }
};

FindDlg::FindDlg(wxWindow* parent, const wxString& find, const ride::FindDlg& data, bool findd)
  : ui::Find(parent, wxID_ANY)
{
  uiFindText->SetValue(find);
  uiFindText->SelectAll();
  uiFindText->SetFocus();

  uiLookIn->Append("Current file");
  uiLookIn->Append("This project");
  uiLookIn->SetSelection(0);

  uiFindTarget->Append("Normal text");
  uiFindTarget->Append("Regex");
  uiFindTarget->Append("Posix");

  uiIncludeSubFolders->SetValue(data.sub_folders());
  uiMatchCase->SetValue(data.match_case());
  uiMatchWholeWord->SetValue(data.match_whole_word());
  uiFindWordStart->SetValue(data.match_start());
  uiFileTypes->SetValue(data.file_types().c_str());
  uiFindTarget->SetSelection(data.target());

  uiReplaceStatic->Enable(findd==false);
  uiReplaceText->Enable(findd == false);
}

void FindDlg::ToData(ride::FindDlg& data) const {
  data.set_sub_folders(uiIncludeSubFolders->GetValue());
  data.set_match_case(uiMatchCase->GetValue());
  data.set_match_whole_word(uiMatchWholeWord->GetValue());
  data.set_match_start(uiFindWordStart->GetValue());
  data.set_file_types(uiFileTypes->GetValue());
  data.set_target(static_cast<::ride::FindDlgTarget>(uiFindTarget->GetSelection()));
}

void FindDlg::OnCancel(wxCommandEvent& event) {
  EndModal(wxID_CANCEL);
}

void FindDlg::OnOk(wxCommandEvent& event) {
  if (uiFindText->GetValue().length() <= 0) {
    ShowInfo(this, "Need to enter search text", "Missing Search Text");
    return;
  }
  EndModal(wxID_OK);
}

const int FindDlg::GetFlags() {
  int ret = 0;

  if (uiMatchCase->GetValue()) {
    ret |= wxSTC_FIND_MATCHCASE;
  }

  if (uiMatchWholeWord->GetValue()) {
    ret |= wxSTC_FIND_WHOLEWORD;
  }

  if (uiFindWordStart->GetValue()) {
    ret |= wxSTC_FIND_WORDSTART;
  }

  switch (uiFindTarget->GetSelection()) {
  case 0:
    break;
  case 1:
    ret |= wxSTC_FIND_REGEXP;
    break;
  case 2:
    ret |= wxSTC_FIND_POSIX;
    break;
  default:
    assert(false && "invalid selection");
    break;
  }

  return ret;
}

struct FindResult {
  FindResult(const wxString& f, const wxString& co, const int sl, const int sc, const int el, const int ec)
    : file(f)
    , content(co)
    , start_line(sl)
    , start_col(sc)
    , end_line(el)
    , end_col(ec)
  {
  }

  wxString file;
  wxString content;
  int start_line;
  int start_col;
  int end_line;
  int end_col;
};

int FindInStc(wxStyledTextCtrl* stc, const wxString& file, const wxString& text, int flags, std::vector<FindResult>* res, bool doReplace, const wxString& replaceText) {
  assert(res);
  assert(stc);
  int next_index = 0;
  int count = 0;
  while (true) {
    int end_index = 0;
    const int start_index = stc->FindText(next_index, stc->GetLength(), text, &end_index, flags);
    if (start_index == -1) return count;
    assert(start_index != end_index);

    const int start_line = stc->LineFromPosition(start_index);
    const int start_col = start_index - stc->PositionFromLine(start_line);
    const int end_line = stc->LineFromPosition(end_index);
    const int end_col = end_index - stc->PositionFromLine(end_line);
    res->push_back(FindResult(file, stc->GetLine(start_line).Trim(true).Trim(false), start_line+1, start_col+1, end_line+1, end_col+1));
    ++count;

    if (doReplace) {
      const bool useRegex = flags & wxSTC_FIND_REGEXP || flags & wxSTC_FIND_POSIX;
      const int change = useRegex
        ? stc->ReplaceTargetRE(replaceText)
       : stc->ReplaceTarget(replaceText);
      assert(change > 0);
      next_index = start_index + change;
    }
    else {
      next_index = end_index;
    }
  }

  return count;
}

void FindInFiles(MainWindow* parent, wxStyledTextCtrl* fallback, const wxString& file, const wxString& text, int flags, std::vector<FindResult>* res, bool doReplace, const wxString& replaceText, bool keepFilesOpen) {
  FileEdit* edit = parent->GetFile(file);
  wxStyledTextCtrl* stc = NULL;
  if (edit) {
    stc = edit->GetStc();
  }
  else {
    fallback->LoadFile(file);

    if (doReplace && keepFilesOpen) {
      int found = fallback->FindText(0, stc->GetLength(), text, NULL, flags);
      if (found > 0) {
        FileEdit* opened_edit = parent->OpenFile(file);
        stc = opened_edit->GetStc();
      }
    }
    if( stc == NULL ) {
      stc = fallback;
    }
  }
  assert(stc);
  int count = FindInStc(stc, file, text, flags, res, doReplace, replaceText);

  if (doReplace && count > 0 && stc == fallback) {
    if (false == stc->SaveFile(file)) {
      ShowError(parent, "Failed to save after replace!", "Error saving!");
    }
  }
}

bool ShowFindDlg(MainWindow* parent, const wxString& current_selection, const wxString& current_file, const wxString root_folder, wxStyledTextCtrl* output, bool find) {
  static ride::FindDlg find_dlg_data;
  FindDlg dlg(parent, current_selection, find_dlg_data, find);

  if (wxID_OK != dlg.ShowModal()) return false;
  dlg.ToData(find_dlg_data);

  std::vector<FindResult> results;
  wxString file_info = current_file;

  // we can't create a styled ctrl so we cheat by having a 0x0 widget on the find dlg
  // and use that for searching/replacing...
  wxStyledTextCtrl* fallback = dlg.GetStc();

  if (dlg.LookInCurrentFile()) {
    FindInFiles(parent, fallback, current_file, dlg.GetText(), dlg.GetFlags(), &results, find==false, dlg.getReplaceText(), dlg.KeepFilesOpen());
  }
  else {
    wxArrayString files;
    const wxString pattern = find_dlg_data.file_types();
    const size_t count = wxDir::GetAllFiles(root_folder, &files, pattern,
      dlg.IsRecursive() ? wxDIR_FILES | wxDIR_DIRS : wxDIR_FILES);
    file_info = wxString::Format("%d files in %s", count, root_folder);
    for (const auto file : files) {
      FindInFiles(parent, fallback, file, dlg.GetText(), dlg.GetFlags(), &results, find == false, dlg.getReplaceText(), dlg.KeepFilesOpen());
    }
  }

  const auto count = results.size();

  ClearOutput(output);
  WriteLine(output, wxString::Format("Searching for %s in %s", dlg.GetText(), file_info));
  WriteLine(output, wxString::Format("Found %d matches", count));
  WriteLine(output, "");
  for (auto res : results) {
    // try to format the same way rust related error looks like so we can reuse the parser code for both and get some synergy effects
    const wxString mess = wxString::Format("%s:%d : %d : %d : %d found: %s", res.file, res.start_line, res.start_col, res.end_line, res.end_col, res.content);
    WriteLine(output, mess);
  }

  return true;
}
<|endoftext|>


<commit_before>/*
 * Copyright 2013 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "Test.h"
#include "SkDeviceLooper.h"
#include "SkRasterClip.h"

static void make_bm(SkBitmap* bm, int w, int h) {
    bm->setConfig(SkBitmap::kA8_Config, w, h);
    bm->allocPixels();
}

static bool equal(const SkRasterClip& a, const SkRasterClip& b) {
    if (a.isBW()) {
        return b.isBW() && a.bwRgn() == b.bwRgn();
    } else {
        return a.isAA() && a.aaRgn() == b.aaRgn();
    }
}

static void test_simple(skiatest::Reporter* reporter) {
    static const struct {
        SkISize fDevSize;
        SkIRect fRCBounds;
        SkIRect fRect;
    } gRec[] = {
        { { 4000, 10 }, { 0, 0, 4000, 10 }, { 0, 0, 4000, 4000 } },
        { { 10, 4000 }, { 0, 0, 10, 4000 }, { 0, 0, 4000, 4000 } },
        // very large devce, small rect
        { { 32000, 10 }, { 0, 0, 32000, 10 }, { 0, 0, 4000, 4000 } },
        { { 10, 32000 }, { 0, 0, 10, 32000 }, { 0, 0, 4000, 4000 } },
        // very large device, small clip
        { { 32000, 10 }, { 0, 0, 4000, 10 }, { 0, 0, 32000, 32000 } },
        { { 10, 32000 }, { 0, 0, 10, 4000 }, { 0, 0, 32000, 32000 } },
    };

    for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); ++i) {
        SkBitmap bitmap;
        make_bm(&bitmap, gRec[i].fDevSize.width(), gRec[i].fDevSize.height());

        SkRasterClip rc(gRec[i].fRCBounds);

        for (int aa = 0; aa <= 1; ++aa) {
            SkDeviceLooper looper(bitmap, rc, gRec[i].fRect, SkToBool(aa));

            bool valid = looper.next();
            REPORTER_ASSERT(reporter, valid);
            if (valid) {
                REPORTER_ASSERT(reporter, looper.getBitmap().width() == bitmap.width());
                REPORTER_ASSERT(reporter, looper.getBitmap().height() == bitmap.height());
                REPORTER_ASSERT(reporter, equal(looper.getRC(), rc));

                REPORTER_ASSERT(reporter, !looper.next());
            }
        }
        // test that a rect that doesn't intersect returns no loops
        {
            SkIRect r = rc.getBounds();
            r.offset(r.width(), 0);
            SkDeviceLooper looper(bitmap, rc, r, false);
            REPORTER_ASSERT(reporter, !looper.next());
        }
    }
}

// mask-bits are interpreted as the areas where the clip is visible
//  [ 0x01  0x02 ]
//  [ 0x04  0x08 ]
//
static void make_rgn(SkRegion* rgn, int w, int h, unsigned mask) {
    SkASSERT(SkAlign2(w));
    SkASSERT(SkAlign2(h));
    w >>= 1;
    h >>= 1;
    const SkIRect baseR = SkIRect::MakeWH(w, h);

    int bit = 1;
    for (int y = 0; y <= 1; ++y) {
        for (int x = 0; x <= 1; ++x) {
            if (mask & bit) {
                SkIRect r = baseR;
                r.offset(x * w, y * h);
                rgn->op(r, SkRegion::kUnion_Op);
            }
            bit <<= 1;
        }
    }
}

static void test_complex(skiatest::Reporter* reporter) {
    // choose size values that will result in 4 quadrants, given fAA setting
    const int BW_SIZE = 17 * 1000;
    const int AA_SIZE = 7 * 1000;

    struct {
        SkISize fSize;
        bool    fAA;
    } const gRec[] = {
        { { BW_SIZE, BW_SIZE }, false },
        { {  AA_SIZE, AA_SIZE }, true },
    };

    for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); ++i) {
        const int w = gRec[i].fSize.width();
        const int h = gRec[i].fSize.height();

        SkBitmap bitmap;
        make_bm(&bitmap, w, h);

        const SkIRect rect = SkIRect::MakeWH(w, h);

        // mask-bits are interpreted as the areas where the clip is visible
        //  [ 0x01  0x02 ]
        //  [ 0x04  0x08 ]
        //
        for (int mask = 0; mask <= 15; ++mask) {
            SkRegion rgn;
            make_rgn(&rgn, w, h, mask);

            SkRasterClip rc;
            rc.op(rgn, SkRegion::kReplace_Op);

            SkDeviceLooper looper(bitmap, rc, rect, gRec[i].fAA);
            while (looper.next()) {
                REPORTER_ASSERT(reporter, !looper.getRC().isEmpty());
            }
        }
    }
}

static void TestDeviceLooper(skiatest::Reporter* reporter) {
    test_simple(reporter);
    test_complex(reporter);
}

#include "TestClassDef.h"
DEFINE_TESTCLASS("DeviceLooper", DeviceLooperClass, TestDeviceLooper)
<commit_msg>Fix Mac 10.6 DeviceLooperTest build error (this time with feeling)<commit_after>/*
 * Copyright 2013 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "Test.h"
#include "SkDeviceLooper.h"
#include "SkRasterClip.h"

static void make_bm(SkBitmap* bm, int w, int h) {
    bm->setConfig(SkBitmap::kA8_Config, w, h);
    bm->allocPixels();
}

static bool equal(const SkRasterClip& a, const SkRasterClip& b) {
    if (a.isBW()) {
        return b.isBW() && a.bwRgn() == b.bwRgn();
    } else {
        return a.isAA() && a.aaRgn() == b.aaRgn();
    }
}

static const struct {
    SkISize fDevSize;
    SkIRect fRCBounds;
    SkIRect fRect;
} gRec[] = {
    { { 4000, 10 }, { 0, 0, 4000, 10 }, { 0, 0, 4000, 4000 } },
    { { 10, 4000 }, { 0, 0, 10, 4000 }, { 0, 0, 4000, 4000 } },
    // very large devce, small rect
    { { 32000, 10 }, { 0, 0, 32000, 10 }, { 0, 0, 4000, 4000 } },
    { { 10, 32000 }, { 0, 0, 10, 32000 }, { 0, 0, 4000, 4000 } },
    // very large device, small clip
    { { 32000, 10 }, { 0, 0, 4000, 10 }, { 0, 0, 32000, 32000 } },
    { { 10, 32000 }, { 0, 0, 10, 4000 }, { 0, 0, 32000, 32000 } },
};

static void test_simple(skiatest::Reporter* reporter) {

    for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); ++i) {
        SkBitmap bitmap;
        make_bm(&bitmap, gRec[i].fDevSize.width(), gRec[i].fDevSize.height());

        SkRasterClip rc(gRec[i].fRCBounds);

        for (int aa = 0; aa <= 1; ++aa) {
            SkDeviceLooper looper(bitmap, rc, gRec[i].fRect, SkToBool(aa));

            bool valid = looper.next();
            REPORTER_ASSERT(reporter, valid);
            if (valid) {
                REPORTER_ASSERT(reporter, looper.getBitmap().width() == bitmap.width());
                REPORTER_ASSERT(reporter, looper.getBitmap().height() == bitmap.height());
                REPORTER_ASSERT(reporter, equal(looper.getRC(), rc));

                REPORTER_ASSERT(reporter, !looper.next());
            }
        }
        // test that a rect that doesn't intersect returns no loops
        {
            SkIRect r = rc.getBounds();
            r.offset(r.width(), 0);
            SkDeviceLooper looper(bitmap, rc, r, false);
            REPORTER_ASSERT(reporter, !looper.next());
        }
    }
}

// mask-bits are interpreted as the areas where the clip is visible
//  [ 0x01  0x02 ]
//  [ 0x04  0x08 ]
//
static void make_rgn(SkRegion* rgn, int w, int h, unsigned mask) {
    SkASSERT(SkAlign2(w));
    SkASSERT(SkAlign2(h));
    w >>= 1;
    h >>= 1;
    const SkIRect baseR = SkIRect::MakeWH(w, h);

    int bit = 1;
    for (int y = 0; y <= 1; ++y) {
        for (int x = 0; x <= 1; ++x) {
            if (mask & bit) {
                SkIRect r = baseR;
                r.offset(x * w, y * h);
                rgn->op(r, SkRegion::kUnion_Op);
            }
            bit <<= 1;
        }
    }
}

static void test_complex(skiatest::Reporter* reporter) {
    // choose size values that will result in 4 quadrants, given fAA setting
    const int BW_SIZE = 17 * 1000;
    const int AA_SIZE = 7 * 1000;

    struct {
        SkISize fSize;
        bool    fAA;
    } const gRec[] = {
        { { BW_SIZE, BW_SIZE }, false },
        { {  AA_SIZE, AA_SIZE }, true },
    };

    for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); ++i) {
        const int w = gRec[i].fSize.width();
        const int h = gRec[i].fSize.height();

        SkBitmap bitmap;
        make_bm(&bitmap, w, h);

        const SkIRect rect = SkIRect::MakeWH(w, h);

        // mask-bits are interpreted as the areas where the clip is visible
        //  [ 0x01  0x02 ]
        //  [ 0x04  0x08 ]
        //
        for (int mask = 0; mask <= 15; ++mask) {
            SkRegion rgn;
            make_rgn(&rgn, w, h, mask);

            SkRasterClip rc;
            rc.op(rgn, SkRegion::kReplace_Op);

            SkDeviceLooper looper(bitmap, rc, rect, gRec[i].fAA);
            while (looper.next()) {
                REPORTER_ASSERT(reporter, !looper.getRC().isEmpty());
            }
        }
    }
}

static void TestDeviceLooper(skiatest::Reporter* reporter) {
    test_simple(reporter);
    test_complex(reporter);
}

#include "TestClassDef.h"
DEFINE_TESTCLASS("DeviceLooper", DeviceLooperClass, TestDeviceLooper)
<|endoftext|>


<commit_before>#ifndef __MAPNIK_VECTOR_TILE_COMPOSITE_H__
#define __MAPNIK_VECTOR_TILE_COMPOSITE_H__

// mapnik-vector-tile
#include "vector_tile_merc_tile.hpp"
#include "vector_tile_datasource_pbf.hpp"
#include "vector_tile_processor.hpp"
#include "vector_tile_config.hpp"

// mapnik
#include <mapnik/map.hpp>
#include <mapnik/layer.hpp>

//protozero
#include <protozero/pbf_reader.hpp>

namespace mapnik
{

namespace vector_tile_impl
{

void composite(merc_tile & target_vt,
               std::vector<merc_tile_ptr> const& vtiles,
               mapnik::Map & map,
               processor & ren, // processor should be on map object provided
               double scale_denominator = 0.0,
               unsigned offset_x = 0,
               unsigned offset_y = 0,
               bool reencode = false)
{
    if (target_vt.tile_size() <= 0)
    {
        throw std::runtime_error("Vector tile size must be great than zero");
    }

    for (auto const& vt : vtiles)
    {
        if (vt->tile_size() <= 0)
        {
            throw std::runtime_error("Vector tile size must be great than zero");
        }

        if (vt->is_empty())
        {
            continue;
        }

        bool reencode_tile = reencode;
        if (!reencode_tile && !target_vt.same_extent(*vt))
        {
            reencode_tile = true;
        }

        protozero::pbf_reader tile_message(vt->get_reader());
        // loop through the layers of the tile!
        while (tile_message.next(Tile_Encoding::LAYERS))
        {
            bool reencode_layer = reencode_tile;
            auto data_pair = tile_message.get_data();
            protozero::pbf_reader layer_message(data_pair);
            if (!layer_message.next(Layer_Encoding::NAME))
            {
                continue;
            }

            std::string layer_name = layer_message.get_string();

            if (!reencode_layer)
            {
                target_vt.append_layer_buffer(data_pair.first, data_pair.second, layer_name);
            }

            if (target_vt.has_layer(layer_name))
            {
                continue;
            }

            protozero::pbf_reader layer_pbf(data_pair);
            auto ds = std::make_shared<mapnik::vector_tile_impl::tile_datasource_pbf>(
                        layer_pbf,
                        vt->x(),
                        vt->y(),
                        vt->z());
            mapnik::layer lyr(layer_name,"+init=epsg:3857");
            ds->set_envelope(vt->get_buffered_extent());
            lyr.set_datasource(ds);
            map.add_layer(lyr);
        }
    }
    if (!map.layers().empty())
    {
        ren.update_tile(target_vt,
                        scale_denominator,
                        offset_x,
                        offset_y);
    }
}

} // end ns vector_tile_impl

} // end ns mapnik

#endif // __MAPNIK_VECTOR_TILE_COMPOSITE_H__
<commit_msg>Made it so that compositing would attempt to keep the same extent of the tiles being composited.<commit_after>#ifndef __MAPNIK_VECTOR_TILE_COMPOSITE_H__
#define __MAPNIK_VECTOR_TILE_COMPOSITE_H__

// mapnik-vector-tile
#include "vector_tile_merc_tile.hpp"
#include "vector_tile_datasource_pbf.hpp"
#include "vector_tile_processor.hpp"
#include "vector_tile_config.hpp"

// mapnik
#include <mapnik/map.hpp>
#include <mapnik/layer.hpp>

//protozero
#include <protozero/pbf_reader.hpp>

namespace mapnik
{

namespace vector_tile_impl
{

void composite(merc_tile & target_vt,
               std::vector<merc_tile_ptr> const& vtiles,
               mapnik::Map & map,
               processor & ren, // processor should be on map object provided
               double scale_denominator = 0.0,
               unsigned offset_x = 0,
               unsigned offset_y = 0,
               bool reencode = false)
{
    if (target_vt.tile_size() <= 0)
    {
        throw std::runtime_error("Vector tile size must be great than zero");
    }

    for (auto const& vt : vtiles)
    {
        if (vt->tile_size() <= 0)
        {
            throw std::runtime_error("Vector tile size must be great than zero");
        }

        if (vt->is_empty())
        {
            continue;
        }

        bool reencode_tile = reencode;
        if (!reencode_tile && !target_vt.same_extent(*vt))
        {
            reencode_tile = true;
        }

        protozero::pbf_reader tile_message(vt->get_reader());
        // loop through the layers of the tile!
        while (tile_message.next(Tile_Encoding::LAYERS))
        {
            bool reencode_layer = reencode_tile;
            auto data_pair = tile_message.get_data();
            protozero::pbf_reader layer_message(data_pair);
            if (!layer_message.next(Layer_Encoding::NAME))
            {
                continue;
            }

            std::string layer_name = layer_message.get_string();

            if (!reencode_layer)
            {
                target_vt.append_layer_buffer(data_pair.first, data_pair.second, layer_name);
            }

            if (target_vt.has_layer(layer_name))
            {
                continue;
            }

            protozero::pbf_reader layer_pbf(data_pair);
            auto ds = std::make_shared<mapnik::vector_tile_impl::tile_datasource_pbf>(
                        layer_pbf,
                        vt->x(),
                        vt->y(),
                        vt->z(),
                        true);
            mapnik::layer lyr(layer_name,"+init=epsg:3857");
            ds->set_envelope(vt->get_buffered_extent());
            lyr.set_datasource(ds);
            map.add_layer(lyr);
        }
    }
    if (!map.layers().empty())
    {
        ren.update_tile(target_vt,
                        scale_denominator,
                        offset_x,
                        offset_y);
    }
}

} // end ns vector_tile_impl

} // end ns mapnik

#endif // __MAPNIK_VECTOR_TILE_COMPOSITE_H__
<|endoftext|>